Redes Neurais Artificiais e Deep Learning · Insper

Transfer Learning e Fine-Tuning

Se vale mudar os pesos e quais deles

A pergunta mudou

Seu modelo responde certo, mas ignora o formato de saída de que você precisa. Você faz fine-tuning?

  • Não de primeira. Quase ninguém treina mais do zero e mexer nos pesos virou a opção cara.
  • A pergunta não é mais como adaptar um modelo pré-treinado: é se vale adaptá-lo.
  • E, se valer: quais pesos, quantos e em direção a qual objetivo.

Antes de fazer fine-tuning: não faça

Tente isto primeiro Resolve Não resolve
Um prompt melhor, com exemplos formato, tom, enquadramento da tarefa conhecimento ausente; custo por chamada
Busca (RAG) fatos que faltam, fatos que mudam, citações comportamento e estilo
Ferramentas / chamadas de função aritmética, dados atuais, ações qualquer coisa sem API
Um modelo maior ou mais novo quase tudo, na hora suas metas de latência e custo unitário
Fine-tuning comportamento consistente a baixo custo; um modelo pequeno que iguala um grande na sua tarefa fatos que mudam

Percorra de cima para baixo. Parar no meio é o desfecho normal.

Fine-tune comportamento, busque conhecimento

Um fine-tune espalha fatos novos por bilhões de pesos: sem citação, sem jeito de atualizar ou apagar um deles. Um índice faz o mesmo trabalho com um PUT.

A documentação da empresa muda toda semana. Alguém propõe fazer fine-tuning nela. O que você responde?

  • Busca. Fine-tune comportamento; busque conhecimento.
  • O único caso econômico que justifica fine-tuning de forma confiável: um prompt que funciona num modelo de fronteira precisa rodar 100× mais barato → gere dados com o modelo grande e faça fine-tuning num pequeno. Isso é destilação.

O quadro clássico: camadas

  • As camadas iniciais aprendem bordas e texturas: transferem para qualquer lugar.
  • As finais aprendem as categorias da tarefa de pré-treino.
  • Então: congele a frente e retreine o fundo (Yosinski et al., 2014).

Congelar = requires_grad = False. Os pesos continuam calculando, mas não ganham gradiente nem estado de otimizador.

Correto e, para uma tarefa pequena, ainda exatamente o que fazer. O laboratório usa o DistilBERT (66,4 M de parâmetros) com uma cabeça nova 768 → 2 para sentimento: 768 é o tamanho do vetor que o encoder entrega por frase; 2, as classes (negativo, positivo).

Três regimes, com os preços do DistilBERT

Regime O que treina Treináveis O que ele não consegue
Linear probe só a cabeça nova 768 · 2 + 2 = 1.538 mudar as features
Fine-tuning parcial cabeça + últimos blocos ~7,1 M por bloco consertar os blocos iniciais congelados
Fine-tuning completo tudo, taxa de aprendizado (lr) pequena 66,4 M sair barato

Um bloco: 4 projeções de atenção 768 × 768 + MLP 768 → 3072 → 768 + 2 LayerNorm =
4·(768² + 768) + (768·3072 + 3072) + (3072·768 + 768) + 2·2·768 = 7.087.872 (cada Linear tem viés).
O modelo: embeddings 23.835.648 + 6 blocos 42.527.232 + cabeça 1.538 = 66.364.418.

  • Um encoder congelado tem um bônus escondido: as features nunca mudam, então calcule-as uma vez e guarde. Aí o probe treina em cerca de um segundo.

O que treina e por onde passa o gradiente

O DistilBERT com uma cabeça nova, desenhado como uma fila: as embeddings, seis blocos Transformer, a média sobre os tokens, a cabeça e a perda. Um botão escolhe o regime. Linear probe: só a cabeça treina, a passagem reversa para na cabeça e o encoder roda uma vez por frase. Fine-tuning parcial: o bloco 6 e a cabeça treinam e a passagem reversa para no bloco 6. LoRA: os pesos pré-treinados ficam congelados, os adaptadores ficam dentro dos seis blocos e a passagem reversa atravessa o encoder inteiro para chegar a eles. Fine-tuning completo: tudo treina e a passagem reversa chega às embeddings.

Por que o quadro clássico deixou de bastar

Fine-tuning completo de um modelo de 8B com AdamW em bf16. Quantos GB antes de uma única ativação?

  • bf16 guarda um número em 2 bytes; fp32, em 4. Pesos: 8·10⁹ × 2 bytes = 16 GB. Gradientes, também em bf16: 16 GB.
  • AdamW: cópia mestra em fp32 (4) + dois momentos em fp32 (4 + 4) = 12 bytes/parâmetro → 96 GB.
  • 2 + 2 + 12 = 16 bytes por parâmetro: 128 GB. O estado do otimizador (12) vale seis vezes os pesos (2).
  • E num modelo de linguagem o comportamento está espalhado por todos os blocos: "retreinar o fundo" vira "retreinar tudo".

Momentos: as médias móveis do gradiente e do seu quadrado. Cópia mestra: os pesos em fp32, onde cada passo pequeno é somado sem se perder no arredondamento do bf16.

Simulador · a conta de memória

A conta é dimensionada pelo que treina

Gradientes e estado do otimizador só existem para parâmetros treináveis — não para o modelo.

Modelo de 8B, AdamW completo: 8·10⁹ treináveis LoRA: 0,5% = 4·10⁷ treináveis
pesos (bf16, 2 bytes) 8·10⁹ × 2 = 16 GB 16 GB — a base inteira
gradientes (2 bytes) 8·10⁹ × 2 = 16 GB 4·10⁷ × 2 = 0,08 GB
estado do otimizador (12 bytes) 8·10⁹ × 12 = 96 GB 4·10⁷ × 12 = 0,48 GB
ativações (checkpointing) 1,4 GB 1,4 GB
total 129 GB 18 GB

Ativações: a estimativa do simulador, com checkpointing (guarda poucas ativações e recalcula o resto na passagem reversa).
Medido no laboratório, no DistilBERT em fp32 (sem cópia mestra, só os dois momentos de 4 bytes): 66.364.418 × 8 = 530,9 MB no fine-tuning completo; 665.090 × 8 = 5,3 MB no LoRA r = 8.

LoRA: a atualização é de posto baixo

Hipótese (Hu et al., 2022): a mudança que uma tarefa exige tem posto muito menor que a matriz que ela modifica.

  • é a matriz pré-treinada, ( saídas, entradas): congelada. Só e treinam.
  • Posto = quantas direções independentes uma matriz tem. tem no máximo .
  • É uma afirmação sobre adaptação, não sobre compressão: a própria tem posto cheio.
  • é uma escala fixa (hiperparâmetro); dividir por faz que mudar não obrigue a reajustar a taxa de aprendizado.

Inicialização: um fator em zero

começa aleatória, começa em zero → : o treino começa exatamente no modelo pré-treinado.

Por que não as duas em zero?

Com e (o gradiente que chega à saída da camada):

  • As duas em zero → os dois gradientes zero → nenhuma sai do lugar.
  • Só com : no primeiro passo recebe gradiente zero e não. Um passo depois, as duas treinam.

Laboratório, checkpoint 4 (a lin1 do primeiro bloco com r = 8): ‖∂L/∂A‖ = 0,0 exato; ‖∂L/∂B‖ = 1163,42.

Simulador · uma camada LoRA, linha a linha

W₀ (congelada), x e A₀ · k = 3 colunas
y e B₀ · d = 2 linhas

A aritmética: em vez de

matriz atualização completa LoRA, : razão
projeção 4096 × 4096 (classe de 8B) 4096 · 4096 = 16.777.216 8 · (4096 + 4096) = 65.536 256×
q_lin do DistilBERT, 768 × 768 768 · 768 = 589.824 8 · (768 + 768) = 12.288 48×
lin1 do DistilBERT, 768 → 3072 768 · 3072 = 2.359.296 8 · (768 + 3072) = 30.720 77×

LoRA, em escala

r =
Uma camada LoRA em escala: a matriz congelada W0, de d linhas e k colunas, mais alfa sobre r vezes B, uma lasca de d linhas e r colunas, vezes A, uma lasca de r linhas e k colunas. O produto BA tem o formato de W0 e posto no máximo r. Botões escolhem a matriz (a q_lin do DistilBERT, a lin1 dele ou uma projeção 4096 por 4096) e o posto; o texto embaixo conta os números: d vezes k congelados contra r vezes d mais k treináveis.

Exercício · conte os adaptadores

LoRA com nas seis camadas lineares de cada um dos seis blocos do DistilBERT, mais a cabeça nova. Quantos parâmetros treináveis? Preencha antes de virar o slide.

LoRA numa matriz : . A cabeça é nova: treina inteira (pesos + viés).

camada formato treináveis
q_lin, k_lin, v_lin, out_lin (atenção) 768 × 768 cada ?
lin1 (MLP) 768 → 3072 ?
lin2 (MLP) 3072 → 768 ?
um bloco ?
seis blocos ?
cabeça nova Linear(768, 2) 768 → 2 ?
total ?

Conte os adaptadores · resposta

camada formato treináveis de onde vem
q_lin, k_lin, v_lin, out_lin 768 × 768 cada 49.152 4 · 8 · (768 + 768) = 4 · 12.288
lin1 768 → 3072 30.720 8 · (768 + 3072)
lin2 3072 → 768 30.720 8 · (3072 + 768)
um bloco 110.592 8 · (4 · 1536 + 2 · 3840) = 8 · 13.824
seis blocos 663.552 6 · 110.592
cabeça nova 768 → 2 1.538 768 · 2 + 2, treina inteira
total 665.090 663.552 + 1.538

Exatamente o que o print_trainable_parameters do peft imprimiu no laboratório: 665.090 de 67.027.970 = 0,99%. O total inclui os adaptadores: 66.364.418 + 663.552.

Simulador · de quanto posto a tarefa precisa?

O terceiro painel é a parte que você escolheu não aprender

O painel mostra o que da atualização fica fora do posto escolhido.

  • Estilo ou formato: posto 2, mais ou menos. O LoRA empata com o fine-tuning completo.
  • Uma mudança de domínio: pede de 16 a 32.
  • Um idioma novo ou conhecimento novo: não é de posto baixo em nenhum acessível.

Os espectros do painel são inventados. A medição: no pré-treino continuado para código e matemática, o fine-tuning completo aprende uma atualização de posto 10 a 100× maior que as configurações típicas de LoRA. Ali o LoRA fica para trás (Biderman et al., 2024).

  • Uma perda que estaciona alta sob LoRA é a restrição apertando, não um hiperparâmetro ruim.

Configurações práticas

  • , (escala ) para começar; aumente só se a perda de treino estacionar alta.
  • Todas as camadas lineares (q,k,v,o da atenção, gate,up,down do MLP, nos nomes do Llama), não só como no artigo original: é o que é preciso para empatar com o fine-tuning completo — e o MLP tem dois terços de um bloco (no DistilBERT, 2 · 2,36 M de 7,09 M).
  • Taxa de aprendizado ~10× a do fine-tuning completo (no laboratório, 5e-4 contra 5e-5).
  • Merge para produção: volta a ser uma matriz só → a inferência não custa nada a mais.
  • Deixe sem merge para servir muitos adaptadores sobre uma base compartilhada.

Medido no laboratório: três regimes

DistilBERT, 2.000 frases do SST-2, 3 épocas, teste nas 872 da partição de validação.

método treináveis acc teste estado do otimizador
cabeça aleatória — 0,520 —
linear probe 1.538 0,787 0,01 MB
fine-tuning completo, lr 5e-5 66.364.418 0,849 530,9 MB
LoRA r = 8, lr 5e-4 665.090 0,853 5,3 MB
  • O LoRA empata com o fine-tuning completo com 1% dos parâmetros treináveis (665.090 / 66.364.418) e do estado do otimizador (5,3 / 530,9 MB).
  • Mas foi só ~15% mais rápido (71 s contra 85 s): a passagem reversa ainda atravessa o encoder inteiro. O LoRA economiza memória, não cálculo.

Uma frase do teste vale 1/872 ≈ 0,11 ponto: diferenças de um ponto são ruído. Cabeça aleatória ≈ chance (duas classes).

Medido no laboratório: posto e taxa de aprendizado

treináveis = 6 · 13.824 · + 1.538 acc teste
1 84.482 0,839
2 167.426 0,848
4 333.314 0,858
8 665.090 0,853
16 1.328.642 0,860
32 2.655.746 0,846
  • Uns 2 pontos (0,839 a 0,860) numa faixa de 32× em parâmetros, sem tendência depois de : sentimento é uma atualização de posto baixo.
  • O mesmo LoRA na lr do fine-tuning completo (5e-5): 0,822. A atualização começa em zero; ela precisa da lr ~10× maior.
  • O fine-tuning completo, livre: na q_lin do último bloco, as 8 direções principais guardam 65% da energia de (aleatória: 4%).

Energia = soma dos quadrados dos valores singulares σᵢ (o tamanho de ΔW em cada uma das suas direções independentes): 65% = (σ₁² + … + σ₈²) / (σ₁² + … + σ₇₆₈²).

O merge, conferido

Depois do merge_and_unload(), quantos parâmetros? A que distância ficam os logits dos do modelo sem merge?

  • 66.364.418 — exatamente o modelo de antes do LoRA.
  • Diferença máxima nos logits: 6,2 × 10⁻⁶ (arredondamento de float32).
  • Mesma acurácia de teste. Nenhuma camada a mais, nenhuma multiplicação a mais.

O LoRA custa memória só durante o treino. Depois do merge, ele é a arquitetura base.

QLoRA e DoRA

QLoRA (Dettmers et al., 2023)

  • Guarde a base congelada em NF4 de 4 bits (0,5 byte por peso); treine adaptadores de 16 bits por cima.
  • A base está congelada, então o erro de quantização é uma perturbação fixa em torno da qual o adaptador aprende.
  • Pôs o fine-tuning de um 65B numa única GPU de 48 GB: 65·10⁹ × 0,5 byte = 32,5 GB de base (33,5 GB com as escalas dos blocos, no próximo slide).

DoRA (Liu et al., 2024)

  • Separa cada peso em magnitude e direção; LoRA só na direção.
  • Nos testes dos autores, sempre acima do LoRA a um custo parecido.
  • O merge funciona do mesmo jeito.

Os pesos são o único item que o LoRA não encolhe. O QLoRA encolhe: 70B com LoRA ≈ 140 GB de pesos (70·10⁹ × 2) + 9 GB de gradientes, otimizador e ativações = 149 GB; com QLoRA, 35 GB de pesos (70·10⁹ × 0,5) + os mesmos 9 = 44 GB, uma placa de 80 GB.

QLoRA: guardado em 4 bits, calculado em 16

O armazenamento do QLoRA, passo a passo, num bloco de 64 pesos congelados: os pesos numa reta numérica; divididos pelo maior valor absoluto do bloco, de modo que ficam entre menos um e um; arredondados para o mais próximo dos 16 níveis do NF4 (densos perto de zero) e guardados como índices de 4 bits; as constantes de escala quantizadas de novo; a passagem direta, que desquantiza para bf16 e soma o caminho LoRA em bf16, com o gradiente chegando a A, a B e à entrada, mas não aos códigos guardados; e a conta de um modelo de 65B: 130 GB em bf16 contra 33,5 GB em NF4.

O resto do zoológico de PEFT, com honestidade

Técnica Situação em 2026
LoRA o padrão; todo o resto é medido contra ele
QLoRA o padrão quando a restrição é memória
DoRA tente quando o LoRA não basta e o fine-tuning completo não cabe no orçamento
Camadas adaptadoras (Houlsby) histórico: acrescentam latência de inferência, não podem ser fundidas
Prefix / prompt tuning histórico: difíceis de otimizar, mais fracos, comem janela de contexto
BitFit (só os vieses), IA³ (um vetor de escala por ativação) curiosidades: úteis para ver o que basta, não para entregar

Pós-treino: o que você otimiza

O PEFT responde quais pesos se movem. A outra metade: em direção a quê.

  1. SFT (fine-tuning supervisionado) — pares (prompt, boa resposta), a mesma perda de próximo token. Transforma um modelo base num que responde. Qualidade vence quantidade.
  2. Otimização de preferências — "A é melhor que B", que o SFT não ensina. RLHF (aprendizado por reforço com feedback humano: modelo de recompensa + PPO), hoje quase sempre DPO.
  3. RL a partir de um verificador — respostas que um programa consegue checar: GRPO.

Nem todo modelo passa pelos três. A destilação escreve as demonstrações do estágio 1.

Pós-treino, um prompt pelos estágios

DPO: o modelo de recompensa, eliminado algebricamente

x: o prompt · yw, yl: a resposta preferida e a rejeitada · πθ: o modelo em treino (a política) · πref: o modelo SFT, congelado · β: o quanto πθ pode se afastar de πref · σ: sigmoide · PPO: o algoritmo de aprendizado por reforço do RLHF original · rede de valor: um modelo que prevê a recompensa esperada, a linha de base do PPO

  • RLHF com PPO: quatro modelos na memória (política, referência, modelo de recompensa, rede de valor) e um laço instável.
  • O objetivo do RLHF tem uma política ótima em forma fechada → a recompensa pode ser escrita em função da política.
  • DPO: dois modelos (πθ + πref), sem laço de amostragem, treina como aprendizado supervisionado. Ainda exige SFT antes e dados de preferência.

GRPO: fine-tuning com um verificador em vez de um rótulo

Quando a correção pode ser checada (testes passam, uma prova compila, a resposta bate), não é preciso modelo de recompensa aprendido.

  • Amostre um grupo de tentativas do mesmo prompt; é a nota do verificador para a tentativa ; (a vantagem) empurra na direção das que ficaram acima da média do grupo.
  • Exemplo: , → média 0,5, desvio 0,5 → .
  • Sem modelo de recompensa e sem rede de valor (Shao et al., 2024). O sinal de treino por trás dos modelos de raciocínio (DeepSeek-R1) — ver a aula de LLMs.

Esquecimento catastrófico não é hipotético

Faça fine-tune pesado numa tarefa estreita e o modelo piora em todo o resto.

encoder probe no AG News (tópicos de notícias)
original 0,856
depois do fine-tuning completo no SST-2 0,840 (−1,6 ponto)
depois do LoRA r = 8 no SST-2 0,843 (−1,3 ponto)

Medido no laboratório: 3 épocas em 2.000 frases de sentimento já custaram à tarefa de notícias de 1,3 a 1,6 ponto. Probe = só uma cabeça linear treinada sobre o encoder congelado. A diferença de 0,3 ponto entre os dois é ruído com 1.000 exemplos de teste; em escala, o LoRA esquece menos (Biderman et al., 2024).

Mitigações: LoRA (muda menos, esquece menos), taxa de aprendizado baixa, ~10% de dados gerais na mistura e avaliar fora da tarefa, antes e depois: a única forma de descobrir.

Quando usar o quê

Situação Faça isto
Formato ou tom errados Engenharia de prompt
Fatos ausentes ou que mudam RAG
Qualidade de fronteira a 1% do custo Destile: SFT num modelo pequeno com as saídas do grande
< 1k exemplos rotulados Prompting few-shot, ou encoder congelado + cabeça linear
1k–100k exemplos, uma GPU LoRA, todas as camadas lineares,
Idem, limitado por memória QLoRA
Muitos clientes, uma base Adaptadores LoRA servidos sem merge
"Prefira esta resposta àquela" SFT → DPO
Respostas que um programa checa SFT → GRPO com um verificador

Laboratório · fine-tuning, com o preço na etiqueta

Notebook no Colab, ~2 h, DistilBERT no SST-2, GPU T4. Cada seção termina num checkpoint com valor de verificação.

  1. o modelo e os dados: contando parâmetros
  2. linear probe: features uma vez, só a cabeça
  3. fine-tuning completo: o estado do otimizador, medido
  4. LoRA escrito à mão: inicialização, gradientes, merge
  5. LoRA com peft: contra o que ele imprime
  1. a varredura de posto
  2. merge e produção
  3. a atualização completa é de posto baixo?
  4. o que cada método esqueceu
  5. (opcional) QLoRA, só com CUDA
  6. sua vez: quando o probe basta?

abrir no Colab →

Pontos principais

  1. Primeiro pergunte se vale fazer fine-tuning. Prompting, busca, ferramentas e um modelo maior resolvem a maior parte.
  2. Fine-tune comportamento, busque conhecimento.
  3. O fine-tuning completo é caro por causa do estado do otimizador: o AdamW custa 12 bytes por parâmetro treinável.
  4. O LoRA treina em vez de , começa no modelo pré-treinado, sai de graça depois do merge — e funciona quando a atualização é de posto baixo.
  5. QLoRA quantiza a base congelada; DoRA quando o LoRA fica aquém.
  6. Pós-treino: SFT → DPO → GRPO com um verificador.
  7. Fine-tuning causa esquecimento: prefira LoRA, misture dados gerais, avalie fora da tarefa.

Roteiro: (1) antes do fine-tuning: as alternativas mais baratas; (2) os regimes clássicos e a conta de memória; (3) LoRA: a hipótese, a aritmética, o posto; (4) o que o laboratório mediu; (5) QLoRA, DoRA e o zoológico de PEFT; (6) pós-treino: SFT, DPO, GRPO; esquecimento. Fecha com o laboratório no Colab.

Deixe responderem. A maioria vai dizer "fine-tuning". Para formato, a resposta é um prompt melhor com exemplos.

Laboratório, checkpoint 1: as embeddings (30.522 tokens e 512 posições, cada um um vetor de 768, mais uma LayerNorm) são mais de um terço do modelo.

A tabela anterior, desenhada. Clique nos quatro botões em ordem. Probe: o encoder roda uma vez, a passagem reversa para na cabeça. Parcial: para no bloco 6. LoRA: tudo congelado, mas a passagem reversa desce até o bloco 1 para chegar aos adaptadores dele; por isso o LoRA economizou memória e não tempo no laboratório (71 s contra 85 s). Completo: até as embeddings, 530,9 MB de estado do AdamW. Passe o mouse num bloco para ver a contagem. A faixa é o quadro clássico: o começo geral, o fim específico.

Comece em 8B, fine-tuning completo: 129 GB, 74% de estado do otimizador. Troque para LoRA: 18 GB, cabe numa placa de 24 GB. Depois 70B com LoRA (149 GB) e com QLoRA (44 GB): essa é a diferença de uma GPU.

As fórmulas do slide anterior com números: W0 é 2 × 3, r = 1, α = 2. Avance até a linha 5: B.grad = [-1; -0,4], A.grad exatamente 0, o checkpoint 4 do laboratório em miniatura. Linha 6: só B se mexeu. Linha 7: a perda vai de 0,29 para 0,1856 e agora A recebe gradiente. Linha 8: a W fundida dá o mesmo h. Depois os casos: "A = 0 e B = 0" nunca sai do lugar; "ao contrário" também funciona (B aleatória, A = 0), então a regra é um fator em zero, não qual deles; "a taxa do fine-tuning completo" quase não se mexe (0,2785).

A tabela acima, em escala. Comece na q_lin com r = 8: as duas lascas têm 8 de largura em 768, 12.288 números contra 589.824. Troque para a lin1 (77x) e para a projeção 4096 x 4096 (256x; nessa escala as lascas são mais finas que um pixel). Depois r = 64 na q_lin: ainda 6x menos. BA nunca é guardada no treino: a camada calcula B(Ax).

Estilo: r=1 deixa uma lasca, r=2 nada. Domínio: olhe r=8 (84%) e r=16 (98%). Idioma: cada posto a mais compra os mesmos 2%; em r=32 ainda falta um terço da atualização.

Seções 2, 3 e 5 do notebook. Os segundos são de uma GPU Apple; numa T4 serão outros.

Seis passos num bloco de 64 pesos congelados. A escala pelo absmax põe os pesos em [-1, 1]; cada um é arredondado para o mais próximo dos 16 níveis do NF4 (densos perto de zero) e guardado como um índice de 4 bits: 4,5 bits por peso com a escala em fp32, 4,127 com a quantização dupla. O passo 5 é o ponto: a base é desquantizada para bf16 a cada multiplicação, A e B estão em bf16 e nenhum gradiente chega aos códigos. Passo 6: 65B em 33,5 GB, uma GPU de 48 GB.

Cinco estágios, um prompt (quantos r em strawberry). Base: continua o texto. SFT: o formato, mas errado. DPO: a resposta preferida ganha probabilidade contra a rejeitada, em relação ao modelo SFT congelado. GRPO: um grupo de quatro, recompensas (1; 0; 1; 1), média 0,75, desvio 0,43, vantagens +0,58 e -1,73. Em produção: pesos congelados.