Certified Sparse Attention via Perturbed Retrieval
Organizations: University of Illinois Urbana-Champaign
Abstract
Sparse attention speeds up long-context decoding by reading few keys of the KV cache, but existing methods do not control the error of a query, and on real KV caches their errors have heavy tails. We show that perturbing the score of every key with an independent Exp(1) variable turns threshold retrieval into sampling keys with probability proportional to their attention weights. Lowering the threshold along a geometric grid gives nested samples, a Horvitz--Thompson estimate of the output at every level, and confidence bounds that hold simultaneously over all levels, so each head stops at the first level whose certificate meets the target error . With fresh perturbations at every decoding step, each certificate fails with probability at most during generation. At a suitable threshold, the estimator reads values regardless of the context length, and no adaptive method reads fewer, up to constants. A 4-bit scan with deterministic bounds, shared across a grouped-query-attention group, generates the candidates exactly but reads every key. On three LLMs and ten settings at 16K--128K tokens, no certificate is violated, and at equal keys read our 90th-percentile error is 4.6--7.9 lower than that of the best of 15 baseline families. At equal bytes, the best baselines have 0.6--1.6 times our 90th-percentile error and at least 4.9 times our largest. End to end, our method stays within one point of dense attention on tasks and within 0.1% in PG-19 perplexity, and the strongest baselines at equal bytes score as well. On CPU, decoding steps at 32K--128K tokens run 1.1--1.4 faster than dense attention on the same 16-bit cache.
Figures & tables
Appendix figures & tables23 assets
Supplementary material from the paper’s appendix.
Appendix
| Array | Layout | Bytes per token | Read per query |
|---|---|---|---|
| Keys and values | fp16, token-major (256 B per row) | 512 | exact keys of candidates; values of sampled keys; window |
| 4-bit codes | VNNI-interleaved per block (below) | 64 | every pool token |
| 8-bit codes | token-major, one byte per channel | 128 | refined candidates |
| Perturbation | fp32, rewritten at every step | 4 | every pool token (and written before the scan) |
| Block scales ( , , per channel) | fp32, per block | 12 | every pool token |
| Total | 720 (+40%) | floor 80 B read + 4 B written per pool token (16.4%) |
| Component | Variant | Effect |
|---|---|---|
| Certified adaptive stopping | Fixed threshold without certificate, closest number of keys read | p90 error 2.4–9.6 higher, max error 3.8–16 higher; 14% of errors exceed 0.1 at 128K |
| GQA-shared scan | Each query head scans separately | Bytes read 2.7–4.0 higher (3.9–4.0 for ) |
| Certificate rule | Uncertified CLT rule with 30 tail samples (CLT30) | Ours reads 1.8–3.5 more keys (Llama 16K / 32K / 128K: 2.9 / 2.9 / 3.5 ; Qwen2.5: 1.8 ); CLT30’s worst layer reaches a 4.9% violation rate (denominator) |
| Certificate rule | Oracle stopping level (IDEAL, unrealizable) | Ours reads 4.1–4.9 more keys (2.7–3.0 at ) |
| 8-bit refinement | Removed | Bytes 1% to +4%; speedup 3% to +6% |
| Model data | Ours: keys / p90 / max | Best three baselines |
|---|---|---|
| Llama LongBench 16K | 2.70% / 0.011 / 0.021 | MagicPIG (ref.) 2.75%, 0.059 / 0.83; RetroInfer 2.22%, 0.063 / 0.72; oracle top- 2.58%, 0.074 / 0.43 |
| Llama RULER 32K | 1.35% / 0.011 / 0.025 | RetroInfer 1.24%, 0.058 / 0.49; MagicPIG (ref.) 1.48%, 0.066 / 1.21; oracle top- 1.30%, 0.085 / 0.77 |
| Llama RULER 64K | 0.70% / 0.012 / 0.028 | RetroInfer 0.58%, 0.059 / 0.68; oracle top- 0.69%, 0.084 / 0.89; vAttention (oracle) 0.76%, 0.101 / 0.60 |
| Llama LongBench-v2 64K | 0.61% / 0.011 / 0.021 | RetroInfer 0.57%, 0.051 / 0.39; oracle top- 0.59%, 0.068 / 0.43; oracle top- 0.61%, 0.101 / 0.56 |
| Llama RULER 128K | 0.46% / 0.012 / 0.029 | RetroInfer 0.47%, 0.077 / 0.65; oracle top- 0.50%, 0.099 / 0.88; vAttention (oracle) 0.50%, 0.117 / 0.58 |
| Llama LongBench-v2 128K | 0.42% / 0.012 / 0.022 | RetroInfer 0.32%, 0.069 / 0.65; oracle top- 0.40%, 0.078 / 0.44; vAttention (oracle) 0.43%, 0.137 / 0.85 |
| Model data | Ours | 2-bit, 128-token key groups | 4-bit, 128-token key groups | 8-bit, 128-token key groups | 2-bit, 32-token key groups | 4-bit, 32-token key groups |
|---|---|---|---|---|---|---|
| Llama LongBench 16K | 28.6% / 0.011 / 0.021 | 17.5% / 0.2394 / 1.855 | 29.8% / 0.0458 / 0.284 | 54.5% / 0.0026 / 0.017 | 19.8% / 0.1732 / 1.283 | 32.1% / 0.0371 / 0.268 |
| Llama RULER 32K | 22.6% / 0.011 / 0.025 | 16.9% / 0.2363 / 2.047 | 29.3% / 0.0464 / 0.236 | 54.2% / 0.0026 / 0.013 | 19.2% / 0.1749 / 1.925 | 31.6% / 0.0381 / 0.251 |
| Llama RULER 64K | 20.1% / 0.012 / 0.028 | 16.6% / 0.2370 / 2.661 | 29.1% / 0.0472 / 0.325 | 54.0% / 0.0027 / 0.018 | 19.0% / 0.1764 / 1.448 | 31.4% / 0.0382 / 0.201 |
| Llama LongBench-v2 64K | 19.9% / 0.011 / 0.021 | 16.7% / 0.2133 / 1.269 | 29.1% / 0.0427 / 0.254 | 54.1% / 0.0024 / 0.013 | 19.0% / 0.1592 / 1.410 | 31.5% / 0.0343 / 0.170 |
| Llama RULER 128K | 19.5% / 0.012 / 0.029 | 16.5% / 0.2160 / 3.702 | 29.0% / 0.0406 / 0.262 | 54.0% / 0.0024 / 0.017 | 18.9% / 0.1604 / 1.715 | 31.4% / 0.0337 / 0.232 |
| Llama LongBench-v2 128K | 19.3% / 0.012 / 0.022 | 16.5% / 0.2069 / 1.001 | 29.0% / 0.0377 / 0.276 | 54.0% / 0.0022 / 0.019 | 18.9% / 0.1397 / 1.291 | 31.4% / 0.0299 / 0.162 |
| Model data | Ours, | With replacement from the 4-bit proposal | Poisson PPS on 4-bit probabilities | Poisson PPS, one budget per setting |
|---|---|---|---|---|
| Llama LongBench 16K | 2.70% / 0.0112 / 0.021 | 1.47% / 0.0616 / 0.645 | 2.70% / 0.0115 / 0.108 | 2.70% / 0.0192 / 0.093 |
| Llama RULER 32K | 1.35% / 0.0114 / 0.025 | 0.82% / 0.0630 / 0.612 | 1.35% / 0.0117 / 0.080 | 1.35% / 0.0187 / 0.100 |
| Llama RULER 64K | 0.70% / 0.0115 / 0.028 | 0.43% / 0.0624 / 0.689 | 0.70% / 0.0118 / 0.033 | 0.70% / 0.0188 / 0.090 |
| Llama LongBench-v2 64K | 0.61% / 0.0112 / 0.021 | 0.35% / 0.0626 / 0.492 | 0.61% / 0.0116 / 0.022 | 0.61% / 0.0171 / 0.094 |
| Llama RULER 128K | 0.46% / 0.0119 / 0.029 | 0.28% / 0.0574 / 0.706 | 0.46% / 0.0122 / 0.031 | 0.46% / 0.0194 / 0.094 |
| Llama LongBench-v2 128K | 0.42% / 0.0117 / 0.022 | 0.24% / 0.0553 / 0.314 | 0.42% / 0.0120 / 0.024 | 0.42% / 0.0177 / 0.071 |
| CPU | Model data | Indexing: per KV head / all heads / keys per s (1 thread) | Append per step (all heads) | Query: 1 / 8 / 24 threads | Append / query (24 threads) |
|---|---|---|---|---|---|
| 8555C | Llama 16K | 0.030 s / 7.8 s / 536K | 0.70 ms | 297 / 37 / 13 ms | 5.2% |
| 8555C | Llama 32K | 0.060 s / 15.5 s / 535K | 0.69 ms | 348 / 45 / 17 ms | 4.1% |
| 8555C | Llama 64K | 0.122 s / 31.4 s / 528K | 0.73 ms | 516 / 66 / 25 ms | 2.9% |
| 8555C | Llama 128K | 0.270 s / 69.2 s / 483K | 0.71 ms | 1039 / 133 / 60 ms | 1.2% |
| 8555C | Qwen2.5 16K | 0.030 s / 3.4 s / 539K | 0.31 ms | 194 / 26 / 9 ms | 3.3% |
| 8358 | Llama 16K | 0.028 s / 7.1 s / 586K | 0.96 ms | 313 / 40 / 22 ms | 4.3% |
| CPU (threads) context | Steady step: SDPA / dense16 / ours | Attention: SDPA / dense16 / ours | Rest | Step speedup over dense16 / SDPA | Attention speedup over dense16 | Ours: first step | Break-even |
|---|---|---|---|---|---|---|---|
| 8555C (26) 32K | 421 / 306 / 273 ms | 219 / 105 / 66 ms | 202 ms | 1.12 / 1.54 | 1.58 | 0.91 s | 18 steps |
| 8555C (26) 64K | 715 / 416 / 314 ms | 508 / 210 / 104 ms | 206 ms | 1.32 / 2.27 | 2.02 | 1.56 s | 11 steps |
| 8555C (26) 128K | 1192 / 629 / 439 ms | 976 / 412 / 218 ms | 217 ms | 1.43 / 2.72 | 1.89 | 3.15 s | 13 steps |
| 8358 (32) 32K | 343 / 330 / 298 ms | 128 / 115 / 81 ms | 215 ms | 1.11 / 1.15 | 1.42 | 0.91 s | 18 steps |
| 8358 (32) 64K | 470 / 434 / 347 ms | 250 / 219 / 126 ms | 215 ms | 1.25 / 1.35 | 1.74 | 1.57 s | 13 steps |
| 8358 (32) 128K | 724 / 649 / 479 ms | 503 / 432 / 257 ms | 217 ms | 1.35 / 1.51 | 1.68 | 2.92 s | 13 steps |
| Model data | Dense (ms) | Speedup, fixed | Speedup, per step | Per step ÷ fixed | ÷ per step | Keys: per step / |
|---|---|---|---|---|---|---|
| Llama LongBench 16K | 356 / 56.8 / 38.6 | 1.09 / 1.34 / 1.54 | 1.06 / 1.27 / 1.51 | 1.04 / 1.05 / 1.04 | 1.32 / 1.32 / 1.34 | 2.75% / 4.41% |
| Llama RULER 32K | 702 / 112.8 / 81.2 | 1.37 / 1.53 / 1.77 | 1.32 / 1.47 / 1.70 | 1.06 / 1.03 / 1.04 | 1.31 / 1.31 / 1.34 | 1.68% / 2.92% |
| Llama RULER 64K | 1385 / 235 / 175.1 | 1.82 / 1.97 / 2.15 | 1.69 / 1.82 / 2.05 | 1.08 / 1.06 / 1.04 | 1.25 / 1.27 / 1.25 | 0.89% / 1.49% |
| Llama RULER 128K | 2932 / 514 / 385 | 2.01 / 1.99 / 2.23 | 1.79 / 1.88 / 2.16 | 1.10 / 1.05 / 1.03 | 1.22 / 1.22 / 1.24 | 0.63% / 1.04% |
| Llama LongBench-v2 128K | 2927 / 521 / 386 | 2.62 / 2.58 / 2.86 | 2.32 / 2.41 / 2.70 | 1.13 / 1.06 / 1.04 | 1.17 / 1.17 / 1.17 | 0.39% / 0.64% |
| Qwen3 LongBench 16K | 398 / 63.1 / 46.0 | 1.14 / 1.25 / 1.58 | 1.08 / 1.22 / 1.47 | 1.05 / 1.03 / 1.03 | 1.26 / 1.25 / 1.27 | 1.99% / 3.03% |
| Model context (books) | Dense PPL | Ours, : keys / PPL / KL | Ours, : keys / PPL / KL | Oracle top- : PPL / KL | Top- , layers 0–1 dense: PPL |
|---|---|---|---|---|---|
| Llama 32K (16) | 11.076 | 1.79% / +0.03% [ 0.06, +0.13] / 0.0005 | 1.10% / +0.22% [+0.07, +0.36] / 0.0014 | +5.9% [+3.1, +9.3] / 0.095 | +5.2% [+2.3, +8.7] |
| Llama 64K (12) | 11.487 | 0.98% / +0.07% [ 0.05, +0.19] / 0.0006 | 0.59% / +0.03% [ 0.10, +0.18] / 0.0014 | +4.8% [+2.7, +7.3] / 0.085 | +4.1% [+2.0, +6.7] |
| Llama 128K (8) | 8.757 | 0.58% / +0.01% [ 0.03, +0.05] / 0.0005 | 0.34% / +0.11% [ 0.08, +0.31] / 0.0013 | +8.8% [+3.4, +18.7] / 0.106 | +8.5% [+3.1, +18.3] |
| Qwen3 32K (16) | 12.536 | 1.95% / +0.05% [ 0.03, +0.13] / 0.0003 | 1.26% / +0.12% [+0.01, +0.22] / 0.0007 | +8.4% [+4.6, +14.2] / 0.114 | +8.7% [+4.9, +14.6] |
| Qwen2.5 32K (16) | 10.071 | 2.25% / 0.02% [ 0.06, +0.02] / 0.0002 | 1.35% / 0.02% [ 0.11, +0.06] / 0.0006 | +11.5% [+5.7, +19.4] / 0.126 | +10.3% [+4.5, +18.4] |
| Model context (books) | Method | Keys read | Bytes read | Perplexity vs dense [95% CI] | Perplexity vs ours [95% CI] | KL mean | KL / ours [95% CI] |
|---|---|---|---|---|---|---|---|
| Llama 32K (16) | ours, per-step perturbations | 1.79% | 26.0% | +0.03 [ 0.06, +0.13] | – | 0.0005 | 1 |
| Llama 32K (16) | ours, fixed perturbations | 1.79% | 25.2% | +0.03 [ 0.08, +0.12] | 0.00 [ 0.18, +0.16] | 0.0009 | 1.78 [1.25, 2.40] |
| Llama 32K (16) | ours, , per step | 1.10% | 22.3% | +0.22 [+0.07, +0.36] | +0.19 [+0.06, +0.32] | 0.0014 | 2.83 [2.58, 3.21] |
| Llama 32K (16) | oracle top- (our keys per head) | 1.84% | oracle | +5.89 [+3.09, +9.26] | +5.85 [+3.09, +9.19] | 0.0951 | 188 [145, 236] |
| Llama 32K (16) | oracle top- , layers 0–1 dense | 7.80% | oracle | +5.20 [+2.32, +8.71] | +5.17 [+2.31, +8.67] | 0.0911 | 180 [136, 227] |
| Llama 32K (16) | MagicPIG (reference), , | 23.41% | 24.0% ( ) | +0.09 [ 0.02, +0.19] | +0.06 [ 0.11, +0.21] | 0.0009 | 1.83 [1.67, 2.01] |
| Model context (books) | Method | Keys read | Bytes read | Perplexity vs dense [95% CI] | Perplexity vs ours [95% CI] | KL mean | KL / ours [95% CI] |
|---|---|---|---|---|---|---|---|
| Llama 64K (12) | ours, per-step perturbations | 0.98% | 22.5% | +0.07 [ 0.05, +0.19] | – | 0.0006 | 1 |
| Llama 64K (12) | ours, , per step | 0.59% | 20.2% | +0.03 [ 0.10, +0.18] | 0.04 [ 0.14, +0.06] | 0.0014 | 2.46 [2.05, 2.92] |
| Llama 64K (12) | oracle top- (our keys per head) | 1.00% | oracle | +4.80 [+2.67, +7.32] | +4.73 [+2.64, +7.19] | 0.0847 | 148 [101, 214] |
| Llama 64K (12) | oracle top- , layers 0–1 dense | 7.09% | oracle | +4.12 [+1.95, +6.67] | +4.04 [+1.93, +6.58] | 0.0794 | 138 [92.9, 203] |
| Llama 128K (8) | ours, per-step perturbations | 0.58% | 20.6% | +0.01 [ 0.03, +0.05] | – | 0.0005 | 1 |
| Llama 128K (8) | ours, , per step | 0.34% | 18.9% | +0.11 [ 0.08, +0.31] | +0.10 [ 0.08, +0.27] | 0.0013 | 2.61 [2.35, 2.90] |
| Model context (books) | Method | Keys read | Bytes read | Perplexity vs dense [95% CI] | Perplexity vs ours [95% CI] | KL mean | KL / ours [95% CI] |
|---|---|---|---|---|---|---|---|
| Qwen3 32K (16) | ours, per-step perturbations | 1.95% | 30.8% | +0.05 [ 0.03, +0.13] | – | 0.0003 | 1 |
| Qwen3 32K (16) | ours, fixed perturbations | 1.95% | 30.0% | +0.04 [ 0.09, +0.17] | 0.01 [ 0.15, +0.14] | 0.0005 | 1.57 [1.30, 1.87] |
| Qwen3 32K (16) | ours, , per step | 1.26% | 26.7% | +0.12 [+0.01, +0.22] | +0.07 [ 0.01, +0.14] | 0.0007 | 2.59 [2.40, 2.77] |
| Qwen3 32K (16) | oracle top- (our keys per head) | 2.00% | oracle | +8.44 [+4.65, +14.18] | +8.38 [+4.61, +14.05] | 0.1143 | 396 [270, 598] |
| Qwen3 32K (16) | oracle top- , layers 0–1 dense | 7.39% | oracle | +8.72 [+4.90, +14.55] | +8.66 [+4.88, +14.43] | 0.1155 | 400 [273, 603] |
| Qwen3 32K (16) | MagicPIG (reference), , | 18.54% | 19.0% ( ) | +0.18 [+0.01, +0.33] | +0.13 [ 0.08, +0.33] | 0.0016 | 5.71 [4.82, 6.49] |
| Model context (books) | Method | Keys read | Bytes read | Perplexity vs dense [95% CI] | Perplexity vs ours [95% CI] | KL mean | KL / ours [95% CI] |
|---|---|---|---|---|---|---|---|
| Qwen2.5 32K (16) | ours, per-step perturbations | 2.25% | 41.2% | 0.02 [ 0.06, +0.02] | – | 0.0002 | 1 |
| Qwen2.5 32K (16) | ours, fixed perturbations | 2.24% | 40.4% | +0.01 [ 0.06, +0.07] | +0.02 [ 0.07, +0.12] | 0.0004 | 1.61 [1.44, 1.79] |
| Qwen2.5 32K (16) | ours, , per step | 1.35% | 34.3% | 0.02 [ 0.11, +0.06] | 0.00 [ 0.08, +0.06] | 0.0006 | 2.62 [2.46, 2.78] |
| Qwen2.5 32K (16) | oracle top- (our keys per head) | 2.30% | oracle | +11.49 [+5.66, +19.43] | +11.51 [+5.67, +19.44] | 0.1257 | 555 [318, 893] |
| Qwen2.5 32K (16) | oracle top- , layers 0–1 dense | 9.11% | oracle | +10.34 [+4.50, +18.38] | +10.36 [+4.51, +18.42] | 0.1190 | 525 [286, 866] |
| Qwen2.5 32K (16) | MagicPIG (reference), , | 16.54% | 17.0% ( ) | +0.13 [+0.01, +0.26] | +0.15 [+0.02, +0.28] | 0.0020 | 8.79 [5.90, 13.6] |
| Method (7 books) | Mean KL | Max KL | First / last quarter | Mean KL / ours | Max KL / ours | NLL minus dense | Repeated 4-grams minus dense (points) |
|---|---|---|---|---|---|---|---|
| dense attention | — | — | — | — | — | NLL 1.157 | 9.5% |
| ours, | 4.5e-04 | 5.8e-02 | 4.0e-04 / 4.1e-04 | 1 | 1 | 0.011 [ 0.125, +0.083] | 2.3 [ 5.1, +0.6] |
| MagicPIG (reference) | 7.3e-04 | 4.8e-02 | 1.0e-03 / 5.3e-04 | 1.63 [1.32, 2.01] | 0.84 [0.68, 1.71] | 0.024 [ 0.093, +0.049] | +0.0 [ 2.1, +2.6] |
| RetroInfer (CPU port) | 1.9e-03 | 1.2e-01 | 2.1e-03 / 1.7e-03 | 4.25 [3.40, 5.43] | 1.99 [1.02, 7.16] | 0.212 [ 0.424, 0.026] | +5.3 [ 2.5, +14.6] |
| vAttention (HashAttention) | 1.7e-03 | 2.1e-01 | 2.5e-03 / 1.3e-03 | 3.89 [2.93, 5.14] | 3.71 [0.42, 11.82] | 0.085 [ 0.254, +0.080] | 1.8 [ 6.2, +2.0] |
| Component | Contents |
|---|---|
| Kernel and binding | csrc/certattn/ : the C++ kernel with AVX-512 intrinsics, its pybind11 binding and a build script |
| Reference implementation and tests | the NumPy reference with exact scores ( attn/pps_ref.py ) and the kernel and index tests ( attn/test_certattn.py , attn/test_append_many.py ) |
| Certificate rules | attn/certify.py and the rule comparison of Appendix D.7 ( attn/cert_ablation.py ) |
| Operator-level evaluation | KV-cache capture ( probe/capture.py ), baseline configurations and evaluation ( attn/methods.py , attn/eval_maskers.py ) with the chunked routines of Appendix C.3, the reference ports ( attn/official_ref.py , attn/retroinfer_port.py ) and SANTA ( attn/eval_santa.py ) |
| End-to-end evaluation and perplexity | attn/e2e.py with one configuration file per method, attn/e2e_stats.py and attn/ppl.py |
| Timing | attention and whole-step timing, the append cost ( attn/bench_append.py ) and the comparison with llama.cpp ( attn/bench_dense_vs_llamacpp.py , with the llama.cpp patch) |
| Item | Version |
|---|---|
| sparse-attention-hub (baseline maskers) | xAlg-ai/sparse-attention-hub, commit 497da5b |
| MagicPIG reference | Infini-AI-Lab/MagicPIG, commit ac9aa36 |
| Quest reference | mit-han-lab/Quest, commit 01c1623 |
| RetroInfer (ported) | microsoft/RetrievalAttention, commit 03f912c |
| HashAttention weights (Llama-3.1-8B, 64K patch v1) | sha256 8b496b02… |
| LongBench prompts and metrics | THUDM/LongBench, commit 2e00731f8d |
Sparse Attention
Sparse attention reduces the token interactions computed by Transformers to lower the cost of long-context modeling and inference.
See all 244 papers