Reentrenar el modelo entero es matar moscas a cañonazos
Tienes un modelo de siete mil millones de parámetros y quieres que aprenda tu dominio: tu jerga, tu formato de salida, tu tono. La reacción instintiva es hacer fine-tuning completo. Pero eso significa actualizar los siete mil millones de pesos, guardar una copia entera del modelo por cada experimento y necesitar una GPU con memoria de sobra para el optimizador, que suele pedir el triple de RAM que el propio modelo.
Multiplica eso por cada cliente, cada tarea y cada iteración fallida. El coste se dispara y el disco se llena de checkpoints de catorce gigas que solo se diferencian en un puñado de matices.
LoRA (Low-Rank Adaptation) rompe ese trato. En vez de mover todos los pesos, los congela y aprende un parche minúsculo al lado. El resultado se acerca al del fine-tuning completo entrenando menos del 1 % de los parámetros. Estas son las notas de campo.
La idea: no toques el modelo, súmale un parche de rango bajo
Cada capa lineal de un Transformer tiene una matriz de pesos W. El fine-tuning completo la reemplaza por W + ΔW, donde ΔW es todo lo que ha aprendido durante el entrenamiento. Esa matriz de cambios ΔW tiene el mismo tamaño gigante que W.
La apuesta de LoRA es que ΔW, aunque grande, contiene poca información real: se puede aproximar bien con un rango bajo. En vez de aprender la matriz entera, se factoriza en dos matrices flacas, A y B, tales que su producto tiene la forma correcta pero muchísimos menos números:
ΔW ≈ B · A
W: d × d (por ejemplo, 4096 × 4096 ≈ 16,7 M de parámetros)
A: r × d (r = 8 → 8 × 4096 ≈ 32 K)
B: d × r (4096 × 8 ≈ 32 K)
Con un rango r de ocho, esas dos matrices juntas suman unos 65 000 parámetros frente a los 16,7 millones de la capa original. Congelas W, entrenas solo A y B, y en inferencia sumas su producto a la salida. El modelo base ni se entera: sigue intacto en disco, compartido por todos tus adaptadores.
Un ejemplo con PEFT
En la práctica no implementas esto a mano. La librería peft de Hugging Face envuelve cualquier modelo y coloca los adaptadores donde le digas:
from transformers import AutoModelForCausalLM
from peft import LoraConfig, get_peft_model
modelo = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
config = LoraConfig(
r=8, # rango del adaptador: el mando principal
lora_alpha=16, # escala del parche (suele ir a 2·r)
target_modules=[ # a qué capas engancharlo
"q_proj", "v_proj", # las proyecciones de atención son lo habitual
],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
modelo = get_peft_model(modelo, config)
modelo.print_trainable_parameters()
# trainable params: 3.4M || all params: 7.24B || trainable%: 0.047
Menos del 0,05 % de los parámetros quedan entrenables. El resto está congelado. A partir de aquí entrenas con tu bucle habitual, y al terminar guardas solo los adaptadores: unos pocos megas en lugar de catorce gigas.
Los dos mandos que de verdad importan son r y target_modules. Subir el rango da más capacidad de aprendizaje a cambio de más parámetros; con tareas de estilo o formato, un r de ocho suele bastar. Enganchar los adaptadores solo a las proyecciones de atención (q_proj, v_proj) es el punto de partida clásico; ampliarlo a todas las capas lineales ayuda en tareas más exigentes, pero encarece.
Cuánto ahorra, en cifras
La diferencia no es de matiz. Es de otro orden de magnitud en las tres cosas que duelen: memoria, almacenamiento y agilidad para servir varios adaptadores.
| Aspecto | Fine-tuning completo | LoRA |
|---|---|---|
| Parámetros que se entrenan | 100 % | menos del 1 % |
| Memoria de GPU (modelo de 7B) | 60–80 GB | 14–18 GB |
| Tamaño del checkpoint | 13–14 GB | 10–200 MB |
| Cambiar de tarea en producción | Cargar otro modelo entero | Intercambiar el adaptador en caliente |
| Calidad en tareas de dominio | Referencia | Muy cercana, a menudo indistinguible |
Ese penúltimo punto es el que más cambia la arquitectura. Como el modelo base es siempre el mismo, puedes tener un servidor con el modelo cargado una sola vez y decenas de adaptadores de pocos megas que entran y salen según el cliente o la tarea. Un modelo, muchas personalidades, sin duplicar nada pesado.
QLoRA: el mismo truco, pero en una GPU de andar por casa
LoRA reduce lo que entrenas, pero el modelo base congelado sigue ocupando memoria. QLoRA ataca justo eso: cuantiza el modelo base a cuatro bits mientras los adaptadores se entrenan en precisión normal. La combinación mete el fine-tuning de un modelo de 7B en una sola GPU de consumo, algo impensable con el enfoque completo.
Es la variante que más ha democratizado el ajuste de modelos: no necesitas un clúster para adaptar un modelo mediano a tu caso. Si quieres el porqué de la cuantización a cuatro bits, lo cubrí en la nota sobre cuantización de LLMs; aquí basta con saber que se apoya en ese mismo mecanismo.
Cuándo usar LoRA y cuándo no
LoRA brilla cuando quieres enseñarle al modelo una forma: un formato de salida estricto, un tono, una jerga de dominio, un comportamiento consistente que el prompt por sí solo no consigue fijar. También cuando necesitas muchas variantes especializadas sin multiplicar el coste de servir.
No es la respuesta a todo. Si tu problema es que al modelo le faltan hechos —datos que cambian, documentación viva, conocimiento privado—, LoRA no es el camino: eso es territorio de RAG, y la comparación entre ambos la desarrollé en la nota de fine-tuning frente a RAG. Meter conocimiento factual a base de adaptadores envejece mal y es caro de mantener actualizado.
Tampoco esperes que un rango bajo absorba una capacidad totalmente nueva y compleja. Para reorientaciones profundas del modelo, el fine-tuning completo sigue teniendo su hueco. LoRA es una herramienta de ajuste fino, no de cirugía mayor.
En resumen
LoRA parte de una observación sencilla —lo que un modelo necesita aprender para tu tarea cabe en muy pocos parámetros— y la convierte en un ahorro brutal: entrenas menos del 1 %, guardas megas en lugar de gigas y sirves muchas variantes sobre un único modelo base.
Antes de lanzarte, tres comprobaciones. Primero, confirma que tu problema es de forma y no de hechos; si es lo segundo, empieza por RAG. Segundo, arranca con un rango de ocho sobre las proyecciones de atención y sube solo si la calidad se queda corta, midiendo con tu propio conjunto de evaluación. Tercero, si vas justo de GPU, ve directo a QLoRA: el mismo resultado en una máquina que ya tienes.
El fine-tuning completo era un cañón para matar moscas. LoRA es el matamoscas: más pequeño, más barato y, para casi todo lo que necesitas, igual de eficaz.