Inicio / Artículos / Cómo QLoRA ajusta modelos grandes en GPU pequeñas: lo básico de los 4 bits

Cómo QLoRA ajusta modelos grandes en GPU pequeñas: lo básico de los 4 bits

Entiende QLoRA desde cero: por qué el ajuste fino completo sale caro, cómo se combinan los adaptadores LoRA y la cuantización a 4 bits y cuándo encaja este enfoque en tu proyecto.

1834 palabras

Hacer ajuste fino de un modelo de lenguaje grande suena a proyecto de laboratorio con mucho presupuesto: varias GPU potentes, cientos de gigabytes de VRAM, infraestructura en la nube cara y una montaña de datos de entrenamiento. QLoRA, abreviatura de Quantized Low-Rank Adaptation, toma otro camino. Comprimes el modelo, le acoplas una pieza entrenable diminuta y lo ajustas con mucha menos memoria. Funciona porque une dos ideas, la cuantización y LoRA, que juntas ponen el ajuste fino eficiente en parámetros al alcance de mucha más gente.

Qué es el ajuste fino

Partimos de un modelo preentrenado. Ya sabe muchas cosas, desde lenguaje y gramática hasta programación y conocimiento general.

Language
Grammar
Programming
General knowledge
Reasoning patterns

A menudo quieres que se especialice. Un camino convierte el modelo generalista, tras el ajuste fino, en un tipo de experto:

General LLM
     ↓
Fine-tuning
     ↓
Medical assistant

Otro camino lo convierte en un especialista distinto:

General LLM
     ↓
Fine-tuning
     ↓
Legal document assistant

Y un tercero da lugar a otro más:

General LLM
     ↓
Fine-tuning
     ↓
Agricultural assistant

La vía tradicional es actualizar muchos o todos los parámetros del modelo, y ahí empiezan los problemas.

Por qué el ajuste fino completo es caro

Los modelos de lenguaje pueden tener miles de millones de parámetros.

7 Billion parameters
13 Billion parameters
70 Billion parameters

El ajuste fino estándar necesita memoria para varias cosas a la vez, entre ellas los pesos, los gradientes y más:

Model weights
+
Gradients
+
Optimizer states
+
Activations

El total se vuelve enorme. Eso llevó a los investigadores a preguntarse si de verdad hay que cambiar cada parámetro, y la respuesta suele ser que no.

LoRA

LoRA significa Low-Rank Adaptation (adaptación de bajo rango). Deja congelados los pesos originales y añade a su lado pequeñas matrices entrenables.

Original Model
      │
      │ frozen
      ▼
 ┌─────────────┐
 │ Base Weights│
 └─────────────┘
      +
 ┌─────────────┐
 │ LoRA Adapter │ ← Train this
 └─────────────┘

En términos matemáticos, una matriz de pesos W normalmente se modifica directamente. LoRA no la toca y aprende una actualización adicional, de modo que los pesos efectivos pasan a ser W' = W + BA, donde A y B son matrices mucho más pequeñas. Acabas entrenando una pequeña fracción de los parámetros en lugar de miles de millones.

El problema que queda

LoRA reduce el conjunto de parámetros entrenables, pero el modelo base sigue teniendo que cargarse en memoria. Toma un modelo cuyos pesos se guardan como números de 16 bits. Cada peso ocupa 2 bytes, así que un modelo de 7B necesita aproximadamente 7B x 2, unos 14 GB, solo para los pesos. El entrenamiento añade más encima. ¿Y si se pudiera hacer más pequeño el propio modelo? Ese es el trabajo de la cuantización.

Cuantización

Cuantizar significa guardar números con menos bits. Un parámetro puede empezar en coma flotante de 32 bits.

FP32
32 bits

A partir de ahí puede bajar por formatos cada vez más pequeños:

      ↓FP16
16 bits      ↓INT8
8 bits      ↓4-bit
4 bits

Usar una representación más pequeña en lugar de una de alta precisión reduce notablemente el uso de memoria.

16-bit model
      ↓
4-bit quantized model
      ↓
Much lower memory requirement

La contrapartida es que una precisión menor puede perjudicar la calidad del modelo. El reto es ahorrar memoria sin arruinar el rendimiento que te importa.

Juntando las dos ideas

Combina ambos conceptos y obtienes QLoRA.

Large LLM
                 │
                 ▼
        ┌─────────────────┐
        │ 4-bit Quantize  │
        └────────┬────────┘
                 │
                 ▼
        Frozen Base Model
                 │
                 +
          ┌────────────┐
          │ LoRA       │
          │ Adapters   │
          └─────┬──────┘
                │
                ▼
        Train Only Adapters

La receta es corta: cuantiza el modelo base, mantenlo congelado y entrena pequeños adaptadores LoRA.

Por qué importa

Compara los dos enfoques con un modelo de 7B. El ajuste fino tradicional se ve así:

Traditional Fine-Tuning
7B Model
   ↓
Train everything
   ↓
Huge memory requirement

QLoRA va por otro camino:

7B Model
   ↓
4-bit quantization
   ↓
Freeze base model
   ↓
Add small LoRA adapters
   ↓
Train adapters

Las necesidades de memoria pueden caer drásticamente. Por eso QLoRA llamó tanto la atención de investigadores y desarrolladores sin acceso a grandes clústeres de GPU.

Qué ocurre durante el entrenamiento

Supongamos que tus datos de entrenamiento contienen un turno de usuario que pide explicar la fotosíntesis a un niño de 10 años:

User:
Explain photosynthesis to a 10-year-old.

y la respuesta correspondiente del asistente:

Assistant:
Photosynthesis is the process...

Los datos pasan por el siguiente pipeline:

Training Dataset
       ↓
Tokenization
       ↓
4-bit Base Model
       ↓
LoRA Layers
       ↓
Forward Pass
       ↓
Loss
       ↓
Backpropagation
       ↓
Update LoRA Parameters

Lo importante es que el enorme modelo base no se actualiza por completo. Solo se actualizan los parámetros entrenables de LoRA.

Un vistazo más de cerca a las matemáticas

Toma una capa con pesos originales W. LoRA añade una actualización delta W = BA, así que la capa adaptada es W' = W + delta W, que es lo mismo que W + BA. El rango de A y B se mantiene pequeño a propósito. Esta es una capa en su forma original:

Original:

mientras que la versión LoRA son solo estas dos matrices estrechas:

4096 × 4096LoRA:4096 × 8
+
8 × 4096

La diferencia es grande. En lugar de aprender 4096 x 4096 parámetros, LoRA aprende unos 4096 x 8 + 8 x 4096, muchísimos menos.

Más que LoRA a 4 bits

El trabajo original de QLoRA añadió varias técnicas que cooperan entre sí. Las más destacadas son estas.

4-bit NormalFloat

QLoRA usa cuantización NF4 (NormalFloat 4-bit), diseñada para pesos de redes neuronales que siguen una distribución normal.

Doble cuantización

La cuantización necesita información de escala. QLoRA cuantiza también esas constantes de cuantización, lo que ahorra algo más de memoria.

Optimizadores paginados

Los optimizadores paginados (paged optimizers) ayudan a gestionar la memoria de la GPU y suavizan los picos de memoria que se producen durante el entrenamiento.

Todo junto, la fórmula simplificada queda así:

QLoRA
=
4-bit Quantization
+
LoRA
+
Memory-efficient training techniques

Con qué te quedas al final

Una ventaja importante del ajuste fino al estilo LoRA es que el adaptador se puede guardar por separado.

Base Model
     +
LoRA Adapter
     =
Fine-Tuned Model

En lugar de guardar otra copia completa del gigantesco modelo base, almacenas un adaptador relativamente pequeño. Eso facilita los experimentos. Un mismo modelo base puede servir para varias tareas, cada una con su propio adaptador:

Base Model
     │
     ├── Medical Adapter
     ├── Coding Adapter
     ├── Legal Adapter
     └── Agriculture Adapter

QLoRA, LoRA y ajuste fino completo, comparados

  • Modelo base: se actualiza en el ajuste fino completo y queda congelado tanto en LoRA como en QLoRA.
  • Precisión de la base: suele ser mayor en el ajuste fino completo y en LoRA, y habitualmente de 4 bits en QLoRA.
  • Parámetros entrenables: enormes en el ajuste fino completo, pocos en LoRA y QLoRA.
  • Memoria de GPU: muy alta en el ajuste fino completo, menor en LoRA, mucho menor en QLoRA.
  • Adaptador: ninguno en el ajuste fino completo, sí en LoRA y QLoRA.
  • Complejidad: alta en el ajuste fino completo, menor en LoRA, moderada en QLoRA.
  • Para GPU limitadas: difícil con el ajuste fino completo, mejor con LoRA y QLoRA.

QLoRA no hace caber por arte de magia cualquier modelo grande en cualquier GPU. El uso real de memoria depende del tamaño del modelo, la longitud de secuencia, el tamaño del batch, el método de cuantización, el optimizador, la configuración de LoRA, el framework y la arquitectura de la GPU. Aun así, el ahorro puede ser considerable.

Una cadena de herramientas típica para QLoRA

Un stack habitual se construye sobre PyTorch:

PyTorch
                │
        ┌───────┴────────┐
        │                │
 Transformers          PEFT
        │                │
        └───────┬────────┘
                │
          bitsandbytes
                │
                ▼
              QLoRA

Las piezas habituales son:

  • PyTorch, el framework de deep learning.
  • Transformers, que proporciona modelos de lenguaje preentrenados.
  • PEFT, para el ajuste fino eficiente en parámetros.
  • bitsandbytes, para la cuantización y las operaciones eficientes en memoria.

Un ejemplo

Imagina que quieres AgriGPT, un modelo de preguntas y respuestas sobre agricultura. Empiezas con un LLM preentrenado y construyes sobre él así:

Pretrained LLM
      ↓
4-bit quantization
      ↓
Add LoRA adapters
      ↓
Agriculture dataset
      ↓
QLoRA training
      ↓
Agriculture adapter

Ahora el modelo se puede especializar en conversaciones agrícolas sin ajustarlo entero. Un usuario podría preguntar:

User:
My tomato leaves have yellow spots. What could be the reason?

y el modelo respondería más o menos así:

Model:
Possible causes include...

La clave es que la especialización procede sobre todo de los parámetros aprendidos del adaptador.

Cuándo encaja QLoRA

QLoRA encaja bien en estas situaciones:

  • El modelo es un LLM de código abierto que quieres ajustar.
  • Vas justo de memoria de GPU.
  • Buscas precisamente un entrenamiento eficiente en parámetros.
  • Necesitas varios adaptadores específicos por tarea.
  • Estás probando modelos específicos de un dominio.
  • Quieres mantener bajo el coste de entrenamiento.

Encaja mal si tu objetivo exige reentrenar el modelo subyacente desde cero o cambiarlo de forma sustancial.

No es entrenar desde cero

Esta distinción importa mucho. Entrenar desde cero empieza así:

Training from scratch
Random initialization
        ↓
Huge dataset
        ↓
Train entire model

QLoRA parte de algo que ya existe:

Pretrained model
        ↓
Quantize
        ↓
Freeze
        ↓
Add LoRA
        ↓
Fine-tune adapter

QLoRA da por hecho que ya tienes un modelo preentrenado.

La idea de fondo

QLoRA cambia la forma de pensar el desarrollo de IA. La pregunta deja de ser cómo entrenar un modelo gigantesco y pasa a ser cómo adaptar con eficiencia un modelo existente a tu problema. Para estudiantes, investigadores, startups y desarrolladores independientes es una pregunta mucho más práctica.

Hardware más pequeño, experimentos más grandes

Técnicas como QLoRA hacen más accesibles los experimentos serios con modelos. Puede que el futuro no se reduzca a esto:

Bigger Model
+
More GPUs

y que cada vez se parezca más a esto:

Efficient Models
+
Efficient Fine-Tuning
+
Better Data
+
Better Evaluation
+
Specialized Adapters

Lo interesante no es solo hacer modelos más grandes, sino aprender a hacerlos más útiles con menos recursos.

Cambia poco, gana mucho

QLoRA es cuantización más LoRA más eficiencia de memoria. El modelo base se comprime a menor precisión, permanece congelado y se adapta mediante pequeñas matrices LoRA entrenables. Esa combinación hace mucho más asequible el ajuste fino de modelos de lenguaje grandes. Y quizá la lección principal sea que no siempre hay que cambiar el modelo entero para cambiar lo que es capaz de hacer. A veces basta con un añadido pequeño y entrenado con cuidado.