La inferencia de modelos de lenguaje grandes (LLMs) a escala de producción presenta desafíos fundamentales en la gestión de recursos computacionales, la latencia y la flexibilidad para modelos personalizados. Tradicionalmente, las organizaciones dependen de APIs de terceros, pero para cargas de trabajo a escala de hyperscaler con requisitos específicos de latencia, costo y privacidad de datos, la operación interna se vuelve imperativa. Este artículo detalla la evolución de una plataforma de inferencia de LLMs en Netflix, destacando cómo se abordaron las complejidades de la integración de motores de inferencia, el empaquetado de modelos, el diseño de APIs y las estrategias de despliegue para lograr un sistema robusto y eficiente.
El problema central es cómo ejecutar inferencia de LLMs de manera eficiente y escalable, integrándose con un ecosistema de ML ya maduro, sin sacrificar la capacidad de iteración rápida en modelos personalizados o la aplicación de lógica de negocio compleja como el 'constrained decoding'. La solución de Netflix se enfoca en la reutilización de infraestructura existente y la adopción de estándares de facto, como la API compatible con OpenAI, para minimizar la fricción en el ciclo de vida del desarrollo y despliegue de modelos.
Arquitectura del Sistema
La arquitectura de inferencia de LLMs de Netflix se basa en un sistema de servicio unificado basado en JVM que maneja el flujo de extremo a extremo para los consumidores. Este sistema gestiona el enrutamiento, la lógica de pruebas A/B, la generación de candidatos, la recuperación de características, la inferencia, el post-procesamiento y el registro. Para modelos pequeños basados en CPU, la inferencia se ejecuta en proceso. Para modelos más grandes que requieren GPUs, el sistema delega la inferencia a un servicio remoto compartido, el Model Scoring Service (MSS).
MSS actúa como un backend de inferencia unificado que soporta diversos frameworks como XGBoost, TensorFlow, PyTorch y LLMs. Debajo de MSS, NVIDIA Triton Inference Server gestiona la carga de modelos, el batching y la programación de GPUs. Un plano de control Java se encarga del despliegue, versionado, monitoreo de salud, autoescalado y despliegues multi-región. Los autores de modelos empaquetan sus artefactos y configuran el despliegue, y el plano de control provisiona instancias de GPU, configura Triton y orquesta actualizaciones sin tiempo de inactividad. La plataforma utiliza vLLM como motor de inferencia principal, integrado con Triton, y expone una API compatible con OpenAI además de la API gRPC interna. Para el almacenamiento de modelos, se utiliza Amazon FSx para reducir la latencia de arranque en caliente, precargando modelos desde S3 o Hugging Face en el momento del anuncio del modelo. La observabilidad se logra mediante un proxy HTTP ligero que fusiona métricas de vLLM (leídas de archivos .db de PROMETHEUS_MULTIPROC_DIR) y Triton (vía HTTP) en un único endpoint /metrics compatible con Prometheus.
Flujo de Inferencias de LLM
- 1 Consumer Request Solicitud HTTP (OpenAI-compatible) o gRPC al sistema de servicio.
- 2 JVM Serving System Maneja enrutamiento, A/B testing, pre-procesamiento, y delegación.
- 3 Model Scoring Service (MSS) Backend de inferencia unificado para varios tipos de modelos.
- 4 NVIDIA Triton Inference Server Carga de modelos, batching, scheduling de GPU. Puede ser embebido o standalone.
- 5 vLLM Engine Ejecuta la inferencia del LLM, incluyendo 'constrained decoding'.
- 6 GPU Ejecución de la pasada forward del modelo y procesamiento de logits.
- 7 Response Resultados de inferencia devueltos al consumidor.
Flujo de Despliegue de Modelo
- 1 Model Author Empaqueta artefactos del modelo y configura el despliegue.
- 2 Java Control Plane Provisiona instancias de GPU, configura Triton, orquesta actualizaciones.
- 3 Model Caching (FSx) Descarga modelos grandes de S3/Hugging Face a FSx para arranque rápido.
- 4 Triton/vLLM Instance Boot Extracción de paquete, instalación de plugins, inicialización del motor.
- 5 Health Checks Verificación de la disponibilidad y funcionalidad del nuevo despliegue.
- 6 Traffic Shift (Red-Black/Versioned) Cambio gradual o simultáneo de tráfico a la nueva versión.
| Capa | Tecnología | Justificación |
|---|---|---|
| compute | vLLM | Motor de inferencia principal para LLMs, elegido por su capacidad de cargar arquitecturas personalizadas, extensibilidad para lógica de decodificación y facilidad de depuración. vs TensorRT-LLM |
| orchestration | NVIDIA Triton Inference Server | Backend de inferencia compartido que gestiona la carga de modelos, el batching y la programación de GPUs para diversos frameworks de ML. |
| orchestration | Java Control Plane | Plano de control personalizado para despliegue, versionado, monitoreo de salud, autoescalado y despliegues multi-región de instancias de GPU. |
| storage | Amazon FSx | Sistema de archivos de alto rendimiento utilizado para el almacenamiento en caché de modelos grandes, reduciendo la latencia de arranque en frío. vs S3, Hugging Face (direct download) |
| networking | gRPC | Protocolo de comunicación interno para el sistema de servicio unificado de ML. |
| networking | HTTP (OpenAI-compatible API) | Interfaz externa para la inferencia de LLMs, adoptada por su compatibilidad con el ecosistema de LLMs y para facilitar la transición de experimentación a producción. |
| observability | Prometheus | Sistema de monitoreo y alertas. Se utiliza un proxy HTTP para unificar métricas de vLLM y Triton en un solo endpoint. PROMETHEUS_MULTIPROC_DIR para métricas de vLLM. |
Trade-offs
Ganancias
- ▲ Flexibilidad para modelos personalizados
- ▲ Reducción de latencia de arranque en frío
- ▲ Integración con ecosistema LLM (OpenAI API)
- ▲ Rendimiento de 'constrained decoding' a escala
Costes
- ▲ Mayor complejidad de infraestructura (operar LLMs internamente)
- △ Costo temporal de GPU durante despliegues versionados
- △ Necesidad de parches en componentes open-source (ej. Triton OpenAI frontend)
- △ Manejo de incompatibilidades de versión entre Triton y vLLM
Fundamentos Teóricos
El problema de la inferencia eficiente de modelos grandes, especialmente LLMs, se relaciona con principios fundamentales de la computación distribuida y la optimización de recursos. La gestión de la memoria de la GPU y la latencia de inferencia son desafíos clave, abordados por técnicas como el 'KV cache' y la 'paged attention' implementadas en motores como vLLM. Estos conceptos se basan en la optimización de la localidad de datos y la reducción de la sobrecarga de memoria, similar a los principios de 'memory paging' en sistemas operativos y la gestión de caché en arquitecturas de CPU.
El 'constrained decoding' es un ejemplo de cómo la lógica de negocio se integra directamente en el bucle de inferencia, un concepto que tiene paralelos con la programación con restricciones y los autómatas finitos. La optimización de este proceso, pasando de una ejecución secuencial en CPU a un procesamiento por lotes en C++ con multithreading, refleja la búsqueda de paralelismo y la reducción de la sobrecarga de la Global Interpreter Lock (GIL) en Python, un problema bien documentado en la literatura de sistemas concurrentes. La necesidad de manejar la preemption y los prefills parciales en el estado de la máquina de estados del decodificador se alinea con los desafíos de mantener la consistencia del estado en sistemas distribuidos y tolerantes a fallos, donde las operaciones pueden ser interrumpidas y reanudadas.