Ajuste fino de Laya con tus propias decisiones
En el benchmark de typed-decisions los checkpoints base puntúan cerca del azar sin ejemplos previos — 0.36 y 0.35 frente a una línea base aleatoria de 0.318 — mientras que el checkpoint ajustado alcanza 0.766 en las mismas 2,000 decisiones, por encima del 0.727 publicado de TypeSafe Jev y por encima del techo de autoacuerdo del profesor de 0.735. El ajuste fino es donde está la mayor parte del valor, y el notebook de ajuste fino público ejecuta todo el bucle en las GPUs 2xT4 gratuitas de Kaggle: construir el conjunto de datos, entrenar con RLCD, ajustar las temperaturas de calibración, evaluar y subir el resultado al Hub. Esta página recorre ese notebook y señala las partes que siguen siendo fundamentales cuando cambias los datos por los tuyos.
El otro ejemplo trabajado — una cabeza de decisión para agente de navegador en una sola GPU de 16 GB sin API de pago — está en Ajuste fino de Laya como cabeza de decisión para agente de navegador.
Qué hace el notebook, en orden
| # | paso | qué ocurre |
|---|---|---|
| 1 | Entorno | verifica que ambas GPUs T4 son visibles y están asignadas |
| 2 | Instalación | laya, transformers, datasets y las dependencias de entrenamiento |
| 3 | Preprocesado | los 1,200 casos de entrenamiento (6,000 decisiones tipadas) se convierten en elementos tokenizados con objetivos suaves, escritos a disco para ambos rangos de DDP |
| 4 | Entrenamiento | train_ddp.py bajo torchrun --nproc_per_node=2, cuatro épocas |
| 5 | Calibración | una temperatura por tipo, ajustada sobre una porción reservada antes del entrenamiento (dentro del script de entrenamiento, tras la última época) |
| 6 | Evaluación | la partición oficial test respondida por el checkpoint ajustado — 400 casos, 2,000 decisiones — con latencia por caso |
| 7 | Métricas | precisión, precisión suave, Brier, ECE, MAE de score, within-one-level, KL/TV y percentiles de latencia; una tabla comparativa directa contra Jev y el techo del profesor |
| 8 | Publicación | (opcional) una tarjeta de modelo construida con los propios números de la ejecución, carpeta subida al Hub |
| 9 | Informe | benchmark_report.json con la tabla de métricas y la precisión por flujo de trabajo |
Ajustes de Kaggle: Accelerator GPU T4 x2, Internet On. Las salidas van a
/kaggle/working/laya_finetuned_typed_decisions.
La receta de entrenamiento
RLCD entrena sobre las distribuciones doradas del benchmark, no sobre etiquetas duras: cada elemento lleva la probabilidad que el profesor asignó a cada opción, y ambas mitades de la pérdida leen ese objetivo —
- un término de gradiente de política sobre proyecciones de logits ruidosas muestreadas (estilo GRPO: cuatro muestras por elemento, ruido de exploración atenuado 0.4 → 0.1), recompensado por reglas de puntuación propias (esférica 0.75, ranked probability 1.0);
- un término de entropía cruzada suave a peso completo contra la misma distribución.
Los ajustes que el notebook fija para una tarjeta de 16 GB:
| épocas | 4 |
| lote efectivo | 64 secuencias (8 por micro-lote, 2 GPUs, 4 pasos de acumulación) |
| tasas de aprendizaje | codificador 2.5e-5, cabeza 1e-4 — AdamW, planificación coseno |
| memoria | autocast fp16, gradient checkpointing en el codificador y la cabeza, recorte de norma de gradiente 1.0 |
| presupuesto de secuencia | max_len 1024, head_max_len 256, max_tokens_per_batch 4096 |
El tiempo de ejecución en 2xT4 es de minutos para la demo y de horas para datos reales: unos 4–6 minutos para las 6,000 decisiones de la demo, y unas 4–5 horas para cuatro épocas sobre ~30k preguntas.
Para apuntarlo a tus datos, reemplaza las dos llamadas a load_dataset y conserva el esquema de fila:
cada caso lleva state, questions y gold (las probabilidades del profesor por pregunta), y el
preprocesador los convierte en elementos. Los tipos de pregunta son choice, score y noul; cualquier
cosa que puedas expresar con ellos sobre un estado es válida.
La calibración es parte de la ejecución
Este es el paso que más probablemente se omite al copiar el bucle, y es fundamental en el momento en que alguien aplica gating sobre la confianza.
El notebook toma una porción de calibración de los datos de entrenamiento antes de repartirla entre los rangos (hasta 400 elementos, o un 10%, con una semilla fija, idéntica en cada rango). Ajustar las temperaturas sobre elementos con los que la ejecución ya se ha entrenado mide el ajuste en lugar de la calibración — el modelo está casi seguro y casi en lo correcto con ellos, así que el optimizador no tiene nada que suavizar y devuelve una escala degenerada.
Tras la última época, el rango 0 ajusta una temperatura por tipo de pregunta (choice, score,
noul) por LBFGS sobre el logaritmo de la temperatura, acotada a [0.1, 10] (1.0 para una porción de
menos de diez elementos, 1.2 si el ajuste lanza una excepción). Los valores van a rl_agent_config.json
como temperature, y el notebook elimina cualquier temperature_by_options heredado en la misma
escritura: esos valores antiguos por cubos tienen prioridad en la inferencia y enmascararían silenciosamente
el nuevo ajuste.
El escalado por temperatura deja el argmax — y la precisión — sin cambios; lo que se mueve es la confianza. Los checkpoints tal como se distribuyen son demasiado confiados, así que ajusta antes de confiar en cualquier umbral, y evalúa el resultado con datos reservados antes de afirmar una mejora. La regresión de persistencia de la configuración se ejecuta sin descargas ni entrenamiento:
python tests/test_calibration_persistence.py
Evaluar antes de confiar en ello
La evaluación es una pasada completa sobre la partición oficial de test: 400 casos, 2,000 decisiones entre
Agent Trace Observability, Customer Service, Invoice Processing y Security Incidents. Calcula precisión,
precisión suave, Brier, ECE (mediante laya.common.ece_score), MAE de score, within-one-level y
percentiles de latencia, y luego construye una tabla comparativa directa cuyas filas de referencia son fijas:
| modelo | tipo | precisión | ECE |
|---|---|---|---|
| TypeSafe Jev 1.13.0 | general | 0.727 | 0.144 |
| ModernBERT-base (149M) | especialista | 0.646 | 0.179 |
| Teacher Self-Agreement | techo | 0.735 | — |
| Laya (checkpoint publicado) | ajustado | 0.766 | — |
La fila de Laya de tu propia ejecución se calcula de la misma manera — el notebook reconstruye la tabla a
partir de los propios números de la ejecución. Dos hábitos que vale la pena copiar: mantén las porciones
que te importan (un idioma, un flujo de trabajo) dentro de los datos reservados, e informa la calibración
junto a la precisión, porque la señal de entrenamiento es una distribución, no solo una etiqueta. Cuando
tengas números, un mensaje en las Discussions del
repositorio es el sitio para compartirlos; los benchmarks y los límites conocidos viven en BENCHMARKS.md
en la raíz del repositorio.
Publicar en el Hub
La celda de publicación es la última milla del bucle, y es deliberadamente aburrida:
- Pon un
HF_TOKENde escritura en Kaggle (Add-ons → Secrets). La celda lanza una excepción con las instrucciones exactas si falta. - Define el repositorio de destino — la celda distribuida usa por defecto un nombre en el propio espacio de nombres del proyecto, así que cámbialo antes de ejecutarla.
- Ejecútala. Escribe una tarjeta de modelo cuyos números provienen de la tabla de comparación de esta
ejecución, y luego sube
model.safetensors,encoder/,tokenizer/,rl_agent_config.json, la tarjeta y el informe del benchmark.
El resultado se carga como cualquier otro checkpoint — no hay ninguna API específica del ajuste fino:
import laya
agent = laya.load("your-org/your-checkpoint") # the repo you just pushed
result = agent.predict(state, questions)
Un checkpoint_latest/ móvil se sobrescribe tras cada época, así que un timeout o un OOM de Kaggle cuesta
una época en lugar de la ejecución.
Qué vigilar
- El bucle vale tanto como los objetivos. RLCD imita la distribución de un profesor sobre tus preguntas; recoge las confianzas del profesor antes (o junto con) el entrenamiento, y trata su calidad como el techo.
- La porción de calibración es pequeña a propósito. Hasta 400 elementos o un 10% — suficiente para tres escalares por tipo, no para validar. Reserva tus propios datos de evaluación.
- Tus etiquetas deben encajar en las tres primitivas. Si tu decisión no es una elección, una escala o una probabilidad de sí/no, dale forma de una primero. Dos aristas afiladas ya están documentadas: los recuentos altos de opciones degradan la selección por confianza (#394), y la negación en opción forzada puede seguir la pregunta en lugar del estado (#377).
- Distribuye la configuración, no solo los pesos. El
temperature_by_optionseliminado es la parte que desajusta silenciosamente una calibración si sobrevive en una configuración copiada.