Ajuste Fino Supervisionado
O que é Ajuste Fino Supervisionado (Supervised Fine-Tuning, SFT)?
O ajuste fino supervisionado (supervised fine-tuning, SFT) é uma forma comum de adaptar um modelo de linguagem grande (large language model, LLM) pré-treinado (pretrained) para seguir instruções e executar tarefas específicas com mais confiabilidade. No SFT, você pega um modelo que já aprendeu padrões gerais de linguagem durante o pré-treinamento (pretraining) e continua treinando-o em um conjunto de dados rotulado (labeled dataset) de exemplos de instrução–resposta (às vezes chamado de ajuste por instruções (instruction tuning)).
Conceitualmente, o SFT trata um LLM como um gerador condicional (conditional generator):
- Entrada: uma instrução (e, opcionalmente, contexto extra como um documento, saída de ferramentas ou histórico de conversa)
- Alvo: uma resposta desejada escrita por um humano (ou por um modelo de alta qualidade)
Ao otimizar o modelo para reproduzir as respostas-alvo, o SFT ensina como responder nos estilos, formatos e comportamentos que você deseja.
O SFT normalmente faz parte de um pipeline mais amplo de adaptação de LLM:
- Pré-treinamento em grandes textos não rotulados (predição do próximo token (next-token prediction))
- SFT em dados rotulados de instrução–resposta
- Etapas opcionais de otimização de preferências / alinhamento (preference optimization / alignment) (por exemplo, abordagens no estilo aprendizado por reforço com feedback humano (Reinforcement Learning from Human Feedback, RLHF))
Este artigo foca na etapa de SFT: formatos de dados, objetivo de treinamento e considerações práticas — e como o SFT se relaciona com métodos eficientes em parâmetros, como LoRA (Adaptação de Baixa Patente; Low-Rank Adaptation) sob o guarda-chuva de Ajuste Fino Eficiente em Parâmetros (PEFT; Parameter-Efficient Fine-Tuning).
Por que o SFT funciona para LLMs
O pré-treinamento ensina a um LLM padrões linguísticos e factuais amplos usando predição do próximo token. No entanto, modelos pré-treinados não são necessariamente bons em:
- Seguir instruções explícitas (“Escreva um objeto JSON com os campos X e Y”)
- Recusar solicitações inseguras de forma consistente
- Produzir saídas estruturadas (structured outputs) com confiabilidade
- Adotar um tom ou estilo de domínio específico (jurídico, médico, suporte ao cliente)
- Lidar com convenções de chat de múltiplos turnos (papéis system/user/assistant)
O SFT resolve isso fornecendo supervisão direta: dada esta instrução/contexto, produza esta resposta. Após o SFT, o modelo tende a ser:
- Mais prestativo e melhor em seguir instruções
- Mais consistente na formatação
- Melhor nas tarefas representadas no conjunto de treinamento
O SFT não concede magicamente novas capacidades fora da distribuição dos dados; ele, em geral, melhora comportamentos que estão presentes no conjunto de dados e que são compatíveis com o conhecimento latente do modelo pré-treinado.
Formatos comuns de dados para SFT
Conjuntos de dados de SFT vêm em múltiplas formas, mas todos se reduzem ao mesmo padrão de treinamento: concatenar um contexto semelhante a um prompt (prompt) com uma resposta-alvo e, então, treinar o modelo para prever os tokens (tokens) da resposta.
1) Instrução–resposta de turno único (o “instruction tuning” clássico)
Um formato JSONL comum é:
{"instruction": "Summarize the following text in 2 sentences.", "input": "Text: ...", "output": "Two-sentence summary ..."}
Muitas vezes input é opcional. Na hora do treinamento, você o converte em um modelo de prompt, como:
Instruction: Summarize the following text in 2 sentences.
Input: Text: ...
Response: Two-sentence summary ...
2) Formato de chat / mensagens (conversas de múltiplos turnos)
Muitos LLMs modernos são treinados com “papéis” (roles) explícitos (system/user/assistant). Um formato típico:
{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a haiku about compilers."},
{"role": "assistant", "content": "Parsing the quiet\nTokens fall in ordered streams\nErrors fade to null"}
]
}
Para treinamento com múltiplos turnos, você pode incluir vários pares user/assistant, em que o modelo aprende a gerar cada turno do assistente condicionado ao histórico.
3) Formato “Prompt + completion” (APIs no estilo completion)
Alguns conjuntos de dados armazenam exatamente o que o modelo vê e o que ele deve completar (completion):
{"prompt": "<|user|>Explain gradient descent.\n<|assistant|>", "completion": "Gradient descent is ..."}
Esse formato é conveniente porque mapeia diretamente para o treinamento de predição do próximo token, mas você precisa ter cuidado com onde o modelo está autorizado a aprender (ver “mascaramento da perda (loss masking)” abaixo).
4) Saídas estruturadas (JSON, XML, chamadas de função)
O SFT é amplamente usado para impor saídas estruturadas:
{
"instruction": "Extract entities and return valid JSON with keys: people, orgs.",
"input": "Apple hired Jane Doe from Acme Corp.",
"output": "{\"people\": [\"Jane Doe\"], \"orgs\": [\"Apple\", \"Acme Corp\"]}"
}
Na prática, você frequentemente mistura exemplos estruturados e não estruturados para evitar fragilidade.
O objetivo de treinamento: entropia cruzada nos tokens-alvo
O SFT normalmente usa o objetivo padrão de modelagem de linguagem: maximizar a verossimilhança dos tokens de resposta desejados dado o contexto do prompt. De forma equivalente, minimizar a perda de entropia cruzada (cross-entropy loss) (Perda de Entropia Cruzada) sobre os tokens-alvo.
Dada uma sequência de tokens dividida em:
- tokens de prompt/contexto: (x_{1:m})
- tokens de alvo/resposta: (y_{1:n})
O SFT treina o modelo para prever cada próximo token-alvo:
[ \mathcal{L} = -\sum_{t=1}^{n} \log p_\theta(y_t \mid x_{1:m}, y_{1:t-1}) ]
Essa é a mesma mecânica do pré-treinamento (predição do próximo token) usando Arquitetura Transformer, otimizada via Retropropagação e Descida do Gradiente — mas aplicada a sequências rotuladas por instruções.
Teacher forcing e por que isso importa
Durante o treinamento, o modelo recebe os tokens anteriores de verdade-terreno (forçamento do professor (teacher forcing)), e não suas próprias saídas amostradas. Isso torna a otimização estável e eficiente, mas também significa:
- O modelo aprende a imitar as respostas do conjunto de dados de perto
- Erros podem se acumular no tempo de inferência se o modelo se desviar do estilo de resposta esperado (uma forma de viés de exposição (exposure bias))
Mascaramento da perda (treinar apenas nos tokens do assistente)
No SFT de chat, é comum computar a perda apenas nos tokens do assistente, e não nos tokens de system/user. Ou seja, você alimenta a conversa inteira como entrada, mas só penaliza erros nos turnos do assistente.
Por quê?
- Em geral, você não quer que o modelo “aprenda” a produzir mensagens do usuário
- Você quer que a massa de probabilidade do modelo se concentre em gerar boas respostas do assistente, e não em reproduzir o prompt
Concretamente, a maior parte do código de treinamento constrói labels iguais aos IDs de tokens de entrada, e então define os rótulos como -100 (ignore index) para tokens que não devem contribuir para a perda (tokens de system/user/prefixo).
Exemplo prático: uma amostra de treinamento do início ao fim
Suponha que queremos ensinar o modelo a responder em um modelo específico.
Instrução
Classifique o sentimento como Positivo, Neutro ou Negativo. Produza apenas o rótulo.
Entrada
“A atualização corrigiu minhas quedas, mas a interface ainda é confusa.”
Alvo
Neutro
Um modelo de prompt simples poderia ser:
Instruction: Classify the sentiment as Positive, Neutral, or Negative. Output only the label.
Text: The update fixed my crashes, but the UI is still confusing.
Answer:
O modelo é treinado para gerar Neutral após Answer:.
Se você incluir muitos exemplos desse tipo, o SFT tende a melhorar:
- Seguir “Output only the label”
- Não adicionar explicação extra
- Formatação consistente entre tarefas
Qualidade do conjunto de dados: o principal fator dos resultados de SFT
Para SFT, a qualidade dos dados geralmente importa mais do que a quantidade de dados a partir de certo ponto. Dimensões-chave:
Correção e utilidade
Se seu conjunto de dados contém respostas erradas, o modelo irá aprendê-las. Até problemas sutis — como respostas que soam confiantes, mas são vagas — podem aumentar comportamento semelhante a alucinações (hallucination).
Verificações práticas:
- Amostrar e revisar manualmente exemplos
- Usar validadores automatizados para saídas estruturadas (por exemplo, checagens de parse de JSON)
- Filtrar respostas com contradições, recusas quando ajuda é apropriada, ou verbosidade excessiva
Diversidade e cobertura de instruções
Se você treinar apenas em sumarização, não espere grandes melhorias em geração de código. Seu conjunto de dados deve refletir a distribuição das tarefas que você considera importantes:
- Perguntas e respostas, extração, reescrita, classificação, arcabouço para uso de ferramentas, etc.
- Diferentes domínios (documentação de produto, tickets de suporte, wiki interna, texto jurídico)
Uma estratégia comum é misturar múltiplos tipos de tarefa para melhorar o seguimento geral de instruções.
Consistência de estilo e políticas
Se metade do seu conjunto de dados responde de forma breve e metade responde com longas redações, o modelo fará uma média disso. Se o comportamento de segurança for inconsistente (às vezes recusando, às vezes atendendo), o modelo também será inconsistente.
Defina e imponha:
- diretrizes de tom (conciso vs verboso)
- limites da política de recusa
- política de citação ou de “dizer que não sabe”
Vazamento e contaminação de dados
Se benchmarks de avaliação aparecerem nos dados de treinamento, os resultados se tornam enganosos. Isso é uma forma de vazamento de dados (data leakage).
Mitigações:
- Deduplicar contra conjuntos de avaliação (correspondência exata e aproximada)
- Usar divisões baseadas no tempo quando possível (treinar com dados mais antigos, testar com dados mais novos)
- Rastrear cuidadosamente a proveniência do conjunto de dados
Sobreajuste, esquecimento catastrófico e generalização
SFT é aprendizado supervisionado; ele pode sofrer sobreajuste como qualquer outro.
Sintomas de sobreajuste
- A perda de treinamento diminui enquanto a perda de validação aumenta
- O modelo fica excessivamente “guiado por template”, frágil a variações do prompt
- O modelo tem pior desempenho em tarefas gerais que antes conseguia resolver
Mitigações:
- Parada antecipada (early stopping) com base em métricas de validação
- Taxas de aprendizado menores (comum em ajuste fino de LLM)
- Regularização (decaimento de pesos (weight decay)), dropout (dropout) (se habilitado)
- Aumentar o tamanho/diversidade do conjunto de dados, melhorar a qualidade dos rótulos
Esquecimento catastrófico
Se você fizer SFT intensivamente em dados estreitos (por exemplo, cláusulas de contratos jurídicos), o modelo pode perder a habilidade de conversa geral ou comportamentos de conhecimento geral. Isso é chamado de esquecimento catastrófico (catastrophic forgetting).
Mitigações comuns:
- Misturar dados gerais de instruções
- Misturar uma pequena quantidade de texto geral (às vezes chamado de “replay”)
- Usar taxas de aprendizado menores e menos épocas (epochs)
- Usar métodos eficientes em parâmetros para restringir atualizações (ver abaixo)
Considerações de configuração de treinamento (o que praticantes ajustam)
Taxa de aprendizado e número de épocas
LLMs são sensíveis à taxa de aprendizado. Padrões típicos:
- O ajuste fino completo (full fine-tuning) frequentemente usa taxas de aprendizado pequenas (por exemplo, na faixa de 1e-6 a 2e-5, altamente dependente do tamanho do modelo e dos dados)
- 1–3 épocas é comum; mais pode causar sobreajuste, a menos que o conjunto de dados seja grande e diverso
Comprimento de sequência, empacotamento e formação de lotes
Exemplos de SFT podem ser curtos (classificação) ou longos (chat de múltiplos turnos). Treinamento eficiente frequentemente usa:
- Empacotamento (packing): concatenar múltiplos exemplos curtos em uma sequência longa para reduzir desperdício com padding
- Atenção cuidadosa para não “contaminar” rótulos entre exemplos empacotados (os tokens de prompt de cada exemplo devem permanecer mascarados adequadamente)
Tokenização e tokens especiais
Seu formato de prompt deve corresponder aos tokens esperados pelo modelo (por exemplo, marcadores de papel em chat). Formatação incompatível pode causar grandes regressões de qualidade, porque o modelo foi pré-treinado ou ajustado por instruções com uma convenção específica (Tokenização também é relevante).
Avaliação: além da perda
A perda de validação é útil, mas não suficiente. Uma boa avaliação frequentemente inclui:
- Métricas específicas de tarefa (accuracy/F1 para classificação, ROUGE para sumarização, pass@k para código, etc.)
- Métricas de aderência a formato (taxa de parse de JSON)
- Avaliação humana de utilidade, factualidade e segurança
- Testes de regressão (regression tests) para comportamentos conhecidos (“não revela segredos”, “usa o esquema (schema) exigido”, etc.)
Ajuste fino completo vs PEFT: onde o LoRA se encaixa
SFT descreve o objetivo de treinamento e os dados (instrução–resposta supervisionada). Como você aplica atualizações aos parâmetros do modelo é uma escolha separada:
- Ajuste fino completo: atualizar todos (ou a maioria) dos pesos do modelo
- Ajuste fino eficiente em parâmetros (PEFT): atualizar um pequeno número de parâmetros enquanto congela o modelo-base (base model)
Métodos de PEFT são descritos com mais detalhes em Ajuste Fino Eficiente em Parâmetros (PEFT). Uma técnica de PEFT amplamente usada para SFT é o LoRA (Adaptação de Baixa Patente; Low-Rank Adaptation).
Por que usar LoRA para SFT?
O LoRA injeta pequenas matrizes de baixa patente treináveis em certas camadas lineares (frequentemente projeções de atenção (attention) e/ou do perceptron multicamadas (multi-layer perceptron, MLP)). Benefícios:
- Uso de memória de vídeo (VRAM) muito menor do que no ajuste fino completo
- Treinamento mais rápido e experimentação mais fácil
- Você pode manter múltiplos “adaptadores (adapters)” para diferentes tarefas/domínios sobre um único modelo-base
- Frequentemente reduz o esquecimento catastrófico porque os pesos-base ficam congelados
Trade-offs:
- A qualidade de pico pode ser ligeiramente menor do que no ajuste fino completo em alguns cenários (embora frequentemente comparável)
- Exige escolha cuidadosa de módulos-alvo, posto (rank) e escala (scaling)
Na prática, muitas equipes adotam SFT + LoRA como linha de base padrão: é custo-efetivo e tipicamente forte.
Como o SFT se relaciona com outros métodos de alinhamento
O SFT ensina o modelo a imitar “boas respostas”. No entanto, conjuntos de dados de instruções geralmente contêm uma resposta escolhida por prompt, e não codificam explicitamente preferências entre múltiplas respostas.
Outras etapas de alinhamento (frequentemente aplicadas após o SFT) usam comparações ou recompensas para moldar o comportamento:
- Aprendizado de preferências: “A resposta A é melhor do que a resposta B”
- Modelagem de recompensa (reward modeling) + aprendizado por reforço (reinforcement learning) (estilo RL)
- Variantes de otimização direta de preferências (direct preference optimization)
O SFT ainda é fundamental porque:
- Fornece uma inicialização supervisionada forte para alinhamento posterior
- Ensina seguimento básico de instruções e formatação
- Métodos de preferência geralmente funcionam melhor quando o modelo já produz candidatos razoáveis
Armadilhas comuns no SFT (e como evitá-las)
Treinar com dados sintéticos de baixa qualidade sem filtragem
Dados sintéticos de instrução podem ajudar, mas, se você gerar grandes volumes sem controle de qualidade, o modelo pode aprender:
- texto prolixo de preenchimento
- raciocínio incorreto
- comportamento de recusa e segurança inconsistente
Mitigação: use filtros fortes (heurísticas (heuristics) + avaliadores baseados em modelo (model-based judges)) e mantenha um conjunto central revisado por humanos.
Templates de prompt inconsistentes
Se seu conjunto de dados usa múltiplos templates incompatíveis (“### Instruction”, “User:”, diferentes tokens de papel), o modelo pode ficar confuso.
Mitigação: padronize em um formato canônico alinhado à convenção de chat do modelo-base.
Não mascarar os tokens do prompt
Se você computa a perda sobre toda a sequência concatenada (prompt + resposta), o modelo pode aprender a reproduzir o prompt e os papéis. Isso pode causar comportamentos estranhos (por exemplo, produzir User: ou repetir instruções).
Mitigação: masque tokens que não sejam do assistente na perda.
Otimizar demais por “utilidade” em detrimento da veracidade
Exemplos de SFT frequentemente recompensam respostas confiantes e completas — mesmo quando o prompt não pode ser respondido.
Mitigação:
- incluir exemplos que corretamente dizem “Eu não sei” ou pedem esclarecimento
- adicionar tarefas que exigem citar o contexto fornecido e recusar fabricar fora dele
Aplicações práticas do SFT
O SFT é amplamente usado para:
- Assistentes de chat: melhor seguimento de instruções, padrões mais seguros, persona consistente
- Adaptação a domínio: por exemplo, helpdesk interno de TI, suporte a redação jurídica, estruturação de notas médicas (com governança apropriada)
- Extração de informação: converter texto não estruturado em campos estruturados
- Rascunho para suporte ao cliente: controle de tom, aderência a políticas, respostas com template
- Assistentes de código: guias de estilo, padrões específicos de API, convenções da empresa
- Chamada de ferramentas / funções (tool / function calling): produzir saídas restritas que acionam ferramentas com confiabilidade
Um padrão recorrente é começar com um modelo-base geral e, em seguida, aplicar SFT em um conjunto de dados cuidadosamente curado que reflita o ambiente-alvo.
Esboço mínimo em pseudo-código (o que “é” o SFT computacionalmente)
Em alto nível, SFT é apenas predição do próximo token em sequências rotuladas:
# Pseudo-code
for batch in dataloader:
input_ids, attention_mask, labels = batch
# labels: -100 for tokens we want to ignore (e.g., user/system tokens)
logits = model(input_ids, attention_mask=attention_mask).logits
loss = cross_entropy(logits.view(-1, vocab_size), labels.view(-1), ignore_index=-100)
loss.backward()
optimizer.step()
optimizer.zero_grad()
Todo o resto — templates, mascaramento, empacotamento, adaptadores, avaliação — determina se este loop simples produz um modelo útil e capaz de seguir instruções.
Resumo
O ajuste fino supervisionado (SFT) adapta um LLM pré-treinado ao treinar em pares rotulados de instrução–resposta, tipicamente usando perda de entropia cruzada nos tokens-alvo (do assistente). É a forma padrão de melhorar o seguimento de instruções, a confiabilidade de formatação e o desempenho em domínio/tarefa — desde que o conjunto de dados seja de alta qualidade e esteja bem alinhado ao comportamento desejado.
Na prática, o sucesso do SFT depende fortemente de:
- dados curados, consistentes e alinhados a políticas
- formatação correta e mascaramento da perda
- ajuste cuidadoso para evitar sobreajuste e esquecimento
- escolha entre ajuste fino completo e abordagens eficientes em parâmetros como LoRA (Adaptação de Baixa Patente; Low-Rank Adaptation) dentro de Ajuste Fino Eficiente em Parâmetros (PEFT)
O SFT não é o fim do alinhamento, mas costuma ser a etapa mais impactante e acessível para transformar um LLM geral em um sistema útil e capaz de seguir instruções.