- Netflix trennt LLMs nicht als separates Silo ab, sondern betreibt sie gemeinsam in der bestehenden ML-Infrastruktur und bindet vLLM und Triton an ein integriertes Serving-System an
- vLLM, das als Basismodul gewählt wurde, bietet Unterstützung für benutzerdefinierte Modelle, einfache Fehlersuche, Erweiterungs-Hooks und Vertrautheit aus Forschungsumgebungen; mit dem vLLM-Backend von Triton wird zudem die Kopplung zwischen Modell und Frontend reduziert
- Neben bestehendem gRPC wird auch eine OpenAI-kompatible API angeboten, doch Lücken, die sich in der Produktion zeigten — wie fehlendes
response_format, Versionskonflikte zwischen Triton und vLLM oder die Behandlung nicht standardisierter Modelle — mussten direkt selbst geschlossen werden - Für stabile Deployments wird zunächst die kostengünstige Red-Black-Strategie genutzt; nur wenn inkompatible I/O-Änderungen unvermeidbar sind, kommt eine versionierte Strategie mit mehreren parallelen Versionen zum Einsatz
- Ein Logits-Prozessor, der anfragebezogene Einschränkungen in der Decoding-Schleife erzwingt, wurde für die Batch-Verarbeitung von vLLM V1 und multithreaded C++ neu implementiert; künftig soll er auf GPU-Fused-Kernels, asynchrones Scheduling und Modelle mit niedriger Präzision erweitert werden
In die bestehende ML-Infrastruktur integrierte Serving-Architektur
- Das JVM-basierte integrierte Serving-System von Netflix verarbeitet Routing und A/B-Tests, Kandidatengenerierung, Feature-Abruf, Inferenz, Nachbearbeitung und schrittweises Logging und unterstützt sowohl Echtzeit- als auch gecachte Batch-Pfade
- Aufrufer greifen auf Inferenz entweder über den bestehenden gRPC-Pfad des Serving-Systems oder über einen neuen direkten HTTP-Pfad für LLM-Anwendungen zu
- Der Ausführungsort hängt von der Modellgröße ab
- Kleine CPU-Modelle laufen im Prozess, um die Kosten entfernter Aufrufe zu vermeiden
- Große GPU-Modelle führen Vor- und Nachbearbeitung lokal aus und delegieren die Inferenz an den entfernten Model Scoring Service (MSS)
- MSS bietet XGBoost, TensorFlow, PyTorch und LLMs über eine einheitliche Schnittstelle an; darunter übernimmt der NVIDIA Triton Inference Server das Laden von Modellen, Batch-Verarbeitung und GPU-Scheduling
- Die Java-Steuerungsebene über Triton kümmert sich um Deployment, Versionsverwaltung, Zustandsprüfungen, Auto-Scaling und Multi-Region-Rollouts
- Wenn Modellentwickler Artefakte und Deployment-Konfiguration paketieren, werden GPU-Instanzen bereitgestellt und Triton konfiguriert
- Upgrades werden ohne Downtime koordiniert
vLLM als Standard-Inferenz-Engine
- Die erste Plattform nutzte TensorRT-LLM, das damals hohe Leistung bot und bereits in Triton innerhalb des MSS integriert war
- Im Sommer 2025 hatten Open-Source-Engines den Leistungsabstand zu spezialisierten Stacks weitgehend geschlossen, und die Workloads hatten sich auf folgende Bereiche ausgeweitet
- Embedding-Erzeugung
- Prefill-only-Inferenz für Ranking und Suche
- Autoregressives Decoding
- Benutzerdefinierte Modelle mit komplexer schrittweiser Constraint-Logik
- Nach erneutem Benchmarking dieser Workloads wurde vLLM anhand der Betriebseignung als Standard-Engine für den Hauptpfad ausgewählt
- Benutzerdefinierte Modellarchitekturen lassen sich ohne mehrstufige Kompilierung laden, was die iterative Entwicklung nicht standardisierter Modelle beschleunigt
- Es bietet Erweiterungs-Hooks für benutzerdefinierte Decoding-Logik
- Im Vergleich zum frühen, compilerbasierten TensorRT-LLM lassen sich Ausfälle und Zwischenzustände leichter untersuchen
- Viele ML-Praktiker waren bereits in der Forschungsphase mit vLLM vertraut, wodurch die Kosten der Überführung in die Produktion sinken
Paketierungsmodell von Triton und vLLM
- In Triton gibt es zwei Paketierungspfade, das Python-Backend und das vLLM-Backend; der zentrale Unterschied ist, wie stark Frontend-Upgrades und Modellartefakte gekoppelt sind
- Im Python-Backend definieren Entwickler beim Paketieren die Ein- und Ausgabe-Tensorspezifikation
- Die Spezifikation wird im Artefakt festgeschrieben und muss mit dem Request-Builder des externen Frontends übereinstimmen
- Wenn sich durch ein Frontend-Upgrade das I/O ändert, muss auch der Paketierungscode angepasst werden, sonst schlagen Requests zur Laufzeit fehl
- Artefakte des vLLM-Backends bestehen aus einer JSON-Konfiguration, die auf Modellgewichte und Tokenizer verweist
- Beim Deployment erzeugt das Triton-Backend die I/O-Tensorspezifikation dynamisch
- Modellentwickler müssen die Tensorspezifikation nicht selbst definieren, und Modell sowie Frontend können unabhängig voneinander geändert werden
- Die Standardwahl ist das vLLM-Backend, doch in der Produktion zeigten sich zwei Einschränkungen
- Versionskonflikte: Das Triton-Backend wird gegen eine bestimmte vLLM-API kompiliert; wenn beide Versionen auseinanderlaufen, lässt sich das gesamte Backend nicht laden
- Triton 25.09 importiert beispielsweise
vllm.engine.metrics, doch dieses Modul wurde in vLLM 0.11.2 entfernt - Beim Erstellen des Service-Images müssen kompatible Versionen fixiert werden, und Modellentwickler dürfen die vLLM-Version im Paketierungsschritt nicht überschreiben
- Triton 25.09 importiert beispielsweise
- Benutzerdefinierte Ausführungslogik: Das vLLM-Backend setzt standardmäßige HuggingFace-kompatible Modelle und den vollständigen Inferenz-Lebenszyklus voraus
- Für benutzerdefinierte Vor- und Nachbearbeitung, Ensemble-Pipelines oder separate Tokenisierung ist ein Python-Backend nötig, das
execute()kontrollieren kann - Für einige Modelle bleibt dieser Umgehungspfad weiter erforderlich
- Für benutzerdefinierte Vor- und Nachbearbeitung, Ensemble-Pipelines oder separate Tokenisierung ist ein Python-Backend nötig, das
- Versionskonflikte: Das Triton-Backend wird gegen eine bestimmte vLLM-API kompiliert; wenn beide Versionen auseinanderlaufen, lässt sich das gesamte Backend nicht laden
gRPC und OpenAI-kompatible HTTP-API
- Von XGBoost-Ensembles bis zu großen LLMs wird über denselben gRPC-Aufruf ausgewertet, sodass bestehende Client-Bibliotheken, Zustandsprüfungen und Deployment-Pipelines wiederverwendet werden können
- Da Inferenz-Engines, Orchestrierungs-Frameworks, Evaluierungswerkzeuge und Client-Bibliotheken im LLM-Ökosystem OpenAI-kompatible Schnittstellen nutzen, wird diese zusätzlich parallel zu gRPC angeboten
- Da dieselbe API erhalten bleibt, sind Codeänderungen gering, wenn aus Gründen von Qualität, Latenz, Kosten oder Datenschutz von gehosteten Modellen zu selbst gehosteten, feinabgestimmten Modellen gewechselt wird
- Die Implementierung nutzt NVIDIAs OpenAI-kompatibles Triton-Frontend wieder
- Ein eingebetteter Triton-Server wird gestartet
TritonLLMEnginewandelt das Request-Schema in Triton-Inferenzanfragen um- Antworten werden über FastAPI bereitgestellt
- Zusätzlich wird das KServe-HTTP/gRPC-Frontend aktiviert, damit die Java-Steuerungsebene per gRPC auf dieselbe Triton-Instanz zugreifen kann
- Es wurde entdeckt, dass das Frontend
response_format, obwohl im Schema erlaubt, stillschweigend verwirft, bevor es an vLLM weitergereicht wird- Selbst wenn JSON-Ausgabe angefordert wurde, lief die Ausführung ohne Guided-Decoding-Constraints und konnte ungültiges JSON zurückgeben, ohne dass ein Plattformfehler sichtbar wurde
- Das Frontend wurde als Git-Subtree eingebunden und so gepatcht, dass
response_format-Requests in Guided-Decoding-Parameter von vLLM übersetzt werden
Strategien für Deployments ohne Downtime
- GPU-Deployments haben längere Startzeiten als CPU-Services, und zwischen Modellversionen kann sich sogar das I/O-Schema ändern; deshalb sind für Rollouts ohne Unterbrechung zusätzliche Anpassungen nötig
- Beim Red-Black-Deployment wird neben der bestehenden Version eine neue Version hochgefahren; nach bestandenen Zustandsprüfungen wird der Traffic schrittweise umgeschaltet
- Skalierung nach oben und unten von neuer und bestehender Version erfolgt im gleichen Verhältnis
- Schlägt ein Schritt fehl, wird atomar zurückgerollt
- Geeignet ist dies, wenn die Modellschnittstelle stabil bleibt
- Wenn sich das I/O-Schema ändert, etwa durch neue Tensor-Dimensionen, entsteht bei Red-Black eine Koordinationslücke
- Bevor das neue Modell vollständig aktiv ist, können übergeordnete Verbraucher ihre Konfiguration nicht ändern
- Werden während des Übergangs Requests im alten Format an das neue Deployment geleitet, schlagen sie fehl
- Das versionierte Deployment löst dieses Problem, indem für jedes Paar
(modelId, modelVersion)ein unabhängiges Deployment erhalten bleibt- Mehrere Versionen werden gleichzeitig bedient, sodass Modell-Deployment und Consumer-Update entkoppelt sind
- Verbraucher ändern ihre Konfiguration erst, wenn die neue Version vollständig bereit ist, während die alte Version weiter Legacy-Traffic verarbeitet
- Frühere Deployments werden bereinigt, sobald sie inaktiv sind, aber die neueste Version bleibt immer erhalten
- Während des Übergangs mit überlappenden Versionen steigen die GPU-Kosten vorübergehend an
- Es wird empfohlen, veränderliche Einstellungen wie Tensorformen direkt in das Inferenzmodell einzubauen, um sie versionsunabhängig zu machen und die günstigere Red-Black-Strategie zu nutzen
- Versionierte Deployments sollen nur eingesetzt werden, wenn inkompatible Schnittstellenänderungen unvermeidbar sind
Startprozedur und Modell-Cache
- Eine vLLM-on-Triton-Instanz muss mehrere Startschritte abschließen, bevor sie den gRPC-Port öffnen kann
- Wenn große LLMs direkt von S3 oder Hugging Face geladen werden, wird der Cold Start länger, als es der Scheduler zulässt
- Zum Zeitpunkt der Modellveröffentlichung wird das Modell vorab auf Amazon FSx materialisiert
- Im anschließenden Startprozess wird dann statt Objektspeicher ein Hochleistungs-Dateisystem verwendet
- Bei Deployments, die eine OpenAI-kompatible API benötigen, läuft Triton als eingebetteter Server innerhalb des Frontend-Prozesses
- Andernfalls wird Triton eigenständig ausgeführt
- Die Ausführungsart wird beim Paketieren pro Deployment konfiguriert
- Zu den weiteren Startschritten gehören das Entpacken des Modellpakets, die Installation benutzerdefinierter vLLM-Plugins über Python-
entry_points, das Bereinigen des Prometheus-Multiprozess-Verzeichnisses und das Blockieren des gRPC-Ports, bis die Engine vollständig bereit ist
Integration von Triton- und vLLM-Metriken
- vLLM schreibt Metriken als
.db-Dateien inPROMETHEUS_MULTIPROC_DIR, während Triton Servermetriken über einen separaten Prometheus-Endpunkt bereitstellt - Beide Systeme kennen die Metriken des jeweils anderen nicht, und die eingebaute Triton-Bridge stellt von den mehr als 40 Metriken von vLLM nur 9 bereit
- Token-Durchsatz
- KV-Cache-Auslastung
- Wichtige Kennzahlen wie die Trefferquote des Präfix-Caches fehlen
- Ein leichter HTTP-Proxy holt die Triton-Metriken per HTTP ab und liest die vLLM-Metriken auf der Festplatte über den Prometheus-
MultiProcessCollector, um sie in einer einzigen/metrics-Antwort zusammenzuführen - Bestehende Dashboards und Alarme können unverändert weiter genutzt werden
Erzwingen von Ausgabe-Constraints im Decoding-Prozess
- Einige Produktions-Workloads benötigen eine feingranulare Kontrolle über die Tokenerzeugung; statt ungültige Ergebnisse nach der Inferenz per Retry oder Recovery zu behandeln, werden Constraints direkt in der Decoding-Schleife angewendet
- Jede Constraint wird als Zustandsmaschine modelliert, deren Zustand sich anhand der erzeugten Token-Historie ändert und die in jedem Schritt eine Maske zulässiger Token ausgibt
- Verwendet wird die benutzerdefinierte Logits-Prozessor-Schnittstelle von vLLM; da sich die Regeln pro Anfrage unterscheiden, wird je Anfrage ein separat konfigurierter Prozessor zugewiesen
- Anfangs wurde wegen funktionaler Lücken vLLM V0 verwendet; im 4. Quartal 2025 erfolgte nach Reifung von V1 der Wechsel
Skalierungsengpässe in vLLM V0
- Die erste reine Python-Implementierung funktionierte funktional, skalierte aber bei steigender Zahl gleichzeitiger Anfragen nicht
- Benutzerdefinierte Logits-Prozessoren in vLLM V0 werden pro Anfrage ausgeführt
- Die GPU erzeugt die Logits für den gesamten Batch
- Die CPU kopiert diese und wartet, bis die Übertragung abgeschlossen ist
- Anschließend wird die Constraint-Logik jeder Anfrage nacheinander ausgeführt
- Wegen des GIL in Python ließ sich diese Arbeit pro Anfrage nicht parallelisieren; dadurch stieg die CPU-Zeit für die Logits-Verarbeitung proportional zur Batch-Größe, und die Tail-Latenz nahm zu
- Selbst wenn die Vorwärtsläufe des Modells auf der GPU effizient gebatcht wurden, blieb die Gesamtlatenz an die CPU gebunden
- Dieser Engpass zeigt sich nicht in Single-Request-Benchmarks, sondern erst bei realitätsnaher Parallelität
Batch-basierte Verarbeitung in vLLM V1
- vLLM V1 verlagert die Logits-Verarbeitung von einer pro Anfrage orientierten Methode auf Batch-Ebene
- Benutzerdefinierte Prozessoren wurden auf Basis von Batch-Datenstrukturen neu geschrieben, um Masken für mehrere Anfragen gemeinsam zu berechnen
- Der leistungskritische Pfad wurde in multithreaded C++ neu implementiert, um den GIL zu umgehen; dadurch bleibt die Zeit für die Logits-Verarbeitung auch bei wachsender Batch-Größe konstant
- In der V1-API muss über
update_state(batch_update)die Änderung der Batch-Mitglieder explizit verfolgt werden- Das ist komplexer als die pro Anfrage ausgelegte Schnittstelle von V0
- Es ist aber nötig, um anfragebezogenen Zustand in dynamisch wechselnden Batches korrekt zu erhalten
Operative Absicherung zustandsbasierter Constraint-Verarbeitung
- Auch nach Beseitigung des Performance-Engpasses zeigten sich bei zustandsbehafteter Decoding-Logik zwei weitere Probleme
-
Teilweises Prefill
- V1 führt Prefilling in Chunks aus, sodass das Prefill einer Anfrage sich über mehrere Engine-Schritte erstrecken kann
- Allein mit
BatchUpdatelässt sich vollständiges und teilweises Prefill nicht unterscheiden, daher wurde internes Tracking ergänzt
-
Verdrängung (Preemption)
- Bei Speichermangel kann vLLM den KV-Cache teilweise abgeschlossener Anfragen entfernen und sie später mit einer anderen Liste aus Prompt- und Ausgabetoken erneut einplanen
- Das verletzt die Annahme der Zustandsmaschine, dass die Liste der Ausgabetoken nur wächst
- Es wird erkannt, ob die Token-Historie zwischen zwei Decoding-Schritten kürzer geworden ist; dann wird die Zustandsmaschine zurückgesetzt und mit dem neuen Prompt neu aufgebaut
Nächste Investitionsfelder
- Die aktuelle Plattform zielt auf niedrige Latenz, tiefe Anpassbarkeit und Integration in die bestehende Infrastruktur und bietet über vLLM und Triton sowie konsistente APIs einen Pfad von Experimenten bis zur Produktion
- Durch Gegenmaßnahmen gegen fest verdrahtete Versionen, stillschweigend fallengelassene API-Felder und Kompromisse bei der Paketierung werden Plattformstabilität und Developer Experience verbessert
- Geplant sind vier weitere Verbesserungen
- Komprimierung von System-Prompts, um die Prompt-Länge ohne Qualitätsverlust zu reduzieren
- Asynchrones Scheduling in vLLM V1
- Vektorisierte Logits-Prozessoren, die statt CPU-Code auf GPU-Fused-Kernels laufen
- Modellvarianten mit niedriger Präzision, um den Speicherverbrauch zu senken und den Durchsatz zu erhöhen
- Netflix will weiterhin Open-Source-ML-Bibliotheken wie Triton, vLLM und PyTorch nutzen und mit den jeweiligen Communities zusammenarbeiten
Noch keine Kommentare.