Skip to content

English · Español

Lab 01 — Conteos de parámetros y memoria de LoRA

🇪🇸 Pura aritmética: contar parámetros entrenables, calcular memoria. Sin entrenar nada. Lo que hace esta práctica reveladora es comparar full FT vs LoRA r=4/8/16 vs QLoRA al mismo modelo (MiniGPT con d_model=64, n_layer=4). El ratio importa más que el valor absoluto.

Anclas: theory/02-parameter-count.md, theory/03-memory-footprint.md.


Qué produces

Un script experiments/28-lora-counts/count.py que imprime una tabla de conteo de parámetros + huella de memoria para MiniGPT bajo cinco regímenes de entrenamiento:

  1. Ajuste fino completo (mixed precision fp16).
  2. LoRA r=4 (todos los Linears).
  3. LoRA r=8 (todos los Linears).
  4. LoRA r=16 (todos los Linears).
  5. QLoRA r=8 (todos los Linears, base en NF4).

Más un report en markdown experiments/28-lora-counts/REPORT.md discutiendo los ratios.

TODOs (esbozo)

Bloque A — Conteos de parámetros (pura aritmética, sin cargar el modelo)

  1. Codifica a mano la forma de MiniGPT según §A13: n_layer=4, n_head=4, d_model=64, vocab_size (léelo del artefacto de la Fase 13), d_ff = 4 * d_model = 256.
  2. Por capa:
  3. Atención: 4 Linears de (d_model, d_model) = (64, 64).
  4. MLP: (d_model, d_ff) = (64, 256) + (d_ff, d_model) = (256, 64).
  5. Params entrenables por capa en full FT: 4 * 64 * 64 + 64 * 256 + 256 * 64 = 16384 + 16384 + 16384 = 49152.
  6. LoRA r=8 por capa: atención 4 * (64+64) * 8 = 4096; MLP (64+256)*8 + (256+64)*8 = 2560 + 2560 = 5120; total 9216.
  7. A lo largo de las n_layer=4 capas, más embedding/lm_head (excluidos de LoRA por defecto según BLUEPRINT).

Bloque B — Huella de memoria (régimen mixed-precision)

Según el modelo de cuatro buckets de theory 03. Para cada régimen, calcula los bytes para:

  • Pesos (fp16 + master fp32 si full FT; NF4 si QLoRA; fp16 si base LoRA).
  • Gradientes (fp16, sólo para los entrenables).
  • Estado de Adam (fp32 m y v, sólo para los entrenables).
  • Activations: estimación aproximada batch_size × seq_len × d_model × n_layer × 16 bytes (usa batch_size=16, seq_len=32).

Bloque C — La tabla

Produce una tabla Markdown como:

Régimen Params entrenables Params congelados Pesos Grads Adam Activations Total
Full FT (fp16+fp32) ... 0 ... ... ... ... ...
LoRA r=4 ... ... ... ... ... ... ...
...

Más una columna "ratio vs full FT".

Bloque D — Un gráfico de barras

Barra apilada de Matplotlib (una barra por régimen, pilas: pesos / grads / Adam / activations). Guardar en experiments/28-lora-counts/memory_breakdown.png.

Bloque E — Comprobación de sanidad contra la teoría

Los ratios deberían coincidir con r/h de theory 02 para capas cuadradas (LoRA r=8 vs full FT sobre atención: ratio = (64+64)*8 / 64² = 1024/4096 = 25%). Mayor que el r/h ≈ 0.2% a escala LLaMA — eso es porque nuestro h=64 es diminuto. Anótalo en el REPORT.

Restricciones

  • Sin entrenar. Pura aritmética.
  • Los números del REPORT deben ser reproducibles desde count.py — sin editarlos a mano.
  • Cita theory 02 y 03 donde provengan las fórmulas.

Condiciones de parada

Has terminado cuando:

  1. python experiments/28-lora-counts/count.py produce la tabla.
  2. memory_breakdown.png existe y es legible.
  3. REPORT.md incluye: la tabla, una discusión de 2 párrafos sobre los ratios a escala MiniGPT vs escala de producción, y la respuesta numérica explícita a "¿Qué fracción de params entrena LoRA r=8?" para MiniGPT.
  4. La comprobación de sanidad a mano coincide con la salida de count.py (haz al menos un régimen a mano).

Trampas (específicas de esta práctica)

  1. Olvidar los biases. Un nn.Linear(in, out) típico tiene out × in + out params (con bias). Que incluyamos biases o no en el conjunto LoRA-able depende de target_modules. Por defecto, según BLUEPRINT: el bias se queda congelado, no se le aplica LoRA. Sé explícito.
  2. Contar el lm_head dos veces. Algunas implementaciones atan el embedding al lm_head. Comprueba el flag tie_weights.
  3. Las activations están dominadas por batch × seq × d_model, no por los params. No las subestimes.
  4. Copia maestra fp32 para Adam. Full FT en mixed precision mantiene una copia fp32 de los pesos para estabilidad. Añade 4N bytes. Fácil de pasar por alto.
  5. Escalas por bloque de NF4. NF4 empaqueta 2 pesos/byte pero también necesita ~1 escala fp16 por bloque de 64 pesos. El overhead es 4/64 = 0.0625 byte/peso. Inclúyelo.

Cuándo consultar las soluciones

Cuando tu comprobación a mano discrepa con count.py, depura tú mismo primero. Si has pasado más de 30 minutos y la discrepancia sigue ahí, abre solutions/01-lora-counts-ref.md.

Tiempo estimado

2-3 horas.


Siguiente: lab/02-lora-finetune.md.