veloxquant_mlx.cache.squeeze_cache module¶
SqueezeAttention-adapted KV cache — 2D layer×token budget attention-mass eviction.
Inspired by “SqueezeAttention: 2D Management of KV-Cache in LLM Inference via Layer-wise Optimal Budget” (Wang et al., 2024, arXiv:2404.04793). Documented as “SqueezeAttention-adapted (VeloxQuant-MLX implementation)” — not a faithful port.
SqueezeAttention is H2O’s cumulative-attention-mass eviction with a data-driven per-layer budget. Where PyramidKV assumes a fixed positional taper resolved at build time, SqueezeAttention measures each layer’s attention concentration from the prefill keys and reallocates a fixed total budget toward broad layers and away from concentrated ones — a 2D (layer × token) budget grid.
The re-budget is one-shot at the prefill boundary, mediated by a shared
SqueezeCoordinator (injected at KVCacheBuilder.for_model build time):
On the first
update_and_fetch(the prompt), the layer computes its concentration score over the incoming keys and reports it to the coordinator.Once every attention layer has reported, the coordinator computes the per-layer budget schedule (
squeeze_budgets) and publishes it.The layer pulls its resolved budget and stamps it onto every head’s eviction state; decode steps then run against the frozen budget.
Until the coordinator finalises (or when constructed with no coordinator, e.g.
KVCacheFactory.create), the layer uses squeeze_budget (the average) as a
fallback and behaves as one uniform-budget H2O layer. The 2D reallocation only
takes effect via for_model.
- This is the sixth distinct eviction configuration in VeloxQuant-MLX:
SnapKV-adapted : score-based, once at prefill end.
StreamingLLM-adapted : positional (recency + sink), every step.
H2O-adapted : cumulative attention mass, uniform budget, every step.
TOVA-adapted : current-step attention weight (memoryless), every step.
PyramidKV-adapted : H2O scoring with a fixed per-layer pyramid budget.
SqueezeAttention-adapted : H2O scoring with a DATA-DRIVEN per-layer budget (measured concentration, one-shot re-budget at prefill).
- Adaptation limitations (stated plainly):
Key-as-query proxy for both concentration and eviction (same as H2O-adapted / PyramidKV-adapted).
Cosine-dispersion proxy for attention entropy (paper uses actual attention maps, not visible at cache level).
One-shot re-budget at the prefill boundary; frozen for decode.
No RoPE position-ID remapping after eviction.
Uniform budget across heads within a layer.
- Byte accounting:
squeeze_kept_bytes — fp16 bytes for currently retained K + V tokens full_seq_bytes — hypothetical fp16 cost if all tokens were kept compression_ratio — full_seq_bytes / squeeze_kept_bytes (> 1 = savings) tokens_seen — total token positions ever passed to update_and_fetch tokens_kept — tokens currently in the first (B=0, H=0) head’s cache layer_budget — this layer’s resolved (or fallback) budget (diagnostic) concentration — this layer’s measured concentration score (diagnostic)
- class veloxquant_mlx.cache.squeeze_cache.SqueezeAttentionCache(config, layer_id=None, coordinator=None)[source]¶
Bases:
KVCacheKV cache implementing SqueezeAttention-adapted 2D eviction for one layer.
- Parameters:
config (
Any) –KVCacheConfig. Fields consumed:squeeze_budget(int, default 512) — average/fallback budget.squeeze_n_sink(int, default 4) — leading positions never evicted.squeeze_resolved_budget(int or None) — an explicit budget override(mainly for single-cache / testing); normally None and the coordinator supplies the budget after prefill.
layer_id (
int|None) – This layer’s index (used to report/query the coordinator). None for single-cache construction (behaves as uniform H2O).coordinator (
SqueezeCoordinator|None) – SharedSqueezeCoordinator, or None. When present, the layer reports concentration at prefill and pulls a resolved budget.
Notes
No
.bitsattribute — stores and returns fp16 K/V directly. Per-head state is lazily initialised on the first call. The one-shot re-budget happens on the firstupdate_and_fetchonce the coordinator finalises. Writes through to the basemlx_lmKVCache’sself.keys/self.values/self.offseton every call so.statestays valid (mlx_lm’sgenerate()reads it unconditionally during chunked prefill);is_trimmable()reportsFalsesince the internal per-token state can’t be rolled back by a base-classtrim()(see #83).- update_and_fetch(keys, values)[source]¶
Absorb new K/V tokens, apply SqueezeAttention eviction, return retained window.
On the first call the layer reports its concentration and (once the coordinator finalises) adopts its resolved budget before eviction runs.
- Parameters:
keys (
array) –[B, H, S, D]new key tokens (any dtype; cast to fp16).values (
array) –[B, H, S, D]new value tokens.
- Returns:
(K_out, V_out)both[B, H, n_kept, D]fp16, wheren_kept <= layer_budgetfor all heads.
- is_trimmable()[source]¶
False: trim() would only roll back base-class offset bookkeeping, not the internal per-token eviction/compression state that actually determines what gets returned, silently corrupting future calls.
- Return type:
- property squeeze_kept_bytes: int¶
Bytes currently stored across all heads (fp16 K + V, kept tokens only).
- property compression_ratio: float¶
full_seq_bytes / squeeze_kept_bytes; > 1 means memory savings over fp16.
- property tokens_seen: int¶
Total token positions ever passed to update_and_fetch (all heads summed).
- property merge¶