main
py 255 lines 8.19 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 """E2E tests for online MXFP8 quantization.
5
6 Loads a BF16 model with ``--quantization mxfp8`` (online quantization) and
7 compares log-probabilities against the same model served in BF16 without
8 quantization. This exercises the full pipeline: config parsing,
9 ``Mxfp8OnlineLinearMethod``, ``Mxfp8OnlineMoEMethod``, weight loading,
10 online quantization / shuffling, and inference through ``apply_monolithic``.
11
12 Layer skipping (``modules_to_not_convert``) is configured in the model's
13 ``config.json`` under ``quantization_config`` and is not tested here.
14
15 ``example_prompts`` is a pytest fixture (from conftest.py) that loads 8
16 diverse prompts from ``tests/prompts/example.txt``.
17 """
18
19 import pytest
20 import torch
21
22 from tests.quantization.utils import is_quant_method_supported
23 from vllm.platforms import current_platform
24
25 from ..utils import check_logprobs_close
26
27 # A small MoE model that fits on a single GPU and has both linear + MoE layers.
28 MOE_MODEL = "allenai/OLMoE-1B-7B-0125-Instruct"
29 # A small dense model (no MoE) to validate the linear-only path.
30 DENSE_MODEL = "Qwen/Qwen3-0.6B"
31
32 MAX_MODEL_LEN = 1024
33 MAX_TOKENS = 4
34 NUM_LOG_PROBS = 8
35
36
37 @pytest.mark.skipif(
38 not is_quant_method_supported("mxfp8"),
39 reason="mxfp8 is not supported on this GPU type (requires sm_100+).",
40 )
41 @pytest.mark.quant_model
42 @pytest.mark.parametrize("model", [DENSE_MODEL, MOE_MODEL], ids=["dense", "moe"])
43 def test_mxfp8_logprobs(
44 vllm_runner,
45 quant_baseline_logprobs,
46 example_prompts,
47 model: str,
48 monkeypatch: pytest.MonkeyPatch,
49 ) -> None:
50 """Compare BF16 baseline logprobs against online MXFP8-quantized model.
51
52 Runs the same model twice -- once in BF16 (baseline) and once with
53 online MXFP8 quantization -- then checks that the top log-probabilities
54 are close. Only 4 tokens are generated to keep the test fast while
55 still catching numerical divergence.
56 """
57 with monkeypatch.context() as m:
58 m.setenv("TOKENIZERS_PARALLELISM", "true")
59
60 baseline_outputs = quant_baseline_logprobs(
61 model,
62 example_prompts,
63 max_model_len=MAX_MODEL_LEN,
64 max_tokens=MAX_TOKENS,
65 num_logprobs=NUM_LOG_PROBS,
66 )
67
68 with vllm_runner(
69 model,
70 max_model_len=MAX_MODEL_LEN,
71 enforce_eager=True,
72 quantization="mxfp8",
73 ) as vllm_model:
74 test_outputs = vllm_model.generate_greedy_logprobs(
75 example_prompts, MAX_TOKENS, NUM_LOG_PROBS
76 )
77
78 check_logprobs_close(
79 outputs_0_lst=baseline_outputs,
80 outputs_1_lst=test_outputs,
81 name_0="bf16",
82 name_1="mxfp8",
83 )
84
85
86 @pytest.mark.skipif(
87 not is_quant_method_supported("mxfp8"),
88 reason="mxfp8 is not supported on this GPU type (requires sm_100+).",
89 )
90 @pytest.mark.skipif(
91 not current_platform.is_rocm(),
92 reason="AITER MXFP8 MoE backend is ROCm-only.",
93 )
94 @pytest.mark.quant_model
95 def test_mxfp8_aiter_requires_swigluoai_activation(
96 monkeypatch: pytest.MonkeyPatch,
97 ) -> None:
98 from vllm.model_executor.layers.fused_moe.activation import MoEActivation
99 from vllm.model_executor.layers.fused_moe.config import (
100 FusedMoEConfig,
101 FusedMoEParallelConfig,
102 RoutingMethodType,
103 )
104 from vllm.model_executor.layers.fused_moe.experts import aiter_mxfp8_moe
105 from vllm.model_executor.layers.fused_moe.oracle.mxfp8 import (
106 select_mxfp8_moe_backend,
107 )
108
109 monkeypatch.setattr(
110 aiter_mxfp8_moe.AiterMxfp8Experts,
111 "_supports_current_device",
112 staticmethod(lambda: True),
113 )
114
115 config = FusedMoEConfig(
116 num_experts=8,
117 experts_per_token=2,
118 hidden_dim=256,
119 intermediate_size=256,
120 num_local_experts=8,
121 num_logical_experts=8,
122 moe_parallel_config=FusedMoEParallelConfig.make_no_parallel(),
123 activation=MoEActivation.SILU,
124 in_dtype=torch.bfloat16,
125 device="cuda",
126 routing_method=RoutingMethodType.Renormalize,
127 moe_backend="aiter",
128 )
129
130 with pytest.raises(ValueError, match="requires activation=swigluoai_uninterleave"):
131 select_mxfp8_moe_backend(config)
132
133
134 @pytest.mark.skipif(
135 not is_quant_method_supported("mxfp8"),
136 reason="mxfp8 is not supported on this GPU type (requires sm_100+).",
137 )
138 @pytest.mark.skipif(
139 not current_platform.is_rocm(),
140 reason="AITER MXFP8 MoE backend is ROCm-only.",
141 )
142 @pytest.mark.quant_model
143 def test_mxfp8_aiter_requires_swigluoai_params(
144 monkeypatch: pytest.MonkeyPatch,
145 ) -> None:
146 from vllm.model_executor.layers.fused_moe.activation import MoEActivation
147 from vllm.model_executor.layers.fused_moe.config import (
148 FusedMoEConfig,
149 FusedMoEParallelConfig,
150 RoutingMethodType,
151 )
152 from vllm.model_executor.layers.fused_moe.experts import aiter_mxfp8_moe
153 from vllm.model_executor.layers.fused_moe.oracle.mxfp8 import (
154 select_mxfp8_moe_backend,
155 )
156
157 monkeypatch.setattr(
158 aiter_mxfp8_moe.AiterMxfp8Experts,
159 "_supports_current_device",
160 staticmethod(lambda: True),
161 )
162
163 config = FusedMoEConfig(
164 num_experts=8,
165 experts_per_token=2,
166 hidden_dim=256,
167 intermediate_size=256,
168 num_local_experts=8,
169 num_logical_experts=8,
170 moe_parallel_config=FusedMoEParallelConfig.make_no_parallel(),
171 activation=MoEActivation.SWIGLUOAI_UNINTERLEAVE,
172 in_dtype=torch.bfloat16,
173 device="cuda",
174 routing_method=RoutingMethodType.Renormalize,
175 moe_backend="aiter",
176 )
177
178 with pytest.raises(ValueError, match="hardcodes SwiGLU-OAI"):
179 select_mxfp8_moe_backend(config)
180
181
182 @pytest.mark.skipif(
183 not is_quant_method_supported("mxfp8"),
184 reason="mxfp8 is not supported on this GPU type (requires sm_100+).",
185 )
186 @pytest.mark.skipif(
187 not current_platform.is_rocm(),
188 reason="AITER MXFP8 MoE backend is ROCm-only.",
189 )
190 @pytest.mark.quant_model
191 def test_mxfp8_aiter_accepts_swigluoai_params(
192 monkeypatch: pytest.MonkeyPatch,
193 ) -> None:
194 from vllm.model_executor.layers.fused_moe.activation import MoEActivation
195 from vllm.model_executor.layers.fused_moe.config import (
196 FusedMoEConfig,
197 FusedMoEParallelConfig,
198 RoutingMethodType,
199 )
200 from vllm.model_executor.layers.fused_moe.experts import aiter_mxfp8_moe
201 from vllm.model_executor.layers.fused_moe.oracle.fp8 import Fp8MoeBackend
202 from vllm.model_executor.layers.fused_moe.oracle.mxfp8 import (
203 select_mxfp8_moe_backend,
204 )
205
206 monkeypatch.setattr(
207 aiter_mxfp8_moe.AiterMxfp8Experts,
208 "_supports_current_device",
209 staticmethod(lambda: True),
210 )
211
212 config = FusedMoEConfig(
213 num_experts=8,
214 experts_per_token=2,
215 hidden_dim=256,
216 intermediate_size=256,
217 num_local_experts=8,
218 num_logical_experts=8,
219 moe_parallel_config=FusedMoEParallelConfig.make_no_parallel(),
220 activation=MoEActivation.SWIGLUOAI_UNINTERLEAVE,
221 in_dtype=torch.bfloat16,
222 device="cuda",
223 routing_method=RoutingMethodType.Renormalize,
224 moe_backend="aiter",
225 swiglu_alpha=aiter_mxfp8_moe._AITER_SWIGLU_ALPHA,
226 swiglu_beta=aiter_mxfp8_moe._AITER_SWIGLU_BETA,
227 )
228
229 backend, experts_cls = select_mxfp8_moe_backend(config)
230
231 assert backend == Fp8MoeBackend.AITER_MXFP8
232 assert experts_cls is aiter_mxfp8_moe.AiterMxfp8Experts
233
234
235 @pytest.mark.skipif(
236 not is_quant_method_supported("mxfp8"),
237 reason="mxfp8 is not supported on this GPU type (requires sm_100+).",
238 )
239 @pytest.mark.quant_model
240 @pytest.mark.parametrize("model", [DENSE_MODEL, MOE_MODEL], ids=["dense", "moe"])
241 def test_mxfp8_generation(vllm_runner, model: str) -> None:
242 """Smoke test: verify online MXFP8 model generates coherent text."""
243 prompt = "1 2 3 4 5"
244 with vllm_runner(
245 model,
246 enforce_eager=True,
247 quantization="mxfp8",
248 max_model_len=MAX_MODEL_LEN,
249 ) as vllm_model:
250 output = vllm_model.generate_greedy([prompt], max_tokens=5)
251
252 generated = output[0][1]
253 assert len(generated) > len(prompt), (
254 f"MXFP8 model produced no new tokens. Output: {generated!r}"
255 )