Phase 10 - Lesson 13
Construcción de un Pipeline Completo de LLM
Todo lo de las Lecciones 01 a 12 es una etapa de un pipeline. Esta lección es el andamiaje que convierte esas etapas en una sola ejecución de extremo a extremo: tokenizar, preentrenar, escalar, SFT, alinear, evaluar, cuantizar, servir. No entrenarás un modelo de 70B en una laptop. Producirás la capa de orquestación, el manifiesto, la puerta de evaluación y el plan de rollback que un equipo de frontera en 2026 utiliza para decidir qué se implementa. Este es el proyecto final.
Tipo: Build Lenguajes: Python (stdlib) Prerrequisitos: Todas las lecciones de la Fase 10 (01-12) Tiempo: ~120 minutos
Objetivos de Aprendizaje
- Componer las once lecciones previas (tokenizador, datos, preentrenamiento, escalado, SFT, RLHF, DPO, CAI, evaluación, cuantización, inferencia) en una sola especificación de pipeline reproducible
- Definir el contrato de artefacto entre etapas: qué consume cada etapa, qué produce y cómo la siguiente etapa verifica la entrada
- Construir un orquestador que rastree experimentos, genere hashes de artefactos y condicione las decisiones de envío en umbrales de evaluación
- Diseñar el plan de rollback: qué artefactos son baratos de volver a ejecutar, cuáles son costosos y cuánto cuesta un checkpoint corrompido
El Problema
Las lecciones anteriores funcionan individualmente. Tokenizador entrenado. Tiny GPT preentrenado. Conjunto de datos SFT ensamblado. Modelo de recompensa entrenado. Ejecución de DPO realizada. Evaluaciones medidas. Pesos cuantizados exportados. Servidor de inferencia iniciado. Cada uno es un notebook. Cada uno tiene sus propias convenciones, sus propios caminos de salida, su propia semilla.
Una ejecución de entrenamiento de frontera no es un notebook. Llama 3 405B tomó 30 millones de horas de H100 a lo largo de aproximadamente 54 días. DeepSeek-V3 usó alrededor de 2.8 millones de horas de H800. Durante ese tiempo, un checkpoint corrompido, una contaminación de datos o una regresión de evaluación puede costarle a un equipo una semana de tiempo real y un mes de presupuesto de GPU. La forma en que los equipos sobreviven a esto es mediante la higiene del pipeline: cada etapa tiene una entrada determinista, una salida determinista, un manifiesto, un hash y una puerta.
Este es el proyecto final. No ejecutarás el pipeline de extremo a extremo en una laptop. Escribirás el orquestador que coordina las etapas, el manifiesto que describe la ejecución, el verificador que condiciona las decisiones de envío y el plan de replicación que permite a un tercero volver a ejecutar tu trabajo a partir de un solo archivo. El código es pequeño; la disciplina es grande.
El patrón escala de 100M a 1T de parámetros sin cambios. Los mismos cuatro componentes —manifiesto, orquestador, puerta de evaluación, almacenamiento de artefactos— ejecutan Llama 3 y también tu GPT de pasatiempo. La diferencia radica en el tamaño de los números dentro de la configuración de cada etapa, no en la forma del pipeline.
El Concepto
Las Doze Etapas
Cada lección de la Fase 10 es una etapa. Aquí está el grafo de dependencias completo.
graph TD
S1["01 Tokenizer vocab"] --> S2["02 Trained tokenizer"]
S2 --> S3["03 Sharded dataset"]
S3 --> S4["04 Base model checkpoint"]
S4 --> S5["05 Scaled training recipe"]
S5 --> S6["06 SFT checkpoint"]
S6 --> S7["07 Reward model + PPO policy"]
S6 --> S8["08 DPO policy"]
S7 --> S9["09 CAI / GRPO refined policy"]
S8 --> S9
S9 --> S10["10 Eval report"]
S9 --> S11["11 Quantized weights"]
S11 --> S12["12 Inference server"]
S10 --> GATE["Ship gate"]
S12 --> GATE
style S1 fill:#1a1a2e,stroke:#e94560,color:#fff
style S4 fill:#1a1a2e,stroke:#0f3460,color:#fff
style S9 fill:#1a1a2e,stroke:#0f3460,color:#fff
style GATE fill:#1a1a2e,stroke:#51cf66,color:#fff
Las etapas 07 y 08 pueden ejecutarse en paralelo. Todo lo demás es una dependencia estricta. Un cambio en la etapa 02 (tokenizador) invalida todos los artefactos a continuación. Un cambio en la etapa 10 (evaluación) invalida únicamente la decisión de envío.
El Manifiesto
Un manifiesto es un solo archivo que describe una ejecución de manera lo suficientemente completa como para replicarla. Nada de lo que produce el pipeline debe depender de un estado que no esté en el manifiesto. Los campos son simples y obligatorios.
pipeline_version: 1.2.3
seed: 42
git_commit: a1b2c3d4
stages:
01_tokenizer:
recipe: bpe_32k
input_hash: sha256:...
output_hash: sha256:...
wall_clock_sec: 3600
cost_usd: 12
El hash de salida de la etapa N es el hash de entrada de la etapa N+1. Cualquier desviación y el pipeline se detiene. Así es como se detecta la corrupción de datos a tiempo. También es la forma en que un compañero de equipo en otro continente verifica que su réplica produjo el mismo artefacto que el tuyo.
En la práctica, los equipos utilizan un esquema YAML pequeño más un verificador de manifiesto que compara con la ejecución exitosa anterior. Cualquier variación fuera de los campos esperados (costo, tiempo real) es una señal de alerta.
Tipado de Artefactos
La salida de cada etapa es un artefacto tipado. No un directorio genérico, no un archivo pickle, sino un tipo nombrado con un esquema conocido.
| Etapa | Tipo de Artefacto | Campos Clave |
|---|---|---|
| 01-02 | Tokenizador | vocab.json, merges.txt, config.json, hash |
| 03 | Dataset | shards[], conteo de filas, conteo de tokens, estadísticas de deduplicación |
| 04-05 | Checkpoint | weights.safetensors, config.json, estado del optimizador, conteo de pasos |
| 06 | Modelo SFT | checkpoint + receta de SFT + mezcla de datos |
| 07 | Modelo de Recompensa | checkpoint del RM + hash de datos de preferencia |
| 08-09 | Política | checkpoint + hash de referencia + beta + presupuesto de KL consumido |
| 10 | Reporte de Evaluación | puntajes de benchmark + diferencias de regresión + hash de datos de evaluación |
| 11 | Modelo Cuantizado | pesos cuantizados + datos de calibración + delta de precisión vs FP16 |
| 12 | Especificación del Servidor | endpoint + hash del modelo + configuración + hooks de observabilidad |
El tipado evita el modo de falla más común: usar la salida de la etapa 08 como entrada de la etapa 06, enviando un modelo entrenado con DPO a través del flujo de SFT. Los artefactos tipados y las firmas de etapa tipadas convierten estos errores en fallas en tiempo de compilación, no en fallas al quinto día.
La Puerta de Evaluación
El envío no es simplemente "entrenamiento finalizado". El envío es "entrenamiento finalizado y aprobación de la puerta de evaluación". La puerta se define antes de que comience la ejecución.
gates:
mmlu: >= baseline + 0.5 # no regression
humaneval: >= baseline + 1.0
truthfulqa: >= baseline # no drop
safety_refusal_rate: <= 0.05
kl_from_reference: <= 25.0
cost_total_usd: <= 50000
Cada puerta es un umbral numérico. Sin puertas de "se ve bien". Sin aprobaciones subjetivas. Si todas las puertas pasan, el artefacto se marca como listo para enviar. Si alguna puerta falla, la ejecución se retiene a la espera de una anulación (override) explícita por parte de un revisor designado, lo cual se registra en el propio manifiesto.
Dos puertas previenen la mayoría de los desastres. Una puerta de regresión (el nuevo modelo debe ser al menos tan bueno como el anterior en los benchmarks principales) detecta errores de entrenamiento. Una puerta de presupuesto de KL (la política alineada no debe haberse desviado más de X de su referencia) detecta el exceso de alineación (alignment overcooking). Todo pipeline de producción cuenta con ambas.
El Orquestador
Una pequeña sección de código que lee el manifiesto, despacha las etapas, rastrea los artefactos y se detiene ante cualquier violación de contrato. Esto no es Airflow. Esto no es Kubeflow. Para mantener la higiene del pipeline, querrás algo simple y predecible que hayas escrito tú mismo.
El trabajo del orquestador es limitado:
- Resolver el DAG a partir del manifiesto.
- Para cada etapa, verificar si la salida esperada ya existe con el hash correcto (omitir si es así).
- Ejecutar la etapa, capturar stdout/stderr, medir el tiempo real y el costo.
- Verificar el hash de salida contra el hash de entrada esperado de la etapa siguiente.
- En caso de falla, escribir un manifiesto parcial con la etapa exacta que falló y salir con un código de estado distinto de cero.
Eso son unas 200 líneas de Python. Se parecerá al archivo code/main.py de esta lección. Bajo el capó, el pipeline real utiliza torchrun or ray para ejecutar etapas individuales en clústeres, pero el orquestador en sí se ejecuta en una sola máquina.
Rastreo de Experimentos y Almacenamiento de Artefactos
Dos sistemas externos anclan el pipeline.
Rastreador de experimentos (wandb, neptune, mlflow). Registra curvas de pérdida, métricas de evaluación y telemetría del sistema por etapa. El rastreador es adonde acudes cuando necesitas comparar la ejecución A con la ejecución B tres semanas después. Los equipos casi siempre utilizan un rastreador alojado para esto; escribir el tuyo propio consume tiempo que debería dedicarse al entrenamiento.
Almacenamiento de artefactos (S3, R2, GCS). Almacenamiento de objetos inmutable para checkpoints, conjuntos de datos, tokenizadores y reportes de evaluación. Los artefactos se direccionan por hash, no por nombre de archivo. Un nombre de archivo como latest.pt es un peligro; ckpt-7b-step-20000-sha256:abc123.safetensors es un contrato.
El orquestador escribe en ambos. El rastreador es para que los humanos miren gráficos. El almacenamiento de artefactos es para que la siguiente etapa consulte las entradas.
Estimación de Costos
Una ejecución de frontera tiene un valor en dólares asociado. La disciplina presupuestaria ocurre en dos lugares.
Estimación previa a la ejecución. A partir del manifiesto, se calculan los FLOPs esperados (para preentrenamiento: 6 x parámetros x tokens), las horas de GPU esperadas (FLOPs / rendimiento pico / utilización) y el costo en dólares a la tarifa de alquiler actual. Si la estimación supera la puerta del presupuesto, el pipeline se niega a iniciar.
Seguimiento durante la ejecución. El tiempo real y el costo de cada etapa se registran en el manifiesto. Después de cada etapa, se verifica el presupuesto restante. Si una etapa se excedió, la puerta de la siguiente etapa se evalúa con el nuevo presupuesto restante. No te enteras de que te quedaste sin dinero recién cuando llama el inversionista.
El costo reportado de Llama 3 fue de $61 millones de dólares. DeepSeek-V3 reportó $5.6 millones de dólares para la ejecución principal del preentrenamiento. La proporción se debe principalmente a la eficiencia del hardware más la mezcla de expertos (mixture-of-experts), pero el costo específico es visible porque ambos equipos lo rastrearon por etapa, no por ejecución.
Reproducibilidad vs Determinismo
No son lo mismo. Reproducible significa que el mismo manifiesto más el mismo código más la misma infraestructura producen un checkpoint con métricas equivalentes en las etapas siguientes. Determinista significa un resultado idéntico bit a bit.
El entrenamiento moderno de LLM es reproducible pero no determinista. El reduce-order del entrenamiento distribuido, el no determinismo de los kernels de GPU (cuBLAS, flash-attn) y el redondeo de precisión mixta se combinan para producir floats que difieren a nivel de 1e-5 entre ejecuciones. Esto es aceptable para las métricas finales, que no cambian. Sin embargo, es fatal si estás intentando depurar con diferencias a nivel de bit. La solución consiste en registrar el hash de entrada, el hash de salida y las métricas principales de cada etapa: si coinciden, la ejecución se considera "reproducida", incluso si los pesos no son idénticos bit a bit.
graph LR
M["Manifiesto v1.2.3"] --> O["Orchestrator"]
O --> S["Stages 01 → 12"]
S --> AS["Artifact Store\n(content-addressed)"]
S --> ET["Experiment Tracker\n(metrics, curves)"]
AS --> GATE["Eval Gate"]
ET --> GATE
GATE -->|pass| SHIP["Ship"]
GATE -->|fail| ROLL["Rollback plan"]
style M fill:#1a1a2e,stroke:#0f3460,color:#fff
style GATE fill:#1a1a2e,stroke:#e94560,color:#fff
style SHIP fill:#1a1a2e,stroke:#51cf66,color:#fff
style ROLL fill:#1a1a2e,stroke:#c0392b,color:#fff
El Plan de Rollback
Antes de comenzar la ejecución, define qué sucede en caso de falla de cada etapa. Tres categorías.
- Barato de volver a ejecutar (horas): tokenizador, evaluación, cuantización, servidor de inferencia. Simplemente vuelve a ejecutar.
- Medio (dias): SFT, DPO, CAI. Mantén el modelo base; vuelve a ejecutar solo las etapas de alineación.
- Costoso (semanas y millones de dólares): preentrenamiento. El plan de rollback aquí no es "volver a ejecutar". Consiste en "utilizar el último checkpoint bueno y volver a ejecutar las etapas posteriores más baratas con datos revisados".
Debido a que las dependencias de etapa están tipadas y hasheadas, el orquestador puede calcular el conjunto de rollback automáticamente: invalidar la etapa fallida más cada descendente. Una falla en la etapa 06 (SFT) invalida 06, 07, 08, 09, 10, 11, 12. Una falla en la etapa 11 (cuantización) invalida solo la 11 y la 12. Definir esto de antemano evita improvisar mientras el equipo está exhausto a las 4 de la mañana.
Recetas de Producción Observadas en 2026
La mayoría de los equipos de frontera convergieron en el mismo esqueleto.
- Tokenizador: BPE de 128k con byte fallback. Entrenado en una sección pequeña y equilibrada de carácter multilingüe.
- Preentrenamiento: 10-20T de tokens, principalmente web más código más sintéticos. Optimizador Muon o AdamW. FSDP2 o DeepSpeed ZeRO-3. Checkpointing de gradiente. Pesos en BF16, maestro en FP32.
- SFT: 500k-2M pares de instrucciones, mezcla de humanos y sintéticos, con una rigurosa deduplicación contra el conjunto de evaluación.
- Alineación: DPO o CAI + GRPO. RLHF solo donde la señal de preferencia sea demasiado multidimensional para DPO.
- Evaluación: MMLU-Pro, MATH, HumanEval+, GPQA, SWE-Bench Verified, LiveBench, además de un conjunto privado retenido que el público nunca ve.
- Cuantización: GPTQ o AWQ de 4 bits para el servicio, 8 bits para las evaluaciones de seguridad donde los deltas de precisión importan.
- Servicio: vLLM, TensorRT-LLM o interno. Loteado continuo (continuous batching). Decodificación especulativa. Desalojo (eviction) de caché KV.
Los números cambian cada seis meses. El esqueleto no.
Constrúyelo
El código de la lección consiste en un orquestador y un verificador de manifiesto, no en doce scripts de entrenamiento. Cada etapa se simula con un marcador de posición (placeholder) que produce un artefacto de salida con la forma y el hash correctos. Ejecutar el orquestador de extremo a extremo demuestra que la infraestructura del pipeline funciona antes de gastar presupuesto de GPU en las etapas reales.
Consulta code/main.py para ver la implementación completa. Las piezas clave:
- Dataclass
Manifest: versión del pipeline, semilla (seed), commit de git, etapas, puertas. - Dataclass
Stage: nombre, tipo, entradas (hashes), salida (hash), tiempo real, costo. Orchestrator.run(): resuelve el DAG, despacha las etapas, verifica los hashes, actualiza el manifiesto.EvalGate.check(): lee los umbrales, los compara con el reporte de evaluación más reciente y devuelve aprobado/fallido (pass/fail).ArtifactStore(stub en memoria): coloca/obtiene por hash, simulando S3.CostTracker: seguimiento por etapa y acumulado, deteniéndose cuando se supera el límite.
El pipeline en main.py ejecuta doce etapas simuladas, produce un manifiesto y ejercita una puerta de evaluación fallida para mostrar cómo se ve una ejecución retenida. Reemplaza cada placeholder con el script de entrenamiento real de la lección correspondiente y tendrás el esqueleto que utiliza un pipeline de frontera real.
Cómo Usarlo
El flujo de trabajo canónico tiene tres comandos.
python code/main.py plan # validate manifest, compute cost estimate, print DAG
python code/main.py run # execute stages, writing to manifest.out.yaml
python code/main.py gate # read manifest.out.yaml, apply eval gates, ship-or-hold
Siempre ejecuta plan primero. La mayoría de los errores del pipeline se muestran en el momento del plan: umbrales de puerta faltantes, hashes obsoletos, excesos de presupuesto. Ejecutar plan es gratis. Ejecutar run es costoso. Ahorra dinero detectando errores en la fase económica.
El resultado de gate es SHIP o HOLD: <reason>. Una ejecución retenida (held run) no es una falla; es un punto de decisión. Un revisor designado puede anularla (y la anulación se registra) o aprobar el rollback.
Envíalo
Esta lección produce outputs/skill-llm-pipeline-reviewer.md. Proporciónale un manifiesto de pipeline propuesto y verificará todos los contratos: tipado de etapas, cadena de hashes, puertas, plan de rollback, estimación de costos. Se niega a aprobar un manifiesto al que le falte una puerta de evaluación, un presupuesto de KL sin límites o una ejecución que mezcle datos de evaluación y de entrenamiento.
Ejercicios
- Extiende el orquestador para admitir la ejecución paralela de las etapas 07 y 08. Utiliza el módulo
concurrent.futuresde la biblioteca estándar. Confirma que el manifiesto final registre las salidas de ambas etapas y que el hash de entrada de la etapa 09 sea una combinación determinística de ambas. - Agrega una puerta de "verificación de contaminación". Dado el hash del conjunto de datos de evaluación y los fragmentos del conjunto de datos de entrenamiento, calcula la superposición (coincidencia de cadena exacta o coincidencia de 13-grams). La puerta falla si la superposición supera el 0.1%. Proporciónale un conjunto de entrenamiento contaminado y confirma que la puerta retiene la ejecución.
- Implementa un estimador de costos desde cero. Para la etapa 04 (preentrenamiento), estima los FLOPs como 6 x parámetros x tokens, asume un 40% de MFU (utilización de FLOPs del modelo) en H100 a 989 TFLOPs BF16, a