LoRA foi introduzido no artigo “LoRA: Low-Rank Adaptation of Large Language Models” (Hu et al., Microsoft Research, 2021). A principal motivação era resolver a ineficiência do ajuste fino completo sem sacrificar o desempenho. Os autores observaram que durante o ajuste fino, os pesos do modelo não mudam arbitrariamente, mas tendem a se mover ao longo de direções de baixo rank no espaço de parâmetros.
Em outras palavras: as atualizações de pesos de um modelo podem ser aproximadas por uma matriz de baixo rank.
Em um modelo Transformer, operações-chave (como projeções em camadas de atenção) são realizadas via multiplicação matricial. Por exemplo, a projeção de consulta é calculada como:
Q = X * W_Q
Onde:
X é a entrada (ativações da camada anterior)W_Q é a matriz de pesos treináveis para a projeção de consultaDurante o ajuste fino completo, W_Q é atualizado diretamente, implicando modificação de todos os seus elementos.
No LoRA, ao invés disso, W_Q é mantido congelado, e uma atualização de baixo rank é introduzida:
Q = X * (W_Q + B * A)
Onde:
A é uma matriz de tamanho (d_model, r)B é uma matriz de tamanho (r, d_head)r é o rank (um hiperparâmetro pequeno, tipicamente entre 4 e 64)d_model e d_head são as dimensões originais de W_QA matriz B * A tem rank r, muito menor que o rank completo de W_Q. Isso significa que, em vez de atualizar milhões de parâmetros, apenas os parâmetros de A e B são treinados, totalizando:
Número de parâmetros LoRA = r * (d_model + d_head)
Por exemplo, se d_model = 4096, d_head = 128, e r = 8, então:
Parâmetros LoRA = 8 * (4096 + 128) = 8 * 4224 = 33.792
Enquanto isso, a matriz original W_Q poderia ter 4096 * 128 = 524.288 parâmetros. Ou seja, apenas 6,4% dos parâmetros originais são treinados.
r (rank): Controla o número de parâmetros treináveis. Valores baixos (4–8) são suficientes para tarefas simples; valores mais altos (32–64) para tarefas complexas. Um r muito alto elimina os ganhos de eficiência.lora_alpha: Fator de escala que controla a magnitude da atualização B * A. Tipicamente definido como múltiplo de r (por exemplo, alpha = 16 se r = 8). Age como uma "taxa de aprendizado implícita" para atualizações LoRA.lora_dropout: Dropout aplicado às saídas da camada LoRA para regularização. Valores típicos: 0,0 a 0,1.target_modules: Lista de módulos do modelo onde LoRA é aplicado. Em Transformers, comumente aplicado às projeções de Query e Value (q_proj, v_proj) em camadas de atenção. Às vezes também a k_proj, o_proj, ou camadas MLP densas (fc1, fc2).A biblioteca peft da Hugging Face permite aplicar LoRA a qualquer modelo compatível com a interface transformers em apenas algumas linhas de código:
from peft import LoraConfig, get_peft_model
# Configuração LoRA
lora_config = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# Aplicar LoRA ao modelo
model = get_peft_model(model, lora_config)
# O modelo agora treina apenas parâmetros LoRA
model.print_trainable_parameters() # Mostra quantos parâmetros são treináveis
Isso transforma o modelo original para que apenas as matrizes A e B nas camadas especificadas sejam atualizadas durante o treinamento. O resto permanece congelado.