Módulo 07 · Evaluación

Evaluación reproducible

La trampa más común tras un fine-tuning es "probar" el modelo charlando con él: unas cuantas preguntas, una impresión subjetiva y un veredicto. Eso no es evaluación, es anécdota. Para saber si el entrenamiento sirvió hay que construir un harness reproducible: el mismo set de prompts, la misma configuración de generación, la misma seed, aplicados por igual a cada variante. La regla de oro es simple y no negociable: construye el set de evaluación primero y NUNCA lo uses para entrenar.

Al terminar sabrás

  • Separar el set de evaluación del de entrenamiento y por qué el solapamiento invalida los números.
  • Comparar base vs +LoRA vs fusionado vs cuantizado con los mismos prompts, misma config y misma seed.
  • Distinguir métricas académicas (calidad de la respuesta) de métricas técnicas (coste y velocidad).
  • Calcular perplexity de ventana deslizante y exactitud con su intervalo de confianza.
  • Hacer la evaluación determinista (seeds fijas, $T=0$ greedy) para que re-ejecutar dé el mismo resultado.

1Por qué no se evalúa charlando

Un chat casual mide tu memoria selectiva, no el modelo. Cambias el prompt sin darte cuenta, ignoras los fallos que no esperabas y recuerdas el mejor turno. Peor aún: si comparas dos variantes en sesiones distintas, la temperatura, la seed o incluso el orden de las preguntas ya te dieron números que no significan nada. La evaluación seria es un procedimiento fijo que produce el mismo veredicto cada vez que lo corres.

El pilar es un conjunto retenido (held-out): un set de casos que el modelo nunca vio durante el entrenamiento. Si un ejemplo aparece tanto en train como en eval, el modelo puede haberlo memorizado y la métrica sube por la razón equivocada. Separa ambos conjuntos antes de entrenar y trátalos como sagrados.

Regla de oro

Crea el set de evaluación primero y NUNCA lo uses para entrenar. Un solo ejemplo filtrado desde eval hacia train contamina toda la comparación: los números dejan de medir generalización y empiezan a medir memorización.

2Las cuatro variantes bajo el mismo microscopio

Tras entrenar rara vez hay "un" modelo: hay una familia de artefactos derivados del mismo trabajo. Para decidir cuál llevar a producción hay que puntuarlos a todos con el mismo procedimiento. Las cuatro variantes típicas del curso son:

VarianteQué esPara qué la comparas
BaseEl modelo original sin tocar (p. ej. Qwen3-0.6B).Es tu línea de referencia: sin ella no sabes si ganaste algo
+LoRABase con el adaptador cargado en tiempo de inferencia.Mide el efecto puro del entrenamiento
FusionadoAdaptador integrado a los pesos en fp16.Verifica que fusionar no degrada respecto a +LoRA
CuantizadoEl fusionado convertido a GGUF-Q4 (u otra precisión).Cuantifica el precio en calidad de comprimir

La condición innegociable: mismos prompts, misma configuración de generación y misma seed para las cuatro. Si cambias cualquiera de esas tres cosas entre variantes, estás midiendo el cambio, no el modelo. Un solo bucle debe recorrer las cuatro variantes con exactamente los mismos argumentos de decodificación.

3Métricas académicas — ¿es buena la respuesta?

Estas métricas juzgan la calidad de lo que produce el modelo. Algunas son automáticas (exactitud, perplexity); otras requieren una rúbrica y un juez (humano o un modelo evaluador). Para un tutor educativo, por ejemplo, importan dimensiones como:

  • Exactitud: ¿la respuesta es correcta respecto a la referencia?
  • Adecuación: ¿el tono y el nivel encajan con el destinatario?
  • Uso del currículo: ¿se apoya en el material previsto y no inventa?
  • Claridad: ¿se entiende sin releer tres veces?
  • Calidad de las pistas: ¿guía sin resolver de golpe?
  • Detección del error: ¿identifica dónde se equivocó el usuario?
  • No revelar la solución de inmediato: ¿resiste dar la respuesta completa al primer intento?
  • Reconocer la incertidumbre: ¿admite cuando no sabe en lugar de alucinar?

Cada dimensión se puntúa contra una rúbrica escrita de antemano, no según el ánimo del revisor. Fijar la rúbrica primero es lo que hace repetible una evaluación cualitativa.

4Métricas técnicas — ¿cuánto cuesta?

Una respuesta perfecta que tarda ocho segundos en un teléfono no sirve. Las métricas técnicas miden el coste de servir cada variante y son las que suelen decidir entre el fusionado y el cuantizado:

MétricaQué captura
Tokens/sRendimiento de generación sostenido
Tiempo al primer tokenLatencia percibida antes de que empiece a responder
RAM máximaPico de memoria; decide si cabe en el dispositivo
TamañoPeso del artefacto en disco
PerplexityQué tan bien predice el texto retenido
Δ antes/después de cuantizarCuánto se degrada la calidad al comprimir

La columna que más se ignora es la última: el delta de cuantización. No basta con saber la perplexity del Q4; hay que compararla con la del fp16 del que salió. Si el salto es pequeño, la compresión fue gratis; si es grande, estás pagando calidad por tamaño y hay que decidirlo a conciencia.

5Perplexity de ventana deslizante

La perplexity resume qué tan "sorprendido" queda el modelo por un texto: es la exponencial de la entropía cruzada media por token. Menor es mejor. Formalmente, sobre una secuencia de $N$ tokens:

$$ \mathrm{PPL} = \exp\!\left(-\dfrac{1}{N}\sum_{t=1}^{N}\log p_\theta(x_t\mid x_{<t})\right) = \exp(\text{cross-entropy}) $$

El detalle que arruina las comparaciones es la tokenización y el stride. Dos variantes solo son comparables si usan el mismo tokenizer y la misma estrategia de ventana. Cuando la secuencia excede el contexto del modelo, se evalúa por ventanas deslizantes con solapamiento (stride), contando la pérdida solo de los tokens nuevos de cada ventana. Reporta siempre qué tokenizer y qué stride usaste: sin eso, el número no es reproducible.

Nota · comparabilidad

Un modelo cuantizado usa el mismo tokenizer que su fp16 de origen, así que su PPL es directamente comparable. Pero comparar la PPL de dos familias con vocabularios distintos no tiene sentido: la unidad de "sorpresa por token" cambia con la tokenización.

6Exactitud y su intervalo de confianza

Para tareas con respuesta verificable, la métrica base es la exactitud (exact-match): la fracción de casos donde la predicción coincide con la referencia.

$$ \mathrm{Acc} = \dfrac{1}{N}\sum_i \mathbb{1}[\hat y_i = y_i] \qquad\text{y para opción múltiple}\qquad \arg\max_c \sum_t \log p_\theta(\text{opción}_c) $$

En opción múltiple no se genera texto libre: se puntúa cada opción por su log-probabilidad y se elige la de mayor score. Pero una exactitud sola engaña: con pocos casos, un 82% puede ser indistinguible de un 78%. Por eso se reporta con un intervalo de confianza (aproximación normal o Wilson):

$$ \mathrm{Acc} \pm z\sqrt{\dfrac{\mathrm{Acc}(1-\mathrm{Acc})}{N}} $$

donde $z$ es el cuantil normal para el nivel deseado (p. ej. $z \approx 1.96$ para el 95%). Esta es la aproximación de Wald; con $N$ pequeño o exactitudes cercanas a 0 o 1 es poco fiable, y conviene el intervalo de Wilson, más robusto en ese régimen. La lectura práctica: si el intervalo de una variante solapa con el de la base, no puedes afirmar que ganaste; la diferencia cabe dentro del ruido muestral. Un set más grande estrecha el intervalo y vuelve detectables las mejoras reales.

7Determinismo — que re-ejecutar dé lo mismo

Una evaluación no es reproducible si dos corridas dan números distintos. La fuente principal de varianza es el muestreo de la decodificación. La solución es puntuar con decodificación greedy, es decir temperatura cero:

$$ T=0 \;\Rightarrow\; x_{t+1} = \arg\max_{v} z_v \qquad\text{(la varianza de muestreo se anula en } T=0\text{)} $$

Con $T=0$ el modelo siempre elige el token más probable, así que no hay aleatoriedad en la elección. Aun así, fija todas las seeds (Python, NumPy, el framework) y ancla el tokenizer a una versión concreta: distintas versiones tokenizan distinto y cambian tanto la PPL como qué prompt ve el modelo. Determinismo = seeds fijas + $T=0$ + tokenizer y config anclados. Solo entonces la tabla de resultados es un artefacto estable que cualquiera puede regenerar.

En el teléfono

La evaluación no es solo académica: para on-device debe incluir métricas de sistema — tokens/s, tiempo al primer token, RAM pico, tamaño del modelo — medidas en el dispositivo objetivo. Un modelo con +2% de exactitud pero la mitad de tokens/s puede no valer la pena en un teléfono (Módulo 10).

Cómo practicar
  1. Separa un set de evaluación y nunca lo uses para entrenar.
  2. Fija la seed y usa greedy (T=0).
  3. Puntúa exactitud con intervalo de confianza y perplexity de ventana deslizante.
  4. Compara base vs +LoRA vs fusionado vs GGUF-Q4 con el mismo harness.
  5. Marca la variante cuyo CI solape al base (sin ganancia real).
Herramientas: Python · lm-evaluation-harness · evaluate
Rust · on-device

Para medir perplexity y latencia sobre el modelo que realmente corre en el teléfono, evalúa con el runtime de despliegue: llama.cpp trae herramientas de perplexity y bench, y candle permite scriptear la evaluación en Rust.

Así mides el artefacto real que se instala, no una aproximación en el servidor.

Lecturas y recursos

Ejercicios

De menor a mayor complejidad. El último es el que hace un practicante de verdad.

Ejercicio 1 · calentamiento

Separa y congela el set retenido

Toma tu dataset y divídelo en train y eval con una seed fija. Verifica por programa que ningún ejemplo de eval aparece en train (por hash del texto) e imprime los tamaños.

Entrega: conteo train/eval + assert de solapamiento cero.   Pista: normaliza el texto y compara conjuntos de hashes.

Ejercicio 2

Perplexity de ventana deslizante

Implementa el cálculo de perplexity sobre el set retenido para el modelo base, usando ventanas con stride y contando la pérdida solo de los tokens nuevos de cada ventana.

Entrega: un número de PPL + el tokenizer y el stride usados.   Pista: enmascara con -100 los tokens ya contados en la ventana anterior.

Ejercicio 3

Exactitud con intervalo de confianza

Para una tarea de opción múltiple, puntúa cada opción por log-probabilidad, calcula la exactitud sobre el set retenido y reporta su intervalo de confianza al 95%.

Entrega: Acc ± CI.   Pista: usa $\mathrm{Acc} \pm 1.96\sqrt{\mathrm{Acc}(1-\mathrm{Acc})/N}$ o el intervalo de Wilson.

Ejercicio 4

Decodificación determinista

Corre la misma evaluación dos veces con T=0 (greedy), seeds fijas y tokenizer anclado. Demuestra que ambas corridas producen exactamente los mismos números; luego cambia a T=0.7 y muestra que ya no coinciden.

Entrega: dos tablas idénticas con T=0 y dos distintas con T=0.7.   Pista: fija seeds de Python, NumPy y el framework antes de cada corrida.

Ejercicio 5 · ejercicio top

Un script de eval reproducible sobre las cuatro variantes

Construye UN script de eval reproducible (seed fija, decodificación greedy, tokenizer anclado) que puntúe el mismo set retenido sobre cuatro variantes — Qwen3-0.6B base, +adaptador LoRA, fusionado fp16, y fusionado→GGUF-Q4 — reportando exactitud de la tarea (con intervalo de confianza) y perplexity de ventana deslizante en una sola tabla, y marca cualquier variante cuyo CI solape al base (es decir, sin ganancia real).

Entrega: la tabla de 4 filas × (Acc±CI, PPL) producida por un único comando, estable ante re-ejecución.   Pista: un solo bucle recorre las cuatro variantes con los mismos argumentos de decodificación; marca la fila cuando Acc_var − CIAcc_base + CI.

Puntos clave
  • No evalúes charlando: construye un harness reproducible con procedimiento fijo.
  • Crea el set de evaluación primero y NUNCA lo uses para entrenar.
  • Compara base, +LoRA, fusionado y cuantizado con mismos prompts, misma config y misma seed.
  • Separa métricas académicas (calidad) de técnicas (tokens/s, RAM, tamaño, PPL, Δ cuantización).
  • Reporta exactitud con intervalo de confianza; si solapa al base, no hubo ganancia real.
  • Determinismo = seeds fijas + $T=0$ greedy + tokenizer y stride anclados.