A conta de GPU que assusta raramente vem de escolher a placa errada. Vem de deixar a placa certa ligada.

Uma RTX 4090 a R$ 2,78 por hora custa cerca de R$ 2.000 por mês ligada o tempo todo, e R$ 170 se ligar duas horas por dia. É a mesma máquina, o mesmo trabalho entregue — a diferença é só quem lembrou de desligar.

Separe o que precisa estar ligado do que não precisa

A pergunta que resolve: alguém está esperando na frente da tela?

CargaPrecisa responder emFormato certo
Chat, autocompletar, busca do usuárioSegundosServiço ligado — ou API por token
Relatório noturno, resumo do diaHorasLote
Indexar acervo, gerar catálogo, transcrever gravaçõesHoras ou diasLote
Treinar ou ajustar modeloQuando terminarLote
Processar arquivo que o usuário enviouMinutosFila com máquina que acorda

Na maioria das empresas, a maior parte da carga de GPU é da metade de baixo dessa tabela — e está rodando numa máquina ligada o tempo todo porque foi assim que começou.

O padrão: subir, processar, desligar

A forma mais confiável de garantir que a máquina desligue é a máquina desligar a si mesma quando acabar. Não depender de ninguém lembrar, nem de um alarme.

#!/usr/bin/env bash
set -euo pipefail

LOG=/var/log/lote.log
exec >> "$LOG" 2>&1

encerrar() {
    codigo=$?
    echo "[$(date -Is)] terminando com código $codigo"
    curl -s -X POST "$WEBHOOK" -H 'content-type: application/json' \
         -d "{\"status\": $codigo, \"host\": \"$(hostname)\"}" || true
    sleep 10
    sudo shutdown -h now          # desliga aconteça o que acontecer
}
trap encerrar EXIT               # <-- a linha que salva a fatura

echo "[$(date -Is)] iniciando"
python3 /opt/trabalho/processar.py --entrada /dados/fila --saida /dados/pronto
echo "[$(date -Is)] processamento concluído"
✅ A linha que importa é o trap

Com trap ... EXIT, o desligamento acontece se o script terminar bem, se falhar, se o Python estourar exceção ou se alguém matar o processo. Sem ele, um erro na terceira linha deixa a máquina ligada o fim de semana inteiro.

Já vimos conta de mais de mil reais causada por um ImportError numa sexta-feira à noite.

Torne o trabalho retomável

Máquina que desliga sozinha combina mal com processo que precisa começar do zero. Três regras que resolvem:

from pathlib import Path

PRONTO = Path("/dados/pronto")

for item in fila:
    destino = PRONTO / f"{item.id}.json"
    if destino.exists():
        continue
    try:
        resultado = processar(item)
        tmp = destino.with_suffix(".tmp")
        tmp.write_text(resultado, encoding="utf-8")
        tmp.rename(destino)          # troca atômica: nunca meio-arquivo
    except Exception as e:
        (PRONTO / f"{item.id}.erro").write_text(str(e), encoding="utf-8")

O rename depois de escrever num arquivo temporário é o detalhe que evita a pior situação: um arquivo pela metade que o processo seguinte vai considerar pronto.

Dimensionar pelo tempo total, não pela velocidade

Em trabalho de lote, a pergunta certa é quanto custa terminar, não quanto custa a hora. E a resposta muda a escolha da placa.

PlacaPreço/horaTempo do trabalhoCusto total
RTX 4090R$ 2,7810 hR$ 27,80
L40SR$ 7,084,5 hR$ 31,86
A100 80 GBR$ 11,053 hR$ 33,15

Preços de agosto de 2026, para uma GPU avulsa, sem interrupção programada. O catálogo muda: confira a vitrine antes de fechar a conta.

Custos praticamente iguais, tempos muito diferentes. Se ninguém está esperando, pegue a mais barata; se o resultado precisa estar pronto às 7h, pague os R$ 5 a mais e durma tranquilo. A placa cara não é desperdício em lote — desde que ela desligue no fim.

A exceção é quando o modelo não cabe na placa pequena: aí não há escolha, e forçar a barra com descarregamento para a memória do sistema deixa o trabalho tão lento que a placa barata sai mais cara no total.

⚠️ Cuidado com o que não escala em paralelo

Nem toda carga acelera com placa maior. Transcrição de áudio, por exemplo, tem gargalo em decodificação e leitura de arquivo — uma placa três vezes mais cara entrega menos de 40% de ganho.

Meça com uma amostra pequena nas duas placas antes de comprometer o lote inteiro. Meia hora de teste evita escolher a opção errada por dez horas.

Fila com máquina que acorda

Para carga irregular — o usuário envia um arquivo e espera minutos, não horas — o padrão é uma fila com disparo:

  1. O pedido entra numa fila persistente (banco, arquivo, serviço de fila).
  2. Um verificador roda a cada poucos minutos numa máquina barata, sem GPU.
  3. Se houver itens pendentes acima de um mínimo, ele cria a instância com GPU pela API.
  4. A instância processa tudo que estiver na fila, avisa por webhook e se desliga.

Dois parâmetros definem a economia: o mínimo para acordar (subir máquina para um item só raramente compensa) e o tempo de espera antes de desligar depois de esvaziar a fila — cinco a dez minutos evitam o ciclo de ligar e desligar seguidamente quando os pedidos chegam espaçados.

O que checar antes de dormir tranquilo

Pague pelo trabalho, não pelo mês

Suba a máquina, rode a fila e desligue. A cobrança é por hora, em reais, e a instância parada não gasta como a ligada.

Criar conta →

Conclusão

Metade da economia em GPU não vem de escolher melhor a placa — vem de reconhecer que a maior parte do seu trabalho não precisa de ninguém esperando. Transforme em fila, escreva o script para ser retomável, ponha o trap de desligamento e meça o custo por trabalho concluído, não por hora.

A pergunta para levar para a próxima reunião: quantas horas de GPU nós pagamos no mês passado e quantas delas tiveram alguém do outro lado?

Continue: transcrição em lote · imagens em lote · quando precisa ficar ligado