[AMD] [GLM-5.3-Flash Day 0] Handle the zero-width RoPE tail in the ROCm MHA k concat - #38541
Closed
Raiden-Makoto wants to merge 3 commits into
Closed
Raiden-Makoto wants to merge 3 commits into
Raiden-Makoto wants to merge 3 commits into
Conversation
Raiden-Makoto
requested review from
Fridge003,
ch-wan,
fzyzcjy and
ispobock
as code owners
September 8, 2026 17:25
Raiden-Makoto
marked this pull request as draft
September 8, 2026 18:03
Raiden-Makoto
marked this pull request as ready for review
September 8, 2026 19:28
GLM-5.3-Flash's norope MLA layers set qk_rope_head_dim=0 and pass no RoPE tail, but _concat_and_cast_mha_k_rocm always allocates a qk_head_dim-wide buffer and appends k_pe. On the aiter backend the Triton concat kernel is handed a None/zero-width k_pe; on the fallback branch the slice assignment is a no-op that still costs an allocation and a copy. Mirror the CUDA path in forward_mha.py, which already returns k_nope directly when qk_rope_head_dim == 0. No cast is needed on ROCm because the concat branch keeps k_nope's dtype.
Raiden-Makoto
force-pushed
the
RM/reopen-37530
branch
from
September 8, 2026 19:41
fe4abb5 to
2dce440
Compare
This was referenced Sep 11, 2026
Closed
Contributor
Author
|
Closing this replacement because @Jacob0226 will reopen and maintain the original PR, #37530. Please continue review and CI there. |
Contributor
|
Thanks @Raiden-Makoto. Reopening as #39338 rather than #37530: #37530's base branch |
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
Replacement for #37530, which GitHub closed when its deleted support base was merged into main. The original author and review history remain credited there.
GLM-5.3-Flash's 11 full-attention layers are norope (
qk_rope_head_dim == 0), sok_pereaches_concat_and_cast_mha_k_rocmasNoneor zero-width while the helper still allocates aqk_head_dim-widekand appends it. #31531 split this helper out of the shared CUDA path on 2026-08-08, when no norope model existed and neither side carried a guard;0b9c384on this branch then added one to the CUDA twin_concat_and_cast_mha_konly. This restores parity.k_pecurrent_attention_backendNoneaiterconcat_and_cast_mha_k_tritonhanded aNonerope tensorNonek[..., qk_nope_head_dim:] = k_peraisesaiternew_empty+ onek_nope-sized copy per callScope
forward_mha_rocm.pyonly. CUDA and every other backend are untouched. ROCm models withqk_rope_head_dim > 0— DeepSeek V3/R1, the roped GLM-5.x MLA layers — never reach the guard and keep current behaviour. No new environment variable, no architecture gate, no dispatch change.k_pewidens totorch.Tensor | Noneto match the CUDA signature.On MI355X this is the default short-prefill path, not an edge case:
handle_attention_dsabackend.use_mhaHybridLinearAttnBackend.use_mhaDeepseekSparseAttnBackend.set_dsa_prefill_implTrueon_IS_GFX95, listed beside SM90/SM100, whenmax_kv_len <= SGLANG_DSA_PREFILL_DENSE_ATTN_KV_LEN_THRESHOLD(2048)resolve_rocm_forward_methodMHA_ONE_SHOT→MHA_ONE_SHOT_ROCMforward_normal_one_shot_rocm_prepare_concat_and_cast_mha_k_rocm(k_nope, k_pe)kin the KV-pool dtype forfa3on an FP8 KV cache; the ROCm branch isk_nope.new_empty(*k_shape)with no override, sok_nope.contiguous()is dtype-identical to what it would have builtTest plan
Combined main-based integration (
RM/glm53-day0-main-integrationtested at9d0d62b744; current integration head4e2f84ff3c; TP8/TP4 validation predates the above-cap guard, whose below-cap path is unchanged, pinned AITERd9e5ef7ce0, fresh caches): TP8 GSM8K 97.50% in 87.0s with 0.00% errors; TP4 GSM8K 96.97% in 320.2s with 0.00% errors. Decode CUDA graphs were enabled in both runs.Recovery base:
main@30e7a3072d.Recovery validation on MI355X: scoped pre-commit passed; 7 unit tests passed.
rocm/sgl-dev:v0.5.18-rocm720-mi35x-20260901, the image familypr-test-amd-rocm720.ymlresolves to, onxinyuan/glm-5.3-flash-support@515e865189with no other PRs applied. Both builds run the same test file; the guard is the only variable.cd test && python3 registered/unit/models/test_nope_mha_k_cast.py.Nonecases and zero-width onaiterfailZero-width on the non-
aiterbackend passes either way, per the Summary table's last row; it is kept so both backends are pinned to one behaviour rather than one of them resting on that accident.register_cpu_ci(suite="base-a-test-cpu"), unchanged — the four cases are mocked and GPU-free, and this change removes a kernel call rather than adding one, so there is no gfx950 work for an AMD-suite test to coverpre-commitvalidate registered test CI registriesCI States
Latest PR Test (Base): ⏳ Run #34768725511
Latest PR Test (Extra): ❌ Run #34768725378
Latest PR Test (AMD ROCm 10): ❌ Run #34768725524