Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
b313689
fix issues with nvfp4 dense emulation in vllm (squash)
fxmarty-amd Mar 2, 2026
bc6ff39
address comments
fxmarty-amd Mar 2, 2026
14bc668
nvfp4 moe emulation support
fxmarty-amd Mar 2, 2026
a11d131
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Mar 2, 2026
95c6a4a
wip use TritonExperts
fxmarty-amd Mar 2, 2026
5a2cf8c
wip cleanup
fxmarty-amd Mar 2, 2026
0ea8f82
wip cleanup
fxmarty-amd Mar 2, 2026
d99373e
wip cleanup
fxmarty-amd Mar 2, 2026
7a5f2ba
fix activation quantization
fxmarty-amd Mar 2, 2026
457f9df
address comment
fxmarty-amd Mar 2, 2026
01b4dce
enable test on non-blackwell devices
fxmarty-amd Mar 3, 2026
1d6c770
Merge branch 'main' into upstream-nvfp4-simulation-support-moe
fxmarty-amd Mar 4, 2026
cf189ef
cleanup
fxmarty-amd Mar 4, 2026
6db0c7b
Merge branch 'main-upstream' into upstream-nvfp4-simulation-support-rocm
fxmarty-amd Mar 4, 2026
ec1f4b8
address comment
fxmarty-amd Mar 4, 2026
309cefb
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Mar 4, 2026
cca5040
fix
fxmarty-amd Mar 4, 2026
9007357
Merge branch 'main' into upstream-nvfp4-simulation-support-rocm
fxmarty-amd Mar 5, 2026
e7d72f5
address bowen's comments
fxmarty-amd Mar 6, 2026
e3a8ebd
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Mar 6, 2026
311d47d
linting
fxmarty-amd Mar 6, 2026
74e6eec
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Mar 6, 2026
bf46483
use a single global scale for a2 in MOE, following flashinfer default…
fxmarty-amd Mar 6, 2026
0b47522
do not modify test_blackwell_moe
fxmarty-amd Mar 6, 2026
4a5c5c1
fix test and typo
fxmarty-amd Mar 6, 2026
6ed0611
fix typo
fxmarty-amd Mar 6, 2026
80a37f6
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Mar 6, 2026
35c88a8
simplify test
fxmarty-amd Mar 6, 2026
d439e80
remove outdated comment
fxmarty-amd Mar 6, 2026
2d9e65c
Merge branch 'main' into upstream-nvfp4-simulation-support-rocm
fxmarty-amd Mar 24, 2026
c6791f7
address Michael's comments
fxmarty-amd Mar 26, 2026
1fa136e
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Mar 30, 2026
56dd2bf
Merge branch 'main' into upstream-nvfp4-simulation-support-rocm
fxmarty-amd Apr 1, 2026
ad93d2a
linting
fxmarty-amd Apr 1, 2026
0d788d8
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Apr 1, 2026
e8a596f
Update vllm/model_executor/layers/quantization/compressed_tensors/sch…
fxmarty-amd Apr 1, 2026
c6adfe8
Update vllm/model_executor/layers/quantization/compressed_tensors/sch…
fxmarty-amd Apr 1, 2026
e36296a
move unsupported reasons warning in is_backend_supported
fxmarty-amd Apr 1, 2026
33f118f
Merge branch 'upstream-nvfp4-simulation-support-rocm' of https://gith…
fxmarty-amd Apr 1, 2026
44aadca
fix input
fxmarty-amd Apr 1, 2026
3f36269
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Apr 2, 2026
911b316
addres Michael's comments
fxmarty-amd Apr 2, 2026
90a54e3
simulation -> emulation
fxmarty-amd Apr 2, 2026
74b9212
linting
fxmarty-amd Apr 2, 2026
d930b84
Merge branch 'main' into upstream-nvfp4-simulation-support-rocm
fxmarty-amd Apr 2, 2026
24ec4ce
pre-commit passes locally and should not take 50min
fxmarty-amd Apr 2, 2026
58439aa
Merge branch 'upstream-nvfp4-simulation-support-rocm' into upstream-n…
fxmarty-amd Apr 3, 2026
8e61be3
Merge branch 'main' into upstream-nvfp4-simulation-support-moe
fxmarty-amd Apr 8, 2026
f2204ce
refactor OCP MX MOE emulation and address comment about moe_kernel_qu…
fxmarty-amd Apr 8, 2026
ca07f68
move to experts subfolder
fxmarty-amd Apr 8, 2026
223c275
simplifications
fxmarty-amd Apr 9, 2026
d8e9283
linting
fxmarty-amd Apr 9, 2026
1e1d139
Merge branch 'main' into upstream-nvfp4-simulation-support-moe
fxmarty-amd Apr 9, 2026
3663f59
fix quant_dtype
fxmarty-amd Apr 9, 2026
adfb9da
precise comment about maybe_roundup_sizes
fxmarty-amd Apr 13, 2026
9513361
add Qwen3-30B-A3B-NVFP4, Qwen3.5-35B-A3B-MXFP4-TP2 to gfx942 tests
fxmarty-amd Apr 13, 2026
c06e387
Merge branch 'main' into upstream-nvfp4-simulation-support-moe
fxmarty-amd Apr 13, 2026
df32bf3
Merge branch 'upstream-nvfp4-simulation-support-moe' of https://githu…
fxmarty-amd Apr 13, 2026
4e7ab24
Merge branch 'main' into upstream-nvfp4-simulation-support-moe
fxmarty-amd Apr 15, 2026
bfc4f90
address comment
fxmarty-amd Apr 15, 2026
1e914e9
Merge branch 'main' into upstream-nvfp4-simulation-support-moe
fxmarty-amd Apr 16, 2026
b292c90
address michael's comment
fxmarty-amd Apr 17, 2026
445809e
use dummy load_format
fxmarty-amd Apr 20, 2026
fd03157
Merge branch 'main' into upstream-nvfp4-simulation-support-moe
fxmarty-amd Apr 20, 2026
232d855
Merge branch 'main' into upstream-nvfp4-simulation-support-moe
fxmarty-amd Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions tests/models/quantization/test_nvfp4.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,22 @@ def test_models(example_prompts, model_name) -> None:
EAGER = [True, False]


@pytest.mark.skipif(
not current_platform.has_device_capability(100),
reason="modelopt_fp4 is not supported on this GPU type.",
)
if not current_platform.has_device_capability(100):
TEST_NVFP4_BACKENDS = ["emulation"]
else:
TEST_NVFP4_BACKENDS = [
"emulation",
"flashinfer-cudnn",
"flashinfer-trtllm", # the small seq_len ensures trtllm_8x4_layout backend is used
"flashinfer-cutlass",
]


@pytest.mark.parametrize("model", ["nvidia/Llama-3.1-8B-Instruct-NVFP4"])
@pytest.mark.parametrize("eager", EAGER)
@pytest.mark.parametrize(
"backend",
[
"flashinfer-cudnn",
"flashinfer-trtllm", # the small seq_len ensures trtllm_8x4_layout backend is used
"flashinfer-cutlass",
],
TEST_NVFP4_BACKENDS,
)
def test_nvfp4(vllm_runner, model, eager, backend, monkeypatch):
monkeypatch.setenv("VLLM_NVFP4_GEMM_BACKEND", backend)
Expand Down
89 changes: 84 additions & 5 deletions tests/quantization/test_blackwell_moe.py
Comment thread
fxmarty-amd marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@
from tests.utils import RemoteOpenAIServer
from vllm.platforms import current_platform

if not current_platform.is_device_capability_family(100):
pytest.skip(
"This test only runs on Blackwell GPUs (SM10x).", allow_module_level=True
)


@pytest.fixture(scope="module", autouse=True)
def set_test_environment():
Expand Down Expand Up @@ -84,6 +79,10 @@ def can_initialize(
"'list'."
)
)
@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_llama4_fp8_tensor_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/Llama-4-Scout-17B-16E-Instruct-FP8",
Expand All @@ -92,6 +91,10 @@ def test_llama4_fp8_tensor_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPatc
)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_llama4_fp8_tensor_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/Llama-4-Scout-17B-16E-Instruct-FP8",
Expand All @@ -100,6 +103,10 @@ def test_llama4_fp8_tensor_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch
)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_llama4_nvfp4_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/Llama-4-Scout-17B-16E-Instruct-FP4",
Expand All @@ -108,6 +115,10 @@ def test_llama4_nvfp4_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPatch):
)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_llama4_nvfp4_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/Llama-4-Scout-17B-16E-Instruct-FP4",
Expand All @@ -116,9 +127,21 @@ def test_llama4_nvfp4_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
)


def test_llama4_nvfp4_moe_emulation(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/Llama-4-Scout-17B-16E-Instruct-FP4",
hf_overrides=HF_OVERRIDE_MM,
extra_args=["--moe-backend=emulation", "--gpu-memory-utilization", "0.8"],
)


## DeepSeekV3 ##


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_deepseek_fp8_block_moe_deep_gemm(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"deepseek-ai/DeepSeek-V3.1",
Expand All @@ -141,6 +164,10 @@ def test_deepseek_fp8_block_moe_vllm_triton(monkeypatch: pytest.MonkeyPatch):
"Expected failure: assert self.block_quant is None"
)
)
@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_deepseek_fp8_block_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"deepseek-ai/DeepSeek-V3.1",
Expand All @@ -149,6 +176,10 @@ def test_deepseek_fp8_block_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPat
)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_deepseek_fp8_block_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"deepseek-ai/DeepSeek-V3.1",
Expand All @@ -157,6 +188,10 @@ def test_deepseek_fp8_block_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatc
)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_deepseek_nvfp4_moe_flashinfer_vllm(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/DeepSeek-R1-0528-FP4-v2",
Expand All @@ -165,6 +200,10 @@ def test_deepseek_nvfp4_moe_flashinfer_vllm(monkeypatch: pytest.MonkeyPatch):
)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_deepseek_nvfp4_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/DeepSeek-R1-0528-FP4-v2",
Expand All @@ -173,6 +212,10 @@ def test_deepseek_nvfp4_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPatch):
)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_deepseek_nvfp4_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/DeepSeek-R1-0528-FP4-v2",
Expand All @@ -184,16 +227,28 @@ def test_deepseek_nvfp4_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
## GPT-OSS ##


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_gptoss_mxfp4bf16_moe_flashinfer(monkeypatch: pytest.MonkeyPatch):
monkeypatch.setenv("VLLM_USE_FLASHINFER_MOE_MXFP4_BF16", "1")
can_initialize("openai/gpt-oss-20b", hf_overrides=HF_OVERRIDE_TEXT)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_gptoss_mxfp4mxfp8_moe_flashinfer_cutlass(monkeypatch: pytest.MonkeyPatch):
monkeypatch.setenv("VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8_CUTLASS", "1")
can_initialize("openai/gpt-oss-20b", hf_overrides=HF_OVERRIDE_TEXT)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_gptoss_mxfp4mxfp8_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
monkeypatch.setenv("VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8", "1")
can_initialize("openai/gpt-oss-20b", hf_overrides=HF_OVERRIDE_TEXT)
Expand All @@ -210,6 +265,10 @@ def test_gptoss_eager(monkeypatch: pytest.MonkeyPatch):
## Qwen3 Next ##


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_qwen3_next_bf16_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"Qwen/Qwen3-Next-80B-A3B-Instruct",
Expand All @@ -221,6 +280,10 @@ def test_qwen3_next_bf16_moe_flashinfer_trtllm(monkeypatch: pytest.MonkeyPatch):
## NemoTron ##


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_nemotron_fp8_moe_flashinfer_throughput(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-FP8",
Expand All @@ -236,6 +299,10 @@ def test_nemotron_fp8_moe_flashinfer_throughput(monkeypatch: pytest.MonkeyPatch)
"no act_and_mul MLP layer."
)
)
@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_nemotron_fp8_moe_flashinfer_latency(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-FP8",
Expand All @@ -251,6 +318,10 @@ def test_nemotron_fp8_moe_flashinfer_latency(monkeypatch: pytest.MonkeyPatch):
"no act_and_mul MLP layer."
)
)
@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_nemotron_fp8_moe_vllm_triton(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-FP8",
Expand All @@ -259,6 +330,10 @@ def test_nemotron_fp8_moe_vllm_triton(monkeypatch: pytest.MonkeyPatch):
)


@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_nemotron_fp4_moe_flashinfer_throughput(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-NVFP4",
Expand All @@ -274,6 +349,10 @@ def test_nemotron_fp4_moe_flashinfer_throughput(monkeypatch: pytest.MonkeyPatch)
"hidden_dim % 512 != 0."
)
)
@pytest.mark.skipif(
not current_platform.is_device_capability_family(100),
reason="This test only runs on Blackwell GPUs (SM10x).",
)
def test_nemotron_fp4_moe_flashinfer_latency(monkeypatch: pytest.MonkeyPatch):
can_initialize(
"nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-NVFP4",
Expand Down
5 changes: 1 addition & 4 deletions tests/quantization/test_compressed_tensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,6 @@ def check_model(model):
assert output


@pytest.mark.skipif(
not current_platform.is_cuda(), reason="This test is skipped on non-CUDA platform."
)
@pytest.mark.parametrize(
"args",
[
Expand Down Expand Up @@ -671,7 +668,7 @@ def check_model(model):
assert qkv_proj.scheme.group_size == 16

llm.apply_model(check_model)
output = llm.generate_greedy("Hello my name is", max_tokens=4)
output = llm.generate_greedy(["Hello my name is"], max_tokens=4)
print(output)
assert output

Expand Down
6 changes: 5 additions & 1 deletion vllm/config/kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"flashinfer_cutedsl",
"marlin",
"aiter",
"emulation",
]


Expand All @@ -40,7 +41,10 @@ class KernelConfig:
- "flashinfer_cutlass": Use FlashInfer with CUTLASS kernels\n
- "flashinfer_cutedsl": Use FlashInfer with CuteDSL kernels (FP4 only)\n
- "marlin": Use Marlin kernels (weight-only quantization)\n
- "aiter": Use AMD AITer kernels (ROCm only)"""
- "aiter": Use AMD AITer kernels (ROCm only)
- "emulation": use BF16/FP16 GEMM, dequantizing weights and
running QDQ on activations.
"""

@field_validator("moe_backend", mode="before")
@classmethod
Expand Down
3 changes: 3 additions & 0 deletions vllm/envs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1405,6 +1405,8 @@ def _get_or_set_default() -> str:
# - "flashinfer-trtllm": use flashinfer trtllm GEMM backend
# - "flashinfer-cutlass": use flashinfer cutlass GEMM backend
# - "marlin": use marlin GEMM backend (for GPUs without native FP4 support)
# - "emulation": use BF16/FP16 GEMM,
# dequantizing weights and running QDQ on activations.
# - <none>: automatically pick an available backend
"VLLM_NVFP4_GEMM_BACKEND": env_with_choices(
"VLLM_NVFP4_GEMM_BACKEND",
Expand All @@ -1415,6 +1417,7 @@ def _get_or_set_default() -> str:
"flashinfer-cutlass",
"cutlass",
"marlin",
"emulation",
],
),
# Controls garbage collection during CUDA graph capture.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project

import flashinfer

import torch

import vllm.model_executor.layers.fused_moe.modular_kernel as mk
Expand Down Expand Up @@ -157,6 +157,8 @@ def apply(
expert_tokens_meta: mk.ExpertTokensMetadata | None,
apply_router_weight_on_input: bool,
):
import flashinfer

assert activation in [MoEActivation.SILU, MoEActivation.RELU2_NO_MUL]
assert a1q_scale is not None
assert self.quant_config.w1_scale is not None
Expand Down Expand Up @@ -271,6 +273,8 @@ def apply(
routed_scaling_factor: float | None = None,
topk_group: int | None = None,
) -> torch.Tensor:
import flashinfer

assert activation in [MoEActivation.SILU, MoEActivation.RELU2_NO_MUL]
assert a1q_scale is not None
assert self.quant_config.w1_scale is not None
Expand Down
3 changes: 3 additions & 0 deletions vllm/model_executor/layers/fused_moe/fused_moe.py
Original file line number Diff line number Diff line change
Expand Up @@ -1932,6 +1932,7 @@ def __init__(
moe_config: FusedMoEConfig,
quant_config: FusedMoEQuantConfig,
):
self.emulation = False
Comment thread
fxmarty-amd marked this conversation as resolved.
Outdated
super().__init__(moe_config, quant_config)

@staticmethod
Expand Down Expand Up @@ -2130,6 +2131,8 @@ def apply(
self.quant_dtype,
self.per_act_token_quant,
self.block_shape,
emulation=self.emulation,
topk_ids=topk_ids,
)

invoke_fused_moe_triton_kernel(
Expand Down
Loading