Repository navigation
[Perf][ROCm][ROCM_ATTN] Run large fp8 decode batches on the AITER asm paged attention - #3
Open
lishuoshuo-amd wants to merge 1 commit into
Open
lishuoshuo-amd wants to merge 1 commit into
lishuoshuo-amd wants to merge 1 commit into
Conversation
lishuoshuo-amd
force-pushed
the
perf/rocm-attn-aiter-asm-decode
branch
from
November 6, 2026 07:47
a412428 to
091e870
Compare
lishuoshuo-amd
changed the base branch from
base/main-fce61a05a
to
base/main-8af2080e7
November 6, 2026 07:47
lishuoshuo-amd
force-pushed
the
perf/rocm-attn-aiter-asm-decode
branch
from
November 6, 2026 08:11
091e870 to
8fcbf2a
Compare
lishuoshuo-amd
force-pushed
the
perf/rocm-attn-aiter-asm-decode
branch
from
November 6, 2026 08:49
8fcbf2a to
f9da43c
Compare
… paged attention ROCM_ATTN, the default ROCm backend for non-MLA models, runs every decode step through its HIP paged attention. With an fp8 KV cache and 16-token blocks its K/V blocks already match the layout the AITER asm decode reads, so pure-decode batches above 2 * CUs query heads call pa_fwd_asm with the ultra-precision kernel (GQA <= 8). Smaller batches, where the HIP kernel is as fast and more accurate, are unchanged. Signed-off-by: lishuoshuo-amd <shuoli@amd.com>
lishuoshuo-amd
force-pushed
the
perf/rocm-attn-aiter-asm-decode
branch
from
November 6, 2026 09:20
f9da43c to
68843ae
Compare
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
ROCM_ATTN, the default ROCm backend for non-MLA models, runs every decode step through its HIP paged attention, also with AITER enabled. With an fp8 KV cache and 16-token blocks its K/V blocks already match the layout of the AITER asm paged attention, so this PR runs large pure-decode batches on
pa_fwd_asmwith no KV relayout and keeps the HIP kernel for everything else. ROCM_AITER_FA already uses this kernel, but only when it is selected explicitly with the shuffled KV cache layout.Claims
VLLM_ROCM_USE_AITER=1,--kv-cache-dtype fp8: output throughput +4.2–6.3% at concurrency 64 and +6.2–8.8% at concurrency 128 on Qwen3-14B-FP8, Llama-3.1-8B-Instruct and Qwen3-8B at TP1, and +2.7–4.4% at TP2. Batches below the cut are unchanged (concurrency 1 and 8 everywhere, and 16 except Qwen3-14B at TP1, which already crosses it there: +2.4%).2 * num_compute_units()query heads (512 on MI355X), the cut AITER itself uses between its asm and HIP kernels, and only for GQA ratios up to 8, with the ultra-precision kernel (high_precision=2).Validation
MI355X, ROCm 10.0, AITER 0.1.27,
vllm/vllm-openai-rocm:nightly-rocm100-a2bcb5657a881a002e79d0adab3c6b5e39436121. In that imagerocm_attn.py,_aiter_ops.pyandplatforms/rocm.pymatch this PR's base8af2080e7exceptget_preferred_block_sizefrom vllm-project#63231, which only sets block size 16 for ROCM_ATTN, the size used here.Output tok/s, main -> this PR, fresh server per arm (n = 8 / 32 / 64 / 256 / 256 prompts at concurrency 1 / 8 / 16 / 64 / 128):
Median TPOT drops 4–11% at concurrency 64–128. Repeats agree: at TP1 concurrency 64 / 128, main ran 4852–4899 / 6024–6229 tok/s in four runs of Qwen3-14B-FP8 and the asm decode 5105–5115 / 6612–6635 in five (two at AITER's default precision, which runs at the same speed), and a second Llama pair gave +5.1% / +7.8%. One further PR run had host stalls (p99 ITL 79.7 ms against 15.5–17.1 ms in every other run) and is left out.
GSM8K, 1319 questions, 5-shot chat, greedy, 64 in flight so decode runs above the cut, Qwen3 thinking off; flexible match, mean over runs (each arm: two or three CUDA graph runs and one
--enforce-eagerrun):Passkey retrieval at 3K / 8K / 16K / 32K tokens (24 prompts, 30 in flight): 24/24 in every run, both arms, TP1 and TP2. At TP2, GSM8K is 0.8362 -> 0.8347 (Llama) and 0.9189 -> 0.9189 (Qwen3-14B-FP8).
VLLM_GPU_SYNC_CHECK=errorwith the asm path active (Llama-3.1-8B-Instruct at TP1: GSM8K plus the five concurrencies above; Qwen3-14B-FP8 at TP2: GSM8K): torch's sync debug mode is armed in every worker and no synchronization is reported, no tracebacks, GSM8K 0.8317 and 0.9204. main's Llama run under the same check is clean as well.Kernel latency, accuracy runs and kernel error
impl.forwardin a CUDA graph, µs per call, fp8 cache, all sequences at the given context length (asm at AITER's default precision; the serving runs showhigh_precision=2runs at the same speed):Below the cut, forcing asm is slower on long contexts (40/8, ctx 4096, 1–4 sequences: 20.0–20.6 µs against 8.0–10.7 µs), and AITER's HIP fallback is as fast as ROCM_ATTN's kernel but about 16x less accurate on an fp8 cache (mean absolute error 0.0056 against 0.00035 vs an fp32 reference).
Error vs an fp32 reference above the cut, 4 head layouts × 3 seeds, 1–4000 tokens, max / mean: HIP 0.0035–0.0072 / 0.00013–0.00018; asm at AITER's default precision 0.015–0.026 / 0.00076–0.00108; asm with
high_precision=20.015–0.026 / 0.00044–0.00078.GSM8K per run, flexible / strict:
high_precision=2)"main" includes runs of this branch with
VLLM_ROCM_USE_AITER_MHA=0, which turns the path off. Any attention numerics change moves many greedy outputs: main in eager mode against main with CUDA graphs leaves 27% (Qwen3-14B) and 50% (Llama) of the GSM8K outputs identical, and this PR against main 38% / 44% / 49%. At AITER's default precision the asm decode, including the shipped ROCM_AITER_FA path, is 0.2–0.9 points below main's mean in all six Qwen3-14B and Llama runs, which is why this PR asks for the ultra-precision kernel.Details
split_kv_cachegives K as[blocks, kv_heads, head_size / 16, 16, 16]and V as[blocks, kv_heads, head_size, 16]. With 16-token blocks that V is AITER's shuffled[blocks, kv_heads, block_size / 16, head_size, 16]with one group, sounsqueeze(2)is all the asm kernel needs; the interleaved V of the AITER fused RoPE + KV-cache writer has the same bytes.has_native_kv_cache_layoutis required because the kernel addresses pages by a dense page stride.[blocks, kv_heads, block_size]scales. The metadata builder maps each layer to a table filled with its per-tensor scale once the KV cache is bound, shaped by the KV cache group's spec rather than the model-wide head count, reusing ROCM_AITER_FA'sAsmKvScaleTables, so layers with equal scales share one allocation (K and V together about 0.08% of the KV cache for Qwen3-14B) andforwardreads nothing on the host.num_actual_tokens * num_heads, so each captured CUDA graph uses one kernel; both kernels are deterministic and batch-invariant on their own, but a request's kernel depends on how many others share its batch, as with AITER'spaged_attention_common. ROCM_ATTN does not claim batch invariance, soVLLM_BATCH_INVARIANT=1never selects it. Withhigh_precision=2AITER requires the ultra-precision kernel instead of falling back to the lowest-precision one;pa_asm.csvfor gfx942 and gfx950 has it (pa_bf16_pertokenFp8_gqa8_2tg_4w_uhp) for GQA up to 8 only, so larger ratios keep the HIP decode.rocm_aiter_ops.pa_fwd_asmgains ahigh_precisionargument with the old default, so ROCM_AITER_FA is unchanged.tests/kernels/attentionand depend onvllm/v1/attentionandvllm/_aiter_ops.py.Unverified: gfx942 / MI300X outside CI (same kernels, cut 608), TP > 2, GQA 9–16 models (unchanged by design), models other than the three above, and AITER versions other than 0.1.27.
Not a duplicate: no open or recent PR adds an asm decode to ROCM_ATTN (searched
rocm_attn pa_fwd_asm,ROCM_ATTN asm,ROCM_ATTN decode aiter,rocm_attn fp8 kv decode). AI assistance was used; the submitter reviewed every changed line and ran the tests above.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.
Powered by Hyperloom, with human review, writing and testing.