Repository navigation
[ROCm][Perf] Use AITER top-k for the DeepSeek-V3.2/GLM-5 sparse indexer - #61943
Merged
shen-shanshan merged 4 commits intoOct 19, 2026
Merged
Conversation
The ROCm sparse indexer only routes compressed indexers (compress_ratio > 1, e.g. DeepSeek-V4 C4A) to AITER's top-k. The uncompressed DSA indexer of DeepSeek-V3.2 and GLM-5 (k=2048) stays on the in-tree kernel, which has no gfx950 path for k=2048. On MI355X with GLM-5.2's indexer (32 heads, k=2048), AITER cuts decode top-k from 81 to 28 us per layer at 128K context. It wins or ties every measured decode shape except short contexts when max_model_len is in (128K, 200K], where it costs up to ~6 us per layer. Decode graphs cannot see the context length, so decode always takes AITER. Prefill runs eagerly and takes AITER once the longest row of a chunk reaches 32K tokens (e.g. 4.0 -> 2.6 ms per 16K-row chunk at 128K); shorter chunks, where AITER is slower, stay on the in-tree kernel. GLM-5.2-MXFP4, TP4, FP8 KV: 128K/1K TPOT -7.0%/-4.6%/-3.0% at c1/c8/c16, MTP3 128K c8 -3.0%, 8K/1K within noise; gsm8k and passkey unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: whx-sjtu <56632993+whx-sjtu@users.noreply.github.com>
whx-sjtu
marked this pull request as ready for review
October 16, 2026 02:53
whx-sjtu
requested review from
AndreasKaratzas,
WoosukKwon,
mgoin,
tjtanaa,
tlrmchlsmth,
yewentao256 and
zyongye
as code owners
October 16, 2026 02:54
6 tasks done
Fangzhou-Ai
approved these changes
Oct 16, 2026
Collaborator
|
/ci run |
|
✅ @whx-sjtu, CI is now available for this PR.
|
|
✅ Triggered Buildkite CI #95466 for commit ℹ️ This PR is 94 commits behind upstream |
Contributor
Author
|
/ci run |
|
✅ Triggered Buildkite CI #95519 for commit |
Contributor
Author
|
/ci run |
|
✅ Triggered Buildkite CI #95846 for commit |
shen-shanshan
approved these changes
Oct 19, 2026
whx-sjtu
added a commit
to whx-sjtu/vllm
that referenced
this pull request
Oct 27, 2026
Let `--attention-config '{"indexer_kv_dtype": "mxfp4"}'` serve the
DeepSeek-V3.2-style DSA models (GLM-5.x, DeepSeek-V3.2 and their MTP
drafts) on gfx950, reusing the paged MXFP4 indexer that DeepSeek-V4.1
already runs on: the model writes the indexer K cache in the page order
aiter's paged_mxfp4_mqa_logits reads, and the existing RocmSparseAttnIndexer /
RocmMxfp4IndexerMetadataBuilder score it in place for prefill and decode,
with the per-step decode schedule and native next_n rows for MTP.
- fused_norm_rope gains an MXFP4 cache write: the indexer key, after its
LayerNorm and RoPE, is quantized per 32 values (2^ceil(log2(amax/6))
e8m0 scales) and stored values-then-scales in RocmPagedMxfp4CacheLayout
order.
- fused_q can emit the index query as MXFP4 with its e8m0 bytes, leaving
the query scale out of the weights.
- The ROCm indexer cache sizes its row as 68 bytes and selects the new
DeepseekV32RocmMxfp4IndexerBackend (64/128-token pages; context
parallelism is rejected at startup).
FP8 stays the default. A token's indexer key shrinks from 132 to 68 bytes.
MI355X, TP4, FP8 KV, against the FP8 indexer with AITER top-k (vllm-project#61943):
GLM-5.2-MXFP4 KV cache +3.0% tokens; random 128K/1K TPOT -5.4% (c8),
-5.9% (c16), MTP3 c8 -6.8%, TTFT -7% to -8%; 128K c1 and 8K/1K within
noise; GSM8K 20-shot 0.9325 vs 0.9272, passkey unchanged. DeepSeek-V3.2:
KV cache +10.2% tokens, 128K/1K c8 TPOT -12.5%, c1 and 4K/1K c16 within
noise, GSM8K 5-shot 0.9575 vs 0.9515.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: whx-sjtu <56632993+whx-sjtu@users.noreply.github.com>
bantianyue
pushed a commit
to bantianyue/vllm
that referenced
this pull request
Oct 28, 2026
…er (vllm-project#61943) Signed-off-by: whx-sjtu <56632993+whx-sjtu@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: vllm-agent <claw@inferact.ai>
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.
Overview
On gfx950 with AITER enabled, the uncompressed sparse indexer of DeepSeek-V3.2 and GLM-5.x (
index_topk2048) now takes AITER's top-k for decode and for prefill chunks whose longest row reaches 32K tokens, through the adapters #52882 added for DeepSeek-V4. Related: #55327, #50470, #46172, #60012.Claims
--max-model-len 133120: 128K/1K TPOT -7.0% / -4.6% / -3.0% at c1 / c8 / c16, MTP3 c8 -3.0%; 8K/1K within noise; gsm8k and passkey unchanged.index_topk, GLM-5.3-Flash kpool, gfx942, AITER off and non-ROCm are unchanged.Validation
test_top_k_per_row.py, MI355X: 43 passed (8 new), 246 skipped, 1 failed as on main (pre-existing, see below). glm5next dispatch tests pass. pre-commit clean.Per-run numbers, kernel data and reproduction
Image
vllm/vllm-openai-rocm:nightly(AITER 0.1.25) running main at 7f730b4 and this branch from source, MI355X.GLM-5.2-MXFP4, mean TPOT per run (ms). Order: main, PR, PR, main, PR. A further main run between the two PR sessions was dropped: another process held about 88 GiB per GPU while it started, so its KV cache was 1.23M tokens instead of 3.2M. MTP3 order: main, PR, PR, main, PR, PR, main, main.
deepgemm_fp8_paged_mqa_logits(buffer poisoned past each row), prefill logits fromrocm_fp8_mqa_logits, calls mirroringrocm_aiter_sparse_attn_indexer; widths 133120 and 1M,next_n1 (1-D), 2 (native 2-D) and 4 (one row per token), packed multi-sequence prefill, and graph replay with new lengths. Every row hasmin(L, k)distinct indices in[0, L)followed by-1.DeepSeek-V3.2 (FP8 checkpoint), TP4, same env and flags but no
--max-model-len(163840), mean TPOT per run (ms), order main, PR, PR, main; median ITL and output throughput follow TPOT:Decode top-k per indexer layer (us, in-tree to AITER), GLM-5.2 indexer (32 heads, k=2048); scoring and top-k for 21 layers captured in one graph, LLC flushed before each replay, median of 20:
MTP1 (2-D bounds) and MTP3 (one row per token) follow the same pattern. At 262144 columns AITER wins at every measured context.
Prefill top-k GPU time per 16K-row chunk (us, in-tree to AITER): context 16K 304 to 370, 20K 426 to 469, 24K 568 to 558, 32K 757 to 680, 64K 1681 to 1320, 128K 4026 to 2635. 512-row chunks cross over near 20K. Host enqueue per call: in-tree 5-12 us, AITER 27-36 us.
Details
chunk.max_seqlen_k, a host int, reaches 32K.Design notes, pre-existing failure and related PRs
(B, next_n)bounds for native MTP1 and one row per token otherwise, soseq_lens.reshape(-1)withnext_n=1gives AITER each row's exact end. Prefill turns AITER's chunk-global indices into sequence-local ones and keeps-1.test_aiter_decode_topk_matches_per_row_under_mtp(from [ROCm][Perf][GLM-5.3-Flash] Add AITER topk backend for decodes #58167,requires_gfx950, so not in CI) fails identically on main: it passes(B, 1)seq_lens withnext_n=4to the in-tree k=512 gfx950 kernel, which reads any 2-Dseq_lensper row, so its reference rows are wrong. It does not reach the code changed here.next_n=2) is compatible because decode flattens the bounds.next_nwith its 2-D MTP bounds. On both, the author of [ROCm][Perf] Optimize DeepSeek V4 C4A top-k with AITER #52882 noted that AITER v0.1.19 needs those bounds adapted and asked to treat [ROCm][Perf] Optimize DeepSeek V4 C4A top-k with AITER #52882 as the consolidated direction; [ROCm][Perf] Optimize DeepSeek V4 C4A top-k with AITER #52882 then merged with AITER enabled for compressed indexers only. This PR applies its adapters to the k=2048 path, adds prefill and serving results, and leaves every other indexer unchanged. Theaiter.top_k_per_row_decodeentry point that [ROCm] Route sparse-indexer decode top-k through AITER dispatcher #50470 waited for ships in AITER 0.1.25 and is the function called here.gh pr list --state all --search: "aiter topk", "top-k ROCm", "topk ROCm", "indexer ROCm", "indexer aiter", "DeepSeek-V3.2 ROCm", "GLM-5 ROCm", "sparse indexer AMD", "top_k_per_row_decode", "top_k_per_row_prefill", "compress_ratio aiter topk".Not a duplicate: #50470 and #46172 target the same decode call, have been inactive since 2026-08-22, and were marked superseded by #52882's author; #52882 left k=2048 on the in-tree kernel (details above). Thanks @JH-Leon-KIM-AMD for #50470.
AI assistance (Claude) was used for the implementation, the measurements and this description.
Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.