A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 5, 01:00 UTC
skip fp8e4b15 on xpu (#39957)
Signed-off-by: Xinyu Chen <xinyu1.chen@intel.com> Co-authored-by: Kunshang Ji <kunshang.ji@intel.com>
Xinyu Chen committed
Apr 18, 2026 at 00:55 UTC
251c18d1f89c363b9f5ecaa29247df64f4157308
2 files changed
+26
-18
tests/quantization/test_turboquant.py
+17
-15
@@ -21,6 +21,7 @@ from vllm.model_executor.layers.quantization.turboquant.config import (
21
from vllm.model_executor.layers.quantization.turboquant.quantizer import (
22
generate_wht_signs,
23
)
24
+from vllm.platforms import current_platform
25
from vllm.utils.math_utils import next_power_of_2
26
27
# ============================================================================
@@ -345,7 +346,8 @@ class TestLloydMax:
346
# Rotation matrix tests (GPU required)
347
# ============================================================================
348
348
-CUDA_AVAILABLE = torch.cuda.is_available()
349
+GPGPU_AVAILABLE = torch.cuda.is_available() or torch.xpu.is_available()
350
+DEVICE_TYPE = current_platform.device_type
351
352
353
def generate_rotation_matrix(d: int, seed: int, device: str = "cpu") -> torch.Tensor:
@@ -360,16 +362,16 @@ def generate_rotation_matrix(d: int, seed: int, device: str = "cpu") -> torch.Te
362
return Q.to(device)
363
364
363
-@pytest.mark.skipif(not CUDA_AVAILABLE, reason="CUDA not available")
365
+@pytest.mark.skipif(not GPGPU_AVAILABLE, reason="GPGPU not available")
366
class TestRotationMatrix:
367
"""Tests for the QR-based rotation (standalone benchmarks only)."""
368
369
@pytest.mark.parametrize("dim", [64, 96, 128, 256])
370
def test_rotation_matrix_shape_and_orthogonal(self, dim):
369
- Pi = generate_rotation_matrix(dim, seed=42, device="cuda")
371
+ Pi = generate_rotation_matrix(dim, seed=42, device=DEVICE_TYPE)
372
assert Pi.shape == (dim, dim)
373
eye = Pi @ Pi.T
372
- assert torch.allclose(eye, torch.eye(dim, device="cuda"), atol=1e-5), (
374
+ assert torch.allclose(eye, torch.eye(dim, device=DEVICE_TYPE), atol=1e-5), (
375
f"Pi not orthogonal for dim={dim}"
376
)
377
@@ -385,7 +387,7 @@ class TestRotationMatrix:
387
388
def test_rotation_matrix_det_is_pm1(self):
389
"""Orthogonal matrix determinant must be +1 or -1."""
388
- Pi = generate_rotation_matrix(128, seed=42, device="cuda")
390
+ Pi = generate_rotation_matrix(128, seed=42, device=DEVICE_TYPE)
391
det = torch.linalg.det(Pi)
392
assert abs(abs(det.item()) - 1.0) < 1e-4
393
@@ -403,31 +405,31 @@ def _build_hadamard(d: int, device: str = "cpu") -> torch.Tensor:
405
return (H / math.sqrt(d)).to(torch.device(device))
406
407
406
-@pytest.mark.skipif(not CUDA_AVAILABLE, reason="CUDA not available")
408
+@pytest.mark.skipif(not GPGPU_AVAILABLE, reason="GPGPU not available")
409
class TestWHTRotation:
410
"""Tests for the WHT rotation actually used in serving."""
411
412
@pytest.mark.parametrize("dim", [64, 128, 256])
413
def test_wht_orthonormal(self, dim):
414
"""signs * H must be orthonormal: (signs*H) @ (signs*H)^T = I."""
413
- signs = generate_wht_signs(dim, seed=42, device="cuda")
414
- H = _build_hadamard(dim, "cuda")
415
+ signs = generate_wht_signs(dim, seed=42, device=DEVICE_TYPE)
416
+ H = _build_hadamard(dim, DEVICE_TYPE)
417
PiT = (signs.unsqueeze(1) * H).contiguous()
418
eye = PiT @ PiT.T
417
- assert torch.allclose(eye, torch.eye(dim, device="cuda"), atol=1e-5), (
419
+ assert torch.allclose(eye, torch.eye(dim, device=DEVICE_TYPE), atol=1e-5), (
420
f"WHT rotation not orthonormal for dim={dim}"
421
)
422
423
@pytest.mark.parametrize("dim", [64, 128, 256])
424
def test_wht_self_inverse(self, dim):
425
"""PiT should be self-inverse: PiT @ PiT = I (up to sign flip)."""
424
- signs = generate_wht_signs(dim, seed=42, device="cuda")
425
- H = _build_hadamard(dim, "cuda")
426
+ signs = generate_wht_signs(dim, seed=42, device=DEVICE_TYPE)
427
+ H = _build_hadamard(dim, DEVICE_TYPE)
428
PiT = (signs.unsqueeze(1) * H).contiguous()
429
Pi = PiT.T.contiguous()
430
# Pi @ PiT should be identity (rotation then inverse)
431
result = Pi @ PiT
430
- assert torch.allclose(result, torch.eye(dim, device="cuda"), atol=1e-5), (
432
+ assert torch.allclose(result, torch.eye(dim, device=DEVICE_TYPE), atol=1e-5), (
433
f"WHT rotation not self-inverse for dim={dim}"
434
)
435
@@ -454,7 +456,7 @@ class TestWHTRotation:
456
# ============================================================================
457
458
457
-@pytest.mark.skipif(not CUDA_AVAILABLE, reason="CUDA not available")
459
+@pytest.mark.skipif(not GPGPU_AVAILABLE, reason="GPGPU not available")
460
class TestStoreDecodeRoundTrip:
461
"""End-to-end: store KV into TQ cache, decode, compare vs fp16 ref."""
462
@@ -487,11 +489,11 @@ class TestStoreDecodeRoundTrip:
489
block_size = 16
490
num_blocks = 1
491
490
- device = torch.device("cuda")
492
+ device = torch.device(DEVICE_TYPE)
493
494
# Generate rotation
495
signs = generate_wht_signs(D, seed=42, device=device)
494
- H = _build_hadamard(D, "cuda")
496
+ H = _build_hadamard(D, DEVICE_TYPE)
497
PiT = (signs.unsqueeze(1) * H).contiguous().float()
498
Pi = PiT.T.contiguous()
499
vllm/v1/attention/ops/triton_turboquant_decode.py
+9
-3
@@ -13,6 +13,7 @@ from typing import Any
13
14
import torch
15
16
+from vllm.platforms import current_platform
17
from vllm.triton_utils import tl, triton
18
from vllm.v1.attention.ops.triton_decode_attention import (
19
_fwd_kernel_stage2,
@@ -22,10 +23,15 @@ _FP8_E4B15: dict[int, int] = {}
23
24
25
def _use_fp8_e4b15(device: int = 0) -> int:
25
- """Return 1 if device needs fp8e4b15 (Ampere/Ada, SM < 8.9), else 0."""
26
+ """Return 1 if device needs fp8e4b15 (Ampere/Ada, SM < 8.9), else 0.
27
+ On non-CUDA platforms (e.g. XPU), always returns 0 (use e4nv format).
28
+ """
29
if device not in _FP8_E4B15:
27
- cap = torch.cuda.get_device_capability(device)
28
- _FP8_E4B15[device] = 1 if cap < (8, 9) else 0
30
+ if current_platform.is_cuda_alike():
31
+ cap = torch.cuda.get_device_capability(device)
32
+ _FP8_E4B15[device] = 1 if cap < (8, 9) else 0
33
+ else:
34
+ _FP8_E4B15[device] = 0
35
return _FP8_E4B15[device]
36
37