A pergunta chega quase sempre na mesma forma: "o modelo não entende o jargão da nossa área, dá para treinar ele com os nossos dados?". Dá. Mas na maioria dos casos que chegam até aqui, treinar é a resposta errada — cara, demorada e pior que a alternativa de dez minutos.
Este texto é o critério que a gente usa para decidir, seguido do passo a passo de quem passou no critério.
Primeiro: o seu problema é de conhecimento ou de comportamento?
Essa é a divisão que resolve 90% das dúvidas.
Problema de conhecimento é quando o modelo não sabe algo: a política interna de reembolso, o preço da tabela de 2026, o que o contrato do cliente X diz. Ajustar o modelo é a pior forma de ensinar isso. O fato entra diluído em pesos, você não consegue auditar de onde veio a resposta, e quando a política mudar em novembro você vai ter que treinar de novo. Isso é trabalho para recuperação de documentos: o fato fica num índice, é citável e se corrige com um ctrl+S.
Problema de comportamento é quando o modelo sabe, mas responde errado de forma: escreve longo demais quando o seu produto precisa de duas linhas, ignora o formato JSON que o seu sistema espera, usa "olá, prezado cliente" num app cujo tom é informal, classifica em categorias que ele inventa em vez das oito que você definiu. Aí sim: ajustar é a ferramenta certa, e funciona muito bem.
Escreva o comportamento desejado num prompt bem detalhado, com três exemplos dentro dele. Se o modelo acerta, o seu problema é de instrução — resolva com prompt e siga a vida.
Se ele acerta às vezes e erra às vezes, de forma teimosa, com o prompt já bem escrito: aí o ajuste vale. LoRA é excelente para consolidar consistência, e ruim para injetar fatos.
O que é LoRA, sem enrolação
Treinar um modelo de 8 bilhões de parâmetros do jeito tradicional significa atualizar todos os 8 bilhões — e guardar, além deles, o gradiente e os dois estados do otimizador. Na conta grossa, cerca de 16 bytes por parâmetro: 128 GB de VRAM só para o treino de um modelo pequeno. Não cabe em uma GPU acessível.
LoRA (Low-Rank Adaptation) congela o modelo inteiro e treina só um par de matrizes pequenas encaixadas em cada camada de atenção. Você treina algo entre 0,1% e 2% do total de parâmetros. O resultado é um arquivo de algumas dezenas de megabytes — o "adaptador" — que se aplica sobre o modelo original na hora de servir.
QLoRA vai além: carrega o modelo base em 4 bits e treina o adaptador em cima. Corta a VRAM de novo pela metade ou mais, com perda de qualidade que, na prática, quase ninguém consegue medir em tarefas de comportamento.
A consequência prática mais subestimada
Como o adaptador é um arquivo pequeno e separado, você pode ter vários sobre o mesmo modelo base: um para classificar chamados, outro para resumir laudos, outro para o tom da sua marca. Trocar de adaptador é trocar de arquivo, não de máquina. Quem trata cada tarefa como "um modelo treinado inteiro" acaba pagando três GPUs para fazer o trabalho de uma.
Quantos exemplos são suficientes
Menos do que a intuição sugere, e a qualidade importa muito mais que a quantidade.
| Objetivo | Exemplos | Observação |
|---|---|---|
| Formato de saída fixo (JSON, campos) | 200–500 | O ganho satura rápido; passar de mil raramente muda algo. |
| Tom e estilo da marca | 500–1.500 | Precisa de variedade de assunto, senão o modelo decora tema em vez de tom. |
| Classificação em categorias próprias | 50–200 por classe | Classe rara com 5 exemplos vai ser ignorada — melhor juntar em "outros". |
| Jargão e vocabulário técnico | 1.000+ | E ainda assim, verifique se recuperação de documentos não resolve melhor. |
Uma regra que economiza semanas: 300 exemplos revisados por uma pessoa que entende do assunto valem mais que 30 mil raspados automaticamente. O modelo aprende os seus erros com a mesma eficiência com que aprende os seus acertos. Se 5% do seu conjunto tem a resposta errada, você está pagando para ensinar isso.
Separe 10% dos exemplos ANTES de treinar e nunca os mostre ao treino. É o seu conjunto de avaliação. Sem ele você não tem como saber se o ajuste melhorou ou piorou — e o modelo ajustado sempre parece melhor para quem o treinou.
Avalie também o modelo base, sem adaptador, no mesmo conjunto. Já vimos ajuste que ficou 4 pontos abaixo do modelo original e ninguém percebeu porque ninguém mediu o antes.
Que GPU o seu tamanho pede
Regra prática para QLoRA (base em 4 bits), com contexto de 2.048 tokens e lote pequeno:
| Tamanho do modelo | VRAM mínima | Placa confortável | Preço/hora |
|---|---|---|---|
| Até 3B | 8 GB | RTX A4000 16 GB | R$ 1,07 |
| 7B – 9B | 16 GB | RTX 3090 24 GB | R$ 1,27 |
| 12B – 14B | 24 GB | RTX 4090 24 GB | R$ 2,78 |
| 30B – 34B | 48 GB | L40S 45 GB | R$ 7,08 |
| 70B | 80 GB | A100 80 GB | R$ 11,05 |
Preços de agosto de 2026, para uma GPU avulsa, sem interrupção programada. O catálogo muda: confira a vitrine antes de fechar a conta.
Repare que a coluna que dói não é a do preço por hora — é a do tempo. E o tempo depende do tamanho do conjunto, não do tamanho do modelo, na faixa em que a maioria opera.
A conta de um treino real
Caso típico: modelo de 8B, 800 exemplos de mais ou menos 600 tokens cada, três passagens pelo conjunto (três épocas).
- Tokens processados: 800 × 600 × 3 ≈ 1,4 milhão
- Numa RTX 3090, com QLoRA, isso sai em torno de 40 a 70 minutos
- Some 15 minutos para baixar o modelo base e preparar o ambiente
- Custo: cerca de 1,5 hora × R$ 1,27 ≈ R$ 1,90
Sim, menos de dois reais. O treino em si é a parte barata e é por isso que ele engana: o custo verdadeiro do projeto está em montar o conjunto de exemplos e em avaliar o resultado — que é trabalho de gente, não de GPU. Quem começa alugando a placa mais cara antes de ter 300 exemplos revisados inverteu a ordem.
Uma tarde de GPU custa menos que um café da equipe
Placas de 16 a 24 GB por hora, com cobrança em reais e sem assinatura. Você liga, treina, baixa o adaptador e desliga.
Criar conta →O passo a passo
1. Formate os exemplos
O formato de conversa é o padrão de fato e o que menos dá dor de cabeça. Um exemplo por linha, num arquivo .jsonl:
{"messages": [
{"role": "system", "content": "Você classifica chamados de suporte em: cobranca, acesso, desempenho, duvida, outros. Responda só a categoria."},
{"role": "user", "content": "não consigo entrar, diz que a senha expirou"},
{"role": "assistant", "content": "acesso"}
]}
Duas coisas que valem a revisão: o system deve ser o mesmo que você vai usar em produção (se mudar depois, o adaptador perde parte do efeito), e a resposta do assistant deve estar exatamente na forma que você quer receber — sem "A categoria é:" na frente, sem ponto final extra, sem variação de maiúscula. O modelo copia o que vê, inclusive a inconsistência.
2. Suba a máquina e instale
pip install "transformers>=4.44" peft trl bitsandbytes accelerate datasets
3. O script de treino
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig
from trl import SFTTrainer, SFTConfig
import torch
BASE = "Qwen/Qwen3-8B" # troque pelo modelo aberto que você escolheu
quant = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
tok = AutoTokenizer.from_pretrained(BASE)
modelo = AutoModelForCausalLM.from_pretrained(
BASE, quantization_config=quant, device_map="auto", torch_dtype=torch.bfloat16
)
lora = LoraConfig(
r=16, # capacidade do adaptador
lora_alpha=32, # convenção: 2x o r
lora_dropout=0.05,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
task_type="CAUSAL_LM",
)
dados = load_dataset("json", data_files={
"train": "treino.jsonl", "test": "validacao.jsonl"
})
cfg = SFTConfig(
output_dir="./adaptador",
num_train_epochs=3,
per_device_train_batch_size=2,
gradient_accumulation_steps=8, # lote efetivo = 16
learning_rate=2e-4,
lr_scheduler_type="cosine",
warmup_ratio=0.03,
logging_steps=10,
eval_strategy="epoch",
save_strategy="epoch",
bf16=True,
max_seq_length=2048,
gradient_checkpointing=True, # troca velocidade por VRAM
)
SFTTrainer(model=modelo, args=cfg, peft_config=lora,
train_dataset=dados["train"], eval_dataset=dados["test"],
processing_class=tok).train()
4. Leia a curva antes de comemorar
Ao fim de cada época o treinador imprime a perda de treino e a de validação. O que você quer ver: as duas caindo. Se a de treino cai e a de validação sobe, o modelo está decorando os exemplos — pare na época anterior. É o problema mais comum e ele não aparece em nenhum teste que você faça com os mesmos exemplos do treino.
Os quatro botões que realmente importam
| Parâmetro | Comece em | Aumente se… | Diminua se… |
|---|---|---|---|
r (capacidade) | 16 | a tarefa é complexa e a perda estagnou alto | está decorando; 8 costuma bastar para formato |
learning_rate | 2e-4 | a perda quase não se move | a perda oscila ou explode; tente 1e-4 |
num_train_epochs | 3 | validação ainda caindo na 3ª | validação subiu — o clássico |
| lote efetivo | 16 | treino instável e você tem VRAM sobrando | estourou a memória |
Se estourar a VRAM: reduza per_device_train_batch_size para 1 e compense subindo gradient_accumulation_steps. O lote efetivo é o produto dos dois — você mantém a matemática do treino e paga em tempo, não em memória.
Servir o resultado
Você tem duas opções, e a escolha muda o custo mensal.
Adaptador separado — o servidor carrega o modelo base e aplica o adaptador em tempo de execução. Vantagem: vários adaptadores no mesmo servidor, troca instantânea. É o caminho certo quando você tem mais de uma tarefa ajustada.
Fundido no modelo — você soma o adaptador aos pesos e salva um modelo novo. Perde a flexibilidade, ganha um pouco de velocidade e simplicidade. É o caminho de quem tem uma tarefa só.
# fundir
from peft import PeftModel
base = AutoModelForCausalLM.from_pretrained(BASE, torch_dtype=torch.bfloat16)
final = PeftModel.from_pretrained(base, "./adaptador").merge_and_unload()
final.save_pretrained("./modelo-final")
tok.save_pretrained("./modelo-final")
Treine com QLoRA se precisar, mas na hora de fundir carregue o modelo base em bf16, como no exemplo acima. Fundir sobre a versão quantizada acumula erro de arredondamento e o resultado costuma ficar pior que o modelo original — um bug silencioso, porque nada falha, só piora.
Quando o ajuste não vai salvar você
- O modelo base é ruim para a tarefa. LoRA ajusta a borda, não muda a natureza. Se o modelo de 3B não raciocina o suficiente, treiná-lo não vai criar raciocínio — troque de base.
- Você quer que ele saiba de fatos novos. Já dito, mas é o pedido que mais volta. Recuperação de documentos, sempre.
- Os exemplos discordam entre si. Se dois anotadores classificaram o mesmo caso de formas diferentes, o modelo aprende a média — que é a resposta errada nos dois casos. Alinhe o critério antes.
- Você não tem como medir. Sem conjunto de avaliação, ajustar é fé. E fé sai cara em produção.
Conclusão
LoRA é uma das melhores relações custo-benefício do ramo: dois reais de GPU e uma tarde transformam um modelo genérico num que responde exatamente no formato do seu sistema, com o tom do seu produto. O que quase ninguém conta é que o gargalo nunca foi a GPU — é ter 300 exemplos bons e um conjunto de avaliação honesto.
Comece pelo teste de trinta segundos. Se o prompt bem escrito já resolve, você acabou de economizar uma semana. Se não resolve, agora você sabe exatamente o que treinar, com quantos exemplos e em qual placa.
Continue: fine-tuning para pesquisa · quantização e VRAM · medir se melhorou