O que isso constrói
Uma instância de GPU servindo um modelo de pesos abertos por uma API HTTP que fala o esquema compatível com OpenAI, então toda biblioteca de cliente que você já tem funciona contra ela com uma URL base alterada. Atrás do nginx, com TLS, uma chave de API e uma unit do systemd que sobrevive a reinicializações.
Escrito em uma G-L40S: quarenta e oito gigabytes de VRAM em uma única placa, passada para a instância via PCIe em vez de fatiada por tempo entre locatários. Essa distinção é a diferença entre latência previsível e esperar atrás do job de treinamento de outra pessoa. A placa é sua até você cancelar.
Antes de começar
- Uma G-L40S com Debian 13. A G-ADA com vinte gigabytes funciona para modelos menores; a aritmética no passo quatro diz quais.
- Dois terabytes de NVMe neste plano, que é o lugar certo para pesos. Baixar quarenta gigabytes duas vezes porque o cache estava no filesystem raiz é um jeito irritante de gastar uma hora.
- Um hostname apontando para a instância,
llm.example.comabaixo.
1. Driver
sed -i "s/ main$/ main contrib non-free-firmware non-free/" /etc/apt/sources.list.d/debian.sources
apt update
apt install -y nvidia-driver firmware-misc-nonfree build-essential
rebootDepois que ele voltar:
nvidia-smiVocê quer a placa listada, a versão do driver impressa e o uso de memória perto de zero. Uma placa ausente neste ponto é quase sempre um initramfs desatualizado; update-initramfs -u e reinicie mais uma vez antes de abrir um ticket.
nvidia-smi -q -d PERFORMANCE | grep -A3 "Clocks Event Reasons"
nvidia-smi -pm 1O modo de persistência mantém o driver carregado entre processos, o que remove vários segundos de inicialização de cada reinício.
2. Runtime
apt install -y python3-venv python3-pip
install -d -o root -g root /srv/models /opt/vllm
python3 -m venv /opt/vllm/venv
/opt/vllm/venv/bin/pip install --upgrade pip
/opt/vllm/venv/bin/pip install vllmA instalação puxa um grande conjunto de wheels ligados a CUDA e leva um tempo. Enquanto isso, decida sobre um modelo.
3. Escolhendo o que cabe
Os pesos são o piso, não o orçamento. Um modelo em precisão de dezesseis bits precisa de aproximadamente dois gigabytes de VRAM por bilhão de parâmetros, mais o cache de chave-valor para cada requisição concorrente, mais um gigabyte ou mais de overhead de runtime.
| Placa | Pesos em 16 bits | Tamanho realista de modelo | Sobra para cache |
|---|---|---|---|
| L40S, 48 GB | 2 GB por bilhão | Até cerca de 20 bilhões | 6 a 8 GB |
| L40S, 48 GB, 8 bits | 1 GB por bilhão | Até cerca de 34 bilhões | 10 GB |
| RTX 4000 Ada, 20 GB | 2 GB por bilhão | Até cerca de 7 bilhões | 5 GB |
| Duas × L40S, 96 GB | 2 GB por bilhão | Até cerca de 40 bilhões | 12 GB |
A coluna de cache é o que determina quantas pessoas podem usar o endpoint de uma vez. Encha a placa até a borda com pesos e você construiu um brinquedo de usuário único muito rápido.
4. Servindo
Aponte o cache para o NVMe e inicie o servidor. Substitua o identificador do repositório do modelo de pesos abertos que você escolheu; o runtime o busca no primeiro início.
cat > /etc/systemd/system/vllm.service <<EOF
[Unit]
Description=vLLM inference server
After=network-online.target
[Service]
Environment=HF_HOME=/srv/models
Environment=VLLM_API_KEY=<a long random string>
ExecStart=/opt/vllm/venv/bin/vllm serve <org>/<model> \\
--host 127.0.0.1 --port 8000 \\
--served-model-name local \\
--max-model-len 16384 \\
--gpu-memory-utilization 0.92 \\
--max-num-seqs 32
Restart=on-failure
RestartSec=10
TimeoutStartSec=1800
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable --now vllm
journalctl -fu vllmVincular ao loopback é proposital. A verificação de chave de API no runtime é um único segredo compartilhado sem rate limiting por trás, então o nginx faz a exposição e o runtime nunca toca a interface pública.
O timeout generoso de início existe porque o primeiro lançamento baixa dezenas de gigabytes e então compila kernels. Inícios subsequentes levam menos de um minuto.
5. Proxy e TLS
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name llm.example.com;
ssl_certificate /etc/letsencrypt/live/llm.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/llm.example.com/privkey.pem;
location /v1/ {
proxy_pass http://127.0.0.1:8000;
proxy_buffering off;
proxy_read_timeout 600s;
proxy_set_header Host $host;
}
}proxy_buffering off é a linha que faz respostas de streaming fluir. Deixe-a ligada e tokens chegam em lotes educados sempre que o nginx sente que um buffer está cheio, o que parece exatamente um modelo lento e não é.
Verifique
Comece com a placa:
nvidia-smi --query-gpu=memory.used,memory.total,utilization.gpu --format=csvA memória usada deve estar em torno de noventa por cento do total, porque é o que --gpu-memory-utilization pediu. Depois o endpoint:
curl -s https://llm.example.com/v1/models -H "Authorization: Bearer <the key>" | head -20Um modelo, chamado local. Agora uma conclusão real, e cronometre-a:
time curl -s https://llm.example.com/v1/chat/completions \
-H "Authorization: Bearer <the key>" \
-H "Content-Type: application/json" \
-d '{"model":"local","messages":[{"role":"user","content":"List three prime numbers."}],"max_tokens":64}'Finalmente, meça sob carga em vez de uma requisição por vez, que é o único número que vale citar:
/opt/vllm/venv/bin/vllm bench serve \
--backend openai-chat \
--base-url https://llm.example.com \
--endpoint /v1/chat/completions \
--model local --num-prompts 200 --request-rate 8Leia três números da saída: tokens de saída por segundo em agregado, mediana do tempo até o primeiro token e o percentil noventa e nove de ponta a ponta. Em uma única L40S com um modelo na faixa de dez a vinte bilhões, a produção agregada na casa das centenas de tokens por segundo e um tempo até o primeiro token bem abaixo de um segundo é a forma esperada. Tempo até o primeiro token que sobe com a concorrência significa que seu cache de chave-valor é pequeno demais, então diminua --max-model-len ou --max-num-seqs e rode novamente.
Depois
Monitore a temperatura e o throttling de clock durante a primeira semana com nvidia-smi dmon, já que uma placa que sofre throttling térmico sob carga sustentada produz exatamente o tipo de lentidão intermitente que é culpada pela rede. Em termos de fatura, lembre-se de que uma instância de GPU custa o mesmo esteja a placa ocupada ou ociosa, então faça trabalhos em lote em vez de deixá-la quente. Os preços estão em a página de GPU.