Concepto clave
El despliegue de modelos de Machine Learning en producción requiere transformar algoritmos entrenados en servicios accesibles y confiables. Imagina que tu modelo es como un chef experto: en desarrollo, prueba recetas en su cocina privada, pero en producción, debe atender a cientos de clientes en un restaurante con pedidos estandarizados y control de calidad. FastAPI actúa como el sistema de gestión del restaurante, recibiendo solicitudes (como pedidos de predicción), validando que sean correctas (por ejemplo, datos en el formato esperado), y devolviendo respuestas estructuradas (como platos preparados). Este enfoque garantiza que tu API ML no solo funcione, sino que sea escalable, mantenible y monitoreable en entornos reales.
En este contexto, una API ML en producción debe manejar aspectos críticos como la validación de datos de entrada, el manejo de versiones del modelo, y la observabilidad (monitoring). Sin esto, incluso el mejor modelo puede fallar silenciosamente o degradarse con el tiempo. Por ejemplo, si un usuario envía datos mal formateados, la API debe rechazarlos con un error claro, en lugar de procesarlos y dar una predicción errónea. FastAPI facilita esto con su sistema de Pydantic para validación y su integración con herramientas como Prometheus para métricas.
Cómo funciona en la práctica
Para implementar una API ML con FastAPI, sigue estos pasos: primero, define un esquema de datos usando Pydantic para validar las entradas y salidas. Segundo, carga tu modelo entrenado (por ejemplo, con joblib o pickle) en la inicialización de la aplicación. Tercero, crea endpoints REST, como POST /predict, que reciban datos, los validen, apliquen el modelo, y devuelvan resultados. Cuarto, añade middleware para logging y métricas, y configura un servidor como Uvicorn para despliegue. Aquí un ejemplo básico de flujo:
- Instala dependencias: fastapi, uvicorn, scikit-learn, joblib.
- Crea un archivo main.py con la aplicación FastAPI.
- Define un modelo Pydantic para la entrada (por ejemplo, características de un cliente para predicción de riesgo).
- Carga el modelo ML desde un archivo .pkl al iniciar.
- Implementa el endpoint /predict que use el modelo para hacer predicciones.
- Prueba localmente con Uvicorn y luego despliega en un servidor o contenedor Docker.
Codigo en accion
Antes: Un script simple de predicción sin validación o API.
# model_predict.py (versión antigua)
import joblib
model = joblib.load('model.pkl')
def predict_raw(features):
# Sin validación de entrada
return model.predict([features])[0]
# Uso: resultado = predict_raw([1.2, 3.4]) # Riesgo de erroresDespués: API FastAPI con validación y estructura.
# main.py (versión mejorada)
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import joblib
import numpy as np
# Esquema Pydantic para validación
class PredictionInput(BaseModel):
feature1: float
feature2: float
class Config:
schema_extra = {
"example": {
"feature1": 1.2,
"feature2": 3.4
}
}
app = FastAPI(title="ML API en Producción")
# Cargar modelo al iniciar (evita recarga por solicitud)
model = joblib.load('model.pkl')
@app.post("/predict", summary="Realizar predicción con modelo ML")
async def predict(input_data: PredictionInput):
try:
features = np.array([[input_data.feature1, input_data.feature2]])
prediction = model.predict(features)[0]
return {"prediction": float(prediction), "status": "success"}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error en predicción: {str(e)}")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)Errores comunes
- No validar datos de entrada: Aceptar cualquier dato puede llevar a predicciones incorrectas o caídas del servidor. Solución: Usa siempre esquemas Pydantic para definir y validar entradas.
- Cargar el modelo en cada solicitud: Esto ralentiza la API y consume memoria. Solución: Carga el modelo una vez al inicio de la aplicación, como en el código de ejemplo.
- Falta de manejo de errores: Si el modelo falla, la API puede devolver respuestas crípticas. Solución: Implementa try-except y usa HTTPException para errores claros.
- Ignorar el versionado del modelo: Desplegar un nuevo modelo sin control puede romper clientes existentes. Solución: Usa endpoints como /v1/predict y /v2/predict, o sistemas como MLflow para gestión.
- No monitorear métricas: Sin observabilidad, no puedes detectar problemas como alta latencia o drift de datos. Solución: Integra herramientas como Prometheus para métricas de rendimiento y salud.
Checklist de dominio
- ¿Tu API valida todas las entradas usando Pydantic con tipos específicos (por ejemplo, float, int)?
- ¿El modelo ML se carga solo una vez al inicio para eficiencia?
- ¿Los endpoints devuelven errores HTTP apropiados (por ejemplo, 400 para mala entrada, 500 para errores internos)?
- ¿Has implementado logging básico para rastrear solicitudes y respuestas?
- ¿La API incluye documentación automática (por ejemplo, /docs y /redoc) generada por FastAPI?
- ¿Has probado la API con herramientas como curl o Postman en un entorno similar a producción?
- ¿Consideras usar contenedores Docker para empaquetar y desplegar de forma consistente?
Refactorizar un script ML a API FastAPI con validación y monitoreo básico
En este ejercicio, tomarás un script existente de predicción ML y lo transformarás en una API FastAPI lista para producción. Sigue estos pasos:
- Prepara el entorno: Crea un nuevo directorio para el proyecto. Instala fastapi, uvicorn, scikit-learn, y joblib usando pip. Coloca tu modelo entrenado (por ejemplo, un archivo model.pkl) en el directorio.
- Analiza el script original: Examina el código proporcionado (similar al "antes" en la lección) que carga un modelo y hace predicciones sin validación. Identifica los puntos débiles, como falta de validación de entrada.
- Diseña el esquema de datos: Define una clase Pydantic (por ejemplo, PredictionInput) que represente los datos de entrada esperados por tu modelo. Incluye tipos de datos y un ejemplo.
- Implementa la API FastAPI: Crea un archivo main.py. Carga el modelo al inicio. Añade un endpoint POST /predict que acepte el esquema Pydantic, valide, aplique el modelo, y devuelva un JSON con la predicción.
- Añade manejo de errores: Envuelve la predicción en un bloque try-except. Si hay un error, devuelve un HTTPException con código 500 y un mensaje descriptivo.
- Prueba localmente: Ejecuta la API con uvicorn main:app --reload. Usa curl o Postman para enviar una solicitud POST a http://localhost:8000/predict con datos válidos y no válidos, verificando las respuestas.
- Agrega monitoreo básico: Añade un endpoint GET /health que devuelva {"status": "healthy"} para verificar que la API está en funcionamiento. Opcionalmente, integra logging con el módulo logging de Python.
Entrega: Un archivo main.py funcional y un breve informe describiendo los cambios realizados y cómo mejoran la robustez en producción.
Pistas- Usa el decorador @app.post para definir el endpoint /predict, y asegúrate de especificar el tipo de parámetro como tu clase Pydantic.
- Para cargar el modelo una sola vez, declara la variable model fuera de la función predict, por ejemplo, justo después de crear la app FastAPI.
- Prueba con datos incorrectos (por ejemplo, strings en lugar de números) para verificar que la validación de Pydantic funcione y devuelva un error 422.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.