MLOps para IoT es la práctica de desplegar, monitorizar y actualizar modelos de machine learning que se ejecutan en dispositivos que no puedes ver. En esta guía construirás un bucle de monitorización ligero: los dispositivos de borde publican métricas de inferencia por MQTT, un servicio central en Python mide la deriva y los modelos degradados disparan alertas en un topic dedicado.
Por qué se degradan los modelos en campo
Un modelo que obtuvo buenos resultados en el laboratorio empieza a perder precisión el mismo día en que se despliega. En IoT, los motivos son físicos y a menudo lentos:
- Envejecimiento y recalibración de sensores. Un sensor de vibración deriva, la lente de una cámara se llena de polvo, un micrófono capta un ventilador nuevo.
- Cambios de proceso. En una planta de manufactura de Querétaro o una mina en Chile, un material nuevo, un patrón de turnos distinto o una nueva variante de producto desplazan la distribución de entrada.
- Estacionalidad. La temperatura y la humedad ambiente cambian las líneas base de los sensores a lo largo de los meses.
- Desajuste en el despliegue. La cuantización o una compilación de firmware distinta cambian ligeramente las salidas respecto al modelo evaluado.
En un servicio web puedes registrar cada petición y comparar las predicciones con la respuesta de los usuarios. En campo normalmente no tienes ninguna etiqueta, el ancho de banda es limitado y los dispositivos se desconectan. Por eso MLOps para IoT se apoya en señales indirectas: estadísticas de entrada, distribuciones de salida, confianza y latencia.
Qué medir en el dispositivo
Enviar ventanas de sensores en bruto a la nube en cada inferencia anula el sentido de la IA en el borde. En su lugar, cada dispositivo agrega unas pocas cifras por intervalo y publica un mensaje de métricas compacto.
| Métrica | Qué revela | Agregación típica |
|---|---|---|
| Media y desviación típica de entrada por variable | Deriva de datos, fallos de sensores | Por minuto o cada 1.000 inferencias |
| Recuento de predicciones por clase | Deriva de salida, modelos atascados | Recuentos por intervalo |
| Confianza media y de percentil bajo | Aumento de la incertidumbre del modelo | Media, percentil 10 |
| Latencia de inferencia | Limitación térmica, contención de recursos | p50, p95 |
| Versión y hash del modelo | Qué compilación se está ejecutando realmente | En cada mensaje |
| Recuento de entradas fuera de rango | Sensores averiados o desconectados | Recuento por intervalo |
Un payload de métricas podría tener este aspecto:
{
"device": "press-07",
"model": "vib-classifier",
"modelVersion": "1.4.2",
"window": "2026-10-16T10:00:00Z/PT1M",
"inferences": 600,
"inputMean": {"rms": 0.42, "peakHz": 118.0},
"inputStd": {"rms": 0.05, "peakHz": 6.1},
"classCounts": {"normal": 588, "imbalance": 9, "bearing": 3},
"confMean": 0.91,
"confP10": 0.74,
"latencyMsP95": 14.2
}
Diseño de topics para MLOps en IoT
Mantén la telemetría de los modelos separada de la telemetría de proceso para que los dashboards y los consumidores puedan suscribirse con precisión:
connectmq/plant1/ml/<model>/<device>/metrics
connectmq/plant1/ml/<model>/<device>/status (retained: version, loaded at)
connectmq/plant1/ml/<model>/alerts
connectmq/plant1/ml/<model>/<device>/cmd (rollout or rollback commands)
Retener el topic de estado significa que cualquier suscriptor nuevo sabe al instante qué versión del modelo ejecuta cada dispositivo, que es la pregunta más habitual durante un incidente.
Publicar métricas desde un dispositivo de borde
El siguiente script simula un dispositivo de borde que ejecuta un clasificador y publica un mensaje de métricas por intervalo. En hardware real acumularías las estadísticas dentro de tu bucle de inferencia. Usa el área pública de broker.connectmq.com, el servidor MQTT público gratuito, pensado para pruebas y no para datos de producción; sustituye el prefijo por tu propio ID aleatorio.
import json
import random
import time
import uuid
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/mlops-91bc/plant1/ml/vib-classifier"
DEVICE = "press-07"
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"{DEVICE}-{uuid.uuid4().hex[:6]}")
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
status = {"modelVersion": "1.4.2", "loadedAt": time.time()}
client.publish(f"{PREFIX}/{DEVICE}/status", json.dumps(status), qos=1, retain=True)
drift = 0.0
while True:
drift += 0.002 # desplaza lentamente la entrada para simular el envejecimiento del sensor
rms = [random.gauss(0.42 + drift, 0.05) for _ in range(600)]
conf = [min(1.0, max(0.0, random.gauss(0.91 - drift, 0.06))) for _ in range(600)]
conf.sort()
msg = {
"device": DEVICE,
"modelVersion": "1.4.2",
"inferences": len(rms),
"inputMean": {"rms": sum(rms) / len(rms)},
"inputHist": {"rms": [sum(1 for v in rms if lo <= v < lo + 0.05)
for lo in [0.25 + 0.05 * i for i in range(10)]]},
"confMean": sum(conf) / len(conf),
"confP10": conf[len(conf) // 10],
"ts": time.time(),
}
client.publish(f"{PREFIX}/{DEVICE}/metrics", json.dumps(msg), qos=1)
time.sleep(10)
El histograma con intervalos fijos es lo que permite medir la deriva de forma centralizada sin enviar datos en bruto.
Detectar la deriva de forma centralizada
El monitor se suscribe a todos los dispositivos, compara cada histograma entrante con un histograma de referencia capturado en el despliegue y calcula el Population Stability Index (PSI). Una regla práctica habitual considera estable un PSI inferior a 0,1, digno de vigilancia entre 0,1 y 0,25 y un cambio significativo por encima de 0,25, pero ajusta esas bandas con tus propios datos.
import json
import math
import uuid
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/mlops-91bc/plant1/ml/vib-classifier"
reference = {} # dispositivo -> histograma de referencia
CONF_FLOOR = 0.70
def psi(expected, actual, eps=1e-4):
e_total, a_total = sum(expected) or 1, sum(actual) or 1
score = 0.0
for e, a in zip(expected, actual):
e_p = max(e / e_total, eps)
a_p = max(a / a_total, eps)
score += (a_p - e_p) * math.log(a_p / e_p)
return score
def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe(f"{PREFIX}/+/metrics", qos=1)
def on_message(client, userdata, msg):
m = json.loads(msg.payload)
dev, hist = m["device"], m["inputHist"]["rms"]
if dev not in reference:
reference[dev] = hist
print(f"reference captured for {dev}")
return
score = psi(reference[dev], hist)
status = "ok"
if score > 0.25 or m["confP10"] < CONF_FLOOR:
status = "degraded"
elif score > 0.1:
status = "watch"
print(f"{dev} psi={score:.3f} confP10={m['confP10']:.2f} -> {status}")
if status != "ok":
alert = {"device": dev, "modelVersion": m["modelVersion"],
"psi": round(score, 3), "confP10": round(m["confP10"], 3),
"status": status}
client.publish(f"{PREFIX}/alerts", json.dumps(alert), qos=1)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"mlops-monitor-{uuid.uuid4().hex[:6]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever()
Ejecuta ambos scripts y verás cómo el estado pasa de ok a watch y a degraded a medida que se acumula la deriva simulada. En producción, el histograma de referencia debe proceder de los datos de validación usados para aprobar el modelo, almacenados junto al artefacto del modelo, y no del primer mensaje tras el arranque.
Actuar ante las alertas
Una alerta solo es útil si alguien o algo responde. Opciones, de la más sencilla a la más automatizada:
- Avisar a una persona. Un flujo de Node-RED o un pequeño servicio se suscribe al topic de alertas y envía correos o mensajes de chat.
- Alertas visuales en el portal del broker. En un broker privado de ConnectMQ puedes definir reglas de alerta por umbral sobre un campo numérico como
psiy revisar los disparos en el registro de alertas. - Recoger etiquetas. Cuando un dispositivo deriva, pídele que suba unas cuantas muestras en bruto a un topic separado para que los ingenieros puedan etiquetarlas y reentrenar.
- Revertir. Publica un comando en el topic
cmddel dispositivo para cargar la versión anterior del modelo y confírmalo después mediante el topic de estado retenido.
El lado del despliegue, cómo llegan los modelos a los dispositivos en primer lugar, se trata en desplegar modelos de ML en dispositivos de borde.
Despliegues canary y modelos en sombra
La monitorización te dice cuándo se degrada un modelo; la disciplina de despliegue evita que un modelo nuevo empeore las cosas. Dos patrones funcionan bien con topics MQTT.
Despliegue canary. Envía primero el nuevo modelo a un grupo pequeño de dispositivos, por ejemplo el cinco por ciento de la flota o una línea por planta. Como cada mensaje de métricas incluye modelVersion, el monitor puede comparar la confianza, la distribución de clases y la deriva entre el grupo canary y el resto durante el mismo periodo. Promuévelo solo cuando el canary parezca al menos tan sano como el modelo vigente, y revierte con el mismo topic de comandos si no lo es.
Modo sombra. Ejecuta el nuevo modelo junto al actual en el mismo dispositivo, pero actúa solo sobre la salida del modelo actual. Publica ambas predicciones en el mensaje de métricas, o publica una tasa de coincidencia acumulada entre los dos. Un modelo en sombra que discrepa del modelo de producción en una gran parte de las entradas merece un examen más detenido antes de tomar el relevo, aunque ambos modelos parezcan seguros.
Ninguno de los dos patrones necesita del broker nada más que una entrega fiable y topics claros. Además, facilitan el análisis posterior a un incidente: cuando salta una alerta, la primera pregunta es si coincide con un cambio de versión, y los topics de estado retenidos lo responden al instante.
Una nota práctica sobre el ancho de banda: un mensaje de métricas por minuto de cada dispositivo es minúsculo, pero las subidas de muestras en bruto para etiquetado no lo son. Mantén las subidas en un topic separado, dispáralas solo bajo petición y mantente por debajo del límite de tamaño de mensaje de tu plan.
Lista de comprobación de MLOps para IoT
- Cada mensaje incluye el nombre y la versión del modelo.
- Los dispositivos publican estadísticas de entrada agregadas, no datos en bruto, a intervalos fijos.
- Se almacena una distribución de referencia con cada modelo publicado.
- Los umbrales de deriva y confianza están documentados y se revisan tras cada incidente.
- Las alertas van a un topic, y al menos un consumidor las convierte en notificaciones para personas.
- La reversión es un comando probado, no un plan.
- Los datos de reentrenamiento se recogen de forma deliberada cuando se produce deriva.
- En producción, las métricas y las alertas viajan por TLS con credenciales por dispositivo.
Infraestructura para monitorizar toda la flota
Las métricas de cientos de dispositivos, un monitor, los dashboards y las herramientas de despliegue comparten un único bus de mensajes. Gestionar ese bus por tu cuenta implica parches, certificados y planificación de capacidad. Un broker MQTT gestionado elimina ese trabajo, y un broker MQTT en la nube es accesible desde dispositivos en cualquier red. Las suscripciones compartidas del plan Serverless de pago te permiten ejecutar varias instancias del monitor que se reparten la carga de métricas.
El mismo flujo de métricas alimenta también trabajos específicos de modelos, como el mantenimiento predictivo con machine learning, y las comprobaciones de deriva son parientes cercanas de la detección de anomalías IoT: una vigila la máquina y la otra vigila el modelo. Para una visión más amplia de la IA en el borde y en la nube, consulta la guía de IA e IoT.
Monitoriza tus modelos en campo con ConnectMQ
Crea un broker privado en el plan gratuito Serverless en app.connectmq.com, sin tarjeta de crédito, conecta tus dispositivos con las credenciales generadas por el puerto 8883 y observa cómo llegan las métricas de los modelos al explorador de topics en directo. Añadir el monitor de deriva es el script anterior con un usuario y una contraseña.
Preguntas frecuentes
¿En qué se diferencia MLOps para IoT del MLOps convencional?
Los dispositivos en campo rara vez tienen etiquetas, disponen de un ancho de banda limitado y pueden estar desconectados, por lo que la monitorización se basa en estadísticas agregadas de entrada y salida en lugar de registros por petición. El despliegue y la reversión también deben funcionar sobre enlaces poco fiables.
¿Con qué frecuencia deben publicar los dispositivos las métricas del modelo?
Una vez por minuto o cada pocos cientos de inferencias es un buen punto de partida. Es lo bastante frecuente como para detectar la deriva en cuestión de horas y lo bastante reducido como para mantenerse holgadamente dentro de los límites de mensajes.
¿Qué métrica de deriva debo usar?
El Population Stability Index y las pruebas de Kolmogorov-Smirnov son habituales para las entradas, y seguir la confianza de percentil bajo detecta muchos problemas de salida. Usa más de una señal, ya que cada una pasa por alto algunos modos de fallo.
¿Puede el broker detectar la deriva por mí?
No. El broker transporta las métricas; la detección de deriva se ejecuta en tu propio servicio suscrito a ellas. Las reglas de alerta por umbral del portal de ConnectMQ pueden señalar límites numéricos sencillos una vez que tu servicio publique una puntuación de deriva.



