Skip to content

Commit 8878ebd

Browse files
authored
[ROCm][CI] Expand AITER W4A4 MoE Coverage (#52647)
Signed-off-by: Micah Williamson <micah.williamson@amd.com>
1 parent f08a95f commit 8878ebd

2 files changed

Lines changed: 59 additions & 7 deletions

File tree

tests/kernels/moe/test_ocp_mx_moe.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ def test_mxfp4_loading_and_execution_moe(vllm_runner, model_case: ModelCase):
125125

126126
# if model_case.model_id == "fxmarty/qwen_1.5-moe-a2.7b-mxfp4":
127127
# llm.apply_model(check_model)
128-
129128
output = llm.generate_greedy("Today I am in the French Alps and", max_tokens=20)
130129
assert output
131130

@@ -187,6 +186,16 @@ def mxfp8_dequantize(x, scale):
187186
return x_float * scale
188187

189188

189+
def mxfp4_quant_dequant(x: torch.Tensor) -> torch.Tensor:
190+
shape = x.shape
191+
quantized, scale = dynamic_mxfp4_quant(x.to(torch.bfloat16).flatten(0, -2))
192+
return (
193+
upcast_from_mxfp(quantized.view(torch.uint8), scale, torch.bfloat16, axis=-1)
194+
.reshape(shape)
195+
.float()
196+
)
197+
198+
190199
def reference_moe(
191200
roouting_logits,
192201
topk,
@@ -219,6 +228,8 @@ def reference_moe(
219228
expert_weights = torch.nn.functional.softmax(experts.values, dim=1)
220229
expert_indices = experts.indices
221230
t = hidden_states.clone()
231+
if act_type == "mxfp4":
232+
t = mxfp4_quant_dequant(t)
222233
# MLP #1
223234
mlp1_weight = w13[expert_indices, ...]
224235
mlp1_bias = bias13[expert_indices, ...]
@@ -244,6 +255,8 @@ def reference_moe(
244255
t.to(torch.bfloat16), is_sf_swizzled_layout=False
245256
)
246257
t = mxfp8_dequantize(t_quantized, t_scale)
258+
elif act_type == "mxfp4":
259+
t = mxfp4_quant_dequant(t)
247260
# MLP #2
248261
mlp2_weight = w2[expert_indices, ...]
249262
mlp2_bias = bias2[expert_indices, ...]
@@ -1392,6 +1405,14 @@ def test_trtllm_gen_mxfp8_block_scale_moe(
13921405
"requires_aiter": True,
13931406
"requires_gfx950": True,
13941407
},
1408+
"AITER_MXFP4_MXFP4": {
1409+
"activation": "SILU",
1410+
"act_type": "mxfp4",
1411+
"rtol": 1.0,
1412+
"percent": 0.8,
1413+
"requires_aiter": True,
1414+
"requires_gfx950": True,
1415+
},
13951416
}
13961417

13971418

@@ -1662,7 +1683,7 @@ class MockLayer:
16621683
alpha=1.702 if activation == MoEActivation.SWIGLUOAI else 1.0,
16631684
beta=1.0 if activation == MoEActivation.SWIGLUOAI else 0.0,
16641685
limit=7.0 if activation == MoEActivation.SWIGLUOAI else None,
1665-
act_type="bf16",
1686+
act_type=str(config.get("act_type", "bf16")),
16661687
activation=act_name,
16671688
use_interleaved_layout=use_interleaved,
16681689
)

tests/quantization/test_gfx950_moe.py

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,32 @@
2525

2626
ROCM_AVAILABLE = current_platform.is_rocm()
2727
ROCM_GFX950 = False
28-
ROCM_AITER_AVAILABLE = False
28+
ROCM_AITER_SUPPORTED = False
2929

3030
if ROCM_AVAILABLE:
31-
from vllm._aiter_ops import rocm_aiter_ops
31+
from vllm._aiter_ops import is_aiter_found_and_supported, rocm_aiter_ops
3232
from vllm.platforms.rocm import on_gfx950
3333

3434
ROCM_GFX950 = on_gfx950()
35-
ROCM_AITER_AVAILABLE = rocm_aiter_ops.is_fused_moe_enabled()
35+
ROCM_AITER_SUPPORTED = is_aiter_found_and_supported()
36+
37+
38+
def set_rocm_aiter(monkeypatch: pytest.MonkeyPatch, enabled: bool) -> None:
39+
value = "1" if enabled else "0"
40+
monkeypatch.setenv("VLLM_ROCM_USE_AITER", value)
41+
monkeypatch.setenv("VLLM_ROCM_USE_AITER_MOE", value)
42+
monkeypatch.setattr(rocm_aiter_ops, "_AITER_ENABLED", enabled)
43+
monkeypatch.setattr(rocm_aiter_ops, "_FMOE_ENABLED", enabled)
44+
45+
46+
@pytest.fixture
47+
def enable_rocm_aiter(monkeypatch: pytest.MonkeyPatch):
48+
set_rocm_aiter(monkeypatch, True)
49+
50+
51+
@pytest.fixture
52+
def disable_rocm_aiter(monkeypatch: pytest.MonkeyPatch):
53+
set_rocm_aiter(monkeypatch, False)
3654

3755

3856
def _make_w4a4_moe_config(moe_backend: str = "auto") -> FusedMoEConfig:
@@ -68,8 +86,8 @@ def mxfp4_oracle_config():
6886

6987

7088
@pytest.mark.skipif(not ROCM_GFX950, reason="Requires GFX950 (mi355x)")
71-
@pytest.mark.skipif(not ROCM_AITER_AVAILABLE, reason="Requires AITER enabled")
72-
def test_w4a4_dispatches_to_aiter(mxfp4_oracle_config):
89+
@pytest.mark.skipif(not ROCM_AITER_SUPPORTED, reason="Requires supported AITER")
90+
def test_w4a4_dispatches_to_aiter(mxfp4_oracle_config, enable_rocm_aiter):
7391
"""With AITER enabled + GFX950, W4A4 selects AITER_MXFP4_MXFP4."""
7492
config = _make_w4a4_moe_config()
7593
backend, experts_cls = select_mxfp4_moe_backend(
@@ -79,6 +97,19 @@ def test_w4a4_dispatches_to_aiter(mxfp4_oracle_config):
7997
assert experts_cls is not None
8098

8199

100+
@pytest.mark.skipif(not ROCM_GFX950, reason="Requires GFX950 (mi355x)")
101+
def test_w4a4_falls_back_without_aiter(
102+
mxfp4_oracle_config,
103+
disable_rocm_aiter,
104+
):
105+
config = _make_w4a4_moe_config()
106+
backend, experts_cls = select_mxfp4_moe_backend(
107+
config, activation_key=kMxfp4Dynamic
108+
)
109+
assert backend == Mxfp4MoeBackend.EMULATION
110+
assert experts_cls is not None
111+
112+
82113
@pytest.mark.skipif(not ROCM_GFX950, reason="Requires GFX950 (mi355x)")
83114
def test_w4a4_dispatches_to_emulation_with_moe_backend(mxfp4_oracle_config):
84115
"""With --moe-backend emulation, W4A4 selects EMULATION."""

0 commit comments

Comments
 (0)