cuda : support for sparse KV indices in MMA flash attention kernel - #25917
cuda : support for sparse KV indices in MMA flash attention kernel#25917fairydreaming wants to merge 11 commits into
Conversation
| struct ggml_tensor * a, | ||
| struct ggml_tensor * sinks); | ||
|
|
||
| GGML_API void ggml_flash_attn_ext_add_top_k( |
There was a problem hiding this comment.
Please add comments documenting how this input affects the calculations.
|
Edit: DeepSeek V4 shall work correctly now with sparse attention (from my experience it shows improved performance starting from context length around 64k). |
…mark Port of llama.cpp-dsaport/tests/bench-fattn-dsa.cpp to this tree: - gather path (standalone DSA op) removed, does not exist here - mma_topk path added: stock ggml_flash_attn_ext over the BASE causal mask + ggml_flash_attn_ext_add_top_k (PR ggml-org#25917 use_top_k kernel), PREC_F32 - dense path added as fallback fingerprint + full-attention reference - --verify mode: mask vs mma_topk vs dense elementwise comparison, classifies SPARSE-OK / FELL-BACK-TO-DENSE / MISMATCH per shape Measured on RTX PRO 6000 Blackwell (GPU0), GLM-5.2 MLA shapes (DK 576 / DV 512 / 64 heads / MQA / V=K view / top_k 2048): - correctness: 22/22 shapes SPARSE-OK, maxdiff vs mask arm 3.1e-5..4.8e-5 (decode) / 3.5e-4..7.9e-4 (prefill), 0 nonfinite - decode: flat 0.0293-0.0295 ms across n_kv 8K..128K, mask/mma 1.09x (8K) .. 7.35x (128K) - prefill 512: LOSES to mask below n_kv/top_k ~= 8 (0.54x at ratio 4, 1.05x at ratio 8), wins 2.06x (32K) .. 5.75x (128K) - speedup ~= 13% of the theoretical n_kv/top_k work ratio (prefill), 14-28% (decode)
|
The main thing that I am wondering is if we need to explicitly pass the top_k indices to the flash attention. The alternative approach that I would like to consider is to just pass a boolean hint to the flash attention op: "is the attention sparse?". Then in the backend, I would check this hint, and if it set, I will first run a quick kernel on top of the KQ mask to collect the non-masked indices and pass those to the FA kernels. I think this could be more generic than the proposed "top-k hint". The only question is if it will be efficient enough to collect the indices this way. @tarruda Initially, I thought that your sparse approach from earlier (#26512) was doing the described idea above. LMK if you give this a shot - it should be quite light on the ggml changes (just a hint for the existing |
|
@ggerganov I don't like it because of the memory usage. If the model does not use compressed attention like DSv4 the memory needed for 1M context length and for example 8k ubatch (for fast PP) is 1M * 8k * 2 (f16) = 16GB - filled mostly with -INF in DSA based models. I thought about this a bit and I wonder if perhaps we could simply support KQ mask tensor in two formats - dense and sparse. FA implementation would check the mask tensor type - if F16/F32 it would be dense (value-based), if I32 it would be sparse (indices-based). So DSA-based models instead of modifying dense KQ mask based on top-k tensor like it's currently done would:
This is simple and keeps the memory usage low. We could convert the mask from sparse format to dense only for backends that do not support sparse KQ mask. It doesn't require any FA API changes (except for new allowed KQ mask tensor type/shape). Thoughts? |
Not sure if it is the same thing you are talking about, but in an earlier branch had implemented a env var gated selection for dense attention: |
It would work, but that specific part might be complicated because the causality-related information is on the host side in the Regarding the memory concern - if the attention is not compressed, then the KV cache would already be an enormous amount of memory, multiple times bigger than the F16 KQ mask. Plus I think that beyond ubatch of 2048 no setup actually improves (at least I am not aware of one). |
@ggerganov I see, thanks for sharing your opinion.
OK, maybe my setup is a bit special since I use |
|
Yes, the Anyway, yes it's a drawback to have a large mask. But the architecture to support that is already in place - it won't hurt to try to take the most of it. The sparse integer mask would likely require quite a few extra logic in the |
Overview
This PR adds support for sparse KV indices (called
top-k) in MMA flash attention kernel. Originally I wrote this for my DeepSeek V3.2 implementation (#21149). I think it may be still useful for someone or at least serve as an inspiration for implementing sparse attention in llama.cpp.Additional information
Currently the sparse path is only enabled for:
Requirements