#IndexCache
Speed up your LLMs! IndexCache’s sparse attention drops long‑context inference time by 1.82×, blending dense‑sparse tricks inside transformer blocks. Curious how it works? Dive in for the details. #IndexCache #SparseAttention #LongContextAI

🔗 aidailypost.com/news/indexca...
March 27, 2026 at 6:10 PM
📻 Worth taking a closer look: IndexCache, a new sparse attention optimizer, boosts long‑context AI model inference 1.82× faster. Could change how we run real‑time analytics? 🤖 #AI #Optimization #Tech
IndexCache, a new sparse attention optimizer, delivers 1.82x faster inference on long-context AI models
Processing 200,000 tokens through a large language model is expensive and slow: the longer the context, the faster the costs spiral. Researchers at Tsinghua University and Z.ai have built a technique call
venturebeat.com
March 27, 2026 at 11:17 PM
IndexCache, a new sparse attention optimizer, delivers 1.82x faster inference on long-context AI models

Processing 200,000 tokens through a large language model is expensive and slow: the longer the context, the faster the cost increases. Researchers at Tsinghua University and Z.ai have created a…
IndexCache, a new sparse attention optimizer, delivers 1.82x faster inference on long-context AI models
Processing 200,000 tokens through a large language model is expensive and slow: the longer the context, the faster the cost increases. Researchers at Tsinghua University and Z.ai have created a technology called IndexCache that cuts up to 75% of redundant computation in sparse attention models, delivering 1.82x faster time-to-first-token and 1.48x faster generation throughput at that context length. This technique is applicable to models using the DeepSeq sparse attention architecture, including the latest DeepSeq and GLM families. It can help enterprises provide faster user experiences for production-scale, long-context models, a capability already proven in initial tests on a 744-billion-parameter GLM-5 model.
cnznews.com
March 27, 2026 at 7:07 PM
今日のHuggingFaceトレンド

tencent/Hy4-preview
Tencent Hy Teamが開発した次世代のMixture-of-Experts(MoE)フラッグシップモデルであるHy4 previewの公開を目的としています。
総パラメータ数770Bを持ち、Gated DSAやIndexCache、iHCなどの最新アーキテクチャや推測デコーディング用のMTPレイヤーを採用した、効率的なテキスト生成を目指す大規模言語モデルです。
tencent/Hy4-preview · Hugging Face
We’re on a journey to advance and democratize artificial intelligence through open source and open science.
huggingface.co
September 1, 2026 at 2:30 PM
IndexCache сокращает вычислительные издержки моделей с разреженным вниманием до 75%, ускоряя обработку 200 тысяч т...

#IndexCache #сокращает #вычислительные #издержки #моделей #с #разреженным #вниманием #до #75%, #ускоряя

Origin | Interest | Match
March 28, 2026 at 9:17 AM
IndexCache: Accelerating Sparse Attention via Cross-Layer Index Reuse

huggingface.co/papers/2603....
Paper page - IndexCache: Accelerating Sparse Attention via Cross-Layer Index Reuse
Join the discussion on this paper page
huggingface.co
March 15, 2026 at 11:43 AM
Yushi Bai, Qian Dong, Ting Jiang, Xin Lv, Zhengxiao Du, Aohan Zeng, Jie Tang, Juanzi Li: IndexCache: Accelerating Sparse Attention via Cross-Layer Index Reuse https://arxiv.org/abs/2603.12201 https://arxiv.org/pdf/2603.12201 https://arxiv.org/html/2603.12201
March 13, 2026 at 6:30 AM
GML5 IndexCache
# IndexCache: Killing the Indexer's O(NL²) Bottleneck in DeepSeek Sparse Attention _Notes from my notebook on GLM-5.2 / DeepSeek Sparse Attention (DSA), reconstructed from the IndexCache paper (Bai, Dong et al., Tsinghua + Z.ai, 2026) — the mechanism behind GLM-5.2's "IndexShare."_ ## 1. Why this exists — the bottleneck nobody talks about DSA's whole pitch is: don't do full O(L²) attention, instead let a cheap **lightning indexer** look at all preceding tokens and pick the top-k (k=2048) that actually matter, then do real attention only on those. That drops core attention from O(L²) → O(Lk). Great — except I missed this the first time I read DSA: **the indexer itself is still O(L²)**. It has to score every preceding token against the query to decide who's in the top-k. So across N layers you've traded one O(L²) cost for N separate O(L²) costs — total O(NL²). At long context this _indexer_ becomes the dominant cost, not the attention it was supposed to fix. > Adding the indexer is "DSA on steroids" because it kills DSA's one real bottleneck (full attention) — but in doing so, it grows its own. The indexer is cheap per-FLOP (few heads, low-rank, FP8) but it still runs at every single layer. The fix the paper proposes isn't a smarter indexer — it's **don't run it every layer at all.** ## 2. The core insight: adjacent layers pick almost the same tokens If you measure pairwise overlap between the top-k token sets selected by each layer's indexer, **adjacent layers share 70–100% of their picks.** The heatmap even shows block structure — clusters of layers (e.g. layers 3–5, 17–30, etc.) that all converge on roughly the same "important" tokens. So most of the O(NL²) indexer cost is _redundant computation of the same answer._ This motivates **IndexCache** : split the N layers into two roles — * **F (Full)** layers — run their own indexer, compute fresh top-k, cache it. * **S (Shared)** layers — skip the indexer entirely, just reuse the nearest preceding F layer's cached top-k. The first layer is always F (has to seed the cache). ### Inference loop comparison **Standard DSA:** for l = 1 to N: I⁽ˡ⁾ ← Indexer_l(X) T⁽ˡ⁾ ← top-k(I⁽ˡ⁾) X ← SparseAttn_l(X, T⁽ˡ⁾) X ← FFN_l(X) # + norm, residual **IndexCache:** for l = 1 to N: if c_l == F: I⁽ˡ⁾ ← Indexer_l(X) T⁽ˡ⁾ ← top-k(I⁽ˡ⁾) T_cache ← T⁽ˡ⁾ else: # c_l == S T⁽ˡ⁾ ← T_cache # reuse X ← SparseAttn_l(X, T⁽ˡ⁾) X ← FFN_l(X) `T_cache` is just a temp buffer holding the _current_ index tensor — it gets overwritten at every F layer, so it adds **zero extra GPU memory** over standard DSA. The only real change to the loop is one if/else branch. That's the whole elegance of this method — no architecture surgery, just a routing decision. ## 3. Finding top-k (the indexer mechanics, cleaned up) This part is just DSA's own lightning indexer, for reference since it's what gets shared: Compatibility between query `q` and each candidate position `i`, per block/head: * `s_i = q · W_i + b_i` — raw score for position i * `g_i = max(0, s_i)` — ReLU gate (this is the "lightning" part: cheap, no softmax needed before selection) * `Top-k = argmax_i(g_i)` over all i — pick the k highest-scoring positions This sits _underneath_ MLA (Multi-head Latent Attention). The reason MLA matters here: instead of every head keeping its own full KV, MLA squeezes all heads' KV into one shared **low-rank latent vector** — `latent = x·W^D` (down-projection). The indexer scores against this compressed representation, which is part of why it's so much cheaper per-FLOP than the main attention. ## 4. Two ways to find the F/S pattern The question is: which layers do you keep as F? Two answers, training-free and training-aware — and notably, the "obvious" third answer (similarity-based) **fails**. Order of discovery matters here, so I'm keeping it in the order the paper actually tried things. ### 4.1 Why the naive static pattern fails The dumbest idea: just alternate uniformly, e.g. `F S S S F S S S ...` (1 F every 4 layers). This **doesn't work well**. Why: indexer "importance" is _not_ uniform across depth. Some layers — especially early/transitional ones — are way more sensitive to losing their own indexer than others. A fixed period can easily land an F on a redundant layer and an S on a critical one. You need the model (or data) to tell you which layers are safe to share. ### 4.2 Training-free IndexCache — greedy search No weight updates at all. Just: 1. Start with **all layers = F**. 2. Pool of candidate layers = `{2, 3, ..., N}` (layer 1 is always F — has to seed the cache). 3. Pick a small calibration dataset (cached batches from training data — same batches reused for every candidate evaluation, so loss differences come purely from the pattern, not data noise). 4. For each step: try flipping every remaining F layer to S, one at a time, measure resulting LM loss on the calibration set, and **commit whichever flip increases the loss the least.** 5. Repeat for K steps, where K = target number of S layers (e.g. K = 3N/4 to keep only 1/4 of indexers). This is literally a greedy "convert layers one-by-one, always pick the one with minimum loss increase" search — full search is O(N²) forward passes, but if you've got pipeline-parallel stages (P of them), you can split layers into P blocks and search them in parallel, cutting total passes by roughly P×. **What you get out of this (empirically, from the paper's 30B DSA model + GLM-5):** * The searched pattern reliably beats uniform interleaving at the same retention ratio. * The per-step loss curve has a visible kink — first ~20 layers are "easy" (cheap to convert), the rest are "critical" (loss jumps fast). So there's a real ordering of indexer importance baked into the model, not noise. * This ranking is stable across different calibration sets — it's an intrinsic property of the trained model, not a calibration artifact. * Retaining only **1/4 of indexers** (75% removed) with the searched pattern matches the original model's downstream performance almost exactly. ### 4.3 Training-aware IndexCache — multi-layer distillation If you're willing to retrain (continued pretraining, not from scratch), you can go further: **force the indexer to actually learn to serve multiple layers** , instead of hoping a pattern search finds layers that happen to tolerate sharing. Standard DSA already trains each layer's indexer via KL-divergence distillation against that _same_ layer's aggregated attention distribution `p_t⁽ˡ⁾`. The extension here: if layer `ℓ` is F and serves S layers `ℓ+1, ..., ℓ+m`, train its indexer against **all of them jointly** : L_multi = Σ_{j=0}^{m} [ 1/(m+1) · Σ_t D_KL( p_t^(ℓ+j) || q_t^(ℓ) ) ] where: * `q_t⁽ˡ⁾` = indexer's own output distribution (softmax of its scores) at layer ℓ * `p_t⁽ˡ⁾` = the real aggregated attention distribution at layer ℓ (averaged across heads) * `1/(m+1)` = just averaging over however many layers reuse this same index **Important note (training detail I almost missed):** you don't do this from random init. A randomly initialized model's attention distribution has no real structure yet — forcing the indexer to chase an undefined target just injects noise. So this is always done as continued pretraining / fine-tuning on top of an already-trained DSA model, in two stages: a frozen "dense warm-up" that trains only the indexer, then a "sparse training" phase that activates top-k and trains everything jointly. ## 5. The proof: L_multi and L_avg give the exact same gradient This is the part of my notes that was the messiest, so here's the clean derivation. Define the **averaged target distribution** across the m+1 served layers: p̄_t = Σ_{j=0}^{m} [ 1/(m+1) · p_t^(ℓ+j) ] and the single-target loss using that averaged target: L_avg = Σ_t D_KL( p̄_t || q_t^(ℓ) ) **Claim:** `∇_θ L_multi = ∇_θ L_avg`. **Proof.** The key trick: in `D_KL(p || q)`, only `q` depends on the trainable parameters θ (p is just data — the real attention distribution, treated as a fixed target with `stop-gradient`). So when you differentiate KL divergence w.r.t. θ, the entropy term of `p` (which doesn't depend on θ) vanishes entirely. What's left is just the cross-entropy term: ∇_θ D_KL(p || q_t^(ℓ)) = -∇_θ Σ_s p(s) · log q_t^(ℓ)(s) This is the step I got stuck on in my notebook — I wasn't sure _why_ only the `log q` term survives. The answer is straightforward once you write KL out fully: D_KL(p || q) = Σ_s p(s) log p(s) − Σ_s p(s) log q(s) └──────┬──────┘ └───────┬───────┘ entropy term of p cross-entropy term (no θ dependence, (only term with θ, gradient = 0) via q = softmax(indexer)) Now apply this to `L_multi`: ∇_θ L_multi = - Σ_{j=0}^{m} [1/(m+1)] Σ_t ∇_θ Σ_s p_t^(ℓ+j)(s) log q_t^(ℓ)(s) Since the sum over j and the sum over s are both linear, swap their order and pull the constant log term out: = - Σ_t ∇_θ Σ_s [ Σ_{j=0}^{m} (1/(m+1)) p_t^(ℓ+j)(s) ] · log q_t^(ℓ)(s) └──────────────────┬──────────────────┘ = p̄_t(s) = - Σ_t ∇_θ Σ_s p̄_t(s) log q_t^(ℓ)(s) = ∇_θ L_avg. ∎ So averaging _before_ taking KL and summing the KL terms _after_ are mathematically identical at the gradient level — the indexer ends up being pulled toward the **centroid** of all the attention distributions it serves, not toward any one layer. **Then why use L_multi in practice if they're equivalent?** Pure memory/engineering reason: with `L_multi`, each S layer only needs to send its own predicted `q` value backward. With `L_avg`, you'd need to pass both `p` and `q` for _every_ served layer to compute the average first — which means extra memory overhead and extra runtime cost for no actual gain, since the gradient comes out identical either way. > _My takeaway after sitting with this for a while: a lot of "novel" architecture papers ultimately reduce to "design the right loss function for what you want, and let the network figure out the rest." This derivation is a good concrete example — the multi-layer trick isn't a new optimization method, it's just an equivalent (and cheaper) way to write the same gradient._ ## 6. Performance (30B DSA model, 200K context) Metric | Standard DSA | + IndexCache (1/4 retained) ---|---|--- Prefill latency | 19.5 s | 10.7 s (**1.82× speedup**) Decode throughput (per request) | 58 tok/s | 86 tok/s (**1.48× speedup**) **Why the training-aware version works where uniform static doesn't:** the greedy search has to _avoid_ sensitive layers because the model was never trained to tolerate sharing — without retraining, certain layers are tightly coupled to their own indexer's exact top-k, and feeding them someone else's indices causes a distribution shift that breaks things. Once you train with the multi-layer distillation loss, the S layers themselves _learn to adapt_ to inherited indices, and the F layer's indexer learns to produce a selection that generalizes across all the layers it serves. That joint adaptation is what makes even a dumb uniform pattern work fine after training — the layer-specific sensitivity just disappears. **Extra structural note from the overlap heatmap:** the first layer is _always_ kept as a full F layer (it has to seed the index cache, and early layers attend to a fundamentally different token subset than later ones — overlap with deep layers is ≤0.4). The strongest, most similar index regions cluster near the diagonal — i.e., a layer's indexer output looks most like its _immediate_ neighbors, decaying as you move further away. ## 7. The failure case — and why it's actually an important negative result Before landing on the greedy LM-loss search, the natural-seeming alternative was tried: **pick the sharing pattern by directly maximizing cosine similarity** between attention outputs, since that's cheaper to compute than running full LM-loss evaluations. Build an N×N similarity matrix `S[i][j]` = cosine similarity between layer i's attention output using its own indexer vs. using layer j's indexer instead. Then solve for the best F/S assignment with dynamic programming: dp[i][k] = max over j<i, c_j=F of: dp[j][k-1] + Σ_{m=j+1}^{i-1} S[m][j] — i.e., find the best previous F layer to "branch" from, accumulating similarity scores for every S layer that would reuse it. Solvable exactly by backtracking through the DP table. **This failed.** The similarity-optimal pattern performed about the same as plain uniform interleaving — both clearly worse than the greedy LM-loss search. The reason is the core insight of the whole negative result: > Cosine similarity is a **local** metric — it only tells you how well-preserved a single layer's output is _in isolation_. It can't see how small token-selection mismatches **propagate and compound** through all the downstream layers. Two layers can have near-identical attention outputs (similarity ≈ 1) yet differ in exactly the handful of tokens that turn out to matter several layers later. Those subtle errors accumulate — and a layer-local similarity score has no way to predict that. The LM-loss-based greedy search avoids this because it's a **global, end-to-end** signal — it measures the actual downstream effect of a sharing decision on the whole model's output, not just on one layer's local activation. This is the real lesson: local geometric similarity is a tempting cheap proxy, but for anything where errors compound across depth, you need an end-to-end metric. ## My summary of the idea in one line DSA's indexer recomputes "who matters" from scratch at every layer even though the answer barely changes between adjacent layers — IndexCache just caches that answer and reuses it, and the only real engineering question is _which_ layers are allowed to skip recomputation, which can be found either by greedy search (no training) or learned directly via a provably-equivalent averaged-KL loss (with training). if you found any mismatched detail in this post or want to contribute in paper or working code for indexcache please open issue on github.link
dev.to
June 30, 2026 at 3:55 AM