Concepto clave
En el despliegue de modelos de ML, containerización no es solo empaquetar código, sino encapsular todo el entorno de ejecución: dependencias, librerías, sistema operativo y el modelo entrenado. Imagina que tu modelo es una planta delicada: Docker es la maceta que contiene tierra, nutrientes y agua específicos, mientras Kubernetes es el invernadero que gestiona múltiples macetas, asegurando que cada planta reciba luz y agua automáticamente.
Para un sistema de recomendación, la arquitectura debe separar claramente el servicio de inferencia (que responde a peticiones) del entrenamiento del modelo (que se ejecuta periódicamente). Esto permite actualizar el modelo sin interrumpir el servicio, similar a cómo un restaurante renueva su menú en la cocina mientras sigue sirviendo platos en el comedor.
Cómo funciona en la práctica
Vamos a construir un sistema de recomendación de películas paso a paso. Primero, definimos los componentes:
- API REST: Endpoint que recibe user_id y devuelve recomendaciones
- Modelo: Algoritmo de filtrado colaborativo entrenado
- Base de datos: Almacena ratings y perfiles de usuarios
- Orquestador: Kubernetes gestiona réplicas y balanceo de carga
El flujo: cuando un usuario visita la plataforma, su navegador envía una petición HTTP a nuestra API. El contenedor con el modelo carga los pesos entrenados, realiza la inferencia y devuelve las 10 películas recomendadas en formato JSON. Kubernetes monitorea la carga y escala automáticamente si hay muchas peticiones simultáneas.
Código en acción
Primero, definimos la estructura del proyecto:
# Estructura del proyecto
movie_recommender/
├── Dockerfile
├── requirements.txt
├── app.py
├── model/
│ ├── train_model.py
│ └── model.pkl
└── kubernetes/
├── deployment.yaml
└── service.yamlAhora, el archivo app.py con la API Flask:
from flask import Flask, request, jsonify
import pickle
import numpy as np
app = Flask(__name__)
# Cargar modelo al iniciar
with open('model/model.pkl', 'rb') as f:
model = pickle.load(f)
@app.route('/recommend', methods=['POST'])
def recommend():
data = request.json
user_id = data.get('user_id')
# Simular inferencia (en realidad usarías el modelo cargado)
recommendations = model.predict(user_id)
return jsonify({
'user_id': user_id,
'recommendations': recommendations.tolist(),
'model_version': '1.0'
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)Errores comunes
- Modelo demasiado grande para el contenedor: Incluir datasets completos en la imagen Docker. Solución: Separar datos del modelo, usando volúmenes o almacenamiento externo.
- Variables de entorno hardcodeadas: Credenciales de base de datos en el código. Solución: Usar ConfigMaps y Secrets de Kubernetes.
- Falta de health checks: Kubernetes no sabe si el modelo está listo. Solución: Implementar endpoints /health y /ready en la API.
- Versionado incorrecto: Actualizar modelo sin cambiar versión. Solución: Sistema de versionado semántico para modelos y APIs.
- Recursos insuficientes: No definir límites de CPU/memoria. Solución: Especificar requests y limits en el deployment.
Checklist de dominio
- ¿Tu Dockerfile tiene múltiples stages para reducir el tamaño final?
- ¿El modelo se carga una vez al iniciar el contenedor, no por cada petición?
- ¿Tienes separados los Dockerfiles para entrenamiento e inferencia?
- ¿Los endpoints de la API siguen convenciones RESTful?
- ¿El deployment de Kubernetes tiene readinessProbe y livenessProbe?
- ¿Los logs incluyen request_id para trazar peticiones?
- ¿Has probado el escalado horizontal con HPA (Horizontal Pod Autoscaler)?
Containerizar un modelo de recomendación básico
Objetivo: Crear una imagen Docker funcional para un sistema de recomendación y desplegarla localmente.
- Crea un directorio
movie_recommendercon la estructura mostrada en la lección - En
requirements.txt, añade:flask==2.3.0, numpy==1.24.0, scikit-learn==1.3.0 - Crea un Dockerfile que:
- Use python:3.9-slim como base
- Copie requirements.txt e instale dependencias
- Copie el código de la aplicación
- Exponga el puerto 5000
- Ejecute
python app.pyal iniciar
- Genera un modelo dummy en
train_model.pyque guarde un array numpy comomodel.pkl - Construye la imagen:
docker build -t movie-recommender:v1 . - Ejecuta el contenedor:
docker run -p 5000:5000 movie-recommender:v1 - Prueba la API con curl:
curl -X POST http://localhost:5000/recommend -H "Content-Type: application/json" -d '{"user_id": 123}'
- Usa COPY --chown en el Dockerfile para evitar problemas de permisos
- Para el modelo dummy, puedes usar pickle.dump(np.random.rand(10, 10), file)
- Si el puerto 5000 está ocupado, usa -p 5001:5000 en docker run
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.