[triton] Optimized Unified Attention for Gemma-4-31b#4044
Conversation
🏷️ CI GuideRuns automatically on every PR:
Extended tests (opt-in via labels):
|
44efba5 to
ab0f4b3
Compare
There was a problem hiding this comment.
Pull request overview
Retunes Triton unified-attention config selection in AITER to better handle Gemma-4’s larger head sizes (256/512) on CDNA (gfx950), addressing performance regressions and avoiding LDS-related decode failures without changing kernel math.
Changes:
- Adjust
select_2d_configprefill and decode heuristics forhead_size >= 256/512on non-RDNA targets (warps/stages/tile sizing). - Adjust
select_3d_configsplit-KV heuristics forhead_size >= 512(warps/stages and increased minimum segment count).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
op_tests/triton_tests/attention/test_unified_attention.py:580
- This parametrization doubles the already-large cartesian product of cases (head_size list grows from 2→4 values), which can make this test suite significantly slower and more resource-intensive. A straightforward way to keep coverage for 256/512 while limiting runtime is to couple (head_size, dtype combo) into a single parametrization so large head sizes run BF16-only, while smaller head sizes keep the broader dtype coverage.
@pytest.mark.parametrize("head_size", [64, 128, 256, 512])
@pytest.mark.parametrize("block_size", [16, 64])
@pytest.mark.parametrize("sliding_window", [None, 256])
@pytest.mark.parametrize(
"soft_cap",
[None, 50.0],
)
@pytest.mark.parametrize(
"num_blocks",
[2048, 32768],
)
@pytest.mark.parametrize(
"q_dtype, kv_dtype, out_dtype, use_q_descale, use_kv_descale, use_out_scale",
[
(torch.bfloat16, torch.bfloat16, torch.bfloat16, False, False, False),
(torch.bfloat16, e4m3_dtype, torch.bfloat16, False, True, False),
(e4m3_dtype, e4m3_dtype, torch.bfloat16, True, True, False),
(torch.float16, torch.float16, torch.float16, False, False, False),
],
)
|
@ROCm/team_aiter may I ask you to take a look at these changes please? Thank you in advance |
Motivation
On AMD CDNA4 (MI355X / gfx950), the vLLM Triton unified-attention backend was
significantly faster than AITER's
ROCM_AITER_UNIFIED_ATTNforgoogle/gemma-4-31B-it,and AITER's full-attention decode crashed outright with
OutOfResources. Gemma-4interleaves two large-head attention layers that fall outside the range the AITER configs
were tuned for (
head_dim ≤ 128):head_dimblock_sizenqpkv=8)nqpkv=2)This PR retunes
select_2d_config/select_3d_configfor these shapes. Changes areconfig-level only (
BLOCK_M,TILE_SIZE,num_warps,num_stages,MIN_SEGMENTS) —no compute-kernel logic is touched, so outputs stay bit-comparable. Result: AITER goes
from 2.3–5.6× slower (and crashing on decode due to reaching LDS limits) to parity-or-faster than the Triton
reference on every prefill/decode case, with full-attention decode fixed.
Technical Details
1. Full-attention prefill — eliminate accumulator spill (
select_2d_config)BLOCK_M 128 → 16,num_warps=4,num_stages=1,TILE_SIZE=64.acc[BLOCK_M, 512]atBLOCK_M=128needs128×512×4/(4×64) = 256 VGPR/lane— the entire architectural register file — forcing everything else to spill to scratch and pinning occupancy at the 4-wave floor.BLOCK_M=16cuts this 8× to 32 VGPR/lane and matches the MFMA M-tile exactly.TILE_SIZE=64= one full KV page per tile (best gather locality on a scattered pool); a 2nd stage would need 256 KB > 160 KB LDS, sonum_stages=1.2. Full-attention decode — fix LDS overflow + raise memory-level parallelism (
select_2d_config+select_3d_config)num_stages 2 → 1,num_warps 2 → 4. 3D split-KV:attn_warps 2 → 4,num_stages 2 → 1,MIN_SEGMENTS 8 → 16.HEAD=512, TILE=64, one KV tile pair is 128 KB; double-buffering requested ~270 KB > 160 KB → the crash.num_stages=1drops it to ~135 KB.MIN_SEGMENTS=16splits the tiny decode grid (e.g. 64 WGs → 1024 WGs) so the ~8 TB/s HBM is saturated instead of latency-exposed.3. Sliding-attention prefill — fill the grid (
select_2d_config)BLOCK_M 128 → 16,num_warps 4 → 2,num_stages 1 → 2,TILE_SIZE 64 → 32.nqpkv=2,BLOCK_M=128 → BLOCK_Q=64launched only ~0.28 WG/CU (GPU mostly idle).BLOCK_M=16 → BLOCK_Q=8raises this to ~2 WG/CU. The smallerHEAD=256tiles (32 KB pair) leave room fornum_stages=2prefetch, andTILE_SIZE=32= one page per tile.Test Plan
op_tests/triton_tests/attention/test_unified_attention.pyTest Result
Added tests for
head_dim256 and 512Benchmark Result
Validated on model
google/gemma-4-31B-itusing vLLM v0.22, table below contains total token throughputs (t/s)OutOfResourcesOutOfResourcesOutOfResourcesOutOfResourcesOutOfResourcesThis optimization allows user to use AITER's Unified attention kernel for Gemma-4-31b model and increases total token throughput in x1.05-x1.17 times in comparison with using triton unified attention from vLLM.
Submission Checklist