vLLM vs TGI vs SGLang: Inferência de LLMs em Produção em 2026

vLLM, TGI e SGLang comparados para servir LLMs open source em produção: throughput, KV cache, quantização FP8 e como escolher o servidor certo em 2026.

vLLM vs TGI vs SGLang: Guia 2026

Atualizado em: 2 de setembro de 2026

Em 2026, vLLM, TGI e SGLang são os três servidores de inferência open source dominantes para servir LLMs auto-hospedados em produção. O vLLM ainda lidera em throughput bruto e adoção, o TGI é a escolha mais estável para quem já vive no ecossistema Hugging Face, e o SGLang venceu o benchmark de latência para cargas com prefixos longos e reutilizados. Honestamente, a escolha certa depende menos de "qual é o mais rápido" e mais de qual padrão de tráfego você tem, quanto controle de GPU você aceita ceder e o quão maduro está seu pipeline de observabilidade.

  • vLLM ≥ 0.7 domina em throughput agregado graças ao PagedAttention e ao continuous batching amadurecido; é a escolha padrão para APIs multi-tenant de alto QPS.
  • Text Generation Inference (TGI) 3.x da Hugging Face é o mais fácil de operar quando você já usa o Hub e quer suporte comercial via Inference Endpoints.
  • SGLang 0.4+ ganha em latência para prompts longos e reutilizados (chat com histórico, RAG com system prompt gigante) usando RadixAttention e um scheduler zero-overhead.
  • Continuous batching é hoje o piso, não o diferencial: todos os três suportam. O que ainda diferencia é o KV cache (paginado no vLLM, radix-tree no SGLang ou flat no TGI).
  • Quantização FP8 com Marlin/Machete é o novo default para GPUs H100/H200; AWQ e GPTQ ainda entregam em L40S e A100.
  • Sem métricas de time-to-first-token, inter-token latency e KV cache hit rate você está pilotando às cegas. Isso vale mais do que trocar de framework.

O que é um servidor de inferência de LLM?

Um servidor de inferência de LLM é o processo que recebe requisições HTTP com prompts, mantém o modelo carregado em GPU, agrupa tokens em lotes, gerencia o KV cache e devolve tokens gerados (normalmente via streaming SSE). É a camada entre a sua API pública (ou seu LLM gateway) e o hardware. Se você usa apenas APIs da OpenAI, Anthropic ou Google, não precisa dele: a inferência é responsabilidade delas. No momento em que você decide servir um modelo open source (Llama 4, Qwen3, DeepSeek V3, Mistral Large 2) por questões de custo, latência, dados sensíveis ou fine-tuning proprietário, o servidor de inferência vira o componente mais crítico do stack.

Servir LLM não é como servir um endpoint REST tradicional. O tempo de geração é dominado por duas fases muito diferentes: prefill (processar o prompt inteiro de uma vez, memory-bound e paralelizável) e decode (gerar um token por vez, latency-bound e sequencial). Um bom servidor precisa intercalar requisições nas duas fases sem que uma requisição longa segure as outras. É isso que continuous batching resolve. Ele também precisa reaproveitar o KV cache (a atenção computada para tokens já vistos) entre requisições que compartilham prefixo, senão você paga o prefill duas vezes por chat multi-turn.

Tabela comparativa: vLLM vs TGI vs SGLang

A tabela abaixo compacta o que eu olho antes de escolher. Números de throughput e latência variam com modelo, hardware e workload, então trate como ordem de grandeza, não como benchmark oficial.

Dimensão vLLM 0.7+ TGI 3.x SGLang 0.4+
MantenedorvLLM Project (LF AI)Hugging FaceLMSYS / SGLang team
LicençaApache 2.0Apache 2.0 (uso comercial permitido desde v3)Apache 2.0
KV cachePagedAttention (blocos)Flat + prefix cachingRadixAttention (árvore radix)
Throughput agregadoAlto (melhor referência)AltoAlto (vence quando há reuso de prefixo)
TTFT (time-to-first-token)MédioMédioBaixo em chats/RAG com system prompt longo
Speculative decodingSim (Medusa, EAGLE, n-gram)Sim (Medusa, draft model)Sim (EAGLE-2, EAGLE-3)
QuantizaçãoFP8, AWQ, GPTQ, INT8, Marlin/MacheteFP8, AWQ, GPTQ, bitsandbytes, EETQFP8, AWQ, GPTQ, BlockFP8
API OpenAI-compatívelNativaNativa (Messages API)Nativa
Suporte multimodalAmplo (Llama Vision, Qwen-VL, Pixtral)AmploBom (Qwen-VL, LLaVA)
Facilidade de operarMédia (muitos knobs)Alta (Docker "just works")Média (CLI direto, docs menores)
Melhor caso de usoAPI multi-tenant de alto QPSDeploy simples, integração com HF HubChat/RAG com prefixos longos reutilizados

vLLM: PagedAttention e o padrão de fato

O vLLM nasceu em Berkeley em 2023 com o paper de PagedAttention e virou rapidamente o padrão de facto para servir LLMs open source. A ideia central: em vez de reservar KV cache contíguo por requisição (o que gera fragmentação brutal), o vLLM aloca o cache em blocos de tamanho fixo, como páginas de memória virtual, e mapeia blocos lógicos para blocos físicos via tabela de páginas. Isso permite compartilhar prefixos entre requisições, sobrescrever slots livres e aproveitar até 96% da VRAM disponível.

Em 2026, o vLLM 0.7 é maduro: suporte a Llama 4, DeepSeek V3, Qwen3, tensor parallelism e pipeline parallelism nativos, chunked prefill (que impede que um prompt de 100k tokens congele o decode das outras requisições) e speculative decoding com EAGLE. A API é OpenAI-compatível out of the box, o que significa que qualquer cliente que fala com api.openai.com fala com o seu vLLM trocando apenas base_url.

Subir uma instância em uma H100 é dois comandos:

# requer CUDA 12.4+, Python 3.11
pip install "vllm>=0.7.0"

vllm serve meta-llama/Llama-3.3-70B-Instruct \
    --tensor-parallel-size 2 \
    --max-model-len 32768 \
    --gpu-memory-utilization 0.92 \
    --enable-prefix-caching \
    --enable-chunked-prefill \
    --quantization fp8 \
    --port 8000

E consumir do lado do cliente é literalmente o SDK da OpenAI apontando para o seu host:

from openai import OpenAI

client = OpenAI(
    base_url="http://vllm-prod.internal:8000/v1",
    api_key="sk-nao-importa-vllm-nao-valida",
)

resp = client.chat.completions.create(
    model="meta-llama/Llama-3.3-70B-Instruct",
    messages=[{"role": "user", "content": "Resuma o RFC 9110 em 3 linhas."}],
    stream=True,
    max_tokens=256,
)

for chunk in resp:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

Onde o vLLM ainda dói: são flags demais, e uma configuração ruim de --max-num-seqs, --max-num-batched-tokens ou --gpu-memory-utilization transforma um servidor rápido em uma máquina de OOM. Eu já reiniciei pods vLLM em produção às 3h da manhã porque um prompt de 128k tokens estourou o KV cache. Desde então, rodo sempre com chunked prefill ativo e --max-model-len conservador.

Text Generation Inference (TGI): o caminho Hugging Face

O TGI é o servidor oficial da Hugging Face, escrito em Rust (o router) e Python (o worker). Foi a primeira solução realmente polida para servir LLMs em produção, e a própria Hugging Face usa em escala nos Inference Endpoints. Na versão 3, o TGI passou a Apache 2.0 sem restrições comerciais (a v2 tinha licença HFOIL que assustou muita gente), adicionou prefix caching, e ficou competitivo em throughput com o vLLM na maioria dos benchmarks que rodei.

A grande vantagem do TGI é a operação. O container oficial ghcr.io/huggingface/text-generation-inference:3.0 resolve dependências CUDA, faz download do modelo do Hub com autenticação transparente, e expõe endpoints Prometheus prontos. Se você já tem uma pipeline que usa o Hub para versionar modelos fine-tuned, o TGI é a via de menor atrito.

# docker-compose.yml
services:
  tgi:
    image: ghcr.io/huggingface/text-generation-inference:3.0
    ports: ["8080:80"]
    volumes:
      - ./hf-cache:/data
    environment:
      HF_TOKEN: ${HF_TOKEN}
      MODEL_ID: meta-llama/Llama-3.3-70B-Instruct
      NUM_SHARD: "2"
      MAX_INPUT_TOKENS: "16384"
      MAX_TOTAL_TOKENS: "32768"
      QUANTIZE: fp8
      USE_PREFIX_CACHING: "true"
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 2
              capabilities: [gpu]

Onde o TGI perde: o suporte a modelos novos costuma chegar dias ou semanas depois do vLLM. Se você precisa servir o modelo que acabou de sair no arxiv ontem, vLLM ou SGLang geralmente estão prontos primeiro. E a API OpenAI-compatível existe (endpoint /v1/chat/completions), mas foi adicionada depois do endpoint nativo /generate, então alguns clientes antigos ainda tropeçam.

SGLang: RadixAttention e o novato ambicioso

O SGLang é o mais novo dos três em maturidade de produção, mas venceu de forma clara em uma categoria: workloads com reuso alto de prefixo. Chats multi-turn, RAG com system prompts longos, agentes que reusam few-shot examples. Qualquer caso onde o mesmo prefixo aparece em muitas requisições, o SGLang faz voar. O truque é a RadixAttention: em vez de gerenciar KV cache em blocos independentes, o SGLang organiza todos os prefixos ativos numa árvore radix, e cada requisição nova "encaixa" no galho existente, reusando o cache computado sem precisar de match exato de prefixo.

Na prática, isso significa hit rates de KV cache de 60–90% em cargas de chat, contra 20–40% em prefix caching baseado em hash. No meu último projeto (um agente de suporte com system prompt de 6k tokens em toda chamada), vi TTFT cair de 800ms para 90ms trocando vLLM por SGLang. Ganho absurdo, com literalmente uma flag.

pip install "sglang[all]>=0.4.0"

python -m sglang.launch_server \
    --model-path meta-llama/Llama-3.3-70B-Instruct \
    --tp 2 \
    --context-length 32768 \
    --mem-fraction-static 0.88 \
    --enable-torch-compile \
    --quantization fp8 \
    --host 0.0.0.0 \
    --port 30000

Além do servidor, o SGLang expõe uma DSL para programas estruturados de LLM (constrained decoding, forks paralelos, tool use) que compete com Outlines e Guidance. Não uso a DSL em produção (prefiro manter a lógica do lado do cliente com structured outputs), mas para pipelines de avaliação e prototipagem ela é bastante elegante.

O ponto fraco: documentação e ferramental de operação são menos maduros. Menos exemplos de Helm charts, menos posts de troubleshooting, comunidade menor no Slack. Se algo quebra às 2h da manhã, você vai ler código-fonte antes de encontrar uma Stack Overflow que resolva.

Continuous batching, KV cache e o que realmente importa

Muita gente escolhe framework olhando primeiro para throughput. Em 2026, isso é o critério errado, porque os três suportam continuous batching (também chamado de iteration-level scheduling). Nenhum deles paga o preço horrível do static batching que dominava até 2023. A pergunta certa é: qual estratégia de KV cache combina com o meu padrão de tráfego?

Continuous batching em uma frase

Cada iteração do decode (a geração de um token) é um step. Em cada step, o scheduler decide qual conjunto de requisições ativas participa. Requisições que terminaram saem do batch imediatamente e liberam slot para novas. O resultado é que GPUs ficam saturadas mesmo quando as requisições têm tamanhos muito diferentes, e a latência de uma request nova é dominada pelo prefill dela, não pela request mais longa que ainda está no batch.

Estratégias de KV cache que diferenciam

  • Flat cache (TGI antigo): um buffer por requisição, contíguo. Simples, mas fragmenta mal e não compartilha prefixo. Superado.
  • Paged (vLLM): blocos de tamanho fixo (16 tokens é o default), tabela de páginas. Compartilha prefixo via copy-on-write; suporta chats longos sem fragmentar; padrão da indústria.
  • Radix tree (SGLang): uma árvore global de prefixos ativos. Match por qualquer profundidade, não só exato. Ganha em chat/RAG; overhead maior em cargas 100% únicas.

Prefix caching não é bala de prata

Prefix caching só ajuda quando há reuso real. Um endpoint que serve prompts totalmente únicos (transcrição, tradução one-shot, sumarização de documentos diferentes) não se beneficia; pelo contrário, paga overhead de bookkeeping. Meça kv_cache_hit_rate antes de otimizar. Se está abaixo de 15%, foca em batching e quantização, não em cache tree.

Como escolher entre vLLM, TGI e SGLang?

Depois de operar os três em produção, essa é a árvore de decisão que eu uso hoje:

  1. Você precisa suporte comercial e SLA? Vá de TGI + Hugging Face Inference Endpoints, ou de vLLM via um provider gerenciado (Anyscale, Together, Fireworks, que rodam vLLM ou fork dele por baixo).
  2. Seu workload é chat com system prompt grande, RAG, ou agentes com few-shot longo? Comece por SGLang. O ganho de TTFT costuma justificar a curva de aprendizado.
  3. Você precisa do modelo que saiu ontem? vLLM ou SGLang costumam ter suporte primeiro.
  4. Você quer o menor número de knobs para configurar? TGI. O default funciona, e os overrides são via env vars simples.
  5. API multi-tenant de alto QPS com prompts variados? vLLM. É o mais testado nesse regime, e a maioria dos providers públicos roda ele.
  6. Você já tem observabilidade OTel/Prometheus? TGI e vLLM expõem métricas prontas; SGLang requer scraping manual ou middleware customizado.

Quantização, tensor parallelism e escala horizontal

Servir um modelo de 70B em FP16 exige ~140 GB de VRAM. Uma H100 80GB sozinha não chega, então você precisa de tensor parallelism em 2 GPUs, ou de quantização, ou dos dois. Em 2026, a matriz de escolhas para escalar é razoavelmente clara.

Quantização: qual formato usar

  • FP8 (E4M3): padrão em Hopper (H100/H200) e Ada (L40S/L4). Perda de qualidade < 0.5% em benchmarks, throughput 1.6–2x vs FP16. Suportado nativamente por vLLM, TGI e SGLang via kernels Marlin/Machete. É o meu default para GPUs H100+.
  • AWQ: quantização de pesos para INT4, ativações em FP16. Reduz VRAM por ~4x, boa qualidade, roda em qualquer GPU. Uso em A100 e L40S quando VRAM aperta.
  • GPTQ: similar ao AWQ; a diferença é o método de calibração. AWQ costuma sair na frente em modelos de instrução.
  • INT8/bitsandbytes: conveniente, mas mais lento que AWQ em serving. Uso só em fine-tuning.

Tensor parallelism vs replicação

Regra de bolso: tensor parallelism (TP) divide o modelo entre GPUs do mesmo nó via NVLink; funciona bem em TP=2 e TP=4, degrada em TP=8+ por overhead de all-reduce. Para escalar horizontalmente, replique instâncias inteiras atrás de um load balancer L7 (Envoy, HAProxy, ou o gateway do seu cloud). Pipeline parallelism só entra em cena quando o modelo não cabe nem num nó DGX inteiro. Em 2026, isso é DeepSeek V3 671B ou Llama 4 400B em FP16, cenários raros.

# exemplo prático: 4 réplicas de Llama 3.3 70B FP8 em H100
# cada réplica: 2 GPUs (TP=2), 1 pod

# k8s hpa scaling on tokens/s
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: vllm-llama33
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-llama33
  minReplicas: 2
  maxReplicas: 12
  metrics:
    - type: Pods
      pods:
        metric:
          name: vllm_num_requests_waiting
        target:
          type: AverageValue
          averageValue: "8"

Métricas e o dashboard que você vai desejar ter construído primeiro

Se eu pudesse voltar no tempo e falar com o eu de 2023, seria isso: configure a observabilidade antes de escolher framework. Trocar entre vLLM, TGI e SGLang é uma tarde de trabalho quando você tem um dashboard confiável. Sem ele, é semanas de debate baseado em folclore. Eu aprendi isso da forma dolorosa.

As métricas que importam

  • TTFT (time-to-first-token) p50/p95/p99: a métrica que o usuário sente. Se subiu, algo mudou no prefill (prompt maior, cache miss, GPU quente).
  • ITL (inter-token latency) p50/p99: latência entre tokens durante geração. Se subiu, o batch está cheio demais.
  • Throughput (tokens/s output): tokens gerados por segundo agregado. Correlacione com utilização de GPU.
  • KV cache utilization e hit rate: quanto do cache está em uso e quanto está sendo reaproveitado. Baixo hit rate + alta utilização = tempo de aumentar VRAM ou reduzir max-model-len.
  • Requests waiting / batch fill ratio: se há fila persistente, você está no limite. Escale ou reduza max tokens.
  • GPU SM utilization e memory bandwidth: se SM está baixa mas memory bandwidth está alta, você está memory-bound (normal em decode). Se SM está baixa e memory também, o scheduler está deixando GPU idle.

vLLM e TGI expõem tudo isso em /metrics no formato Prometheus. SGLang expõe menos out of the box, mas o time está fechando o gap. Casado com um sistema de observabilidade de LLM como Langfuse ou Helicone no nível de aplicação, você tem visibilidade end-to-end: gateway → servidor de inferência → traços de conversação.

O runbook mínimo

Documente três cenários antes de ir para produção: (1) o que fazer se TTFT p99 dobrar, (2) o que fazer se OOM crash em loop, (3) como fazer rollback do modelo se qualidade cair. Sem esses três playbooks escritos, seu on-call vai improvisar às 3h da manhã e você vai aprender do jeito difícil (eu falo por experiência própria).

Perguntas frequentes

Qual é a diferença principal entre vLLM e TGI?

O vLLM foi construído em torno de PagedAttention e tende a ter suporte a novos modelos primeiro; o TGI vem da Hugging Face, é mais fácil de operar via Docker e integra melhor com o Hub. Em throughput bruto os dois se equivalem em 2026, então a escolha é mais sobre ecossistema e velocidade de suporte a modelos novos do que performance.

SGLang é realmente mais rápido que vLLM?

Depende do workload. Em cargas com alto reuso de prefixo (chats multi-turn, RAG com system prompt longo, agentes com few-shot), o SGLang tem TTFT significativamente menor graças ao RadixAttention. Em cargas com prompts únicos (sumarização, tradução one-shot), o vLLM iguala ou supera.

Preciso de continuous batching se meu tráfego é baixo?

Sim, e ele já vem ligado por padrão nos três frameworks. Mesmo com tráfego baixo, continuous batching reduz cauda de latência quando duas requisições chegam quase juntas. Você só sentiria diferença desligando em cenários single-user offline.

Quanto de GPU preciso para servir Llama 3.3 70B?

Em FP16 puro, precisa de ~140 GB de VRAM, o que dá 2x H100 80GB com tensor parallelism. Com quantização FP8 numa H100/H200, cabe em uma GPU só com folga para KV cache razoável. Com AWQ INT4, roda até em uma A100 80GB.

É seguro usar quantização FP8 em produção?

Sim, para a maioria dos casos de uso. FP8 (formato E4M3) mantém qualidade dentro de 0.5% do FP16 em benchmarks padrão como MMLU e HumanEval. Sempre valide no seu próprio conjunto de avaliação antes de trocar, porque modelos fine-tuned às vezes são mais sensíveis.

Auto-hospedar LLM é mais barato do que usar API paga?

Só a partir de volumes altos e sustentados. Como regra grosseira: acima de ~500M tokens/dia com utilização média de GPU acima de 60%, auto-hospedagem vence em custo. Abaixo disso, o custo de GPU ociosa, on-call e operação supera a economia por token. Compliance e latência podem justificar mesmo sem vantagem de custo.

Cara Donovan
Sobre o Autor Cara Donovan

AI operations lead at a B2B SaaS. Builds the unglamorous infrastructure that keeps prod LLM apps from melting.