Zum Inhalt springen
labkompass

Guides · KI & Local AI

KV-Cache verständlich erklärt: Das Kurzzeitgedächtnis im Grafikspeicher

Was der KV-Cache ist, warum langer Kontext so viel VRAM frisst, wie man seinen Bedarf selbst ausrechnet — und was GQA und Cache-Quantisierung dagegen tun.

Von Niclas Hennrich · Veröffentlicht: · 9 Min. Lesezeit

Reality Check

Stand: September 2026

Belegt
12 Aussagen
Herstellerangabe
1 Aussage

8 Quellen · Was die Stufen bedeuten


Kurz gesagt: Der KV-Cache ist das Kurzzeitgedächtnis eines Sprachmodells. Für jedes Token im bisherigen Text hebt das Modell in jeder Schicht zwei kleine Zahlenreihen auf — einen Key und einen Value —, damit es sie beim nächsten Wort nicht neu berechnen muss. Das spart enorm Rechenzeit, kostet aber Speicher, und zwar linear mit der Kontextlänge. Deshalb passt ein Modell mit kurzem Kontext locker in den Grafikspeicher und mit langem plötzlich nicht mehr.

Wer lokal mit Ollama oder llama.cpp arbeitet, kennt das Muster: Das Modell startet flott, nach einem langen Chat oder einem eingefügten Dokument wird es zäher, und wer das Kontextfenster hochdreht, bekommt eine Speicherwarnung — obwohl sich an der Modelldatei nichts geändert hat. Der Grund steckt fast immer im KV-Cache. Dieser Artikel erklärt, was darin liegt, wie man seine Größe mit Stift und Papier ausrechnet und welche Stellschrauben es gibt.

Attention in einfachen Worten #

Moderne Sprachmodelle sind Transformer. Ihr Kernbaustein heißt Attention (Aufmerksamkeit): Bei jedem neuen Wort schaut das Modell auf alle bisherigen Wörter und entscheidet, welche davon gerade wichtig sind. Das Transformer-Paper von 2017 beschreibt Attention als Abbildung einer Query und einer Menge von Key-Value-Paaren auf eine Ausgabe, wobei alle Beteiligten Vektoren sindBelegt — also einfach Listen von Zahlen.

Ein Bild dafür ist ein Bibliothekskatalog:

  • Die Query ist die Suchanfrage des aktuellen Tokens: „Worauf muss ich mich gerade beziehen?“
  • Jedes frühere Token trägt ein Key-Etikett: „Dafür bin ich relevant.“
  • Und es hat einen Value, den eigentlichen Inhalt, den es beisteuert.

Das Modell vergleicht die Query mit allen Keys, gewichtet danach die Values und mischt sie zu einer Antwort. Im Paper steht das als softmax(QKᵀ/√dₖ)·V: Skalarprodukte von Query und Keys, skaliert, in Gewichte umgewandelt und mit den Values verrechnetBelegt. Das passiert nicht einmal, sondern parallel in mehreren Köpfen (Heads) pro Schicht — jeder Kopf achtet auf andere Zusammenhänge — und das in jeder der Dutzenden Schichten des Modells.

Wichtig für alles Weitere: Beim Erzeugen darf jede Position nur auf sich selbst und die Positionen davor schauen; spätere Positionen werden ausgeblendetBelegt. Ein Token, das einmal im Text steht, bekommt seinen Key und Value also nie wieder geändert — egal, was danach noch kommt.

Warum man Keys und Values aufhebt #

Genau diese Eigenschaft macht den Cache möglich. Ein Modell schreibt Text Token für Token. Ohne Cache müsste es für Token Nummer 1.000 die Keys und Values aller 999 Vorgänger in allen Schichten erneut ausrechnen, für Token 1.001 wieder alle 1.000 — der Aufwand würde mit jedem Wort wachsen, obwohl sich an den alten Werten nichts ändert.

Also rechnet man sie einmal aus und hebt sie auf. Die Key- und Value-Tensoren jeder Schicht — der KV-Cache — müssen dafür während der gesamten Textgenerierung im Speicher liegenBelegt. Pro neuem Token kommt nur noch ein Satz Keys und Values dazu; die Query wird nur für das aktuelle Token gebraucht und muss nicht gespeichert werden. Deshalb heißt er KV-Cache und nicht QKV-Cache.

Den Cache füllt das Modell in zwei Schritten, die der Artikel Tokens pro Sekunde: Was der Wert bei lokalen LLMs wirklich bedeutet genauer erklärt: Beim Prefill liest es deinen Prompt auf einmal ein und schreibt dessen Keys und Values in den Cache; beim Decode hängt es pro erzeugtem Token einen Eintrag an.

Die Speicherformel #

Was genau liegt da? Pro Token, pro Schicht und pro KV-Kopf ein Key-Vektor und ein Value-Vektor, jeweils so lang wie die Kopfdimension (die Anzahl Zahlen pro Kopf). Daraus ergibt sich:

KV-Cache (Bytes) = 2 × Schichten × KV-Köpfe × Kopfdimension × Bytes pro Wert × Tokens

Die 2 steht für Key und Value. Die übrigen Werte stehen in der Konfigurationsdatei jedes Modells auf Hugging Face (config.json) — man muss sie nicht schätzen.

Rechenbeispiel: Qwen2.5-7B-Instruct #

Als Beispiel ein verbreitetes offenes Modell. Laut offizieller config.json hat Qwen2.5-7B-Instruct 28 Schichten (num_hidden_layers), 28 Attention-Köpfe (num_attention_heads), aber nur 4 Key-Value-Köpfe (num_key_value_heads), eine hidden_size von 3.584 und max_position_embeddings von 32.768; gespeichert ist es in bfloat16Belegt. Die Kopfdimension steht nicht direkt drin, sie ergibt sich aus 3.584 ÷ 28 = 128.

Die Rechnung — ausdrücklich eine Rechnung, keine Messung:

  • Pro Token in 16 Bit (2 Bytes pro Wert): 2 × 28 × 4 × 128 × 2 = 57.344 Bytes, also rund 57 KB.
  • Bei 4.096 Tokens Kontext: rund 0,23 GB.
  • Bei 8.192 Tokens: rund 0,47 GB.
  • Beim vollen Kontext von 32.768 Tokens: rund 1,9 GB.

Zum Vergleich: Dieselbe Rechnung für ein anderes Modell zitiert schon Warum kostet lokale KI so viel Hardware? — dort liegt der Wert pro Token um mehr als eine Größenordnung höher. Warum Qwen so sparsam ist, zeigt der nächste Abschnitt.

Im Local-AI-Rechner lässt sich das nachstellen: Unter „Architektur (für den KV-Cache)“ ist Qwen 2.5 7B mit genau diesen Werten hinterlegt, bei „KV-Cache-Präzision“ kann man zwischen 16 und 8 Bit wechseln. Der Rechner zeigt Gewichte, KV-Cache und Overhead als getrennte Balken. Reale Programme weichen etwas ab — manche reservieren den Puffer für das ganze eingestellte Fenster schon beim Laden, andere sparen durch Flash Attention oder Cache-Quantisierung.

Grouped-Query Attention: weniger Köpfe für Keys und Values #

In der Formel steckt ein Hebel, den Modellbauer ausgiebig nutzen: die Zahl der KV-Köpfe. Im ursprünglichen Transformer hat jeder Attention-Kopf eigene Keys und Values. Qwen2.5-7B hat aber 28 Query-Köpfe und nur 4 KV-Köpfe — jeweils sieben Query-Köpfe teilen sich einen Key-Value-Kopf.

Die Idee hat zwei Stufen:

  1. Multi-Query Attention (MQA) teilt Keys und Values über alle Köpfe, verkleinert so diese Tensoren und damit die Speicherbandbreite beim Generieren; laut Paper dekodieren solche Modelle deutlich schneller bei nur geringem QualitätsverlustBelegt.
  2. Grouped-Query Attention (GQA) ist der Mittelweg: mehr als ein, aber weniger KV-Köpfe als Query-Köpfe. Die Autoren zeigen, dass GQA nahe an die Qualität der klassischen Multi-Head-Attention kommt und dabei ähnlich schnell ist wie MQABelegt.

Was das in Gigabyte bedeutet, zeigt ein Gedankenexperiment — eine hypothetische Rechnung, kein existierendes Modell: Hätte Qwen2.5-7B für jeden seiner 28 Köpfe eigene Keys und Values, wären es pro Token 2 × 28 × 28 × 128 × 2 = rund 401 KB, beim vollen Kontext von 32.768 Tokens rund 13 GB statt 1,9 GB. Mehr als eine komplette 12-GB-Grafikkarte, nur für das Kurzzeitgedächtnis. GQA ist damit einer der Gründe, warum lange Kontexte auf Consumer-Hardware überhaupt praktikabel sind.

Deshalb lohnt der Blick in die config.json, bevor man Modelle vergleicht: Zwei Modelle mit gleicher Parameterzahl können sich beim KV-Cache um ein Vielfaches unterscheiden.

Warum lange Chats langsamer werden #

Der KV-Cache kostet nicht nur Platz, sondern auch Zeit. Für jedes neue Token muss das Modell die Query mit allen gespeicherten Keys vergleichen — also den ganzen Cache aus dem Speicher lesen. Gewichte und KV-Cache müssen bei jedem Durchlauf vom Grafikspeicher zu den Rechenwerken; bei kleinen Batches und kurzen Sequenzen dominiert das Laden der Gewichte, bei großen Batches und langen Sequenzen das Laden des KV-CachesBelegt.

Im Homelab mit einer Person am Modell bleiben die Gewichte meist der größere Brocken. Aber der Cache wächst mit jeder Zeile Unterhaltung, und jedes Byte darin wird pro Token erneut gelesen. In der Rechnung oben kommen bei 32.768 Tokens rund 1,9 GB zu jedem Lesedurchgang dazu. Deshalb sinkt die Generierungsrate mit wachsendem Kontext — wie das in Benchmarks sichtbar wird, zeigt der Abschnitt zu @ d512 im oben verlinkten Artikel zu Tokens pro Sekunde. Und das Einlesen eines langen Prompts dauert, weil der Cache für jedes Token erst gefüllt werden muss. Dass Daten zu bewegen oft mehr kostet als sie zu verrechnen, ist übrigens ein Grundproblem heutiger Rechner — die Landkarte Was kommt nach CPU und GPU? zeigt, welche Architekturen daran ansetzen.

Die gute Nachricht: Weil der Cache aufbewahrt wird, muss ein Chat-Verlauf nicht bei jeder Nachricht komplett neu eingelesen werden. Der llama.cpp-Server hat Prompt-Caching standardmäßig aktiviertBelegt; ein gleichbleibender Anfang der Unterhaltung kann so wiederverwendet werden.

Der Cache im Rechenzentrum: PagedAttention #

Im Rechenzentrum ist der KV-Cache das eigentliche Nadelöhr, weil dort viele Anfragen gleichzeitig laufen und jede ihren eigenen Cache braucht. Die vLLM-Autoren beschreiben, dass der KV-Cache pro Anfrage groß ist, dynamisch wächst und schrumpft und bei ungeschickter Verwaltung durch Fragmentierung und doppelte Kopien viel Speicher verschwendet. Ihr Verfahren PagedAttention verwaltet ihn in Blöcken wie virtueller Speicher im Betriebssystem und kommt auf nahezu keinen VerschnittBelegt. Die Zahlen dazu stehen in Warum kostet lokale KI so viel Hardware? — für den Einzelbetrieb zu Hause ist das Thema weniger drängend, erklärt aber, warum Server-Software wie vLLM so viel Aufwand in die Cache-Verwaltung steckt.

KV-Cache-Quantisierung: der Cache in weniger Bits #

Was bei den Gewichten funktioniert, geht auch beim Cache: weniger Bits pro Wert. (Wie Quantisierung grundsätzlich funktioniert, erklärt Quantisierung und GGUF.) Der Cache ist davon unabhängig — ein Q4-Modell legt seinen KV-Cache standardmäßig trotzdem in 16 Bit an.

In Ollama steuert das eine Umgebungsvariable des Servers: OLLAMA_KV_CACHE_TYPE kennt die Werte f16 (Standard), q8_0 und q4_0; die Quantisierung funktioniert nur mit aktivierter Flash AttentionBelegt, die Ollama laut Doku bei unterstützten Modellen automatisch einschaltet (erzwingen lässt sie sich mit OLLAMA_FLASH_ATTENTION=1). Laut Ollama braucht q8_0 etwa die Hälfte des Speichers von f16 bei sehr kleinem Genauigkeitsverlust, q4_0 etwa ein Viertel bei kleinem bis mittlerem VerlustHerstellerangabe. Wie man Umgebungsvariablen für den Dienst setzt, zeigt Ollama einrichten.

# Beispiel für einen manuell gestarteten Ollama-Server
OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0 ollama serve

In llama.cpp gibt es getrennte Optionen für Keys und Values: -ctk/--cache-type-k und -ctv/--cache-type-v erlauben unter anderem f16, bf16, q8_0, q5_0, q4_0; Standard ist jeweils f16. Flash Attention steht per -fa standardmäßig auf autoBelegt.

# llama.cpp-Server: 32K Kontext, Keys und Values in 8 Bit
llama-server -m modell.gguf -c 32768 -fa on -ctk q8_0 -ctv q8_0

Übertragen auf das Rechenbeispiel (wieder Rechnung, keine Messung): Die 1,9 GB für 32.768 Tokens würden mit q8_0 auf grob 1 GB schrumpfen, mit q4_0 auf grob 0,5 GB. Ob sich die Qualitätseinbuße bemerkbar macht, hängt von Modell und Aufgabe ab — und das haben wir selbst noch nicht gemessen.

Reality Check #

Stand September 2026:

  • Gesichert ist der Mechanismus: Keys und Values werden gespeichert, der Bedarf wächst linear mit dem Kontext, und die Formel oben ergibt sich direkt aus der Architektur. MQA und GQA sind in begutachteten Arbeiten beschrieben und in offenen Modellen wie Qwen2.5 umgesetzt.
  • Herstellerangabe sind die Qualitätsaussagen zur Cache-Quantisierung in der Ollama-Doku — sie klingen plausibel, eine unabhängige Prüfung für typische Homelab-Modelle haben wir nicht.
  • Offen ist, wie viel Speicher eine konkrete Runtime tatsächlich reserviert. Die Formel ist die Untergrenze für den Cache selbst; Puffer, Flash Attention und Implementierungsdetails verschieben den realen Wert. Eigene Messungen dazu gibt es auf LabKompass noch nicht.

Was heißt das fürs eigene Homelab? #

Drei praktische Folgen:

  1. Kontext nicht größer einstellen als nötig. Der KV-Cache wächst mit dem eingestellten Fenster. Wer 32K Tokens konfiguriert, aber nur kurze Fragen stellt, verschenkt Grafikspeicher, der sonst für ein größeres Modell oder eine bessere Quantisierung reichen würde. Die Gesamtrechnung aus Gewichten, Cache und Overhead macht Wie viel RAM und VRAM braucht ein LLM?.
  2. Vor dem Download die config.json ansehen. num_hidden_layers, num_key_value_heads und die Kopfdimension verraten, wie teuer langer Kontext bei diesem Modell wird — der Local-AI-Rechner nimmt diese Werte im Modus „Eigenes Modell“ direkt entgegen.
  3. Cache-Quantisierung als Reserve. Passt ein Modell mit dem gewünschten Kontext knapp nicht, ist q8_0 für den Cache ein naheliegender erster Versuch, bevor man auf ein kleineres Modell ausweicht. Ob die Antworten dabei merklich schlechter werden, prüft man am besten mit den eigenen, typischen Aufgaben.

Und wenn ein Chat nach einer Stunde zäh wird: Ein neuer Chat leert den Cache. Das ist kein Trick, sondern schlicht weniger Kurzzeitgedächtnis, das bei jedem Token gelesen werden muss.

Quellen

  1. Originalpaper · 2017

    Attention Is All You Need (externer Link, neues Fenster) — Vaswani et al.

  2. Originalpaper · 2022

    Efficiently Scaling Transformer Inference (externer Link, neues Fenster) — Pope et al. (Google)

  3. Originalpaper · 2019

    Fast Transformer Decoding: One Write-Head is All You Need (externer Link, neues Fenster) — Shazeer

  4. Originalpaper · 2023

    GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints (externer Link, neues Fenster) — Ainslie et al.

  5. Offizielle Dokumentation

    Qwen2.5-7B-Instruct — config.json (externer Link, neues Fenster) — Qwen-Team (Alibaba Cloud)

  6. Originalpaper · 2023

    Efficient Memory Management for Large Language Model Serving with PagedAttention (externer Link, neues Fenster) — Kwon et al.

  7. Offizielle Dokumentation

    Ollama — FAQ (Flash Attention, K/V-Cache-Quantisierung) (externer Link, neues Fenster) — Ollama-Projekt

  8. Offizielle Dokumentation

    llama.cpp — Server-Dokumentation (tools/server/README.md) (externer Link, neues Fenster) — llama.cpp-Projekt

Häufige Fragen

Wie viel Speicher braucht der KV-Cache?
Pro Token: 2 × Schichten × KV-Köpfe × Kopfdimension × Bytes pro Wert. Für Qwen2.5-7B-Instruct (28 Schichten, 4 KV-Köpfe, Kopfdimension 128) sind das in 16 Bit rund 57 KB pro Token — bei 32.768 Tokens Kontext also rund 1,9 GB zusätzlich zu den Gewichten. Das ist eine Rechnung, kein Messwert; Runtimes reservieren teils etwas mehr.
Warum braucht langer Kontext so viel VRAM?
Weil das Modell für jedes Token im Kontext pro Schicht einen Key- und einen Value-Vektor aufbewahrt, solange die Unterhaltung läuft. Der Speicherbedarf wächst deshalb linear mit der Kontextlänge — doppelt so viel Kontext, doppelt so viel KV-Cache.
Kann man den KV-Cache in Ollama quantisieren?
Ja. Mit der Umgebungsvariablen OLLAMA_KV_CACHE_TYPE lässt sich der Cache laut Ollama-Doku von f16 (Standard) auf q8_0 (etwa halber Speicher) oder q4_0 (etwa ein Viertel) umstellen. Voraussetzung ist aktivierte Flash Attention. llama.cpp bietet dafür die Optionen --cache-type-k und --cache-type-v.

Teil des Themen-Hubs Lokale KI im Homelab · Abschnitt „Hardware verstehen“

Weiterlesen