Repository navigation
Allow prefill breakable CUDA graph for Qwen3.5 via multimodal opt-in allowlist - #30620
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for breakable CUDA graphs in specific multimodal model architectures, specifically Qwen 3.5 and Qwen 3.5 MoE. It adds a configuration property and helper function to identify supported architectures and updates the server arguments to allow breakable CUDA graphs for these allowlisted multimodal models. There are no review comments, and I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Oasis-Git
left a comment
There was a problem hiding this comment.
Could you add a CI test?
…allowlist The generic "multimodal model" rule in _disable_breakable_cudagraph_if_incompatible disables prefill BCG for every arch in multimodal_model_archs. Qwen3.5 (Qwen3_5[Moe]ForConditionalGeneration) is caught by it even for text-only serving, although its GDN/GQA prefill path fully supports BCG capture/replay. Mirror the existing tc_piecewise opt-in pattern (multimodal_piecewise_cuda_graph_supported_model_archs) with a BCG-specific allowlist. The replay-time guard is unchanged: batches carrying input_embeds/replace_embeds are rejected by can_run_graph and fall back to eager, so vision requests never replay the text-only graph. Add unit tests covering the rule (allowlisted arch keeps breakable, non-allowlisted multimodal arch is disabled) and allowlist membership.
46d66a5 to
3d3cf25
Compare
Sure — added a unit test for the gate logic: TestBreakableCudaGraphMultimodalAllowlist (allowlisted archs keep breakable; other multimodal archs still resolve to disabled).
E2E is already covered by existing CI — these run per-commit on B200 (base-c) with a gsm8k >= 0.95 gate, and neither sets any prefill CUDA-graph flag, so with this PR they run under BCG by default: The nightly FP8 suite picks it up as well: |
|
/tag-and-rerun-ci |
The captured prefill graph embeds from input_ids only; multimodal batches merge mm embeddings in the outer model wrapper, which graph capture bypasses, so replaying them silently drops image inputs (caught by test_vlm_tp4.py MMMU dropping to 0.50 vs the 0.65 threshold once the allowlist enabled BCG for Qwen3.5). can_run_graph already rejects input_embeds/replace_embeds batches; add the same rejection for batches carrying mm_inputs so they fall back to eager prefill, while text-only batches keep the captured graph. mm_inputs persists on the request until it finishes, so every prefill chunk of a multimodal request is covered.
|
/rerun-failed-ci |
|
/rerun-test test/registered/vlm/test_vlm_tp4.py test/registered/models_e2e/test_qwen35_fp4_flashinfer.py test/registered/models_e2e/test_qwen35_fp4_mtp.py test/registered/unit/server_args/test_server_args.py |
|
|
/rerun-test test/registered/vlm/test_vlm_tp4.py test/registered/models_e2e/test_qwen35_fp4_flashinfer.py test/registered/models_e2e/test_qwen35_fp4_mtp.py test/registered/unit/server_args/test_server_args.py |
|
Results for 🚀 🚀 🚀 |
Motivation
Since #29458, breakable CUDA graph (BCG) is the default prefill CUDA graph backend on CUDA, but the generic "multimodal model" rule in
_disable_breakable_cudagraph_if_incompatibleturns it off for every arch inmultimodal_model_archs. Qwen3.5 (Qwen3_5[Moe]ForConditionalGeneration) is caught by this rule even for text-only serving, although its GDN/GQA prefill path fully supports BCG capture/replay.The failure mode the rule protects against ("multimodal prefill replay faults") is real: the captured graph embeds from
input_idsonly, while multimodal batches merge mm embeddings in the outer model wrapper, which capture bypasses — replaying them silently drops image inputs. The existingcan_run_graphguard only coveredinput_embeds/replace_embeds; this PR extends it to batches carryingmm_inputs(caught bytest_vlm_tp4.pyMMMU dropping to 0.50 on the first CI run of this PR; multimodal batches now fall back to eager prefill, which is today's behavior).Modifications
Mirror the existing tc_piecewise opt-in pattern (
multimodal_piecewise_cuda_graph_supported_model_archs) with a BCG-specific allowlist:model_config.py: addmultimodal_breakable_cuda_graph_supported_model_archs(Qwen3.5 dense + MoE) and the correspondingModelConfigfield.server_args.py: the BCG "multimodal model" rule becomesis_multimodal and not is_multimodal_breakable_cuda_graph_supported.prefill_cuda_graph_runner.py:can_run_graphrejects batches carryingmm_inputs, so multimodal batches run eager prefill while text-only batches replay the graph.mm_inputspersists on the request until it finishes, so every prefill chunk of a multimodal request is covered.No behavior change for any arch not on the allowlist.
Accuracy Tests
Speed Tests and Profiling
Qwen3.5-397B-A17B-FP8, single node TP4 (GB200), 1k1k random dataset, closed-loop client (range-ratio 0.8, num-prompts 10×conc, request-rate inf). Server args follow the InferenceX/InferenceMAX qwen3.5 fp8 configs (
trtllm_mhaattention,flashinfer_trtllmMoE, fp8_e4m3 KV cache,--enable-symm-mem,--disable-radix-cache). "BCG off" = same build with--disable-prefill-cuda-graph, which is the effective status quo for Qwen3.5 today.EAGLE accept length is unchanged between the two arms (2.956 vs 2.931). One-time capture cost: ~41 s at startup, 1.83 GB per GPU (chunked-prefill 16384 bucket set).
Note: the numbers above were measured with #27918 (restores the fused Triton MRoPE path under BCG) applied on top; that fix is complementary and tracked separately.
Unit test
test/registered/unit/server_args/test_server_args.py::TestBreakableCudaGraphMultimodalAllowlistcovers the new rule (allowlisted arch keepsbreakable, non-allowlisted multimodal arch resolves todisabled) and allowlist membership. Verified together with the neighboringTestCudaGraphDisaggregationRoles: 7 passed.Checklist
CI States
Latest PR Test (Base): ✅ Run #29230286789
Latest PR Test (Extra): ❌ Run #29230286551