Ajuste fino con LoRA y QLoRA
El ajuste fino afina comportamiento, no conocimiento. Es la herramienta
correcta cuando el modelo conoce el material pero ejecuta el baile
equivocado: formato de salida erróneo, tono erróneo, dialecto de dominio
erróneo, calibración de rechazos errónea. Es la herramienta equivocada
para «conoce mis documentos» — eso es recuperación: RAG.
¿Ajustar fino o no?
| Objetivo | Recurre a |
|---|---|
| Responder preguntas de mis documentos | RAG |
| Emitir siempre mi formato exacto JSON/XML | LoRA — o decodificación restringida por gramática |
| Escribir con un estilo editorial consistente | LoRA |
| Dejar de rechazar peticiones legítimas del dominio | LoRA, con datos cuidadosos |
| Hablar con fluidez el dialecto de mi dominio | LoRA, luego RAG encima |
| Razonar mejor | Modelo base más grande o mejor — el ajuste no añade IQ |
Si un prompt o un esquema pueden hacerlo, prefiere el prompt o el
esquema. Afina cuando te pillas pegando los mismos 300 tokens de
instrucciones en cada llamada.
LoRA en un párrafo
Congela todos los pesos base. Para cada matriz de pesos objetivo, añade
dos matrices pequeñas entrenables — A (r×d) y B (d×r) — y entrena solo
esas. La actualización es de rango bajo:
W' = W + (alpha / r) · B·A # A es r×d, B es d×r, rango r << d
Concreto: una matriz de d = 4096 a rango r = 16 necesita 2 × 4096 × 16 =
131k parámetros de adaptador en vez de los 4096² ≈ 16.8M densos — el
0.8% de esa matriz. A lo largo de un modelo de 7–8B, los adaptadores
totales suman ~40–80M de parámetros: 0.5–1% de la base, unos cientos de
MB. Esa capacidad basta para mover con fuerza estilo y formato, porque
esos comportamientos viven en direcciones fuertemente de rango bajo.
QLoRA: una tarjeta de consumo
QLoRA mantiene la base congelada cuantizada a 4 bits (NF4) durante el
entrenamiento y corre los adaptadores en 16 bits. Números operativos en
pilas actuales: un modelo de 7–8B se entrena con QLoRA en una sola GPU de
24GB; un 3B entrena cómodo en 8GB. El checkpointing de gradientes y los
optimizadores paginados los maneja la herramienta — lo que aportas tú es
la matemática del presupuesto: cálculo de VRAM.
Los datos vencen a todo
500–5,000 pares de alta calidad vencen a 100k pares raspados, todas las
veces. Las reglas que importan:
- Un formato consistente. Usa exactamente la plantilla de chat con la
que servirás — un desajuste de plantilla entre entrenamiento y servicio
deshace toda la corrida. - Calidad sobre volumen. Cada par debería ser una salida que
aceptarías del modelo. Deduplica; tira los ejemplos perezosos. - Cobertura. Incluye los casos donde quieres que el modelo decline
o trate especial — de lo contrario sobre-generaliza su nuevo
comportamiento sobre todo. - Comprobaciones de contaminación. Asegúrate de que las preguntas de
evaluación no aparezcan en los datos de entrenamiento — de lo contrario
estás calificando memorización. - Conjunto de evaluación aparte. 50–100 ejemplos en los que nunca
entrenas, calificados antes y después.
Cómo se ve un par (el formato messages que consumen la mayoría de las
herramientas):
{"messages": [{"role": "system", "content": "You are a 1998-era equipment manual assistant."},
{"role": "user", "content": "How do I reset the service counter?"},
{"role": "assistant", "content": "Press MENU and hold for 3 seconds..."}]}
Herramientas
| Herramienta | Por qué elegirla |
|---|---|
| Unsloth | entrenadores de una sola GPU más rápidos, cuadernos comunitarios gratis — el arranque fácil |
| Axolotl | dirigido por configuración, amplio soporte de formatos de dataset, recetas reproducibles |
| LLaMA-Factory | GUI más CLI, fuerte ecosistema de datasets multilingües |
A fecha de redacción los tres se mantienen activamente:
unsloth,
axolotl,
llama-factory.
Hiperparámetros que importan de verdad
En orden de impacto:
- Tasa de aprendizaje — 1e-4 a 2e-4 para QLoRA es la banda sensata;
demasiado alta es la causa habitual de la papilla. - Épocas — 1–3. Más es de donde sale el adulón.
- Rango / alpha — r 8–32 con alpha 16–32 cubre la mayoría de los
retoques de comportamiento; rango mayor para cambios cargados de
dominio. - Longitud de contexto — fijada a tu ejemplo real más largo, no al
valor por omisión del entrenador. - Tamaño de lote — 1–8 es normal para QLoRA en una tarjeta; es un
control de rendimiento, no de calidad.
Si una corrida decepciona, arregla primero los datos, luego la tasa de
aprendizaje, el rango al final.
Tiempo y coste
QLoRA sobre 2,000 pares, 3 épocas, modelo de 7–8B: espera 1–3 horas en
una tarjeta clase RTX 3090/4090. Eso es electricidad, no facturas de API,
y la iteración es de una noche en el peor caso. Por eso el ajuste fino
local es un hobby, no un proceso de adquisición.
Presupuesta iteración: la primera corrida te enseña los problemas de los
datos, la segunda es la que conservas.
Evalúa antes de enviar
Corre una batería fija de 30–50 prompts — incluido el conjunto aparte —
antes y después; difunde las salidas lado a lado. Luego comprueba por
regresión el chat general: el fallo clásico es un modelo afinado por
dominio que responde todo en formato de informe de bugs. Si la calidad
general bajó, usa menos épocas, una tasa de aprendizaje menor, o mezcla
10–30% de datos de instrucciones generales en la corrida.
Las curvas de pérdida sirven para detectar divergencia, no para poner
notas: la pérdida de entrenamiento debe caer y aplanarse. La batería de
evaluación es el árbitro.
Exporta y sirve
Dos caminos desde un adaptador entrenado:
- Fusiona el LoRA en la base a fp16, luego convierte a GGUF para
llama.cpp — el artefacto amistoso para el foro: un archivo, cualquier
motor: formatos de modelo,
cuantización. - Mantén el adaptador separado para transformers/vLLM, que cargan
base + adaptador en tiempo de ejecución — más barato de iterar,
específico del motor.
Modos de fallo
- Sobreajuste / «adulón» — hace eco de tu prompt, está de acuerdo con
todo; pérdida de entrenamiento baja, evaluación peor. Arreglo: menos
épocas, LR más baja, datos más diversos. - Olvido catastrófico — habilidad de dominio arriba, capacidad general
abajo. Arreglo: mezcla datos generales; baja la LR. - Deriva de plantilla — entrenado con una plantilla de chat, servido
con otra; los síntomas son los clásicos de resolución de
problemas.
DPO tras el SFT
Cuando el formato ya está bien pero las preferencias no — demasiado
verboso, tono equivocado, rechaza de más — una corrida pequeña de DPO
sobre pares de preferencias (respuestas elegidas vs rechazadas) ajusta el
comportamiento sin otra pasada de SFT. Barato, estable, y la segunda
etapa estándar de la receta SFT-luego-DPO.
Relacionados: rag · formatos de modelo · cuantización · cálculo de VRAM