Expand description
Per-sequence DSA indexer state — the cache the selector reads every decode step.
§Why this exists at all
The indexer scores each pool from k_normed and gate, both projections of the
hidden state (indexer.wk, index_kpool_compress_gate). Neither is recoverable
from the MLA latent — wk · hidden cannot be inverted out of a rank-512 compression —
so the indexer needs its own cache stream alongside the KV cache. HF does the same
thing, keeping indexer state on a per-layer DynamicIndexedLayer via
past_key_values.update_indexer.
§No new subsystem
TransformerLayer::alloc_state is called once per sequence and LayerState is an
Any downcast hook — the same mechanism qwen3_ssm uses for recurrent state. This is
that, with a bigger buffer.
§🪤 Flat, not paged
dsa_kpool_compress and dsa_index_scores index k[raw * D + d] linearly, and
pools are built over absolute positions from the first valid token. So this is one
contiguous per-sequence buffer, not block-table paged. The MLA latent stays paged; only
the indexer stream is flat.
Structs§
- Glm5
Next DsaState - One sequence’s indexer cache for one DSA layer.
Functions§
- dsa_
capacity - THE authoritative indexer-capacity computation. Everything that needs to know how many
rows a sequence’s indexer cache holds calls this —
max_dsa_contextfor the allocation side, and the serve’s pre-model reserve for the budget side. - indexer_
state_ bytes - Bytes ONE sequence’s indexer cache occupies for ONE DSA layer at
capacityrows. - max_
dsa_ context - Longest context DSA can select over, in tokens.