Repository navigation
Use the 128-row query tile for head_dim <= 128 on gfx950 - #6
Closed
jiaqiang-dot-liu wants to merge 11 commits into
Closed
jiaqiang-dot-liu wants to merge 11 commits into
jiaqiang-dot-liu wants to merge 11 commits into
Conversation
jiaqiang-dot-liu
force-pushed
the
perf/gfx950-extend-attention-tile-hd-le-128
branch
from
September 15, 2026 03:10
4bf3b30 to
f2d938c
Compare
jiaqiang-dot-liu
force-pushed
the
perf/gfx950-extend-attention-tile-hd-le-128
branch
from
September 16, 2026 11:24
f2d938c to
47d3d1a
Compare
…oject#42889) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… dropping it (sgl-project#43174) Co-authored-by: Hanming Lu <69857889+hanming-lu@users.noreply.github.com> Co-authored-by: xiezhq-hermann <xiezhq-hermann@users.noreply.github.com>
…ssion rewind (sgl-project#43183) Co-authored-by: Hanming Lu <69857889+hanming-lu@users.noreply.github.com> Co-authored-by: Joshua Deng <91448271+joshuadeng@users.noreply.github.com>
…ssors (sgl-project#43181) Co-authored-by: joshuadeng <joshuadeng@users.noreply.github.com>
…gl-project#42666) Co-authored-by: Kan Wu <kan.wu@radixark.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…per-character loop (sgl-project#43117) Co-authored-by: Mick Qian <mickqian@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The extend kernel only takes BLOCK_M=128 with 8 warps when 128 < head_dim <= 256; head dims 64 and 128 fall through to BLOCK_M=64 with 4 warps. Every workgroup streams the whole prefix, so the KV bytes read per call scale with the number of query tiles and doubling BLOCK_M halves them. BLOCK_M / num_warps = 16 rows per warp is exactly one MFMA tile at matrix_instr_nonkdim=16. Neither argument depends on the head dim being above 128, and 64 and 128 cover most dense models. BLOCK_N stays 64, so the KV sweep per query row and its online-softmax order are unchanged; BLOCK_M only groups more independent rows per program. Measured on MI355X (gfx950, ROCm 7.2, Triton 3.7.0): o_extend bitwise identical across 12 configurations, -45% to -54% at head_dim 64 and -19% to -24% at head_dim 128, head_dim 256 unchanged within run-to-run drift, and no VGPR spills introduced at any head dim.
jiaqiang-dot-liu
force-pushed
the
perf/gfx950-extend-attention-tile-hd-le-128
branch
from
October 9, 2026 06:07
47d3d1a to
42ac9cb
Compare
Owner
Author
|
Superseded by the upstream PR sgl-project#39808 (same 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.
Motivation
On gfx950 the extend-attention kernel only takes the 128-row query tile when
128 < head_dim <= 256:Every workgroup in this kernel streams the whole prefix, so the KV bytes read per call scale with the number of query tiles: doubling
BLOCK_Mhalves them. AndBLOCK_M / num_warps = 128 / 8 = 16rows per warp is exactly one MFMA tile atmatrix_instr_nonkdim=16, so the wider tile maps cleanly onto the hardware rather than leaving a partial tile.Neither part of that reasoning depends on the head dim being above 128. Head dims 64 and 128 — which cover most dense models, including the Llama family — are left on the narrow tile for no stated reason.
Modifications
Drop the lower bound on the condition:
BLOCK_Nstays at 64 in both branches, so the KV sweep per query row is unchanged and each row's online-softmax accumulates in the same order.BLOCK_Monly changes how many query rows a program handles, and rows are independent. The output is therefore expected to be bit-identical, and it is — see below. Other AMD architectures, CUDA, and head dims above 256 are untouched.Accuracy Tests
MI355X (gfx950), 256 CU, ROCm 7.2, torch 2.9.1, Triton 3.7.0.
B=32, H_Q=64, H_KV=8, bf16, causal, tensors from the repo's_build_batch.12 configurations, head_dim {64, 128, 256} × N_CTX {1024, 2048, 4096, 8192}, run before and after. Each run hashes its inputs as well as its
o_extend, so the output comparison is only accepted when the inputs provably matched.12/12 inputs identical, 12/12 outputs bitwise identical.
test/registered/attention/unittests/dense/test_triton.pyand.../swa/test_triton.py: 14 passed, 2 skipped, 55 subtests passed.Speed Tests
Minimum over 7 repetitions of
triton.testing.do_bench(warmup=100ms, rep=500ms, return_mode="median"), one idle GPU. The baseline sweep was run twice, before and after the patched sweep; maximum run-to-run drift was 0.33%.head_dim 64 —
BLOCK_M64 → 128head_dim 128 —
BLOCK_M64 → 128head_dim 256 — control, tile choice unchanged
All four control rows are inside the 0.33% drift, as they must be — the condition change cannot reach this head dim.
Register pressure
A wider query tile costs registers, and this file has a history of Triton 3.7 gfx950 spill regressions, so wall-clock alone is not enough. From the compiled AMDGCN at
N_CTX=4096:No VGPR spills appear at any head dim, the SGPR spill counts stay in the single digits and move in both directions, and head_dim 128 actually uses 18 fewer VGPRs on the wider tile. Nothing here resembles the scratch-spill regime that motivated the narrower tile for
Lq == 576.What this does not cover
gfx950 only, and kernel-level only — no end-to-end serving numbers. The change is gated on
_is_gfx95, so no other architecture is affected by construction.CI States
Latest PR Test (Base): ❌ Run #35090178559
Latest PR Test (Extra): ❌ Run #35090178192
Latest PR Test (AMD ROCm 10): ❌ Run #35090178552