Implantar o vLLM em production
Para implantar o vLLM em produção: instale-o no Linux (via pip ou a imagem Docker vllm/vllm-openai), inicie vllm serve com seu modelo, ajuste --gpu-memory-utilization e --max-model-len, ative --api-key e, depois, coloque um proxy reverso à frente do servidor. O servidor escuta na porta 8000 com uma API compatível com a da OpenAI. Ele serve apenas um modelo de cada vez e prioriza a taxa de processamento para muitos usuários simultâneos.
vLLM é o servidor de inferência projetado para compartilhar uma GPU entre muitas requisições em paralelo. Este guia aborda o dimensionamento da memória (o ponto central), a instalação, a inicialização, Docker e systemd, os parâmetros que importam, a medição de throughput e a segurança, com uma correção importante: a opção --api-key protege apenas parte das rotas.
#O que faz o vLLM e o que exige
vLLM é um motor de inferência open source criado no laboratório Sky Computing da UC Berkeley. Sua ideia central, PagedAttention, gerencia o cache chave-valor da atenção por páginas, como a memória virtual de um sistema operacional. Segundo o anúncio inicial do projeto em 2023, os sistemas existentes desperdiçavam uma grande parte de sua memória, e o vLLM atingia até 24 vezes a taxa de processamento do Hugging Face Transformers e até 3,5 vezes a do TGI em testes da época. Esses números são antigos e específicos daquele ambiente de testes: indicam uma direção, não o que você obterá com seu modelo e sua placa.
Quanto aos pré-requisitos, a documentação atual exige Linux e Python de 3.10 a 3.13; no Mac, existe uma opção separada, vLLM-Metal, que se baseia em MLX. O servidor expõe uma API compatível com a API da OpenAI, escuta por padrão na porta 8000 e serve apenas um modelo de cada vez: para vários modelos, são necessárias várias instâncias.
#Quando escolher vLLM em vez de Ollama
Seu ChatGPT privado e gratuito na sua máquina em 1 hora — LM Studio, Ollama, Open WebUI, seus documentos, sem nuvem.
- Espaço online vitalício
- PDF + arquivos
- Atualizações vitalícias
A diferença não está na capacidade de processar requisições em paralelo, que também é oferecida por Ollama, mas na forma como a memória é compartilhada. De acordo com a FAQ de Ollama, o processamento paralelo de um modelo multiplica o tamanho do contexto pelo número de requisições: um contexto de 2.000 tokens com 4 requisições em paralelo torna-se um contexto de 8.000 tokens na memória, reservado antecipadamente. O vLLM aloca seu cache em blocos, conforme demanda, e agrupa as requisições em andamento nos mesmos cálculos.
| Critério | Ollama | vLLM |
|---|---|---|
| Usuários simultâneos | 1 a alguns; OLLAMA_NUM_PARALLEL controla o paralelismo | Dezenas de requisições simultâneas |
| Modelos servidos | Vários, carregados e descarregados conforme necessário | Apenas um por instância |
| Implementação | Um comando de instalação | Python, CUDA e parâmetros para ajustar |
| Quantizações | GGUF, grande variedade de opções | Formatos do Hub (AWQ, GPTQ, FP8); GGUF parcialmente |
| Métricas de acompanhamento | Não detalhadas neste guia | Ponto de acesso /metrics documentado |
| Uso típico | Computador pessoal, pequena equipe | Serviço interno ou produto |
Regra prática: se menos de três pessoas usam o modelo ao mesmo tempo, ou se você quer trocar de modelo com frequência, Ollama é suficiente. Acima disso, ou com um único modelo servido continuamente, vLLM justifica sua complexidade. O guia comparativo detalha a escolha.
#Quando vLLM é uma má escolha
O vLLM não traz nenhum benefício para um único usuário em uma GPU de 8 a 12 GB: falta memória para um cache compartilhado, e é mais simples iniciar o Ollama ou o llama.cpp. Ele não é muito adequado se você alterna entre cinco modelos ao longo do dia, pois é necessário reiniciar uma instância para cada modelo. Em um Mac, o caminho é diferente e se baseia no MLX. Por fim, se você precisa de uma interface de chat para a equipe em vez de uma API sob alta carga, uma pilha com Ollama e Open WebUI atende melhor e exige menos trabalho operacional.
#Dimensionar a memória: o cálculo a ser feito antes de tudo
Um servidor vLLM é dimensionado com base no cache de chave-valor, não nos pesos. Após carregar o modelo, o vLLM reserva uma fração da memória do GPU, 92% por padrão de acordo com o código de configuração atual, e dedica o restante ao cache. Esse restante determina quantos tokens de conversa podem coexistir, ou seja, quantos usuários simultâneos você pode atender.
Vamos tomar o Qwen2.5-7B-Instruct, cuja ficha indica 7,61 bilhões de parâmetros, 28 camadas e 4 cabeças chave-valor (atenção agrupada). O peso em 16 bits é de aproximadamente 15,2 GB. O cache de um token equivale a 2 (chaves e valores) × 28 camadas × 4 cabeças × 128 dimensões × 2 bytes, ou seja, 57.344 bytes, cerca de 56 KiB.
| Memória da GPU | Reserva de 92 % | Espaço restante para o cache | Tokens de cache (limite superior) | Equivalente em requisições de 4.096 tokens |
|---|---|---|---|---|
| 24 GB | 22,1 GB | 6,9 GB | cerca de 120.000 | cerca de 29 |
| 48 GB | 44,2 GB | 28,9 GB | cerca de 500.000 | cerca de 120 |
| 80 GB | 73,6 GB | 58,4 GB | aproximadamente 1 milhão | cerca de 250 |
Esses limites são altos: os buffers de cálculo e os grafos CUDA consomem parte da memória restante, e o modelo pode ter outro perfil. O método continua válido para qualquer modelo: consulte o número de camadas e de cabeças de chave-valor na ficha do modelo, calcule o custo por token e divida a memória restante por esse custo. Se os logs indicarem preempções, a documentação recomenda aumentar gpu_memory_utilization ou reduzir max_num_seqs.
Duas medidas ampliam o cache sem trocar de placa: carregar uma versão quantizada do modelo, que libera parte do espaço ocupado pelos pesos, ou limitar --max-model-len, o que evita reservar espaço para contextos que ninguém utiliza. A primeira medida pode custar um pouco de qualidade; a segunda não custa nada desde que suas requisições permaneçam curtas.
#1. Instalação
A documentação recomenda uv, que escolhe automaticamente a versão certa do PyTorch de acordo com seu driver CUDA. Para GPUs AMD, a instalação passa por um índice dedicado; para Intel, TPU ou Ascend, existem plugins. Em produção, a imagem Docker evita conflitos de versões CUDA e é atualizada com uma simples troca de tag.
#2. Iniciar o servidor
O comando vllm serve substitui a antiga invocação python -m vllm.entrypoints.openai.api_server, que a documentação atual já não utiliza. Na primeira execução, os pesos são baixados do Hugging Face: reserve espaço em disco (cerca de 15 GB para um modelo 7B em 16 bits). O servidor aplica por padrão o arquivo generation_config.json do repositório do modelo e, portanto, os parâmetros de amostragem recomendados por quem o publica; --generation-config vllm restaura os valores padrão do vLLM.
#3. Docker e systemd
A imagem oficial vllm/vllm-openai é a maneira mais segura. Monte o cache do Hugging Face para não baixar os pesos novamente e um volume para o cache de compilação: caso contrário, cada novo contêiner inicia com um cache vazio e recompila os artefatos do seu modelo. Observe que a imagem é executada como root por padrão; a documentação descreve uma execução com um usuário não privilegiado (--user 2000:0).
#4. Os parâmetros que importam
| Parâmetro | Função | Conselho |
|---|---|---|
| --gpu-memory-utilization | Fração da memória da GPU reservada (0,92 por padrão) | Reduzir se outro processo estiver usando a GPU; aumentar se os logs mostrarem preempções |
| --max-model-len | Contexto máximo aceito | O mais baixo possível: cada token de contexto custa memória de cache |
| --max-num-seqs | Número máximo de requisições por lote | Reduzir em caso de falta de memória |
| --tensor-parallel-size | Distribui o modelo entre várias GPUs de um nó | Apenas se o modelo não couber em uma GPU |
| --api-key | Exige uma chave para algumas rotas | Ver a seção de segurança: insuficiente sozinho |
| --generation-config vllm | Ignora o arquivo generation_config.json do modelo | Utilizar se as respostas forem diferentes do que você espera |
Um princípio da documentação: se o modelo cabe em uma única GPU, a distribuição provavelmente é inútil; se não cabe, mas cabe em um nó, utiliza-se o paralelismo tensorial com --tensor-parallel-size. Os modelos já quantizados são carregados diretamente do Hub, sem nenhuma opção específica: a opção --quantization serve apenas para a quantização dinâmica.
#5. Medir a taxa de processamento corretamente
O comando vllm bench serve envia requisições ao servidor e informa a taxa de processamento, o tempo até o primeiro token (TTFT) e a latência entre tokens. A documentação esclarece que esses benchmarks servem principalmente para avaliar funcionalidades e detectar regressões, e recomenda o GuideLLM para testar um servidor de produção.
#Implantação e operação
Após o dimensionamento, a implantação segue sempre a mesma sequência. Ela se aplica a uma equipe de cerca de vinte pessoas consultando o mesmo modelo de 7 a 8 bilhões de parâmetros em uma placa de 24 ou 48 GB.
- 01Escolher o modelo e o formatoUm único modelo por instância. Prefira um repositório já quantizado ou em 16 bits, de acordo com a memória disponível.
- 02Calcular o cacheAplique o cálculo por token da seção de dimensionamento para definir --max-model-len e --max-num-seqs.
- 03Iniciar no DockerUse a imagem oficial com o cache do Hugging Face montado e uma tag de versão fixa em vez de latest, para evitar que uma atualização mude o comportamento.
- 04Adicionar o proxyReverse proxy com lista branca de rotas, TLS e limitação de taxa, seguido pela chave da API como complemento.
- 05MedirInicie um teste de carga com vllm bench serve variando a semente e anote o TTFT e a taxa de transferência total.
- 06MonitorarIntegre a coleta de métricas do endpoint /metrics à sua ferramenta de monitoramento.
Os sinais a monitorar são os que indicam falta de cache: preempções nos logs, TTFT que aumenta, filas que se alongam. A documentação indica que a preempção, cujo modo padrão é o recálculo, protege o serviço, mas degrada a latência de ponta a ponta. Se ela se tornar frequente, aumente gpu_memory_utilization, reduza o contexto ou limite o número de requisições simultâneas. Como último recurso, adicione um GPU e distribua o modelo com paralelismo tensorial.
#6. Segurança e exposição: --api-key não é suficiente
Ao contrário do que muitas vezes se lê, o vLLM sabe verificar uma chave de API, com --api-key ou a variável VLLM_API_KEY. Mas a documentação de segurança reforça: a chave protege apenas as rotas sob /v1, /v2, /inference e /cohere. Outras rotas permanecem sem autenticação, como rotas de inferência fora de /v1, rotas de controle como /pause ou /abort_requests, e /health. Portanto, nunca conte apenas com --api-key.
- Reverse proxy
- Coloque nginx, Envoy ou um gateway Kubernetes à frente do vLLM, com uma lista de permissões contendo apenas as rotas a serem expostas, e bloqueie todas as outras.
- Rede
- Uma VPN ou uma rede isolada: a comunicação entre os nós de uma implantação distribuída não é protegida por padrão.
- Modo de desenvolvimento
- Nunca ative VLLM_SERVER_DEV_MODE=1 em produção: ele expõe rotas perigosas.
- Limites
- Aplique a limitação de taxa e a validação das requisições no nível do proxy, conforme recomendado na documentação.
- Registros
- Registre quem envia o quê, para depuração e auditoria.
- Fonte: início rápido com vLLM
- Fonte: segurança do vLLM
- Fonte: vLLM com Docker
- Fonte: anúncio do vLLM e PagedAttention
vLLM é melhor que Ollama em produção?+
Como iniciar um servidor vLLM com API compatível com OpenAI?+
Quanta VRAM é necessária para o vLLM?+
A opção --api-key é suficiente para proteger o vLLM?+
O vLLM funciona no Mac ou com uma placa AMD?+
Um comentário, um erro ou uma observação? Avise-nos; isso ajuda a melhorar o guia para todos.