Guia Definitivo: Alinhamento de LLMs com DPO usando Unsloth
Enquanto o Supervised Fine-Tuning (SFT) ensina o modelo a como falar (formato, estilo e sintaxe), o alinhamento ensina o modelo a como pensar e o que preferir. Durante muito tempo, o RLHF (Reinforcement Learning from Human Feedback) foi o padrão da indústria, mas sua arquitetura complexa, exigindo múltiplos modelos rodando simultaneamente (Reward Model, Reference Model), o tornava instável e caro.
É aqui que entra o DPO (Direct Preference Optimization). O DPO elimina a necessidade de um modelo de recompensa separado, otimizando diretamente a política do modelo base usando uma perda estatística ajustada.
Neste guia, vamos estruturar um pipeline completo de DPO utilizando a biblioteca Unsloth (que acelera o treinamento em até 2x e reduz drasticamente o uso de VRAM) e a biblioteca TRL (Transformer Reinforcement Learning) da Hugging Face.
1. O Dataset de Preferências (Chosen vs. Rejected)
O coração do DPO é o dataset. Em vez de apenas fornecer a resposta certa, você fornece um prompt e duas saídas: uma que o modelo deve imitar (chosen) e outra que ele deve evitar (rejected).
Isso é especialmente crítico em domínios que exigem rigor técnico e raciocínio lógico. A diferença entre uma resposta aceita e rejeitada não é apenas sobre tom de voz, mas sobre a metodologia e o Chain of Thought (CoT) aplicado.
Estrutura do Dataset (Formato JSONL)
{
"prompt": "Paciente do sexo masculino, 45 anos, relata dor no peito irradiando para o braço esquerdo há 30 minutos, acompanhada de sudorese fria. Qual a suspeita e conduta?",
"chosen": "A apresentação clínica é altamente sugestiva de Síndrome Coronariana Aguda (SCA), possivelmente um Infarto Agudo do Miocárdio (IAM). A conduta imediata envolve acionamento do serviço de emergência, monitoramento de sinais vitais, administração de AAS (se não houver contraindicações) e realização de um ECG de 12 derivações em até 10 minutos após o primeiro contato médico para classificar o risco e guiar a terapia de reperfusão.",
"rejected": "O paciente provavelmente está tendo um ataque cardíaco. Você deve dar aspirina imediatamente e fazer uma cirurgia de ponte de safena. Pode ser ansiedade também, então espere um pouco para ver se melhora."
}
Nota: No cenário acima, o
chosendemonstra diretrizes estruturadas e seguras, enquanto orejectedpula etapas diagnósticas e fornece conclusões precipitadas. É essa "bússola moral e técnica" que o DPO ajusta.
2. Configurando o Ambiente com Unsloth
O Unsloth otimiza as operações matemáticas por trás do LoRA (Low-Rank Adaptation) e da atenção, permitindo rodar fine-tuning de modelos pesados (como Llama 3 ou Mistral) em GPUs de consumo.
Instalação das dependências
pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
pip install --no-deps trl peft accelerate bitsandbytes
Carregando o Modelo
import torch
from unsloth import FastLanguageModel
from datasets import load_dataset
from trl import DPOTrainer, DPOConfig
# Configurações do modelo
max_seq_length = 2048
dtype = None # Auto detecção (Bfloat16 se suportado)
load_in_4bit = True # Essencial para economizar VRAM
# 1. Carregando o Modelo e Tokenizer via Unsloth
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "mistralai/Mistral-7B-Instruct-v0.2",
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
)
# 2. Aplicando PEFT / LoRA
model = FastLanguageModel.get_peft_model(
model,
r = 16, # Rank do LoRA (capacidade de aprendizado)
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
lora_alpha = 16,
lora_dropout = 0, # Unsloth exige dropout = 0 para otimização
bias = "none",
use_gradient_checkpointing = "unsloth",
)
3. O Treinamento (DPOTrainer)
Com o modelo pronto, passamos para o DPOTrainer. O hiperparâmetro mais importante aqui é o beta. Ele atua como um regularizador KL, controlando o quanto o modelo pode desviar da sua política de referência original. Um beta típico varia entre 0.1 e 0.5.
# Carregar o dataset formatado (Hugging Face datasets)
dataset = load_dataset("seu_usuario/seu_dataset_dpo", split="train")
# Configurações do DPO
dpo_config = DPOConfig(
beta = 0.1, # Fator de regularização KL
per_device_train_batch_size = 2,
gradient_accumulation_steps = 4,
learning_rate = 5e-6, # Atenção: LR no DPO deve ser BEM menor que no SFT
lr_scheduler_type = "cosine",
max_steps = 200,
optim = "adamw_8bit", # Otimizador em 8-bit para poupar memória
output_dir = "outputs_dpo",
)
trainer = DPOTrainer(
model = model,
ref_model = None, # O Unsloth gerencia o ref_model automaticamente sob o capô
tokenizer = tokenizer,
train_dataset = dataset,
args = dpo_config,
)
# Iniciar o treinamento
trainer.train()
4. Monitorando a Perda (Loss) e Evitando o Colapso
O treinamento DPO é mais sensível e propenso a over-fitting do que o SFT padrão. Se não for monitorado, o modelo pode sofrer de Reward Hacking (onde ele encontra uma brecha estatística para maximizar a recompensa sem melhorar a utilidade real).
Ao monitorar os logs no Weights & Biases (W&B) ou TensorBoard, observe estas três métricas cruciais:
- Margem de Recompensa (Reward Margin): A diferença entre a recompensa da resposta
chosene arejected. Ela deve aumentar ao longo do tempo e depois estabilizar. - Loss: A perda do DPO deve cair consistentemente. Se começar a subir ou oscilar violentamente, seu
learning_rateestá muito alto ou seubetaestá muito baixo. - Chosen vs Rejected Rewards: Ambas podem diminuir em valores absolutos, mas a linha da Rejected Reward deve cair muito mais rápido que a da Chosen.
5. Próximos Passos e Exportação
Após a conclusão do treinamento, você vai querer testar o modelo e possivelmente quantizá-lo para rodar localmente de forma eficiente (ex: via Ollama ou LM Studio). O Unsloth facilita a exportação direta para o formato GGUF.
# Salvar o modelo LoRA padrão
model.save_pretrained("modelo_dpo_lora")
# Exportar diretamente para GGUF (Quantização Q4_K_M - excelente custo-benefício de VRAM/Velocidade)
model.save_pretrained_gguf("modelo_dpo_gguf", tokenizer, quantization_method = "q4_k_m")
6. Referências e Links Úteis
Para aprofundar seus estudos, construir datasets robustos e acompanhar as atualizações das bibliotecas usadas neste guia, confira os materiais abaixo:
Artigos e Documentação Oficial
- Paper Original do DPO (arXiv): "Direct Preference Optimization: Your Language Model is Secretly a Reward Model" (Rafailov et al., 2023) - O artigo acadêmico fundamental que introduziu a técnica e a matemática por trás da eliminação do modelo de recompensa.
- Documentação do TRL (Hugging Face): Guia oficial do
DPOTrainerdetalhando todos os hiperparâmetros disponíveis para ajuste fino. - Repositório Oficial do Unsloth: GitHub da biblioteca. Vale a pena acompanhar as releases, pois eles adicionam suporte otimizado para novos modelos de ponta constantemente.
Ferramentas e Datasets para Alinhamento
- Argilla: Uma excelente plataforma open-source para curadoria de dados e criação de datasets de preferências humanas com interface gráfica.
- UltraFeedback (Hugging Face): Um dos maiores e mais utilizados datasets open-source de preferências (Chosen/Rejected) para treinar modelos de alinhamento.
Inferência e Quantização (Rodando o Modelo Localmente)
- llama.cpp: O motor principal (escrito em C/C++) para rodar os arquivos
.ggufque exportamos no Passo 5, extraindo o máximo de performance da CPU e GPU. - Ollama e LM Studio: As melhores interfaces para carregar o seu modelo GGUF alinhado e conversar com ele na sua máquina local, garantindo total privacidade dos dados.