Kapitel 13 — Autoscaling und Cold-Start-Minderung
Dreizehnter Beitrag im Kapitel-für-Kapitel-Walkthrough zu LLM Primer VI: KI-Systeme skalieren. Das Kapitel erklärt, warum der Standard-Kubernetes-Autoscaler unter LLM-Traffic Ausfälle produziert und wie KEDA, Knative und CRIU die Antwort zusammensetzen.
Warum es dieses Kapitel gibt
Ein Chat-Assistent schwankt über einen Tag um den Faktor 30 zwischen Spitze und Tal. Ein Entwicklertool geht am Wochenende auf null. Ein Konsumentenprodukt reitet auf einer pazifisch-europäischen Welle. Für die Spitze zu provisionieren verschwendet Geld im Tal; für das Tal zu provisionieren wirft Anfragen in der Spitze weg. Autoscaling hält das Deployment im Takt mit dem Traffic; Cold-Start-Minderung macht Autoscaling — insbesondere Scale-to-Zero — schnell genug, dass Nutzer es nicht bemerken. Kapitel 13 erklärt, warum der Standard-Kubernetes-HPA für LLMs der falsche Skalierer ist, welche Signale KEDA stattdessen skaliert, wie Knative Scale-to-Zero ausdrückt und was es braucht, um einen 60–180-Sekunden-Cold-Start in einstellige Sekunden zu drücken.
13.1 HPA versagt an LLM-Traffic auf vier spezifische Weisen
Standard-HPA skaliert auf CPU- oder GPU-Auslastung. Bei LLMs versagt er auf vier Weisen. Erstens ist die GPU-Auslastung das falsche Signal — nvidia-smi meldet den Anteil der Zeit, in der irgendein Kernel läuft, nicht ob der Batch gut gepackt ist oder Anfragen vorankommen. Ein zu 95 Prozent ausgelasteter Server mit acht langen Prefills, die hinter einem Decode warten, ist überlastet; ein zu 60 Prozent ausgelasteter Server mit gesundem Continuous Batch ist in Ordnung. Zweitens ist die Dauer einer LLM-Anfrage (Sekunden bis Dutzende Sekunden) lang gegenüber der Regelschleife von HPA (15 Sekunden), sodass die Skalierung der Last um eine ganze Anfragedauer hinterherhinkt. Drittens ist die Kapazitätseinheit kein Pod; ein disaggregiertes Deployment skaliert in Cliques, und HPA versteht keine Cliques. Viertens der Cold Start: ein neuer Pod kommt 60–180 Sekunden später online, lange nach dem Peak, der ihn ausgelöst hat, der die Flotte entweder überlastet oder sich als Timeouts abgeschüttelt hat. Der typische Ausfallmodus ist ein zweiminütiger Ausfall während einer Traffic-Verdopplung, gefolgt von einer Herunterskalierung, die das Deployment für den nächsten Peak unterprovisioniert hinterlässt.
13.2 KEDA skaliert auf Queue-Tiefe, TTFT und KV-Belegung
KEDA erweitert HPA um eine ScaledObject-CRD, die eine Ziel-Arbeitslast an einen oder mehrere Skalierer bindet, die eine externe Metrik in eine gewünschte Replica-Zahl übersetzen. Für LLM-Serving zählen drei Signale. Queue-Tiefe ist am direktesten: die Anzahl wartender Anfragen der Engine ist der Überschuss ankommender Arbeit über Serving-Kapazität; vLLM exportiert sie als vllm:num_requests_waiting. Time-to-First-Token — konkret p95 oder p99 über ein gleitendes Fenster — erfasst nutzerspürbare Degradierung und fängt asymmetrische Überlast ein, die die Queue-Tiefe verpasst (Prefill gesättigt, Decode nicht — oder umgekehrt). Die KV-Cache-Belegung ist vorausschauend; wenn die Belegung 80 Prozent übersteigt, sollten neue Replicas online kommen, bevor die bestehenden zu preempten oder abzulehnen anfangen. Ein produktives ScaledObject komponiert meist alle drei, wobei der aggressivste gewinnt. Knative Serving legt sich für Scale-to-Zero darüber: unterhalb einer kleinen Aktivierungsschwelle werden alle Pods entfernt; ankommende Anfragen werden von einem Aktivator gehalten, der einen Pod bei Bedarf hochfährt — nur wirtschaftlich, wenn der Cold Start schnell ist.
13.3 CRIU staucht einen 90-Sekunden-Cold-Start auf 3–6 Sekunden
Ein 70B-Cold-Start zerlegt sich in Image-Pull (10–60 s), Python-Init (2–5 s), Gewichts-Laden (60–120 s), CUDA-Kontext-Init (5–15 s), CUDA-Graph-Capture (10–30 s), KV-Warmup (2–10 s) — insgesamt 90–250 s. CRIU (Checkpoint/Restore In Userspace) fotografiert einen vollständig aufgewärmten Prozess — Gewichte geladen, CUDA-Kontext oben, Graphen erfasst, KV-Pool angelegt, Healthcheck bestanden — und stellt ihn später aus dem Speicher in Sekunden wieder her. NVIDIAs cuda-checkpoint-Utility (2024) erweitert CRIU um GPU-Zustand: Gerätespeicher-Pools, CUDA-Kontext, gecachtes PTX, erfasste Graphen. Ein warmer vLLM-Snapshot wird in 3–6 Sekunden vom lokalen NVMe wiederhergestellt. Ein DaemonSet legt den Checkpoint auf dem NVMe jedes Knotens vorab bereit, sodass Knative aus einer lokalen Datei statt über das Netz restauriert. Zusammen mit Image Streaming (Pull beginnen, bevor er fertig ist) und lazy Gewichts-Laden sind Cold Starts unter fünf Sekunden in Produktion erreichbar — die Zahl, unterhalb derer sich Scale-to-Zero für nutzergerichtete Anwendungen wirtschaftlich verteidigen lässt.
Was Kapitel 13 vorbereitet
Die Kapitel 1 bis 13 sind den physischen Stack des LLM-Servings abgegangen — Hardware, Engines, Plattformen, Disaggregation, Skalierung. Der Rest des Buches wendet sich dem Geld zu. Kapitel 14 erklärt, warum das Token die Abrechnungseinheit ist, warum Output zwei- bis fünfmal höher als Input bepreist wird und wie unsichtbare Reasoning-Tokens auf der Rechnung landen. Kapitel 15 geht die Break-even-Rechnung zwischen Selbstbetrieb und API-Anbietern ab sowie den Posten Plattform-Engineering, den die meisten Teams unterschätzen. Kapitel 16 ist der Katalog von Kostensenkungszügen, die sich multiplikativ aufschichten.
Als Nächstes — Kapitel 14: Token-Ökonomie und API-Preise. Warum die Rechnung so aussieht, wie sie aussieht, und wie der Zähler läuft, wenn keiner hinsieht.
ScaledObject-YAML für einen LLM-Skalierer mit drei Signalen, das Knative-Revisionsmanifest für Scale-to-Zero, die vollständige Cold-Start-Anatomie, das CRIU-Pre-Stager-DaemonSet und die „Tag im Leben"-Spur eines autoskalierten Deployments durch eine tageszeitliche Traffic-Kurve. LLM Primer VI auf Amazon →