Um modelo genérico como o Claude Sonnet 5 ou o Gemini 3.7 Flash resolve a maioria das tarefas do dia a dia, mas nenhum dos dois conhece o tom de voz da sua empresa, o jargão do seu setor ou o formato exato que o seu produto precisa de devolver. É aqui que entra o fine-tuning: pegar num modelo open source já treinado e ensiná-lo, com os seus próprios dados, a fazer uma coisa muito específica, muito bem. Este tutorial mostra o processo completo, do zero ao modelo exportado, com o Hugging Face Transformers, PEFT e TRL, usando LoRA e quantização de 4 bits para treinar em hardware que cabe num orçamento normal.

No final vai ter um projeto funcional, um checklist de dez passos, tabelas com custos reais de GPU na cloud e uma lista de erros que custam horas de debugging a quem faz isto pela primeira vez. Tudo o que vê aqui corre em código Python normal, sem depender de nenhuma plataforma paga além do aluguer opcional de uma GPU.

Este guia assume que já experimentou modelos generalistas via API e chegou ao limite do que um prompt bem escrito consegue fazer. Talvez o modelo continue a variar o formato da resposta, ou continue a “esquecer” uma instrução depois de algumas trocas de mensagens. É precisamente nesse ponto que vale a pena investir algumas horas a preparar dados de treino e a correr o processo descrito abaixo, em vez de continuar a empilhar regras num prompt cada vez mais longo e cada vez mais frágil.

O que é fine-tuning e porque faz sentido em 2026

Fine-tuning é o processo de continuar o treino de um modelo já pré-treinado, usando um conjunto de dados mais pequeno e específico, para ajustar o seu comportamento a uma tarefa concreta. Em vez de treinar uma rede neuronal do zero (o que exigiria milhões de euros em computação), aproveita-se o conhecimento geral que o modelo já tem sobre linguagem e ensina-se apenas o que falta: o estilo de resposta, o domínio técnico, ou um formato de saída rígido como JSON estruturado.

O ecossistema de open source cresceu muito depressa. A Hugging Face confirma que o seu Model Hub ultrapassou os 900 mil modelos publicados em abril de 2026, além de mais de 200 mil datasets disponíveis para download direto, segundo dados compilados pela PE Collective. Isto significa que já existe, quase de certeza, um modelo base adequado ao seu caso de uso, seja ele Llama, Qwen, Mistral ou Gemma.

A técnica que tornou isto acessível a quem não tem um cluster de GPUs chama-se LoRA (Low-Rank Adaptation), descrita no paper original de Hu et al., publicado em 2021. Em vez de atualizar todos os parâmetros do modelo, o LoRA treina apenas pequenas matrizes adicionais inseridas nas camadas de atenção, reduzindo drasticamente a memória necessária. Combinada com quantização de 4 bits (QLoRA), técnica descrita no paper de Dettmers et al., esta abordagem permite treinar modelos de 7 ou 8 mil milhões de parâmetros numa única placa gráfica de consumo.

Vale a pena situar isto no contexto dos modelos fechados que fazem manchetes em 2026. A Anthropic lançou o Claude Sonnet 5 a 30 de junho, disponível a todos os planos, incluindo o gratuito, com preço de $2 por milhão de tokens de entrada e $10 por milhão de tokens de saída, tornado definitivo a 10 de agosto segundo o anúncio oficial da Anthropic. Já a Google colocou o Gemini 3.7 Flash em disponibilidade geral a 12 de agosto, descrito nas suas notas de lançamento como o modelo mais capaz da linha Flash para tarefas de código e agentes. Estes modelos são excelentes para uso geral, mas continuam a cobrar por token e a devolver um comportamento que não é totalmente seu. Um modelo open source afinado localmente corre sem custo por chamada, mantém os dados dentro da sua infraestrutura e pode ser ajustado quantas vezes forem necessárias sem depender da disponibilidade de uma API externa.

Fine-tuning vs RAG vs prompt engineering: quando usar cada abordagem

Antes de gastar horas a preparar um dataset, vale a pena confirmar que o fine-tuning é mesmo a ferramenta certa. Muitos problemas resolvem-se com um prompt melhor escrito, ou com uma pipeline de RAG (Retrieval-Augmented Generation) que vai buscar contexto a uma base de dados vetorial no momento da pergunta. O fine-tuning brilha quando o problema não é falta de informação, mas sim falta de comportamento consistente.

CritérioPrompt engineeringRAGFine-tuning
Custo inicialQuase zeroBaixo a médioMédio (GPU + dados)
Atualiza conhecimento factualLimitado ao contextoSim, em tempo realNão, fica congelado no treino
Muda o tom e o estiloParcialmenteNãoSim, de forma consistente
Reduz o tamanho do promptNãoNãoSim, comportamento fica embutido
Formato de saída rígido (JSON, XML)InstávelInstávelMuito fiável após treino
Tempo até resultadosMinutosHoras a diasHoras a dias, mais iteração

Na prática, as equipas mais maduras combinam as três técnicas: um prompt bem escrito, uma camada de RAG para dados que mudam com frequência, e um fine-tuning leve para fixar o comportamento e o formato de resposta. Se o objetivo for apenas responder com dados de um manual interno, comece por RAG, é mais barato e mais fácil de atualizar. Se o problema é o modelo “esquecer” instruções longas ou variar o formato da resposta, o fine-tuning resolve isso de forma mais estável.

Um sinal prático de que precisa de fine-tuning, e não apenas de um prompt melhor: se está a repetir as mesmas instruções de formato em todos os pedidos e mesmo assim recebe variações inconsistentes, o modelo não está a “esquecer” por falta de contexto, está a comportar-se dentro da variabilidade normal de um modelo generalista. Fixar esse comportamento no próprio peso do modelo, via treino, costuma ser mais fiável do que continuar a alongar o prompt.

Pré-requisitos: hardware, software e contas necessárias

Este tutorial assume conhecimentos básicos de Python e de linha de comandos. Não é preciso saber matemática de redes neuronais para seguir os passos, mas ajuda perceber o que é um tensor e o que faz uma função de perda. A tabela seguinte resume o que precisa de ter instalado antes de avançar.

RequisitoVersão ou especificação recomendadaNotas
Python3.11 ou 3.12Use sempre um ambiente virtual dedicado
GPUNVIDIA com pelo menos 16 GB de VRAM24 GB dá margem confortável para modelos 7B/8B com QLoRA
Driver NVIDIA + CUDADriver atual com suporte a CUDA 12.xConfirme com nvidia-smi
PyTorchVersão estável mais recente com suporte CUDAInstalar via instruções oficiais do site pytorch.org
transformersVersão estável mais recente (pip)Instalar com pip install "transformers[torch]"
peft, trl, bitsandbytes, accelerateVersões estáveis mais recentesO TRL chegou à v1.7.0 em 25 de junho de 2026
Conta Hugging FaceGratuitaNecessária para descarregar modelos com licença restrita e publicar o resultado
Espaço em discoPelo menos 40 GB livresCheckpoints e cache de modelos ocupam espaço rapidamente

Não tem uma GPU local com VRAM suficiente? Não é impeditivo. Mais à frente há uma tabela com preços reais de aluguer de GPU na cloud, incluindo opções a partir de menos de 30 cêntimos por hora.

Passo 1: Preparar o ambiente Python e verificar a GPU

Comece por criar um ambiente isolado. Isto evita conflitos de versões entre projetos diferentes, um dos erros mais comuns quando se trabalha com bibliotecas de machine learning que mudam depressa.

# Criar e ativar o ambiente virtual
python3 -m venv .venv
source .venv/bin/activate

# Confirmar que a GPU está visível e o driver está a funcionar
nvidia-smi

# Confirmar a versão do CUDA reportada pelo driver
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv

Se o comando nvidia-smi não devolver nada, o driver não está instalado corretamente ou o sistema não tem uma GPU NVIDIA disponível. Confirme isso antes de perder tempo a instalar bibliotecas, porque o erro mais frustrante neste processo aparece só na fase de treino, quando já preparou o dataset todo.

Utilizadores Windows devem correr este tutorial dentro do WSL2 (Windows Subsystem for Linux), porque o suporte a CUDA para bibliotecas como o bitsandbytes é mais estável em Linux. Em macOS com chips Apple Silicon, o caminho é diferente: não há suporte CUDA, pelo que a quantização de 4 bits via bitsandbytes não se aplica da mesma forma, sendo preferível recorrer a uma GPU alugada na cloud, descrita mais à frente neste artigo.

Passo 2: Instalar Transformers, PEFT, TRL e Bitsandbytes

Com o ambiente ativo, instale o PyTorch com suporte CUDA seguindo as instruções do site oficial (o comando exato depende da versão do CUDA do seu driver) e depois as quatro bibliotecas centrais deste fluxo de trabalho.

# Instalar as bibliotecas principais da Hugging Face
pip install "transformers[torch]"
pip install peft trl bitsandbytes accelerate datasets

# Confirmar que tudo importa sem erros
python3 -c "import torch, transformers, peft, trl, bitsandbytes; print('torch CUDA disponível:', torch.cuda.is_available())"

Se a última linha imprimir torch CUDA disponível: False, o PyTorch foi instalado numa versão sem suporte a GPU. Desinstale e volte a instalar seguindo exatamente o comando gerado no site oficial do PyTorch para a sua versão de CUDA, não use o comando genérico do PyPI.

Passo 3: Escolher o modelo base certo

A escolha do modelo base condiciona tudo o resto: a VRAM necessária, a velocidade de treino e a qualidade final. Para a maioria dos projetos de fine-tuning num orçamento pessoal ou de pequena equipa, os modelos na faixa de 7 a 9 mil milhões de parâmetros são o ponto de equilíbrio entre capacidade e custo de treino.

Família de modeloTamanhos típicos disponíveisMelhor para
Llama (Meta)8B, variantes maioresUso geral, grande comunidade e tutoriais
Qwen3 (Alibaba)0.6B até dezenas de mil milhõesTarefas com tool calling e código
Gemma 4 (Google)e2b, 26b, 31b entre outrasEficiência em hardware mais modesto
MistralVários tamanhos densos e mixture-of-expertsBoa relação desempenho por parâmetro

Para este tutorial vamos usar um modelo de 7B como referência, porque cabe confortavelmente numa GPU de 24 GB com QLoRA de 4 bits. Se a sua GPU tiver menos memória, opte por um modelo mais pequeno, como uma variante e2b ou de poucos mil milhões de parâmetros, antes de reduzir agressivamente o batch size, que costuma prejudicar mais a qualidade final do que reduzir o tamanho do modelo.

Confirme sempre a licença do modelo antes de o usar em produção. Alguns modelos, como certas variantes Llama, exigem aceitar termos específicos na página do Hugging Face Hub antes do primeiro download, e algumas licenças impõem restrições ao uso comercial acima de um determinado número de utilizadores mensais. Ler a licença demora cinco minutos e evita problemas legais mais tarde.

Outro fator a pesar é a comunidade e a documentação disponível à volta de cada família de modelos. Modelos com mais downloads e mais discussões abertas no Hub costumam ter problemas conhecidos já documentados por outros utilizadores, o que poupa tempo quando algo corre mal durante o treino. Antes de decidir, vale a pena pesquisar o nome do modelo junto de termos como “fine-tuning” ou “LoRA” para ver que dificuldades outras pessoas já enfrentaram com essa arquitetura específica.

Passo 4: Preparar e formatar o dataset de treino

Esta é a etapa que mais determina o resultado final, e a que mais gente subestima. O formato mais comum para fine-tuning conversacional é o JSONL, com um exemplo por linha, seguindo a estrutura de mensagens no estilo chat completions. Cada exemplo deve representar exatamente o comportamento que quer que o modelo replique.

{"messages": [{"role": "system", "content": "És um assistente de apoio ao cliente da loja online Nortex."}, {"role": "user", "content": "O meu pedido ainda não chegou, o que faço?"}, {"role": "assistant", "content": "Lamento o atraso. Pode indicar-me o número do pedido para eu verificar o estado do envio?"}]}
{"messages": [{"role": "system", "content": "És um assistente de apoio ao cliente da loja online Nortex."}, {"role": "user", "content": "Quero devolver um artigo, como funciona?"}, {"role": "assistant", "content": "Sem problema. As devoluções têm 30 dias a partir da entrega. Envie-me o número de encomenda e o motivo da devolução."}]}

Quanto ao volume necessário, um guia de fine-tuning publicado pela CrazyRouter em 2026 recomenda começar por um mínimo entre 50 e 500 exemplos de boa qualidade, sublinhando que a qualidade importa mais do que a quantidade: cada exemplo deve representar exatamente o comportamento pretendido, sem ambiguidade. Separe sempre uma fatia dos dados, tipicamente entre 10% e 20%, para validação, para conseguir detetar overfitting mais à frente.

Duas práticas ajudam a subir a qualidade do dataset sem multiplicar o trabalho manual. Primeiro, varie a forma como a mesma pergunta é feita: utilizadores reais não escrevem todos da mesma maneira, e um dataset onde todas as perguntas seguem o mesmo padrão sintático produz um modelo frágil fora desse padrão. Segundo, inclua alguns exemplos de recusa ou de pedido de esclarecimento, não apenas respostas diretas, para o modelo aprender também quando não deve responder de forma definitiva.

from datasets import load_dataset

dataset = load_dataset("json", data_files="dados_treino.jsonl", split="train")
dataset = dataset.train_test_split(test_size=0.15, seed=42)

print(f"Exemplos de treino: {len(dataset['train'])}")
print(f"Exemplos de validação: {len(dataset['test'])}")

Passo 5: Carregar o modelo com quantização QLoRA de 4 bits

Com o dataset pronto, é hora de carregar o modelo base em memória. A quantização de 4 bits, via bitsandbytes, reduz o espaço que os pesos ocupam em VRAM sem alterar de forma significativa a qualidade do resultado, o que é o que torna possível treinar em hardware de consumo.

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

nome_modelo = "meta-llama/Llama-3.1-8B-Instruct"

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

tokenizer = AutoTokenizer.from_pretrained(nome_modelo)
modelo = AutoModelForCausalLM.from_pretrained(
    nome_modelo,
    quantization_config=bnb_config,
    device_map="auto",
)

O parâmetro device_map="auto" distribui o modelo automaticamente pela GPU disponível. Se receber um erro de memória insuficiente nesta fase, confirme primeiro que não tem outros processos a ocupar VRAM (o próprio ambiente gráfico do sistema operativo, por exemplo) antes de assumir que precisa de trocar de GPU.

O argumento bnb_4bit_quant_type="nf4" usa o formato NormalFloat4, otimizado para a distribuição normal dos pesos de redes neuronais treinadas, e costuma dar melhores resultados do que a quantização inteira simples. Já o bnb_4bit_use_double_quant=True aplica uma segunda quantização às constantes da primeira, poupando ainda mais alguns megabytes de VRAM sem impacto percetível na qualidade final. São detalhes pequenos, mas em GPUs no limite da memória fazem a diferença entre o treino correr ou falhar logo no arranque.

Passo 6: Configurar o adaptador LoRA

Com o modelo carregado, a biblioteca PEFT permite injetar os adaptadores LoRA nas camadas de atenção. Os parâmetros mais importantes aqui são o r (rank, que controla a capacidade do adaptador) e o lora_alpha (fator de escala). Valores mais altos de r aumentam a capacidade de aprendizagem, mas também o risco de overfitting em datasets pequenos.

from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training

modelo = prepare_model_for_kbit_training(modelo)

lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

modelo = get_peft_model(modelo, lora_config)
modelo.print_trainable_parameters()

O resultado de print_trainable_parameters() costuma mostrar que menos de 1% dos parâmetros totais do modelo são efetivamente treinados. É essa a razão pela qual o QLoRA cabe em GPUs muito mais modestas do que um fine-tuning completo exigiria.

A escolha de target_modules também importa. Limitar o LoRA às projeções de atenção (q_proj, k_proj, v_proj, o_proj) é o ponto de partida mais comum e mais leve em VRAM. Para tarefas que exigem mudanças mais profundas de comportamento, como ensinar um domínio técnico muito específico, vale a pena estender a lista às camadas de feed-forward do modelo (normalmente identificadas como gate_proj, up_proj e down_proj), à custa de mais memória e tempo de treino.

Passo 7: Definir hiperparâmetros e lançar o treino com o SFTTrainer

O TRL (Transformers Reinforcement Learning), que a Hugging Face atualizou para a versão 1.7.0 em 25 de junho de 2026, fornece o SFTTrainer, uma classe pensada especificamente para supervised fine-tuning que trata da tokenização, do agrupamento em batches e do ciclo de treino.

from trl import SFTTrainer, SFTConfig

config_treino = SFTConfig(
    output_dir="./resultado-fine-tuning",
    num_train_epochs=3,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    learning_rate=2e-4,
    logging_steps=10,
    eval_strategy="steps",
    eval_steps=50,
    save_strategy="steps",
    save_steps=50,
    bf16=True,
    max_seq_length=1024,
)

trainer = SFTTrainer(
    model=modelo,
    args=config_treino,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
)

trainer.train()

Com um dataset de algumas centenas de exemplos e um modelo de 7B em QLoRA, este treino costuma demorar entre 20 minutos e algumas horas, dependendo da GPU. Deixe o processo correr e vá acompanhando a evolução da perda (loss) nos logs, que é o assunto do próximo passo.

Repare em três parâmetros que costumam gerar dúvidas. O gradient_accumulation_steps simula um batch maior sem exigir mais VRAM de uma vez, somando os gradientes de vários mini-batches antes de atualizar os pesos, o que é essencial em GPUs de 16 ou 24 GB. O learning_rate de 2e-4 é um valor de referência razoável para LoRA, mais alto do que se usaria num fine-tuning completo, porque só uma fração pequena dos parâmetros está a ser treinada. E o bf16=True ativa o formato de precisão brain float 16, que reduz o uso de memória face ao float32 tradicional sem a instabilidade numérica que o float16 clássico por vezes introduz.

Passo 8: Monitorizar a perda e testar o modelo com inferência

Durante o treino, a perda de treino deve descer de forma consistente. O sinal de overfitting mais claro é a perda de validação começar a subir enquanto a perda de treino continua a descer, o que indica que o modelo está a memorizar exemplos em vez de generalizar o comportamento. Quando isso acontecer, o checkpoint anterior ao ponto de viragem costuma ser a melhor escolha, não o último.

Depois de terminado o treino, teste o modelo com perguntas fora do dataset de treino, para confirmar que o comportamento generaliza e não decorou apenas as respostas exatas dos exemplos.

from transformers import pipeline

gerador = pipeline("text-generation", model=modelo, tokenizer=tokenizer)

prompt = [
    {"role": "system", "content": "És um assistente de apoio ao cliente da loja online Nortex."},
    {"role": "user", "content": "Posso trocar um artigo por outro tamanho?"},
]

resposta = gerador(prompt, max_new_tokens=150, temperature=0.7)
print(resposta[0]["generated_text"])

Um exemplo de saída típica, depois de um fine-tuning bem-sucedido com um dataset de apoio ao cliente, seria algo como: “Claro. As trocas de tamanho seguem o mesmo prazo das devoluções, 30 dias após a entrega. Indique-me o número do pedido e o tamanho pretendido para eu confirmar a disponibilidade.” Note o tom consistente com os exemplos de treino, sem precisar de repetir instruções no prompt.

Além do teste manual, vale a pena montar um pequeno conjunto de avaliação automática: dez a vinte perguntas representativas, com uma resposta de referência para cada uma, corridas antes e depois do fine-tuning. Comparar as duas versões lado a lado torna muito mais fácil perceber se o treino melhorou o comportamento pretendido ou se, pelo contrário, degradou capacidades que o modelo já tinha antes, como seguir instruções gerais fora do domínio treinado.

Passo 9: Fundir os adaptadores LoRA e exportar o modelo final

Os adaptadores LoRA, isolados, não servem para muito sem o modelo base. Para distribuir ou colocar o modelo em produção de forma mais simples, é comum fundir (merge) os pesos do adaptador diretamente nos pesos do modelo base, criando um único conjunto de ficheiros pronto a usar.

from peft import PeftModel
from transformers import AutoModelForCausalLM

modelo_base = AutoModelForCausalLM.from_pretrained(
    nome_modelo, torch_dtype=torch.bfloat16, device_map="auto"
)
modelo_fundido = PeftModel.from_pretrained(modelo_base, "./resultado-fine-tuning")
modelo_fundido = modelo_fundido.merge_and_unload()

modelo_fundido.save_pretrained("./modelo-final")
tokenizer.save_pretrained("./modelo-final")

A partir daqui, o modelo fundido pode ser convertido para o formato GGUF com as ferramentas do projeto llama.cpp, para correr localmente através de aplicações como o Ollama, ou publicado diretamente no Hugging Face Hub com modelo_fundido.push_to_hub("o-seu-utilizador/nome-do-modelo") para partilhar com a equipa ou disponibilizar ao público.

Se o destino final for correr o modelo localmente via Ollama, exporte para GGUF e defina um quantization level (por exemplo Q4_K_M para um equilíbrio razoável entre tamanho e qualidade) antes de o importar. Já cobrimos esse fluxo, do lado do Ollama, com detalhe noutro tutorial neste site, incluindo os comandos exatos para importar um modelo GGUF personalizado.

Passo 10: Estrutura completa do projeto

Um projeto de fine-tuning organizado poupa tempo em iterações futuras. Esta é a estrutura de pastas usada ao longo deste tutorial, já testada de ponta a ponta.

projeto-fine-tuning/
├── .venv/                       # ambiente virtual Python
├── dados/
│   ├── dados_treino.jsonl       # exemplos formatados
│   └── preparar_dataset.py      # script de limpeza e formatação
├── treino/
│   ├── carregar_modelo.py       # passo 5: quantização QLoRA
│   ├── configurar_lora.py       # passo 6: LoraConfig
│   └── treinar.py               # passo 7: SFTTrainer
├── avaliacao/
│   └── testar_modelo.py         # passo 8: inferência e testes manuais
├── exportar/
│   └── fundir_adaptador.py      # passo 9: merge_and_unload
├── resultado-fine-tuning/       # checkpoints gerados durante o treino
├── modelo-final/                # modelo fundido, pronto a publicar
└── requirements.txt

O ficheiro requirements.txt deve fixar as bibliotecas centrais para garantir que o projeto continua a correr da mesma forma daqui a seis meses: transformers, peft, trl, bitsandbytes, accelerate e datasets, além do PyTorch instalado à parte com suporte CUDA.

Erros comuns no fine-tuning de LLMs

Estes são os erros que mais aparecem em projetos de fine-tuning, muitas vezes só detetados depois de horas de treino desperdiçadas. A lista está ordenada pela frequência com que aparece em fóruns e issues de projetos open source, começando pelos problemas de dados, que continuam a ser a causa mais comum de resultados fracos, mesmo quando toda a configuração técnica está correta.

  • Dataset demasiado pequeno e inconsistente. Vinte exemplos escritos à pressa, sem revisão, produzem um modelo confuso, que aprende ruído em vez de padrão. Prefira menos exemplos, mas revistos linha a linha e consistentes no formato de resposta.
  • Ignorar o conjunto de validação. Treinar apenas a olhar para a perda de treino esconde overfitting até ser tarde demais. É comum ver a perda de treino continuar a descer durante horas enquanto o modelo, na prática, já parou de generalizar duas épocas antes.
  • Learning rate demasiado alto. Valores acima de 5e-4 em LoRA costumam destabilizar o treino e produzir respostas sem sentido nas primeiras épocas. Se a perda oscilar de forma errática em vez de descer, esse é normalmente o primeiro parâmetro a rever.
  • Misturar formatos de prompt diferentes do template do modelo. Cada família de modelos espera um template de chat específico, com marcadores de início e fim de turno próprios. Usar um formato errado durante o treino faz o modelo aprender um padrão que a aplicação final, que usa o template correto, nunca vai reproduzir.
  • Não guardar checkpoints intermédios. Sem save_steps configurado, uma falha de energia ou uma sessão de cloud interrompida a meio do treino obriga a recomeçar do zero, perdendo horas de computação já paga.
  • Escolher um modelo base maior do que a GPU aguenta “porque sim”. Um modelo mais pequeno bem treinado, com um dataset cuidado, supera quase sempre um modelo grande mal ajustado por falta de memória, que obriga a cortar o batch size e a sequência ao ponto de comprometer a qualidade do treino.
  • Avaliar apenas com os olhos, sem comparação estruturada. Testar duas ou três perguntas manualmente dá uma primeira impressão, mas não substitui um conjunto de avaliação fixo, corrido antes e depois do treino, que permita comparar versões de forma objetiva.

Resolução de problemas: erros frequentes e como corrigi-los

Erro ou sintomaCausa provávelComo corrigir
CUDA out of memoryBatch size ou sequência demasiado grandes para a VRAMReduza per_device_train_batch_size e aumente gradient_accumulation_steps
torch.cuda.is_available() devolve FalsePyTorch instalado sem suporte CUDAReinstale seguindo o comando exato do site oficial do PyTorch para a versão de CUDA do driver
Perda não desce ao longo das épocasLearning rate demasiado baixo, ou dados mal formatadosConfirme o formato JSONL e suba a learning rate gradualmente
Modelo responde sempre a mesma fraseOverfitting num dataset pequeno e repetitivoAumente a diversidade do dataset e reduza o número de épocas
Erro ao carregar tokenizer para modelos com licença restritaSessão não autenticada na Hugging FaceExecute huggingface-cli login e aceite os termos do modelo na página do Hub
ImportError relacionado com bitsandbytesVersão de CUDA incompatível com o build do bitsandbytesReinstale bitsandbytes depois de confirmar a versão de CUDA ativa
Treino extremamente lento em CPUGPU não detetada ou device_map mal configuradoConfirme nvidia-smi e defina explicitamente device_map="auto"
Modelo fundido ocupa muito mais espaço do que o esperadoMerge feito em precisão float32 em vez de bfloat16Force torch_dtype=torch.bfloat16 ao carregar o modelo base antes do merge

Dicas avançadas e custos reais de GPU na cloud

Depois do primeiro fine-tuning bem-sucedido, há três direções naturais para explorar. A primeira é o treino multi-GPU, distribuindo o trabalho com o Accelerate ou o DeepSpeed quando um único modelo já não cabe numa placa. A segunda é o DPO (Direct Preference Optimization), suportado pelo TRL, que em vez de treinar apenas com pares pergunta-resposta, treina o modelo a preferir uma resposta boa a uma resposta má, útil para afinar tom e segurança depois do supervised fine-tuning inicial. A terceira é gerir bem o custo de computação, que é normalmente o maior obstáculo para quem experimenta pela primeira vez.

Vale ainda a pena experimentar o rank adaptativo do LoRA, subindo o valor de r gradualmente (de 16 para 32 ou 64) apenas quando o modelo mostrar sinais de capacidade insuficiente, como respostas demasiado genéricas mesmo depois de várias épocas de treino. Subir o rank sem necessidade só aumenta o tempo de treino e o risco de overfitting, sem trazer ganho real de qualidade. Outra prática útil é o early stopping automático, interrompendo o treino assim que a perda de validação deixar de melhorar durante um número definido de avaliações consecutivas, poupando tempo de GPU sem intervenção manual constante.

Se não tiver uma GPU local adequada, alugar por hora costuma sair mais barato do que comprar hardware para um projeto pontual. A tabela seguinte mostra preços oficiais e de mercado observados em 2026.

GPUFornecedorPreço por horaFonte
RTX 4090 (24 GB)Vast.ai (mercado, spot)desde $0,29/hVast.ai, dados de 2026
A100 40GBLambda Cloud (on-demand)$1,99/hlambda.ai/pricing
A100 SXM 80GBLambda Cloud (on-demand)$2,79/hlambda.ai/pricing

Para um fine-tuning de um modelo 7B com QLoRA e um dataset de algumas centenas de exemplos, uma única RTX 4090 alugada é normalmente suficiente e sai muito mais barata do que uma A100. Reserve a A100 para modelos maiores ou datasets com dezenas de milhares de exemplos, onde o tempo de treino mais longo justifica a diferença de preço.

Um cálculo rápido ajuda a orçamentar o projeto antes de começar: se o treino completo, incluindo experimentação com hiperparâmetros, ocupar cerca de quatro horas de GPU numa RTX 4090 a $0,29 por hora no ponto mais barato do mercado, o custo total fica perto de $1,16, mesmo contando com duas ou três repetições para afinar o resultado. É um valor irrisório face ao tempo de engenharia investido, e é essa relação que torna o fine-tuning open source viável mesmo para equipas pequenas ou projetos pessoais.

Perguntas frequentes

Preciso de uma GPU própria para fazer fine-tuning?
Não. Serviços de aluguer como o Vast.ai ou o Lambda Cloud permitem alugar GPUs por hora, com preços a partir de menos de 30 cêntimos para placas de consumo como a RTX 4090.

Quantos exemplos preciso no dataset de treino?
Um bom ponto de partida situa-se entre 50 e 500 exemplos de qualidade elevada. Datasets maiores ajudam, mas só se mantiverem a mesma consistência de formato e tom.

Fine-tuning é melhor do que RAG?
Não são concorrentes diretos. RAG é melhor para conhecimento que muda com frequência, fine-tuning é melhor para fixar comportamento, tom e formato de resposta. Muitos sistemas em produção usam os dois em conjunto.

O que é QLoRA e em que difere do LoRA normal?
QLoRA combina a técnica LoRA com quantização de 4 bits do modelo base, descrita no paper de Dettmers et al., permitindo treinar modelos maiores com muito menos VRAM do que o LoRA tradicional em precisão total.

Posso fazer fine-tuning de modelos fechados como o Claude ou o Gemini?
A Anthropic e a Google disponibilizam APIs de fine-tuning gerido para alguns dos seus modelos através das respetivas plataformas empresariais, mas o processo é diferente do fluxo open source descrito aqui, com menos controlo sobre os hiperparâmetros e o dataset processado do lado do fornecedor.

Quanto tempo demora um fine-tuning típico?
Com um modelo 7B, QLoRA e algumas centenas de exemplos, entre 20 minutos e poucas horas numa GPU de gama alta. Datasets maiores ou mais épocas de treino aumentam esse tempo proporcionalmente.

O modelo afinado esquece o que sabia antes do fine-tuning?
Pode acontecer, chama-se catastrophic forgetting. Um learning rate moderado, um rank de LoRA equilibrado e um número de épocas contido (normalmente entre 2 e 4) reduzem bastante esse risco.

Preciso de publicar o modelo no Hugging Face Hub?
Não é obrigatório. Pode manter o modelo fundido apenas localmente, mas publicar facilita a partilha com a equipa e permite usar a Inference API sem gerir infraestrutura própria.

Vale a pena fazer fine-tuning de um modelo muito pequeno, como uma variante e2b?
Sim, para tarefas bem delimitadas. Modelos mais pequenos treinam mais depressa, correm em hardware mais modesto e, para tarefas estreitas como classificação ou extração de dados num formato fixo, muitas vezes igualam o desempenho de um modelo maior sem afinar, com uma fração do custo de inferência a longo prazo.

Cobertura relacionada

Para mais artigos sobre modelos de linguagem, veja também a nossa cobertura de Inteligência Artificial.