Skip to content

English · Español

06 — Build / deploy / rollback para el tutor de gramática §A13; la matriz de CI

🇪🇸 Una pipeline MLOps no es una pieza de infraestructura mágica: es el procedimiento que convierte un commit en un binario corriendo, con un camino de vuelta. Esta página describe ese procedimiento para el tutor §A13 concretamente, incluyendo qué corre CI en cada PR. Sin esto, Phase 40 no tiene de qué hacer postmortem.


El flujo de deploy en cinco pasos

Para el tutor de gramática §A13 en concreto (una app FastAPI pequeña + un modelo de 500k parámetros + la tabla de verificación de ground truth):

  1. Build. Snapshot del repo en un SHA de commit. Lint + chequeo de tipos (just check). Corre el test suite completo (just test). Produce dos artefactos:
  2. model.safetensors — los pesos (inmutables, content-addressed).
  3. tutor-<sha>.tar — la imagen OCI con FastAPI + verificador + modelo symlinkeado dentro.
  4. Stage. Empuja imagen + modelo al registry (artifacts/ para el currículo; un registry OCI real en producción). Etiqueta con el SHA del commit y la fecha.
  5. Gate pre-deploy. Corre el eval suite (tests/eval/ + data/exams/phase-39-capstone.yaml) contra el artefacto staged. Si el score de evaluación cae > 2% vs el release anterior → bloquea.
  6. Deploy. Switch atómico — o bien blue/green (dos réplicas, traffic-flip) o rolling update (reemplazo gradual). El tutor de gramática es lo suficientemente pequeño como para que blue/green sea el default; el coste de correr dos copias es despreciable.
  7. Camino de rollback. Siempre presente. El tag de la imagen anterior se queda en el registry; un comando (just rollback) hace flip del tráfico de vuelta. Sin procedimiento especial para "el caso de rollback" — es el mismo switch atómico en reversa.

Lo no negociable: el paso 5 debe existir antes de que ocurra el paso 4. Un deploy sin camino de rollback está roto por diseño.

Paso a paso para el tutor §A13

Paso 1 — Build (CI en PR)

# .github/workflows/build.yml (sketch — actual file may differ)
on: pull_request
jobs:
  build:
    steps:
      - lint:    just lint
      - type:    just typecheck
      - test:    just test
      - eval:    just eval --gate-threshold 0.95
      - build:   just build-image
      - push:    just push artifacts/tutor-${SHA}.tar

El orden importa: chequeos baratos (lint, type) corren antes que los caros (eval). La matriz de CI en §"Matriz de CI por PR" abajo detalla qué corre.

Paso 2 — Stage

El artefacto de build se empuja a un registry. Para el currículo, esto es artifacts/ en el repo (per docs/phase-38-mlops/lab/00-registry-roundtrip.md). Para producción, un registry OCI content-addressed.

El registry guarda como mínimo: - la imagen (digest sha256 como clave primaria); - los pesos del modelo (digest sha256 también; symlinkeados desde la imagen); - un manifest mapeando SHA-de-commit → digest-de-imagen → digest-de-modelo; - las puntuaciones de evaluación en tiempo de build.

Paso 3 — Gate pre-deploy (el eval suite)

El gate pre-deploy es la práctica MLOps más importante que enseñamos. Es el sustituto determinístico de "vigilaremos los dashboards y revertiremos si algo va mal" — captura regresiones antes de que los usuarios las vean.

Para el tutor §A13, la evaluación corre: - data/exams/phase-39-capstone.yaml — el examen capstone (5 ítems actuales, más el YAML extra). - tests/eval/regression_corpus.jsonl — un set de regresión congelado de ~300 frases construido a lo largo de las fases. - tests/eval/prompt_injection_set.jsonl — los payloads de inyección de la Fase 37 con rechazos/verificaciones esperados.

Si el score agregado de evaluación cae > 2% relativo al release anterior → la PR es bloqueada. El umbral del 2% está calibrado; modelos más pequeños tienen evaluación más ruidosa, más grandes tienen menos; ajusta por proyecto.

Paso 4 — Deploy (blue/green para el tutor §A13)

Blue/green para un servicio sin estado: - tutor-blue corriendo versión N, tomando 100% del tráfico. - tutor-green levantado corriendo versión N+1, sano, tomando 0% del tráfico. - Health check + smoke test sobre green. - Flip atómico de tráfico: el load balancer apunta a green, blue se queda caliente. - Espera el bake period (10 minutos para el tutor — suficiente para una sesión de quiz en el portal). - Si no hay alertas en el bake → blue se convierte en la nueva reserva. Si no → flip de vuelta.

Para modelos con estado (índices RAG, adaptadores de fine-tune): el data plane necesita manejar el version skew durante el flip de tráfico. El tutor no tiene tal estado, así que blue/green es limpio.

Paso 5 — Rollback

just rollback hace flip del tráfico de vuelta a la versión anterior. La imagen + pesos anteriores siguen en el registry, etiquetados por SHA. Sin "build de rollback" especial: el rollback es solo deploy-pero-apuntando-a-un-tag-más-viejo.

El coste de que el rollback esté disponible es una réplica extra corriendo (o caliente en el registry). El coste de que el rollback no esté disponible está documentado en break/00-break-no-rollback.md.

Matriz de CI por PR

Qué corre en cada PR. La matriz es intencionalmente pequeña — CI hinchada es su propio anti-patrón.

Etapa Corre en ¿Bloquea merge? Coste
just lint cada PR ~5 s
just typecheck (mypy --strict on src/) cada PR ~15 s
just test cada PR ~60 s
just security (bandit + pip-audit) cada PR (también nightly) ~20 s
just eval --gate-threshold 0.95 cada PR tocando src/minitutor/ o src/minimoe/ o models/ ~90 s
just docs PRs tocando docs/ no (avisa) ~10 s
just bench --quick nightly + opt-in no (publica) ~5 min
Eval suite completo (lento) nightly + en tag de release sí (en release) ~10 min
Chequeo de drift de baseline pre-entrenado semanal no (alerta) ~5 min

El split entre bloqueante en PR (barato, determinístico) y monitoring nightly (lento, indicativo) es intencional. El bloqueante en PR debería ser ≤ 3 min total para que un cambio pequeño se sienta rápido; runs más largos se esconden fuera del path crítico.

Los tests específicos de §A13 en cada PR

Cada PR que toca el tutor debe correr:

  1. Integridad de la tabla de conjugación — el hash de la tabla de ground truth (data/verbs.yaml) coincide con lo que verify.py espera.
  2. Round-trip del tokenizer — encode → decode → equal sobre un corpus fijo Spanish/English.
  3. Smoke end-to-end del tutor — POST de una frase fija a un servidor local, obtener la forma JSON esperada.
  4. Replay del set de inyecciones — los payloads de la Fase 37, expect que el verificador rechace los incorrectos.
  5. Presupuesto de latencia — el p50 de un set fijo de 50-requests debe mantenerse dentro de ±20% del p50 del release anterior.

Estos son el set mínimo. Añadir más está bien; remover cualquiera es una puerta de un solo sentido — una vez que dejas de correr un chequeo, dejas de saber si habría capturado la regresión.

Qué falla cuando el rollback falta

Ver break/00-break-no-rollback.md para el ejercicio trabajado: un release malo alcanza a los usuarios, y el tiempo de recuperación está dominado por el camino de rebuild-desde-cero porque ninguna imagen previa fue preservada.

La versión corta: el coste de que el rollback no esté disponible se mide en minutos de servicio roto cara-al-usuario, no en segundos de CI. Un outage de 5 minutos en el portal durante una clase es peor que 10 minutos de CI por release.

Lo que este capítulo NO cubre

  • Deployments canary (traslado gradual de tráfico, p. ej. 1% → 5% → 25% → 100%). Real, usado a gran escala; para el tutor §A13, blue/green es más simple.
  • Feature flags para A/B in-app (distinto de blue/green; envía ambas versiones y togglea por usuario). El lab 01 de la Fase 38 cubre shadow-A/B a un nivel más ligero.
  • Deployment multi-región — fuera del scope §A13.
  • Versionado de datos para fine-tunes — historia DVC + MLflow; cross-ref docs/phase-38-mlops/lab/00-registry-roundtrip.md.

Referencias

  • Forsgren, Humble, Kim, "Accelerate: The Science of Lean Software and DevOps" (2018). Las cuatro métricas clave DORA (frecuencia de deploy, lead time, MTTR, change failure rate) operacionalizan el flujo de deploy de arriba.
  • Google SRE Book, cap. "Release Engineering". Disciplina de blue/green y rollback.
  • Sculley et al., "Hidden Technical Debt in Machine Learning Systems" (NeurIPS 2015). Por qué MLOps difiere de ops; el aviso del "small piece of glue".

Siguiente: ../break/00-break-no-rollback.md y el lab 04-ci-deploy-gate.md.