Repository navigation
[ROCm][gfx1151] ROCM_ATTN: HIP decode attention on gfx1151 - #1330
Closed
roberteg16 wants to merge 2 commits into
Closed
roberteg16 wants to merge 2 commits into
roberteg16 wants to merge 2 commits into
Conversation
roberteg16
force-pushed
the
rogarcia.gfx1151-rdna35-attn
branch
from
October 2, 2026 13:29
b69d9d7 to
ba84732
Compare
roberteg16
force-pushed
the
rogarcia.gfx1151-rdna35-attn
branch
2 times, most recently
from
October 2, 2026 18:26
74eca64 to
b8a382d
Compare
…ache The benchmark built its model config with dtype="auto" and ignored the requested dtype, so it ran the stand-in model's native bfloat16 whatever was asked: everything labelled fp16 was bf16. --dtype (float16 or bfloat16) now sets Q/K/V and the output, and the bfloat16 -> float16 cast warning that then fires once per cell is filtered (that message only, so a backend's fallback warning stays visible). BenchmarkConfig.sliding_window: the impl and the KV cache spec get the window, and the block table holds only the blocks some query's window reaches (the rest name the null block), as vLLM's sliding-window manager keeps a windowed layer, instead of the whole sequence. benchmark_fn walks one KV cache per layer and divides by the layer count, so whether a cell reads DRAM or a resident last-level cache depends on num_layers * kv_bytes_per_layer. On parts with a large one (Strix Halo's 32 MiB MALL, never flushed between CUDA-graph replays) a small model at a short context stays resident: TRITON_ATTN decode cells under 32 MiB read 35 % fast (median, worst 64 %), those over it 0 %. --min-working-set-mb raises --num-layers until the working set (the window, for a windowed layer) reaches the given size; it only raises, so cells already past the cache do not move. The README documents it. AI assistance was used for this patch. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Robert Esclapez Garcia <robert.garcia@amd.com>
On gfx1151 (Strix Halo, RDNA3.5) ROCM_ATTN serves decode, speculative
decode (M <= 8 query tokens per sequence) and the decodes of mixed
batches with a HIP WMMA kernel, and everything else with TRITON_ATTN's
kernels, on Triton's packed KV cache in the HND layout. It becomes the
default attention backend there, ahead of TRITON_ATTN. On every other
device ROCM_ATTN is unchanged.
Kernel (csrc/rocm/rdna35_decode_attn.cu, csrc/rocm/rdna35_attn/): one
workgroup per KV head, GQA-packed WMMA for Q@K and P@V in fp16 and bf16,
D in {64, 128, 256, 512}, full and sliding-window attention, split-KV
with the cross-workgroup merge done in-kernel, a dot-product mode for
short sequences, V staged in LDS so the next tile's loads overlap,
batched decode. Each configuration (heads, kv heads, D, M, window) is
tuned and compiled into _rocm_C as a variant (variants.def, written by
vllm/v1/attention/ops/rdna35_hip_decode.py from its tables;
cmake/rdna35_attn.cmake); VLLM_RDNA35_ATTN_JIT builds them from source
for kernel development.
RocmAttentionBackend, on gfx1151 only, returns the packed shape and
stride order of TRITON_ATTN, requires HND, adds head size 512, and
builds RocmAttentionRdna35MetadataBuilder (Triton's, with the batch
ordered decodes first) and RocmAttentionRdna35Impl. The impl subclasses
TritonAttentionImpl without modifying it: its forward launches the
kernel when the call is a uniform decode it can serve and hands anything
else to Triton's forward (prefill, alibi, softcap, non-causal, quantized
KV or output, shapes not built); in a mixed batch the decodes go to the
kernel and the prefills to Triton on a slice of the metadata. The
branches check the class, so ROCM_AITER_UNIFIED_ATTN, a subclass, keeps
its own layout. What ROCM_ATTN does not declare (sinks, KV connectors,
encoder-decoder) is served by TRITON_ATTN through the normal selection.
Gemma 4's forced single backend is ROCM_ATTN on gfx1151.
benchmarks/kernels/gfx1151_decode_attn/tools: the tuning, sweep,
roofline and batch tools that produced variants.def and the
measurements, on top of attention_benchmarks.
Tests: tests/kernels/attention/test_rdna35_hip_decode.py.
AI assistance was used for this patch.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Robert Esclapez Garcia <robert.garcia@amd.com>
roberteg16
force-pushed
the
rogarcia.gfx1151-rdna35-attn
branch
from
October 2, 2026 18:46
b8a382d to
d7b0402
Compare
6 tasks done
Author
|
Supperseded by #1346 |
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.
Summary
Two commits on
gfx11, each reviewable on its own. The fused RoPE/KV-cache write that used to be part of this PR is now a separate draft PR, stacked on this one: #1342.--min-working-set-mb, so a small model at a short context does not stay in the 32 MiB MALL and read 35 % fast) plus two fixes the kernel work needed:--dtypeasked;BenchmarkConfig.sliding_window, with a block table holding only the blocks the window reaches.Kernel: a HIP kernel for decode and speculative decode (M <= 8 query tokens per sequence) on gfx1151 (Strix Halo).
v_wmma_f32_16x16x16_{f16,bf16}, or a per-q-head dot decomposition where that wins.Built into
_rocm_C, no JIT at run time.csrc/rocm/rdna35_attn/variants.deflists 1280 variants:vllm/v1/attention/ops/rdna35_hip_decode.pywrites the list from its tuning tables, andcmake/rdna35_attn.cmakecompiles one unit per (configuration, dtype).What
RocmAttentionBackendchanges on gfx1151, and only there:RocmAttentionRdna35MetadataBuilder: Triton's builder, with the batch ordered decodes first;RocmAttentionRdna35Impl, aTritonAttentionImplsubclass. TRITON_ATTN is not modified.The branches check the class, so
ROCM_AITER_UNIFIED_ATTN(a subclass of ROCM_ATTN) keeps its own layout.registry.pyandtriton_attn.pyare untouched.Dispatch: the impl's
forwardlaunches the kernel when the call is a uniform decode it can serve. Anything else goes to TRITON_ATTN'sforwardon the same cache:In a mixed batch the decodes go to the kernel and the prefills to Triton on a slice of the metadata, where the split measured faster.
Selection:
Tuning tools in
benchmarks/kernels/gfx1151_decode_attn/tools/produce the tables and the measurements below.Performance
Attention kernel against TRITON_ATTN
Same harness (
attention_benchmarks, HND, batch 1,--min-working-set-mb 96), geomean over the contexts 128..32768; sliding-window configurations are included under their head size.At the page sizes of the hybrid models Triton is 2.0-6.5x slower than the kernel (e.g. 16/2/256 at block 1056: 3.4x at M=1, 5.8x at M=4, 16k context).
Test plan
tests/kernels/attention/test_rdna35_hip_decode.py: 168 passed._rocm_Cmatches the reference through the registry, for one sequence past a partial tile/page and for a batch with a padded sequence.variants.defin sync with the tables.--attention-backend TRITON_ATTNthe kernel does not run.tests/v1/attention/test_rocm_attention_backends_selection.py,tests/kernels/attention/test_rocm_attention_selector.py,tests/kernels/attention/test_attention_selector.pyon gfx1151: 41 passed, 3 failed, identical before and after. The 3 expect ROCM_ATTN with AITER off; with AITER installed in the test venv they get ROCM_AITER_UNIFIED_ATTN.pre-commit(ruff, mypy, clang-format, markdownlint) clean.Known, not changed here
attention.pyassertsget_name() == "TRITON_ATTN"for layers withchunk_lookback(rnj1). On ROCM_ATTN that fails on any ROCm device, gfx1151 included.logits_soft_capbutchunked_prefill_paged_decodetakes no softcap, so it is silently not applied. On gfx1151 softcap goes to Triton, which applies it.Not duplicated
No other open PR adds an RDNA3.5 decode-attention kernel for gfx1151; it continues the gfx1151 attention work of #1295 and #1308. Commit 1 extends #1311. Whichever lands first, the other rebases onto it. The default HND layout for TRITON_ATTN on gfx1151 (#1315) is no longer part of this PR: ROCM_ATTN requires HND through its own
get_required_kv_cache_layout.AI assistance (Claude) was used for this change.