Terug naar de blog

128k context op desktop is gelogen. De KV-cache at het op.

22 september 2026

Elke modelkaart praalt tegenwoordig met een 128k-contextvenster. Op een desktop is dat nummer een huurcontract dat je RAM tekent zonder het te lezen. Wat bepaalt hoe ver je een lang document kunt duwen, zijn niet de gewichten — het is de KV-cache, en die schaalt mee met de context als een belasting die in iemand anders munt werd afgesproken.

Het contextvenster is geen functie die je omzet. Het is een geheugenhuur die je elke seconde betaalt zolang de server draait.

Hoeveel RAM vreet een 128k-context er werkelijk door?

De rekenkunde is publiek en kort. Zoals Transformer Inference Arithmetic uiteenzet, bewaart de KV-cache twee tensoren — keys en values — voor elke laag, elke KV-head, elke token:

cache_bytes = 2 × lagen × context × kv_heads × head_dim × bytes_per_element

Neem Llama 3.1 8B: 32 lagen, 8 KV-heads, head_dim 128 — rechtstreeks uit de config.json op Hugging Face. Bij 131.072 tokens in fp16 (2 bytes):

2 × 32 × 131072 × 8 × 128 × 2 = 17.179.869.184 bytes ≈ 16 GiB

De gewichten van datzelfde model in fp16 wegen zo’n 16 GiB. Bij maximale context is de cache net zo groot als het model waar hij bij hoort. Het “8B-model dat in 16 GiB past” wordt stilletjes een probleem van 32 GiB zodra je num_ctx naar 128k optrekt.

Waarom groeit de cache mee met het venster?

Omdat attention elke token moet vergelijken met alles wat ervoor kwam, en inferentie autoregressief is — niets wordt opnieuw berekend, alles wordt onthouden. Dat is de hele truc die generatie snel maakt: keys en values van elke token worden eenmaal berekend en bewaard. Opslag per token is constant, dus het totaal is lineair in de context. 128k is geen “groter getal” — het is 128× de cache van een 1k-venster, gereserveerd voor de hele sessie.

Grouped-query attention (GQA) is de korting aan modelkant: minder KV-heads, slankere cache. Qwen2.5 7B gebruikt 28 lagen met maar 4 KV-heads (config hier), dus hetzelfde 128k-venster kost zo’n 7 GiB in fp16 — echte verlichting, en een reden waarom die modellen op bescheiden machines verrassend meegaand aanvoelen.

Model (fp16)Lagen × KV-headsKV-cache @ 128kGewichtenCache vs gewichten
Llama 3.1 8B32 × 8~16 GiB~16 GiB~100%
Qwen2.5 7B28 × 4~7 GiB~15 GiB~47%

Reken zelf na — dit is de hele controle:

def kv_cache_gib(layers, kv_heads, head_dim, ctx, bytes_per=2):
    return 2 * layers * ctx * kv_heads * head_dim * bytes_per / 2**30

print(kv_cache_gib(32, 8, 128, 131_072))  # Llama 3.1 8B  -> 16.0
print(kv_cache_gib(28, 4, 128, 131_072))  # Qwen2.5 7B    -> 7.0

Wat het marketinggetal verzwijgt

Hier is het eerlijke kasboek van dit betoog — inclusief de plekken waar het doorzakt:

  • Prefill is de tweede rekening. Voordat de eerste antwoord-token komt, wordt de hele prompt in één keer verwerkt. Een prompt van 100k tokens betekent 100k tokens kauwen voor je het eerste teken ziet. Op een 3060 zijn dat minuten, geen milliseconden.
  • Sliding-window-modellen breken de berekening — in jouw voordeel. Mistral-achtige architecturen perken attention per laag tot een vast venster, dus de cache stopt met groeien. De simpele formule overschat ze. Deze post gaat over full-attention-transformers — het merendeel van wat mensen draaien.
  • KV-kwantisatie is echt maar partieel. llama.cpp kan de KV in q8_0 bewaren, goed voor grofweg de helft van de cache bij wat kwaliteitsrisico. De helft van 16 GiB is nog steeds 8 GiB.
  • Specs vermelden zelden het aantal KV-heads. Je moet de config.json uitgraven — wat op zich al zegt hoe dat getal gelezen wil worden.

Niets hiervan maakt lange context zinloos. RAG bestaat juist omdat een vol venster de dure manier is om “lees paragraaf 4” te zeggen. Maar een kaart die “128k” drukt zonder de geheugenrekening, verkoopt een auto op topsnelheid en zwijgt de tank dood.

Niemand leest 128.000 tokens. Je RAM betaalt ze desondanks, allemaal.

De remedie is saai: zet de context op wat je werk echt gebruikt. Een 32k-venster kost een kwart van de 128k-cache en dekt vrijwel elke prompt die een solodeveloper werkelijk verstuurt. Dit is dezelfde kasboekdiscipline als de RAM-rekenkunde voor lokale LLM’s — modelgrootte is de helft van het budget, en kwantisatieniveaus krimpen de gewichten maar raken de cacheberekening niet.

Als de cache de echte prijs van context is, waarom verkopen modelkaarten dan het venster en nooit de rekening? En de belronde: wat is de grootste context die je werkelijk tot de laatste token vulde — en rechtvaardigde de output die gigabytes? De reacties staan open; het volgende deel van de serie kiest de kant van de verliezer.

FAQ

Hoeveel RAM gebruikt een 128k-contextvenster?

Voor Llama 3.1 8B in fp16 weegt alleen de KV-cache al zo'n 16 GiB bij 131.072 tokens — ongeveer evenveel als de modelgewichten. Formule: 2 × lagen × context × KV-heads × head_dim × bytes.

Waarom gebruikt lange context meer geheugen?

Elke token in de cache slaat key- en value-tensoren op voor elke attention-laag. Dubbele context, dubbele cache. De allocatie bestaat ook als je het venster nooit volschrijft.

Hoe verklein ik het KV-cache-geheugen bij lokale LLM's?

Zet de context op wat je echt gebruikt, kies modellen met grouped-query attention (minder KV-heads), kwantiseer de KV-cache naar q8 waar de runtime het ondersteunt, of gebruik sliding-window- en hybride architecturen.

— mrsaynothing

— mrsaynothing

Meningen getest onder belasting vóór release. Meestal.

Het volgende argument per e-mail

Eén e-mail per post. Eens, of sloopt het.

self-hosted · geen derden · uitschrijven met één klik

wat is dit?

git stash: één bestand zonder de rest te verliezen

Schrijf je dit met plezier? Dit bouw ik professioneel. huur me in