6.1.13 · HinglishScaling & Efficient Architectures

KV-cache optimization

2,745 words12 min readRead in English

6.1.13 · AI-ML › Scaling & Efficient Architectures

Yeh Kyun Chahiye: First Principles se Derivation

Naive Attention Cost

Multi-head self-attention mein, sequence length ke liye, hum compute karte hain:

Step-by-step cost analysis:

  1. Training ke dauran (teacher forcing): Hamare paas ek saath saare tokens hote hain.

    • ek baar compute hote hain
    • Attention matrix: operations
    • Total per layer:
  2. Autoregressive generation ke dauran (problem):

    • Position par token generate karo: compute karo ✓
    • Position par token generate karo: compute karo (naya), lekin recompute
    • Position par token generate karo: recompute aur

Yeh step kyun? Har generation step mein sirf ek naya token add hota hai, lekin caching ke bina model is poori sequence ko fresh treat karta hai aur saare previous tokens ke projections recompute karta hai.

tokens generate karne ka total naive cost:

Yeh sequence length mein quadratic hai sirf projection overhead ke liye, attention karne se pehle bhi!

KV-Cache Solution

Savings ki derivation:

Yeh kyun kaam karta hai: Attention mein causality mask ensure karta hai ki token sirf positions par attend kare. Kyunki for fixed hain (model generation ke dauran frozen hai), unki values kabhi nahi badalti — caching ke liye perfect.

Full-model cache (saare layers mein) = .

Example: GPT-3 style model (, heads, , fp16):

  • Per token, per layer:
  • Per token, saare 96 layers:
  • 2048 tokens ke liye (saare layers):

Yeh step kyun? Hamare paas 2 matrices hain (K aur V), har ek ka size (num_tokens × num_heads × head_dim) hai, jo per layer store hoti hain. Full-model cost layers ki number se multiply hoti hai, isliye per-token figure ~48 KB (ek layer) se ~4.7 MB (saare 96 layers) tak jump karta hai.

Worked Examples

Step 1: Previous cache state (tokens 1-2 generate karne ke baad):

Yeh step kyun? Har ka shape (num_heads, head_dim) = (4, 64) hai. Ab tak 2 tokens generate ho chuke hain.

Step 2: Naye token ke liye projections compute karo:

Step 3: Cache update karo (concatenation):

Step 4: Sirf use karke saare cached keys ke saath attention compute karo:

Yeh step kyun? (shape 4×64) cached K se multiply hota hai (shape 3×4×64 → transpose karke 4×64×3). Har head ko ek 1×3 score vector milta hai (3 positions par attending).

Cost: ek token ke projections ke liye + attention scores ke liye. ka koi recomputation nahi.

100-token sequence generate karna:

Cache ke bina:

  • Per layer, per token : key-value pairs compute karo →
  • Total: FLOPs

Cache ke saath:

  • Per layer, per token: 1 naya K, V compute karo →
  • Total: FLOPs
  • Speedup: 50× ( ke liye approximately factor se match karta hai)

Memory overhead:

  • Cache size:

Yeh kyun important hai: 3.7 MB, 500 MB model weights ke comparison mein negligible hai, lekin 98% projection compute bachata hai.

Advanced Optimizations

1. Multi-Query Attention (MQA)

Cache reduction:

Yeh step kyun? heads ke saath, MQA 32× kam KV-cache memory use karta hai. Quality drop typically 1-2% perplexity hota hai.

2. Grouped-Query Attention (GQA)

Middle ground: query heads ko groups mein group karo (), har group ek K, V head share karta hai.

Example: Llama-2 70B , use karta hai (standard ke against 8× cache reduction).

3. Sliding Window / Local Attention

Bahut lambi sequences ke liye, sirf last tokens cache karo:

Tradeoff: Constant memory, lekin tokens se aage long-range dependencies kho jaate hain.

Use case: 100K+ token contexts ke saath summarization jahan recent context sabse zyada important hota hai.

4. FlashAttention Integration

FlashAttention operations ko fuse karke aur SRAM tiling use karke, poora score matrix materialize kiye bina attention compute karta hai. KV-cache + FlashAttention mila ke kaam karte hain:

  • Cache redundant K, V projections eliminate karta hai
  • FlashAttention attention scores ka memory overhead eliminate karta hai

Combined speedup: Long sequences ke liye 10-20× (dono alag-alag bottlenecks reduce karte hain).

Common Mistakes

Yeh sahi kyun lagta hai: ko bhi ek matrix multiply chahiye, toh caching logical lagti hai.

Steel-man: Ek typical forward pass mein, cache karna help karta. Lekin autoregressive generation mein, har naya token ek fresh query generate karta hai jo saari previous positions par attend karta hai. Humein token ke liye naya chahiye kyunki yeh encode karta hai "naya token kya dhundh raha hai."

Fix: Sirf K aur V reusable hain kyunki yeh represent karte hain "previous tokens kya offer karte hain." Query represent karta hai "current token ko kya chahiye" — ise recompute karna hi hoga.

Yeh sahi kyun lagta hai: Cache mein data hai, toh use kyun na karein?

Steel-man: Full sequences ke saath training ke dauran hum causal mask use karte hain. Yeh bhoolna asaan hai ki generation ke dauran bhi yeh zaruri hai.

Fix: Caching ke saath bhi, causal mask apply karo:

Yeh ensure karta hai ki token sirf positions dekhe (chahe physically autoregressive mode mein abhi exist hi na karein, yeh batched generation ke liye matter karta hai).

Yeh sahi kyun lagta hai: Notation memory kehta hai.

Steel-man: Notation constants hide karta hai. 32-layer, 32-head model ke liye fp16 mein:

tokens ke liye: sirf cache ke liye ~105 GB (zyaatar GPU memory se zyada).

Fix: Hybrid strategies use karo jaise sliding window cache, purane cache ko CPU par offload karna, ya ultra-long contexts ke liye sparse attention.

Implementation Details

Typical PyTorch pattern:

class CachedAttention:
    def __init__(self):
        self.kv_cache = None  # Will hold (batch, num_heads, seq_len, head_dim)
    def forward(self, x, use_cache=True):
        B, T, C = x.shape
        Q = self.W_q(x)  # Always compute fresh
        K_new = self.W_k(x)
        V_new = self.W_v(x)
        if use_cache and self.kv_cache is not None:
            K_cached, V_cached = self.kv_cache
            K = torch.cat([K_cached, K_new], dim=2)  # Concat along seq_len
            V = torch.cat([V_cached, V_new], dim=2)
        else:
            K, V = K_new, V_new
        # Standard attention computation
        scores = (Q @ K.transpose(-2, -1)) / math.sqrt(self.head_dim)
        atn = F.softmax(scores, dim=-1)
        out = atn @ V
        
        if use_cache:
            self.kv_cache = (K.detach(), V.detach())  # Detach to avoid gradient retention
        
        return out

Detach kyun? Poore cached history ke through backprop rokta hai (sirf training ke dauran zaruri hai; inference ke dauran waise bhi koi gradients nahi hote).

Kab Kya Use Karein

Context Length Strategy Example Use Case
< 2K tokens Standard KV-cache Chatbot turns, code completion
2K - 8K KV-cache + MQA/GQA Document Q&A
8K - 32K Sliding window cache Long-form writing
32K+ Sparse/local + offload Book summarization, legal docs
Recall Ek 12-Saal Ke Bache Ko Samjhao

Socho tum ek story likh rahe ho ek word at a time. Har baar jab tum naya word likhte ho, tumhe yaad rakhna hota hai ki saare previous words kiske baare mein the taaki tumhara naya word sense kare.

Slow tarika: Har baar jab tum naya word likhte ho, tum poori story ki shuruaat se re-read karte ho aur har word ke baare mein notes lete ho. 100 words likhne ka matlab hai story 100 baar padhna!

KV-cache tarika: Pehli baar jab tum har word padhte ho, sticky notes par notes likhte ho (wahi "cache" hai). Jab tum word #50 likhte ho, tum sirf apne 49 sticky notes par ek nazar daalte ho instead of poori story re-read karne ke. Tum sirf word #50 ke liye ek naya sticky note add karte ho.

Tradeoff: Tumhe apni desk par saare sticky notes ke liye jagah chahiye (memory), lekin tum bahut sara time bachate ho poori story re-read na karke. Agar tumhari desk bahut bhar jaaye (bahut lambi story), toh shayad tum sirf last 20 sticky notes rakho aur puraane throw away karo (sliding window).


Connections

  • 6.1.1-transformer-architecture - Self-attention mechanism jise KV-cache optimize karta hai
  • 6.1.4-multi-head-attention - Kai heads cache requirements ko kaise multiply karte hain
  • 6.2.3-inference-optimization - Deployment speedups ki broader category
  • 6.3.1-model-quantization - Lower precision (int8, fp16) ke through cache memory reduce karna
  • 5.4.2-beam-search - Generation algorithm jo multiple beams ke saath cache-intensive ho jaata hai
  • 6.1.11-sparse-attention - attention cost reduce karne ka alternative approach
  • 7.2.1-llm-deployment - Real-world systems jahan cache management critical hai

#flashcards/ai-ml

KV-cache kis primary problem ko solve karta hai? :: Autoregressive generation ke dauran, previously generated tokens ke key aur value projections ka redundant recomputation rokna. Caching ke bina, hum har step par saare prior tokens ke K aur V recompute karte hain, jisse cost aati hai ki jagah.

KV-cache memory formula per layer derive karo :: Cache size = . 2 alag K aur V matrices ke liye hai, sequence length hai, attention heads ki number hai, head dimension hai, aur bytes precision hai (fp16 ke liye 2, fp32 ke liye 4). Full model ke liye se multiply karo.

Hum Query (Q) projections cache kyun nahi karte?
Query represent karta hai "current token kya dhundh raha hai" aur har naye token ke liye recompute karna padta hai. Keys aur values represent karte hain "previous tokens kya offer karte hain," jo past tokens ke liye fixed hain, isliye unhe safely cache kiya ja sakta hai. Q cache karna naye token ko apna context-dependent query banane se rokta.
Multi-Query Attention (MQA) kya hai aur iska cache benefit kya hai?
MQA ek single shared K aur V projection saare query heads mein use karta hai, per-head K, V pairs ki jagah. Yeh cache size ko (heads ki number) factor se reduce karta hai, kyunki cache ho jaata hai ki jagah. Trade-off: massive memory savings ke liye ~1-2% quality drop.

GPT-2 Small ke liye 512 tokens generate karne par KV-cache size calculate karo :: GPT-2 Small: 12 layers, 12 heads, , fp16. Cache = bytes = 18.9 MB. Yeh per-sample hai; batch size ise multiply karta hai.

KV-cache ke saath bhi causal masking kyun zaruri hai?
Generation ke dauran cache mein sirf past tokens hone ke bawajood, masking kyun crucial hai: (1) batched generation jahan sequences ki alag-alag lengths hain, (2) training behavior ke saath consistency, (3) attention score indexing mein off-by-one errors rokna. Mask ensure karta hai ki position sirf positions par attend kare.
Grouped-Query Attention (GQA) kya hai?
Standard multi-head attention aur MQA ke beech ka middle ground. Query heads ko groups mein divide kiya jaata hai (jahan ), aur har group ek K, V head share karta hai. Partial cache reduction ( factor) deta hai full MQA ke comparison mein kam quality degradation ke saath. Example: Llama-2 70B use karta hai.
KV-cache kab bottleneck ban jaata hai?
(1) Bahut lambi sequences (100K+ tokens) jahan memory phir bhi GPU capacity se zyada ho, (2) Production mein large batch sizes, (3) Kai layers aur heads wale models (GPT-3 scale), (4) Multi-beam search cache ko beam width se multiply karta hai. Solutions: sliding window, offloading, ya sparse attention.

Concept Map

recomputes

costs

motivates

stores

reused via

reduces to

yields

makes past KV fixed

trades

scales with

Autoregressive generation

Redundant KV projections

Naive cost O L squared d squared

KV-cache

Cached K and V matrices

Compute once and append

Cached cost O L d squared

Speedup factor L

Causal mask

Extra memory per layer

2 x layers x L x h x d_k x precision