🖧 OpenLLM-router(vastAI) Privacidade e Economia com LLMs: Como Rodar GPUs Alugadas por Centavos com Túnel Reverso e Watchdog em Go - Ollama - Seleção de tokens/s - Sem limites
Se você trabalha com inteligência artificial, agentes autônomos ou pipelines de dados, sabe que o maior gargalo atual é o custo linear por token de APIs centralizadas e a falta de controle sobre a privacidade dos dados.
Enviar informações confidenciais de clientes para intermediários ou servidores externos pode violar políticas de compliance (como LGPD/GDPR). Por outro lado, rodar localmente exige hardware potente e caro, limitando o uso a modelos pequenos (7B, 8B).
Alugar GPUs dedicadas sob demanda (como no Vast.ai, RunPod ou Lambda Labs) oferece a melhor relação preço/performance do mercado. Uma RTX 4090 custa cerca de $0.30/hora e entrega 122 tokens/s no DeepSeek-R1 7B. Mas gerenciar isso traz três problemas de infraestrutura:
- Segurança e Privacidade: Como expor o Ollama remoto sem abrir portas públicas na máquina alugada?
- Desperdício Financeiro: Se você esquecer a máquina alugada ligada após terminar os testes, ela continuará cobrando.
- Setup DevOps: Toda vez que aluga, precisa instalar drivers, Ollama, baixar o modelo e configurar tudo de novo.
Para resolver isso, criamos o openllm (um ecossistema open-source em Go) e detalhamos aqui os aprendizados de engenharia de redes e custos.
🛠️ A Arquitetura do Sistema e Fluxo de Execução
O sistema é dividido em três binários escritos em Go:
openllm(CLI): Usado para buscar ofertas de GPU em tempo real, calcular o TPS estimado e fazer deploy.openllmd(Daemon Local): Roda em background na máquina do desenvolvedor, gerencia o banco de sessões SQLite, mantém os túneis SSH e expõe um proxy compatível com Ollama/OpenAI em:11434.openllm-watchdog(Remote Helper): Um utilitário de 8MB enviado para a máquina remota que atua como um botão de autodestruição físico em caso de queda de rede ou esquecimento.
O Fluxo Passo a Passo:
- A CLI solicita um deploy automático ao Daemon Local.
- O Daemon aluga a máquina mais barata via API do provedor (Vast.ai) e aguarda o SSH estar pronto.
- O Daemon conecta via SSH, prepara o ambiente, instala o Ollama e copia o binário do Watchdog para a máquina remota.
- O Daemon abre o Túnel SSH Direto (
-L) para trazer a porta:11434(Ollama remoto) de volta para o localhost de forma segura. - O Daemon abre o Túnel SSH Reverso (
-R) para que o Watchdog possa enviar pings para a porta:17291local sem precisar de IP público exposto. - Se o Watchdog detectar falha de comunicação persistente (padrão 5 min), ele dispara um comando direto para o provedor solicitando a destruição imediata da própria máquina alugada.
graph TD
subgraph Local ["Seu Computador (Local)"]
CLI[openllm CLI] -->|Control API :17290| Daemon[openllmd daemon]
App["Seu App / Cursor / n8n"] -->|Ollama Proxy :11434| Daemon
Daemon -->|Heartbeat Server :17291| HBS[Heartbeat Listener]
end
subgraph Nuvem ["GPU Alugada (Nuvem / Vast.ai)"]
Ollama[Ollama Server :11434]
WD[openllm-watchdog]
end
Daemon -->|Túnel SSH Direto -L| Ollama
WD -->|Túnel SSH Reverso -R| HBS
💻 Implementando Túneis SSH Programaticamente em Go
Uma das partes mais interessantes do projeto foi implementar a multiplexação de rede utilizando a biblioteca golang.org/x/crypto/ssh. Em vez de subir um processo ssh -L ou ssh -R no shell (que é difícil de monitorar e fechar de forma graciosa), criamos os túneis nativamente.
Aqui está um trecho simplificado de como o Túnel Reverso é estabelecido em Go, utilizando cópia bidirecional assíncrona:
// StartReverseTunnel escuta na porta remota (ex: localhost:17291)
// e repassa as conexões para o listener local (nosso Heartbeat Server)
func (s *SSHClient) StartReverseTunnel(ctx context.Context, remoteAddr, localAddr string) error {
// 1. Escuta na porta interna do host remoto usando a conexão SSH ativa
listener, err := s.client.Listen("tcp", remoteAddr)
if err != nil {
return fmt.Errorf("failed to listen on remote: %w", err)
}
go func() {
defer listener.Close()
// Fecha o listener remoto se o contexto local for cancelado
go func() {
<-ctx.Done()
listener.Close()
}()
for {
remoteConn, err := listener.Accept()
if err != nil {
return // Conexão encerrada pelo cancelamento do contexto
}
// Para cada conexão aceita na máquina remota, abrimos um dial local
go func(remote net.Conn) {
defer remote.Close()
localConn, err := net.Dial("tcp", localAddr)
if err != nil {
return
}
defer localConn.Close()
// Copia bidirecional transparente e encriptada entre local e remoto
errChan := make(chan error, 2)
go func() {
_, err := io.Copy(localConn, remote)
errChan <- err
}()
go func() {
_, err := io.Copy(remote, localConn)
errChan <- err
}()
<-errChan // Aguarda o fim da transmissão de dados
}(remoteConn)
}
}()
return nil
}
🚀 Testando na Prática (Com Outputs do Terminal)
Veja como o ecossistema funciona na prática através do terminal, desde a pesquisa dinâmica até a chamada de inferência final rodando a 122 tokens/s.
1. Inicializando o Projeto
Ao rodar o comando de inicialização, ele monta o banco SQLite interno de controle e cria um arquivo de configurações openllm.json estruturado por provedores:
$ ./openllm init
----------------------------------------------------------------------
SUCCESS: Initialized state folder .openllm/ and template 'openllm.json'
Please configure your API Key in 'openllm.json' and run:
openllm deploy
----------------------------------------------------------------------
2. Pesquisando GPUs Ativas com Estimativa de TPS
O sistema calcula automaticamente a VRAM mínima necessária para o modelo e estima a velocidade (tokens/s) de cada oferta em tempo real, baseando-se nos benchmarks das GPUs disponíveis:
$ ./openllm search --model deepseek-r1:7b --tps 100
🔍 Searching GPUs for deepseek-r1:7b (VRAM target: 5.5 GB, TPS target: 100)
Min specifications required per instance: VRAM: 5.5 GB | GPUs: 1
+----------+-----------+-------+------------+-------------+-----------+------------------+
| ID | GPU MODEL | COUNT | VRAM (GPU) | EST TPS | COST/HOUR | LOCATION |
+----------+-----------+-------+------------+-------------+-----------+------------------+
| 44566376 | RTX 4090 | 1 | 24.0 GB | ✓ 120.0 t/s | $0.283/h | Guangdong, CN |
| 40232086 | RTX 4090 | 1 | 48.0 GB | ✓ 120.0 t/s | $0.607/h | California, US |
| 34227702 | A100 PCIE | 1 | 80.0 GB | ✓ 192.0 t/s | $1.001/h | Virginia, US |
+----------+-----------+-------+------------+-------------+-----------+------------------+
Summary: Found 3 matching offers
Price Range: $0.283/h (min) — $1.001/h (max)
To rent a machine, run: openllm deploy --machine-id <ID> --model deepseek-r1:7b
3. Executando o Deploy Automático
O Daemon conecta via SSH, executa os scripts de instalação de dependências e do Ollama, configura as chaves SSH e atrela o watchdog. O túnel é aberto e fica pronto para uso na porta :11434 local:
$ ./openllm deploy --machine-id 44566376
Contacting openllmd daemon at http://127.0.0.1:17290...
✓ Deployment started in background! Instance ID: 45292076
Monitoring deployment status...
🚀 SUCCESS: Instance is fully deployed and active!
Ollama is available locally on: http://localhost:11434
Instance SSH target: ssh4.vast.ai:12076
Watchdog heartbeat is active. Keep this daemon running to maintain the tunnels.
4. Testando a Inferência (Retorno com Métricas de GPU)
Com a porta local :11434 roteando encriptada diretamente para a RTX 4090 dedicada, você consome a API de forma idêntica a um Ollama local.
Aqui está o retorno de uma chamada de geração real (não-streaming):
$ curl -s http://localhost:11434/api/generate -d '{"model":"deepseek-r1:7b","prompt":"Say hello.","stream":false}' | python3 -m json.tool
{
"model": "deepseek-r1:7b",
"created_at": "2026-07-19T07:40:39.123456Z",
"response": "Hello! How can I assist you today? 😊",
"done": true,
"done_reason": "stop",
"eval_count": 16,
"eval_duration": 131147000
}
- Tokens gerados: 16 tokens
- Tempo de geração (eval_duration): 131ms (0.13 segundos)
- Velocidade real obtida: 122 tokens por segundo (16 tokens / 0.131s)
- Segurança: Seu prompt trafegou por um canal SSH criptografado e foi executado em memória exclusiva na nuvem, sem passar por intermediários.
📊 A Economia Real das GPUs Dedicadas
Consumir APIs prontas é excelente pela facilidade de setup, mas o custo linear por token rapidamente inviabiliza automações de larga escala ou loops contínuos de agentes.
Como as GPUs modernas suportam continuous batching (processar múltiplos usuários em paralelo na mesma VRAM compartilhando os mesmos pesos de modelo), a eficiência escala com o uso.
Custo Efetivo p/ 1M Tokens vs. Concorrência
Simulação usando uma RTX 3090/4090 (aluguel fixo de $0.30 por hora) rodando o modelo 7B.
| Usuários Concorrentes | Throughput Total da GPU | Tokens Gerados em 1 Hora | Custo Fixo da GPU | Custo Efetivo por 1M Tokens | Custo no OpenRouter | Quem Ganha? |
|---|---|---|---|---|---|---|
| 1 | 70 t/s | 252.000 | $0.30 | $1.19 | $0.10 | 🟢 OpenRouter |
| 5 | 180 t/s | 648.000 | $0.30 | $0.46 | $0.10 | 🟢 OpenRouter |
| 10 | 280 t/s | 1.008.000 | $0.30 | $0.29 | $0.10 | 🟢 OpenRouter |
| 20 | 360 t/s | 1.296.000 | $0.30 | $0.23 | $0.10 | 🟢 OpenRouter |
| 30 | 390 t/s | 1.404.000 | $0.30 | $0.21 | $0.10 | 🟢 OpenRouter |
Custo Mensal Acumulado por Volume
Embora a API seja mais barata para poucas consultas isoladas (pois você não paga a ociosidade do hardware), na escala comercial a GPU dedicada torna-se infinitamente mais viável:
| Volume Mensal de Tokens | Custo no OpenRouter (API) | Custo no Vast.ai (1 GPU dedicada 24/7) | Diferença / Economia |
|---|---|---|---|
| 5 Milhões | $0.50 | $216.00 | Perda de -$215.50 |
| 50 Milhões | $5.00 | $216.00 | Perda de -$211.00 |
| 500 Milhões | $50.00 | $216.00 | Perda de -$166.00 |
| 2,5 Bilhões | $250.00 | $216.00 | Economia de +$34 |
| 10 Bilhões | $1.000.00 | $216.00 | Economia de +$784 |
| 50 Bilhões | $5.000.00 | $216.00 | Economia de +$4.784 |
🔮 Futuro da Plataforma e Código Fonte
O projeto está disponível sob a licença Fair-Code (estilo n8n):
- Permitido: Uso pessoal, acadêmico, estudos e protótipos de forma 100% gratuita.
- Restrito: Comercialização direta do código ou hospedagem comercial como serviço de terceiros (neste caso, entre em contato).
Próximos passos: Planejamos construir uma plataforma gerenciada (SaaS). A ideia é que o usuário conecte sua própria conta de nuvem (BYOK - Bring Your Own Key) e nós gerenciemos de forma transparente os deploys das GPUs, a injeção do watchdog e a segurança de tráfego, cobrando apenas uma pequena porcentagem de corretagem por tempo de máquina.
- Repositório: github.com/MrJc01/crom-openllm-vastai
Como você costuma hospedar e gerenciar seus workloads de IA? Deixe sua experiência ou dúvidas nos comentários!