Por que este guia importa agora
Em 2026, a diferença entre um chatbot e um agente de IA está em uma única capacidade: chamar ferramentas. Seja consultar uma API, buscar dados em um banco, executar código ou acionar outro sistema, o tool calling (ou function calling) transformou modelos de linguagem em executores de tarefas do mundo real. O que antes exigia clusters caros e meses de engenharia hoje cabe em uma GPU de notebook — e este guia mostra o caminho completo, do zero ao modelo ajustado.
O avanço que muda o jogo é a combinação de três peças abertas: o dataset XYZ-Aquila-SFT, publicado pela XYZAILab no Hugging Face, com trajetórias reais de conversas multi-turno que usam ferramentas; o modelo compacto Qwen3-0.6B, leve o suficiente para rodar em hardware modesto; e a técnica LoRA (Low-Rank Adaptation), que ajusta uma fração mínima dos pesos em vez do modelo inteiro. Há dois anos, um fine-tuning supervisionado desse tipo exigia um A100; hoje roda em uma GPU Colab gratuita.
Este tutorial reproduz, passo a passo, o pipeline publicado pela equipe do MarkTechPost: streaming do dataset, parsing de chamadas de ferramenta, conversão para o formato ChatML com mascaramento de perda, fine-tuning com LoRA e avaliação antes/depois do treino. Todo o código-fonte está disponível no repositório indicado ao final.
O que você ganha (e o que não ganha)
✅ O que este pipeline entrega
- Controle total do formato de treino: você renderiza o ChatML manualmente, preservando blocos de raciocínio (
<think>) que o template padrão do Qwen3 descartaria silenciosamente. - Custo próximo de zero: LoRA sobre um modelo de 0,6 bilhão de parâmetros roda em GPU de notebook, sem necessidade de alugar servidores.
- Supervisão token a token precisa: a perda é aplicada apenas aos tokens gerados pelo assistente — o modelo aprende a responder, não a decorar o prompt.
- Dataset pronto e aberto: o XYZ-Aquila-SFT já vem com chamadas de ferramenta anotadas, sem trabalho de curadoria manual.
- Avaliação objetiva: métricas de acurácia de nome de ferramenta e F1 de argumentos medem se o ajuste realmente funcionou.
⚠️ O que este pipeline NÃO entrega
- Um modelo pronto para produção: os 30 passos sobre ~350 trajetórias são um smoke test — um experimento de validação, não um resultado de referência. Para algo real, escale os dados e os passos.
- Garantia de generalização: o ajuste melhora o formato das chamadas, mas não ensina raciocínio novo fora da distribuição do dataset.
- Substituição de modelos grandes: um Qwen3-0.6B ajustado não compete com modelos de fronteira em tarefas complexas de múltiplas ferramentas.
Requisitos
| Componente | Mínimo | Recomendado | Ideal |
|---|---|---|---|
| GPU | Colab com T4 (16 GB) | L4 ou T4 com bf16 | RTX 3090/4090 (24 GB) |
| Memória RAM | 16 GB | 32 GB | 64 GB |
| Python | 3.10 | 3.11 | 3.12 |
| Bibliotecas | transformers ≥ 4.51, peft ≥ 0.13, datasets ≥ 3.0, accelerate ≥ 1.0 | — | últimas estáveis |
| Conhecimento prévio | Python básico + noção de transformers | Experiência com Hugging Face | Já ter rodado um fine-tuning |
| Tempo estimado | 2 horas (setup + execução) | 1 hora (ambiente pronto) | 30 minutos (smoke test) |
Passo a passo
1. Configure o ambiente e instale as dependências
O primeiro bloco define os parâmetros globais do experimento — repositório do dataset, modelo base, tamanho máximo de sequência (2048 tokens), taxa de aprendizado (1e-4) e o rank do LoRA (16). Em seguida, instala as bibliotecas necessárias e detecta se há GPU CUDA com suporte a bf16, que acelera o treino em placas modernas.
import os, sys, subprocess
CFG = dict(
REPO = "XYZAILab/XYZ-Aquila-SFT", # dataset no Hugging Face
MODEL_ID = "Qwen/Qwen3-0.6B", # modelo base compacto
MAX_SEQ_LEN = 2048,
LORA_R = 16, # rank da adaptação LoRA
LR = 1e-4,
MAX_STEPS = 30, # smoke test, não produção
)
subprocess.run([sys.executable, "-m", "pip", "install", "-q", "-U",
"datasets>=3.0.0", "transformers>=4.51.0",
"peft>=0.13.0", "accelerate>=1.0.0"], check=False)
from datasets import load_dataset
stream = load_dataset(CFG["REPO"], "en", split="train", streaming=True)
RAW = list(stream.take(400)) # baixa 400 exemplos em streaming
print(f"pulled {len(RAW)} rows")O streaming=True é o detalhe que importa: em vez de baixar o dataset inteiro para o disco, os exemplos são lidos sob demanda. Para um dataset de trajetórias de ferramentas — que pode ter centenas de milhares de conversas — isso poupa dezenas de gigabytes.
2. Inspecione e analise as trajetórias
Cada linha do dataset contém uma pergunta (question), a resposta final (answer), o número declarado de chamadas de ferramenta e uma lista trajectory com as mensagens do diálogo (papel + conteúdo). O tutorial converte cada linha em um objeto estruturado e calcula estatísticas do corpus: média de chamadas por trajetória, profundidade das conversas, distribuição de ferramentas usadas e até o peso das trajetórias mais longas.
O ponto de atenção é o parser de JSON aninhado. Chamadas de ferramenta reais têm objetos arguments aninhados, então uma regex ingênua como {.*?} quebra. O tutorial usa um scanner com json.JSONDecoder().raw_decode(), que respeita o aninhamento de colchetes e chaves — um erro clássico que o tutorial resolve logo no início.
3. Converta os esquemas de ferramentas entre formatos
O dataset armazena as definições de ferramentas embutidas na mensagem de sistema (entre tags <tools>). Para treinar o Qwen3, é preciso extraí-las para um formato estruturado (messages + tools) e, no caminho inverso, reembuti-las no template correto. O tutorial valida a conversão com um teste de byte-exact: extrair e re-renderizar deve reconstruir a mensagem original sem diferenças.
4. Renderize o ChatML e aplique o mascaramento de perda
Este é o coração técnico do guia. O Qwen3 usa o formato ChatML, delimitado por <|im_start|> e <|im_end|>. O tutorial renderiza esse formato manualmente em vez de usar apply_chat_template() — e explica o porquê: o template nativo do Qwen3 remove os blocos <think>...</think> de todos os turnos do assistente exceto o último. Nesse dataset, isso destruiria silenciosamente a maior parte da supervisão de raciocínio pela qual você está pagando para treinar.
O mascaramento segue o princípio padrão de SFT: tokens do sistema e do usuário recebem rótulo -100 (ignorados na perda); apenas os tokens do assistente — incluindo cabeçalhos e a chamada de ferramenta — contribuem para o cálculo da perda. É isso que ensina o modelo a gerar respostas e chamadas de ferramenta corretas, sem copiar o prompt.
5. Prepare o dataset PyTorch e o collator
Com os exemplos tokenizados e mascarados, o tutorial cria um Dataset do PyTorch e um collator que faz o padding dinâmico até o maior exemplo do batch, preenchendo os rótulos com -100 para manter o mascaramento alinhado. A divisão treino/avaliação reserva uma fração das trajetórias para as métricas finais.
6. Treine com LoRA, gradiente acumulado e precisão mista
O modelo é carregado com precisão bf16 (ou fp32 em CPU), ganha adaptadores LoRA (rank 16, alpha 32, dropout 0,05) e é treinado com otimizador AdamW, agendador cosseno com warmup e gradient checkpointing para economizar memória. O acúmulo de gradiente (8 trajetórias por passo) permite um batch efetivo maior do que a GPU suportaria de uma vez — técnica essencial em hardware limitado.
7. Avalie antes e depois do treino
A avaliação usa probes com teacher forcing: cada trajetória é cortada exatamente antes de um turno do assistente que emite uma chamada de ferramenta, e o modelo deve completá-la. As métricas são acurácia do nome da ferramenta e F1 das chaves de argumentos — o modelo acerta o nome e os parâmetros da chamada? Comparando o baseline (modelo original) com o adaptado, você vê o ganho real do fine-tuning.
8. Exporte os artefatos
Por fim, o tutorial salva as trajetórias estruturadas em JSONL, um relatório de estatísticas em JSON e o adaptador LoRA treinado. Esses artefatos permitem reutilizar o dataset transformado em experimentos futuros sem reprocessar tudo.
Comparação: fine-tuning completo × LoRA × prompting
| Abordagem | Custo de treino | Memória | Quando usar |
|---|---|---|---|
| Prompting (zero/few-shot) | Zero | Mínima | Modelos grandes, tarefas simples |
| LoRA (este guia) | Baixo | ~1-2 GB de adaptadores | Modelos pequenos, formato específico |
| Fine-tuning completo | Alto | Modelo inteiro | Domínio especializado, máximo desempenho |
Integração com o ecossistema
O pipeline se encaixa naturalmente no ecossistema Hugging Face: o dataset vem do Hub, o modelo base é o Qwen/Qwen3-0.6B e o adaptador treinado pode ser carregado com PeftModel.from_pretrained() em qualquer aplicação. Para servir o modelo ajustado, use o vLLM ou o llama.cpp com o adaptador LoRA fundido — e conecte-o a um runtime de agentes como o LangChain ou o framework da sua preferência. O notebook completo está disponível no repositório do MarkTechPost (link no final).
Casos de uso reais
- Suporte técnico automatizado: um modelo ajustado que consulta uma base de conhecimento via ferramenta antes de responder o cliente.
- Assistentes de dados: gerar SQL ou consultas a uma API a partir de perguntas em linguagem natural, com chamadas estruturadas.
- Automação de e-commerce: acionar buscas de preço, checar estoque e montar o carrinho em um fluxo de múltiplas ferramentas.
- Agentes de pesquisa: encadear busca na web + leitura de páginas + sumarização em trajetórias multi-turno.
- Prototipagem de produtos: validar uma ideia de agente em horas, antes de investir em modelos grandes ou APIs pagas.
Custo estimado
| Cenário | Hardware | Custo aproximado |
|---|---|---|
| Local (GPU própria) | RTX 3090 usada | ~R$ 0,50/hora de energia (ajuste curto) |
| Colab gratuito | T4 | R$ 0 |
| Cloud (GPU alugada) | A10G / L4 | ~R$ 3-6/hora |
| API comercial | — | Por token, sem fine-tuning próprio |
Troubleshooting
- ❌
CUDA out of memorydurante o treino → Causa: batch efetivo ou sequência longa demais para a GPU. Solução: reduzaMAX_SEQ_LEN, mantenhagradient_checkpointingativo ou use acúmulo de gradiente maior em vez de aumentar o batch. - ❌ O parser de JSON quebra em chamadas aninhadas → Causa: regex ingênua que não respeita aninhamento. Solução: use
json.JSONDecoder().raw_decode(), como no tutorial. - ❌ A acurácia não muda após o treino → Causa: 30 passos sobre ~350 trajetórias é apenas um teste de fumaça. Solução: aumente
N_STREAMeMAX_STEPSpara um experimento real. - ❌ O template do Qwen3 descarta o raciocínio → Causa:
apply_chat_template()remove<think>dos turnos intermediários. Solução: renderize o ChatML manualmente, como demonstrado. - ❌
bf16não suportado → Causa: GPU antiga sem suporte a bfloat16. Solução: o código já faz fallback para fp32/fp16 automaticamente. - ❌ Perda não converge (NaN) → Causa: taxa de aprendizado alta demais com precisão mista. Solução: reduza
LRou desative a precisão mista.
Perguntas frequentes
Preciso de GPU para rodar este tutorial? Em CPU funciona, mas é muito lento. O ideal é qualquer GPU CUDA, inclusive a T4 gratuita do Google Colab.
O que é exatamente o tool calling? É a capacidade do modelo de gerar, em formato estruturado, uma chamada a uma função externa — nome da função e argumentos em JSON — que o seu código executa e devolve o resultado para o modelo.
Por que usar LoRA em vez de treinar o modelo inteiro? O LoRA ajusta apenas matrizes de baixo rank adicionadas às camadas, reduzindo drasticamente a memória e o custo, com desempenho competitivo em tarefas de adaptação de formato.
O que é o dataset XYZ-Aquila-SFT? É um dataset aberto da XYZAILab com trajetórias de conversas multi-turno que incluem chamadas de ferramenta, raciocínio e observações — ideal para SFT de agentes.
O modelo ajustado substitui o GPT-4 ou o Claude? Não para tarefas gerais. Ele é um modelo pequeno especializado em formato de chamada de ferramenta, útil como componente barato e local de um sistema maior.
Para onde isso vai
A tendência é clara: modelos pequenos e especializados — ajustados com LoRA para tarefas específicas como o tool calling — vão se multiplicar em 2027, à medida que agentes deixam de ser demonstração e viram infraestrutura. Dominar esse pipeline hoje significa ter a base para treinar os agentes de amanhã com custo de café, não de cluster.
Descubra mais sobre noticiAI
Assine para receber nossas notícias mais recentes por e-mail.



