KV-Cache Optimization Techniques
Advanced KV-cache management: PagedAttention, prefix caching, KV quantization (KV-INT4/INT8), token eviction strategies, sliding window cache, multi-query sharing, and cache compression via low-rank projections.
Prerequisites
Table of Contents
- Learning Objectives
- Notation
- Core Intuition
- PagedAttention (vLLM)
- Prefix Caching
- KV-Cache Quantization
- Token Eviction Strategies
- Sliding Window Cache
- Multi-Query and Grouped-Query Caching
- Low-Rank KV Compression
- Cache-Aware Scheduling
- Common Pitfalls
- Summary
- Exercises
Learning Objectives
- Explain memory fragmentation in KV-cache and how PagedAttention solves it.
- Derive the memory savings from KV quantization (INT4, INT8).
- Design token eviction policies based on attention scores.
- Analyze the tradeoffs of sliding window vs full cache.
- Explain how prefix caching enables efficient shared prompts.
Notation
- — page size (number of tokens per page)
- — total pages allocated
- — fraction of shared prefix between requests
- — attention score threshold for eviction
Core Intuition
The KV-cache is the dominant memory consumer during LLM serving (often exceeding model weights for long contexts). Naive allocation reserves maximum-length contiguous memory per request, causing massive waste. Modern systems treat KV-cache like virtual memory: paging, sharing, compression, and intelligent eviction dramatically improve throughput.
KV-Cache Optimizations
PagedAttention (vLLM)
Problem: Pre-allocating contiguous memory for max sequence length wastes 60–80% of GPU memory (requests rarely use full context).
Solution: Store KV-cache in fixed-size pages (blocks), allocated on demand.
Architecture:
- Physical memory divided into pages of size tokens.
- Each request has a page table mapping logical KV positions to physical pages.
- Pages allocated only when needed; freed when request completes.
Benefits:
- Near-zero internal fragmentation (waste tokens per request).
- Memory shared across requests with common prefixes.
- Dynamic allocation enables much higher batch sizes.
Attention computation: Modified to gather pages from non-contiguous memory:
Memory utilization: Increases from ~20–40% (static) to ~95% (paged).
Prefix Caching
Observation: Many requests share common prefixes (system prompts, few-shot examples, shared documents).
Implementation: Hash the token sequence; if the KV-cache for a prefix already exists, reuse it via copy-on-write.
Savings: For requests with tokens: saves → massive for batch serving.
Radix tree: Organize cached prefixes in a radix tree for efficient lookup and longest-prefix matching.
KV-Cache Quantization
Reduce cache precision from FP16 to INT8 or INT4:
Per-token or per-channel calibration:
- Per-token: one scale/zero-point per token (per row of K/V).
- Per-channel: one scale per feature dimension (per column).
Memory reduction:
- FP16 → INT8: 2x reduction in KV-cache.
- FP16 → INT4: 4x reduction.
Quality impact: INT8 KV-cache typically has negligible quality loss ( on benchmarks). INT4 KV requires careful calibration but is increasingly viable.
KIVI (2024): Quantize K to per-channel INT2 and V to per-token INT2 with residual FP16 for recent tokens. Achieves 10x compression with minimal quality loss.
Token Eviction Strategies
When KV-cache exceeds budget, evict less important tokens.
Strategies:
1. Attention-score based (H2O): Keep tokens with highest cumulative attention scores ("Heavy Hitters"):
Keep top- tokens by importance + recent window.
2. Sliding window + sink tokens (StreamingLLM): Always keep the first few tokens ("attention sinks") + last tokens. Discard middle.
3. Random eviction: Surprisingly competitive baseline — remove random tokens beyond the window.
4. Learned eviction: Train a small network to predict which tokens will be needed.
Sliding Window Cache
Only cache the last tokens (discard everything beyond):
Fixed memory: Cache size is bounded regardless of context length.
Effective context: With layers and window , information can propagate tokens through the residual stream (though exponentially attenuated).
Used in: Mistral (alternating sliding window + full attention layers).
Multi-Query and Grouped-Query Caching
MQA: All heads share one K/V → cache is the size of MHA.
GQA with groups: Cache is the size.
Tradeoff analysis:
For LLaMA-2 70B: reduction.
This is orthogonal to quantization: GQA + INT4 KV = 32x total reduction.
Low-Rank KV Compression
Observation: Across the sequence, K and V matrices often lie in a low-rank subspace.
Approach: Project cached KV through learned low-rank matrices:
Store instead of . Compression ratio: .
Attention becomes: (extra projection).
Cache-Aware Scheduling
Batching strategy: Group requests by prefix length to maximize prefix cache reuse.
Preemption: When memory is full, preempt (swap to CPU/disk) the least-recently-used request's KV-cache rather than evicting tokens.
Chunked prefill: Process long prompts in chunks, overlapping prefill of new requests with decode of existing ones — maximizes GPU utilization.
Common Pitfalls
Pitfall 1. Applying token eviction uniformly across layers. Different layers attend to different patterns; important tokens vary by layer. Layer-wise eviction policies perform better.
Pitfall 2. Ignoring "attention sink" tokens. The first few tokens often receive disproportionate attention regardless of content (due to softmax normalization). Evicting them breaks the model.
Pitfall 3. Over-quantizing KV-cache for long-context tasks. INT4 KV works well for short contexts but quality degrades for tasks requiring precise retrieval from early tokens.
Summary
- PagedAttention eliminates memory fragmentation → near-100% memory utilization.
- Prefix caching reuses shared prompt KV-cache across requests.
- KV quantization (INT8/INT4) reduces cache 2–4x with minimal quality loss.
- Token eviction (H2O, StreamingLLM) enables unbounded context with fixed memory.
- Sliding window provides O(1) cache with bounded receptive field.
- GQA + quantization compose multiplicatively: up to 32x cache reduction.
Exercises
Exercise 1. For PagedAttention with page size , compute the maximum wasted memory per request and compare to static allocation with max .
Exercise 2. Derive the memory savings from prefix caching for requests sharing a 1024-token system prompt.
Exercise 3. Compute the KV-cache size for a 7B model () at in (a) FP16, (b) INT8, (c) INT4 with GQA .
Exercise 4. Design a token eviction policy for a streaming chat application where the model must remember user preferences stated at the beginning.
Exercise 5. For the "attention sink" phenomenon: explain mathematically why the first token receives high attention scores even when semantically irrelevant.