LoRA fue introducido en el artículo “LoRA: Low-Rank Adaptation of Large Language Models” (Hu et al., Microsoft Research, 2021). La motivación principal era resolver la ineficiencia del ajuste fino completo sin sacrificar el rendimiento. Los autores observaron que durante el ajuste fino, los pesos del modelo no cambian arbitrariamente sino que tienden a moverse a lo largo de direcciones de rango bajo en el espacio de parámetros.
En otras palabras: las actualizaciones de pesos de un modelo pueden aproximarse mediante una matriz de rango bajo.
En un modelo Transformer, las operaciones clave (como las proyecciones en capas de atención) se realizan mediante multiplicación matricial. Por ejemplo, la proyección de consulta se calcula como:
Q = X * W_Q
Donde:
X es la entrada (activaciones de la capa anterior)W_Q es la matriz de pesos entrenables para la proyección de consultaDurante el ajuste fino completo, W_Q se actualiza directamente, implicando la modificación de todos sus elementos.
En LoRA, en cambio, W_Q se mantiene congelada, y se introduce una actualización de rango bajo:
Q = X * (W_Q + B * A)
Donde:
A es una matriz de tamaño (d_model, r)B es una matriz de tamaño (r, d_head)r es el rango (un hiperparámetro pequeño, típicamente entre 4 y 64)d_model y d_head son las dimensiones originales de W_QLa matriz B * A tiene rango r, mucho más bajo que el rango completo de W_Q. Esto significa que en lugar de actualizar millones de parámetros, solo se entrenan los parámetros de A y B, totalizando:
Número de parámetros LoRA = r * (d_model + d_head)
Por ejemplo, si d_model = 4096, d_head = 128, y r = 8, entonces:
Parámetros LoRA = 8 * (4096 + 128) = 8 * 4224 = 33,792
Mientras tanto, la matriz original W_Q podría tener 4096 * 128 = 524,288 parámetros. Es decir, solo el 6.4% de los parámetros originales se entrenan.
r (rango): Controla el número de parámetros entrenables. Valores bajos (4–8) son suficientes para tareas simples; valores más altos (32–64) para tareas complejas. Un r demasiado alto elimina las ganancias de eficiencia.lora_alpha: Factor de escala que controla la magnitud de la actualización B * A. Típicamente se establece como múltiplo de r (por ejemplo, alpha = 16 si r = 8). Actúa como una "tasa de aprendizaje implícita" para las actualizaciones LoRA.lora_dropout: Dropout aplicado a las salidas de la capa LoRA para regularización. Valores típicos: 0.0 a 0.1.target_modules: Lista de módulos del modelo donde se aplica LoRA. En Transformers, comúnmente se aplica a las proyecciones de Consulta y Valor (q_proj, v_proj) en capas de atención. A veces también a k_proj, o_proj, o capas MLP densas (fc1, fc2).La biblioteca peft de Hugging Face permite aplicar LoRA a cualquier modelo compatible con la interfaz transformers en solo unas pocas líneas de código:
from peft import LoraConfig, get_peft_model
# Configuración de 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 al modelo
model = get_peft_model(model, lora_config)
# El modelo ahora entrena solo los parámetros LoRA
model.print_trainable_parameters() # Muestra cuántos parámetros son entrenables
Esto transforma el modelo original para que solo las matrices A y B en las capas especificadas se actualicen durante el entrenamiento. El resto permanece congelado.