Monitoreo y Depuracion del Entrenamiento
Por Que Importa el Monitoreo
Una ejecucion de fine-tuning puede tomar desde 30 minutos hasta varias horas. Sin monitoreo adecuado, puedes descubrir problemas solo despues de que la ejecucion termine — desperdiciando computo y tiempo. Un buen monitoreo te permite detectar sobreajuste, identificar problemas de datos y cancelar ejecuciones malas temprano. Esta leccion cubre las metricas que debes rastrear, los patrones que debes reconocer y las herramientas que hacen todo esto visible.
Metricas Esenciales de Entrenamiento
Perdida de Entrenamiento (Training Loss)
La metrica principal. Mide que tan bien el modelo predice el siguiente token en los datos de entrenamiento. Una curva de perdida saludable muestra una caida inicial pronunciada seguida de una disminucion gradual.
Que observar:
- Disminucion constante: Bien. El modelo esta aprendiendo.
- Meseta temprana: La tasa de aprendizaje puede ser muy baja, o la tarea es demasiado simple para el rango LoRA.
- Oscilacion: La tasa de aprendizaje es demasiado alta o el tamano de batch es demasiado pequeno.
- Pico repentino: Posible corrupcion de datos en ese batch, o inestabilidad numerica.
Perdida de Validacion (Validation Loss)
Mide el rendimiento en datos que el modelo no ha visto durante el entrenamiento. La brecha entre la perdida de entrenamiento y la de validacion es tu indicador de sobreajuste.
Patron saludable: La perdida de entrenamiento y validacion disminuyen juntas, con la de validacion ligeramente mas alta.
Patron de sobreajuste: La perdida de entrenamiento sigue disminuyendo mientras la de validacion comienza a aumentar. Esto significa que el modelo esta memorizando ejemplos de entrenamiento en lugar de aprender patrones generalizables.
# En TrainingArguments, habilitar evaluacion
training_args = TrainingArguments(
eval_strategy="steps",
eval_steps=50, # Evaluar cada 50 pasos
load_best_model_at_end=True, # Recargar el mejor checkpoint
metric_for_best_model="eval_loss",
greater_is_better=False,
)
Programacion de Tasa de Aprendizaje
Rastrea la tasa de aprendizaje para verificar que tu programador funciona correctamente. Una programacion coseno debe mostrar una curva suave del pico a casi cero. Una programacion lineal debe mostrar un declive recto.
Norma del Gradiente
La magnitud de los gradientes te dice sobre la estabilidad del entrenamiento. Normas de gradiente que se disparan a valores muy altos indican inestabilidad. Normas que colapsan a casi cero indican gradientes que se desvanecen.
# Habilitar registro de norma de gradiente
training_args = TrainingArguments(
logging_steps=10,
logging_first_step=True,
max_grad_norm=1.0, # Recortar gradientes por encima de esta norma
)
Detectando y Corrigiendo el Sobreajuste
El sobreajuste es el problema mas comun en fine-tuning, especialmente con datasets pequenos.
Senales de Sobreajuste
- La perdida de validacion aumenta mientras la de entrenamiento disminuye
- Las salidas del modelo se vuelven copias casi exactas de ejemplos de entrenamiento
- La calidad del modelo se degrada en entradas fuera de distribucion
- La perdida de entrenamiento alcanza valores muy bajos (por debajo de 0.1) inusualmente rapido
Remedios
- Reducir epocas. Si el sobreajuste comienza en la epoca 2, entrena por 1.5 epocas.
- Aumentar dropout. Sube
lora_dropoutde 0.05 a 0.1. - Reducir rango. Un rango LoRA mas bajo (r=8 en lugar de r=16) reduce la capacidad del modelo.
- Agregar mas datos. La mejor solucion si es posible.
- Usar early stopping. Detener el entrenamiento cuando la perdida de validacion no ha mejorado por N pasos de evaluacion.
from transformers import EarlyStoppingCallback
trainer = SFTTrainer(
# ... otros argumentos
callbacks=[EarlyStoppingCallback(early_stopping_patience=5)],
)
Depurando Problemas Comunes
Perdida NaN
La perdida NaN (Not a Number) significa que ha ocurrido un desbordamiento numerico. Esto tipicamente mata la ejecucion de entrenamiento.
Causas comunes y soluciones:
- Tasa de aprendizaje demasiado alta. Reducir de 2e-4 a 5e-5.
- Problemas de precision mixta. Cambiar de fp16 a bf16 (si tu GPU lo soporta). bf16 tiene un rango dinamico mas grande y es menos propenso al desbordamiento.
- Problemas de datos. Verificar ejemplos con texto extremadamente largo o caracteres inusuales que producen valores de perdida muy altos.
- Explosion de gradientes. Reducir
max_grad_normde 1.0 a 0.3.
# Depurar perdida NaN paso a paso
training_args = TrainingArguments(
learning_rate=5e-5, # Tasa de aprendizaje mas baja
bf16=True, # Usar bfloat16 en lugar de fp16
max_grad_norm=0.3, # Recorte agresivo de gradientes
logging_steps=1, # Registrar cada paso para encontrar donde ocurre NaN
)
Explosion de Gradientes
Sintomas: La perdida se dispara repentinamente, las normas de gradiente se vuelven muy grandes (>100), el entrenamiento puede recuperarse o colapsar.
Soluciones:
- Bajar
max_grad_norm(prueba 0.3 o incluso 0.1) - Reducir tasa de aprendizaje
- Aumentar pasos de calentamiento para dejar que el modelo se ajuste gradualmente
Errores de Formateo de Datos
Los bugs mas insidiosos. El modelo entrena sin errores, pero produce basura porque la plantilla de conversacion era incorrecta.
Como verificar:
# Siempre inspecciona ejemplos formateados antes de entrenar
sample = dataset["train"][0]
formatted = tokenizer.apply_chat_template(
sample["messages"],
tokenize=False,
)
print("=== Ejemplo formateado ===")
print(formatted)
print("=== IDs de tokens ===")
tokens = tokenizer.encode(formatted)
print(tokens[:50]) # Primeros 50 tokens
print(f"Total de tokens: {len(tokens)}")
Verifica que:
- Los tokens especiales (BOS, EOS, marcadores de rol) estan presentes y son correctos
- La respuesta del modelo no esta siendo enmascarada durante el entrenamiento
- Los tokens de relleno no estan mezclados en el contenido
El Modelo Produce Salida Repetitiva
El modelo genera la misma frase una y otra vez, o entra en un bucle.
Causas:
- Sobreajuste en datos de entrenamiento repetitivos
- La perdida de entrenamiento llego demasiado baja (sobre-optimizacion)
- Parametros de generacion incorrectos (temperature=0 sin penalizacion)
Soluciones:
- Verificar datos de entrenamiento por duplicados
- Reducir epocas de entrenamiento
- Usar
repetition_penalty=1.1durante la generacion
Configurando TensorBoard
TensorBoard es la solucion de monitoreo mas simple — viene integrada con Hugging Face:
training_args = TrainingArguments(
report_to="tensorboard",
logging_dir="./logs",
logging_steps=10,
)
Lanzar TensorBoard:
tensorboard --logdir ./logs
Esto abre un panel en http://localhost:6006 donde puedes ver curvas de perdida, tasa de aprendizaje, normas de gradiente y mas en tiempo real.
Configurando Weights and Biases
W&B proporciona mas funcionalidades: comparacion de experimentos, barridos de hiperparametros, colaboracion en equipo y rastreo de artefactos de modelo.
pip install wandb
wandb login # Ingresar tu clave API
import wandb
wandb.init(
project="llm-fine-tuning",
name="llama3-8b-legal-v1",
config={
"model": "Llama-3.1-8B",
"rank": 16,
"alpha": 32,
"learning_rate": 2e-4,
"dataset_size": len(dataset["train"]),
}
)
training_args = TrainingArguments(
report_to="wandb",
logging_steps=10,
)
W&B automaticamente registra todas las metricas de entrenamiento, metricas del sistema (memoria GPU, utilizacion) y te permite agregar registro personalizado:
# Registrar predicciones de muestra durante entrenamiento
class PredictionCallback(TrainerCallback):
def on_evaluate(self, args, state, control, **kwargs):
# Generar predicciones en algunos ejemplos
model.training = False # Cambiar a modo evaluacion
test_prompts = ["Explica LoRA", "Que es QLoRA"]
for prompt in test_prompts:
output = generate(model, tokenizer, prompt)
wandb.log({f"prediction/{prompt}": output, "step": state.global_step})
Estrategia de Checkpointing
Guarda checkpoints sabiamente — son tu poliza de seguro:
training_args = TrainingArguments(
save_strategy="steps",
save_steps=100, # Guardar cada 100 pasos
save_total_limit=3, # Mantener solo los 3 mas recientes
load_best_model_at_end=True,
metric_for_best_model="eval_loss",
)
Consejos:
- Para ejecuciones cortas (menos de 500 pasos), guarda cada 50 pasos
- Para ejecuciones largas (mas de 2000 pasos), guarda cada 200 pasos
- Siempre manten al menos el mejor checkpoint basado en la perdida de evaluacion
save_total_limitpreviene llenar el espacio en disco con checkpoints grandes
Lista de Verificacion Practica de Depuracion
Cuando una ejecucion de entrenamiento produce malos resultados, trabaja a traves de esta lista:
- Inspecciona datos en bruto. Lee 10 ejemplos de entrenamiento aleatorios. Son correctos?
- Verifica formato. Imprime un ejemplo formateado con todos los tokens especiales visibles. Coinciden con la plantilla esperada del modelo?
- Verifica tokenizacion. Se estan truncando los ejemplos? Cual es la distribucion de longitud de tokens?
- Revisa curvas de perdida. Esta disminuyendo la perdida de entrenamiento? Esta divergiendo la de evaluacion?
- Prueba manualmente. Genera salidas del modelo en diferentes checkpoints. Mejora la calidad?
- Compara con el modelo base. Es el modelo fine-tuned realmente mejor que el modelo base en tu tarea?
En la proxima leccion, abordamos el tema frecuentemente pasado por alto de la evaluacion — como medir sistematicamente si tu modelo fine-tuned realmente mejoro.