6.1.13 · D3 · HinglishScaling & Efficient Architectures

Worked examplesKV-cache optimization

3,619 words16 min read↑ Read in English

6.1.13 · D3 · AI-ML › Scaling & Efficient Architectures › KV-cache optimization

Shuru karne se pehle, un symbols ki ek choti si reminder jo hum use karte rahenge, taaki koi peeche na rahe:


Scenario matrix

Har KV-cache question in mein se kisi ek cell ka hota hai. Neeche diye gaye examples shuru mein declare karte hain ki woh kis cell(s) ko cover karte hain.

# Case class Concrete trigger Covered by
A Empty / first token () pehle token ka prefill, cache empty se shuru Ex 1
B Growing cache, one step token append karo, positions pe attend karo Ex 2
C Prefill vs decode asymmetry poora prompt ek saath jaata hai, phir ek-ek karke decode Ex 3
D Zero / degenerate input , ya single-head (), ya bahut chhota Ex 4
E Limiting behaviour () cache memory kab model weights se aage nikal jaati hai? Ex 5
F Head-layout variants standard vs MQA vs GQA cache size Ex 6
G Real-world word problem "kya yeh 32 GB GPU pe serve hoga?" — deployment sizing Ex 7
H Exam twist sliding window: cache barhna band, break-even token dhundo Ex 8

Hum inhe order mein attack karte hain. Cells A–C mechanics hain, D–E edge aur limit, F–H engineering reality.


Example 1 — Cell A: empty cache, pehla token

Forecast: Abhi compute karne se pehle andaza lagao — cache mein pehle kitne rows hain? Aur ek token ke baad?

Steps:

  1. Generation se pehle, cache empty hai. Iska shape hai — literally zero rows. Yeh step kyun? Caching incremental hai; pehle token ke exist hone se pehle kuch bhi remember karne ke liye nahi hota. Yeh woh base case hai jis se har loop shuru hoti hai.

  2. Pehle token ke projections compute karo: aur , dono ka shape hai. Yeh step kyun? token 1 ki embedding hai (ek length- vector). Fixed matrix se multiply karne par is token ki key saare 4 heads ke liye milti hai. Value ke liye bhi yahi. Dekho projection step.

  3. Append karo. Cache se ho jaata hai. Yeh step kyun? Appending hi poori trick hai: hum exactly ek row per token badhate hain.

  4. Store hue numbers count karo. Do matrices (K aur V), har ek numbers: Yeh step kyun? Yeh parent note ka per-token memory formula hai, par evaluate kiya hua.

Verify: Token 1 ka attention sirf position 1 par attend karna chahiye — ek score (ek score per head, ek position). Exactly 1 row wale cache ke saath exactly yahi milta hai. Units check: . ✓


Example 2 — Cell B: ek growth step, teesra token

Forecast: Token 3 ke score row ki width (kitne columns) kitni hogi?

Steps:

  1. Cache pehle: (tokens 1,2). Yeh step kyun? Hum sirf re-read karte hain; kabhi recompute nahi karte. Cache ka yahi point hai.

  2. Naye token ki key aur value compute karo: aur , dono ka shape , jahan token 3 ki embedding hai. Yeh step kyun? Sirf token 3 genuinely naya hai, isliye sirf iske K aur V compute karne hain — woh reusable "what previous tokens offer" pieces jo hum cache mein append karenge.

  3. Naya query alag compute karo: , yeh bhi — aur hum ise cache nahi karte. Yeh step kyun? encode karta hai "token 3 kya dhundh raha hai". Har future token apna fresh query lekar aata hai, aur purane queries par kabhi re-attend nahi hota, isliye cache karna memory waste hoga (parent mein yeh Mistake 1 hai). Keys aur values yaad rakhe jaate hain; queries hamesha ek use ke baad discard kar diye jaate hain.

  4. K aur V append karo: cache ho jaata hai. ( append nahi hota.)

  5. Score shape. Har head ke liye, (ek vector) 3 cached keys () se dot product karta hai: Yeh step kyun? Ek row per head (4), ek column per attended position (3). scaling dot products ko blow up hone se rokti hai (scaled dot-product attention se).

Figure — KV-cache optimization
Figure 1 — cache append aur score fan-out. Left mein, do lavender rows frozen cache hain () jo hum kabhi recompute nahi karte; coral row (, marked NEW) woh single row hai jo humne abhi append ki, cache ko banate hue. Right mein, mint box fresh query hai — teen coral arrows trace karo: 3 cached keys mein se har ek tak wapas pahunchta hai, aur vertical slate arrow (labelled "/ 8") se divide karta hai butter box se pehle jo result collect karta hai: ek score, ek row per head, teen columns teen attended positions ke liye. Notice karo ka koi arrow cache mein nahi jaata — yeh ek baar use hota hai aur discard ho jaata hai, exactly jaisa step 3 ne argue kiya.

Verify: Figure dekho — naya row (coral) height-1 hai, aur score arrow exactly 3 cached columns tak fan out karta hai. Column count = current token index = 3. ✓ Aur , ek clean integer. ✓


Example 3 — Cell C: prefill vs decode

Forecast: Kya cached run roughly times sasta hoga, ya beeche mein kuch, bade prefill chunk ki wajah se?

Steps:

  1. Unit fix karo. Ek token project karna matlab iska -vector ko mein se har ek se multiply karna (har ek ), jiska cost multiply-adds hai. Hum isse ek block kehte hain. tokens project karna independent aisi products hain, isliye exactly blocks cost hogi — chahe ek-ek karke karo ya ek single batched matmul mein fuse karo. Yeh step kyun? Ek batched matmul alag waalon se kam arithmetic nahi karta — woh same token-products ko ek call mein pack karta hai hardware efficiency ke liye. Isliye " tokens ek matmul mein" phir bhi blocks kaam hai, constant nahi. Yehi wajah hai ki tokens ka prefill blocks cost karta hai, constant nahi.

  2. Naive projection cost. Har token position par naive model saare positions ke liye K,V recompute karta hai: blocks. Yeh step kyun? Cache ke bina, token generate karna sequence ko fresh treat karta hai — har baar projections.

  3. Cached projection cost. Prefill saare prompt tokens ko ek baar project karta hai (10 blocks, step 1 se), phir decode steps mein se har ek exactly 1 naya token project karta hai (5 blocks): blocks. Yeh step kyun? Cache ka matlab hai hum prompt ka K,V kabhi redo nahi karte, aur har decode step sirf apna single naya token add karta hai.

  4. Speed ratio. . Yeh step kyun? Yeh theoretical "" speed-up ki concrete cash value hai — lekin yeh 15 nahi, 8 aata hai, kyunki naive sum hai, nahi, aur cached cost ke barabar hai.

Verify: General check: naive , cached , ratio . ke liye: . ✓ Step 4 se match karta hai. Parent ka "" big-O scaling hai; exact ratio hai.


Example 4 — Cell D: degenerate inputs

Forecast: In mein se kaunsa zero bytes deta hai, aur kaunsa sabse chhota non-zero cache deta hai?

Steps:

  1. (a) . Total cache . Yeh step kyun? Empty sequence → kuch store nahi karna. Confirm karta hai ki formula gracefully degrade karta hai; koi divide-by-zero nahi, koi negative memory nahi.

  2. (b) . Per token bytes. Yeh step kyun? Single-head model ko sirf mein collapse karta hai. Yeh MQA per-token figure bhi hai (ek shared K/V) — Ex 6 ka preview.

  3. (c) , . Per token bytes. Yeh step kyun? Head dimension ko 1 tak shrink karne se har key/value ek single scalar ban jaata hai. Phir bhi 8 heads hain, toh K ke liye 8 scalars + V ke liye 8 = 16 numbers = 32 bytes.

Verify: (a) . ✓ (b) bytes, non-zero aur "real" cases mein heads ki number ke hisaab se sabse chhota. (c) bytes yahan actually sabse chhota total hai. Ordering: . ✓ Har formula degenerate inputs ke neeche finite aur non-negative rehta hai.


Example 5 — Cell E: crossover limit ()

Forecast: Hazaron tokens? Laakhon? Order of magnitude guess karo.

Steps:

  1. Per-token full-model cache. bytes KB. Yeh step kyun? Yeh parent ka formula layers par summed hai, per token. Har naya token yeh fixed slab add karta hai.

  2. Cache = weights set karo. solve karo: Yeh step kyun? Cache linearly mein badhta hai jabki weights constant hain — isliye hamesha ek crossover hoti hai. Iske baad, memory cache se dominated hoti hai, model se nahi.

  3. Limit interpret karo. Jaise cache sab kuch dwarf kar deta hai: . Yehi wajah hai ki MQA/GQA aur sliding windows exist karte hain (Ex 6, 8). Yeh step kyun? Parent ka poora "advanced optimizations" section is unbounded growth ka response hai.

Verify: MB. ✓ Linear-in- growth ka matlab hai ratio ka koi finite bound nahi hai. ✓ (Yahan MB = bytes, decimal — units clarification ke liye Ex 7 dekho.)


Example 6 — Cell F: standard vs MQA vs GQA

Forecast: MQA koi bada divisor chhota hona chahiye. Exactly kitne factor se, aur GQA kahan land karta hai?

Steps:

  1. (a) Standard. bytes KB. Yeh step kyun? Har query head apna K aur V rakhta hai. Yeh woh baseline hai jo parent ka formula deta hai.

  2. (b) MQA. Ek shared K/V head: bytes. Yeh step kyun? MQA K/V heads ki jagah ek single rakh deta hai. Reduction .

  3. (c) GQA, . bytes KB. Yeh step kyun? GQA ek K/V per group rakhta hai. 8 groups ke saath reduction hai — parent ka stated Llama-2 figure.

Figure — KV-cache optimization
Figure 2 — cache size staircase. Teen bars, sabse lambe se sabse chhote: lavender bar standard multi-head hai 32,768 bytes/token/layer par (saare 64 K/V heads rakhe hue); mint bar GQA hai 8 groups ke saath 4,096 bytes par (labelled "8x smaller"); coral bar MQA hai 512 bytes par (labelled "64x smaller"). Left-to-right padhne par staircase har baar girta hai jab hum zyada queries mein K/V heads share karte hain — height literally memory bill hai, isliye chhota bar sasta cache hai. GQA deliberately dono extremes ke beech mein baith hai: MQA ki bahut zyada saving, lekin uski quality loss bahut kam.

Verify: Standard B; MQA B → ratio . ✓ GQA B → ratio . ✓ GQA MQA aur standard ke beech mein hai, exactly jaisa figure ka staircase dikhata hai. ✓


Example 7 — Cell G: real-world deployment sizing

Forecast: GPU ka kaafi headroom hai, toh kya cache yahan problem bhi hai — haan ya nahi?

Steps:

  1. Per-user cache (standard). Ex 5 se, per-token full-model cache bytes. 2048 tokens ke liye: bytes. Binary MiB mein (): MiB exactly. Yeh step kyun? Ek user ka cache = per-token slab context length. Bytes se cleanly divide hoti hain, isliye 72 MiB exact hai, rounded nahi.

  2. 8 users + weights. MiB GiB. Yeh step kyun? Concurrent requests mein se har ek ko apna khud ka cache chahiye; weights ek baar shared hain. Total 32 GiB budget mein fit hona chahiye.

  3. Fit check. haan, easily fit ho jaata hai. Weights reserve karne ke baad, caches ka budget MiB, isliye Yeh step kyun? Cache, weights nahi, concurrency ke liye scaling bottleneck hai — yeh core inference-optimization insight hai.

  4. MQA switch. MQA K/V ko head factor se shrink karta hai, isliye per-user cache MiB. Max users . Yeh step kyun? Cache cut karne se serviceable concurrency roughly multiply hoti hai (448 → ~5378). Yehi wajah hai production LLMs MQA/GQA use karte hain — dekho deployment.

Verify: Standard: MiB, aur MiB. ✓ Max standard users ; MQA ; ratio . ✓ Units: MiB / (MiB/user) = users, poora binary throughout. ✓


Example 8 — Cell H: exam twist, sliding window break-even

Forecast: Kya window cache token 1 se hi memory bachata hai, ya kisi threshold ke baad?

Steps:

  1. Growth laws. Full cache rows (hamesha badhta hai). Window cache rows . Yeh step kyun? Sliding window exceed hone par purana token drop kar deta hai, isliye iska size 512 par plateau ho jaata hai — constant memory, parent ke "Sliding Window" section se.

  2. Pehla farq. Har ke liye dono caches rows rakhte hain (abhi tak kuch drop nahi hua), isliye woh identical hain. par full cache ke 513 rows hain lekin window ne token 1 already evict kar diya hai aur sirf rakhta hai. Toh woh pehli baar par alag hote hain. Yeh step kyun? Window size se neeche koi saving nahi hoti; saving exactly se ek token aage shuru hoti hai. Woh threshold hi woh "break-even" hai jo question pooch raha hai.

  3. par ratio. Full rows; window rows. Yeh step kyun? Long context par window yahan chhota hai — tradeoff hai 512 tokens se purane dependencies ka loss (relevant to long-horizon decoding jahan distant context matter kar sakta hai).

  4. Limit behaviour. Window memory constant hai jabki full linear hai, isliye jaise ratio : saving unbounded badhti hai. Yeh step kyun? 100K+ token contexts ke liye sliding-window attention ka yahi poora point hai — memory barhna bilkul band ho jaata hai.

Verify: aur → pehla divergence par. ✓ . ✓ Ratio par unbounded hai. ✓


Recall Self-check

With-cache projection cost vs naive, exact ratio for length ? ::: (nahi — woh big-O hai). KV-cache pehli baar length- window cache se kab differ karta hai? ::: Token par. MQA cache reduction factor vs standard multi-head with heads? ::: (ek shared K/V head). kabhi cache kyun nahi hota? ::: Har naye token ko ek fresh query chahiye ("woh kya dhundh raha hai"); purane queries par kabhi re-attend nahi hota. Per-token full-model cache formula? ::: .

Related: 6.3.1-model-quantization upar diye gaye har formula mein bytes-per-number factor ko shrink karta hai — head-count tricks se orthogonal, aur unke saath stack hota hai.