[Bugfix][ROCm][CI] Restore the DeepSeek-V4 input GEMM override point - #51821
Merged
AndreasKaratzas merged 4 commits intoAug 13, 2026
Merged
AndreasKaratzas merged 4 commits into
AndreasKaratzas merged 4 commits into
Conversation
vllm-project#51430 removed DeepseekV4Attention._fused_wqa_wkv_gemm and inlined the call at its only call site. That method is the override point the ROCm attention layer implements: it preshuffles the fused_wqa_wkv weight in place at load time, so afterwards the weight can only be multiplied through AITER. With the call inlined, the input projection ran the plain linear over a shuffled weight and DeepSeek-V4 produced garbage on ROCm, scoring 0.0000 on the amd/DeepSeek-V4-Flash-NVFP4 GSM8K job. The removal also left the ROCm override falling back to a super() method that no longer existed. Restore the method on the base class and route the call site through it. The narrowed CUDA graph region from vllm-project#51430 is untouched. GSM8K on gfx950 at TP8 goes from 0.0000 to 0.953. Signed-off-by: Stefan Koncarevic <Stefan.Koncarevic@amd.com>
zyongye
approved these changes
Aug 12, 2026
Member
|
/ci run |
|
✅ Triggered Buildkite CI #83584 for commit |
Member
|
/ci run |
|
✅ Triggered Buildkite CI #83591 for commit |
Member
|
/ci run |
|
✅ Triggered Buildkite CI #83623 for commit |
zyp2014
pushed a commit
to zyp2014/vllm
that referenced
this pull request
Aug 21, 2026
…llm-project#51821) Signed-off-by: Stefan Koncarevic <Stefan.Koncarevic@amd.com> Co-authored-by: Andreas Karatzas <akaratza@amd.com>
khushali9
pushed a commit
to khushali9/vllm
that referenced
this pull request
Aug 29, 2026
…llm-project#51821) Signed-off-by: Stefan Koncarevic <Stefan.Koncarevic@amd.com> Co-authored-by: Andreas Karatzas <akaratza@amd.com> Signed-off-by: khushali9 <khushali.desai9@gmail.com>
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.
Purpose
The GSM8K accuracy job for
amd/DeepSeek-V4-Flash-NVFP4on gfx950 reports 0.0000 against athreshold of 0.92. It is not a near miss: the server comes up clean and then answers every one of
the questions with an unparsable run of repeated tokens, so the failure is in the numerics rather
than in the harness. A bisect over the window in which the job turned red lands on
79c865b, "[Perf] Narrow DeepSeek V4 eager CUDA graph region"
(#51430).
Alongside narrowing the graph region, that commit deleted
DeepseekV4Attention._fused_wqa_wkv_gemmand inlinedself.fused_wqa_wkv(hidden_states)[0]at itsonly call site. The deleted method is the override point the ROCm attention layer implements. On
ROCm the
fused_wqa_wkvweight is preshuffled in place when the model loads and its block scale iskept to the side, so the only thing that can multiply it correctly afterwards is AITER's
preshuffled-B GEMM. With the call inlined, the input projection of every attention layer runs the
plain linear over a shuffled weight, and the model produces garbage from the first layer on. The
same removal leaves the ROCm override's own fallback calling a
super()method that no longerexists, so any path that took the fallback would raise
AttributeError.Nothing about this is visible on CUDA, and the ROCm override still reads as if it were connected,
which is why the removal went through.
Relationship to the other #51430 follow-ups
Two open PRs address #51430, both for a different symptom on NVIDIA, and neither covers this one.
#51750 is an auto-generated full revert opened
after the B200 nightly saw GSM8K fall to 0.0432 with MTP acceptance collapsing to 4.1%; it would
undo this bug as a side effect, but it is still a draft and the author of #51430 has proposed a
narrower fix-forward instead. That fix-forward, #51768, attributes the NVIDIA failure to the legacy V1 model runner's breakable PIECEWISE CUDA graph path and guards that combination in
vllm/config/vllm.py, leaving the attention implementation exactly as #51430 left it. If #51768 isthe one that lands, ROCm stays broken.
The two failures are independent. This one does not need a model runner, a graph mode or MTP to
show up: it reproduces at compilation mode 0 with no graph captured, and at
FULL_DECODE_ONLY,which #51768 explicitly keeps allowed. It also cannot appear on CUDA, since nothing preshuffles the
weight there.
This is not an alternative to either of them. On CUDA the restored method computes exactly what the
inlined call computed, so this change is a no-op there and does nothing for the B200 failure —
#51768 is still needed for that. In the other direction, if #51750 lands after all, this one becomes
redundant and I will close it.
Searches for open PRs mentioning
fused_wqa_wkv, and for open PRs referencing #51430, turned upnothing else that restores this method.
The change
Restore
_fused_wqa_wkv_gemmon the base class as a plain call intofused_wqa_wkv, and send thecall site back through it. That is the whole change, eight lines. The narrowed CUDA graph region and
everything else from #51430 are untouched.
Test Plan
gfx950 (MI355X), with the model, server arguments and environment taken verbatim from
tests/evals/gsm8k/configs/DeepSeek-V4-Flash-NVFP4.yaml: tensor parallel 8, fp8 KV cache,compilation mode 3 with
FULL_DECODE_ONLY, AITER enabled. GSM8K at 8 shots, shortened to 400questions to keep the turnaround reasonable. The same evaluation was run before the change on the
unmodified checkout and after it.
To rule out the parts of #51430 that the title points at, the failure was also reproduced at tensor
parallel 1 and at compilation mode 0, where no graph is captured at all.
Test Result
Before the change, on current main, accuracy is 0.0000 with an invalid rate of 1.000 — no answer is
parsable. It stays 0.0000 at tensor parallel 1 and at compilation mode 0, so neither sharding nor
graph capture is what breaks it.
After the change, accuracy is 0.953 with an invalid rate of 0.000, comfortably above the 0.84 floor
the threshold and its tolerance imply. Reverting #51430 in full gives an equivalent result, which
confirms the method removal is the only part of that commit involved.
Essential Elements of an Effective PR Description Checklist
supported_models.mdandexamplesfor a new model.