English · Español
00 — Por qué el fine-tuning necesitaba reforma¶
El fine-tuning completo desperdicia recursos: ajustas todos los pesos para enseñar una habilidad pequeña. LoRA explota que los modelos preentrenados están sobre-parametrizados — los cambios útiles viven en un subespacio de rango (rank) bajo. Es una idea elegante y empíricamente sólida, no un truco de ingeniería.
El problema del fine-tuning completo¶
Supón que tienes un modelo preentrenado de 7B parámetros y quieres enseñarle una habilidad nueva — digamos, "ser especialmente bueno detectando errores de conjugación de verbos irregulares en inglés, como goed → went". Tienes ~500 ejemplos de entrenamiento extraídos del subconjunto de verbos irregulares del corpus de verbos de la Fase 12.
El enfoque directo: fine-tuning supervisado completo (SFT). Actualizar cada peso del modelo con descenso de gradiente sobre la pérdida (loss) de cross-entropy contra los nuevos ejemplos. Tras suficientes épocas, el modelo aprende la habilidad.
El enfoque directo tiene tres problemas:
- Memoria. Almacenar gradientes (
7B × 2bytes fp16), estado de Adam (7B × 4 × 2 = 56 GiBfp32 m y v), más los pesos (7B × 2 = 14 GiBfp16). Total: ~84 GiB. Más grande que cualquier GPU de consumo. - Cómputo. Un backward pass sobre 7B parámetros por ejemplo de entrenamiento es comparable al forward — estás haciendo trabajo a escala de inferencia dos veces por paso, durante cientos de pasos.
- Olvido catastrófico. Actualizar los 7B parámetros sobre una tarea estrecha puede degradar capacidades no relacionadas. El modelo que corrige perfectamente
goed→wentahora conjuga mal los verbos regulares-edque antes manejaba sin problema.
Necesitamos un método que:
- Actualice pocos parámetros (poca memoria).
- Preserve la mayoría de los pesos preentrenados (sin olvido).
- Sea matemáticamente limpio para razonar sobre él.
LoRA entrega las tres cosas. He aquí por qué funciona.
La observación de sobre-parametrización¶
Los modelos preentrenados tienen muchos más parámetros de los que la tarea necesita. La razón: los objetivos de preentrenamiento (predicción del siguiente token sobre internet) requieren capacidad para encajar cualquier distribución imaginable. Cualquier tarea downstream específica — una persona de chatbot, un estilo de código, un dominio — sólo necesita una pequeña fracción de esa capacidad.
Empíricamente: si preguntas "¿cuánto cambian realmente los pesos durante el fine-tuning?", la respuesta es "muy poco, y a lo largo de muy pocas direcciones". Concretamente, la matriz de actualización ΔW = W_finetuned − W_pretrained es aproximadamente de bajo rango — aunque W en sí tenga rango completo.
Hu et al. (LoRA, 2021) precisaron esta observación: para muchas tareas de fine-tuning, ΔW tiene un "stable rank" de ~10 incluso para W ∈ ℝ^{4096 × 4096}. El resto de los valores singulares son ruido.
Es una afirmación empírica fuerte. Dice: la información útil añadida por el fine-tuning vive en un subespacio de dimensión r ≪ min(in, out).
La construcción de LoRA¶
Si ΔW es aproximadamente de rango r, parametrízalo directamente como rango r:
El cómputo forward:
W, b se congelan (freeze) en valores preentrenados. A, B se entrenan. α es una constante de escala (típicamente 16 o 32); α/r hace el escalado invariante a la elección de r.
Entrenamiento: los gradientes fluyen sólo a A, B. Estado del optimizador sólo para A, B. El W congelado no necesita su buffer de gradiente.
Inferencia: opcionalmente fusionar (merge) A, B en W en tiempo de servicio: W_eff = W + (α/r) B A. Mismo cómputo que un Linear plano. O mantenerlos separados para intercambiar adaptadores (adapters) por request.
Lo que ahorras¶
Para un Linear(768, 768):
- Full FT: 590K params entrenables; 590K grads; 590K × 2 estados de Adam = 590K × 4 buffers en precisión mixta. Total ~4.7 MiB.
- LoRA r=8: 12K params entrenables; ~96 KiB de estado total. 50× menos.
A lo largo de un modelo completo con cientos de Linears, los ahorros se multiplican.
Lo que no pierdes¶
Una preocupación habitual: una actualización de rango r es estrictamente menos expresiva que una actualización completa. ¿No sufre la accuracy?
Empíricamente, no — para tareas dentro de las capacidades generales del modelo preentrenado. Las ablaciones de Hu et al. muestran que LoRA r=4 iguala a full FT en GLUE; r=8 iguala a full FT en SuperGLUE. El razonamiento: la información específica de la tarea es de bajo rango, así que una parametrización de bajo rango es suficiente.
Para tareas fuera de la distribución del modelo preentrenado — p.ej., enseñar a un modelo entrenado en inglés a rendir bien en suajili — LoRA puede quedarse corto frente a full FT porque el ΔW requerido no es de bajo rango para un cambio de distribución tan grande. La mayoría del fine-tuning en producción no es este escenario.
Nuestra especialización de la Fase 28 — "sesgar el modelo hacia detectar errores de verbos irregulares" — está claramente dentro de la distribución: el MiniGPT preentrenado ya ha visto los 8 verbos irregulares (be, have, do, go, come, see, eat, write) durante el entrenamiento de la Fase 17. Sólo estamos empujando la masa de distribución de "¿cómo se ve go → pasado simple?" lejos del prior de la forma regular. Eso es una perturbación de bajo rango de manual.
QLoRA: combinando ideas¶
QLoRA (Dettmers et al., 2023) notó que los pesos base W en LoRA tampoco necesitan precisión completa, porque están congelados. Cuantízalos agresivamente (NF4 — ver theory 03 de la Fase 26). Las matrices LoRA A, B se quedan en fp16 (lo bastante pequeñas como para que el almacenamiento no importe).
El forward se convierte en:
La descuantización ocurre al vuelo por capa. Ahorros de memoria: 4× sobre los pesos base — que dominan la huella total.
Un modelo de 7B: - LoRA fp16: 14 GiB base + ~7 MiB LoRA + 56 MiB Adam (sólo para LoRA) ≈ 14 GiB. - QLoRA NF4: 3.5 GiB base + 7 MiB LoRA + 56 MiB Adam ≈ 3.6 GiB.
Un modelo de 7B se ajusta (fine-tunes) en <6 GiB de RAM de GPU. Nivel consumo. Esta es la razón por la que cada experimento de fine-tuning en la comunidad LLM open-source desde mediados de 2023 usa QLoRA.
Lo que la Fase 28 hace realmente¶
Nuestro MiniGPT es pequeño — millones de params, no miles de millones. El beneficio de memoria de LoRA a esta escala es modesto; el argumento de conteo de parámetros sigue siendo válido (el conjunto entrenable de LoRA es mucho menor que el conjunto completo de pesos), pero los ahorros absolutos en bytes son marginales.
Está bien. La Fase 28 trata de entender, no de lograr los mayores ahorros posibles. Nosotros:
- Implementamos
LoRALineardesde cero (vive ensrc/minituner/). - Derivamos la matemática de params/memoria de forma simbólica.
- Hacemos fine-tuning de MiniGPT sobre el subconjunto de verbos irregulares del corpus de la Fase 12 — concretamente, pares de entrenamiento de la forma
(prompt = "He __ to school yesterday", target = "went")para los 8 verbos irregulares. - Mostramos empíricamente que la PPL de la tarea base (frases held-out de verbos regulares) se preserva (sin olvido).
- Barremos el rango (rank) para encontrar el codo de rendimientos decrecientes.
- Adelantamos QLoRA combinando el NF4 de
src/miniquant/con nuestroLoRALinear.
La vista previa de QLoRA no mostrará ahorros de memoria dramáticos porque MiniGPT es demasiado pequeño. Mostrará la integración — el patrón de ingeniería que escala a 7B+ en el mismo código.
Un ejemplo numérico concreto¶
Un Linear(in=4096, out=4096) estándar:
- Full FT params entrenables:
4096² = 16.78 M. - LoRA r=8 params entrenables:
4096 × 8 + 8 × 4096 = 65 K. 256× menos. - LoRA r=16 params entrenables:
4096 × 16 × 2 = 131 K. 128× menos.
Para un transformer de 32 capas con 4 Linears por capa (proyecciones Q, K, V, output) todas de tamaño (4096, 4096):
- Full FT:
32 × 4 × 16.78M = 2.15 Gparams entrenables. - LoRA r=8:
32 × 4 × 65K = 8.3 Mparams entrenables. Menos del 0.4% del total.
Añade los Linears del MLP (típicamente (4096, 16384) y (16384, 4096) por capa):
- Params MLP por capa:
4096 × 16384 + 16384 × 4096 = 134 M. - LoRA r=8 MLP por capa:
(4096 + 16384) × 8 × 2 = 328 K. 408× menos.
A lo largo de 32 capas MLP + atención: full FT ~7 G params; LoRA ~30 M params. Dos órdenes de magnitud de diferencia.
Para un modelo de 7B, los números correspondientes son similares en ratio: LoRA r=8 a lo largo de todos los Linears = ~50 M params entrenables, sobre 7 G totales. ~0.7% entrenable.
Olvido catastrófico en una línea¶
Cuando entrenas los 2.15 G de parámetros de atención sobre una tarea de 500 ejemplos, cada paso de gradiente los empuja. A lo largo de 1000 pasos, la deriva acumulada es suficiente para degradar perceptiblemente capacidades no relacionadas — la distribución original para la que los pesos eran "buenos" ya no es la distribución que estás optimizando.
El truco de LoRA: los 2.15 G de parámetros congelados no pueden derivar. Sólo los 8.3 M de nuevos params de LoRA absorben el gradiente. La capacidad preentrenada se preserva estructuralmente.
En el lab 02 medimos esto: PPL sobre el split de control de verbos regulares antes y después del fine-tuning, tanto para full FT (deriva al alza) como para LoRA (se mantiene plana). Concretamente: entrenar sobre los 8 verbos irregulares; evaluar en frases con los 12 verbos regulares (work, play, walk, talk, …). LoRA debería dejar plana la PPL de verbos regulares (dentro del 5%); full FT derivará visiblemente.
Lo que esta fase NO cubre¶
- RLHF / DPO / PPO implementados de verdad. Repasados sólo en theory 04.
- Métodos de adaptador (adapter) distintos a LoRA (prefix tuning, prompt tuning, IA³). Mencionados, no implementados.
- Gestión multi-adaptador (cargar/descargar adaptadores en tiempo de servicio). Territorio de la Fase 31.
- Fine-tuning de un modelo de 7B+. Nuestro modelo es MiniGPT; la matemática escala, el experimento no necesita hacerlo.
- Búsqueda de hiperparámetros a escala. Un LR + un batch size + una planificación de decaimiento.
- Entrenamiento de modelo de recompensa. Fuera de alcance.
- Fine-tuning específico de pares en español. La señal bilingüe ya está en el corpus; LoRA la absorbe naturalmente. Sin tratamiento especial.
Recapitulación en un párrafo¶
El fine-tuning completo actualiza todos los parámetros de un modelo preentrenado — derrochador en memoria y cómputo, y propenso al olvido catastrófico. La observación empírica clave que habilita LoRA es que la actualización útil del fine-tuning vive en un subespacio de bajo rango del espacio de pesos. LoRA lo parametriza directamente: dos matrices pequeñas A, B cuyo producto BA se suma a cada W congelado. El conteo de parámetros entrenables cae 50–400×, la memoria cae correspondientemente, y la base congelada preserva la capacidad preentrenada. QLoRA empuja más allá cuantizando la base congelada a NF4 — combinando la cuantización de la Fase 26 con los adaptadores de esta fase. El resto de la Fase 28 deriva la matemática con precisión y ejecuta la receta en MiniGPT.
Siguiente: theory/01-sft-and-forgetting.md.