[Bugfix] Guard DeepSeek V4 MRV1 piecewise CUDA graphs (#51768)

Signed-off-by: Woosuk Kwon <woosuk@inferact.ai> Co-authored-by: OpenAI Codex <codex@openai.com>

Woosuk Kwon committed Aug 11, 2026 at 07:34 UTC 87668ab69b3e2c849a607ece36e8a43bde7c7ee5
2 files changed +73
tests/test_config.py
+47
@@ -66,6 +66,43 @@ def test_v2_model_runner_env_tri_state(monkeypatch, env_value, expected):
66 assert envs.VLLM_USE_V2_MODEL_RUNNER is expected
67
68
69 +@pytest.mark.parametrize(
70 + "cudagraph_mode",
71 + [CUDAGraphMode.PIECEWISE, CUDAGraphMode.FULL_AND_PIECEWISE],
72 +)
73 +def test_deepseek_v4_rejects_mrv1_piecewise_cudagraph(cudagraph_mode):
74 + config = SimpleNamespace(
75 + use_v2_model_runner=False,
76 + model_config=SimpleNamespace(architectures=["DeepseekV4ForCausalLM"]),
77 + compilation_config=SimpleNamespace(cudagraph_mode=cudagraph_mode),
78 + )
79 +
80 + with pytest.raises(ValueError, match="DeepSeek V4 does not support PIECEWISE"):
81 + VllmConfig._validate_mrv1_piecewise_cudagraph(config)
82 +
83 +
84 +@pytest.mark.parametrize(
85 + ("use_v2_model_runner", "architecture", "cudagraph_mode"),
86 + [
87 + (True, "DeepseekV4ForCausalLM", CUDAGraphMode.PIECEWISE),
88 + (False, "DeepseekV4ForCausalLM", CUDAGraphMode.NONE),
89 + (False, "DeepseekV4ForCausalLM", CUDAGraphMode.FULL),
90 + (False, "DeepseekV4ForCausalLM", CUDAGraphMode.FULL_DECODE_ONLY),
91 + (False, "LlamaForCausalLM", CUDAGraphMode.PIECEWISE),
92 + ],
93 +)
94 +def test_mrv1_piecewise_cudagraph_allowed(
95 + use_v2_model_runner, architecture, cudagraph_mode
96 +):
97 + config = SimpleNamespace(
98 + use_v2_model_runner=use_v2_model_runner,
99 + model_config=SimpleNamespace(architectures=[architecture]),
100 + compilation_config=SimpleNamespace(cudagraph_mode=cudagraph_mode),
101 + )
102 +
103 + VllmConfig._validate_mrv1_piecewise_cudagraph(config)
104 +
105 +
106 @pytest.mark.parametrize(
107 ("use_v2_model_runner", "expected_capture_sizes"),
108 [
@@ -179,6 +216,16 @@ def test_resolve_cudagraph_mode_adjusts_spec_decode_sizes_only_for_v1(
216 ),
217 True,
218 ),
219 + (
220 + SimpleNamespace(
221 + model="deepseek-ai/DeepSeek-V4-Flash",
222 + architectures=["DeepseekV4ForCausalLM"],
223 + runner_type="generate",
224 + is_moe=True,
225 + is_quantized=True,
226 + ),
227 + True,
228 + ),
229 (
230 SimpleNamespace(
231 model="Qwen/Qwen1.5-MoE-A2.7B",
vllm/config/vllm.py
+26
@@ -66,9 +66,14 @@ else:
66
67 logger = init_logger(__name__)
68
69 +MRV1_UNSUPPORTED_PIECEWISE_CUDAGRAPH_ARCHITECTURES = frozenset(
70 + {"DeepseekV4ForCausalLM"}
71 +)
72 +
73 DEFAULT_V2_MODEL_RUNNER_ARCHITECTURES = frozenset(
74 {
75 "DeepseekV2ForCausalLM",
76 + "DeepseekV4ForCausalLM",
77 "GraniteMoeForCausalLM",
78 "InklingForCausalLM",
79 "InklingForConditionalGeneration",
@@ -702,6 +707,25 @@ class VllmConfig:
707 return False
708 return is_default_v2_architecture or not model_config.is_moe
709
710 + def _validate_mrv1_piecewise_cudagraph(self) -> None:
711 + if self.use_v2_model_runner:
712 + return
713 + model_config = self.model_config
714 + if model_config is None:
715 + return
716 + if not self.compilation_config.cudagraph_mode.has_piecewise_cudagraphs():
717 + return
718 + architectures = getattr(model_config, "architectures", [])
719 + if any(
720 + arch in MRV1_UNSUPPORTED_PIECEWISE_CUDAGRAPH_ARCHITECTURES
721 + for arch in architectures
722 + ):
723 + raise ValueError(
724 + "DeepSeek V4 does not support PIECEWISE CUDA graphs with "
725 + "Model Runner V1. Use Model Runner V2 or disable PIECEWISE "
726 + "CUDA graphs."
727 + )
728 +
729 @property
730 def needs_dp_coordinator(self) -> bool:
731 """
@@ -1589,6 +1613,8 @@ class VllmConfig:
1613 "pipeline parallelism",
1614 )
1615
1616 + self._validate_mrv1_piecewise_cudagraph()
1617 +
1618 # final check of cudagraph mode after all possible updates
1619 if current_platform.is_cuda_alike():
1620 if (