Skip to content

metal : add sparse attention (wip) - #28098

Draft
ggerganov wants to merge 9 commits into
masterfrom
gg/metal-fa-sparse
Draft

metal : add sparse attention (wip)#28098
ggerganov wants to merge 9 commits into
masterfrom
gg/metal-fa-sparse

Conversation

@ggerganov

Copy link
Copy Markdown
Member

Overview

WIP in progress - opening for testing and feedback

This is on top of #27970 to add Metal support.

Initial results for DSv4 on M2 Ultra:

  • Before
|    PP |     TG |    B |   N_KV |   T_PP s | S_PP t/s |   T_TG s | S_TG t/s |      T s |    S t/s |
|-------|--------|------|--------|----------|----------|----------|----------|----------|----------|
|  2048 |     32 |    1 |   2080 |    5.100 |   401.57 |    1.164 |    27.50 |    6.264 |   332.06 |
|  4096 |     32 |    1 |   4128 |   10.900 |   375.77 |    1.189 |    26.92 |   12.089 |   341.47 |
|  8192 |     32 |    1 |   8224 |   25.316 |   323.58 |    1.233 |    25.95 |   26.550 |   309.76 |
| 16384 |     32 |    1 |  16416 |   65.888 |   248.67 |    1.307 |    24.48 |   67.195 |   244.30 |
| 32768 |     32 |    1 |  32800 |  192.359 |   170.35 |    1.407 |    22.75 |  193.765 |   169.28 |
| 65536 |     32 |    1 |  65568 |  612.039 |   107.08 |    1.572 |    20.36 |  613.611 |   106.86 |
  • After
|    PP |     TG |    B |   N_KV |   T_PP s | S_PP t/s |   T_TG s | S_TG t/s |      T s |    S t/s |
|-------|--------|------|--------|----------|----------|----------|----------|----------|----------|
|  2048 |     32 |    1 |   2080 |    5.107 |   401.01 |    1.178 |    27.15 |    6.286 |   330.92 |
|  4096 |     32 |    1 |   4128 |   10.668 |   383.94 |    1.190 |    26.88 |   11.859 |   348.10 |
|  8192 |     32 |    1 |   8224 |   21.934 |   373.49 |    1.202 |    26.62 |   23.135 |   355.47 |
| 16384 |     32 |    1 |  16416 |   45.233 |   362.21 |    1.219 |    26.26 |   46.452 |   353.40 |
| 32768 |     32 |    1 |  32800 |   94.200 |   347.85 |    1.256 |    25.48 |   95.456 |   343.61 |
| 65536 |     32 |    1 |  65568 |  202.556 |   323.54 |    1.342 |    23.84 |  203.899 |   321.57 |

Requirements

@github-actions github-actions Bot added model Model specific testing Everything test related ggml changes relating to the ggml tensor library for machine learning Apple Metal https://en.wikipedia.org/wiki/Metal_(API) CUDA Related to the CUDA backend labels Aug 31, 2026
am17an and others added 9 commits August 31, 2026 21:32
- add kernel_flash_attn_ext_vec_idx: compacts finite mask entries into
  a per-row index list (Hillis-Steele scan, one threadgroup per row)
- extend vec FA kernel with optional sparse index gathering (FC slot 5)
- add host-side gate: sparse path when n_kv_max > 0, mask present,
  supported head sizes / KV types, n_kv_max <= 4096
- new buffer region extra_idx for the index list
- pipeline getter extended with has_sparse param
- add test cases: head sizes, quant types, nb>1, nr23 variants,
  sinks, ALiBi, softcap, permute, v_view_of_k, no-mask fallback

Note: multi-row (nb*nr23[1] > 1) cases still failing - rid mapping
in the store phase needs revisiting for the sparse path.

Assisted-by: pi:llama.cpp/Qwen3.8-27B
- kernel_flash_attn_ext_vec_idx: mask param is half* but nb31 is a byte
  stride, so the per-row mask offset was scaled by 2x; cast to char*
  before applying the byte strides
- kernel_flash_attn_ext_vec: sparse pidx param is char* so the per-row
  element offset was under-scaled by sizeof(int); scale it by sizeof(int)
  to get the correct byte offset
- fixes the multi-row (nb*nr23[1] > 1) sparse flash attention failures

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731
The idx kernel previously read the mask row twice: once to count the finite
entries (for the prefix scan) and again to recover their positions. Since the
kernel is memory-bound, this doubled the mask traffic.

Keep the finite positions in a per-thread register array during the count
pass and write them out directly, avoiding the second mask read. A dense
mask with more than NLOCAL finite entries in a slice falls back to re-reading
the mask to write the remaining positions.

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731
Measure the sparse vec FA kernel across KV sizes, n_kv_max hints and batch
sizes. Run with:

    ./build/bin/test-backend-ops -b MTL0 -o FLASH_ATTN_EXT -p "n_kv_max=[1-9]" perf

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Apple Metal https://en.wikipedia.org/wiki/Metal_(API) CUDA Related to the CUDA backend ggml changes relating to the ggml tensor library for machine learning model Model specific testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants