[Perf] Narrow DeepSeek V4 eager CUDA graph region - #51430
Merged
Merged
Conversation
Co-authored-by: OpenAI Codex <codex@openai.com> Signed-off-by: Woosuk Kwon <woosuk@inferact.ai>
Assisted-by: OpenAI Codex Signed-off-by: Woosuk Kwon <woosuk@inferact.ai>
Assisted-by: OpenAI Codex Signed-off-by: Woosuk Kwon <woosuk@inferact.ai>
WoosukKwon
marked this pull request as ready for review
August 10, 2026 16:05
WoosukKwon
requested review from
dllehr-amd,
hongxiayang,
tjtanaa and
zyongye
as code owners
August 10, 2026 16:05
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
Collaborator
Author
|
/ci run |
|
✅ Triggered Buildkite CI #83167 for commit |
2 tasks
4 tasks
This was referenced Aug 13, 2026
njhill
added a commit
to njhill/vllm
that referenced
this pull request
Aug 14, 2026
vllm-project#51430 narrowed the DeepSeek V4 eager cudagraph region, which corrupts MRV1 output, and vllm-project#51768 responded by defaulting the model to MRV2 and rejecting MRV1 + PIECEWISE. That default costs ROCm, where MRV1 is still the faster runner for this model. Choose the region from the runner instead: MRV1 wraps the whole attention body in `_prepare_and_attn_eager`, restoring the pre-vllm-project#51430 region it needs, while MRV2 keeps the narrow region and its shorter TTFT. The nested `_sparse_indexer_and_attn` break runs inline, since `add_eager` clears `_capturing` first. MRV1 + PIECEWISE is then correct on every platform, so drop the rejection. CUDA still defaults to MRV2; ROCm defaults to MRV1 until MRV2 is competitive there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Nick Hill <nickhill123@gmail.com>
4 tasks
Fangzhou-Ai
added a commit
to Fangzhou-Ai/vllm
that referenced
this pull request
Aug 16, 2026
vllm-project#51430/vllm-project#51768 moved DSV4 to MRV2 and a narrow eager region. That is a large decode TPOT regression on ROCm. Default ROCm back to MRV1, wrap the full attention body in the eager break for MRV1 only, and drop the MRV1+PIECEWISE rejection. CUDA keeps MRV2 and the narrow region. Co-authored-by: Nick Hill <nickhill123@gmail.com> Co-authored-by: Cursor Grok 4.6 <cursoragent@cursor.com> Signed-off-by: fai <fangzhouai@gmail.com>
This was referenced Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Narrow the DeepSeek V4 eager CUDA graph region so attention input preparation remains captured, and organize the flow so the execution stages are visible in one linear
forwardmethod.The existing
attention_impleager break includes Q up-projection, fused Q normalization/RoPE/KV insertion, indexer input preparation, and MLA/indexer compression. This change moves those producer operations intoforwardand keeps only the sparse indexer operation plusforward_mqain the eager region.The final refactor removes the tuple-of-mostly-
Noneplumbing, gives the input-projection helper a descriptive name and explicit return type, and reuses the indexer's existingforwardmethod. It adds no net methods.This branch is synced with
mainatfac808b36f.Parallelism
This does not reduce stream parallelism relative to
main:fused_wqa_wkvplus three auxiliary streams for compressor KV score, indexer weights, and indexer compressor KV score.ROCm retains its existing sequential fallback.
Why this approach
An earlier DeepSeek V4 region-narrowing change was reverted after real-model output corruption. This version deliberately keeps
forward_mqaeager together with the sparse indexer instead of capturing the attention backend. Persistent eager scratch workspaces also keep the tensors consumed by the eager region address-stable.This mirrors the region boundary used by the DeepSeek V3.2 optimization while preserving the DeepSeek V4 attention execution boundary.
Duplicate-work check
I searched open vLLM PRs for
DeepSeek V4 CUDA graph,DeepSeek V4 eager attention,Narrow DeepSeek V4, andeager CUDA graph region DeepSeek. No other open PR implements this DeepSeek V4 eager-region narrowing. #51425 is the analogous DeepSeek V3.2 change and does not modify DeepSeek V4.Performance
DeepSeek-V4-Flash on 4x GB200, Rust frontend, FP8 KV cache, FP4 indexer cache, PIECEWISE breakable CUDA graphs, DeepGEMM mega-MoE, and MTP2.
Short-prefill TTFT uses 1,000 requests with 128 input tokens, 1 output token, and concurrency 1. Saturated throughput uses 4,096 requests with the same token lengths and concurrency 64. The comparison was run against
mainatb706fd162before the final sync.mainA same-session A/B of the readability-only refactor measured 19.889 ms before and 19.742 ms after for mean TTFT (-0.74%); P50 was 19.663 ms and 19.674 ms respectively. This indicates no regression from the structural cleanup.
Validation
pre-commit run --files vllm/models/deepseek_v4/attention.py vllm/models/deepseek_v4/nvidia/model.py vllm/models/deepseek_v4/amd/model.py.venv/bin/python -m pytest tests/v1/cudagraph/test_breakable_cudagraph.py -qReal-weight serving completed graph capture and all evaluation requests in both requested topologies. Both used MTP2 and otherwise identical serving/evaluator settings. The DP4/EP4 run used TP1, DP4, and expert parallel across all four GPUs.
Full GSM8K, 1,319 questions, 5-shot, seed 42, greedy decoding, 128 concurrent requests:
No evaluation requests failed. Raw samples and aggregate result JSON were retained for both runs.
AI assistance
This PR was developed with AI assistance. The human submitter reviewed the changed code and ran the validation and model evaluations listed above.