MLOps: del notebook al pipeline de produccion
El modelo funciona en mi portatil
Esa frase deberia provocar la misma reaccion que “funciona en mi maquina” provoca en un ingeniero de software. Porque el problema es identico: un entorno controlado, datos limpios, un unico usuario, cero concurrencia. El notebook de Jupyter donde un data scientist logra un AUC de 0.94 es un artefacto de investigacion, no un sistema de produccion.
Y sin embargo, la mayoria de equipos de datos intentan poner en produccion exactamente eso. Un notebook convertido en script, ejecutado en un cron, sin versionado de datos, sin monitorizacion de drift, sin rollback posible. Funciona hasta que deja de funcionar, y cuando deja de funcionar nadie sabe por que.
Este whitepaper documenta lo que hemos aprendido desplegando modelos ML en produccion para clientes en logistica, finanzas y retail. No es una guia teorica de MLOps. Es un mapa de las trampas reales que hemos encontrado y las soluciones que han sobrevivido al contacto con la realidad.
El abismo entre experimentacion y produccion
Hay un abismo entre un modelo que funciona y un modelo en produccion. No es un salto tecnico menor. Es una transformacion completa del flujo de trabajo, los artefactos, las garantias y las responsabilidades.
En experimentacion, el data scientist controla todo: los datos, el entorno, el timing. Puede reejecutar un notebook completo, cambiar un hiperparametro, regenerar features manualmente. El output es un numero (accuracy, F1, AUC) y una conclusion (“funciona” o “no funciona”).
En produccion, nada de eso aplica.
Los datos llegan en tiempo real, con formatos inconsistentes, valores nulos que no estaban en el dataset de entrenamiento, y distribuciones que cambian sin previo aviso. El modelo tiene que responder en milisegundos, no en minutos. Y si falla, no hay un humano mirando un notebook para corregirlo: hay un sistema downstream que recibe una prediccion erronea y actua en consecuencia.
Hemos identificado cuatro brechas fundamentales entre experimentacion y produccion:
Brecha de reproducibilidad. El notebook original uso pandas 1.5.3, scikit-learn 1.2.1, y un dataset descargado “ayer”. Tres meses despues, nadie puede reproducir el resultado exacto. Las dependencias han cambiado, el dataset ya no existe en la misma forma, y el random seed no se registro. Sin reproducibilidad, no hay auditabilidad, y sin auditabilidad, no hay confianza.
Brecha de datos. El modelo se entreno con un snapshot estatico. En produccion, los datos son un stream. Las distribuciones cambian. Nuevas categorias aparecen. Valores que eran raros se vuelven comunes. El modelo no sabe que el mundo ha cambiado, y sigue prediciendo como si estuviera en enero cuando estamos en agosto.
Brecha de monitorizacion. En experimentacion, la metrica es un numero que calculas al final. En produccion, necesitas saber en tiempo real si el modelo sigue funcionando correctamente. No solo si devuelve una respuesta (eso es health check basico), sino si la calidad de esa respuesta se mantiene dentro de parametros aceptables.
Brecha de costes. Un notebook que tarda 20 minutos en entrenar un modelo no genera facturas preocupantes. Un pipeline que reentrena diariamente en GPUs cloud, procesa millones de inferencias, y almacena terabytes de features si las genera. Y la factura llega al final del mes, cuando ya es tarde para optimizar.
Model registry: el control de versiones que faltaba
El primer componente de un sistema MLOps maduro es un model registry. Es el equivalente a un repositorio Git para modelos, pero con metadatos especificos de ML: hiperparametros, metricas de evaluacion, dataset de entrenamiento, linaje de datos.
Nosotros usamos MLflow como registry central. No porque sea perfecto (no lo es), sino porque es open source, tiene integraciones con practicamente todo, y la curva de aprendizaje es asumible. Alternativas como Weights & Biases o Neptune ofrecen mejor UX, pero el vendor lock-in nos preocupa para proyectos de largo plazo.
Lo que registramos por cada modelo:
- Version del codigo de entrenamiento (commit hash de Git)
- Hash del dataset de entrenamiento (para reproducibilidad)
- Hiperparametros completos
- Metricas de evaluacion (no solo la metrica principal, todas las relevantes)
- Dependencias y versiones exactas (requirements.txt congelado)
- Fecha de entrenamiento y duracion
- Infraestructura utilizada (tipo de instancia, GPU, RAM)
Con esta informacion, cualquier modelo registrado es reproducible. Podemos volver a entrenar la version 23 exactamente igual que se entreno originalmente. Podemos comparar la version 23 con la 24 en cualquier dimension. Y podemos hacer rollback a la version 22 si la 23 introduce una regresion.
La disciplina clave es tratar los modelos como artefactos inmutables. Un modelo registrado nunca se modifica. Si necesitas cambiar algo, creas una nueva version. Esto parece obvio, pero hemos visto equipos que sobreescriben modelos en produccion directamente porque “es un cambio pequeno”. Esos cambios pequenos son los que generan las incidencias mas dificiles de diagnosticar.
Promocion por etapas
No todo modelo registrado va a produccion. Implementamos un flujo de promocion con tres etapas:
Staging. El modelo pasa por una bateria de tests automatizados: validacion de schema de entrada y salida, tests de rendimiento (latencia p50, p95, p99), tests de regresion contra un golden dataset, y tests de integracion con el pipeline de datos. Si falla cualquier test, no avanza.
Canary. El modelo recibe un porcentaje pequeno del trafico de produccion (tipicamente un 5%). Comparamos sus predicciones contra el modelo en produccion actual. Si las metricas de negocio (no solo las metricas de ML) son iguales o mejores durante 48 horas, avanza. Si hay degradacion, rollback automatico.
Production. El modelo recibe el 100% del trafico. Pero el modelo anterior se mantiene desplegado y listo para recibir trafico durante 7 dias. El rollback es un cambio de configuracion, no un redespliegue.
Este flujo nos ha evitado al menos cuatro incidencias graves en el ultimo ano. En un caso, un modelo de clasificacion de documentos paso staging correctamente pero mostro una degradacion del 12% en accuracy durante la fase canary. El problema era un cambio en la distribucion de tipos de documento que solo se manifestaba con trafico real. Sin la fase canary, ese modelo habria estado en produccion generando errores silenciosos.
Feature stores: la pieza mas infravalorada
Si le preguntas a un data scientist que es lo mas importante para un buen modelo, dira “los datos”. Si le preguntas que herramienta de MLOps es la mas importante, probablemente dira “el registry” o “el pipeline de entrenamiento”. Rara vez dice “el feature store”.
Y sin embargo, en nuestra experiencia, el feature store es la pieza que mas impacto tiene en la operativa diaria de un sistema ML en produccion.
Un feature store resuelve tres problemas:
Consistencia train-serve. El problema numero uno de los modelos en produccion es que las features que el modelo recibe en inferencia son diferentes de las que recibio en entrenamiento. No porque los datos sean diferentes, sino porque el codigo que calcula las features es diferente. El script de entrenamiento calcula la media movil de 30 dias de una forma. El servicio de inferencia la calcula de otra. O peor: el servicio de inferencia no la calcula, la recibe de otro sistema que tiene su propia logica.
Con un feature store, la definicion de cada feature existe en un unico lugar. El pipeline de entrenamiento lee de ahi. El servicio de inferencia lee de ahi. Misma feature, mismo calculo, siempre.
Reutilizacion de features. Sin un feature store, cada equipo calcula sus propias features. El equipo de fraude calcula “numero de transacciones en los ultimos 7 dias”. El equipo de marketing calcula exactamente lo mismo con un nombre diferente. El equipo de riesgo lo calcula con una ventana de 30 dias. Tres pipelines, tres costes de computo, tres oportunidades de inconsistencia. Con un feature store centralizado, una feature se calcula una vez y la usan todos.
Servicio en tiempo real. Algunas features necesitan estar disponibles con latencia de milisegundos para inferencia online. Calcularlas on-the-fly es demasiado lento. Un feature store mantiene las features precalculadas en un almacen de baja latencia (tipicamente Redis o DynamoDB) y las actualiza de forma continua o batch segun el caso.
Usamos Feast como feature store en la mayoria de proyectos. Es open source, soporta tanto batch como online serving, y se integra bien con el ecosistema que ya tenemos (Spark, Kafka, PostgreSQL). Para proyectos mas sencillos donde solo necesitamos batch features, a veces una tabla materializada en BigQuery o Snowflake es suficiente. No todo necesita la complejidad completa de un feature store dedicado.
El coste de no tener feature store
En un proyecto de prediccion de demanda para un cliente de logistica, desplegamos el modelo sin feature store. Las features se calculaban en un script Python que se ejecutaba antes de cada inferencia batch.
A los dos meses, descubrimos que una feature clave (volumen medio por ruta en los ultimos 90 dias) se calculaba de forma diferente en entrenamiento y en inferencia. El script de entrenamiento usaba datos corregidos post-hoc. El script de inferencia usaba datos brutos. La diferencia era sutil (menos del 3% en la mayoria de rutas), pero en rutas de bajo volumen generaba predicciones un 40% mas altas de lo real.
Reconstruir las features correctamente, validar que train y serve eran consistentes, y reentrenar el modelo nos costo tres semanas. Implementar Feast nos costo dos semanas. La leccion fue cara pero clara.
Monitorizacion: mas alla del health check
Un modelo en produccion que devuelve HTTP 200 no significa que funcione correctamente. Significa que no ha crasheado. La monitorizacion de modelos ML tiene tres capas, y la mayoria de equipos solo implementan la primera.
Capa 1: Monitorizacion de infraestructura
Latencia, throughput, errores, uso de CPU/GPU/memoria. Esta es la monitorizacion que cualquier servicio web necesita. Usamos Prometheus + Grafana para esto, con alertas en PagerDuty. Nada especifico de ML aqui.
Capa 2: Monitorizacion de datos (data drift)
Los datos de entrada al modelo cambian con el tiempo. A veces gradualmente (drift estacional), a veces abruptamente (un cambio de politica de un proveedor que altera el formato de datos). La monitorizacion de drift detecta cuando la distribucion de los datos de entrada se ha desviado significativamente de la distribucion de entrenamiento.
Implementamos monitorizacion de drift con dos metricas complementarias:
PSI (Population Stability Index) para features categoricas. Un PSI por encima de 0.2 indica drift significativo. Por encima de 0.25, generamos una alerta automatica.
KS test (Kolmogorov-Smirnov) para features numericas. Un p-valor por debajo de 0.01 con un tamano de efecto relevante dispara la alerta.
No monitorizamos todas las features. Monitorizamos las 10-15 features mas importantes segun la importancia del modelo (SHAP values del ultimo entrenamiento). Monitorizar 200 features genera ruido y falsos positivos. Monitorizar las 15 que realmente importan te da senales accionables.
Cuando detectamos drift significativo, no reentrenamos automaticamente. Primero investigamos. El drift puede ser un cambio real del negocio (y el modelo necesita adaptarse) o un problema de datos (y los datos necesitan corregirse). Reentrenar automaticamente sobre datos corruptos es peor que no reentrenar.
Capa 3: Monitorizacion de rendimiento del modelo
Esta es la capa mas valiosa y la mas dificil de implementar. Requiere ground truth: saber cual era la respuesta correcta para poder compararla con la prediccion del modelo.
En algunos casos, el ground truth llega rapido. Un modelo de clasificacion de tickets se puede evaluar cuando un agente humano resuelve el ticket y confirma o corrige la categoria. En otros casos, tarda semanas o meses. Un modelo de prediccion de churn no se puede evaluar hasta que pasan los 90 dias de la ventana de prediccion.
Para los casos de evaluacion lenta, usamos metricas proxy: el modelo predice churn, y si en las dos semanas siguientes el cliente reduce su actividad un 50%, lo contamos como senal de validacion parcial. No es ground truth perfecto, pero es mejor que volar a ciegas durante 90 dias.
Registramos todas las predicciones con su timestamp y su input hash. Cuando llega el ground truth, lo emparejamos y calculamos metricas reales. Esto alimenta un dashboard que muestra la evolucion de la accuracy real del modelo a lo largo del tiempo.
Pipeline de entrenamiento: automatizacion con guardrails
El reentrenamiento automatico es uno de los temas mas peligrosos de MLOps. Hecho bien, mantiene los modelos actualizados sin intervencion humana. Hecho mal, introduce regresiones silenciosas que degradan el servicio durante semanas antes de que alguien se de cuenta.
Nuestro pipeline de entrenamiento tiene tres modos:
Programado. Reentrenamiento semanal o mensual con datos frescos. El modelo nuevo pasa por el flujo de promocion completo (staging, canary, produccion). Es el modo por defecto para modelos estables.
Disparado por drift. Cuando la capa 2 de monitorizacion detecta drift significativo y un humano confirma que es un cambio real del negocio, se dispara un reentrenamiento. El modelo nuevo se compara explicitamente con el actual en el segmento donde se detecto el drift.
Manual. Un data scientist decide reentrenar porque hay nuevas features disponibles, porque el modelo de base ha sido actualizado, o porque se ha identificado un sesgo que corregir. Este modo bypasea el trigger automatico pero no bypasea el flujo de promocion.
Lo que nunca hacemos es reentrenamiento en bucle cerrado: drift detectado automaticamente produce reentrenamiento que produce despliegue automatico. Sin un humano en algun punto de la cadena, el riesgo de degradacion silenciosa es demasiado alto.
Versionado de datos
Cada entrenamiento debe poder responder a la pregunta: con que datos exactamente se entreno este modelo? No “con los datos de enero” sino “con el snapshot 2025-01-15T08:30:00Z del dataset customer_features_v3, hash SHA256 a1b2c3d4”.
Usamos DVC (Data Version Control) para esto. DVC funciona como Git pero para datasets grandes. Los datos se almacenan en S3, y DVC mantiene los hashes y metadatos en Git. Cada commit de entrenamiento incluye el lockfile de DVC, lo que garantiza que podemos reproducir exactamente el dataset de cualquier version de modelo.
Para datos que cambian con alta frecuencia (features en streaming), usamos snapshots puntuales en Delta Lake. Cada snapshot es una tabla inmutable que se puede referenciar por timestamp. No es tan limpio como DVC para datasets estaticos, pero funciona para nuestro caso de features que se actualizan cada hora.
Optimizacion de costes: donde se va el dinero
Los costes de MLOps tienen cuatro componentes principales, y la intuicion sobre cual es el mas caro suele ser erronea.
Computo de entrenamiento. Es el coste mas visible pero raramente el mas alto. Un entrenamiento semanal en una GPU A100 durante 4 horas cuesta unos $48 en AWS (instancia p4d.24xlarge spot). Son $200 al mes. No es trivial, pero no es el problema.
Computo de inferencia. Aqui es donde se concentra el coste para la mayoria de modelos. Un modelo que procesa 10 millones de inferencias al dia necesita infraestructura dedicada siempre encendida. Si el modelo requiere GPU para inferencia, el coste puede superar los $2,000 mensuales facilmente.
La optimizacion clave aqui es la cuantizacion y la destilacion. Un modelo cuantizado a INT8 ocupa la mitad de memoria y es 2-3x mas rapido en inferencia, con una degradacion tipica de menos del 1% en accuracy. Para modelos que no requieren la maxima precision, es una optimizacion obvia que muchos equipos no implementan.
Otra optimizacion: batching de inferencias. En lugar de procesar cada peticion individualmente, agrupamos peticiones en microbatches de 32 o 64. Esto aprovecha mejor el paralelismo de la GPU y puede reducir el coste de inferencia un 40-60%.
Almacenamiento de features. El feature store online (Redis, DynamoDB) puede ser sorprendentemente caro si no se gestiona activamente. Un feature store con 50 millones de entidades y 200 features por entidad, actualizado cada hora, puede costar mas de $1,500 mensuales en DynamoDB on-demand. La optimizacion aqui es ser selectivo: solo las features que necesitan latencia de milisegundos van al store online. El resto se sirven desde el store offline (S3 + Athena) con latencias de segundos.
Almacenamiento de datos y logs. Los logs de monitorizacion, las predicciones historicas, los snapshots de datos, los artefactos de entrenamiento. Todo suma. Implementamos politicas de retencion agresivas: logs detallados 30 dias, logs agregados 1 ano, predicciones 6 meses (salvo que haya requisitos regulatorios), artefactos de entrenamiento solo para las ultimas 10 versiones.
Caso real: de $4,200/mes a $1,800/mes
Para un cliente de retail con tres modelos en produccion (recomendacion de productos, prediccion de demanda, deteccion de fraude), el coste mensual de MLOps era de $4,200.
Identificamos tres optimizaciones:
- Cuantizacion del modelo de recomendacion de FP32 a INT8. Reduccion del 45% en coste de inferencia para ese modelo.
- Migracion del feature store de DynamoDB on-demand a provisioned con auto-scaling. Reduccion del 35% en coste de almacenamiento.
- Consolidacion de los tres pipelines de entrenamiento en una unica instancia spot con scheduling. Los tres modelos se entrenaban en GPU dedicadas separadas, cuando en realidad nunca se entrenaban simultaneamente.
Resultado: $1,800/mes. Un 57% de reduccion. El esfuerzo de implementacion fue de dos semanas de un ingeniero senior.
Orquestacion: pegamento que sostiene todo
El pipeline de MLOps tiene muchas piezas moviles: extraccion de datos, calculo de features, entrenamiento, evaluacion, registro, despliegue, monitorizacion. Orquestar todo esto requiere un sistema que maneje dependencias, reintentos, paralelismo y estado.
Usamos Prefect para orquestacion. Probamos Airflow primero (lo hace todo el mundo, debe ser la respuesta correcta) y lo abandonamos despues de tres meses. Airflow es excelente para ETL batch clasico, pero su modelo de programacion basado en DAGs estaticos encaja mal con los workflows de ML, que son mas dinamicos: decide si reentrenar basandote en los resultados de la monitorizacion, elige el dataset segun la fecha, selecciona hiperparametros basandose en el rendimiento historico.
Prefect nos permite definir flujos como codigo Python normal con decoradores, tiene reintentos configurables por tarea, soporta ejecucion concurrente nativa, y tiene un UI que los data scientists realmente usan (a diferencia del UI de Airflow, que solo usaba el equipo de infra).
Un detalle que subestimamos al principio: la importancia de las notificaciones. Cuando un pipeline falla a las 3 de la manana, alguien tiene que enterarse. Cuando un reentrenamiento produce un modelo con metricas peores que el actual, alguien tiene que decidir si se despliega o no. Integramos Prefect con Slack y PagerDuty, con diferentes niveles de severidad: fallo de pipeline va a Slack, fallo de despliegue va a PagerDuty.
Testing: lo que nadie quiere hacer
Los modelos ML necesitan tests. No solo validacion en un hold-out set, sino tests de ingenieria que verifican que el sistema completo funciona correctamente.
Tests de esquema. Verifican que el input al modelo tiene el formato esperado. Tipos correctos, rangos validos, valores no nulos donde se requieren. Estos tests se ejecutan en cada inferencia y rechazan inputs invalidos antes de que lleguen al modelo. Triviales de implementar, pero evitan una categoria entera de errores silenciosos.
Tests de regresion. Un golden dataset de 500-1000 ejemplos con predicciones correctas conocidas. Cada nuevo modelo debe producir predicciones dentro de un margen aceptable para este dataset. Si un modelo nuevo clasifica correctamente el 92% del golden set cuando el modelo actual clasifica el 95%, hay una regresion y el modelo no se promueve.
Tests de rendimiento. Latencia p99 por debajo de un umbral. Throughput minimo en inferencias por segundo. Uso de memoria dentro de limites. Estos tests se ejecutan en el entorno de staging con carga sintetica antes de cualquier promocion.
Tests de sesgo. Verifican que el modelo no discrimina por variables protegidas. Calculamos metricas de equidad (demographic parity, equal opportunity) para cada version del modelo. Si hay una degradacion en equidad, el modelo se revisa manualmente antes de desplegarse. Este tipo de test es cada vez mas relevante con regulaciones como el AI Act de la UE.
Tests de integracion. El modelo completo, con su preprocesamiento, inferencia y postprocesamiento, se ejecuta end-to-end con datos sinteticos que cubren los casos edge conocidos. Estos tests verifican que la integracion entre componentes funciona, no solo que cada componente individual pasa sus tests unitarios.
Organizacion: quienes son responsables de que
El aspecto mas dificil de MLOps no es tecnico. Es organizativo. Quien es responsable del modelo en produccion? El data scientist que lo entreno? El ingeniero de ML que lo desplego? El equipo de plataforma que mantiene la infraestructura?
Hemos visto tres modelos organizativos y sus resultados:
Modelo 1: el data scientist hace todo. El data scientist entrena, despliega y monitoriza. Resultado: el data scientist pasa el 70% de su tiempo en operaciones y el 30% en ciencia de datos. Frustracion alta, calidad operativa baja.
Modelo 2: separacion completa. Data scientists entrenan, ingenieros de ML despliegan. Resultado: una cola de 3-4 semanas entre “el modelo esta listo” y “el modelo esta en produccion”. Comunicacion por tickets. Perdida de contexto en cada handoff.
Modelo 3: equipo integrado con plataforma compartida. Data scientists trabajan con ingenieros de ML en el mismo equipo. Una plataforma de MLOps compartida reduce la friccion operativa. El data scientist puede desplegar a staging sin ayuda. La promocion a produccion requiere aprobacion del ingeniero de ML. Resultado: time-to-production de 2-3 dias, calidad operativa alta, data scientists contentos.
El modelo 3 es el que recomendamos, con una condicion: la plataforma de MLOps tiene que ser lo suficientemente buena para que el data scientist pueda usarla sin ser un experto en Kubernetes o Docker. Si desplegar un modelo requiere escribir un Dockerfile, configurar un Helm chart, y crear un Ingress, el data scientist va a buscar atajos. Y esos atajos terminan en produccion.
Checklist de madurez MLOps
Para cerrar con algo accionable, esta es la lista que usamos para evaluar la madurez MLOps de una organizacion. Cada item es binario: lo tienes o no lo tienes.
Nivel 1 (Basico):
- Los modelos estan versionados en un registry
- Las dependencias estan congeladas por version de modelo
- Existe un proceso de despliegue documentado (aunque sea manual)
- Hay monitorizacion de infraestructura basica (latencia, errores, uptime)
Nivel 2 (Operativo):
- El despliegue es automatizado con promocion por etapas
- Hay monitorizacion de data drift en features criticas
- Los datos de entrenamiento estan versionados
- Existe un pipeline de reentrenamiento (aunque sea manual-triggered)
- Hay tests de regresion automaticos
Nivel 3 (Avanzado):
- Feature store compartido con consistencia train-serve
- Monitorizacion de rendimiento del modelo con ground truth
- Reentrenamiento programado con guardrails automaticos
- Tests de sesgo y equidad en el pipeline de promocion
- Costes de MLOps monitorizados y optimizados activamente
- Rollback automatico basado en metricas de produccion
La mayoria de equipos estan en nivel 1. Los que llegan a nivel 2 ya ven una mejora dramatica en la fiabilidad de sus modelos. El nivel 3 es donde queremos llevar a todos nuestros clientes, pero es un camino, no un salto.
Si tu equipo de datos esta luchando con la brecha entre experimentacion y produccion, el primer paso no es comprar una plataforma de MLOps. Es sentarse con los data scientists y los ingenieros, mapear el flujo actual de un modelo desde notebook hasta produccion, identificar los tres puntos de mayor friccion, y resolverlos. La plataforma viene despues.
En abemon, ayudamos a equipos a disenar e implementar flujos MLOps adaptados a su escala y madurez. No vendemos la arquitectura ideal. Construimos la arquitectura que tu equipo puede operar hoy, con un camino claro hacia donde necesitas estar manana. Porque un sistema MLOps que nadie usa es peor que un notebook ejecutado a mano: al menos el notebook, alguien lo entiende.
Sobre el autor
abemon engineering
Equipo de ingenieria
Equipo multidisciplinar de ingenieria, datos e IA con sede en Canarias. Construimos, desplegamos y operamos soluciones de software a medida para empresas de cualquier escala.
