Was ist KV-Cache?
Während der autoregressiven Generierung muss ein Transformer für jedes neue Token die Attention über alle vorherigen Token berechnen. Der KV-Cache speichert die Key- und Value-Projektionen vorheriger Token, damit sie nicht neu berechnet werden müssen. Das reduziert die Berechnung pro Schritt von O(n²) auf O(n) — eine massive Beschleunigung für lange Sequenzen.
Key-Cache
Speichert die Key-Projektionen für jedes Token in jeder Schicht. Diese werden verwendet, um Attention-Scores zwischen dem neuen Token und allen vorherigen Token zu berechnen.
Value-Cache
Speichert die Value-Projektionen für jedes Token in jeder Schicht. Sobald die Attention-Gewichte berechnet sind, werden diese gecachten Values zur Ausgabeerzeugung verwendet.
Warum es wichtig ist
Ohne KV-Caching würde die Generierung jedes neuen Tokens erfordern, die gesamte Sequenz durch jede Attention-Schicht neu zu verarbeiten. Bei einer 4096-Token-Sequenz bedeutet das 4096× redundante Berechnung pro Token.
Geschwindigkeit
Vermeidet die Neuberechnung der Attention für alle vorherigen Token bei jedem Schritt. Generierung wird von quadratisch zu linear.
Inkrementell
Jedes neue Token muss nur sein eigenes Q, K, V berechnen und auf die gecachten K, V vorheriger Positionen zugreifen.
Kompromiss
Tauscht GPU-Speicher gegen Rechenzeit. Der Cache wächst linear mit Sequenzlänge und Modelltiefe.
Interaktiver KV-Cache Explorer
Beobachte den Cache Token für Token wachsen
Gehe schrittweise durch die autoregressive Generierung, um zu sehen, wie der KV-Cache sich aufbaut. Vergleiche die Berechnungskosten mit und ohne Caching — die Einsparungen werden bei längeren Sequenzen dramatisch.
| Pos | Token | Key Vector | Value Vector |
|---|---|---|---|
| Press Play or Step to start generating tokens... | |||
Speicher-Auswirkungen
Der KV-Cache ist der Hauptengpass beim Speicher während der Inferenz. Bei großen Modellen mit langem Kontext kann er Dutzende Gigabyte GPU-Speicher verbrauchen.
KV Cache Memory = 2 × num_layers × seq_len × d_head × num_kv_heads × dtype_sizeFaktor 2 für K und V, dtype_size ist 2 Bytes für FP16. Für Llama 3 70B (80 Schichten, 8 KV-Heads, 128 d_head) bei 8K Kontext: ~2,5 GB pro Anfrage.
Optimierungstechniken
Multi-Query & Grouped-Query Attention (MQA/GQA)
Anstatt separate K/V-Heads pro Attention-Head zu verwenden, teilt MQA ein einzelnes K/V-Head über alle Query-Heads, während GQA einige gemeinsame Gruppen nutzt. Dies reduziert die KV-Cache-Größe um das 4-32-fache bei minimalem Qualitätsverlust. Llama 3 und Mistral verwenden GQA. Siehe den Artikel über Aufmerksamkeitsmechanismen für weitere Details.
Sliding-Window-Attention
Anstatt alle Token zu cachen, werden nur die letzten W Token im Cache gehalten. Wird von Mistral-Modellen verwendet. Reduziert den Speicher von O(seq_len) auf O(W), begrenzt aber die Fähigkeit des Modells, auf sehr frühe Token zuzugreifen.
Paged Attention (vLLM)
Inspiriert von virtüllem Speicher in Betriebssystemen. Anstatt zusammenhängenden Speicher für den KV-Cache jeder Sequenz zuzuweisen, verwaltet vLLM den Cache in „Pages" fester Größe, die dynamisch zugewiesen und freigegeben werden können. Das eliminiert Speicherfragmentierung und ermöglicht effizientes Batching von Anfragen mit unterschiedlichen Sequenzlängen.
Wichtige Erkenntnisse
- 1Der KV-Cache speichert Key- und Value-Projektionen vorheriger Token und vermeidet redundante Berechnungen während der Generierung
- 2Ohne KV-Cache erfordert jedes neue Token O(n) Attention-Berechnung über die gesamte Sequenz; mit Cache wird nur das K/V des neuen Tokens berechnet
- 3Der KV-Cache-Speicher wächst linear mit Sequenzlänge × Schichten × KV-Heads — das ist der Hauptengpass beim Inferenz-Speicher
- 4Techniken wie GQA, Sliding Window und Paged Attention adressieren die Speicherkosten bei gleichbleibender Generierungsgeschwindigkeit