19 · LoRA en una celda
El fine-tuning completo actualiza cada peso — miles de millones. LoRA congela los pesos originales y aprende en su lugar una actualización diminuta de bajo rango B·A, recortando los parámetros entrenables en órdenes de magnitud casi sin pérdida.
LoRA (Adaptación de Bajo Rango) congela el peso preentrenado W y aprende una actualización de bajo rango ΔW = B·A, donde B es d×r y A es r×d con rango r diminuto (p. ej. 8). El peso efectivo es W + (α/r)·B·A. Entrenas solo 2·d·r números en vez de d·d — una reducción de órdenes de magnitud.
Sin esto:
Sin fine-tuning eficiente en parámetros, adaptar un modelo de mil millones de parámetros significa almacenar y actualizar una copia completa de cada peso por tarea — inviable en hardware de consumo y derrochador cuando bastaría un adaptador por tarea.
El fine-tuning completo re-entrena cada peso del modelo. Para una capa cuya matriz de pesos W es d × d, son d² parámetros entrenables — y un modelo real tiene cientos de esas matrices, sumando miles de millones. Además debes almacenar una copia entera nueva del modelo por tarea. Ese es el muro que LoRA fue diseñado para escalar.
La observación clave detrás de LoRA (Adaptación de Bajo Rango): la actualización que necesitas para especializar un modelo preentrenado suele tener rango intrínseco muy bajo — se puede aproximar bien con el producto de dos matrices delgadas. Así que en vez de aprender una actualización completa d × d ΔW, LoRA:
- Congela el peso original
W(sin gradientes, nunca cambia). - Aprende dos matrices pequeñas:
Bde formad × ryAde formar × d, donde el rangores diminuto (a menudo 4, 8, 16). - Usa el peso efectivo
W + (α/r)·B·Aen la inferencia, dondeαes una constante de escala.
La actualización ΔW = B·A es una matriz d × d completa, pero se construye con solo d·r + r·d = 2·d·r números entrenables en vez de d·d. Cuando r ≪ d eso es un ahorro enorme. En el entrenamiento solo retropropagas hacia A y B; W queda congelado. En el despliegue puedes mantener el adaptador aparte (intercambiar adaptadores por tarea) o fundir (α/r)·B·A en W para que la inferencia no cueste nada extra.
Esta es exactamente la idea de bajo rango / factorización de matrices del track de matemáticas — una matriz grande aproximada por el producto de dos delgadas — aplicada a actualizaciones de pesos.
Aquí está LoRA en una celda de NumPy. Tomamos un peso W de 512 × 512, construimos una actualización de bajo rango a partir de B (512×r) y A (r×512), formamos el peso efectivo W + (α/r)·B·A y — lo destacado — contamos los parámetros entrenables del fine-tuning completo versus LoRA en varios rangos. Observa cómo el porcentaje de parámetros que de verdad entrenas se desploma hacia una fracción de un por ciento.
Python (in browser)
LoRA en NumPy: una actualización completa d×d ΔW=(α/r)·B·A se construye con solo 2·d·r números entrenables. Con rango 8 en una capa 512×512 entrenas ~3% de los parámetros; la interfaz de la matriz no cambia.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Los ahorros se multiplican a escala real. Un modelo de 7 mil millones de parámetros tiene miles de matrices de pesos; el fine-tuning completo significa un estado de optimizador de 7B parámetros y un checkpoint de 7B parámetros por tarea. Con LoRA en rango 8 entrenas y despachas unos pocos millones de parámetros — suficientemente pequeños para mantener decenas de adaptadores de tareas en disco e intercambiarlos en caliente sobre un único modelo base congelado. Eso es lo que hace peft en la práctica; lee la configuración real abajo.
El LoraConfig de PEFT es exactamente nuestra demo de NumPy a escala: rango r, escala alpha y una lista de qué matrices de pesos reciben un adaptador B·A — entrenando muy por debajo del 0.1% de los parámetros.
En LoRA, para una matriz de pesos d×d con rango r, ¿cuántos parámetros se entrenan realmente y qué queda congelado?
- LoRA congela el peso preentrenado W y aprende una actualización de bajo rango ΔW = B·A (B es d×r, A es r×d) con rango r diminuto.
- Entrenas 2·d·r parámetros en vez de d·d — órdenes de magnitud menos; el peso efectivo es W + (α/r)·B·A.
- B se inicializa en cero para que el adaptador empiece como no-op (entrenamiento estable), y un único modelo base congelado puede intercambiar en caliente muchos adaptadores pequeños por tarea.
LoRA y su variante cuantizada QLoRA son como se afina hoy casi todo modelo de pesos abiertos — el LoraConfig de PEFT entrena menos del 1% de un modelo de 7B para que quepa en una sola GPU de consumo.
Si lo quitas: Sin adaptadores eficientes en parámetros, cada tarea necesita una copia completa de los miles de millones de pesos del modelo entrenada y almacenada — inviable en hardware común y derrochador a escala.