Repository navigation
vulkan : Strix Halo prefill flash attention (KV contiguize, multi-row coopmat1 FA with V^T) - #396
Conversation
1531f65 to
0555b77
Compare
yingying0906
left a comment
There was a problem hiding this comment.
Two code findings in the Vulkan flash attention path.
4eb5d75 to
07d5b4f
Compare
|
GGML_VK_FA_KV_CONTIG defaults on across coopmat1 devices, although the PR says it was benchmarked only on RADV. NVIDIA CI establishes correctness, not performance. would be better to have non-RADV performance evidence or a narrower default gate. |
|
The perf logger’s query pool can overflow. It allocates n_nodes + 100 slots, but every eligible FA node can emit two extra sub-operation timestamps. A graph with 50 such nodes needs 1 + 50 + 100 = 151 timestamps but receives 150 slots. The helper drops further sub-op marks, but the normal node timestamp then indexes the vectors and Vulkan query pool without a bounds check. |
6a6f69f to
fc7846d
Compare
|
@gianni-cor thanks, both addressed. I also rebased onto K/V contiguize default (fc7846d8b). Agreed, there is no non-RADV performance evidence. The pass now defaults on only for RADV RDNA3, the same gate as the V^T scratch and the multi-row kernel. Other devices keep the strided cm1 loads, as on Perf-logger query pool (cd0c14439). Confirmed: with 50+ FA nodes, the per-node timestamp after a dropped sub-op mark wrote past the pool and its vectors. The pool is now sized from the graph: one start timestamp, one per node, and two per Tested on gfx1151 (clean Vulkan build): FLASH_ATTN_EXT 5725/5725 with the new defaults, and the prefill FA cases pass with |
… coopmat1 FA with V^T) Prefill flash attention for RADV RDNA3 (gfx1151), from halo-box/strix-llama.cpp plus one upstream fix: - upstream ggml-org#29591: fix stale prealloc_y reuse across flash attention and soft_max. - Contiguize strided f16 K/V for prefill FA (strix 6dc9116, e52cc7c, 6d056bf): a strided copy into the dequant-once scratch makes K/V per-head contiguous, with the scratch's device-local capacity gate. On by default for RADV RDNA3; GGML_VK_FA_KV_CONTIG=1 everywhere, =0 off. Its pass is billed on its own perf-logger line (strix 5d5759a). - coopmat1 FA: hoist the P-fragment load out of the hsv_tile loop and store Psh query-major (strix 1007fdc, 11eaefa). Fabric's TurboQuant V path also reads Psh and now indexes the query-major layout. - wave32 pin for cm1 FA on RDNA3 when hsv <= 128 and at least 32 rows (strix bc2b9ad, 1556cd1, 1debd52); GGML_VK_FA_WAVE32=0 off. - Multi-row coopmat1 FA with a V^T scratch (strix 304f481): flash_attn_cm1_mr.comp covers 64 query rows per workgroup of eight wave32 subgroups, with V from a per-head V^T copy (dequant_f16_transpose_vt.comp). On by default for head size 256 on RADV RDNA3; GGML_VK_FA_MR=0 / GGML_VK_FA_VT=0 off. Review fixes: the multi-row kernel zeroes V at the score path's mask threshold (FA_MASK_DEAD); the V^T scratch goes through the device-local capacity gate (separate memoized decision from the K/V scratch); the perf-logger query pool is sized for two sub-op marks per FLASH_ATTN_EXT node. Fabric adaptations: FA flag bits 64..1024 (16 = USE_SPARSE and 32 = QJL_FULL_PROJ are taken), the FA_FLAG_* constants in ggml-vulkan.cpp, no V^T or multi-row on the sparse gather path; the fork's NaN-safe V staging and Xe FA decode path are not carried. Qwen3.8 on gfx1151, Vulkan pp2048 (t/s), before -> after: 27B Q4_K_M d8192 244.0 -> 302.1 d32768 106.7 -> 266.4 27B Q8 d8192 257.9 -> 321.3 d32768 100.9 -> 285.8 Flash-Next d8192 536.3 -> 605.6 d32768 316.8 -> 380.2 (d32768 with -ub 512). FLASH_ATTN_EXT 5725/5725 on Vulkan0. Co-authored-by: Nathan Wilson <nath.flagman151@passmail.com> Co-authored-by: François-Xavier Gsell <fxgsell@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fc7846d to
9e18341
Compare
|
unrelated gpu-webapple-apple failure. Merging |
Overview
Vulkan prefill flash attention for Strix Halo (gfx1151, RADV). This is the attention-at-depth follow-up to #393, rebased onto
temp-11018now that #393 is merged. It is one squashed commit (9e18341cd). Changes from review:Prefill at depth is limited by
FLASH_ATTN_EXTon Qwen3.8 27B and Flash-Next, and this stack speeds it up. All of it comes from halo-box/strix-llama.cpp, except one upstream fix:prealloc_yreuse across flash attention and soft_max, which the contiguize pass below relies on.GGML_VK_FA_KV_CONTIG=1turns it on for every device and=0turns it off.Pshquery-major so the GEMM2 A load vectorizes.GGML_VK_FA_WAVE32=0turns it off). It does not engage at Qwen3.8's head size of 256.flash_attn_cm1_mr.comp,dequant_f16_transpose_vt.comp). One workgroup of eight wave32 subgroups covers 64 query rows (H heads x 64/H tokens sharing a KV head). Q stays in registers and every 16-key K/V tile serves all 64 rows; cm1 pins Br at 16. V comes from a per-head V^T copy, so a P x V fragment is one contiguous 32-byte run per lane. It is on by default for head size 256 on RADV RDNA3.GGML_VK_FA_MR=0turns off the multi-row kernel, andGGML_VK_FA_VT=0turns off V^T (and with it the multi-row kernel).The squashed commit credits Nathan Wilson (the strix-llama.cpp work) and François-Xavier Gsell (upstream ggml-org#29591) as co-authors and lists the strix commits it ports. Two strix FA commits are left out: NaN-safe V staging (
1b899d039), which needs the selected-key attention path that fabric does not have, and ggml-org#29988, which is for the scalar FA MMQ path that fabric disables.Additional information
Results
GMKtec EVO-X2: Ryzen AI MAX+ 395 / Radeon 8060S (gfx1151), Mesa 26.0.8 RADV.
llama-bench -ngl 999 -fa 1 -b 2048 -p 2048 -n 0; Flash-Next adds-lzm on. d0 and d8192 use-ub 2048 -r 2. d32768 uses-ub 512 -r 1, because-ub 2048at 32K trips the amdgpu compute-ring timeout on Vulkan with and without this PR. Before and after are clean builds, interleaved twice.Vulkan pp2048 (t/s), #393 vs this PR:
For reference, strix-llama.cpp
deb5e2fat d8192 (-ub 2048): 27B Q4_K_M 291, 27B Q8 315, Flash-Next 637. Both 27B models now beat it. Flash-Next still trails, because strix runs its full-attention layers as QSA selected-key attention, which is not part of this PR.Where the gain comes from: this PR with one switch at a time (pp2048, t/s):
GGML_VK_FA_MR=0(cm1 + V^T)GGML_VK_FA_VT=0(cm1, no V^T, no multi-row)GGML_VK_FA_KV_CONTIG=0(multi-row on the strided view)GGML_VK_FA_KV_CONTIG=0 GGML_VK_FA_VT=0The contiguize pass does most of the work for the cm1 kernel. The multi-row kernel adds 5% at d8192 and 18% at d32768 on top, and it does nearly as well without the contiguize pass because it reads the strided view efficiently. With every switch off, the cm1 shader changes (P-fragment hoist,
Pshlayout) remain, and they account for the 107 -> 126 at d32768.Fabric-specific adaptations
Flagsalready use 16 =USE_SPARSEand 32 = turbo-quantQJL_FULL_PROJ. The new bits are 64 (V_TRANSPOSED) and 128..1024 (multi-row, host-side selection and schedule knobs), with the constants inggml-vulkan.cpp. V^T and multi-row never run on the sparse gather path.Pshand now indexes the query-major layout. Without this, 88 TBQ/PQFLASH_ATTN_EXTcases fail.FA_MASK_DEADcomes over from the NaN-safe commit, because the multi-row kernel's mask test uses it. The fork's Xe FA decode code that sat in the same hunks is dropped.k_quant && v_quant, since fabric has nokv_needs_dequant.Testing
On gfx1151, Vulkan0, from a clean build:
FLASH_ATTN_EXT5725/5725 (41 cases go through the multi-row kernel),MUL_MAT2123/2123 andSOFT_MAX212/212. The head-size 128/256 prefill FA cases also pass with each ofGGML_VK_FA_MR=0,GGML_VK_FA_VT=0,GGML_VK_FA_WAVE32=0andGGML_VK_FA_KV_CONTIG=0, and all prefill FA cases pass withGGML_VK_FA_KV_CONTIG=1. The new tests cover multi-row shapes (GQA 2/4/6/8/12, H = 1/2, ragged token blocks, no mask, sinks, ALiBi + softcap, q8_0 K/V, KV-cache views and a per-batch mask the kernel must decline), plus perf cases at the Qwen3.8 27B prefill shape.Not tested: other Vulkan drivers and vendors. The contiguize pass, V^T and the multi-row kernel only default on for RADV RDNA3. The cm1 shader changes (P-fragment hoist,
Pshlayout) apply on every coopmat1 device, but were only run on RADV.Requirements
Pshregression, built and ran test-backend-ops and the benchmarks on the EVO-X2, and drafted this description. The commit carries Co-Authored-By trailers.🤖 Generated with Claude Code