{"id":804,"date":"2026-09-07T16:26:32","date_gmt":"2026-09-07T19:26:32","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/2026\/09\/vllm-primeiros-passos-linux\/"},"modified":"2026-09-08T13:29:34","modified_gmt":"2026-09-08T16:29:34","slug":"vllm-primeiros-passos-linux","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/en\/2026\/09\/vllm-primeiros-passos-linux\/","title":{"rendered":"vLLM: serving LLMs on Linux with high throughput \u2014 history, installation, and first steps"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" alt=\"Mascote do LinuxPro paginando blocos de mem\u00f3ria na VRAM, placa 3D do V do vLLM na parede\" src=\"\/wp-content\/uploads\/2026\/09\/vllm-v5.webp\" width=\"1486\" height=\"856\" \/><\/p>\n<p>Se voc\u00ea j\u00e1 rodou um LLM local com Ollama ou llama.cpp, sabe que funciona muito bem \u2014 para <strong>uma ou duas pessoas<\/strong>. Quando a demanda vira uma API que precisa atender dezenas de requisi\u00e7\u00f5es simult\u00e2neas, o jogo muda: a GPU fica ociosa esperando, a mem\u00f3ria se fragmenta e a vaz\u00e3o despenca. \u00c9 exatamente esse problema que o <strong>vLLM<\/strong> resolve, e \u00e9 por isso que ele virou o motor de infer\u00eancia padr\u00e3o de boa parte da ind\u00fastria.<\/p>\n<p>Este post cobre a hist\u00f3ria do projeto, a ideia t\u00e9cnica que o tornou r\u00e1pido, e um passo a passo execut\u00e1vel para instalar e subir seu primeiro servidor no Linux.<\/p>\n<h2>De onde veio o vLLM<\/h2>\n<p>O vLLM nasceu no <strong>Sky Computing Lab da UC Berkeley<\/strong>. O reposit\u00f3rio foi criado em <strong>fevereiro de 2023<\/strong>, e o lan\u00e7amento p\u00fablico veio em <strong>20 de junho de 2023<\/strong>, num post que anunciava algo dif\u00edcil de acreditar na \u00e9poca: at\u00e9 <strong>24x mais vaz\u00e3o<\/strong> que o HuggingFace Transformers e at\u00e9 3,5x mais que o Text Generation Inference, <em>sem alterar a arquitetura do modelo<\/em>.<\/p>\n<p>N\u00e3o era marketing de laborat\u00f3rio. Antes do an\u00fancio, o vLLM j\u00e1 rodava havia dois meses em produ\u00e7\u00e3o servindo o <strong>Vicuna<\/strong> e a <strong>Chatbot Arena<\/strong> do LMSYS \u2014 era a tecnologia que permitia a um grupo de pesquisa pequeno bancar a conta de GPU de um chatbot p\u00fablico.<\/p>\n<p>A ideia central foi publicada no paper <em>&#8220;Efficient Memory Management for Large Language Model Serving with PagedAttention&#8221;<\/em>, apresentado no <strong>SOSP 2023<\/strong> \u2014 o que diz muito sobre a natureza do trabalho: n\u00e3o \u00e9 um paper de machine learning, \u00e9 um paper de <strong>sistemas operacionais<\/strong>.<\/p>\n<p>A linha do tempo desde ent\u00e3o:<\/p>\n<ul>\n<li><strong>Fev\/2023<\/strong> \u2014 reposit\u00f3rio criado no GitHub, sob licen\u00e7a Apache 2.0.<\/li>\n<li><strong>Jun\/2023<\/strong> \u2014 lan\u00e7amento p\u00fablico; j\u00e1 em produ\u00e7\u00e3o no Vicuna e na Chatbot Arena.<\/li>\n<li><strong>Out\/2023<\/strong> \u2014 paper do PagedAttention no SOSP.<\/li>\n<li><strong>Jan\/2025<\/strong> \u2014 <strong>vLLM V1<\/strong>, reescrita do n\u00facleo (scheduler, gerenciador de KV cache, worker, sampler e servidor de API), com ~1,7x de ganho. Sai em alpha na v0.7.0 e vira o motor padr\u00e3o na v0.8.0.<\/li>\n<li><strong>Mai\/2025<\/strong> \u2014 o projeto passa a ser hospedado pela <strong>PyTorch Foundation<\/strong>, um dos primeiros projetos de plataforma sob esse guarda-chuva.<\/li>\n<li><strong>Ago\/2026<\/strong> \u2014 vers\u00e3o <strong>v0.28.0<\/strong>. O reposit\u00f3rio passa de <strong>91 mil estrelas<\/strong> e 21 mil forks, com centenas de contribuidores.<\/li>\n<\/ul>\n<h2>PagedAttention em 30 segundos<\/h2>\n<p>Para gerar cada token novo, o modelo precisa consultar as chaves e valores de aten\u00e7\u00e3o de todos os tokens anteriores. Esse material fica na VRAM e se chama <strong>KV cache<\/strong>. Ele \u00e9 grande (chegava a 1,7 GB por sequ\u00eancia no LLaMA-13B) e, pior, <strong>din\u00e2mico<\/strong>: o tamanho depende do comprimento da conversa, que ningu\u00e9m sabe de antem\u00e3o.<\/p>\n<p>Os motores anteriores resolviam isso reservando um bloco cont\u00edguo do tamanho m\u00e1ximo poss\u00edvel para cada requisi\u00e7\u00e3o. Resultado: os autores mediram <strong>60% a 80% de desperd\u00edcio<\/strong> de VRAM por fragmenta\u00e7\u00e3o e reserva excessiva. Mem\u00f3ria desperdi\u00e7ada significa menos requisi\u00e7\u00f5es simult\u00e2neas, o que significa GPU ociosa.<\/p>\n<p>O PagedAttention aplica ao KV cache a mesma solu\u00e7\u00e3o que o kernel usa para a mem\u00f3ria do sistema h\u00e1 d\u00e9cadas \u2014 <strong>pagina\u00e7\u00e3o<\/strong>:<\/p>\n<ul>\n<li>o KV cache de cada sequ\u00eancia \u00e9 dividido em <strong>blocos<\/strong> de tamanho fixo;<\/li>\n<li>os blocos <strong>n\u00e3o precisam ser cont\u00edguos<\/strong> na VRAM, e s\u00e3o alocados sob demanda;<\/li>\n<li>uma <em>block table<\/em> mapeia blocos l\u00f3gicos para f\u00edsicos, exatamente como uma tabela de p\u00e1ginas.<\/li>\n<\/ul>\n<p>A analogia \u00e9 literal: blocos s\u00e3o p\u00e1ginas, tokens s\u00e3o bytes, sequ\u00eancias s\u00e3o processos. E, como em qualquer sistema com pagina\u00e7\u00e3o, vem de brinde o <strong>compartilhamento<\/strong>: duas requisi\u00e7\u00f5es com o mesmo prompt apontam para os mesmos blocos f\u00edsicos, com contagem de refer\u00eancia e <em>copy-on-write<\/em>. O desperd\u00edcio cai para menos de 4%, e sobra VRAM para agrupar muito mais sequ\u00eancias no mesmo lote.<\/p>\n<p>Some a isso o <strong>continuous batching<\/strong> \u2014 em vez de esperar o lote inteiro terminar, o scheduler encaixa requisi\u00e7\u00f5es novas assim que uma vaga abre \u2014 e voc\u00ea tem a explica\u00e7\u00e3o inteira do ganho de vaz\u00e3o.<\/p>\n<h2>vLLM, Ollama ou llama.cpp?<\/h2>\n<p>Os tr\u00eas servem LLMs, mas resolvem problemas diferentes. Escolher errado d\u00f3i:<\/p>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>vLLM<\/th>\n<th>Ollama \/ llama.cpp<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Caso de uso<\/strong><\/td>\n<td>API multiusu\u00e1rio, produ\u00e7\u00e3o, alta vaz\u00e3o<\/td>\n<td>Uso pessoal e equipes pequenas; atendem concorr\u00eancia (<code>--parallel<\/code>, <code>OLLAMA_NUM_PARALLEL<\/code>), mas a vaz\u00e3o cai r\u00e1pido com a carga<\/td>\n<\/tr>\n<tr>\n<td><strong>Hardware<\/strong><\/td>\n<td>GPU dedicada com VRAM sobrando<\/td>\n<td>Roda em CPU, GPU parcial, pouca VRAM<\/td>\n<\/tr>\n<tr>\n<td><strong>Formato do modelo<\/strong><\/td>\n<td>Pesos do Hugging Face (safetensors)<\/td>\n<td>GGUF quantizado<\/td>\n<\/tr>\n<tr>\n<td><strong>Modelo n\u00e3o cabe na VRAM<\/strong><\/td>\n<td>Offload para a RAM \u00e9 poss\u00edvel (<code>--cpu-offload-gb<\/code>), mas custa caro em lat\u00eancia<\/td>\n<td>Faz offload para a RAM e segue<\/td>\n<\/tr>\n<tr>\n<td><strong>Facilidade<\/strong><\/td>\n<td>Exige planejar VRAM e par\u00e2metros<\/td>\n<td>Um comando e funciona<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Regra pr\u00e1tica: se \u00e9 voc\u00ea sozinho no seu desktop, use <a href=\"\/2026\/09\/rodando-ia-local-no-linux-com-ollama\/\">Ollama<\/a> ou o <a href=\"\/2026\/09\/llama-model-cli\/\">llama-server<\/a>. Se \u00e9 um servi\u00e7o que v\u00e1rias pessoas ou v\u00e1rios agentes v\u00e3o consumir ao mesmo tempo, vLLM.<\/p>\n<h2>Requisitos<\/h2>\n<ul>\n<li><strong>Linux<\/strong> (\u00e9 a plataforma de primeira classe) e <strong>Python 3.10 a 3.13<\/strong>.<\/li>\n<li><strong>GPU NVIDIA<\/strong> com driver e CUDA funcionando \u00e9 o caminho mais suave. H\u00e1 suporte a AMD (ROCm), Intel (XPU), TPU do Google e NPUs Ascend, al\u00e9m do <code>vLLM-Metal<\/code> para Apple Silicon.<\/li>\n<li><strong>VRAM<\/strong>: conte com os pesos do modelo mais o KV cache. Um modelo de 7B em FP16 pede ~14 GB s\u00f3 de pesos \u2014 some folga para o cache. \u00c9 a partir de 24 GB que a coisa fica confort\u00e1vel.<\/li>\n<\/ul>\n<p>Confira o ambiente antes:<\/p>\n<pre><code class=\"language-bash\">nvidia-smi\npython3 --version<\/code><\/pre>\n<h2>Instalando<\/h2>\n<p>A forma recomendada pela documenta\u00e7\u00e3o \u00e9 com o <a href=\"https:\/\/docs.astral.sh\/uv\/\" target=\"_blank\" rel=\"noopener\">uv<\/a>, que resolve o \u00edndice correto do PyTorch para a sua vers\u00e3o de CUDA automaticamente:<\/p>\n<pre><code class=\"language-bash\"># instala o uv, se ainda n\u00e3o tiver\ncurl -LsSf https:\/\/astral.sh\/uv\/install.sh | sh\n\n# ambiente isolado + vLLM\nuv venv --python 3.12 --seed\nsource .venv\/bin\/activate\nuv pip install vllm --torch-backend=auto<\/code><\/pre>\n<p>O <code>--torch-backend=auto<\/code> inspeciona o driver CUDA instalado e escolhe a build certa. Para fixar uma vers\u00e3o espec\u00edfica, troque por <code>--torch-backend=cu129<\/code> (ou a build que voc\u00ea usa \u2014 os bin\u00e1rios do vLLM hoje saem para CUDA 12.8, 12.9 e 13.0).<\/p>\n<p>Quer s\u00f3 experimentar, sem criar ambiente nenhum?<\/p>\n<pre><code class=\"language-bash\">uv run --with vllm vllm --help<\/code><\/pre>\n<p>Em GPUs AMD, o \u00edndice \u00e9 outro:<\/p>\n<pre><code class=\"language-bash\">uv venv --python 3.12 --seed\nsource .venv\/bin\/activate\nuv pip install vllm --extra-index-url https:\/\/wheels.vllm.ai\/rocm\/<\/code><\/pre>\n<p>O <code>--python 3.12<\/code> n\u00e3o \u00e9 detalhe: as wheels ROCm s\u00f3 existem para essa vers\u00e3o. Com 3.11 ou 3.13 o instalador cai silenciosamente na wheel CUDA do PyPI, e o erro s\u00f3 aparece na hora de rodar, como <code>libcudart.so: cannot open shared object file<\/code>.<\/p>\n<p>E, se voc\u00ea prefere n\u00e3o instalar nada no host, a imagem oficial resolve:<\/p>\n<pre><code class=\"language-bash\">docker run --runtime nvidia --gpus all \n  -v ~\/.cache\/huggingface:\/root\/.cache\/huggingface \n  -p 8000:8000 --ipc=host \n  vllm\/vllm-openai:latest \n  --model Qwen\/Qwen2.5-1.5B-Instruct<\/code><\/pre>\n<p>O <code>--ipc=host<\/code> d\u00e1 ao container acesso \u00e0 mem\u00f3ria compartilhada do host. Sem ele, <code>\/dev\/shm<\/code> fica min\u00fasculo e o vLLM quebra ao inicializar os workers \u2014 sobretudo com tensor parallel. A alternativa, se voc\u00ea n\u00e3o quiser compartilhar o namespace de IPC, \u00e9 <code>--shm-size=8g<\/code>.<\/p>\n<h2>Primeiro teste: infer\u00eancia em lote<\/h2>\n<p>Antes de subir o servidor, vale um teste offline para confirmar que a GPU est\u00e1 sendo usada. Crie <code>teste.py<\/code>:<\/p>\n<pre><code class=\"language-python\">from vllm import LLM, SamplingParams\n\nprompts = [\n    \"O kernel Linux foi criado por\",\n    \"A capital do Brasil \u00e9\",\n    \"Em uma frase, explique o que \u00e9 pagina\u00e7\u00e3o de mem\u00f3ria:\",\n]\n\nsampling_params = SamplingParams(temperature=0.8, top_p=0.95, max_tokens=64)\n\nllm = LLM(model=\"Qwen\/Qwen2.5-1.5B-Instruct\")\noutputs = llm.generate(prompts, sampling_params)\n\nfor output in outputs:\n    print(f\"&gt;&gt; {output.prompt!r}\")\n    print(f\"   {output.outputs[0].text!r}n\")<\/code><\/pre>\n<pre><code class=\"language-bash\">python3 teste.py<\/code><\/pre>\n<p>Repare que os tr\u00eas prompts s\u00e3o processados <strong>juntos<\/strong>, n\u00e3o em fila \u2014 \u00e9 o batching em a\u00e7\u00e3o. Um detalhe que pega muita gente: <code>llm.generate()<\/code> <strong>n\u00e3o aplica o chat template<\/strong> do modelo. Para modelos <em>instruct<\/em>, use <code>llm.chat()<\/code> com a mesma estrutura de mensagens da API da OpenAI:<\/p>\n<pre><code class=\"language-python\">mensagens = [[{\"role\": \"user\", \"content\": p}] for p in prompts]\noutputs = llm.chat(mensagens, sampling_params)<\/code><\/pre>\n<h2>Subindo o servidor compat\u00edvel com a API da OpenAI<\/h2>\n<p>Esta \u00e9 a principal raz\u00e3o de ser do vLLM em produ\u00e7\u00e3o: ele fala o protocolo da OpenAI, ent\u00e3o qualquer aplica\u00e7\u00e3o, SDK ou agente que j\u00e1 usa a OpenAI aponta para ele trocando apenas a <code>base_url<\/code>.<\/p>\n<pre><code class=\"language-bash\">vllm serve Qwen\/Qwen2.5-1.5B-Instruct<\/code><\/pre>\n<p>O servidor sobe em <code>http:\/\/localhost:8000<\/code>. Teste:<\/p>\n<pre><code class=\"language-bash\">curl http:\/\/localhost:8000\/v1\/models\n\ncurl http:\/\/localhost:8000\/v1\/chat\/completions \n  -H \"Content-Type: application\/json\" \n  -d '{\n    \"model\": \"Qwen\/Qwen2.5-1.5B-Instruct\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"Explique inodes em duas frases.\"}],\n    \"temperature\": 0.7\n  }'<\/code><\/pre>\n<p>Do lado do cliente Python, \u00e9 o SDK oficial da OpenAI sem gambiarra:<\/p>\n<pre><code class=\"language-python\">from openai import OpenAI\n\nclient = OpenAI(api_key=\"EMPTY\", base_url=\"http:\/\/localhost:8000\/v1\")\n\nresposta = client.chat.completions.create(\n    model=\"Qwen\/Qwen2.5-1.5B-Instruct\",\n    messages=[{\"role\": \"user\", \"content\": \"Escreva um one-liner que conta arquivos por extens\u00e3o.\"}],\n)\nprint(resposta.choices[0].message.content)<\/code><\/pre>\n<p>Para exigir autentica\u00e7\u00e3o, suba com <code>--api-key SEGREDO<\/code> \u2014 ou, melhor, com a vari\u00e1vel <code>VLLM_API_KEY<\/code>, porque chave em linha de comando aparece no <code>ps aux<\/code>. O servidor aceita m\u00faltiplas chaves, o que facilita rota\u00e7\u00e3o sem downtime.<\/p>\n<p><strong>Aten\u00e7\u00e3o:<\/strong> o <code>--api-key<\/code> autentica apenas os prefixos <code>\/v1<\/code>, <code>\/v2<\/code> e <code>\/inference<\/code>. Endpoints como <code>\/invocations<\/code> (que exp\u00f5e a mesma capacidade de infer\u00eancia), <code>\/pooling<\/code>, <code>\/classify<\/code> e os de controle <code>\/pause<\/code>, <code>\/resume<\/code> e <code>\/abort_requests<\/code> continuam abertos. Se voc\u00ea usa <code>--host 0.0.0.0<\/code>, ponha o vLLM atr\u00e1s de um proxy reverso que libere s\u00f3 as rotas que voc\u00ea quer expor \u2014 nunca deixe a porta 8000 acess\u00edvel direto da rede.<\/p>\n<h2>Os par\u00e2metros que realmente importam<\/h2>\n<p>O padr\u00e3o funciona, mas quase nunca \u00e9 o que voc\u00ea quer em produ\u00e7\u00e3o:<\/p>\n<pre><code class=\"language-bash\">vllm serve Qwen\/Qwen2.5-7B-Instruct \n  --host 0.0.0.0 --port 8000 \n  --gpu-memory-utilization 0.90 \n  --max-model-len 8192 \n  --tensor-parallel-size 1 \n  --api-key MINHA_CHAVE<\/code><\/pre>\n<ul>\n<li><code>--gpu-memory-utilization<\/code> \u2014 fra\u00e7\u00e3o da VRAM que o vLLM pode ocupar (padr\u00e3o <strong>0.92<\/strong> nas vers\u00f5es atuais; era 0.9 at\u00e9 a v0.11). <strong>Baixe<\/strong> se a GPU tamb\u00e9m roda seu monitor ou outro processo; <strong>suba<\/strong> se a placa \u00e9 dedicada. Quanto maior, mais KV cache, mais requisi\u00e7\u00f5es simult\u00e2neas.<\/li>\n<li><code>--max-model-len<\/code> \u2014 janela de contexto m\u00e1xima. \u00c9 o par\u00e2metro n\u00ba 1 para resolver erro de mem\u00f3ria na inicializa\u00e7\u00e3o: modelos anunciam contextos gigantes (128k) que exigem KV cache que voc\u00ea n\u00e3o tem. Corte para o que a sua aplica\u00e7\u00e3o de fato usa.<\/li>\n<li><code>--tensor-parallel-size<\/code> \u2014 n\u00famero de GPUs para dividir o modelo. Use quando o modelo n\u00e3o cabe em uma placa s\u00f3.<\/li>\n<li><code>--dtype<\/code> \u2014 <code>auto<\/code> resolve bem; <code>bfloat16<\/code> em placas Ampere ou mais novas, <code>float16<\/code> em placas antigas.<\/li>\n<li><code>--quantization<\/code> \u2014 para pesos AWQ, GPTQ ou FP8, que cortam a VRAM pela metade ou mais.<\/li>\n<li><code>--served-model-name<\/code> \u2014 o nome que a API exp\u00f5e, \u00fatil para n\u00e3o vazar o caminho do Hugging Face para os clientes.<\/li>\n<li><code>--cpu-offload-gb<\/code> \u2014 quantos GiB dos pesos empurrar para a RAM, por GPU. Salva o dia quando o modelo n\u00e3o cabe, mas cada <em>forward pass<\/em> passa pelo barramento: s\u00f3 use se a alternativa for n\u00e3o rodar.<\/li>\n<\/ul>\n<p>Modelos com licen\u00e7a restrita (Llama, Gemma) exigem token do Hugging Face:<\/p>\n<pre><code class=\"language-bash\">export HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxx\nvllm serve meta-llama\/Llama-3.1-8B-Instruct<\/code><\/pre>\n<h2>Rodando como servi\u00e7o no systemd<\/h2>\n<p>Em um servidor de verdade, o vLLM tem que subir sozinho no boot. Crie <code>\/etc\/systemd\/system\/vllm.service<\/code>:<\/p>\n<pre><code class=\"language-ini\">[Unit]\nDescription=vLLM OpenAI-compatible server\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=exec\nUser=vllm\nGroup=vllm\nWorkingDirectory=\/opt\/vllm\nEnvironment=\"HF_HOME=\/opt\/vllm\/hf\"\nEnvironment=\"VLLM_API_KEY=MINHA_CHAVE\"\nExecStart=\/opt\/vllm\/.venv\/bin\/vllm serve Qwen\/Qwen2.5-7B-Instruct \n  --host 0.0.0.0 --port 8000 \n  --gpu-memory-utilization 0.90 \n  --max-model-len 8192\nRestart=always\nRestartSec=10\nTimeoutStartSec=600\n\n[Install]\nWantedBy=multi-user.target<\/code><\/pre>\n<p>O <code>TimeoutStartSec<\/code> alto \u00e9 proposital: na primeira execu\u00e7\u00e3o o modelo \u00e9 baixado do Hugging Face e os kernels s\u00e3o compilados, e com o padr\u00e3o de 90 segundos o systemd desistiria no meio do caminho. Repare que ele s\u00f3 tem efeito porque a unit usa <code>Type=exec<\/code> \u2014 com <code>Type=simple<\/code>, o systemd considera o servi\u00e7o iniciado j\u00e1 no <code>fork()<\/code> e o timeout de partida nunca chega a valer.<\/p>\n<p>O servi\u00e7o roda com usu\u00e1rio e ambiente pr\u00f3prios \u2014 o <code>.venv<\/code> que voc\u00ea criou no seu diret\u00f3rio pessoal n\u00e3o serve aqui:<\/p>\n<pre><code class=\"language-bash\">sudo useradd -r -s \/usr\/sbin\/nologin -d \/opt\/vllm vllm\nsudo mkdir -p \/opt\/vllm\/hf\nsudo chown -R vllm:vllm \/opt\/vllm\n\n# instala o vLLM dentro de \/opt\/vllm, como o usu\u00e1rio do servi\u00e7o\nsudo -u vllm uv venv --python 3.12 --seed \/opt\/vllm\/.venv\nsudo -u vllm env VIRTUAL_ENV=\/opt\/vllm\/.venv uv pip install vllm --torch-backend=auto\n\nsudo systemctl daemon-reload\nsudo systemctl enable --now vllm\njournalctl -u vllm -f<\/code><\/pre>\n<h2>Problemas comuns<\/h2>\n<ul>\n<li><strong><code>CUDA out of memory<\/code> na inicializa\u00e7\u00e3o<\/strong> \u2014 quase sempre \u00e9 o KV cache, n\u00e3o os pesos. Reduza <code>--max-model-len<\/code> primeiro, depois <code>--gpu-memory-utilization<\/code>, e s\u00f3 ent\u00e3o troque de modelo ou parta para pesos quantizados.<\/li>\n<li><strong>Erro de <code>\/dev\/shm<\/code> ou workers morrendo em Docker<\/strong> \u2014 faltou <code>--ipc=host<\/code>.<\/li>\n<li><strong>Modelo responde bobagem em modo chat<\/strong> \u2014 voc\u00ea usou <code>generate()<\/code> em vez de <code>chat()<\/code>, e o chat template n\u00e3o foi aplicado.<\/li>\n<li><strong>A subida do servi\u00e7o demora muito<\/strong> \u2014 \u00e9 a compila\u00e7\u00e3o dos kernels e a captura dos CUDA graphs, que acontecem na inicializa\u00e7\u00e3o do engine, n\u00e3o na primeira requisi\u00e7\u00e3o. Os artefatos ficam em <code>~\/.cache\/vllm<\/code> e s\u00e3o reaproveitados nos boots seguintes; em Docker, monte um volume nesse caminho para n\u00e3o recompilar a cada container. Para pular a etapa, ao custo de decode mais lento, use <code>--enforce-eager<\/code>.<\/li>\n<li><strong>Download travando ou 401<\/strong> \u2014 modelo com licen\u00e7a restrita: aceite os termos na p\u00e1gina do Hugging Face e exporte <code>HF_TOKEN<\/code>.<\/li>\n<\/ul>\n<h2>Fechando<\/h2>\n<p>O vLLM \u00e9 o exemplo raro de projeto de pesquisa que virou infraestrutura padr\u00e3o porque resolveu o problema certo: tratou a VRAM de uma GPU como o kernel trata a RAM de um servidor. A li\u00e7\u00e3o \u00e9 velha \u2014 pagina\u00e7\u00e3o, tabela de p\u00e1ginas, copy-on-write \u2014 s\u00f3 o hardware \u00e9 novo.<\/p>\n<p>Para continuar: entenda a <a href=\"\/2026\/09\/gpu-vs-tpu-como-funcionam-chips-ia\/\">diferen\u00e7a entre GPU e TPU<\/a>, veja como montar um <a href=\"\/2026\/09\/servidor-ia-recondicionado-64gb-vram-v100-p100-mi25\/\">servidor de IA recondicionado com 64 GB de VRAM<\/a> para hospedar tudo isso sem quebrar o or\u00e7amento, ou compare com o caminho mais simples de <a href=\"\/2026\/09\/rodando-ia-local-no-linux-com-ollama\/\">rodar IA local com Ollama<\/a>.<\/p>\n<p><strong>Links oficiais:<\/strong> <a href=\"https:\/\/vllm.ai\/\" target=\"_blank\" rel=\"noopener\">vllm.ai<\/a> \u00b7 <a href=\"https:\/\/github.com\/vllm-project\/vllm\" target=\"_blank\" rel=\"noopener\">github.com\/vllm-project\/vllm<\/a> \u00b7 <a href=\"https:\/\/docs.vllm.ai\/\" target=\"_blank\" rel=\"noopener\">documenta\u00e7\u00e3o<\/a> \u00b7 <a href=\"https:\/\/arxiv.org\/abs\/2309.06180\" target=\"_blank\" rel=\"noopener\">paper do PagedAttention<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you have run a local LLM with Ollama or llama.cpp, you know it works very well \u2014 for one or two people. When demand becomes an API that must handle dozens of simultaneous requests, the situation changes: the GPU sits idle waiting, memory becomes fragmented, and throughput plummets. That is precisely the problem \u2026 <a title=\"vLLM: serving LLMs on Linux with high throughput \u2014 history, installation, and first steps\" class=\"read-more\" href=\"https:\/\/www.linuxpro.com.br\/en\/2026\/09\/vllm-primeiros-passos-linux\/\" aria-label=\"Read more about vLLM: servindo LLMs no Linux com alta vaz\u00e3o \u2014 hist\u00f3ria, instala\u00e7\u00e3o e primeiros passos\">Read more<\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[115,2,120],"tags":[134,116,385,128,152,81,384],"class_list":["post-804","post","type-post","status-publish","format-standard","hentry","category-ia","category-linux","category-servidores","tag-gpu","tag-ia","tag-inferencia","tag-llm","tag-nvidia","tag-python","tag-vllm"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/804","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/comments?post=804"}],"version-history":[{"count":5,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/804\/revisions"}],"predecessor-version":[{"id":1445,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/804\/revisions\/1445"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/media?parent=804"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/categories?post=804"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/tags?post=804"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}