- A Netflix não isola LLMs em um silo separado; ela os opera junto com a infraestrutura de ML existente, conectando vLLM e Triton a um sistema unificado de serving
- O vLLM, escolhido como engine padrão, oferece suporte a modelos personalizados, facilidade de depuração, hooks de extensão e familiaridade com ambientes de pesquisa; com o backend vLLM do Triton, reduz o acoplamento entre modelos e front-end
- Embora ofereça tanto o gRPC existente quanto uma API compatível com OpenAI, a equipe precisou preencher por conta própria lacunas reveladas em produção, como ausência de
response_format, incompatibilidades de versão entre Triton e vLLM e tratamento de modelos não padronizados - Para implantações estáveis, a prioridade é a estratégia Red-Black, de menor custo; a estratégia Versioned, que mantém várias versões simultaneamente, é usada apenas quando mudanças incompatíveis de I/O são inevitáveis
- Processadores de logits, que impõem restrições por requisição dentro do loop de decodificação, foram reimplementados para o processamento em lote do vLLM V1 e em C++ multithread; no futuro, a plataforma deve evoluir para kernels GPU fusionados, agendamento assíncrono e modelos de baixa precisão
Arquitetura de serving integrada à infraestrutura de ML existente
- O sistema unificado de serving da Netflix, baseado em JVM, lida com roteamento e testes A/B, geração de candidatos, consulta de features, inferência, pós-processamento e logging por etapa, dando suporte tanto a caminhos em tempo real quanto a caminhos em lote cacheados
- Os chamadores acessam a inferência pelo caminho gRPC do sistema de serving existente ou por um novo caminho HTTP direto para aplicações de LLM
- O local de execução varia conforme o tamanho do modelo
- Modelos pequenos em CPU rodam dentro do processo para evitar o custo de chamadas remotas
- Modelos grandes em GPU executam o pré e pós-processamento localmente e delegam a inferência ao Model Scoring Service(MSS) remoto
- O MSS oferece XGBoost, TensorFlow, PyTorch e LLMs por uma única interface, enquanto o NVIDIA Triton Inference Server subjacente cuida de carregamento de modelos, processamento em lote e agendamento em GPU
- A camada de controle em Java sobre o Triton trata implantação, gerenciamento de versões, health checks, autoscaling e rollout multirregião
- Quando o desenvolvedor do modelo empacota artefatos e configurações de implantação, ela provisiona instâncias GPU e configura o Triton
- Upgrades são coordenados de forma sem downtime
Escolha do vLLM como engine de inferência padrão
- A plataforma inicial usava TensorRT-LLM, que na época tinha alto desempenho e já estava integrado ao Triton do MSS
- No verão de 2025, engines open source haviam reduzido quase toda a diferença de desempenho em relação a stacks especializadas, e as cargas de trabalho também se ampliaram para os seguintes casos
- Geração de embeddings
- Inferência apenas de prefill para ranqueamento e busca
- Decodificação autorregressiva
- Modelos personalizados com lógica complexa de restrições passo a passo
- Após reexecutar benchmarks dessas cargas, a equipe escolheu o vLLM como engine do caminho padrão com base na adequação operacional
- Permite carregar arquiteturas de modelos personalizadas sem compilação em múltiplas etapas, acelerando a iteração em modelos não padronizados
- Oferece hooks de extensão para lógica de decodificação personalizada
- É mais fácil investigar falhas e estados intermediários do que no TensorRT-LLM inicial, que era uma engine baseada em compilação
- Muitos profissionais de ML já estavam familiarizados com vLLM na fase de pesquisa, reduzindo o custo de levar modelos à produção
Como Triton e vLLM são empacotados
- No Triton há dois caminhos de empacotamento, Python backend e backend vLLM, e a diferença central é o quão fortemente upgrades de front-end e artefatos de modelo ficam acoplados
- No Python backend, o desenvolvedor define a especificação dos tensores de entrada e saída no momento do empacotamento
- A especificação fica fixada no artefato e precisa coincidir com o construtor de requisições do front-end externo
- Se um upgrade do front-end altera o I/O, o código de empacotamento também precisa ser ajustado; caso contrário, as requisições falham em runtime
- Artefatos do backend vLLM são compostos por uma configuração JSON que aponta para os pesos do modelo e o tokenizador
- Durante a implantação, o backend Triton gera dinamicamente a especificação dos tensores de I/O
- O desenvolvedor do modelo não precisa definir a especificação dos tensores, e modelo e front-end podem ser alterados de forma independente
- A escolha padrão é o backend vLLM, mas duas restrições apareceram em produção
- Incompatibilidade de versões: o backend Triton é compilado contra uma API específica do vLLM; se as duas versões divergem, o backend inteiro não consegue ser carregado
- Por exemplo, o Triton 25.09 importa
vllm.engine.metrics, mas esse módulo foi removido no vLLM 0.11.2 - É necessário fixar versões compatíveis ao criar a imagem de serviço e impedir que desenvolvedores de modelos sobrescrevam a versão do vLLM na etapa de empacotamento
- Por exemplo, o Triton 25.09 importa
- Lógica de execução personalizada: o backend vLLM assume modelos compatíveis com HuggingFace padrão e o ciclo de vida completo de inferência
- Execuções não padronizadas, como pré/pós-processamento personalizado, pipelines de ensemble e tokenização separada, exigem o Python backend, que permite controlar
execute() - Esse caminho alternativo continua necessário para alguns modelos
- Execuções não padronizadas, como pré/pós-processamento personalizado, pipelines de ensemble e tokenização separada, exigem o Python backend, que permite controlar
- Incompatibilidade de versões: o backend Triton é compilado contra uma API específica do vLLM; se as duas versões divergem, o backend inteiro não consegue ser carregado
gRPC e API HTTP compatível com OpenAI
- De ensembles XGBoost a LLMs de grande porte, tudo é avaliado pela mesma chamada gRPC, reutilizando bibliotecas cliente, health checks e pipelines de implantação existentes
- Como engines de inferência, frameworks de orquestração, ferramentas de avaliação e bibliotecas cliente do ecossistema de LLM usam interfaces compatíveis com OpenAI, essa interface é oferecida em paralelo ao gRPC
- Como a mesma API é mantida, migrar de um modelo hospedado para um modelo auto-hospedado com fine-tuning próprio, por motivos de qualidade, latência, custo ou privacidade de dados, exige pouca mudança de código
- A implementação reutiliza o front-end compatível com OpenAI do Triton da NVIDIA
- Inicia um servidor Triton embutido
- O
TritonLLMEngineconverte o schema da requisição em uma requisição de inferência do Triton - As respostas são servidas via FastAPI
- O front-end HTTP/gRPC do KServe também é ativado para que a camada de controle Java possa acessar a mesma instância Triton via gRPC
- Foi descoberto um problema em que o front-end aceitava
response_formatno schema, mas o descartava silenciosamente antes de repassá-lo ao vLLM- Mesmo solicitando saída JSON, a execução acontecia sem restrições de decodificação guiada, podendo retornar JSON inválido, e nenhum erro da plataforma era exposto
- O front-end foi incorporado como Git subtree e corrigido para converter requisições
response_formatem parâmetros de decodificação guiada do vLLM
Estratégia de implantação de modelos sem downtime
- Implantações em GPU têm tempo de inicialização maior que serviços em CPU e podem mudar até o schema de I/O entre versões de modelo, exigindo coordenação adicional para rollouts sem interromper requisições
- A implantação Red-Black sobe a nova versão ao lado da versão existente e, após passar nos health checks, transfere o tráfego gradualmente
- A expansão da nova versão e a redução da versão antiga avançam na mesma proporção
- Se qualquer etapa falhar, o rollback é feito de forma atômica
- É adequada quando a interface do modelo é estável
- Quando o schema de I/O muda, como uma nova dimensão de tensor, surge uma lacuna de coordenação no Red-Black
- Antes que o novo modelo esteja totalmente ativo, consumidores upstream não podem mudar suas configurações
- Se requisições no formato antigo forem encaminhadas para a nova implantação durante a transição, elas falham
- A implantação Versioned resolve isso mantendo implantações independentes para cada par
(modelId, modelVersion)- Como várias versões são servidas simultaneamente, a implantação do modelo e as atualizações dos consumidores ficam desacopladas
- Consumidores mudam a configuração depois que a nova versão está completamente pronta, enquanto a versão antiga continua processando tráfego legado
- Implantações antigas que ficam inativas são removidas, mas a versão mais recente é sempre preservada
- Durante o período de sobreposição de versões na transição, o custo de GPU aumenta temporariamente
- A recomendação é colocar configurações que podem variar, como formatos de tensor, diretamente dentro do modelo de inferência para torná-las independentes de versão, usando o Red-Black de menor custo
- Versioned é usado apenas quando mudanças incompatíveis de interface não podem ser evitadas
Procedimento de inicialização e cache de modelos
- Uma instância vLLM-on-Triton precisa concluir várias etapas de inicialização antes de abrir a porta gRPC
- Ao iniciar LLMs grandes, baixá-los diretamente do S3 ou do Hugging Face torna o cold start longo a ponto de exceder a tolerância do scheduler
- No momento da publicação do modelo, ele é materializado previamente no Amazon FSx
- Depois, durante a inicialização, usa-se o sistema de arquivos de alto desempenho em vez do object storage
- Em implantações que precisam de API compatível com OpenAI, o Triton roda como servidor embutido dentro do processo desse front-end
- Nas demais implantações, o Triton roda de forma independente
- O modo de execução é configurado por implantação no momento do empacotamento
- O restante da inicialização inclui descompactar o pacote do modelo, instalar plugins personalizados do vLLM via
entry_pointsdo Python, limpar o diretório multiprocesso do Prometheus e manter a porta gRPC bloqueada até que a engine esteja pronta
Integração de métricas do Triton e do vLLM
- O vLLM grava métricas como arquivos
.dbemPROMETHEUS_MULTIPROC_DIR, enquanto o Triton fornece métricas de servidor em um endpoint Prometheus separado - Os dois sistemas não reconhecem as métricas um do outro, e a ponte embutida do Triton expõe apenas 9 de mais de 40 métricas do vLLM
- Throughput de tokens
- Uso do cache KV
- Indicadores essenciais como taxa de acerto do cache de prefixo ficam de fora
- Um proxy HTTP leve busca as métricas do Triton via HTTP e lê as métricas do vLLM em disco com o
MultiProcessCollectordo Prometheus, combinando tudo em uma única resposta/metrics - Dashboards e alertas existentes podem ser usados sem alterações
Aplicação de restrições à saída durante a decodificação
- Algumas cargas de trabalho em produção exigem controle fino sobre a geração de tokens; em vez de tentar novamente ou recuperar resultados incorretos após a inferência, aplicam restrições dentro do loop de decodificação
- Cada restrição é modelada como uma máquina de estados cujo estado muda conforme o histórico de tokens gerados e que emite, a cada etapa, uma máscara de tokens permitidos
- A interface de processador de logits personalizado do vLLM é usada; como as regras variam por requisição, um processador configurado separadamente é atribuído a cada uma
- Inicialmente, por lacunas de funcionalidades, foi usado o vLLM V0; a migração para V1 ocorreu no quarto trimestre de 2025, quando ela amadureceu
Gargalo de escala no vLLM V0
- A primeira implementação puramente em Python funcionava em termos funcionais, mas não escalava quando aumentava o número de requisições simultâneas
- No vLLM V0, processadores de logits personalizados eram executados por requisição
- A GPU gerava logits para o lote inteiro
- A CPU os copiava e aguardava o término da transferência
- A lógica de restrição de cada requisição era executada sequencialmente
- Por causa do GIL do Python, não era possível paralelizar o trabalho por requisição; o tempo de CPU do processamento de logits crescia proporcionalmente ao tamanho do lote, aumentando a latência de cauda
- Mesmo que o forward pass do modelo na GPU fosse processado em lote de forma eficiente, a latência total ficava presa à CPU
- Esse gargalo não aparece em benchmarks de uma única requisição, apenas em níveis reais de concorrência
Processamento por lote no vLLM V1
- O vLLM V1 move o processamento de logits do modo por requisição para o modo por lote
- Processadores personalizados foram reescritos com base em estruturas de dados de lote, calculando juntas as máscaras de várias requisições
- O caminho crítico de desempenho foi reimplementado em C++ multithread para evitar o GIL, mantendo o tempo de processamento de logits constante mesmo quando o tamanho do lote aumenta
- Na API V1, é preciso rastrear explicitamente mudanças nos membros do lote por meio de
update_state(batch_update)- É mais complexo que a interface por requisição do V0
- Mas é necessário para manter corretamente o estado de cada requisição em lotes que mudam dinamicamente
Reforços operacionais para restrições baseadas em estado
- Mesmo após resolver o gargalo de desempenho, surgiram dois problemas em lógicas de decodificação com estado
-
Prefill parcial
- O V1 realiza prefilling em chunks, então o prefill de uma requisição pode se estender por várias etapas da engine
- Apenas o
BatchUpdatenão permite distinguir prefill completo de prefill parcial, então foi adicionado rastreamento interno
-
Preempção(preemption)
- Quando falta memória, o vLLM remove o cache KV de algumas requisições parcialmente concluídas e depois pode reagendá-las com outra lista de prompt e tokens de saída
- Isso quebra a premissa da máquina de estados de que a lista de tokens de saída sempre cresce
- Entre etapas de decodificação, detecta-se se o histórico de tokens encurtou; a máquina de estados é inicializada e reconstruída com o novo prompt
Próximas áreas de investimento
- A plataforma atual mira baixa latência, customização profunda e integração com a infraestrutura existente, oferecendo um caminho de experimentação até produção por meio de vLLM e Triton e APIs consistentes
- Ao compensar version pinning, campos de API omitidos silenciosamente e trade-offs nas opções de empacotamento, a plataforma melhora a estabilidade e a experiência do desenvolvedor
- Quatro melhorias estão planejadas
- Compressão de system prompt para reduzir o tamanho do prompt sem sacrificar qualidade
- Agendamento assíncrono no vLLM V1
- Processadores de logits vetorizados executados em kernels GPU fusionados em vez de código CPU
- Variantes de modelos de baixa precisão para reduzir uso de memória e aumentar throughput
- A Netflix pretende continuar usando bibliotecas open source de ML como Triton, vLLM e PyTorch, além de colaborar com as comunidades relacionadas
Ainda não há comentários.