# vLLM em uma GPU só: quantos usuários cabem

> Published 2026-10-17T01:32:10.966Z on https://www.crazystack.com.br/pt/p/vllm-em-uma-gpu-so-quantos-usuarios-cabem/
> Source video: https://www.youtube.com/watch?v=MDG372ImRgM

Rodar vLLM em uma GPU só para trinta pessoas funciona, mas não pelo motivo que a maioria imagina. O agendador do vLLM dá conta de distribuir o trabalho entre pedidos simultâneos. O que trava o servidor é a memória ocupada pelo histórico das conversas, e uma medida real mostra o tamanho do problema: 57 KB de cache KV por token no Qwen2.5-7B.

## O que limita quantos usuários cabem com vLLM em uma GPU só

O tempo de resposta raramente estoura por falta de capacidade de cálculo. Ao rodar [vLLM](https://github.com/vllm-project/vllm) em uma GPU só, o recurso que acaba primeiro é a memória do cache KV, que guarda as chaves e valores de cada token já processado. A documentação do projeto descreve a inferência como limitada por entrada e saída de memória, não por matemática.

Durante o decode, a GPU gera um token por passo e cada passo novo depende de todo o histórico anterior. Para não reprocessar o passado a cada passo, o modelo mantém o cache KV, que cresce junto com a conversa. Enquanto só uma pessoa usa o modelo, boa parte dos núcleos de cálculo fica ociosa esperando dados chegarem da memória.

Quando o time inteiro entra, é essa folga que o agendador ocupa. Um único passo do modelo pode gerar o próximo token de todos os pedidos ativos ao mesmo tempo. O ganho de vazão é real, mas ele não cria memória nova. O espaço disponível para cache continua sendo o mesmo.

Por isso, a pergunta certa não é quantas pessoas estão online. É quantas conversas longas ficam ativas ao mesmo tempo. Um colega que manda três mensagens por dia em um tópico de quarenta turnos pesa mais do que cinco pessoas mantendo conversas curtas.

## Prefill e decode: TTFT e ITL medem coisas diferentes

O tempo de espera de cada pessoa se divide em duas métricas distintas. O TTFT (time to first token) mede quanto tempo o usuário encara a caixa vazia até a primeira palavra aparecer. O ITL (inter-token latency) mede o intervalo entre um token e o próximo, ou seja, a velocidade de digitação do modelo.

Prefill é o trabalho de ler o prompt inteiro antes de gerar qualquer coisa. Essa etapa é intensiva em cálculo, e é o que define o TTFT. Decode é o loop que gera um token por passo, intensivo em memória, e é o que define o ITL. As duas fases competem pelo mesmo hardware.

Essa distinção importa no diagnóstico. Se o problema for a primeira palavra demorando demais, você está olhando para prefill e para o orçamento de tokens do passo. Se as respostas saem picadas ou param no meio, o problema costuma ser memória e preempção.

Para uma ferramenta interna de escritório, um ITL estável tende a importar mais do que um TTFT baixo. Ninguém abandona a ferramenta porque a primeira palavra levou dois segundos. As pessoas reclamam quando o texto trava no meio da frase.

## Continuous batching e chunked prefill: o que o agendador faz

O [batching contínuo do vLLM](https://docs.vllm.ai/en/latest/) decide a cada passo quem entra no lote, em vez de travar o grupo até todos terminarem. A ideia vem do artigo Orca, apresentado na USENIX OSDI 2022, que propôs agendamento no nível de iterações. Cada resposta concluída libera o assento imediatamente para quem está na fila.

No batching estático, seis pedidos entram juntos e ninguém novo entra até os seis terminarem. Se uma pergunta exige uma linha e outra exige um plano de projeto inteiro, o espaço fica vazio enquanto a GPU termina o pedido longo. O vLLM evita esse desperdício religando o agendamento a cada passo.

O artigo Orca relata 36,9 vezes a vazão do Faster Transformer com a mesma latência, medindo o GPT-3 de 175 bilhões de parâmetros. É um benchmark dos próprios autores, em um modelo que não roda em uma estação de trabalho. Trate o número como prova de que a ideia funciona, não como previsão para o seu escritório.

O [chunked prefill](https://docs.vllm.ai/en/latest/) resolve um problema diferente, vindo do artigo Sarathi-Serve. Quando alguém cola um documento de vinte páginas, o prefill daquele prompt seria um passo gigantesco que congela todas as respostas em andamento. Fatiar o prompt em partes distribui esse trabalho por vários passos.

O vLLM organiza cada passo em torno de um orçamento de tokens. A documentação atual descreve o passo como um mapa de identificador de pedido para quantidade de tokens, contando prompt e geração no mesmo orçamento. Segundo a documentação atual, o agendador coloca primeiro todos os decodes pendentes e usa o espaço restante para uma fatia do prompt longo.

O tamanho desse orçamento é uma configuração. Um valor menor deixa menos prefill competindo com o decode, então os intervalos entre tokens ficam curtos. Um valor maior termina o prefill mais rápido e antecipa a primeira palavra. O padrão e a existência do chunking mudaram entre versões do vLLM, por isso confira a documentação da release que você está executando.

## O que acaba primeiro: a conta do cache KV

A memória do cache KV decide quantas conversas cabem na GPU. O [Qwen2.5-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct), modelo denso de 7 bilhões de parâmetros da Alibaba, lista 28 camadas, 4 cabeças de chave-valor e números em BFloat16, que ocupam 2 bytes cada. O tamanho oculto de 3.584 dividido por 28 cabeças de atenção dá 128 números por cabeça.

A conta é direta: 2 (chaves e valores) × 28 camadas × 4 cabeças × 128 × 2 bytes = 57.344 bytes por token. Isso dá cerca de 57 KB de cache para cada token na conversa. Uma conversa de 4 mil tokens consome aproximadamente 235 MB. No limite de 32 mil tokens do modelo, são cerca de 1,9 GB para uma única thread.

São estimativas tiradas do arquivo de configuração. Elas ignoram sobrecarga do runtime e arredondamento de blocos, então o consumo real tende a ser um pouco maior. O Qwen2.5-7B leva vantagem porque suas 28 cabeças de atenção compartilham apenas quatro conjuntos de chaves e valores.

Modelos maiores custam bem mais por token. A documentação de dimensionamento do vLLM cita um modelo de 13 bilhões de parâmetros perto de 1 MB por token, mais de dez vezes a estimativa acima. O [post de lançamento do vLLM](https://blog.vllm.ai/2023/06/20/vllm.html) afirma que uma única sequência do Llama 13B pode ocupar até 1,7 GB.

Chat piora a situação porque o modelo não lembra nada entre turnos. A [documentação da OpenAI](https://platform.openai.com/docs/guides/conversation-state) descreve que sua aplicação reenvia as mensagens anteriores de usuário e assistente a cada nova requisição. O turno 10 carrega os turnos 1 a 9 junto com ele, então cada mensagem deixa a conversa mais cara.

## PagedAttention, fragmentação e preempção

O PagedAttention, implementado pelo vLLM, guarda o cache em blocos pequenos de tamanho fixo distribuídos conforme a conversa cresce. O [artigo do PagedAttention](https://arxiv.org/abs/2309.06180), publicado na SOSP 2023, compara o resultado com sistemas anteriores que desperdiçavam de 60% a 80% da memória de cache por fragmentação e reserva excessiva.

O post de lançamento do vLLM atribui essa faixa de desperdício aos sistemas anteriores. Com blocos de tamanho fixo, o vLLM relata redução do desperdício para menos de 4%. O mesmo artigo relata de duas a quatro vezes a vazão dos sistemas comparados com a mesma latência. Como menos memória fica reservada e vazia, mais pedidos cabem em cada lote.

Os blocos também habilitam o cache de prefixo. Quando a décima mensagem de Alice começa com o mesmo histórico da nona, o vLLM reaproveita os blocos já calculados, desde que continuem em memória. O quanto isso economiza depende de como o seu time realmente conversa.

Quando o cache enche, o vLLM não cai. Ele aplica preempção: pausa um pedido, congela seus blocos e recalcula depois, quando há espaço. Do lado do usuário, isso aparece como uma resposta que para no meio e depois continua. No servidor, aparece como aviso de preempção no log. Avisos frequentes significam falta de espaço de cache, com o agendador fazendo o possível ao redor disso.

## Como diagnosticar o sintoma que o seu time está vendo

Cada sintoma aponta para uma causa distinta, e o log do servidor confirma qual delas está ativa. Diagnosticar antes de ajustar qualquer configuração evita mexer no parâmetro errado. Use a tabela abaixo como ponto de partida.

| Sintoma observado | Causa provável | O que verificar |
| --- | --- | --- |
| Todas as respostas congelam juntas quando alguém cola um documento grande | Prefill longo bloqueando o passo | Chunked prefill e tamanho do orçamento de tokens |
| Respostas param no meio e depois retomam | Cache KV cheio, com preempção | Avisos de preempção no log e consumo de memória |
| Todos um pouco mais lentos, mas estáveis | Batching funcionando como esperado | ITL médio e número de pedidos por lote |
| Primeira palavra demorando muito, com digitação fluida | Prefill sem prioridade adequada | TTFT e orçamento de tokens do passo |

Se as respostas congelam ao mesmo tempo, olhe primeiro para o chunked prefill e para o orçamento de tokens. Se pausam e voltam durante conversas longas, o problema é memória. Se tudo ficou um pouco mais devagar, mas continua fluido, o batching está simplesmente fazendo o trabalho dele.

A leitura dos avisos de preempção é o sinal mais barato de todos. Você não precisa instrumentar nada novo para enxergá-los. Basta observar a frequência com que aparecem no log.

## Qual configuração escolher para cada tipo de uso

O ajuste certo depende de quem usa o serviço e de qual métrica essa pessoa sente. Um assistente pessoal, um serviço interno para o time e um produto voltado ao cliente final pedem configurações diferentes. As recomendações abaixo são orientações de editoria baseadas nos mecanismos descritos, não números extraídos das fontes.

### Assistente pessoal, com um usuário

Com uma única pessoa, batching praticamente não entra na conta e a vazão importa pouco. O alvo é o TTFT: um orçamento de tokens maior faz seu próprio prompt longo atravessar o prefill mais cedo. Você pode gastar memória em contexto longo justamente porque ninguém está dividindo a GPU com você.

### Serviço interno de escritório, de 5 a 30 pessoas

Aqui o alvo é vazão com velocidade de digitação estável. Mantenha o chunked prefill ligado e prefira um orçamento de tokens menor, para que documentos longos não travem as respostas em andamento. Trate os avisos de preempção como o sinal antecipado de que o cache encheu.

Vale limitar o comprimento de contexto, algo em torno de 1,9 GB por conversa no limite do modelo de 7B citado acima. Algumas threads gigantes conseguem expulsar todo mundo. Uma saída simples é orientar o time a abrir um chat novo para documentos longos, em vez de continuar no turno 40.

### Produto voltado ao cliente final

Aqui uma resposta lenta é a primeira impressão de alguém. Defina metas sobre a latência de cauda, ou seja, as respostas mais lentas, em vez da média. A mediana pode parecer saudável enquanto um cliente em cem espera tempo demais.

Imponha um teto rígido de comprimento de contexto e reserve folga de memória para picos de uso. Um pico que empurra o cache para preempção vira travamento visível para quem está pagando. Nesse cenário, o custo de uma resposta lenta é muito maior do que o de uma resposta um pouco mais curta.

## Perguntas frequentes

- **Quantos usuários simultâneos cabem em uma GPU só com vLLM?** Não existe número fixo, porque o limite é o espaço de cache KV, não a contagem de pessoas. No Qwen2.5-7B, cada conversa no limite de 32 mil tokens ocupa cerca de 1,9 GB. Faça a conta a partir da memória livre da sua GPU e do tamanho médio das conversas do seu time.

- **O que é cache KV e por que ele cresce com a conversa?** É o armazenamento das chaves e valores de atenção de cada token já processado, usado para não reprocessar o histórico a cada passo. Ele cresce a cada token gerado e permanece enquanto o pedido está ativo. No Qwen2.5-7B, cada token custa aproximadamente 57 KB.

- **Por que o PagedAttention reduz o desperdício de memória?** O PagedAttention guarda o cache em blocos pequenos e de tamanho fixo, entregues conforme a conversa cresce, como um sistema operacional distribui páginas de memória. Os blocos não precisam ser contíguos, então não existe uma reserva gigante desperdiçada. O artigo relata queda do desperdício de 60% a 80% para menos de 4%.

- **O que significa aviso de preempção no log do vLLM?** Significa que o cache KV encheu e o agendador pausou um pedido para liberar espaço, recalculando-o depois. O usuário vê a resposta parar no meio e retomar em seguida. Avisos frequentes indicam falta de memória, e não falha do agendador.

- **Chunked prefill deixa a primeira resposta mais lenta?** Sim, um pouco. O documento é processado em fatias ao longo de vários passos, então a primeira palavra demora mais do que demoraria com prefill inteiro e GPU exclusiva. Em troca, as conversas em andamento continuam fluindo sem travar durante o processo.

[Source video](https://www.youtube.com/watch?v=MDG372ImRgM)
