Guia de Fine-Tuning de LLM: LoRA, QLoRA, Unsloth, Axolotl
Tradução automática Este artigo foi traduzido automaticamente a partir da versão original em inglês.
A maioria das falhas de fine-tuning são falhas de decisão. Uma equipa treina antes de provar que prompting, retrieval ou constrained decoding não conseguem resolver o problema. Outra avalia na distribuição de treino, ou descobre depois do treino que o artefacto é difícil de servir.
Este guia trata a adaptação como uma experiência com uma saída operacional. Começa pelo limite de decisão e segue depois um percurso por dados, LoRA ou QLoRA, avaliação específica da tarefa, exportação e serving.
Para uma decisão rápida sobre a intervenção, consulte Fine-Tuning vs RAG vs Prompting.
Deve mesmo fazer fine-tuning?
Antes de gastar horas de GPU, decida se o fine-tuning é a ferramenta certa para o problema que tem à frente.
Fine-tuning vs RAG
O fine-tuning pode alterar a forma como um modelo usa a linguagem do domínio, mas é um mecanismo fraco para atualizar factos que mudam ou que têm de ser citados. Retrieval e fine-tuning resolvem partes diferentes do problema e pertencem frequentemente ao mesmo sistema.
| Característica | Fine-Tuning | RAG (Retrieval-Augmented Generation) |
|---|---|---|
| Função principal | Altera os pesos internos para ensinar competências, estilos ou comportamentos | Fornece contexto externo e atualizado em tempo de inferência |
| Mais indicado para | • Estilos conversacionais específicos • Seguir instruções complexas • Raciocínio específico do domínio | • Dados que mudam rapidamente (notícias, cotações) • Redução de alucinações (grounding) • Citação de fontes |
| Gestão do conhecimento | Altera o comportamento estatístico nos pesos; a recuperação exata não é garantida | Obtém registos ou excertos que podem ser atualizados e citados |
| Frequência de atualização | Requer novo treino para atualizações | Atualiza imediatamente com novos documentos |
Fine-tuning vs prompt engineering
Os LLMs modernos respondem bem a prompts claros e exemplos. Teste essas opções antes de investir em fine-tuning.
| Aspeto | Fine-Tuning | Prompt Engineering |
|---|---|---|
| Custo de preparação | Elevado (curadoria de dados, computação em GPU, iteração) | Baixo (refinamento iterativo do prompt) |
| Flexibilidade | Requer outro ciclo de treino e release | Altera-se com o prompt |
| Formato/estilo | Pode tornar um comportamento repetido mais provável | Muitas vezes suficiente para estilo e formatos simples |
| Latência | Pode encurtar instruções repetidas | Depende do comprimento do prompt e do caching do provider |
| Mais indicado para | Comportamentos complexos, distillation, custo à escala | Iteração rápida, requisitos variáveis |
[!TIP] Experimente prompting primeiro Comece com um prompt e exemplos representativos. Se apenas a sintaxe da saída for pouco fiável, adicione constrained decoding antes de alterar os pesos.
Fine-tuning vs constrained decoding
Bibliotecas como xgrammar e outlines restringem a geração a um JSON schema, expressão regular ou gramática. Dependendo da restrição e do backend, compilam um autómato ou uma gramática e mascaram os tokens seguintes inválidos. Não é necessária qualquer atualização dos pesos.
Isto garante a pertença à linguagem de saída suportada. A garantia não diz nada sobre os valores serem verdadeiros, completos ou semanticamente adequados. Um function call sintaticamente válido pode, ainda assim, conter o ID de cliente errado.
| Aspeto | Constrained Decoding | Fine-Tuning |
|---|---|---|
| Preparação | Imediata — definir o schema, fazer deploy | Requer curadoria de dados, computação em GPU e iteração |
| Garantia | Sintaxe válida para a restrição suportada | Comportamento aprendido; a conformidade com o schema pode variar |
| Flexibilidade | Alterar o schema a qualquer momento sem novo treino | Fica fixo após o treino |
| Latência | Sobrecarga ligeira (o modelo pode “lutar” contra o schema) | Mais baixa (o modelo produz naturalmente o formato) |
| Mais indicado para | JSON, escolhas, gramáticas, sintaxe de tool call | Comportamentos repetidos que faltam ao modelo base |
Uma ordem prática:
- Comece com prompting e exemplos few-shot para formatação básica.
- Adicione constrained decoding (
xgrammarououtlines) quando a sintaxe for inconsistente. - Faça fine-tuning apenas quando precisar de alterações comportamentais que um schema não consiga impor.
Referência rápida: associar problemas a soluções
| Desafio | Primeiro mecanismo a testar | Porquê? |
|---|---|---|
| Conhecimento em falta | RAG | Os modelos alucinam factos. O retrieval fornece contexto fundamentado e atualizado |
| Formato/tom errado | Prompt Engineering | Os modelos modernos seguem bem instruções de estilo através de exemplos few-shot |
| Sintaxe de saída inválida | Constrained decoding | Impõe um schema ou gramática suportados durante a geração |
| Falha repetida numa tarefa | Fine-tuning (SFT) | Aprende com exemplos de entrada/saída selecionados |
| Desalinhamento de preferências par-a-par | Preference optimization | Usa exemplos escolhido/rejeitado depois de o comportamento da tarefa ser mensurável |
| Latência/custo à escala | Distillation (SFT) | Treina um modelo student mais pequeno com as saídas de um teacher maior |
| Reduzir o tamanho do modelo | Quantization | Não requer treino — comprime os pesos (FP16→INT4) para inferência mais rápida |
Torne o caso de negócio mensurável
O fine-tuning pode reduzir tokens recorrentes nos prompts ou permitir que um modelo mais pequeno atinja o objetivo, mas nenhuma destas poupanças é automática. Calcule o ponto de equilíbrio com o seu tráfego e preços:
[ \text{pedidos de equilíbrio} = \frac{\text{custo de treino + avaliação + deployment}} {\text{custo do baseline/pedido} - \text{custo do modelo afinado/pedido}} ]
Se o denominador for pequeno, negativo ou baseado numa suposição de qualidade ainda não comprovada, o projeto ainda não tem um caso económico.
[!TIP] A configuração híbrida Uma arquitetura comum combina um modelo mais pequeno adaptado à tarefa com retrieval para factos variáveis. Trate o modelo maior com prompting como baseline e mantenha o modelo mais pequeno apenas se atingir os mesmos limiares de qualidade e segurança específicos da tarefa.
Tipos de fine-tuning
Existem três formas principais de fazer fine-tuning. Diferem no tipo de dados de que precisam e no que ensinam ao modelo.
1. Continued pre-training (self-supervised)
Treina o modelo base com mais texto bruto, usando o token seguinte de cada sequência como alvo de treino. Isto é self-supervised learning: o texto fornece os seus próprios alvos, tal como na execução original de pre-training.
Quando usar:
- O domínio tem vocabulário que o modelo base nunca viu (medicina, direito, bases de código internas).
- Tem grandes volumes de texto do domínio, mas não tem pares (entrada, saída) anotados.
- O modelo base tem dificuldades com terminologia específica do domínio.
Exemplo: treinar com milhões de notas clínicas para que o modelo aprenda abreviaturas médicas, nomes de medicamentos e fluxos de trabalho clínicos.
2. Supervised fine-tuning (SFT)
O SFT treina com pares anotados (entrada, saída). Mostra ao modelo exatamente a saída pretendida para cada entrada.
Quando usar:
- Tem uma tarefa específica com um formato de entrada/saída limpo.
- Tem dados anotados de qualidade, mesmo que em pouca quantidade.
- Precisa de um comportamento previsível para uma forma de entrada conhecida.
Exemplo: treinar com pares (descrição de consulta SQL, código SQL) para text-to-SQL.
{
"input": "Get all users who signed up last month",
"output": "SELECT * FROM users WHERE signup_date >= DATE_SUB(NOW(), INTERVAL 1 MONTH)"
}
3. Instruction tuning
Instruction tuning é um caso especial de SFT concebido para levar os modelos a seguir uma grande variedade de instruções em linguagem natural. Os dados de treino são pares (instrução, resposta) abrangendo muitas tarefas diferentes.
Quando usar:
- Quer um assistente de uso geral (como ChatGPT ou Claude).
- O modelo precisa de lidar com pedidos variados e abertos.
- Está a construir uma interface de chat.
Exemplo: treinar com milhares de instruções diversas, como “Resuma este artigo”, “Escreva um poema sobre X” ou “Explique Y em termos simples.”
Comparação
| Aspeto | Continued Pre-training | SFT | Instruction Tuning |
|---|---|---|---|
| Dados | Texto bruto | Pares (entrada, saída) | Pares (instrução, resposta) |
| Rótulos | Nenhum (não supervisionado) | Específicos da tarefa | Tarefas diversas |
| Objetivo | Conhecimento do domínio | Comportamento específico da tarefa | Seguir qualquer instrução |
| Volume de dados | Normalmente o maior corpus | Determinado pela cobertura da tarefa e pela diversidade de erros | Normalmente mais abrangente do que o SFT específico da tarefa |
[!NOTE] O que as pessoas fazem na prática SFT e instruction tuning usam o mesmo objetivo de next-token; a distinção está na abrangência e na construção do dataset. Continued pre-training é uma experiência separada e deve ser seguida de testes tanto para ganhos no domínio como para regressões nas capacidades gerais.
O pipeline de fine-tuning em 7 etapas
O fine-tuning é um pipeline, não um comando isolado. Cada etapa tem os seus próprios modos de falha e, normalmente, saltar uma delas acaba por produzir um modelo problemático mais tarde.
Cada etapa assenta na anterior:
- Preparação dos dados — Definir a unidade de avaliação, dividir os dados, limpá-los e formatá-los
- Seleção do modelo — Escolher o modelo base adequado e carregar os pesos
- Configuração do treino — Configurar hardware, hiperparâmetros e estratégia de otimização
- Fine-tuning — Executar treino SFT, DPO ou ORPO
- Avaliação — Medir o desempenho com benchmarks e validar a qualidade
- Deployment — Exportar e servir o modelo
- Monitorização — Acompanhar o desempenho, fazer manutenção e iterar
[!WARNING] Os dados são a base O treino reproduz falhas sistemáticas presentes nos exemplos. Inspecione rótulos, leakage, cobertura e conformidade com políticas antes de gastar tempo em sweeps do otimizador.
Etapa 1: Preparação dos dados
Muitos projetos de fine-tuning falham aqui, não durante o treino. A preparação moderna de dados é mais do que executar uma regex sobre CSVs.
O pipeline de dados em 5 etapas
Ferramentas como DataTrove e Distilabel podem ajudar à escala. Deixe que a taxonomia de falhas e o contrato de dados orientem o desenho do pipeline; a escolha da ferramenta vem depois.
1. Ingestão e filtragem
- Ação: remover recusas (“Não posso responder a isso”), UTF-8 inválido e idiomas que não são o alvo.
- Ferramentas: Trafilatura para extração e modelos de identificação de idioma do fastText para language ID; os modelos distribuídos
lid.176reconhecem 176 idiomas.
2. Política de dados sensíveis
- Ação: decidir o que o modelo pode aprender e, conforme necessário, anonimizar, tokenizar ou excluir campos pessoais e confidenciais.
- Ferramentas: Microsoft Presidio ou scrubadub.
- Porquê: um detector é apenas um controlo; os requisitos de proveniência, consentimento, retenção, acesso e eliminação continuam a aplicar-se.
3. Deduplicação (MinHash LSH)
- Ação: remover near-duplicates para que o modelo não os memorize.
- Ferramentas: DataTrove lida bem com processamento à escala de terabytes.
4. Aumento sintético, se necessário
- Ação: usar um modelo teacher mais forte (GPT-4o, DeepSeek-V3) para reescrever dados brutos em pares limpos de instrução-resposta.
- Ferramentas: Distilabel.
- Validação: amostrar saídas do teacher, verificá-las com a mesma rubrica usada nos rótulos humanos e manter separadas, na avaliação, as parcelas sintéticas e as escritas por humanos.
5. Formatação
- Ação: converter para um formato padrão (Alpaca ou ShareGPT).
Exemplos de formatos de dados
Formato Alpaca (seguimento de instruções):
{
"instruction": "Summarize the following text.",
"input": "The text to be summarized...",
"output": "This is the summary."
}
Formato ShareGPT/ChatML (conversacional):
{
"conversations": [
{ "from": "user", "value": "Hello, who are you?" },
{ "from": "assistant", "value": "I am a helpful AI assistant." }
]
}
O que realmente importa
- Cobertura antes do volume. Adicione exemplos que representem modos de falha distintos, não repetições do caso fácil e maioritário.
- Limpeza. Remova texto irrelevante, normalize espaços em branco e mantenha a formatação consistente.
- Equilíbrio. Preserve casos raros importantes e reporte o desempenho por parcela.
- Separação. Divida por origem, utilizador, documento ou tempo quando divisões aleatórias por linha causarem leakage de near-duplicates.
- Proveniência. Registe a origem, licença ou permissão, histórico de transformações e percurso de eliminação para cada versão do dataset.
Etapa 2: Seleção do modelo e hardware
Escolher o modelo base e compreender o patamar mínimo de GPU determina o que consegue realmente treinar.
Comece pelo modelo base mais pequeno que já passe as verificações não negociáveis do baseline. Confirme:
- os termos de licença e redistribuição para o produto pretendido;
- o comportamento em termos de idioma, domínio, tool use e segurança antes da adaptação;
- a compatibilidade do tokenizer e do chat template com o dataset;
- o contexto máximo e o comportamento de truncation necessários para exemplos reais;
- o suporte tanto no framework de treino como no serving engine de destino.
O fine-tuning é uma etapa de adaptação, não uma correção para um modelo base inadequado. Se o modelo falhar capacidades que o dataset não cobre, escolha outro modelo base antes de executar mais epochs.
Dimensione a execução, não o escalão de marketing
Não existe uma tabela duradoura do tipo “tamanho do modelo → GPU”. A memória de pico varia com a precisão dos pesos, o otimizador, o número de parâmetros treináveis, o comprimento da sequência, o micro-batch, activation checkpointing, a implementação de attention e o overhead do framework. Comece por uma estimativa de memória e execute depois um smoke test curto com comprimento máximo na stack exata.
| Componente de memória | Full fine-tuning | LoRA | QLoRA |
|---|---|---|---|
| Pesos base | Precisão de treino | Congelados, normalmente BF16/FP16 | Congelados, normalmente NF4 de 4 bits |
| Gradientes | Todos os pesos treináveis | Pesos do adapter | Pesos do adapter |
| Estados do otimizador | Todos os pesos treináveis | Pesos do adapter | Pesos do adapter |
| Ativações | Depende do batch e do comprimento da sequência em todos os métodos | Mesma dependência | Mesma dependência |
O artigo original sobre QLoRA conseguiu ajustar um modelo LLaMA 65B numa única GPU de 48 GB na sua configuração específica. Esse resultado é um limite útil, não uma promessa de que todas as arquiteturas atuais de 70B, comprimentos de contexto, kernels ou trainers caberão no mesmo dispositivo.
Cálculos de memória
Para um modelo com parâmetros, só os pesos requerem aproximadamente bytes em BF16/FP16 ou bytes a quatro bits, antes dos metadados de quantization e dos buffers de runtime. O treino completo ao estilo Adam adiciona gradientes, estados do otimizador e, frequentemente, pesos master de maior precisão. LoRA evita a maior parte da memória de estado treinável; QLoRA reduz adicionalmente a ocupação dos pesos base congelados. As ativações podem continuar a dominar com comprimentos de sequência elevados.
Use este fluxo de trabalho:
- Escolha a sequência mais longa e o micro-batch que tem de suportar.
- Estime os pesos e o estado treinável, deixando margem para ativações e kernels.
- Execute um passo de forward/backward com o comprimento máximo.
- Registe a memória de pico alocada e reservada.
- Só depois aumente o batch size, o rank, o comprimento da sequência ou o número de GPUs.
Etapa 3: Métodos de treino (PEFT e LoRA)
Full fine-tuning vs PEFT
O full fine-tuning (FFT) atualiza todos os pesos, pelo que os gradientes e o estado do otimizador escalam com o modelo completo. O pico não pode ser inferido apenas a partir da contagem de parâmetros, mas é muito superior à memória necessária para carregar os pesos em inferência.
O parameter-efficient fine-tuning (PEFT) treina apenas um subconjunto pequeno de parâmetros e congela o resto. A matemática torna-se muito mais favorável.
LoRA: o ponto de partida
LoRA (Low-Rank Adaptation) congela uma matriz pré-treinada e representa a atualização aprendida com duas matrizes mais pequenas. O artigo original motiva esta abordagem com a hipótese de que as atualizações úteis de adaptação têm baixo rank intrínseco.
Para uma matriz congelada , o LoRA aprende:
A camada adaptada é:
O adapter tem parâmetros treináveis, em vez de para essa matriz. Para uma matriz quadrada com largura 4.096 e rank 16, isso representa uma redução de 128× para a matriz, não de 10.000× para um modelo arbitrário. O valor de 10.000× divulgado no artigo do LoRA correspondia a uma configuração específica do GPT-3 175B que adaptava matrizes selecionadas.
Comparação de métodos PEFT
| Método | O que muda | Escolha-o quando |
|---|---|---|
| LoRA | Base congelada mais atualizações treináveis de baixo rank | O modelo base cabe confortavelmente e pretende artefactos pequenos específicos da tarefa |
| QLoRA | LoRA com a base congelada armazenada em formato de 4 bits | A memória dos pesos base é o fator limitante |
| DoRA | Separa a magnitude dos pesos da direção atualizada por LoRA | Um baseline LoRA medido deixa uma lacuna de qualidade que justifica complexidade adicional |
| Full fine-tuning | Todos os pesos do modelo | PEFT não atinge o objetivo e o ganho de qualidade justifica treino distribuído e checkpoints completos |
Quando escolher cada um
- LoRA: comece aqui. É rápido, eficiente em memória e bem suportado.
- QLoRA: quando a mesma experiência com LoRA não cabe devido aos pesos base congelados.
- DoRA: depois de uma comparação direta com LoRA mostrar um ganho útil.
- Full fine-tuning: apenas quando PEFT for um bottleneck avaliado, e não uma suposição.
DoRA: LoRA com decomposição dos pesos
DoRA (Weight-Decomposed Low-Rank Adaptation) separa a magnitude de cada vetor de pesos da sua direção. O artigo do DoRA aplica uma atualização LoRA à componente direcional e aprende a magnitude separadamente.
Como funciona:
Em vez de tratar os pesos como uma entidade única, o DoRA divide os pesos pré-treinados em duas componentes:
- Magnitude — um valor treinável por vetor de pesos.
- Direção — um vetor normalizado atualizado através de matrizes de baixo rank.
Em notação compacta por coluna:
onde:
m= magnitude (treinável)- = a matriz direcional congelada
- = a atualização direcional de baixo rank aprendida
- = normalização por coluna
O que se obtém com essa estrutura adicional:
- Mais graus de liberdade do que com LoRA standard, porque a magnitude pode mudar de forma independente.
- Melhores resultados do que LoRA em várias configurações reportadas pelo artigo que propôs o método.
- Parâmetros e computação adicionais, pelo que o ganho deve ser verificado na sua tarefa e no seu percurso de serving.
Merging de adapters para aprendizagem multi-task
Adapters separados permitem que uma única base congelada suporte várias tarefas. Pode encaminhar pedidos para um adapter, servir vários adapters a partir de um engine quando suportado, ou criar um candidato merged offline. O merging pode introduzir interferência, pelo que deve avaliar o artefacto merged em vez de assumir que os adapters de origem se compõem corretamente.
Métodos comuns de merging:
- Concatenação — combinar parâmetros dos adapters e aumentar o rank efetivo. Rápido e simples.
- Combinação linear — soma ponderada dos adapters. Dá-lhe parâmetros de controlo.
- SVD — decomposição matricial para merging. Mais flexível, mas mais lenta.
Exemplo: um adapter para sumarização e outro para tradução, combinados num único modelo multi-task.
Etapa 4: Fine-tuning e alinhamento de preferências
SFT aprende demonstrações. A preference optimization aprende, em vez disso, a partir de comparações como “a resposta escolhida A é melhor do que a resposta rejeitada B”. Use-a apenas quando a preferência par-a-par for o rótulo adequado para o erro; a correção factual e a conformidade com políticas exigem frequentemente avaliadores mais fortes do que uma preferência global.
RLHF baseado em PPO
A receita original era um pipeline em três etapas:
- SFT — aprender a tarefa.
- Reward model — treinar com preferências humanas (escolhida vs rejeitada).
- PPO (Proximal Policy Optimization) — reinforcement learning para otimizar a policy.
O custo operacional resulta das várias componentes:
- É complicado de implementar e manter.
- É dispendioso — treina vários modelos.
- O sampling on-policy e a otimização da recompensa exigem verificações cuidadosas de estabilidade e reward hacking.
DPO
DPO (Direct Preference Optimization) elimina o reward model explícito e o RL loop. O artigo do DPO deduz um objetivo reparametrizado para maximização da recompensa com uma restrição de divergência KL, permitindo que a otimização prossiga a partir de pares de preferências em vez de reinforcement learning:
{
"prompt": "Explain quantum computing",
"chosen": "Quantum computing uses qubits...", # Preferred response
"rejected": "Well, it's complicated..." # Non-preferred response
}
O que muda operacionalmente:
- Percurso de código mais simples (sem reward model separado e sem RL loop).
- Um objetivo offline sobre pares de preferências, em vez de reinforcement learning on-policy.
- Uma policy de referência ou probabilidades log de referência equivalentes na formulação standard.
O DPO é mais fácil de prototipar do que um pipeline PPO completo, mas não é uma melhoria automática da qualidade. Os resultados dependem da policy inicial, da qualidade dos pares, das definições da loss, dos efeitos do comprimento e do protocolo de avaliação. Compare-o com um checkpoint SFT no mesmo conjunto de preferências retido e nas mesmas suites de tarefas.
ORPO
ORPO (Odds-Ratio Preference Optimization) combina a loss de negative log-likelihood do SFT com uma penalização de odds ratio nas respostas rejeitadas. Elimina o modelo de referência separado e pode combinar a aprendizagem da tarefa e a preference optimization numa única execução.
Como funciona: o ORPO usa uma loss combinada que faz duas coisas ao mesmo tempo:
- Maximiza a likelihood da resposta escolhida (aprende a tarefa).
- Penaliza a resposta rejeitada com um termo de odds ratio (aprende preferências).
Hiperparâmetros que importa conhecer:
from trl import ORPOConfig
config = ORPOConfig(
learning_rate=8e-6, # Very low, as recommended by the ORPO paper
beta=0.1, # Controls strength of preference penalty
# ... other params
)
- Learning rate: o artigo usou valores baixos nas suas experiências; ajuste ao seu modelo, batch e dados em vez de copiar um valor como regra.
- Beta: controla o termo de preferência relativamente ao termo SFT.
O compromisso:
- Uma etapa de treino em vez de duas.
- Sem reward model.
- Sem forward pass do modelo de referência.
- Uma execução acoplada: se a aprendizagem da tarefa ou o comportamento de preferência regredir, não existe um checkpoint SFT intermédio do mesmo pipeline para inspecionar.
Escolha com base no desenho dos dados e da avaliação:
- Use DPO quando já tiver um checkpoint SFT satisfatório e quiser uma experiência offline de preferências mais simples.
- Teste ORPO quando um objetivo sem modelo de referência e de etapa única se adequar aos seus dados e restrições operacionais.
- Use RLHF baseado em PPO quando o sampling online face a uma reward explícita aprendida fizer parte do requisito e conseguir monitorizar a exploração da recompensa.
Nenhum deles é a opção predefinida para todas as tarefas. Mantenha um baseline apenas com SFT e reporte métricas da tarefa e métricas de preferência.
Frameworks de fine-tuning
Os frameworks sobrepõem-se e mudam rapidamente. Escolha com base no percurso de execução que precisa de suportar, fixe as versões e mantenha a configuração de treino suficientemente portátil para permitir a reprodução fora de um notebook.
Unsloth — velocidade e eficiência de memória
Unsloth integra-se com trl e transformers do Hugging Face e fornece kernels otimizados, checkpointing e percursos de fine-tuning quantizado para modelos suportados.
- Kernels GPU Triton personalizados para attention, RoPE e cross-entropy que evitam o overhead do PyTorch.
- Backpropagation eficiente em memória que recalcula ativações durante o backward pass em vez de as manter em memória.
- Operações fused que combinam vários passos (layer norm + linear e semelhantes) numa única chamada à GPU.
- Quantization de 4 bits integrada diretamente no percurso QLoRA, com dequantization otimizada.
[!IMPORTANT] A ordem dos imports é importante Siga a ordem dos imports no exemplo do Unsloth para a versão que fixar. O Unsloth aplica patches durante o import, pelo que importá-lo antes de
trletransformersevita otimizações em falta ou erros específicos da versão.
# Correct order
from unsloth import FastLanguageModel # Must be first!
from trl import SFTTrainer
from transformers import TrainingArguments
# Avoid this order with Unsloth's patched path
from trl import SFTTrainer
from unsloth import FastLanguageModel
Mais indicado para: treino numa única GPU, prototipagem, notebooks Colab e qualquer pessoa que controle a fatura de GPU.
Os valores publicados de velocidade e memória variam com o modelo, comprimento da sequência, batch, precisão e hardware. Meça tokens por segundo e memória de pico na sua própria execução, em vez de tratar uma proporção de marketing como uma propriedade do framework.
Axolotl — treino orientado por configuração
# config.yaml - no code required
base_model: meta-llama/Meta-Llama-3-8B
adapter: qlora
lora_r: 32
lora_alpha: 16
datasets:
- path: data/my_data.jsonl
type: alpaca
sample_packing: true
Execute com: accelerate launch -m axolotl.cli.train config.yaml
Mais indicado para: execuções declarativas e reproduzíveis, bem como opções integradas de launcher para treino distribuído. A configuração pode ser revista, versionada e reutilizada em execuções locais e distribuídas.
Comparação de frameworks
| Ferramenta | Útil quando | Verificar antes de decidir |
|---|---|---|
| Unsloth | Pretende um percurso otimizado para modelos suportados, com exemplos concisos | Matriz de modelos, GPUs, quantization e suporte distribuído |
| Axolotl | Pretende configurações declarativas e receitas distribuídas integradas | Schema exato da configuração e launcher da release fixada |
| TRL | Pretende acesso direto aos trainers SFT e de preferências do Hugging Face | Formato do dataset, chat template, loss masking e integração com PEFT |
| Torchtune | Pretende receitas e componentes nativos de PyTorch | Cobertura das receitas de modelos e compatibilidade de exportação |
Demo prática: fine-tuning com Unsloth
Eis um excerto representativo de treino do meu repositório unsloth-finetune-demo. A demo faz fine-tuning de Nemotron-Nano para function calling. Antes deste excerto, o src/unsloth_demo/data.py da demo carrega e formata o dataset; depois, o percurso de treino cria os objetos versionados train_dataset e eval_dataset.
Início rápido
# Clone and setup
git clone https://github.com/slavadubrov/unsloth-finetune-demo.git
cd unsloth-finetune-demo
# Install with uv (recommended)
uv sync
# Run fine-tuning (quick test)
uv run finetune --max-samples 1000
Configuração
As partes interessantes estão em config.py:
# Model & Dataset
MODEL_NAME = "nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1" # 4B params, 128K context
DATASET_NAME = "glaiveai/glaive-function-calling-v2" # 113K examples
# LoRA Configuration
LORA_R = 16 # Adapter capacity; tune against held-out results
LORA_ALPHA = 32 # Update scaling; alpha/r is the classic LoRA scale
MAX_SEQ_LENGTH = 4096
# Candidate modules for this Llama-family model
LORA_TARGET_MODULES = [
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
]
[!NOTE] A relação entre alpha e rank
alpha/rescala a atualização LoRA clássica.alpha = 2ré uma heurística de partida comum em alguma documentação de ferramentas, não uma garantia de estabilidade. Faça sweep do rank, alpha, learning rate e módulos alvo apenas depois de fixar os dados e o baseline.
Código principal de treino
from unsloth import FastLanguageModel
from trl import SFTConfig, SFTTrainer
# Load model with 4-bit quantization
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1",
max_seq_length=4096,
load_in_4bit=True,
)
# Add LoRA adapters
model = FastLanguageModel.get_peft_model(
model,
r=16,
lora_alpha=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
use_gradient_checkpointing="unsloth", # Lower activation memory; extra compute
)
# The preceding data step must create these versioned dataset objects.
# Each row has the chat messages and tool schemas expected by current TRL.
# Train with the current TRL configuration surface.
trainer = SFTTrainer(
model=model,
processing_class=tokenizer,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
args=SFTConfig(
output_dir="outputs/nemotron-function-calling",
max_length=4096,
packing=True,
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
learning_rate=2e-4,
num_train_epochs=3,
bf16=True,
),
)
trainer.train()
Fine-tuning com Axolotl
[!NOTE] Demo a caminho Estou a preparar uma demo prática com Axolotl. Até lá, o Accelerate n-D Parallelism Guide do Hugging Face é uma boa referência para estratégias de treino multi-GPU.
Para configurações config-first e setups distribuídos, o Axolotl torna o workflow reproduzível:
# axolotl_config.yaml
base_model: meta-llama/Meta-Llama-3-8B
model_type: LlamaForCausalLM
# QLoRA configuration
load_in_4bit: true
adapter: qlora
lora_r: 32
lora_alpha: 16
lora_dropout: 0.05
lora_target_modules:
- q_proj
- k_proj
- v_proj
- o_proj
- gate_proj
- up_proj
- down_proj
# Dataset
datasets:
- path: data/training_data.jsonl
type: alpaca
# Training settings
sequence_len: 4096
sample_packing: true # Benchmark with your length distribution
micro_batch_size: 2
gradient_accumulation_steps: 4
learning_rate: 0.0002
num_epochs: 3
# Current Axolotl key; verify support on the pinned release
bf16: true
attn_implementation: flash_attention_2
Execute o treino:
axolotl train axolotl_config.yaml
Etapa 5: Avaliação
Congele o contrato de avaliação antes da primeira execução. No mínimo, compare o checkpoint afinado com o base exato, sem fine-tuning, usando o mesmo prompt, as mesmas definições de decoding e o mesmo ambiente de ferramentas. Só reporte a qualidade agregada depois de verificar as parcelas de falhas que o projeto pretendia melhorar.
Acompanhe quatro grupos:
- Tarefa alvo: exact match, sucesso de execução, rubrica humana ou outro resultado ligado ao caso de uso.
- Regressão: capacidades gerais e parcelas de tarefas anteriormente suportadas que a adaptação possa prejudicar.
- Segurança e políticas: recusas, fuga de dados, prompt injection ou restrições específicas do domínio.
- Operações: latência, throughput, memória, tamanho do artefacto e custo na configuração de serving pretendida.
Benchmarks automatizados
Use lm-evaluation-harness para tarefas standardizadas relevantes, mas não como substituto da avaliação do produto:
lm_eval --model hf \
--model_args pretrained=./outputs/merged-model \
--tasks hellaswag,arc_easy,mmlu \
--batch_size 8
LLM-as-judge
Para qualidade subjetiva, um modelo maior pode ajudar na pontuação, mas calibre-o com exemplos revistos por humanos e mantenha oculta a identidade do candidato:
judge_prompt = """
Rate this response from 1-5 on:
- Relevance
- Accuracy
- Formatting
Response: {model_output}
Expected: {ground_truth}
"""
Avaliação específica do domínio
Separe exemplos reais por origem, utilizador, documento ou tempo para evitar que near-duplicates atravessem a divisão. Para function calling, valide a trajetória completa: seleção da ferramenta, argumentos, resultado da execução, recuperação e resposta final. Reporte intervalos de confiança ou contagens de vitórias/derrotas emparelhadas quando a amostra for pequena e inspecione todas as regressões numa parcela crítica.
Etapa 6: Deployment e formatos de saída
Escolha o artefacto com base no serving engine e no plano de rollback, não apenas no tamanho do ficheiro:
1. Adapter LoRA
uv run finetune # Saves ~100-500MB adapter
- Tamanho: proporcional aos módulos alvo, rank, camadas e dtype; frequentemente muito menor do que a base.
- Mais indicado para: desenvolvimento, adapters de tarefas versionados e engines que suportem LoRA diretamente.
- Vantagem adicional: pode trocar de adapter sem voltar a descarregar o modelo base.
2. Modelo merged
uv run finetune --merge # Creates a standalone full model
- Tamanho: aproximadamente o do checkpoint base completo na precisão de saída escolhida.
- Mais indicado para: engines ou percursos de distribuição que não suportem o adapter separadamente.
- Compromisso: artefacto maior e rollout mais lento; carregamento de um único modelo mais simples.
3. Formato GGUF
uv run finetune --gguf q4_k_m # Creates ~2-4GB quantized model
- Tamanho: depende do modelo; aproximadamente pesos de quatro bits mais metadados nas variantes Q4.
- Mais indicado para: inferência em CPU, Ollama, llama.cpp e deployment edge.
- Opções:
q4_k_m(mais pequeno),q5_k_m(maior fidelidade dos pesos),q8_0(maior e com mais fidelidade). Meça o impacto na tarefa depois da conversão.
Etapa 7: Serving e monitorização
Com vLLM
# Serve the base and expose a PEFT adapter as a model name. This parser and
# template pair is for a Llama 3.1-compatible function-calling adapter.
vllm serve nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1 \
--enable-lora \
--lora-modules function-calling=./outputs/adapter \
--enable-auto-tool-choice \
--tool-call-parser llama3_json \
--chat-template examples/tool_chat_template_llama3.1_json.jinja \
--host 0.0.0.0 \
--port 8000 \
--max-model-len 4096
Consulte através da API compatível com OpenAI:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")
response = client.chat.completions.create(
model="function-calling",
messages=[{"role": "user", "content": "Book a flight to Tokyo"}],
tools=[
{
"type": "function",
"function": {
"name": "book_flight",
"description": "Book a flight to a city.",
"strict": True,
"parameters": {
"type": "object",
"properties": {
"destination": {"type": "string"},
},
"required": ["destination"],
"additionalProperties": False,
},
},
}
],
tool_choice="auto",
)
O guia de tool calling do vLLM requer escolha automática de ferramentas e um parser compatível com o modelo; use o chat template compatível do modelo quando a configuração do tokenizer não fornecer um. Com tool_choice="auto", os argumentos constrained também requerem strict: true em pelo menos uma função (e a definição strict-tool-calling do vLLM ativada, que é o valor predefinido); use um schema parameters compatível com strict. Sem essa opção, o vLLM extrai calls a partir de texto bruto, pelo que os argumentos podem estar malformados ou violar o schema.
Com Ollama (local)
# Create Modelfile
echo 'FROM ./outputs/unsloth-nemotron-function-calling-gguf/model-q4_k_m.gguf' > Modelfile
# Import to Ollama
ollama create my-function-model -f Modelfile
# Run
ollama run my-function-model
Com llama.cpp (CPU)
./llama-cli -m ./outputs/model-q4_k_m.gguf \
-p "What's the weather in Tokyo?" \
--ctx-size 4096
Monitorizar o modelo lançado
O ciclo de vida não termina com uma loss de treino saudável. Registe a revisão do modelo base, o tokenizer e o chat template, o hash do adapter, a versão do dataset, a configuração de treino e o relatório de avaliação como uma única unidade de release. Em produção, monitorize o sucesso da tarefa, saídas inválidas, falhas de políticas, latência e drift das entradas nas mesmas parcelas usadas offline. Mantenha o artefacto anterior carregável e defina um limiar de rollback antes do lançamento.
Principais conclusões
- Faça fine-tuning apenas depois de um baseline sem fine-tuning e de uma taxonomia de falhas mostrarem que a adaptação dos pesos aborda o problema.
- O retrieval gere evidência variável; o constrained decoding gere sintaxe; nenhum dos dois é substituído por SFT.
- LoRA reduz o estado treinável. QLoRA comprime adicionalmente os pesos base congelados. Não atribua os valores de memória do QLoRA ao LoRA.
- A cobertura dos dados, a integridade das divisões, a proveniência e o loss masking importam mais do que copiar uma configuração de otimizador da moda.
- DPO, ORPO e RLHF baseado em PPO são desenhos experimentais diferentes, não uma escada de qualidade com uma opção universal.
- Avalie o comportamento alvo, regressões, segurança e operações contra o mesmo modelo base.
- Escolha a saída adapter, merged ou GGUF a partir dos requisitos de serving e rollback antes do treino.
Referências
Artigos e investigação
- LoRA: Low-Rank Adaptation of Large Language Models
- QLoRA: Efficient Finetuning of Quantized LLMs
- DoRA: Weight-Decomposed Low-Rank Adaptation
- DPO: Direct Preference Optimization
- ORPO: Odds Ratio Preference Optimization
- PPO: Proximal Policy Optimization Algorithms — OpenAI, 2017
Ferramentas de processamento de dados
- DataTrove — processamento de dados do Hugging Face à escala
- Distilabel — geração de dados sintéticos (Argilla)
- Trafilatura — extração e crawling de texto Web
- Identificação de idioma do fastText — modelos
lid.176distribuídos para 176 idiomas - Microsoft Presidio — deteção e anonimização de PII
- scrubadub — biblioteca Python para remoção de PII
Constrained decoding
Frameworks de treino
- Unsloth — framework otimizado de fine-tuning
- Axolotl — treino orientado por configuração e launchers distribuídos
- TRL — biblioteca do Hugging Face para SFT e treino de preferências
- Torchtune — biblioteca de fine-tuning nativa de PyTorch
Inferência e deployment
- Adapters LoRA do vLLM — servir um ou mais adapters com o modelo base
- Tool calling do vLLM — compatibilizar escolha automática de ferramentas, parser, chat template e schema do pedido com o modelo
- Ollama — runner local de LLM para Mac/Windows/Linux
- llama.cpp — inferência em CPU/GPU com o formato GGUF
Avaliação
- lm-evaluation-harness — benchmarking standardizado de LLM da EleutherAI
Guias e recursos
- Repositório da demo — exemplo prático de fine-tuning
- LLM Fine-Tuning. Theoretical Intuition and Practical Implementation — notebook de investigação do NotebookLM
- Accelerate n-D Parallelism Guide — estratégias de treino multi-GPU do Hugging Face