| Después de un merge a main, el manifest del gateway apunta al tag del commit nuevo y los pods nuevos quedan en ImagePullBackOff. kubectl describe pod muestra «Failed to pull image "…/classifier-gateway:…": … failed to resolve reference … not found». Los pods viejos siguen sirviendo. | 8 · CI/CD | aws ecr describe-images --repository-name classifier-gateway --image-ids imageTag=commit; si no existe, revisa el job de CI de ese commit (build y push). |
| Tras un PR que «limpió» el manifest de Triton, el pod nuevo queda en Pending: «0/5 nodes are available: 2 node(s) had untolerated taint {nvidia.com/gpu: present}, 3 node(s) didn't match Pod's node affinity/selector». El autoscaler de nodos no agrega ninguno y los pods viejos siguen sirviendo. | 9 · Kubernetes | kubectl describe pod pod_triton -n classifier (evento FailedScheduling) y el diff del PR en tolerations y nodeSelector, contra kubectl describe node nodo_gpu (bloques Taints y Labels). |
| Negocio agregó una categoría nueva al árbol hace dos semanas y el ticket de reentrenamiento se abrió ese mismo día. El modelo nunca la sugiere (siempre se elige a mano en el selector) y una categoría vecina empeora en las métricas sin que nadie haya desplegado nada. | 1 · Datos | Cuenta los ejemplos revisados de la categoría nueva en la cola de etiquetado y en el manifest del último snapshot (meta: ≈ 200–500 antes de reentrenar). |
| La imagen del gateway que construiste en tu Mac con Apple Silicon corre bien con docker run. En EKS, el pod queda en CrashLoopBackOff y kubectl logs --previous solo dice «exec format error». | 7 · Empaquetado | docker image inspect --format '{{.Os}}/{{.Architecture}}' imagen en tu Mac (o docker buildx imagetools inspect --format '{{json .Image}}' imagen en el registro): si dice arm64, reconstruye con --platform linux/amd64. |
| Sin ningún deploy en tres semanas, el job diario reporta PSI > 0.2 sostenido 3 días en las categorías predichas (suben mochilas y útiles escolares) y la aceptación cae más de 3 pp semana contra semana. Cero errores, p99 normal. | 12 · Monitoreo | Confirma que no coincide con ningún deploy (modelo, gateway, app), mira en el job qué categorías se movieron y etiqueta una muestra reciente para medir el impacto antes de reentrenar. |
| Un día después de un deploy del gateway (el modelo es el mismo) salta ClassifierLowConfidenceSpike: la fracción de predicciones con top-1 < 0.3 supera el doble de su promedio de 7 días, en móvil y en web por igual. Cero 5xx, latencia normal. | 6 · Serving | Corre el test de tensores de referencia (20 imágenes) contra el commit desplegado y revisa el diff de gateway/app/preprocess.py; si los tensores cambiaron, rollback del gateway. |
| Desde la última versión de la app, el histograma classifier_image_bytes se corrió de ≈ 200 KB a varios MB, classifier_preprocess_seconds subió y el HPA agregó pods al gateway. El modelo y el gateway no cambiaron. | 11 · Request | En los logs del gateway, image_bytes por source (mobile vs web) antes y después del release de la app; después confirma con el equipo de la app si cambió el downscale. |
| Tras un refactor de train.py, el fine-tune mensual corre sus ≈ 3–4 h sin errores, pero el gate lo bloquea: top-1 muy por debajo del champion. En MLflow, la loss de entrenamiento casi no bajó en ninguna época, y relanzarlo con el snapshot del mes pasado da lo mismo. | 3 · Entrenamiento | Corre el smoke test sobre el commit del refactor (sobreajustar un batch de 32 imágenes en CPU o una GPU chica) y compara en MLflow los params de esta corrida con los del mes anterior. |
| En el deploy de un modelo nuevo, los pods nuevos de Triton quedan en CrashLoopBackOff sin llegar a Ready. kubectl logs --previous: «The engine plan file is generated on an incompatible device… please rebuild» y Triton se cierra. Los pods viejos siguen sirviendo. | 5 · Export | kubectl logs pod_triton -n classifier --previous y, en los tags de la versión del registry, la GPU y la release de NGC con que se construyó el engine (deben ser T4 y 24.08, como triton/Dockerfile). |
| El canary estuvo 3 horas al 5 % fuera del pico, todo verde, y alguien lo pasó directo a 100 %. En el pico diurno siguiente, la tasa de 5xx del modelo nuevo se duplica. | 10 · Rollout | Cuenta los requests del canary por ventana con sum(increase(classifier_requests_total{model_version="version_canary"}[10m])) y verifica si alguna etapa cubrió el pico diurno. |
| Cada reentrenamiento mensual pasa el gate (no inferior al champion, margen −0.3 pp), pero al comparar el champion de hoy con el de hace un año sobre el mismo golden set, el top-1 bajó ≈ 2.4 pp. | 4 · Gate | Evalúa el challenger contra el champion de hace 3 meses (y el de hace 12) en el mismo golden set, con test pareado; las versiones anteriores siguen en el registry de MLflow. |
| Quieres reproducir el modelo de septiembre con ds-2026-09-01, pero el sha256 de su rows.parquet ya no coincide con el rows_sha256 de la tarjeta del snapshot, y el reentrenamiento da métricas que no se parecen a las registradas. | 2 · Versionado | aws s3api list-object-versions --bucket bucket --prefix datasets/ds-2026-09-01/: más de una versión de rows.parquet, o un LastModified posterior al created_at de la tarjeta, confirma la reescritura; después, aws s3api get-bucket-policy --bucket bucket para ver qué la permitió. |
| En el pico salta TritonQueueTimeHigh y KEDA pide una tercera réplica de Triton, pero el pod nuevo lleva 20 minutos en Pending y no aparece ningún nodo GPU nuevo. | 9 · Kubernetes | kubectl describe pod pod_triton -n classifier (eventos FailedScheduling) y el estado del autoscaler de nodos: kubectl -n kube-system get configmap cluster-autoscaler-status -o yaml, o kubectl get nodepools,nodeclaims con Karpenter. |
| Dos pods del gateway del mismo Deployment, ambos con la imagen classifier-gateway:latest, se comportan distinto: solo uno escribe un campo nuevo en su línea de log. kubectl rollout undo no devuelve la versión anterior. | 8 · CI/CD | kubectl get pods -n classifier -l app.kubernetes.io/name=gateway -o custom-columns=POD:.metadata.name,DIGEST:.status.containerStatuses[0].imageID: dos digests distintos confirman que el tag se movió. |
| Para acelerar el fine-tune subiste el batch: el paso falla a los pocos segundos y su log termina en «CUDA out of memory. Tried to allocate …». Alguien propone subir limits.memory del pod. | 3 · Entrenamiento | kubectl logs pod_finetune: ¿termina en «CUDA out of memory»? → VRAM. kubectl describe pod pod_finetune: ¿Reason OOMKilled y Exit Code 137? → RAM del pod. |
| Un martes a media mañana, sin deploys, suben el tiempo en cola de Triton y el p99; KEDA ya está en 4 réplicas. En el panel de tráfico por caller, source=internal se multiplicó y el resto sigue igual. | 11 · Request | sum by (source) (rate(classifier_requests_total[5m])) junto al tiempo en cola de Triton: si internal sube a la par de la cola, es el vecino; después, averigua qué equipo interno (moderación, búsqueda) lanzó un batch por la API. |
| En el reporte del pipeline, el top-1 sobre la validación del snapshot (casi toda con labels débiles de la categoría final de cada publicación) sube mes a mes; en el golden set el challenger apenas empata con el champion y la re-categorización por moderación no baja. | 1 · Datos | Parte la métrica por label_source (humano, moderador, vendedor_filtrado) y compárala con el golden set y con el holdout de ≈ 1 % sin sugerencias. |
| En el pipeline, parity_check.py --backend triton termina con «[parity] NO PASA: no promuevas este artefacto»: el acuerdo top-1 entre el engine FP16 y PyTorch FP32 quedó bajo 99.5 %. El gate offline del modelo había pasado. | 5 · Export | python model/parity_check.py --checkpoint checkpoint --onnx model/classifier.onnx --images muestra_eval --n 2000 (backend ort, en CPU) y compara con el resultado del backend triton. |
| El challenger le gana al champion en el golden set por mucho más que cualquier mes anterior. En shadow, su acuerdo con el champion y su distribución de predicciones son los de siempre, y en el A/B la aceptación no se mueve. | 2 · Versionado | Cruza los sha256 (y pHash) del golden set con el manifest de entrenamiento del snapshot y revisa el split por seller_id: debe haber cero coincidencias. |
| Tras un release que solo cambió gateway/app/main.py (gateway.yaml sigue igual, sin limits.cpu), el p99 sube a medida que crece la concurrencia aunque la CPU de los pods no está llena; hasta /healthz tarda. | 6 · Serving | git diff commit_anterior commit_nuevo -- gateway/app/main.py: busca un decode o resize llamado directo en la ruta async def, fuera de run_in_threadpool. |
| En cada rolling update del gateway, cada pod viejo se queda en Terminating los 45 s completos de terminationGracePeriodSeconds, aunque uvicorn tiene --timeout-graceful-shutdown 20. En local, docker stop gw tarda 10 s y docker ps -a muestra Exited (137). | 7 · Empaquetado | docker image inspect --format '{{json .Config.Cmd}}' imagen: si empieza con "/bin/sh","-c", pásalo a forma exec (lista JSON), como el CMD de gateway/Dockerfile. |
| La corrida mensual quedó en verde en el orquestador y nadie recibió aviso, pero no apareció ninguna versión challenger en MLflow. En el historial, evaluación y gate figuran OK; engine, imagen de Triton, paridad y registro, como omitidos. | 4 · Gate | Abre el log y la salida del paso de gate de esa corrida: si el veredicto es «no pasa» y el paso terminó con exit 0, ese es el hueco; después mira en el reporte qué criterio falló. |
| El análisis del canary revierte la release casi todas las madrugadas por el criterio «PSI de categorías contra el estable > 0.1»; de día nunca falla y en shadow el acuerdo con el champion era el de siempre. | 10 · Rollout | Cuenta las predicciones del canary en la hora de cada rollback: sum(increase(classifier_top1_score_count{model_version="version_canary"}[1h])); si son unos pocos miles, el criterio necesita un n mínimo y agrupar categorías. |
| En el Hot Sale, sin deploys recientes, salta ClassifierHighP99Latency y el tramo que crece es classifier_inference_seconds. Triton sigue en 2 réplicas, TritonQueueTimeHigh nunca se disparó y los paneles de Triton en Grafana están vacíos. | 12 · Monitoreo | kubectl describe scaledobject triton -n classifier (eventos KEDAScalerFailed) y, en Prometheus, busca nv_inference_queue_duration_us{model="classifier"}; si no hay serie, kubectl get servicemonitor -n classifier. |