Prefill vs. Decode: Wie Generierung abläuft
Enter drücken, und die Generierung läuft in zwei Phasen mit völlig unterschiedlicher Physik. Prefill verarbeitet Ihren gesamten Prompt in einem parallelen Durchlauf — rechenlastig, schnell pro Token, aber Sie warten auf alles davon, bevor das erste Wort erscheint. Decode gibt dann die Antwort Token für Token aus — jeder einzelne Schritt liest im Wesentlichen alle Modellgewichte neu aus dem Speicher, um ein Token zu erzeugen. „Erstes Token langsam, dann streamt es“ ist keine Eigenheit Ihres Setups; es sind diese zwei Phasen.
Phase 1: Prefill — der Prompt
- Alle Prompt-Tokens laufen gleichzeitig durch das Model: große parallele Matrixmultiplikationen, exakt das, wofür GPUs gebaut sind. Die Auslastung ist hoch; die Tokens pro Sekunde sind hoch.
- Sie spüren sie als Time-to-First-Token (TTFT): die Stille nach dem Druck auf Enter.
- Der Durchlauf füllt zudem den KV-Cache mit den Key/Value-Vektoren jedes Prompt-Tokens — den Scratchpad, den Decode lesen wird.
- Längere Prompts, linear längeres TTFT: große System-Prompts, RAG-Dokumente und Chat-Verlauf werden jedes Mal neu geprefillt, außer Ihre Engine cached Präfixe.
Phase 2: Decode — die Antwort
- Ein Token pro Forward-Pass. Dieser Pass braucht jedes Gewicht; ein einzelnes Token zu erzeugen heißt, das gesamte Model aus dem VRAM zu streamen.
- Die Obergrenze ist die Speicherbandbreite, nicht Rechenleistung: grob Decode-tok/s ≈ effektive Bandbreite ÷ Bytes an Gewichten. 8 GB Gewichte auf einer Karte mit ~400 GB/s effektiv ≈ 50 tok/s Decke.
- Deshalb beschleunigt Quantisierung den Decode: weniger Bits pro Gewicht heißt weniger Bytes, die pro Schritt zu streamen sind (siehe Geschwindigkeit).
Warum die Asymmetrie: Prefill verarbeitet tausende Tokens pro Gewicht-Lesevorgang (riesige Matrizen, hohe Arithmetikintensität — rechenlimitiert), Decode verarbeitet exakt eines (jedes Byte der Gewichte für ein einziges Token geholt — bandbreitenlimitiert). Dieselben Gewichte, entgegengesetzte Flasenhälse.
total_time ≈ prompt_tokens / prefill_tok_s + output_tokens / decode_tok_s
Durchgerechnetes Beispiel
prompt: 1,000 tokens prefill 2,000 tok/s → 0.5 s (TTFT)
output: 300 tokens decode 40 tok/s → 7.5 s
total ≈ 8.0 s — 94% der Echtzeit ist Decode
- Die erste halbe Sekunde verarbeitete 1.000 Tokens; die nächsten 7,5 Sekunden erzeugen 300. Gleiches Model, gleiche GPU, 50× Unterschied — andere Phase, nicht andere Anstrengung.
- 40 tok/s sind grob 160 englische Zeichen pro Sekunde (≈4 Zeichen pro Token): schneller als irgendjemand tippt, weshalb Streaming sich angenehm liest (Tokens).
- Dieselben 40 tok/s sind auf Koreanisch grob 40–60 Zeichen/s: identische Token-Rate, weniger Text pro Token.
- Die Ausgabelänge ist ein Decode-seitiger Regler: max_tokens begrenzt, wie lange die Generierung läuft, Stop-Sequenzen beenden sie früher. Beides ändert die Echtzeit linear (Engine-Regler).
- Streaming ändert die Wahrnehmung, nicht die Physik: Sie sehen dem Decode dabei zu, statt darauf zu warten — bei denselben 40 tok/s.
Durchgerechnetes Beispiel 2: der RAG-Fall
prompt: 12,000 tokens (system + 20 retrieved chunks) prefill 1,500 tok/s → 8.0 s
output: 500 tokens decode 40 tok/s → 12.5 s
total ≈ 20.5 s — allein das TTFT sind 39% der Wartezeit
Das ist die Gestalt retrieval-lastiger lokaler Setups: Fette Prompts heißen, das Model „denkt“ Sekunden, bevor es tippt. Heilmittel, nach Hebelwirkung geordnet:
- Weniger abrufen — Top 3–5 Chunks schlagen üblicherweise Top 20 (RAG).
- Halten Sie den System-Prompt stabil, damit die Engine ein gecachtes Präfix wiederverwenden kann.
- Kürzen Sie den Verlauf: Alte Runden lassen sich zusammenfassen, statt sie komplett erneut zu senden.
Der KV-Cache: der wachsende Scratchpad
Ohne Cache würde die Generierung von Token N die Attention über alle N−1 früheren Tokens von Neuem berechnen — jeder Schritt wiederholt identische Arbeit, Gesamtkosten quadratisch in der Länge. Stattdessen:
- Prefill berechnet Keys und Values für alle Prompt-Tokens und speichert sie einmal.
- Jeder Decode-Schritt berechnet nur Query/Key/Value des neuen Tokens und hängt sein K/V an den Cache an.
- Attention für das neue Token ist seine Query, gepunktet gegen alle gespeicherten Keys.
- Ein dekodiertes Token, der Reihe nach: einbetten, die Layer unter Lesen des Cache durchlaufen, aufs Vokabular projizieren, samplen — sein K/V anhängen, wiederholen.
Jetzt ist jeder Decode-Schritt linear in der Kontextlänge (den Cache lesen) statt quadratisch (alles neu berechnen). Der Preis ist der Cache selbst, der mit jedem Token wächst:
KV bytes ≈ 2 × layers × kv_heads × head_dim × bytes_per_value × context
8B-class model (32 layers, 8 KV heads, 128 head dim, FP16):
2 × 32 × 8 × 128 × 2 B ≈ 128 KiB per token
→ ~2.6 GB at 20k context, ~17 GB at 128k context
Dieser Cache konkurriert mit den Gewichten um VRAM — Langkontext-Chats bringen Maschinen zum Absturz, die dasselbe Model mit kurzen Prompts problemlos fahren (KV-Cache, VRAM-Mathematik).
Batching ändert die Ökonomie
8 GB Gewichte zu lesen, um ein Token auszugeben, ist Verschwendung; dieselbe Leseaktion kann viele Sequenzen zugleich bedienen. Batchen Sie 8 Anfragen, und ein Gewicht-Strom erzeugt 8 Tokens — der Durchsatz steigt nahezu linear, bis die Rechenleistung gesättigt ist. Das ist der ganze Trick hinter dem Serving (Serving-APIs, Parallelität). Solo auf dem Laptop zahlen Sie die volle Fracht pro Token; Server verteilen sie auf gleichzeitige Nutzer.
Die Messwerte lesen
| Messwert | Phase | Haupttreiber |
|---|---|---|
| TTFT | Prefill | Prompt-Länge, Rechenleistung, Präfix-Cache-Treffer |
| Prompt-Eval-tok/s | Prefill | Rechenleistung, Batchgröße |
| Generierungs-tok/s | Decode | Speicherbandbreite, Gewicht-Bytes, Batch |
| Durchsatz (Anfragen/s) | beide | Batchgröße, Präfix-Cache-Wiederverwendung, parallele Slots |
| Kontextspeicher | beide | KV-Bytes pro Token, Cache-Quantisierung |
Messen Sie vor dem Tuning: Jede ernsthafte Engine loggt Prompt-Eval- und Generierungsgeschwindigkeit pro Anfrage. Eine Minute Logs sagt Ihnen, welche Phase Ihre Latenz frisst; Rätseln nicht.
Tuning folgt der Phase: Kürzere Prompts und Präfix-Caching reparieren das TTFT; Quantisierung und kleinere Gewichte reparieren den Decode (Engine-Regler, Fehlerbehebung).
Verwandt: Geschwindigkeit · KV-Cache · Parallelität · Tokens