From 59730555c3668ef87554eedccfa2842f0da886f2 Mon Sep 17 00:00:00 2001 From: derek Date: Sun, 19 Jul 2026 21:50:07 -0400 Subject: [PATCH] fix(moe): serialize hybrid resident-grid launches --- tests/quantization/test_nvfp4_nf3_hybrid.py | 8 ++++++++ .../layers/quantization/nvfp4_nf3_hybrid.py | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/quantization/test_nvfp4_nf3_hybrid.py b/tests/quantization/test_nvfp4_nf3_hybrid.py index 0bc56b80d53a..06b7cfe99397 100644 --- a/tests/quantization/test_nvfp4_nf3_hybrid.py +++ b/tests/quantization/test_nvfp4_nf3_hybrid.py @@ -8,6 +8,7 @@ from vllm.model_executor.layers.quantization import get_quantization_config from vllm.model_executor.layers.quantization.nvfp4_nf3_hybrid import ( NvFp4Nf3HybridConfig, + NvFp4Nf3HybridMoEMethod, _combined_tier_local_descriptors, _read_hybrid_keys, _unpack_nf3_codes, @@ -109,3 +110,10 @@ def test_grid188_tier_descriptors_encode_exact_partition(): def test_grid188_tier_descriptors_reject_incomplete_partition(): with pytest.raises(ValueError, match="does not cover all 256"): _combined_tier_local_descriptors({0: (0, 0)}) + + +@pytest.mark.parametrize("num_tokens", [1, 8, 256, 3072]) +def test_hybrid_moe_rejects_shared_expert_aux_stream(num_tokens): + method = object.__new__(NvFp4Nf3HybridMoEMethod) + + assert not method.supports_shared_experts_aux_stream(num_tokens) diff --git a/vllm/model_executor/layers/quantization/nvfp4_nf3_hybrid.py b/vllm/model_executor/layers/quantization/nvfp4_nf3_hybrid.py index b0ae89765d8e..8f90af3298a6 100644 --- a/vllm/model_executor/layers/quantization/nvfp4_nf3_hybrid.py +++ b/vllm/model_executor/layers/quantization/nvfp4_nf3_hybrid.py @@ -333,6 +333,16 @@ def __init__( super().__init__(moe_config) self.quant_config = quant_config + def supports_shared_experts_aux_stream(self, num_tokens: int) -> bool: + """The hybrid B12X launches must own the device while they run. + + Both the unified Grid188 decode and the per-tier fused fallback use + resident-grid software barriers. Concurrent shared-expert work can + occupy an SM needed by a barrier participant and deadlock the grid; + the resulting asynchronous fault may surface in a later CUDA op. + """ + return False + def maybe_make_prepare_finalize( self, routing_tables: tuple[torch.Tensor, torch.Tensor, torch.Tensor] | None = None,