README · by ansango
← Volver al libro

Técnicas de finetuning

El arsenal de PEFT, LoRA, QLoRA, adapters, model merging y multi-task finetuning. Cuándo usar cada uno y tácticas prácticas

~6 min de lectura
Resumen

Esta nota cubre la segunda mitad del capítulo 7: las técnicas concretas que existen para hacer fine-tuning viable en hardware modesto. PEFT (Parameter-Efficient Fine-Tuning) con LoRA, QLoRA y adapters, cómo se entrenan, y técnicas avanzadas como model merging y multi-task finetuning. Cerramos con tácticas prácticas: cómo elegir el learning rate, cuántas epochs, cómo evaluar. La parte conceptual (cuándo fine-tunear, memoria) está en Finetuning: decisiones y memoria.

Por qué PEFT

Recordemos la matemática de la nota anterior: fine-tunear un modelo de 7B consume ~56 GB de VRAM solo en pesos + gradientes + optimizador. Para 70B, la cifra se dispara. PEFT (Parameter-Efficient Fine-Tuning) es un conjunto de técnicas que solo ajustan una pequeña fracción de los parámetros, dejando el resto congelado.

Beneficios

“PEFT es la democratización del fine-tuning.”

El libro destaca que PEFT es lo que ha permitido que equipos pequeños fine-tuneen modelos que antes estaban reservados a organizaciones con clusters de GPUs.

LoRA (Low-Rank Adaptation)

La técnica PEFT más popular. La idea central: no actualizar los pesos directamente, sino aprender una matriz de bajo rango que se multiplica con ellos.

Cómo funciona

En cada capa lineal del transformer, los pesos son una matriz W de dimensión d × d. LoRA aprende dos matrices A y B tales que:

W' = W + α × (A × B)

donde:

El número de parámetros entrenables pasa de a 2 × d × r, una reducción brutal.

Intuición

Cuando r es pequeño, la matriz A × B solo puede representar pocos patrones de cambio. Esto fuerza al modelo a aprender adaptaciones simples, no a reescribir sus pesos.

El rank es el hiperparámetro clave

Implementación

from peft import LoraConfig, get_peft_model

config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

model = get_peft_model(base_model, config)
model.print_trainable_parameters()
# Salida típica: "trainable params: 4.2M || all params: 7B || trainable: 0.06%"

Qué módulos targetear

Por defecto, LoRA se aplica a q_proj y v_proj (proyecciones de atención). Pruebas recientes muestran que aplicar también a k_proj, o_proj, gate_proj, up_proj, down_proj mejora resultados sin coste excesivo.

Más módulos ≠ siempre mejor

Más módulos entrenables = más capacidad pero más memoria y más riesgo de overfitting. La convención 2024 es aplicar a todas las proyecciones lineales.

QLoRA

QLoRA = LoRA + cuantización de 4 bits del modelo base.

Cómo funciona

  1. Cuantizar el modelo base a INT4 (con el algoritmo NF4 de bitsandbytes).
  2. Aplicar LoRA sobre las capas cuantizadas.
  3. Entrenar solo los adapters LoRA.

Beneficios

from transformers import BitsAndBytesConfig
from peft import LoraConfig, prepare_model_for_kbit_training

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True
)

model = AutoModelForCausalLM.from_pretrained(
    "model_name",
    quantization_config=bnb_config,
    device_map="auto"
)
model = prepare_model_for_kbit_training(model)
QLoRA es el sweet spot actual

El libro recomienda QLoRA como punto de partida por defecto para fine-tuning en hardware modesto. Si necesitas más capacidad, sube a LoRA en FP16. Si necesitas más aún, full fine-tuning.

Otros métodos PEFT

Adapters

Capas adicionales insertadas dentro del modelo, congelando la red original.

Históricamente importantes, pero hoy LoRA ha ganado la batalla por simplicidad y rendimiento.

Prefix tuning

Añadir prefijos entrenables al input de cada capa de atención. El modelo aprende a condicionarse por estos prefijos.

Prompt tuning

Aprender prompts suaves (embeddings, no tokens reales) que se prependen al input.

(IA)³

Multiplicar las activaciones por vectores aprendidos, escalando el efecto de cada componente.

Cuándo cada técnica

TécnicaParámetros entrenablesMemoriaCuándo
Full FT100%Muy altaTienes 8+ GPUs y presupuesto
LoRA0.1-1%MediaDefault razonable
QLoRA0.1-1%BajaHardware modesto
Adapters1-5%MediaCasos legacy
Prefix tuning0.01%BajaPrompt condicional
Prompt tuning0.001%MínimaMultitask simple

Model merging

Después de entrenar varios adapters, hay técnicas para combinarlos en un solo modelo sin reentrenar.

Model souping

Si tienes varios modelos fine-tuneados con el mismo entrenamiento pero diferentes seeds, promediar los pesos produce a menudo un modelo mejor que cualquiera de los originales.

El truco del “model soup”

Entrena 3 modelos con seeds distintos. Promedia sus pesos. Sin coste adicional, el modelo promediado es típicamente 0.5-1% mejor.

Task arithmetic

Si entrenas adapters para tareas A, B y C, puedes sumar y restar los adapters como vectores:

Adapter_Sumar = Adapter_A + Adapter_B
Adapter_Restar = Adapter_A - Adapter_B (esto te da "lo específico de A")

Permite combinación y descomposición de capacidades.

SLERP (Spherical Linear Interpolation)

Interpolar entre dos modelos en la esfera de pesos (no en línea recta):

def slerp(model_a, model_b, t=0.5):
    """Interpola entre model_a y model_b con factor t."""
    # Implementación usando spherical geometry
    ...

Útil para combinar modelos specialty y base.

MergeKit

La herramienta más popular para todo esto. Soporta:

mergekit-yaml config.yaml merge_output/

Multi-task finetuning

Entrenar un solo modelo en múltiples tareas a la vez.

Por qué

Técnicas

Mixture training

Mezclar datasets de distintas tareas, entrenar normalmente.

Multi-task prompting

Añadir al prompt una instrucción de tarea:

Tarea: clasificación de sentimiento
Review: "El producto es horrible."
Sentimiento: NEGATIVO

Tarea: traducción
Texto: "Hello, world"
Traducción: "Hola, mundo"

Conditional computation

Mezclar los datasets con un campo de “task token” que le indica al modelo qué tarea es.

Multi-task + LoRA

La combinación más popular: un adapter por tarea entrenado con multi-task, después se selecciona el adapter según la tarea. Tienes specialization sin perder el modelo base.

Tácticas prácticas de fine-tuning

El libro cierra con una lista de consejos prácticos basados en la experiencia.

Learning rate

TipoLR típico
Full FT1e-5 a 5e-5
LoRA1e-4 a 5e-4
QLoRA1e-4 a 2e-4
Embeddings1e-5 a 5e-5
LR o learning rate scheduler

El libro recomienda SIEMPRE usar un scheduler (cosine, linear decay). Sin scheduler, los fine-tunes divergen o no convergen.

Número de epochs

Batch size

Cuantización del optimizador

Usar AdamW8bit (bitsandbytes) en lugar de AdamW puro reduce memoria del optimizador un 50%.

Validación

Catastrophic forgetting

Síntoma: el modelo fine-tuneado olvida capacidades que tenía antes (responder en idiomas, seguir instrucciones básicas).

Mitigaciones:

Test de olvido

El libro recomienda un test “anti-forget”: mantener un dataset de capacidades generales y medir que no caigan más de X% después del fine-tune.

Dataset prep

Framework

La elección de framework importa menos que la de datos

El libro es claro: el 80% del éxito de un fine-tune está en los datos, no en el framework. No pierdas semanas eligiendo framework; dedica ese tiempo a curar datos.

Resumen en tres frases

Próximos pasos