Containerizar el Modelo y sus Dependencias

Video
25 min~4 min lectura

Reproductor de video

Concepto clave

Containerizar un modelo de ML significa empaquetarlo junto con todas sus dependencias en una unidad estandarizada llamada contenedor. Imagina que tu modelo es una planta delicada: necesita tierra especifica, agua con cierto pH, y una temperatura controlada. En lugar de intentar recrear estas condiciones en cada jardin donde la quieras plantar, la pones en un invernadero portatil (el contenedor) que ya tiene todo lo necesario. Asi, puedes moverla a cualquier lado y siempre crecera igual.

Docker es la herramienta que construye estos invernaderos. Usa un Dockerfile como plano de construccion para especificar: que sistema operativo base usar (como Ubuntu), que paquetes de Python instalar (scikit-learn, pandas), donde copiar tu codigo del modelo, y que comando ejecutar para iniciar el servicio. El resultado es una imagen Docker inmutable que contiene tu modelo entrenado, el codigo de inferencia, y el entorno de ejecucion, todo en uno.

Como funciona en la practica

Vamos a containerizar un modelo de recomendacion simple basado en filtrado colaborativo. Sigue estos pasos:

  1. Preparar los archivos: Tenemos un modelo entrenado (model.pkl), un script de inferencia (predict.py), y un archivo de requisitos (requirements.txt).
  2. Escribir el Dockerfile: Creamos un archivo llamado Dockerfile que define las capas de la imagen.
  3. Construir la imagen: Ejecutamos docker build -t recomendador:1.0 . para crear la imagen.
  4. Probar localmente: Corremos docker run -p 5000:5000 recomendador:1.0 para verificar que el servicio funciona.
  5. Subir al registro: Etiquetamos y empujamos la imagen a Docker Hub o un registro privado para usar en Kubernetes.

Codigo en accion

Primero, veamos el script de inferencia predict.py que usara nuestro modelo:

import pickle
import numpy as np
from flask import Flask, request, jsonify

app = Flask(__name__)

# Cargar el modelo al iniciar
with open('model.pkl', 'rb') as f:
    model = pickle.load(f)

@app.route('/predict', methods=['POST'])
def predict():
    data = request.get_json()
    user_features = np.array(data['features']).reshape(1, -1)
    prediction = model.predict(user_features)
    return jsonify({'recommendation': int(prediction[0])})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Ahora, el Dockerfile que containeriza todo:

# Usar una imagen base ligera de Python
FROM python:3.9-slim

# Establecer el directorio de trabajo
WORKDIR /app

# Copiar los archivos de requisitos e instalar dependencias
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copiar el modelo y el codigo
COPY model.pkl predict.py .

# Exponer el puerto que usa Flask
EXPOSE 5000

# Comando para ejecutar la aplicacion
CMD ["python", "predict.py"]

Errores comunes

  • Imagenes demasiado grandes: Usar imagenes base como python:3.9 (1GB+) en lugar de python:3.9-slim (200MB). Solucion: Siempre elige variantes slim o alpine para reducir tamaño y mejorar tiempos de despliegue.
  • No limpiar cache de pip: Dejar archivos temporales en la imagen. Mejora el Dockerfile con RUN pip install --no-cache-dir -r requirements.txt para ahorrar espacio.
  • Exponer puertos incorrectos: Flask corre en 5000 por defecto, pero si cambias el puerto en el codigo, debes actualizar EXPOSE y el mapeo en docker run.
  • Modelo no incluido en la imagen: Olvidar copiar el archivo .pkl con COPY. Verifica que todos los archivos necesarios esten listados en el Dockerfile.
  • Variables de entorno hardcodeadas: Poner paths o claves directamente en el codigo. Usa variables de entorno Docker para configuracion sensible.

Checklist de dominio

  1. ¿Puedes escribir un Dockerfile que instale dependencias Python desde requirements.txt?
  2. ¿Sabes construir una imagen Docker y etiquetarla con version?
  3. ¿Verificas que el contenedor funcione localmente antes de subirlo al registro?
  4. ¿Usas imagenes base optimizadas (slim/alpine) para reducir tamaño?
  5. ¿Expones correctamente los puertos que tu aplicacion usa?
  6. ¿Incluyes todos los archivos necesarios (modelo, codigo, configs) en la imagen?
  7. ¿Documentas el proceso de construccion y ejecucion para tu equipo?

Containeriza un modelo de regresion lineal para API REST

En este ejercicio, containerizaras un modelo de regresion lineal simple que predice precios basado en caracteristicas. Sigue estos pasos:

  1. Descarga los archivos base: Crea un directorio de trabajo y dentro, guarda estos tres archivos:
    - model_linear.pkl (un modelo de sklearn LinearRegression ya entrenado)
    - app.py (codigo Flask similar al de la leccion, adaptado para regresion)
    - requirements.txt (con flask, scikit-learn, numpy)
  2. Escribe el Dockerfile: Crea un archivo Dockerfile que:
    - Use python:3.9-slim como imagen base
    - Establezca WORKDIR en /app
    - Copie requirements.txt y ejecute pip install
    - Copie model_linear.pkl y app.py
    - Exponga el puerto 5000
    - Use CMD para ejecutar app.py
  3. Construye la imagen: Ejecuta docker build -t regresor:1.0 . en tu terminal, dentro del directorio.
  4. Ejecuta el contenedor: Corre docker run -p 5000:5000 regresor:1.0 y verifica que el servicio este activo.
  5. Prueba la API: Usa curl o Postman para enviar una peticion POST a http://localhost:5000/predict con un JSON como {"features": [100, 5]}. Deberias recibir una prediccion numerica.
  6. Optimiza: Modifica el Dockerfile para reducir el tamaño de la imagen, por ejemplo, limpiando cache de apt si usas paquetes del sistema.
Pistas
  • Asegurate de que requirements.txt incluya scikit-learn==1.0.2 y flask==2.0.3 para compatibilidad.
  • Si el contenedor falla al iniciar, revisa los logs con docker logs para ver errores de importacion.
  • Para reducir el tamaño, considera usar --no-cache-dir en pip install y combinar RUN comandos en uno solo.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.