Skip to content

[Triton/Gluon] Improving GFX950 Unified Attention for spec. decode and reduce opimizations - #6336

Merged
vgokhale merged 9 commits into
mainfrom
mekaymak/ua_gluon_gfx950_specdecode_splitkv
Oct 12, 2026
Merged

vgokhale merged 9 commits into
mainfrom
mekaymak/ua_gluon_gfx950_specdecode_splitkv

Conversation

@cagrikymk

Copy link
Copy Markdown
Contributor

Motivation

Addressing #6221 and beyond.

Main improvements:

  • Improving split heuristics for cases, especially for small q situations (spec. decode)
  • Improving reduce (added chunking) to remove register spilling when head_size > 128
    (can be enabled via SEGMENT_BLOCK from the config for the reduce, 0 is the default full head size chunking)

Technical Details

Results

Issue shape: 32/2 heads, D=256, page 64, batch 1, fp8 (q/k/v descales)

q ctx max_seqlen_k Triton main Triton branch Gluon main Gluon branch Gluon branch / Triton branch
1 200 live 9.1 9.0 12.2 9.8 1.09
1 200 65536 (graph) 19.6 9.5 168.0 10.5 1.11
1 2000 live 10.2 10.0 11.2 11.0 1.10
1 2000 65536 (graph) 20.1 10.1 167.5 11.0 1.09
1 12000 live 23.8 14.1 71.6 14.2 1.01
1 12000 65536 (graph) 24.0 14.2 169.8 14.5 1.02
1 30000 live 27.5 18.5 168.0 18.7 1.01
1 30000 65536 (graph) 27.7 18.7 168.5 18.1 0.97
2 200 live 9.8 10.1 15.5 15.7 1.55
2 200 65536 (graph) 20.7 10.5 42.7 11.4 1.09
2 2000 live 11.4 11.3 65.9 12.3 1.09
2 2000 65536 (graph) 21.9 11.3 115.8 12.0 1.06
2 12000 live 28.7 18.6 516.4 17.0 0.91
2 12000 65536 (graph) 28.8 19.0 517.9 17.0 0.89
2 30000 live 36.2 26.1 1255.2 23.7 0.91
2 30000 65536 (graph) 36.9 26.8 1254.2 24.0 0.90
4 200 live 9.8 9.9 16.2 16.8 1.70
4 200 65536 (graph) 22.2 10.5 43.3 12.4 1.18
4 2000 live 13.1 13.1 66.7 14.3 1.09
4 2000 65536 (graph) 24.4 12.5 116.0 14.1 1.13
4 12000 live 36.0 24.4 519.0 21.1 0.86
4 12000 65536 (graph) 36.1 24.9 519.9 21.4 0.86
4 30000 live 46.5 36.7 1253.9 30.2 0.82
4 30000 65536 (graph) 47.3 37.6 1254.8 30.5 0.81

All 96 runs checked against the torch reference: max abs error 6.07e-03.

Against Triton main, Gluon on the branch is faster or level everywhere except q >= 2 at 200 tokens with live max_seqlen_k. There the batch stays on the unsplit 2d grid, same as main: 15.7 vs 9.8 us. Against Triton on the branch, which now has the faster reduce, Gluon is within about 10 % up to 2k context and 9-19 % faster for verify from 12k up.

Gluon backend, main vs branch (per shape/dtype over B 1-128, q 1/2/4, ctx 2k/30k, live/graph)

shape (q heads x kv heads x D) dtype cases geomean new/main faster >5 % slower >5 % best worst
32x2x256 fp8 48 0.33 29 2 0.02 1.06
32x2x256 bf16 48 0.43 28 4 0.03 1.13
16x2x256 fp8 48 0.31 29 0 0.02 1.02
16x2x256 bf16 48 0.39 32 2 0.03 1.08
8x1x128 fp8 48 0.31 35 0 0.03 1.00
8x1x128 bf16 48 0.39 27 0 0.03 1.02
64x8x128 fp8 48 0.62 16 0 0.06 1.03
64x8x128 bf16 48 0.69 16 0 0.11 1.04
32x4x128 fp8 48 0.50 27 0 0.04 1.04
32x4x128 bf16 48 0.61 16 0 0.07 1.04
64x8x64 fp8 48 0.58 16 0 0.04 1.04
64x8x64 bf16 48 0.65 16 1 0.08 1.07

…oken batches, chunked segment reduce

Fixes the gfx950 Gluon slowdowns reported in #6221 (speculative-decode verify
and decode with few KV heads).

- Batches of short queries (max_seqlen_q * queries_per_kv <= 128, no sliding
  window) take the split-KV grid when the kv_split config splits them. The
  query block is widened to hold every query of a sequence, so the split
  ranges match what reduce_segments assumes. Before, every such batch took the
  unsplit 2d grid: at batch 1 with 2 KV heads that is 2 programs walking the
  whole context.
- store_partial writes -inf as the max of a row that saw no key in its split.
- reduce_segments takes SEGMENT_BLOCK and merges the segments in chunks of
  that size with an online softmax. The single [NUM_SEGMENTS, head] tile spills
  at head size 256 and 512. 0 (default) keeps the single-tile code.
- gfx950 configs: kv_split caps the split at 128 for decode and 64 otherwise
  (vLLM full-graph capture passes max_model_len as max_seqlen_k, so the uncapped
  fp8 split reached 512); D >= 256 decode uses the KV double buffer; the Triton
  reduce section sets SEGMENT_BLOCK 32 for D >= 256.
…e single-tile reduce as on main

- gfx942 Triton reduce config: SEGMENT_BLOCK 32 for D > 128, as on gfx950. A
  D_LEQ_128 entry with the previous values keeps D <= 128 on the single tile.
- reduce_segments: the single-tile branch keeps main's op order, so an arch
  without SEGMENT_BLOCK compiles to the same instructions as before.
…56 entry, leave any as on main

Replaces the D_LEQ_128 entry and the SEGMENT_BLOCK on any with a D_GEQ_256
reduce entry (the previous any values plus SEGMENT_BLOCK 32), so head sizes
below 256 keep the single-tile reduce from main.
…block bound into _gfx950_split_grid, drop the new tests
@cagrikymk
cagrikymk requested a review from a team October 9, 2026 18:08
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

🏷️ CI Guide

Runs automatically on every PR:

  • ✅ Pre-checks (submodule verification, code formatting)
  • ✅ Aiter op tests (gfx942 + gfx950)
  • ✅ Triton tests on MI35X (only when aiter/ops/triton/** or related paths are changed)

Extended tests (opt-in via labels):

Label Tests
ci:gfx1250-ffm-triton Run the five-shard gfx1250 FFM Triton test suite
ci:triton-300x Run an additional Triton test job on MI300X in PRs (added automatically when gfx942 configs change); main branch always runs both MI35X and MI300X
ci:triton-355 Run the full Triton test suite on MI35X, not only the tests the change affects
ci:multi-gpu Aiter multi-GPU tests on the 8-GPU runner
ci:sglang SGLang integration tests: DeepSeek-R1-MXFP4 accuracy, Qwen 3.5 accuracy
ci:atom ATOM benchmark: DeepSeek-R1-0528, GPT-OSS-120B
ci:atom_full ATOM accuracy suite for PR and main models from ATOM models_accuracy.json
ci:vllm vLLM benchmark: GPT-OSS-120B, DeepSeek-R1-0528, Kimi-K2.5
ci:all All standard extended tests (excludes ci:atom_full)

Only add ci:atom_full for FlyDSL or Triton upgrades.
Add labels via the sidebar or gh pr edit 6336 --add-label <label>

One backend per PR:
A PR changes one kernel backend: [Triton/Gluon] (Triton and Gluon count as one), [HIP], [ASM], [CK], [OPUS] or [FlyDSL]. If the title ends up with two backend tags, split the PR -- as stacked pull requests when one part cannot merge without the other.

PR title tags & labels:
Component tags ([Triton/Gluon], [HIP], [CK], [ASM], ...) are added to the PR title and as PR labels automatically from the changed files and re-synced on every push — change-type tags like [fix]/[Perf], op tags like [MLA], and human labels (ci:*) are left untouched. Add the no-auto-title label to stop the title rewrites; labels stay in sync either way.

@github-actions github-actions Bot changed the title [TRITON][GLUON] Improving GFX950 Unified Attention for spec. decode and reduce opimizations [Triton/Gluon] Improving GFX950 Unified Attention for spec. decode and reduce opimizations Oct 9, 2026
@azaidy
azaidy requested a review from vgokhale October 9, 2026 18:51
@Boss2002n
Boss2002n requested a balanced review from Copilot October 10, 2026 04:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new routing and reduction paths need targeted coverage, and the kernel representation omits the new tuning key.

3 open findings
What changed in this PR

Improves unified attention for speculative decoding on GFX950 by refining split-KV routing and reducing register pressure.

Changes:

  • Routes undersubscribed multi-token Gluon workloads through split-KV.
  • Adds chunked Triton segment reduction.
  • Retunes GFX950 configurations and extends GFX942 reduction tuning.
File Description
configs/​gfx950/​triton/​attention/​unified_attention/​DEFAULT.json Enables chunked reduction.
configs/​gfx950/​gluon/​attention/​unified_attention/​DEFAULT.json Retunes kernels and split heuristics.
configs/​gfx942/​triton/​attention/​unified_attention/​DEFAULT.json Enables chunking for larger heads.
attention/​unified_attention.py Adds GFX950 split-grid routing.
_triton_kernels/​attention/​unified_attention.py Implements chunked segment reduction.
_gluon_kernels/​gfx950/​attention/​unified_attention.py Aligns split boundaries and handles empty partials.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@cagrikymk

Copy link
Copy Markdown
Contributor Author

Comparing #6339 vs this PR( #6336):

Cold cache: L2/MALL flushed each call, profiler device time

shape bf16 #6339 bf16 #6336 bf16 speedup fp8 #6339 fp8 #6336 fp8 speedup
spec b=8 x4 (32 tok), ctx 8k 34.0 25.0 1.36x 18.6 19.9 0.93x
spec b=8 x4 (32 tok), ctx 16k 56.0 40.4 1.39x 24.5 25.7 0.95x
spec b=8 x4 (32 tok), ctx 64k 204.8 123.2 1.66x 64.8 64.8 1.00x
spec b=8 x4 (32 tok), ctx 128k 429.5 196.2 2.19x 117.0 110.9 1.05x
spec b=32 x4 (128 tok), ctx 8k 112.4 69.0 1.63x 39.4 40.4 0.97x
spec b=32 x4 (128 tok), ctx 16k 193.4 120.4 1.61x 66.6 67.1 0.99x
spec b=32 x4 (128 tok), ctx 64k 867.2 374.5 2.32x 191.5 181.0 1.06x
spec b=32 x4 (128 tok), ctx 128k 1728.4 719.3 2.40x 333.8 319.3 1.05x
spec b=64 x4 (256 tok), ctx 8k 210.4 125.2 1.68x 70.0 69.9 1.00x
spec b=64 x4 (256 tok), ctx 16k 377.9 199.6 1.89x 122.5 117.4 1.04x
spec b=64 x4 (256 tok), ctx 64k 1368.9 716.5 1.91x 344.1 307.9 1.12x
spec b=64 x4 (256 tok), ctx 128k 2673.8 1399.3 1.91x 617.4 569.7 1.08x
spec b=128 x4 (512 tok), all ctx 212.9–2847.4 189.2–2335.6 1.12–1.22x 158.7–1976.8 113.3–1043.8 1.40–1.91x
decode b=8–128, all ctx (16 rows) 13.8–1296.0 14.2–1339.8 0.96–1.04x 16.1–667.1 15.6–668.2 0.99–1.04x
prefill 16k tokens 1099.5 1079.4 1.02x 756.9 761.5 0.99x
prefill 32k tokens 4255.6 4043.9 1.05x 2775.6 2717.1 1.02x
mixed 75% decode, b=8, 2048-tok prefill 795.4 703.8 1.13x 549.5 510.5 1.08x
mixed 75% decode, b=32, 1024-tok prefill 1290.9 1207.2 1.07x 846.4 850.7 0.99x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants