Benchmark de inferência numa GPU RTX 4090 exibido num terminal com métricas de desempenho

Ollama vs vLLM vs TGI numa RTX 4090: o que mostram os benchmarks

Ollama, vLLM e Hugging Face TGI com um modelo 8B numa RTX 4090: throughput sob carga com fontes, VRAM, quantização, APIs compatíveis com a OpenAI e o status de manutenção do TGI.

Numa única RTX 4090 servindo um modelo de 7B–8B, o Ollama e o vLLM rodam mais ou menos na mesma velocidade com uma requisição por vez. A diferença aparece quando muitas requisições chegam juntas: num teste publicado em setembro de 2026, com 64 requisições simultâneas, o vLLM entregou cerca de três vezes o throughput total do Ollama. O Hugging Face TGI ainda funciona, mas está em modo de manutenção desde que o repositório foi arquivado em março de 2026, e a própria Hugging Face agora indica o vLLM e o SGLang.

Então a escolha depende de quantas pessoas batem no modelo ao mesmo tempo. Um usuário, um script ou uma ferramenta interna pequena: Ollama, porque dá menos trabalho. Uma API pública ou jobs em lote com muitas requisições em andamento: vLLM. Um deploy novo em TGI: eu não começaria um.

De onde vêm os números

Uma versão anterior desta página mostrava números de throughput, latência e VRAM apresentados como medições nossas numa RTX 4090. Não conseguimos rastreá-los até uma execução reproduzível nem até uma fonte publicada, então os removemos. Um motivo para desconfiar: os números antigos de fluxo único em FP16 passavam do que a largura de banda de memória de uma RTX 4090 permite (veja a próxima seção).

Todo número abaixo agora é atribuído a quem o publicou, com o hardware e o modelo usados. Onde ninguém publicou uma comparação limpa na RTX 4090 (o TGI, por exemplo), eu digo isso em vez de preencher a lacuna.

As fontes principais:

  • ComputingForGeeks, 18 de setembro de 2026. Ollama, vLLM e llama.cpp numa RTX 4090, numa L40S e numa RTX 5090. Modelo: Qwen2.5-7B-Instruct, AWQ em 4 bits no vLLM e GGUF Q4_K_M no Ollama e no llama.cpp. Prompt fixo de 512 tokens, temperatura 0, até 256 tokens de saída, contexto de 4.096 tokens por slot, 64 slots paralelos.
  • Red Hat Developer, 8 de agosto de 2025. Ollama 0.9.2 vs vLLM 0.9.1 numa A100 40 GB, Llama 3.1 8B Instruct em FP16, de 1 a 256 usuários simultâneos, medido com GuideLLM.
  • BentoML, 5 de junho de 2024. vLLM 0.4.2, TGI 2.0.4 e outros numa A100 80 GB com Llama 3 8B Instruct.
  • Placar CUDA do llama.cpp. Velocidade de fluxo único do Llama 2 7B Q4_0 em muitas placas, incluindo a RTX 4090.

Só a primeira foi feita numa RTX 4090 com todos os motores deste post, menos o TGI. As outras mostram o mesmo padrão em placas de data center.

Uma requisição: a placa define o teto

Quando uma GPU gera tokens para uma única requisição, ela precisa ler da memória todos os pesos do modelo a cada token. Por isso quem define o limite é a largura de banda da memória, não o motor.

A RTX 4090 tem 24 GB de GDDR6X a 1.008 GB/s. O Llama 3.1 8B tem 8,03 bilhões de parâmetros.

  • Em FP16, isso dá 8,03 × 2 bytes ≈ 16,1 GB de pesos. 1.008 ÷ 16,1 ≈ 63 tokens por segundo, no máximo, para uma requisição.
  • A tag padrão llama3.1:8b do Ollama é Q4_K_M, um download de 4,9 GB. 1.008 ÷ 4,9 ≈ 205 tokens por segundo, no máximo.

Os motores reais ficam abaixo desses tetos. O placar do llama.cpp mostra uma RTX 4090 gerando 186 tokens por segundo com o Llama 2 7B em Q4_0 (189 com flash attention). O ComputingForGeeks mediu cerca de 174 tokens por segundo com uma única requisição no Qwen2.5-7B em 4 bits, e achou vLLM, llama.cpp e Ollama “praticamente” iguais na 4090. (Na L40S e na RTX 5090, a versão do Ollama que eles usaram decodificava a cerca de metade da velocidade do llama.cpp, então confira a sua placa e a sua versão.)

Para um usuário por vez, escolha o motor pela conveniência e a quantização pela velocidade. Passar de FP16 para 4 bits mais ou menos triplica o teto. Trocar de motor quase não mexe nele.

Muitas requisições: o batching decide

Com muitas requisições em andamento, a GPU pode ler os pesos uma vez e usá-los para um lote inteiro de requisições. Agora o que importa é o quanto o motor sabe montar esses lotes e como ele gerencia o KV cache (a memória de cada requisição com a conversa até ali).

Gráfico de barras do throughput total numa RTX 4090 com 64 requisições simultâneas: vLLM 6.623, llama.cpp 2.391, Ollama 2.018 tokens por segundo vLLM (AWQ) 6.623 llama.cpp 2.391 Ollama 2.018 0 2.000 4.000 6.000 Tokens de saída por segundo no total, 64 requisições simultâneas Uma requisição por vez: cerca de 174 tokens por segundo nos três
RTX 4090, Qwen2.5-7B-Instruct em 4 bits (AWQ no vLLM, GGUF Q4_K_M nos outros), 64 requisições simultâneas. Números do ComputingForGeeks, setembro de 2026; barras em escala. O TGI não fez parte deste teste.

Na RTX 4090, o vLLM serviu 6.623 tokens por segundo no total com 64 requisições, o servidor do llama.cpp 2.391 e o Ollama 2.018. O Ollama foi configurado de forma justa para o teste: OLLAMA_NUM_PARALLEL=64, num_ctx 4096 e flash attention ligado. O vLLM rodou com --quantization awq_marlin --max-model-len 4096 --gpu-memory-utilization 0.90. Os autores também relataram tempo até o primeiro token de cerca de 8 a 12 ms no llama.cpp e de 16 a 25 ms no vLLM, com o Ollama mais alto na L40S e na RTX 5090.

O teste da Red Hat numa A100 aponta na mesma direção com pesos em FP16. O vLLM chegou a um pico de 793 tokens por segundo; o Ollama, com as configurações padrão, fez 41. Depois de aumentar o limite de paralelismo do Ollama para 32, “o maior valor estável”, ele ainda não alcançou o vLLM em nenhum nível de concorrência. O tempo até o primeiro token “subiu drasticamente com mais usuários”, e a latência entre tokens teve “picos enormes” na carga máxima.

Dois cuidados antes de citar isso para alguém. Primeiro, a comparação do ComputingForGeeks não é perfeitamente equivalente: o vLLM rodou pesos AWQ, os outros GGUF, e as versões são diferentes. Segundo, esses são totais somando todas as requisições. Cada um dos 64 usuários vê cerca de 6.623 ÷ 64 ≈ 103 tokens por segundo no vLLM, o que ainda é bem utilizável, e cerca de 2.018 ÷ 64 ≈ 32 no Ollama.

Onde está o TGI

O Text Generation Inference era o servidor de produção da Hugging Face, com continuous batching, Flash Attention e Paged Attention, paralelismo de tensores, métricas do Prometheus e tracing com OpenTelemetry. Tecnicamente, estava na mesma categoria do vLLM.

O status mudou. A documentação do TGI agora abre com: “o text-generation-inference agora está em modo de manutenção. Daqui em diante, vamos aceitar pull requests de pequenas correções de bugs, melhorias na documentação e tarefas leves de manutenção.” Ela recomenda “vllm, SGLang, além de motores locais com intercompatibilidade, como llama.cpp ou MLX.” O repositório no GitHub foi arquivado e passou a ser somente leitura em 21 de março de 2026.

Não encontrei nenhum benchmark recente publicado do TGI numa RTX 4090. A comparação séria mais próxima é a da BentoML numa A100 80 GB, de junho de 2024: com o Llama 3 8B, o vLLM chegou a “2300-2500 tokens por segundo, parecido com o TGI”, e teve o melhor tempo até o primeiro token em todos os níveis de concorrência testados. Isso foi há dois anos e muitas versões dos dois motores, então trate como história.

Se o TGI já roda o seu tráfego de produção, ele vai continuar funcionando. Num deploy novo, você estaria escolhendo um servidor que não vai receber novas arquiteturas de modelo nem trabalho de desempenho. Numa RTX 4090, o vLLM cobre tudo o que o TGI fazia.

VRAM numa placa de 24 GB

Os motores tratam a memória de formas muito diferentes, e isso afeta o que mais pode dividir a placa.

O vLLM pega a maior parte da placa logo de cara. O padrão de --gpu-memory-utilization é 0.9, então numa RTX 4090 de 24 GB ele reserva cerca de 21,6 GB na inicialização, qualquer que seja o tamanho do modelo. Tudo o que os pesos não usam vira KV cache. Com o Llama 3.1 8B em FP16 (cerca de 16,1 GB), sobram uns 5,5 GB para KV cache, ativações e CUDA graphs, o que limita o tamanho do contexto e quantas requisições cabem ao mesmo tempo. Com pesos AWQ em 4 bits (a versão do ComputingForGeeks tinha cerca de 5,6 GB), a maior parte dos 21,6 GB vai para o KV cache, e é assim que ele mantém 64 requisições rodando. Não conte com rodar um segundo programa de GPU ao lado dele, a não ser que você baixe essa fração.

O Ollama aloca por modelo e por contexto. Um modelo llama3.1:8b Q4_K_M tem 4,9 GB, mais o KV cache da janela de contexto. O Ollama escolhe o contexto padrão pela sua VRAM: 4k abaixo de 24 GiB, 32k de 24 a 48 GiB, 256k a partir de 48 GiB. Uma RTX 4090 fica exatamente na linha dos 24 GiB (o nvidia-smi informa um pouco menos que 24 GiB), então rode ollama ps para ver qual contexto você recebeu de fato, ou defina você mesmo. Os slots paralelos multiplicam isso: o exemplo da documentação é que “um contexto de 2K com 4 requisições paralelas resulta num contexto de 8K e em alocação adicional de memória”. Se a memória está apertada, quantizar o KV cache ajuda: q8_0 usa cerca de metade da memória do f16 padrão, e q4_0 cerca de um quarto. O Ollama também consegue manter até três modelos carregados por GPU por padrão, se couberem, o que serve bem para uma placa que alterna entre modelos. Para saber quais modelos cabem em placas de 8, 12, 16 e 24 GB, veja quais modelos de IA cabem na VRAM da sua GPU.

O TGI também pré-aloca memória para o continuous batching, como o vLLM. Não encontrei um número atual e citável de VRAM para um modelo 8B numa 4090, então não vou dar um.

Quantização e formatos de modelo

OllamavLLMTGI
Formato principalGGUF (ex.: Q4_K_M)Safetensors da Hugging FaceSafetensors da Hugging Face
Opções de 4 bitsVariantes GGUF Q4AWQ, GPTQ, bitsandbytes, INT4 W4A16AWQ, GPTQ, Marlin, EXL2, bitsandbytes NF4/FP4
8 bits / FP8GGUF Q8_0FP8 W8A8 em Ada (RTX 4090) e Hopper; INT8bitsandbytes 8 bits, EETQ, fp8
GGUFNativoSuportadoNão listado
Quantização do KV cacheq8_0, q4_0SimNão abordado aqui

A RTX 4090 é uma placa Ada (SM 8.9), então o caminho FP8 do vLLM funciona nela. Pesos em FP8 ocupam metade da memória do FP16: cerca de 8 GB para um modelo 8B, um meio-termo entre FP16 e 4 bits numa única 4090.

A biblioteca de modelos do Ollama já vem com tags GGUF pré-quantizadas, então você quase nunca pensa nisso: ollama pull llama3.1:8b traz o Q4_K_M. No vLLM, você escolhe um checkpoint pré-quantizado na Hugging Face ou passa você mesmo uma flag de quantização.

Servidores compatíveis com a OpenAI e instalação

Os três oferecem uma API HTTP no estilo da OpenAI, então os SDKs da OpenAI e a maioria das ferramentas de chat funcionam trocando a URL base.

OllamavLLMTGI
Endereço padrãolocalhost:11434/v1localhost:8000/v1Porta 80 do contêiner (muitas vezes mapeada para 8080)
Chat completionsSimSimSim (Messages API, desde a 1.4.0)
Outros endpoints da OpenAIcompletions, models, embeddings, responsescompletions, embeddings, responses, audioNão abordado aqui
InstalaçãoUm scriptPacote pipImagem Docker

Para colocar um modelo 8B no ar, segundo a documentação de cada projeto:

# Ollama
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.1:8b

# vLLM (Llama 3.1 is gated: accept the license on Hugging Face and set HF_TOKEN)
pip install vllm
vllm serve meta-llama/Llama-3.1-8B-Instruct

# TGI
docker run --gpus all --shm-size 1g -p 8080:80 -v $PWD/data:/data \
  ghcr.io/huggingface/text-generation-inference:3.3.5 \
  --model-id meta-llama/Llama-3.1-8B-Instruct

O Ollama é, de longe, o que dá menos trabalho. Ele cuida dos downloads, dos arquivos quantizados, de carregar e descarregar modelos, e funciona igual num notebook e num servidor alugado. A camada OpenAI do Ollama tem lacunas: não há logprobs nem tool_choice em chat completions, e as imagens precisam ir em base64, não como URL. O vLLM exige um ambiente CUDA e Python funcionando e mais flags para ajustar, mas é o motor que a Hugging Face agora recomenda no lugar do TGI. O TGI é fácil se você já usa Docker, com a ressalva sobre manutenção acima.

Qual motor para qual trabalho

Ollama para uma pessoa, um script, um assistente de programação, uma ferramenta interna com poucos usuários ou uma máquina que alterna entre vários modelos. A instalação leva minutos, e a velocidade com uma requisição numa 4090 é tão boa quanto a de qualquer outro.

vLLM quando muitas requisições chegam ao mesmo tempo: uma API pública, um produto de chat multiusuário ou jobs em lote que você pode rodar 32 ou 64 de cada vez. Os números publicados mostram cerca de três vezes o throughput total do Ollama numa RTX 4090 com 64 requisições simultâneas, e muito mais numa A100. Ele também tem o suporte mais amplo a quantização e a APIs.

TGI só se você já usa. Para trabalho novo, a recomendação da própria Hugging Face é vLLM ou SGLang.

Quando você aluga por hora, o custo sai do throughput. Pense em um milhão de tokens de saída numa RTX 4090 a US$ 0,31 por hora, o menor preço sob demanda do Vast.ai listado pelo getdeploying.com em setembro de 2026, usando os números do ComputingForGeeks:

  • Uma requisição por vez, 174 tokens/s: 1.000.000 ÷ 174 ≈ 5.750 s ≈ 1,6 hora ≈ US$ 0,50.
  • 64 simultâneas no Ollama, 2.018 tokens/s: ≈ 496 s ≈ US$ 0,04.
  • 64 simultâneas no vLLM, 6.623 tokens/s: ≈ 151 s ≈ US$ 0,01.

Essas contas supõem a GPU ocupada o tempo todo. Se você nunca tem mais de uma requisição em andamento, o batching não traz nada e a escolha do motor não muda a sua conta. Se você tem uma fila de trabalho, ela muda a conta em uma ordem de grandeza. A mesma lógica, comparada com APIs cobradas por token, está em GPU por hora ou API por token.

Onde o GPUFlow entra

O instalador de provedor do GPUFlow configura o Ollama por padrão e o agente do GPUFlow encaminha as requisições para ele, então a coluna do Ollama acima costuma ser a que vale lá. Você aluga uma chave de API compatível com a OpenAI (https://gpuflow.app/v1, com /v1/chat/completions e /v1/models, com suporte a streaming) para um modelo na GPU do provedor. Você paga por tempo, por segundo com mínimo de 1 minuto, não por token.

O que você não pode fazer no GPUFlow: escolher o motor, mudar as configurações dele ou rodar o seu próprio código. Não há SSH nem shell. Para reproduzir os benchmarks acima ou rodar o vLLM por conta própria, alugue uma máquina em que você possa entrar, no Vast.ai ou no RunPod (como os dois se comparam). Para usar um modelo servido pelo Ollama a partir de um app, sem instalar nada, veja o marketplace do GPUFlow e como usar a chave nas ferramentas mais comuns.

Se você fez fine-tuning do seu próprio modelo e está decidindo como servi-lo, o guia de fine-tuning de LLM privado cobre a etapa anterior a esta.

Fontes

Tudo verificado em setembro de 2026.

Perguntas frequentes

O vLLM é mais rápido que o Ollama numa RTX 4090?

Só quando muitas requisições rodam ao mesmo tempo. Num teste de setembro de 2026 do ComputingForGeeks com Qwen2.5-7B em 4 bits, os dois geraram cerca de 174 tokens por segundo com uma única requisição numa RTX 4090. Com 64 requisições simultâneas, o vLLM chegou a 6.623 tokens por segundo no total e o Ollama a 2.018.

O Hugging Face TGI ainda recebe manutenção?

Só o mínimo. A documentação do TGI diz que ele está em modo de manutenção e só aceita pequenas correções de bugs e mudanças na documentação, e o repositório no GitHub foi arquivado como somente leitura em 21 de março de 2026. A Hugging Face recomenda vLLM ou SGLang no lugar dele, ou llama.cpp e MLX para uso local.

Quanta VRAM o vLLM usa com um modelo 8B?

Por padrão, o vLLM reserva 90% da memória da GPU (gpu-memory-utilization 0.9), cerca de 21,6 GB numa RTX 4090 de 24 GB, qualquer que seja o tamanho do modelo. O que os pesos não usam vira KV cache para requisições simultâneas.

O Ollama consegue atender vários usuários ao mesmo tempo?

Consegue, mas o padrão é uma requisição por vez por modelo (OLLAMA_NUM_PARALLEL=1). Dá para aumentar, e cada slot paralelo acrescenta a sua própria memória de contexto. Os benchmarks publicados mostram o Ollama escalando pior que o vLLM com muita concorrência.

Ollama, vLLM e TGI têm APIs compatíveis com a OpenAI?

Têm. Os três servem /v1/chat/completions. O Ollama e o vLLM também servem completions, embeddings e a Responses API; a Messages API do TGI, compatível com a OpenAI, existe desde a versão 1.4.0.

Dá para rodar o Llama 3.1 8B em FP16 numa GPU de 24 GB?

Dá. 8,03 bilhões de parâmetros a 2 bytes cada são cerca de 16,1 GB de pesos, o que cabe em 24 GB com espaço para um KV cache modesto. A maioria das pessoas que servem modelos numa única placa de consumo usa pesos de 4 ou 8 bits para sobrar mais espaço para contexto e usuários simultâneos.