2,89 tokens por segundo numa RTX 5090: um diagnóstico de LLM local
POC técnica: por que um modelo de 72B rodou na velocidade de CPU numa GPU topo de linha, e como medir a causa real.
⚠️ CONTEÚDO DE DEMONSTRAÇÃO — POC derivada de um episódio real (relatado num grupo em maio). Números do episódio preservados; reproduza os comandos no seu hardware antes de tirar conclusões.
Cena real, maio: uma RTX 5090 topo de linha, um Qwen de 72B carregado no LM Studio, e uma velocidade de geração de 2,89 tokens/segundo. GPU a 6% de uso, RAM a 96%. Na prática: a placa mais rápida do mercado rodando na velocidade de um notebook sem GPU.
O diagnóstico que o grupo fez em meia hora de chat vale um artigo. Vou reconstituir com os comandos.
Passo 1: confirmar que a GPU não está fazendo o trabalho
# uso de GPU em tempo real enquanto o modelo gera
nvidia-smi -l 1
# procure por: GPU-Util (percentual de compute) e Memory-Used
# no episódio: GPU-Util ~6%, RAM do sistema ~96%Se GPU-Util fica baixo e a RAM do sistema sobe junto, não é mistério: as camadas do modelo não couberam na VRAM e o runtime fez offload pra RAM. A GPU passa o tempo esperando dados vir pelo barramento, que é mais lento que a memória dela.
Passo 2: fazer a conta de VRAM antes de culpar o driver
Um modelo de 72B parâmetros em FP16 pesa, só de pesos:
pesos = 72e9 * 2 # 2 bytes por parâmetro em fp16
print(f"{pesos/1e9:.0f} GB só de pesos")
# 144 GB144 GB de pesos não cabem em 32 GB de VRAM. Sem quantização, o destino é offload. A regra prática: peso do modelo em GB ≈ parâmetros × bytes por peso, e some por cima o KV cache (que cresce com o contexto) antes de comparar com a VRAM livre.
Passo 3: escolher um modelo que caiba
No episódio, a troca foi pra um 27B quantizado (Q4_K_M ≈ 4.5 bits por peso):
pesos_27b_q4 = 27e9 * 4.5 / 8 # bits -> bytes
print(f"{pesos_27b_q4/1e9:.1f} GB")
# ~15 GB — cabe em 32 GB de VRAM com folga pro KV cacheCom o modelo cabendo inteiro na VRAM e o KV cache também configurado pra GPU, a mesma máquina saiu de 2,89 pra ~7 tokens/s e a GPU passou a trabalhar de verdade (utilização subiu, fallback pra CPU sumiu).
Passo 4: quando mesmo assim estiver lento
Se o modelo cabe e a velocidade ainda estiver abaixo do esperado, os suspeitos usuais, em ordem:
- Runtime: trocar LM Studio por
llama.cpppuro ou vLLM elimina camadas de overhead (no episódio, a troca de runtime fez parte da correção) - Quantização: cada step de quantização perde um pouco de qualidade mas ganha velocidade e memória
- Driver: em Linux, o driver proprietário da NVIDIA (não o nouveau/Nouveau Studio no Windows) é o caminho pra CUDA usar a placa inteira
- Expectativa: uma 3090 bem configurada chega a 85 tokens/s num 27B; se a sua está 10× abaixo disso, o gargalo é configuração, não hardware
O custo escondido
Rodar LLM local tem uma fatura que ninguém mostra no anúncio da placa: energia. No TDP de pico, uma 5090 (~575 W) rodando 24/7 beira 414 kWh/mês — na tarifa de R$ 0,60/kWh, uns R$ 248/mês de luz. Parada, o consumo cai pra ~20 W, o que torna o carregamento sob demanda (acceptando um tempo maior pro primeiro token) uma decisão econômica, não só técnica.
O resumo que fica: LLM local não é sobre ter a melhor GPU, é sobre casar o modelo com a memória que você tem. A conta de bytes por parâmetro é de primária e evita uma tarde de chat de grupo diagnosticando por que a placa mais rápida do mercado está renderizando devagar.