Prefill vs. Decode: Warum LLM-Inference zwei Phasen hat
Automatische Übersetzung
Dieser Artikel wurde automatisch aus der englischen Originalversion übersetzt.
Prefill verarbeitet einen Prompt und erstellt dessen Attention-Cache. Decode nutzt diesen Cache, um weitere Tokens zu erzeugen. Langes oder gebündeltes Prefill kann große Matrixoperationen effizient nutzen; Decode mit kleinen Batches verbringt oft mehr Zeit damit, Weights sowie zwischengespeicherte Schlüssel und Werte zu lesen.
Diese Unterscheidung hilft Ingenieuren, einen langsamen ersten Token getrennt von der langsamen Generierung danach zu untersuchen.
Bestimme, welche Phase langsam ist
Gewöhnliches autoregressives Prefill erzeugt die Logits, aus denen der erste Ausgabe-Token gesampelt wird. Spätere Decode-Schritte fügen jeweils einen Token hinzu. Die Zeit bis zum ersten Token umfasst auch Wartezeit in der Warteschlange, Tokenization, Scheduling und Übertragung über das Netzwerk. Eine hohe TTFT beweist daher nicht, dass Prefill selbst langsam ist.
| Symptom | Vor einer Änderung am Server messen |
|---|---|
| Der erste Token braucht bei längeren Prompts mehr Zeit | Wartezeit und Prefill-Dauer nach Eingabelänge |
| Spätere Tokens werden bei längeren Verläufen langsamer | Decode-Zeit und Datenverkehr des KV cache |
| Ein langer neuer Prompt unterbricht andere Streams | Scheduler-Iterationen und Zeitabstände zwischen Tokens |
| Getrennte Server verbringen Zeit mit der Zustandsübertragung | Übertragene KV-Bytes, Bandbreite und Wartezeit |
Prefill verwendet Weights für mehrere Prompt-Tokens wieder. Die Implementierung kann Matrixblöcke dennoch mehrfach laden; sie garantiert nicht, dass jeder Weight genau einmal aus HBM gelesen wird. Splitwise beschreibt, wie diese Phasen unterschiedliche Hardware-Ressourcen nutzen.
Was Prefill in Chunks verändert
Prefill in Chunks verarbeitet einen langen Prompt über mehrere Scheduler-Iterationen. Der dokumentierte Scheduler von vLLM berücksichtigt zuerst laufende Decode-Anfragen und nutzt das verbleibende Token-Budget der Iteration für Prefill. Die tatsächliche Chunk-Größe richtet sich nach dem verfügbaren Budget.
Das kann Unterbrechungen bestehender Streams verringern und zugleich die TTFT der neuen Anfrage erhöhen. Kleinere Chunks verursachen auch zusätzliche Scheduling-Arbeit und lesen früheren Cache-Zustand erneut. Sarathi-Serve untersucht diesen Zielkonflikt; die dort berichtete zusätzliche Prefill-Zeit von etwa 25% bei Chunks mit 512 Tokens wurde für Yi-34B mit Tensorparallelität von zwei gemessen.
Disaggregated Serving führt Prefill und Decode dagegen auf getrennten GPU-Pools aus. Damit lässt sich jede Phase unabhängig optimieren, aber der KV cache der Anfrage muss übertragen werden. Prüfe Übertragungskosten und Pool-Auslastung, bevor du dieses Design einsetzt. Chunking verändert den Scheduler; Disaggregation verändert auch Deployment und Kommunikation.
Engineering-Leitfaden: Prefill versus Decode enthält Zeitabläufe für beide Ansätze.