Seu notebook tem 16 GB de RAM e uma GPU que não roda o modelo que você precisa testar. Instalar CUDA na máquina local quebrou o driver duas vezes. E o time inteiro tem ambiente diferente, então "na minha máquina funciona" virou piada interna.

A saída é parar de tratar a GPU na nuvem como um lugar onde você manda um job e passar a tratá-la como a sua máquina de desenvolvimento: você abre o VS Code e ele está lá, com o terminal, o depurador, as extensões e a placa de vídeo. O código fica no servidor; a interface fica no seu notebook.

⚡ Resumo

VS Code Remote-SSH + uma instância com GPU = ambiente de desenvolvimento completo com CUDA, sem tocar no seu sistema. Uma RTX A4000 (16 GB) sai por R$ 1,07/h na linha Econômica — R$ 8,56 por um dia inteiro de trabalho. Você desliga no fim do expediente.

Quando isso vale a pena

Quando não vale: desenvolvimento que não usa GPU nenhuma. Para isso, uma instância de CPU custa uma fração do preço e resolve igual.

Passo 1: a chave SSH

Se você ainda não tem uma, gere. E gere uma específica para isto — chave reaproveitada de outro serviço é dor de cabeça no dia da rotação.

ssh-keygen -t ed25519 -C "dev-gpu" -f ~/.ssh/gpu_dev
cat ~/.ssh/gpu_dev.pub          # esta é a que você cola no painel

No painel, em Chaves SSH, cole a chave pública (a que termina em .pub). Ela é injetada na máquina no momento da criação — chave adicionada depois não entra numa instância que já existe.

Passo 2: subir a instância certa

Para desenvolvimento, o critério é diferente de treino: você quer VRAM suficiente e custo baixo, porque a máquina vai passar boa parte do tempo com você lendo código, não computando.

GPUVRAMPreço/hDia de trabalho (8 h)Cabe o quê
RTX A400016 GBR$ 1,07R$ 8,56Modelos até 7B, visão, protótipo
RTX 309024 GBR$ 1,27R$ 10,16Até 13B, melhor custo por GB
RTX 409024 GBR$ 2,38R$ 19,04Igual à 3090, bem mais rápida
RTX 509032 GBR$ 4,77R$ 38,16Modelos maiores, geração atual
RTX PRO 600096 GBR$ 10,73R$ 85,84Modelo grande em uma placa só

Comece pequeno. A troca de instância leva minutos e você não perde nada se o código estiver no Git — que é justamente o ponto da próxima seção.

⚠️ Escolha o disco na criação, não depois

Ambiente de desenvolvimento enche disco rápido: pesos de modelo, imagens de contêiner, cache do pip. Peça pelo menos 100 GB. Aumentar disco depois não é uma operação trivial, e ficar sem espaço no meio de um download de 40 GB é a forma mais irritante de perder uma tarde.

Passo 3: conectar

Assim que a instância fica pronta, o painel mostra o usuário, o IP e a porta. Três detalhes que economizam sua manhã:

ssh -i ~/.ssh/gpu_dev -p PORTA USUARIO@IP

Funcionou? Grave no ~/.ssh/config e nunca mais digite isso:

Host gpu
    HostName 203.0.113.45
    User root
    Port 40123
    IdentityFile ~/.ssh/gpu_dev
    ServerAliveInterval 30
    ServerAliveCountMax 6
    StrictHostKeyChecking accept-new

Agora ssh gpu basta. O ServerAliveInterval não é enfeite: sem ele, a conexão cai sozinha quando você fica alguns minutos sem digitar, e o VS Code passa a vida reconectando.

Passo 4: VS Code de verdade, rodando lá

  1. Instale a extensão Remote - SSH (Microsoft).
  2. F1Remote-SSH: Connect to Hostgpu.
  3. A primeira conexão instala o servidor do VS Code na máquina remota. Leva um minuto.
  4. Abra a pasta do projeto. Terminal, depurador, extensões e Copilot passam a rodar no servidor.

É a diferença entre editar arquivo remoto e ter um ambiente remoto: python train.py no terminal integrado roda na GPU, e o depurador para no breakpoint com a placa carregada.

Confirme que a GPU está mesmo lá

nvidia-smi
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"

Se nvidia-smi responde mas o PyTorch diz False, é quase sempre versão de CUDA incompatível com a do PyTorch instalado — reinstale o PyTorch para a versão de CUDA que a máquina reporta, não o contrário.

Passo 5: as portas — Jupyter, TensorBoard, sua API

Não abra porta no firewall para ver um Jupyter. Use túnel SSH: o serviço fica ouvindo só em localhost na máquina remota, e aparece no seu navegador como se fosse local.

# no seu notebook
ssh -N -L 8888:localhost:8888 -L 6006:localhost:6006 -L 8000:localhost:8000 gpu

Agora localhost:8888 é o Jupyter remoto, 6006 é o TensorBoard e 8000 é a API que você está escrevendo. Nada disso está exposto na internet.

No VS Code é ainda mais simples: quando um processo abre uma porta no servidor, ele detecta e encaminha sozinho — a aba Ports mostra o que está publicado.

💡 Prefere Jupyter sem configurar nada?

O template JupyterLab CUDA sobe em 1 clique com o ambiente já montado. Serve bem para experimentação; para escrever software de verdade, o VS Code Remote continua sendo melhor — você tem Git, depurador e refatoração.

Passo 6: sobreviver à desconexão

Este é o erro que todo mundo comete uma vez. Você inicia um treino de 6 horas pelo terminal, o Wi-Fi oscila, a sessão SSH morre — e o processo morre junto. Seis horas perdidas.

Rode qualquer coisa longa dentro do tmux:

tmux new -s treino        # cria a sessão
python train.py           # roda dentro dela
# Ctrl+B, depois D        → desanexa (o processo continua)

tmux attach -t treino     # volta, de qualquer lugar
tmux ls                   # lista o que está rodando

Com o tmux, fechar o notebook é irrelevante. A sessão vive na máquina remota até ela ser desligada.

Passo 7: não perder o trabalho

⚠️ A instância é descartável. O seu código não pode ser.

Trate a máquina como gado, não como bicho de estimação. Antes de desligar qualquer coisa: git push. Se tem artefato grande que não vai para o Git (pesos, dataset), copie para fora ou para um armazenamento externo.

Um fluxo que funciona bem:

# trazer resultados para o notebook
rsync -avz --progress gpu:/workspace/saidas/ ./saidas/

# levar um dataset local para o servidor
rsync -avz --progress ./dados/ gpu:/workspace/dados/

Bootstrap: a máquina montada em um comando

Guarde este arquivo no repositório. Ele é o que torna o ambiente reproduzível para o time inteiro:

#!/usr/bin/env bash
# bootstrap.sh — roda uma vez em cada instância nova
set -euo pipefail

apt-get update -qq && apt-get install -y -qq git tmux htop rsync build-essential

git config --global user.name  "Seu Nome"
git config --global user.email "voce@empresa.com"

python -m venv /workspace/.venv
source /workspace/.venv/bin/activate
pip install -U pip wheel
pip install -r /workspace/projeto/requirements.txt

cat >> ~/.bashrc <<'EOF'
source /workspace/.venv/bin/activate
cd /workspace/projeto
alias gpu='watch -n1 nvidia-smi'
EOF

echo "pronto. 'tmux new -s dev' para começar."

Instância nova: git clone, bash bootstrap.sh, e você está trabalhando em três minutos.

Passo 8: a disciplina de custo

Aqui mora a diferença entre R$ 200 e R$ 1.700 por mês. A cobrança é por hora ligada, não por trabalho feito — GPU parada aquecendo o datacenter custa igual a GPU treinando.

HábitoRTX 4090 · custo/mês
Deixa ligada 24×7 "porque dá trabalho subir"R$ 1.737
Liga no expediente, desliga à noite (10 h/dia útil)R$ 523
Liga só quando precisa de GPU (4 h/dia útil)R$ 209

Três regras que resolvem:

Dois ambientes que valem montar

Desenvolvimento com LLM local

Se o que você está escrevendo consome um LLM, tem duas opções e elas não competem:

BASE_URL = os.getenv("LLM_BASE_URL", "https://gpubrasil.com.br/v1")
API_KEY  = os.getenv("LLM_API_KEY",  os.getenv("GPUBRASIL_API_KEY"))
cliente  = OpenAI(base_url=BASE_URL, api_key=API_KEY)

# local:  LLM_BASE_URL=http://localhost:8000/v1 LLM_API_KEY=nao-importa python app.py
# nuvem:  python app.py

Contêineres, se o seu projeto usa

Em instância de máquina virtual você tem Docker e pode usar --gpus all normalmente. Em instância de contêiner, você já está num contêiner — nesse caso instale as dependências direto, sem tentar Docker dentro de Docker. O tipo aparece no card da instância.

Sua máquina de desenvolvimento com GPU, por hora

A partir de R$ 1,07/h, cobrada em reais, sem assinatura e com suporte em português. Suba, trabalhe, desligue.

Criar conta →

Problemas comuns e a causa real

SintomaCausa quase sempre
Permission denied (publickey)Usuário errado (root × ubuntu) ou chave cadastrada depois de criar a máquina
Connection timed outPorta errada — copie a do card, não presuma 22
VS Code fica "reconnecting"Falta ServerAliveInterval no ~/.ssh/config
torch.cuda.is_available() = FalsePyTorch compilado para outra versão de CUDA
Processo morre ao fechar o notebookNão estava dentro do tmux
No space left on deviceCache do pip e imagens antigas: pip cache purge, docker system prune -a
Conta maior que o esperadoMáquina ligada no fim de semana

Conclusão

Desenvolvimento remoto com GPU deixou de ser gambiarra: com Remote-SSH, tmux e um bootstrap versionado, o ambiente é melhor que o local — mais potente, reproduzível e descartável quando quebra.

O que faz a diferença entre economia e desperdício não é técnico, é hábito: código no Git, ambiente em script, máquina desligada quando você não está usando. Com isso, um ambiente com GPU de verdade custa menos que um almoço por dia de trabalho.

Continue: um copiloto de código para o time · JupyterLab em 1 clique · servir o seu modelo com vLLM