- Netflix opera los LLM junto con su infraestructura de ML existente, sin separarlos en un silo aparte, y conecta vLLM y Triton a un sistema de serving integrado
- vLLM, elegido como motor base, ofrece soporte para modelos personalizados, facilidad de depuración, hooks de extensión y familiaridad con el entorno de investigación; además, con el backend de vLLM en Triton reduce el acoplamiento entre el modelo y el frontend
- Aunque ofrece tanto gRPC como una API compatible con OpenAI, tuvo que corregir directamente brechas detectadas en producción, como la omisión de
response_format, desajustes de versión entre Triton y vLLM, y el manejo de modelos no estándar - Para despliegues estables, aplica primero la estrategia Red-Black, de menor costo, y usa una estrategia Versioned con varias versiones simultáneas solo cuando los cambios incompatibles de I/O son inevitables
- Reimplementó los procesadores de logits que aplican restricciones por solicitud dentro del bucle de decodificación con procesamiento por lotes en vLLM V1 y C++ multihilo, y planea ampliarlos con kernels fusionados en GPU, scheduling asíncrono y modelos de baja precisión
Estructura de serving integrada en la infraestructura de ML existente
- El sistema unificado de serving basado en JVM de Netflix maneja routing y pruebas A/B, generación de candidatos, consulta de features, inferencia, posprocesamiento y logging por etapa, y admite tanto rutas en tiempo real como rutas por lotes con caché
- Quienes llaman pueden acceder a la inferencia mediante la ruta gRPC del sistema de serving existente o una nueva ruta HTTP directa para aplicaciones LLM
- La ubicación de ejecución cambia según el tamaño del modelo
- Los modelos pequeños en CPU se ejecutan dentro del proceso para evitar el costo de llamadas remotas
- Los modelos grandes en GPU hacen el pre y posprocesamiento localmente y delegan la inferencia al servicio remoto Model Scoring Service (MSS)
- MSS ofrece XGBoost, TensorFlow, PyTorch y LLM bajo una sola interfaz, mientras que el NVIDIA Triton Inference Server subyacente se encarga de la carga de modelos, el batching y el scheduling de GPU
- La capa de control en Java sobre Triton gestiona despliegues, versionado, verificación de estado, autoescalado y rollout multirregión
- Cuando el desarrollador del modelo empaqueta los artefactos y la configuración de despliegue, se aprovisionan instancias GPU y se configura Triton
- Las actualizaciones se coordinan sin tiempo de inactividad
Elección de vLLM como motor de inferencia base
- La plataforma inicial usaba TensorRT-LLM, que en ese momento tenía alto rendimiento y ya estaba integrado con Triton en MSS
- Para el verano de 2025, los motores open source ya habían cerrado en gran parte la brecha de rendimiento con los stacks especializados, y las cargas de trabajo se habían ampliado al siguiente rango
- generación de embeddings
- inferencia solo de prefill para ranking y búsqueda
- decodificación autorregresiva
- modelos personalizados con lógica de restricciones compleja por paso
- Tras volver a benchmarkear estas cargas, eligió vLLM como motor base de la ruta principal por su idoneidad operativa
- Puede cargar arquitecturas de modelos personalizadas sin compilación en múltiples etapas, acelerando la iteración de modelos no estándar
- Ofrece hooks de extensión para lógica de decodificación personalizada
- A diferencia del TensorRT-LLM inicial, orientado a compilación, facilita investigar fallas y estados intermedios
- Muchos profesionales de ML ya estaban familiarizados con vLLM en investigación, lo que reduce el costo de llevarlo a producción
Cómo se empaquetan Triton y vLLM
- Triton tiene dos rutas de empaquetado: Python backend y backend de vLLM; la diferencia clave es qué tan fuertemente quedan acoplados las actualizaciones del frontend y los artefactos del modelo
- En Python backend, el desarrollador define la especificación de tensores de entrada y salida al momento de empaquetar
- La especificación queda fija en el artefacto y debe coincidir con el constructor de solicitudes del frontend externo
- Si el I/O cambia por una actualización del frontend, también hay que modificar el código de empaquetado; de lo contrario, las solicitudes fallan en tiempo de ejecución
- Los artefactos del backend de vLLM consisten en una configuración JSON que apunta a los pesos del modelo y al tokenizer
- En el despliegue, el backend de Triton genera dinámicamente la especificación de tensores de I/O
- El desarrollador del modelo no necesita definir la especificación de tensores, y el modelo y el frontend pueden cambiar de forma independiente
- La opción por defecto es el backend de vLLM, pero en producción aparecieron dos limitaciones
- Desajuste de versiones: el backend de Triton se compila contra una API específica de vLLM, así que si ambas versiones no coinciden no se puede cargar todo el backend
- Por ejemplo, Triton 25.09 importa
vllm.engine.metrics, pero ese módulo fue eliminado en vLLM 0.11.2 - Al crear la imagen del servicio, hay que fijar versiones compatibles y evitar que el desarrollador del modelo sobrescriba la versión de vLLM durante el empaquetado
- Por ejemplo, Triton 25.09 importa
- Lógica de ejecución personalizada: el backend de vLLM asume modelos estándar compatibles con HuggingFace y el ciclo de vida completo de inferencia
- Para ejecuciones no estándar, como pre y posprocesamiento personalizados, pipelines de ensamblado o tokenización separada, se necesita Python backend para controlar
execute() - Algunos modelos seguirán necesitando esta ruta alternativa
- Para ejecuciones no estándar, como pre y posprocesamiento personalizados, pipelines de ensamblado o tokenización separada, se necesita Python backend para controlar
- Desajuste de versiones: el backend de Triton se compila contra una API específica de vLLM, así que si ambas versiones no coinciden no se puede cargar todo el backend
gRPC y API HTTP compatible con OpenAI
- Reutiliza las mismas llamadas gRPC desde ensamblados de XGBoost hasta LLM a gran escala, conservando las bibliotecas cliente, verificaciones de estado y pipelines de despliegue existentes
- Como los motores de inferencia, frameworks de orquestación, herramientas de evaluación y bibliotecas cliente del ecosistema LLM usan interfaces compatibles con OpenAI, las ofrece junto con gRPC
- Al mantener la misma API, se requieren pocos cambios de código al pasar de modelos alojados a modelos propios afinados y autoalojados por motivos de calidad, latencia, costo o privacidad de datos
- La implementación reutiliza el frontend compatible con OpenAI de Triton de NVIDIA
- Inicia un servidor Triton embebido
TritonLLMEngineconvierte el esquema de solicitudes en solicitudes de inferencia de Triton- Entrega respuestas mediante FastAPI
- También activa el frontend HTTP/gRPC de KServe para que la capa de control Java pueda acceder por gRPC a la misma instancia de Triton
- Se detectó un problema en el que el frontend descartaba silenciosamente
response_format, permitido por el esquema, antes de pasarlo a vLLM- Aunque se pidiera salida JSON, la ejecución ocurría sin restricciones de guided decoding, por lo que podía devolver JSON inválido y además no exponer ningún error de plataforma
- Se incorporó el frontend como Git subtree y se parchó para convertir las solicitudes
response_formaten parámetros de guided decoding de vLLM
Estrategias de despliegue de modelos sin tiempo de inactividad
- Los despliegues en GPU tardan más en iniciar que los servicios en CPU y el esquema de I/O puede cambiar entre versiones del modelo, por lo que los rollouts sin interrumpir solicitudes requieren ajustes adicionales
- El despliegue Red-Black levanta una nueva versión junto a la existente y, si pasa las verificaciones de estado, redirige el tráfico gradualmente
- Escala la nueva versión y reduce la anterior en la misma proporción
- Si algo falla en cualquier etapa, hace rollback de forma atómica
- Es adecuado cuando la interfaz del modelo es estable
- Si cambia el esquema de I/O, como una nueva dimensión de tensor, aparece una brecha de coordinación en Red-Black
- El consumidor superior no puede cambiar su configuración hasta que el nuevo modelo esté completamente activo
- Si durante la transición una solicitud en el formato antiguo llega al nuevo despliegue, falla
- El despliegue Versioned resuelve esto manteniendo despliegues independientes para cada par
(modelId, modelVersion)- Como atiende varias versiones a la vez, separa el despliegue del modelo de la actualización del consumidor
- El consumidor cambia la configuración solo cuando la nueva versión está completamente lista, mientras la versión anterior sigue atendiendo tráfico heredado
- Los despliegues anteriores inactivos se limpian, pero la versión más reciente siempre se conserva
- Durante el período en que se superponen versiones en la transición, el costo de GPU aumenta temporalmente
- Recomienda meter directamente en el modelo de inferencia la configuración que puede cambiar, como la forma de los tensores, para que sea independiente de la versión y poder usar Red-Black, de menor costo
- Versioned solo se usa cuando no es posible evitar cambios incompatibles en la interfaz
Procedimiento de arranque y caché de modelos
- Una instancia de vLLM sobre Triton debe completar varias etapas de arranque antes de abrir el puerto gRPC
- Si al iniciar un LLM grande se descarga directamente desde S3 o Hugging Face, el cold start se vuelve demasiado largo para el margen permitido por el scheduler
- Cuando se anuncia el modelo, este se materializa previamente en Amazon FSx
- Luego, el proceso de arranque usa ese sistema de archivos de alto rendimiento en lugar del almacenamiento de objetos
- En los despliegues que requieren una API compatible con OpenAI, Triton se ejecuta como servidor embebido dentro de ese proceso frontend
- En los demás despliegues, Triton se ejecuta por separado
- El modo de ejecución se configura por despliegue durante el empaquetado
- El resto del arranque incluye descomprimir el paquete del modelo, instalar plugins personalizados de vLLM mediante Python
entry_points, limpiar el directorio multiproceso de Prometheus y bloquear el puerto gRPC hasta que el motor esté listo
Integración de métricas de Triton y vLLM
- vLLM escribe métricas como archivos
.dbenPROMETHEUS_MULTIPROC_DIR, mientras que Triton expone las métricas del servidor mediante un endpoint Prometheus aparte - Ambos sistemas no reconocen las métricas del otro, y el puente embebido de Triton solo expone 9 de más de 40 métricas de vLLM
- throughput de tokens
- uso de caché KV
- faltan indicadores clave como la tasa de aciertos de prefix cache
- Un proxy HTTP ligero obtiene por HTTP las métricas de Triton y, con
MultiProcessCollectorde Prometheus, lee desde disco las métricas de vLLM para unirlas en una sola respuesta/metrics - Los dashboards y alertas existentes pueden seguir usándose sin cambios
Aplicación de restricciones de salida durante la decodificación
- Algunas cargas de trabajo en producción requieren control fino sobre la generación de tokens, por lo que en vez de reintentar o reparar resultados inválidos después de la inferencia, aplican restricciones dentro del bucle de decodificación
- Cada restricción se modela como una máquina de estados cuyo estado cambia según el historial de tokens generados y que emite una máscara de tokens permitidos en cada paso
- Usa la interfaz de procesadores de logits personalizados de vLLM y, como las reglas cambian por solicitud, asigna un procesador configurado por separado a cada una
- Al principio usó vLLM V0 por la brecha funcional, y migró en el cuarto trimestre de 2025 cuando V1 ya había madurado
Cuellos de botella de escalado en vLLM V0
- La primera implementación, totalmente en Python, funcionaba a nivel funcional, pero no escalaba cuando aumentaban las solicitudes concurrentes
- En vLLM V0, los procesadores de logits personalizados se ejecutan por solicitud
- La GPU genera los logits de todo el lote
- La CPU los copia y espera a que termine la transferencia
- Luego ejecuta secuencialmente la lógica de restricciones de cada solicitud
- Debido al GIL de Python, no se puede paralelizar el trabajo por solicitud, así que el tiempo de CPU del procesamiento de logits crece en proporción al tamaño del lote y aumenta la latencia en cola
- Aunque el forward del modelo en GPU se procese eficientemente por lotes, la latencia total queda limitada por la CPU
- Este cuello de botella no aparece en benchmarks con una sola solicitud, sino solo con niveles reales de concurrencia
Procesamiento por lotes en vLLM V1
- vLLM V1 movió el procesamiento de logits de un enfoque por solicitud a uno por lotes
- Se reescribieron los procesadores personalizados sobre estructuras de datos por lote para calcular juntas las máscaras de varias solicitudes
- La ruta crítica de rendimiento se reimplementó en C++ multihilo para evitar el GIL, y el tiempo de procesamiento de logits se mantiene constante incluso cuando crece el tamaño del lote
- En la API de V1,
update_state(batch_update)debe rastrear explícitamente los cambios en los miembros del lote- Es más compleja que la interfaz por solicitud de V0
- Pero es necesaria para mantener con precisión el estado por solicitud en lotes que cambian dinámicamente
Refuerzos operativos para el manejo de restricciones con estado
- Incluso después de resolver el cuello de botella de rendimiento, aparecieron dos problemas en la lógica de decodificación con estado
-
Prefill parcial
- V1 realiza prefilling por chunks, así que el prefill de una solicitud puede abarcar varias etapas del motor
- Solo con
BatchUpdateno se puede distinguir entre un prefill completo y uno parcial, por lo que se agregó seguimiento interno
-
Preemption
- Si falta memoria, vLLM puede eliminar la caché KV de solicitudes parcialmente completadas y luego reprogramarlas con otra lista de prompts y tokens de salida
- Eso rompe la premisa de la máquina de estados de que la lista de tokens de salida siempre crece
- Se detecta si el historial de tokens se acortó entre pasos de decodificación, se reinicializa la máquina de estados y luego se reconfigura con el nuevo prompt
Próximas áreas de inversión
- La plataforma actual apunta a baja latencia, personalización profunda e integración con la infraestructura existente, y mediante vLLM y Triton junto con una API consistente ofrece una ruta que va del experimento a producción
- Al corregir el fijado de versiones, los campos de API omitidos en silencio y los compromisos de las opciones de empaquetado, mejora la estabilidad de la plataforma y la experiencia del desarrollador
- Planea las siguientes cuatro mejoras
- Compresión del system prompt para reducir la longitud del prompt sin sacrificar calidad
- scheduling asíncrono en vLLM V1
- procesadores de logits vectorizados que se ejecuten con kernels fusionados en GPU en lugar de código CPU
- variantes de modelos de baja precisión para reducir el uso de memoria y aumentar el throughput
- Seguirá aprovechando bibliotecas open source de ML como Triton, vLLM y PyTorch, y colaborará con las comunidades relacionadas
Aún no hay comentarios.