Repository navigation
vulkan : keep masked keys from leaking NaN through flash attention - #127
Conversation
Masked keys are added to the score and multiplied by P = 0, so a non-finite K or V row of a masked key poisons the output (-inf + NaN, 0 * NaN). Only whole-block masks were skipped. The CPU reference and the HIP selected-key kernels skip masked keys per key; the QSA_PREFILL / QSA_DECODE poison tests check exactly that. - scalar and coopmat1: a masked score (mask <= -65504, the f16 -inf or the lowest f16 some writers use for it) is set to -inf instead of dot + mask, so non-finite K cannot reach the softmax. Free: the pipelines keep their registers and occupancy. - V (flag NAN_SAFE_V, a new Flags bit): the scalar path skips the P * V update for masked (row, key) pairs; coopmat1 marks keys hidden from every row of the tile (4-lane subgroup AND, per-key stamps, no reset) and stages V with those rows zeroed. The host sets the flag for selected-key attention (src[5]), whose selections can name any cell, and for every masked FA with GGML_VK_FA_NAN_SAFE=1 (e.g. a unified multi-sequence cache). Dense attention relies on the KV cache zeroing freed cells. gfx1151 RADV, test-backend-ops -b Vulkan0: QSA_PREFILL 22/26 -> 26/26, QSA_DECODE 82/92 -> 92/92, FLASH_ATTN_EXT 5339/5339 (also with GGML_VK_FA_NAN_SAFE=1). RADV shader stats, cm1 hs256 f16: dense pipeline 120 VGPRs / 12 waves per SIMD, unchanged; NAN_SAFE_V pipeline 192 / 8 (the V staging). llama-bench pp2048 ub2048, ABBA n=4, before -> after: - Qwen3.8-27B d0/12k/32k: 371.1/318.4/262.2 -> 370.2/318.4/261.6 (flat) - Qwen3.6-35B-A3B d0/12k/32k: 1727/1336/975 -> 1727/1339/972 (flat) - Qwen3.8-27B tg128 @ d8192: 12.03 -> 12.03 - Flash-Next REAP-320 (QSA, flag set) d0/6k: 647.8/564.9 -> 641.1/543.1 (-1.0/-3.9%) - Qwen3.8-27B d32k with GGML_VK_FA_NAN_SAFE=1: 263.0 -> 235.5 (-10.5%) Flash-Next wikitext PPL -c 4096: 3.9310 -> 3.9310. Note: a subgroupShuffleXor on a bool value gave wrong results in this shader on RADV/ACO (partial-tile FA tests failed); the shuffles use uint. Assisted-by: Claude Opus 5.5
|
Independent verification on a second Strix Halo (strix-halo-002, gfx1151, RADV) Built
The four prefill failures on master are exactly the Code reviewThe diagnosis is right, and so is the fix. The masked score is
Note: the LGTM. Real correctness fix, covered by tests that fail without it, reproduced on independent hardware. |
This fixes the
poison=1QSA test failures on Vulkan. If a masked key's K or V row holds a NaN, flash attention still lets it through (the mask is added to the score, and V is multiplied by a probability of 0, which stays NaN).GGML_VK_FA_NAN_SAFE=1for a unified multi-sequence cache. Normal attention stays as fast as before and keeps relying on freed KV cells being zeroed (Correctness: repeatable output on gfx1151 (freed-cell zeroing, deterministic top-k), plus two upstream picks #20).On a Strix Halo (gfx1151, RADV): QSA_PREFILL 22/26 -> 26/26, QSA_DECODE 82/92 -> 92/92, FLASH_ATTN_EXT all passing. Prefill on 27B and 35B was unchanged at depth 0, 12k and 32k when I measured it before #111.
Written with Claude, tested by me.
Assisted-by: Claude Opus 5.5