Fazer fine-tuning de modelos de linguagem sempre foi sinônimo de infraestrutura pesada: múltiplas GPUs, configurações distribuídas e horas de debugging. O NVIDIA NeMo AutoModel muda esse jogo ao oferecer uma arquitetura baseada em configuração que escala de uma única GPU no Google Colab até clusters multi-nó — com o mesmo código. Neste tutorial prático, você vai executar um fine-tuning completo do Qwen3-0.6B com LoRA usando apenas uma GPU T4 gratuita do Colab.
Por que isso importa agora?
Até recentemente, fazer fine-tuning de modelos com bilhões de parâmetros exigia hardware de milhares de dólares. Em 2026, o ecossistema de ferramentas como NeMo AutoModel, LoRA e GPUs gratuitas no Colab democratizou o acesso. O que antes era privilégio de empresas com clusters de GPU agora cabe em um notebook Jupyter compartilhado.
Passo 1: Configurando o ambiente Colab
Comece importando as bibliotecas essenciais e definindo a estrutura de diretórios. O NeMo AutoModel precisa ser clonado do repositório oficial e instalado diretamente do código-fonte:
import os, sys, glob, json, subprocess, shutil, textwrap
REPO_DIR = "/content/Automodel"
WORK_DIR = "/content/automodel_demo"
CKPT_DIR = os.path.join(WORK_DIR, "checkpoints")
os.makedirs(WORK_DIR, exist_ok=True)
def sh(cmd, check=True):
print(f"\n$ {cmd}\n" + "-" * 78)
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, text=True, bufsize=1)
for line in p.stdout:
print(line, end="")
p.wait()
if check and p.returncode != 0:
raise RuntimeError(f"Command failed ({p.returncode}): {cmd}")
return p.returncodeA função sh() é um wrapper que executa comandos shell com streaming de saída em tempo real e verificação de erros. Essencial para acompanhar o progresso de instalações longas sem travar o notebook.
Passo 2: Verificando a GPU e instalando o NeMo AutoModel
Antes de instalar, confirme que você tem uma GPU CUDA disponível. No Colab, vá em Runtime → Change runtime type → GPU:
import torch
assert torch.cuda.is_available(), "No GPU found! Runtime -> Change runtime type -> GPU"
GPU_NAME = torch.cuda.get_device_name(0)
BF16_OK = torch.cuda.is_bf16_supported()
VRAM_GB = torch.cuda.get_device_properties(0).total_memory / 1e9
print(f"GPU: {GPU_NAME} | VRAM: {VRAM_GB:.1f} GB | bf16 supported: {BF16_OK}")
# Instalar do repositório oficial
if not os.path.isdir(REPO_DIR):
sh(f"git clone --depth 1 https://github.com/NVIDIA-NeMo/Automodel.git {REPO_DIR}")
sh(f"pip -q install -e {REPO_DIR}")
sh("pip -q install pyyaml peft")A verificação de bfloat16 é crucial: GPUs mais antigas como T4 não suportam bf16 e precisam usar float32. O script se adapta automaticamente a isso.
Passo 3: Carregando e adaptando a receita LoRA
O NeMo AutoModel organiza treinamentos como receitas YAML. Você carrega uma receita oficial de fine-tuning do Qwen3, adapta os parâmetros para uma GPU única e salva a versão personalizada:
import yaml
candidates = sorted(glob.glob(
os.path.join(REPO_DIR, "examples", "llm_finetune", "qwen", "*0p6b*peft*.yaml")
))
BASE_RECIPE = candidates[0]
with open(BASE_RECIPE) as f:
cfg = yaml.safe_load(f)
# Adaptar para GPU única: batch menor, float32 se necessário
def patch(node):
if isinstance(node, dict):
for k, v in list(node.items()):
if isinstance(v, str) and not BF16_OK and v.lower() in ("bf16", "bfloat16"):
node[k] = "float32"
elif k in ("batch_size", "local_batch_size") and isinstance(v, int):
node[k] = min(v, 4)
elif k == "global_batch_size" and isinstance(v, int):
node[k] = min(v, 8)
else:
patch(v)
elif isinstance(node, list):
for item in node:
patch(item)
patch(cfg)
cfg.setdefault("step_scheduler", {})
cfg["step_scheduler"]["max_steps"] = 40
cfg["step_scheduler"]["ckpt_every_steps"] = 40
cfg["step_scheduler"]["num_epochs"] = 1
DEMO_RECIPE = os.path.join(WORK_DIR, "qwen3_0p6b_colab_lora.yaml")
with open(DEMO_RECIPE, "w") as f:
yaml.dump(cfg, f, sort_keys=False)A função patch() percorre recursivamente a configuração YAML reduzindo batch sizes e trocando precisão — o que permite que um treinamento desenhado para múltiplas GPUs rode em uma única T4 com 16 GB de VRAM.
Passo 4: Executando o fine-tuning no HellaSwag
Com a receita pronta, o treinamento é disparado por linha de comando. O dataset HellaSwag é usado para avaliação de raciocínio de senso comum:
env_prefix = "HF_HUB_ENABLE_HF_TRANSFER=0 TOKENIZERS_PARALLELISM=false"
rc = sh(f"cd {WORK_DIR} && {env_prefix} automodel {DEMO_RECIPE}", check=False)
if rc != 0:
sh(f"cd {WORK_DIR} && {env_prefix} automodel finetune llm -c {DEMO_RECIPE}")O fallback para a sintaxe automodel finetune llm garante compatibilidade com versões anteriores do CLI. Em uma T4 do Colab, o treinamento de 40 passos leva aproximadamente 5-10 minutos.
Passo 5: Comparando o modelo base com o fine-tuned
Após o treinamento, carregue o checkpoint LoRA e compare as saídas:
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
DTYPE = torch.bfloat16 if BF16_OK else torch.float32
PROMPT = "A man is sitting on a roof. He starts pulling up roofing shingles. What happens next?"
def generate(model, tok, prompt, max_new_tokens=60):
inputs = tok(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
out = model.generate(**inputs, max_new_tokens=max_new_tokens,
do_sample=False, pad_token_id=tok.eos_token_id)
return tok.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
# Modelo base vs fine-tuned
tok = AutoTokenizer.from_pretrained(MODEL_ID)
base_model = AutoModelForCausalLM.from_pretrained(MODEL_ID, torch_dtype=DTYPE).to("cuda")
print("Base:", generate(base_model, tok, PROMPT))
# Carregar checkpoint LoRA
from peft import PeftModel
ft_model = PeftModel.from_pretrained(base_model, CKPT_DIR)
print("Fine-tuned:", generate(ft_model, tok, PROMPT))A diferença entre as saídas do modelo base e fine-tuned no HellaSwag é notável: o modelo ajustado demonstra compreensão de consequências físicas que o modelo base frequentemente erra.
O que o NeMo AutoModel traz de diferente
Diferente de wrappers tradicionais de fine-tuning, o NeMo AutoModel:
- Separa configuração de código: você nunca modifica o script de treinamento — só o YAML.
- Escala naturalmente: a mesma receita YAML que roda em 1 GPU T4 funciona em 8 H100s com zero alterações de código.
- Integração NVIDIA: caminhos otimizados para GPUs NVIDIA com interface Hugging Face familiar.
- LoRA nativo: suporte a PEFT embutido — sem bibliotecas extras para fine-tuning eficiente.
Limitações e próximos passos
O Qwen3-0.6B é um modelo pequeno (600M parâmetros) — ideal para aprendizado mas limitado para produção. O mesmo fluxo funciona com Qwen3-8B ou maiores, desde que você tenha VRAM suficiente. Para modelos acima de 8B em uma GPU única, considere quantização 4-bit com bitsandbytes antes do LoRA.
Descubra mais sobre noticiAI
Assine para receber nossas notícias mais recentes por e-mail.



