7 points par GN⁺ 3 시간 전 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Netflix n’isole pas les LLM dans un silo distinct, mais les exploite avec son infrastructure ML existante, en connectant vLLM et Triton à un système de serving unifié
  • vLLM, choisi comme moteur par défaut, offre la prise en charge des modèles personnalisés, une meilleure facilité de débogage, des hooks d’extension et une familiarité avec l’environnement de recherche ; le backend vLLM de Triton réduit aussi le couplage entre modèle et frontend
  • L’entreprise fournit à la fois son API gRPC existante et une API compatible OpenAI, mais a dû corriger elle-même des écarts apparus en production comme l’absence de response_format, les incompatibilités de version entre Triton et vLLM, ou la gestion de modèles non standard
  • Pour des déploiements stables, Netflix privilégie d’abord la stratégie Red-Black, moins coûteuse, et n’utilise une stratégie versionnée maintenant plusieurs versions en parallèle que lorsque des changements d’E/S incompatibles sont inévitables
  • L’entreprise a réimplémenté ses processeurs de logits, qui imposent des contraintes par requête dans la boucle de décodage, avec le traitement par lot de vLLM V1 et du C++ multithread ; elle prévoit ensuite d’étendre cela avec des kernels fusionnés GPU, un ordonnancement asynchrone et des modèles en basse précision

Architecture de serving intégrée à l’infrastructure ML existante

  • Le système de serving unifié de Netflix, basé sur la JVM, gère le routage et les tests A/B, la génération de candidats, la récupération de features, l’inférence, le post-traitement et la journalisation par étape, tout en prenant en charge les chemins temps réel et batch mis en cache
  • Les appelants accèdent à l’inférence via le chemin gRPC du système de serving existant ou via un nouveau chemin HTTP direct pour les applications LLM
  • Le lieu d’exécution varie selon la taille du modèle
    • Les petits modèles CPU s’exécutent dans le processus afin d’éviter le coût des appels distants
    • Les grands modèles GPU effectuent le pré- et post-traitement localement et délèguent l’inférence au Model Scoring Service (MSS) distant
  • Le MSS fournit XGBoost, TensorFlow, PyTorch et les LLM via une interface unique, tandis que le serveur sous-jacent NVIDIA Triton Inference Server prend en charge le chargement des modèles, le traitement par lot et l’ordonnancement GPU
  • La couche de contrôle Java au-dessus de Triton gère les déploiements, la gestion des versions, les vérifications d’état, l’autoscaling et les rollouts multi-régions
    • Lorsque le développeur de modèle empaquette les artefacts et la configuration de déploiement, elle provisionne les instances GPU et configure Triton
    • Les mises à niveau sont orchestrées sans interruption de service

Choix de vLLM comme moteur d’inférence par défaut

  • La plateforme initiale utilisait TensorRT-LLM, qui offrait alors de bonnes performances et était déjà intégré au Triton du MSS
  • À l’été 2025, les moteurs open source avaient presque comblé l’écart de performances avec les stacks spécialisées, tandis que les workloads s’étaient élargis à
    • la génération d’embeddings
    • l’inférence prefill-only pour le ranking et la recherche
    • le décodage autorégressif
    • des modèles personnalisés avec une logique de contrainte complexe à chaque étape
  • Après un nouveau benchmark de ces workloads, Netflix a retenu vLLM comme moteur par défaut sur la base de son adéquation opérationnelle
    • Il peut charger des architectures de modèles personnalisées sans compilation multi-étapes, ce qui accélère l’itération sur les modèles non standard
    • Il fournit des hooks d’extension pour une logique de décodage personnalisée
    • Il est plus facile d’y examiner les incidents et les états intermédiaires que dans le TensorRT-LLM initial, moteur compilé
    • De nombreux praticiens ML étaient déjà familiers de vLLM en phase de recherche, ce qui réduit le coût du passage en production

Mode de packaging de Triton et vLLM

  • Triton propose deux voies de packaging, le backend Python et le backend vLLM ; la différence clé tient au degré de couplage entre la mise à niveau du frontend et les artefacts du modèle
  • Avec le backend Python, le développeur définit les spécifications des tenseurs d’entrée/sortie au moment du packaging
    • Ces spécifications sont figées dans l’artefact et doivent correspondre au constructeur de requêtes du frontend externe
    • Si une mise à niveau du frontend modifie les E/S, le code de packaging doit aussi être mis à jour, faute de quoi les requêtes échouent à l’exécution
  • Les artefacts du backend vLLM consistent en une configuration JSON pointant vers les poids du modèle et le tokenizer
    • Au déploiement, le backend Triton génère dynamiquement la spécification des tenseurs d’E/S
    • Le développeur n’a pas à définir la spécification des tenseurs et peut faire évoluer indépendamment le modèle et le frontend
  • Le choix par défaut est le backend vLLM, mais deux contraintes sont apparues en production
    • Incompatibilité de version : le backend Triton étant compilé pour une API vLLM donnée, un décalage de version peut empêcher le chargement complet du backend
      • Par exemple, Triton 25.09 importe vllm.engine.metrics, mais ce module a été supprimé dans vLLM 0.11.2
      • Lors de la création de l’image de service, il faut figer les versions compatibles et empêcher les développeurs de modèles d’écraser la version de vLLM à l’étape de packaging
    • Logique d’exécution personnalisée : le backend vLLM suppose des modèles compatibles HuggingFace standard et un cycle d’inférence complet
      • Les exécutions non standard, comme le pré-/post-traitement personnalisé, les pipelines d’ensemble ou une tokenisation séparée, nécessitent le backend Python, qui permet de contrôler execute()
      • Certains modèles ont toujours besoin de cette voie de contournement

API gRPC et HTTP compatible OpenAI

  • Netflix évalue tout, des ensembles XGBoost aux grands LLM, via le même appel gRPC, ce qui permet de réutiliser les bibliothèques clientes, les vérifications d’état et les pipelines de déploiement existants
  • Comme les moteurs d’inférence, frameworks d’orchestration, outils d’évaluation et bibliothèques clientes de l’écosystème LLM utilisent des interfaces compatibles OpenAI, Netflix les propose en parallèle de gRPC
  • Le maintien de la même API limite les changements de code lors du passage d’un modèle hébergé à un modèle auto-hébergé affiné, pour des raisons de qualité, de latence, de coût ou de confidentialité des données
  • L’implémentation réutilise le frontend compatible OpenAI de Triton de NVIDIA
    • Il démarre un serveur Triton intégré
    • TritonLLMEngine convertit le schéma de requête en requête d’inférence Triton
    • La réponse est fournie via FastAPI
    • Le frontend HTTP/gRPC de KServe est aussi activé afin que la couche de contrôle Java puisse accéder en gRPC à la même instance Triton
  • Netflix a découvert que le frontend ignorait silencieusement le champ response_format autorisé par le schéma avant de le transmettre à vLLM
    • Même lorsqu’une sortie JSON était demandée, l’exécution se faisait sans contrainte de guided decoding, ce qui pouvait renvoyer du JSON invalide sans signaler d’erreur de plateforme
    • L’entreprise a importé le frontend via un Git subtree et l’a patché pour convertir les requêtes response_format en paramètres de guided decoding pour vLLM

Stratégies de déploiement de modèles sans interruption

  • Les déploiements GPU ont des temps de démarrage plus longs que les services CPU et peuvent même modifier le schéma d’E/S entre versions de modèle ; des ajustements supplémentaires sont donc nécessaires pour des rollouts sans interruption des requêtes
  • Le déploiement Red-Black place une nouvelle version à côté de l’ancienne puis bascule progressivement le trafic une fois les vérifications d’état validées
    • Le scale-up de la nouvelle version et le scale-down de l’ancienne se font au même rythme
    • En cas d’échec à n’importe quelle étape, le rollback est atomique
    • Cette approche convient lorsque l’interface du modèle est stable
  • Si le schéma d’E/S change, par exemple avec de nouvelles dimensions de tenseur, un écart de coordination apparaît avec Red-Black
    • Les consommateurs en amont ne peuvent pas modifier leur configuration tant que le nouveau modèle n’est pas totalement actif
    • Si des requêtes à l’ancien format sont envoyées au nouveau déploiement pendant la transition, elles échouent
  • Le déploiement Versioned résout ce problème en maintenant un déploiement indépendant pour chaque paire (modelId, modelVersion)
    • Comme plusieurs versions sont servies en parallèle, le déploiement du modèle est découplé de la mise à jour des consommateurs
    • Les consommateurs modifient leur configuration une fois la nouvelle version totalement prête, tandis que l’ancienne continue à traiter le trafic legacy
    • Les anciens déploiements devenus inactifs sont nettoyés, mais la version la plus récente est toujours conservée
    • Le chevauchement temporaire des versions pendant la transition augmente provisoirement le coût GPU
  • Netflix recommande de rendre indépendantes de la version les configurations susceptibles d’évoluer, comme la forme des tenseurs, en les intégrant directement dans le modèle d’inférence, afin de pouvoir utiliser la stratégie Red-Black, moins coûteuse
  • La stratégie Versioned n’est utilisée que lorsqu’il est impossible d’éviter des changements d’interface incompatibles

Procédure de démarrage et cache de modèles

  • Une instance vLLM-on-Triton doit franchir plusieurs étapes de démarrage avant d’ouvrir son port gRPC
  • Télécharger directement un grand LLM depuis S3 ou Hugging Face au démarrage allonge le cold start au-delà de ce que tolère l’ordonnanceur
    • Au moment de la publication du modèle, Netflix le matérialise à l’avance sur Amazon FSx
    • Le processus de démarrage utilise ensuite ce système de fichiers haute performance au lieu du stockage objet
  • Pour les déploiements nécessitant une API compatible OpenAI, Triton s’exécute comme serveur intégré dans le processus de frontend correspondant
    • Sinon, Triton s’exécute de manière autonome
    • Le mode d’exécution est configuré pour chaque déploiement lors du packaging
  • Le reste de la procédure de démarrage comprend la décompression du package du modèle, l’installation de plugins vLLM personnalisés via les entry_points Python, le nettoyage du répertoire multiprocessus Prometheus et le blocage du port gRPC jusqu’à ce que le moteur soit prêt

Intégration des métriques Triton et vLLM

  • vLLM écrit ses métriques sous forme de fichiers .db dans PROMETHEUS_MULTIPROC_DIR, tandis que Triton expose les métriques serveur via un endpoint Prometheus distinct
  • Les deux systèmes n’ont pas connaissance des métriques de l’autre, et le bridge intégré de Triton n’expose que 9 des plus de 40 métriques de vLLM
    • le débit de tokens
    • le taux d’utilisation du cache KV
    • des indicateurs clés comme le taux de hit du cache de préfixes sont absents
  • Un proxy HTTP léger récupère les métriques Triton en HTTP et lit les métriques vLLM sur disque via Prometheus MultiProcessCollector, puis les fusionne dans une seule réponse /metrics
  • Les dashboards et alertes existants peuvent ainsi être conservés sans modification

Imposer des contraintes de sortie pendant le décodage

  • Certains workloads de production nécessitent un contrôle fin de la génération de tokens ; au lieu de réessayer ou corriger les résultats invalides après l’inférence, Netflix applique les contraintes dans la boucle de décodage
  • Chaque contrainte est modélisée comme une machine à états dont l’état évolue selon l’historique des tokens générés et qui produit, à chaque étape, un masque des tokens autorisés
  • Netflix utilise l’interface de processeur de logits personnalisé de vLLM et assigne un processeur configuré séparément à chaque requête, car les règles diffèrent selon les requêtes
  • Au départ, l’entreprise utilisait vLLM V0 en raison d’un manque de fonctionnalités, puis a migré vers V1 au 4e trimestre 2025 quand celui-ci est devenu plus mature

Goulot d’étranglement de montée en charge avec vLLM V0

  • La première implémentation purement Python fonctionnait sur le plan fonctionnel, mais ne passait pas à l’échelle lorsque les requêtes concurrentes augmentaient
  • Dans vLLM V0, les processeurs de logits personnalisés s’exécutent requête par requête
    • Le GPU génère les logits pour tout le batch
    • Le CPU les copie et attend la fin du transfert
    • La logique de contrainte de chaque requête s’exécute ensuite de manière séquentielle
  • À cause du GIL de Python, il est impossible de paralléliser ce travail par requête ; le temps CPU de traitement des logits augmente donc proportionnellement à la taille du batch, ce qui accroît la latence de queue
  • Même si la passe avant du modèle sur GPU est efficacement batchée, la latence globale reste bloquée par le CPU
  • Ce goulot d’étranglement n’apparaît pas dans les benchmarks à requête unique, mais seulement à un niveau de concurrence réaliste

Traitement par lot dans vLLM V1

  • vLLM V1 fait passer le traitement des logits d’une approche requête par requête à une approche par lot
  • Netflix a réécrit ses processeurs personnalisés autour de structures de données batch afin de calculer ensemble les masques de plusieurs requêtes
  • Le chemin critique de performance a été réimplémenté en C++ multithread pour éviter le GIL, ce qui maintient constant le temps de traitement des logits même quand la taille du batch augmente
  • Dans l’API V1, il faut suivre explicitement les changements de composition du batch via update_state(batch_update)
    • C’est plus complexe que l’interface par requête de V0
    • Mais c’est nécessaire pour conserver correctement l’état par requête dans des batchs dynamiques

Renforts opérationnels pour les contraintes basées sur l’état

  • Même après avoir résolu le goulot de performance, deux problèmes sont apparus avec la logique de décodage avec état
  • Prefill partiel

    • V1 effectue un prefilling par chunks, de sorte que le prefill d’une requête peut s’étendre sur plusieurs étapes du moteur
    • BatchUpdate ne permet pas à lui seul de distinguer un prefill complet d’un prefill partiel ; un suivi interne supplémentaire a donc été ajouté
  • Préemption

    • En cas de manque de mémoire, vLLM peut supprimer le cache KV de certaines requêtes partiellement terminées, puis les replanifier ensuite avec une autre liste de prompts et de tokens de sortie
    • Cela casse l’hypothèse de la machine à états selon laquelle la liste des tokens de sortie ne fait que s’allonger
    • Netflix détecte si l’historique des tokens a raccourci entre deux étapes de décodage, réinitialise alors la machine à états et la reconfigure à partir du nouveau prompt

Prochains axes d’investissement

  • La plateforme actuelle vise une faible latence, une personnalisation poussée et une intégration à l’infrastructure existante, et fournit un chemin allant de l’expérimentation à la production via vLLM et Triton ainsi qu’une API cohérente
  • En corrigeant le figement des versions, les champs d’API ignorés silencieusement et les compromis liés aux choix de packaging, Netflix améliore la stabilité de la plateforme et l’expérience développeur
  • Quatre améliorations sont prévues ensuite
    • la compression du prompt système pour réduire la longueur des prompts sans sacrifier la qualité
    • l’ordonnancement asynchrone de vLLM V1
    • des processeurs de logits vectorisés s’exécutant dans des kernels fusionnés GPU plutôt qu’en code CPU
    • des variantes de modèles en basse précision pour réduire l’utilisation mémoire et augmenter le débit
  • Netflix prévoit de continuer à s’appuyer sur des bibliothèques ML open source comme Triton, vLLM et PyTorch, tout en collaborant avec les communautés concernées

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.