main
py 73 lines 2.05 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import pytest
4 import torch
5
6 from vllm import _custom_ops as ops
7 from vllm.platforms import current_platform
8 from vllm.utils.flashinfer import flashinfer_scaled_fp8_mm
9 from vllm.utils.torch_utils import set_random_seed
10
11 if not current_platform.has_device_capability(100):
12 pytest.skip(
13 reason="Flashinfer FP8 gemms requires compute capability of 10.0 or above.",
14 allow_module_level=True,
15 )
16
17 DTYPES = [torch.float16, torch.bfloat16]
18 # m, n, k
19 SHAPES = [(128, 128, 64), (128, 128, 128), (256, 128, 64), (128, 256, 128)]
20 PAD_SHAPES = [(150, 128, 64), (128, 128, 96)]
21 SHAPES.extend(PAD_SHAPES)
22
23 SEEDS = [42]
24 CUDA_DEVICES = ["cuda:0"]
25
26
27 @pytest.mark.parametrize("dtype", DTYPES)
28 @pytest.mark.parametrize("shape", SHAPES)
29 @pytest.mark.parametrize("use_bias", [True, False])
30 @pytest.mark.parametrize("seed", SEEDS)
31 @pytest.mark.parametrize("device", CUDA_DEVICES)
32 @pytest.mark.parametrize("autotune", [False, True])
33 @torch.inference_mode()
34 def test_flashinfer_fp8_gemm(
35 dtype: torch.dtype,
36 shape: tuple[int, int, int],
37 use_bias: bool,
38 seed: int,
39 device: str,
40 autotune: bool,
41 ) -> None:
42 set_random_seed(seed)
43 m, n, k = shape
44 a = torch.randn((m, k), dtype=dtype, device=device)
45 b = torch.randn((n, k), dtype=dtype, device=device) / k
46
47 a_fp8, a_scale = ops.scaled_fp8_quant(a)
48 b_fp8, b_scale = ops.scaled_fp8_quant(b)
49
50 expected_out = torch.mm(
51 a_scale * a_fp8.to(dtype=torch.float32),
52 b_scale * b_fp8.to(dtype=torch.float32).t(),
53 ).to(dtype=dtype)
54
55 if use_bias:
56 bias = torch.randn((n,), dtype=dtype, device=device)
57 expected_out = expected_out + bias
58 else:
59 bias = None
60
61 import flashinfer
62
63 with flashinfer.autotune(autotune):
64 out = flashinfer_scaled_fp8_mm(
65 a_fp8,
66 b_fp8.t(),
67 a_scale,
68 b_scale,
69 dtype,
70 bias=bias,
71 )
72
73 torch.testing.assert_close(out, expected_out, atol=1e-2, rtol=1e-2)