Concepto clave
En el despliegue de APIs de Machine Learning, el monitoreo es como tener un tablero de control en un coche de carreras. No solo necesitas saber si el motor funciona, sino también su temperatura, presión de aceite y consumo de combustible en tiempo real. Prometheus es el sistema que recoge estas métricas (como un registrador de datos), mientras que Grafana es el panel de instrumentos que las visualiza de forma comprensible.
En el contexto de FastAPI, integrar estas herramientas te permite responder preguntas críticas: ¿Cuántas predicciones por segundo está procesando tu modelo? ¿Cuál es el tiempo de respuesta p95? ¿Hay errores en las validaciones de entrada? Sin esto, operas a ciegas, arriesgando caídas del servicio o degradación silenciosa del rendimiento.
Cómo funciona en la práctica
El flujo típico sigue estos pasos:
- Instrumentas tu aplicación FastAPI con un cliente de Prometheus (como
prometheus-fastapi-instrumentator) que expone métricas en un endpoint/metrics. - Prometheus "raspa" periódicamente ese endpoint (cada 15-30 segundos) y almacena las métricas en su base de datos de series temporales.
- Grafana se conecta a Prometheus como fuente de datos, permitiéndote crear dashboards con gráficos, alertas y paneles personalizados.
- Para APIs de ML, añades métricas específicas como latencia de inferencia, distribución de scores del modelo, o conteo de predicciones por clase.
Codigo en accion
Primero, instala las dependencias necesarias:
pip install prometheus-fastapi-instrumentatorLuego, integra el instrumentador en tu aplicación FastAPI. Aquí el "antes" (sin monitoreo) y "después" (con monitoreo):
Antes: API básica sin métricas.
from fastapi import FastAPI
import numpy as np
app = FastAPI()
@app.post("/predict")
async def predict(data: dict):
# Simulación de inferencia de ML
prediction = np.random.rand()
return {"prediction": float(prediction)}Después: API instrumentada con métricas estándar y personalizadas.
from fastapi import FastAPI, Request
from prometheus_fastapi_instrumentator import Instrumentator
import numpy as np
import time
from prometheus_client import Counter, Histogram
app = FastAPI()
# Métricas personalizadas para ML
PREDICTION_COUNTER = Counter('ml_predictions_total', 'Total de predicciones realizadas')
PREDICTION_LATENCY = Histogram('ml_prediction_latency_seconds', 'Latencia de predicción')
Instrumentator().instrument(app).expose(app)
@app.post("/predict")
async def predict(request: Request, data: dict):
start_time = time.time()
# Simulación de inferencia de ML
prediction = np.random.rand()
# Registrar métricas
PREDICTION_COUNTER.inc()
PREDICTION_LATENCY.observe(time.time() - start_time)
return {"prediction": float(prediction)}Errores comunes
- Exponer el endpoint /metrics sin autenticación en producción: Cualquiera podría acceder a métricas sensibles. Solución: Usa middleware de autenticación o despliega Prometheus en la misma red privada.
- No etiquetar métricas adecuadamente: Por ejemplo, tener solo
ml_predictions_totalsin etiquetas comomodel_versionoendpoint. Esto dificulta el análisis cuando tienes múltiples modelos. Agrega etiquetas con.labels()en Prometheus Client. - Configurar intervalos de scrape demasiado cortos: Si Prometheus consulta cada segundo, puede saturar tu API. En producción, 15-30 segundos es un buen balance entre granularidad y carga.
- Olvidar métricas de negocio para ML: Además de latencia y errores, monitorea la distribución de scores, drift de datos, o precisión en tiempo real si tienes ground truth.
Checklist de dominio
- El endpoint
/metricsresponde con datos en formato Prometheus. - Prometheus está configurado para scrapear tu API y almacena las métricas.
- Grafana muestra un dashboard con al menos: requests por segundo, latencia por percentil, y tasa de errores.
- Tienes métricas personalizadas para tu modelo ML (ej. predicciones por clase, confianza media).
- Las alertas en Grafana notifican cuando la latencia p95 supera un umbral (ej. 500ms).
- Probaste el flujo completo localmente antes de desplegar a producción.
- Documentaste cómo añadir nuevas métricas y dashboards al equipo.
Implementa un sistema de monitoreo para un API de clasificación de imágenes
En este ejercicio, extenderás una API FastAPI existente para monitorear el rendimiento de un modelo de clasificación de imágenes (simulado). Sigue estos pasos:
- Clona el repositorio base desde
https://github.com/ejemplo/ml-monitoring-base(simulado) o crea un archivomain.pycon una API FastAPI que tenga un endpoint/classifyque reciba una imagen (como bytes) y devuelva una clase predicha (ej. "perro", "gato"). Simula la inferencia contime.sleep(0.1)y una clase aleatoria. - Instala
prometheus-fastapi-instrumentatoryprometheus-client. - Instrumenta la aplicación para exponer métricas estándar en
/metrics. - Añade dos métricas personalizadas usando
prometheus_client:- Un contador
images_classified_totalcon etiquetas para la clase predicha (ej. label="perro"). - Un histograma
classification_latency_secondspara medir el tiempo de inferencia.
- Un contador
- Ejecuta la API y verifica que
curl localhost:8000/metricsmuestre tus métricas. - Configura Prometheus local (usa Docker con
docker run -p 9090:9090 prom/prometheus) para scrapear tu API cada 15 segundos. Crea un archivoprometheus.ymlcon el job adecuado. - En Grafana (usa
docker run -p 3000:3000 grafana/grafana), conecta Prometheus como fuente de datos y crea un dashboard con:- Un gráfico de líneas para
rate(images_classified_total[5m])por clase. - Un panel para la latencia p95:
histogram_quantile(0.95, rate(classification_latency_seconds_bucket[5m])).
- Un gráfico de líneas para
- Genera tráfico de prueba con una herramienta como
locusto scripts simples, y observa cómo se actualizan los dashboards.
- Usa
PREDICTION_COUNTER.labels(class="perro").inc()para incrementar el contador con etiquetas. - En Prometheus, el job en
prometheus.ymldebe apuntar alocalhost:8000bajostatic_configs. - Para Grafana, la URL de Prometheus es
http://host.docker.internal:9090si usas Docker en macOS/Windows, ohttp://localhost:9090en Linux.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.