21. Ajuste fino do SO-ARM com Isaac GR00T
Capítulo 21 do curso para iniciantes em SO-ARM Physical AI — monte o ambiente Isaac-GR00T, ajuste o GR00T N1.5 sobre seu dataset de SO-ARM com a configuração so100_dualcam, e rode a inferência com o servidor GR00T e o cliente de controle SO-100, em estação ou Jetson AGX Thor.
21.1 Escolha sua rota de treinamento
21.1 Escolha sua rota de treinamento
Este capítulo segue a rota Isaac-GR00T do guia oficial de ajuste SO101 da NVIDIA — a mesma receita do tutorial da Seeed SO101 + GR00T no Jetson Thor. Três jeitos de conseguir o compute:
| Rota | Hardware | Notas |
|---|---|---|
| Estação local | Classe RTX 4090 / A6000 (Ampere+, ~25GB VRAM) | O que este capítulo assume |
| NVIDIA Brev na nuvem | Um navegador | Os mesmos comandos num notebook em nuvem; exporte e baixe o checkpoint |
| Sem GPU | — | Pule para o Capítulo 22: a rota sem código do SenseCraft Robotics |
O treinamento ou ajuste do GR00T exige GPU com arquitetura Ampere ou mais nova (ex.: RTX A6000, RTX 4090). V100 (Volta) não é suportado.
21.2 Montar o ambiente
21.2 Montar o ambiente
Crie um ambiente dedicado (separar do lerobot está ótimo):
git clone https://github.com/NVIDIA/Isaac-GR00T
cd Isaac-GR00T
conda create -n gr00t python=3.10
conda activate gr00t
pip install --upgrade setuptools
pip install -e .[base]
pip install --no-build-isolation flash-attn==2.7.1.post4
O flash-attn é a etapa que mais falha — precisa casar com seu build de PyTorch/CUDA. Se a compilação der erro: confira python -c "import torch; print(torch.version.cuda)", instale ninja e packaging antes, e tente de novo.
O modelo fundacional baixa automaticamente do Hugging Face no primeiro uso: nvidia/GR00T-N1.5-3B.
21.3 Ajuste fino sobre seu dataset de SO-ARM
21.3 Ajuste fino sobre seu dataset de SO-ARM
Com o dataset do Capítulo 20 pronto (aqui ./demo_data/so101-table-cleanup/ — troque pelo seu caminho):
python scripts/gr00t_finetune.py \
--dataset-path ./demo_data/so101-table-cleanup/ \
--num-gpus 1 \
--output-dir ./so101-checkpoints \
--max-steps 10000 \
--data-config so100_dualcam \
--video-backend torchvision_av
Parâmetros-chave:
--dataset-path: sua pasta LeRobot (a do Capítulo 20);--data-config so100_dualcam: a configuração padrão de duas câmeras do SO-ARM;--max-steps: 10.000 é um primeiro ponto sólido para ~50 episódios;--video-backend torchvision_av: backend de decodificação de vídeo;- Para ajustar a partir de um modelo base salvo localmente, some
--base-model-path ./pretrained/GR00T-N1.5-3B.
O ajuste padrão exige ~25GB de VRAM. Se não tiver, acrescente --no-tune_diffusion_model — congela a cabeça DiT e treina menos, mas cabe em placas menores.
Monitore a perda como no Capítulo 15; espere um tempo por passo bem maior que o ACT — o modelo tem ~3 bilhões de parâmetros.
Exportar de um notebook em nuvem (rota Brev)
A barra lateral do Jupyter não navega dentro das pastas de treino. Compacte o checkpoint em .zip ou .tar.gz primeiro e baixe o arquivo pela interface do notebook.
21.4 Rodar a inferência: servidor + cliente de controle
21.4 Rodar a inferência: servidor + cliente de controle
A inferência move o braço real sem humano no ciclo. Limpe o espaço, afaste as mãos e mantenha a mão pronta para cortar a energia.
Para o melhor desempenho, replique o setup da coleta o mais fielmente possível — mesmas câmeras, mesmas posições, mesma luz. A generalização do modelo é limitada.
Terminal 1 — ligue o serviço de inferência GR00T:
python scripts/inference_service.py --server \
--model_path ./so101-checkpoints \
--embodiment-tag new_embodiment \
--data-config so100_dualcam \
--denoising-steps 4
Terminal 2 — ligue o cliente de controle do robô (o exemplo oficial SO-100, escrito para este braço):
python examples/SO-100/eval_lerobot.py \
--robot.type=so100_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=my_awesome_follower_arm \
--robot.cameras="{ wrist: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, front: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30}}" \
--policy_host=0.0.0.0 \
--lang_instruction="Grab pens and place into pen holder."
Notas:
- Troque
index_or_pathpelos índices das suas câmeras — ache comls /dev/video*oulerobot-find-cameras opencv. Precisam ser as mesmas vistas (frontal + lateral/garras) do dataset. - Troque
--lang_instructionpela frase exata da sua tarefa no dataset — é o condicionamento por linguagem ao vivo (Capítulo 18). - Cliente e servidor podem rodar na mesma máquina, ou o servidor numa máquina com GPU / Jetson Thor da rede.
21.5 Implantação na borda com Jetson AGX Thor
21.5 Implantação na borda com Jetson AGX Thor
O Jetson AGX Thor tem compute suficiente para rodar a inferência do GR00T N1.5 na borda. Todas as dependências vêm numa imagem Docker dedicada:
sudo docker run --rm -it \
--network=host \
-e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video,graphics \
--runtime nvidia \
--privileged \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v /etc/X11:/etc/X11 \
--device /dev/nvhost-vic \
-v /dev:/dev \
<image_name>:<tag>
Dentro do contêiner:
git clone https://github.com/NVIDIA/Isaac-GR00T.git
cd Isaac-GR00T
pip install --upgrade setuptools
pip install -e .[thor]
O ajuste (opcional, se pulou na nuvem) usa o mesmo gr00t_finetune.py de 21.3; depois rode o mesmo par servidor + cliente de 21.4. O percurso completo do Jetson Thor — flash, ambiente, coleta, treino no Brev, implantação — está no tutorial completo: Ajuste o GR00T N1.5 para o LeRobot SO-ARM e implante no Jetson Thor.
21.6 Rota alternativa: a política groot do LeRobot
21.6 Rota alternativa: a política groot do LeRobot
Se preferir ficar na cadeia LeRobot da Fase 3, a política --policy.type=groot também serve (também exige flash-attn e GPU CUDA):
pip install "lerobot[groot]"
accelerate launch \
--num_processes=1 \
$(which lerobot-train) \
--output_dir=outputs/train/groot_so101 \
--save_checkpoint=true \
--batch_size=64 \
--steps=20000 \
--policy.type=groot \
--policy.repo_id=${HF_USER}/groot_so101 \
--dataset.repo_id=seeedstudio123/test \
--wandb.enable=true
As exigências de ambiente são maiores que ACT/Pi0 — o conselho oficial segue: primeiro o ACT ponta a ponta, depois o GR00T. A avaliação usa a receita familiar lerobot-record ... --policy.path do Capítulo 16.
21.7 Avaliação e iteração
21.7 Avaliação e iteração
Reaproveite inteiro o arcabouço do Capítulo 16 — critérios, inícios variados, taxa de sucesso, classificação de falhas — com dois acréscimos próprios de VLA:
- Matriz de instruções: avalie cada frase de tarefa do seu dataset; uma VLA deve trocar de comportamento ao trocar a frase;
- Sonda de instrução não gravada: experimente uma frase que você não gravou — onde acertar é generalização por linguagem; onde falhar é a fronteira de distribuição do Capítulo 18 aparecendo. Responda às falhas com dados, não com esperança.
21.8 FAQ de solução de problemas
21.8 FAQ de solução de problemas
| Problema | Solução |
|---|---|
| Falha/visga na descarga do modelo | Baixe manualmente nvidia/GR00T-N1.5-3B e passe --base-model-path |
Falha ao compilar o flash-attn | Confira o par PyTorch/CUDA; instale ninja + packaging; use a versão fixa 2.7.1.post4 |
| CUDA OOM no ajuste | Some --no-tune_diffusion_model; reduza o batch |
| V100 rejeitada | Esperado — exige Ampere ou mais novo |
| Cliente não alcança o servidor | --policy_host precisa ser o IP acessível do servidor; confira firewall/porta |
| O braço mexe mas ignora a tarefa | Chaves de câmera ou frase divergentes do dataset — regras dos Capítulos 19-20 |