Repository navigation
[ROCm][Perf] Avoid extra reshape kernel in Qwen GDN output norm - #47842
Conversation
|
👋 Hi! Thank you for contributing to the vLLM project. 💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in PRs do not trigger a full CI run by default. Once the PR is approved and ready to go, your PR reviewer(s) can run CI to test the changes comprehensively before merging. To run CI, PR reviewers can either: Add If you have any questions, please reach out to us on Slack at https://slack.vllm.ai. Agent GuidelinesIMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban. 🚀 |
|
This pull request has merge conflicts that must be resolved before it can be |
|
Sorry for the noise here. I accidentally pushed a bad rebase/merge state while trying to sync this branch with main, which caused the huge diff and triggered the extra reviewers/labels. I’ve cleaned up the branch now, but unfortunately I can’t undo the notifications that were already sent 🙇 |
|
Commit 0ae4b45 is missing Signed-off-by. Can you rebase with --signoff and push? |
|
Would be good to add A/B perf and accuracy tests to this. |
A/B test results added in the description. |
|
/ci run |
|
✅ Triggered Buildkite CI #85995 for commit |
|
Oh, does this still depend on an AITER bump, @mjkvaak-amd? I thought that this should be merged, but then I started thinking about that. |
The output projection flattened its per-head tensors to (N*H, D) to normalise, then reshaped back through (N, H, D) to reach the (N, H*D) out_proj consumes. Inductor materialised that round trip as its own pointwise kernel, one per GDN layer per forward. Every caller already passes (N, H, D), so normalise as-is and flatten once. forward_xpu and forward_cpu now share the existing _output_projection helper. That alone breaks the AITER RMSNorm+quant fusion for GDN models with an FP8 block-scaled out_proj. The pattern matches on op structure rather than rank, so it still matches from (N, H, D) and then hands a 3D tensor to a fused op that takes (M, D), failing compilation. Collapse the heads in the replacement instead. Where quant_fp8 is decomposed, the quant's group reshape back to (N, H, D) is additionally a no-op that the compiler drops, so that case needs its own pattern variant traced with the node removed. Cover both layouts and both quant_fp8 modes in the fusion test. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Mikko Tukiainen <Mikko.Tukiainen@amd.com>
|
I found a bug in the fusion pass of RMSNorm with 3D layout + Changes:
The trace, serving sweep and GSM8K results in the description are unchanged and still describe this code @dllehr-amd apologies for invalidating the CI run on |
No AITER bump is needed. I marked this a draft, because I found a problem with RMSNorm and |
Guard the (N, H, D) GDN output-norm path against a flatten-to-2D regression, including a non-contiguous per-head z view, and lock the helper's (N, H*D) contract. Signed-off-by: Mikko Tukiainen <Mikko.Tukiainen@amd.com>
|
@dllehr-amd : Regarding our discussion and your recommendation to check whether the suggested changes affect CUDA detrimentally. CUDA is affected, but nothing breaks.
|
|
/ci run |
|
✅ @mjkvaak-amd, CI is now available for this PR.
|
|
❌ This PR is 561 commits behind upstream |
|
/ci run |
|
✅ Triggered Buildkite CI #90169 for commit |
ZJY0516
left a comment
There was a problem hiding this comment.
could you also test Qwen3-Next?
Tested
|
The opaque AITER quant path preserves a BF16 intermediate before FP8 quantization, while the fused kernel normalizes and quantizes directly. Use a slightly wider tolerance for that mode to account for the expected rounding difference after the FP8 GEMM. Signed-off-by: Mikko Tukiainen <Mikko.Tukiainen@amd.com>
|
/ci run |
|
✅ Triggered Buildkite CI #90205 for commit |
Purpose
Removes an extra Inductor-generated reshape/copy kernel, by reworking Qwen GDN
_output_projectionmethod.RMSNormGatedlogic now directly produces the flattened[num_tokens, hidden]tensor consumed byout_projwhich allows Inductor to pick.Test Plan
Run existing RMSNormGated tests, performance benchmark and GSM8K accuracy tests
Test Result
Serving benchmark on
amd/Qwen3.8-2.4T-A95B-Quark-MXFP4, 8x MI355X, TP8, fixed input/output lengths (--random-range-ratio 0), one run per point, measured against a stock build of the same commit.The change removes a small number of kernel launches per GDN layer per step, so the serving-level effect is under 1% as expected; the kernel-level evidence is the decode trace above.
GSM8K, 5-shot, seed 4321,
batch_size=128:No accuracy regression.
I also validated manually with profiler traces on Qwen3.5-397B that the extra GDN output reshape/copy kernel is now removed.

Baseline:
After the proposed fix:

Co-authored by: Cursor
Essential Elements of an Effective PR Description Checklist
supported_models.mdandexamplesfor a new model.