Concepto clave
En el despliegue de modelos de Machine Learning, la validación de datos es tu primera línea de defensa contra errores en producción. Pydantic no solo valida tipos básicos, sino que permite crear reglas personalizadas que reflejan las restricciones específicas de tus datos ML. Imagina que tu API es un restaurante de alta cocina: los datos crudos son los ingredientes, y Pydantic es el chef que inspecciona cada uno antes de cocinar. Si llega un tomate podrido (dato inválido), lo rechaza inmediatamente, evitando que arruine el plato (tu modelo).
La validación personalizada va más allá de "este campo es un número". En ML, necesitas asegurar que: las probabilidades estén entre 0 y 1, los vectores de características tengan la dimensión correcta, o que ciertas columnas no contengan valores atípicos extremos. Sin esto, tu modelo podría producir predicciones sin sentido o, peor, fallar silenciosamente. En producción, un error de validación temprana es mejor que un error de predicción tardío.
Cómo funciona en la práctica
Pydantic te permite definir validadores a nivel de campo o de modelo. Para datos ML, los validadores a nivel de campo son ideales para reglas específicas como rangos o formatos. Por ejemplo, validar que una probabilidad esté en [0,1] o que un ID de cliente tenga un formato específico. Los validadores a nivel de modelo son útiles para reglas que involucran múltiples campos, como asegurar que la suma de probabilidades en una clasificación multiclase sea 1.
Paso a paso: primero, defines tu modelo Pydantic con los campos necesarios. Luego, añades decoradores como @validator o @field_validator (dependiendo de la versión) para inyectar tu lógica personalizada. Dentro del validador, puedes acceder al valor del campo, y si algo no cumple, lanzas un ValueError con un mensaje claro. FastAPI captura estos errores y los devuelve como respuestas HTTP 422 con detalles, lo que facilita el debugging.
Código en acción
Antes: validación básica que no captura errores específicos de ML.
from pydantic import BaseModel
class PredictionRequest(BaseModel):
feature_vector: list[float]
probability: floatDespués: validación personalizada para datos ML.
from pydantic import BaseModel, field_validator, ValidationError
from typing import List
class MLPredictionRequest(BaseModel):
feature_vector: List[float]
probability: float
model_version: str
@field_validator('feature_vector')
@classmethod
def validate_feature_dimension(cls, v):
if len(v) != 10: # Supongamos que tu modelo espera 10 características
raise ValueError('El vector de características debe tener exactamente 10 elementos')
return v
@field_validator('probability')
@classmethod
def validate_probability_range(cls, v):
if not 0 <= v <= 1:
raise ValueError('La probabilidad debe estar entre 0 y 1')
return v
@field_validator('model_version')
@classmethod
def validate_model_version(cls, v):
allowed_versions = ['v1.0', 'v2.0', 'v3.0']
if v not in allowed_versions:
raise ValueError(f'Versión de modelo no válida. Permitidas: {allowed_versions}')
return v
# Uso en FastAPI
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.post("/predict")
async def predict(request: MLPredictionRequest):
try:
# Tu lógica de predicción aquí
return {"prediction": "éxito", "data": request.dict()}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))Errores comunes
- Validar solo en el endpoint: No delegues toda la validación a la lógica dentro de tu función FastAPI. Usa Pydantic para validar temprano y mantener el código limpio.
- Mensajes de error genéricos: En lugar de "valor inválido", especifica qué falló, como "La característica X debe ser positiva". Esto ayuda en monitoreo.
- Ignorar el contexto de ML: No valides solo tipos; considera distribuciones, valores atípicos o relaciones entre características si es crítico para tu modelo.
- Sobrecargar validadores: Evita lógica compleja o llamadas a bases de datos en validadores; mantenlos simples y rápidos para no afectar la latencia de la API.
- No probar casos límite: Asegúrate de probar entradas en los bordes de tus reglas, como probabilidades de 0 o 1, para evitar errores sutiles.
Checklist de dominio
- ¿Definiste validadores personalizados para al menos dos reglas específicas de tus datos ML (ej., rangos, dimensiones)?
- ¿Los mensajes de error son descriptivos y útiles para debugging en producción?
- ¿Probaste tu validación con datos incorrectos para asegurar que se rechazan adecuadamente?
- ¿Integraste la validación Pydantic con FastAPI, devolviendo códigos de error HTTP 422 para entradas inválidas?
- ¿Documentaste las reglas de validación para que otros equipos (ej., frontend) conozcan los requisitos?
- ¿Consideraste el rendimiento? Los validadores no deben añadir latencia significativa.
- ¿Usaste
field_validatorovalidatorcorrectamente según la versión de Pydantic?
Implementa validación personalizada para un modelo de clasificación de imágenes
En este ejercicio, crearás un endpoint FastAPI para un modelo de clasificación de imágenes que valide entradas personalizadas usando Pydantic. Sigue estos pasos:
- Crea un nuevo archivo Python, e importa FastAPI, Pydantic y las bibliotecas necesarias.
- Define un modelo Pydantic llamado
ImagePredictionRequestcon campos:image_id(string),pixel_data(lista de listas de enteros, representando una imagen 28x28), yconfidence_threshold(float). - Añade validadores personalizados:
- Para
pixel_data: valida que tenga exactamente 28 filas y 28 columnas, y que cada valor esté entre 0 y 255 (valores de píxel típicos). - Para
confidence_threshold: valida que esté entre 0.5 y 1.0, ya que tu modelo solo devuelve predicciones confiables por encima de 0.5. - Para
image_id: valida que comience con 'img_' y tenga al menos 5 caracteres.
- Para
- Crea un endpoint POST
/classifyque acepteImagePredictionRequesty devuelva un JSON simulado, como{"class": "gato", "confidence": 0.8}. - Prueba tu API con datos válidos e inválidos usando curl o una herramienta como Postman, verificando que los errores se manejen correctamente.
- Recuerda usar
@field_validatorde Pydantic v2 o@validatorde v1, dependiendo de tu versión. - En el validador de
pixel_data, itera sobre las filas y columnas para verificar dimensiones y rangos. - Usa
raise ValueError('mensaje')en los validadores para rechazar entradas inválidas.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.