Capítulo 1: Entendendo LoRA
A Intuição por Trás da Low-Rank Adaptation
LoRA (Low-Rank Adaptation) é uma técnica elegante que parte de uma observação simples, porém poderosa: não é necessário atualizar todos os parâmetros para adaptar um modelo a novas tarefas.
O Insight Central
Observação Principal
Ao fazer fine-tuning de modelos pré-treinados, as atualizações dos pesos geralmente têm um "rank intrínseco" baixo — ou seja, as mudanças podem ser capturadas por um conjunto de parâmetros muito menor.
Analogia
Pense como editar um documento:
- Fine-Tuning Completo: Reescrever o documento inteiro
- LoRA: Adicionar post-its com correções
O documento original (modelo base) permanece intacto, e os post-its (adapters LoRA) capturam as mudanças.
Como o LoRA Funciona
Fine-Tuning Tradicional
Em uma camada de rede neural:
h = Wx
Onde W é uma matriz de pesos de tamanho (d × d).
O fine-tuning completo atualiza W diretamente:
W' = W + ΔW
Onde ΔW é a mudança aprendida em todos os parâmetros (d × d).
Abordagem do LoRA
LoRA representa ΔW como o produto de duas matrizes menores:
ΔW = BA
Onde:
- B tem tamanho (d × r)
- A tem tamanho (r × d)
- r é muito menor que d (r ≪ d)
O forward pass se torna:
h = Wx + BAx = (W + BA)x
Representação Visual
Economia de Parâmetros
Exemplo: Uma Matriz de Pesos 4096 × 4096
# Original weight matrix
d = 4096
original_params = d * d # 16,777,216 parameters
# LoRA with rank 16
r = 16
lora_params = d * r + r * d # 131,072 parameters
# Savings
reduction = 1 - (lora_params / original_params)
print(f"Parameter reduction: {reduction:.2%}") # 99.22%
Para um Modelo Completo
| Modelo | Original | LoRA (r=16) | Redução |
|---|---|---|---|
| 7B | 7.000.000.000 | ~4.000.000 | 99,94% |
| 13B | 13.000.000.000 | ~8.000.000 | 99,94% |
| 70B | 70.000.000.000 | ~40.000.000 | 99,94% |
Por Que Low Rank Funciona
Dimensionalidade Intrínseca
Pesquisas mostram que as atualizações de fine-tuning tendem a estar em um subespaço de baixa dimensionalidade:
- Modelos pré-treinados já possuem representações ricas
- A adaptação de tarefas exige "direcionamento", não "reconstrução"
- Muitas dimensões do espaço de pesos são redundantes para tarefas específicas
Evidência Empírica
Do artigo original do LoRA:
- r=4 frequentemente é suficiente para muitas tarefas
- r=8-16 recomendado para adaptações mais complexas
- r=64+ raramente necessário, retornos decrescentes
Inicialização
Matriz A: Gaussiana Aleatória
# A é inicializada com valores aleatórios pequenos
A = torch.randn(r, d) * 0.01
Matriz B: Zero
# B é inicializada com zeros
B = torch.zeros(d, r)
Por Que Essa Inicialização?
No início do treinamento: BA = 0 × A = 0
→ Saída inalterada em relação ao modelo base
→ Início de treinamento estável
→ Adaptação gradual
Quais Camadas Alvejar
Arquitetura Transformer
Bloco de Atenção:
├── Query projection (q_proj) ← Alvo comum
├── Key projection (k_proj) ← Às vezes alvo
├── Value projection (v_proj) ← Alvo comum
└── Output projection (o_proj) ← Às vezes alvo
Bloco Feed-Forward:
├── Gate projection (gate_proj) ← Às vezes alvo
├── Up projection (up_proj) ← Às vezes alvo
└── Down projection (down_proj) ← Às vezes alvo
Configurações Comuns
| Configuração | Módulos Alvo | Caso de Uso |
|---|---|---|
| Mínima | q_proj, v_proj | Experimentos rápidos |
| Padrão | q_proj, k_proj, v_proj, o_proj | Equilíbrio |
| Completa | Toda atenção + FF | Máxima capacidade |
Mesclando LoRA
Durante a Inferência (Com Adapter)
# Dois caminhos: base + LoRA
output = W @ x + B @ A @ x
Pequena sobrecarga devido ao cálculo adicional.
Mesclado (Sem Adapter)
# Mescla uma vez
W_merged = W + B @ A
# Caminho único na inferência
output = W_merged @ x
Sem sobrecarga — idêntico ao modelo fine-tuned.
Exemplo de Mescla
from peft import PeftModel
# Carrega modelo com adapter
model = PeftModel.from_pretrained(base_model, "path/to/adapter")
# Mescla o adapter ao modelo base
model = model.merge_and_unload()
# Agora o modelo é um modelo regular sem sobrecarga de adapter
model.save_pretrained("merged-model")
Variantes do LoRA
LoRA Padrão
A formulação original descrita acima.
LoRA+
Aplica taxas de aprendizado diferentes para as matrizes A e B.
DoRA (Weight-Decomposed Low-Rank Adaptation)
Separa magnitude e direção dos pesos.
GaLore (Gradient Low-Rank Projection)
Projeta os gradientes em um espaço de baixa rank.
Principais Pontos
✅ LoRA representa atualizações de pesos como produtos de matrizes de baixo rank
✅ Treina apenas ~0,01-0,1% dos parâmetros originais
✅ B inicializada em zero garante início de treinamento estável
✅ Comum alvejar projeções de atenção (q_proj, v_proj)
✅ Pode ser mesclado para inferência sem sobrecarga
✅ Low rank funciona porque o fine-tuning tem baixa dimensionalidade intrínseca
Próximos Passos
Continue para Capítulo 2: Matemática do LoRA para os fundamentos matemáticos.
Verificação Rápida
Antes de prosseguir, certifique-se de que você consegue responder:
- Como o LoRA representa as atualizações de pesos?
- Por que B é inicializada em zero?
- O que significa "low rank" no contexto do LoRA?