Automatiza MLOps con GitHub Actions: CI/CD para ML

Automatiza MLOps con GitHub Actions: CI/CD para ML

En la ingeniería de software moderna, las tuberías de CI/CD son la base de la entrega de software eficiente y fiable. Sin embargo, cuando el activo que se está entregando es un modelo de aprendizaje automático, el paradigma tradicional de CI/CD resulta insuficiente. El ciclo de vida único de los modelos de aprendizaje automático – que abarca la validación de datos, el entrenamiento y la supervisión del rendimiento – requiere un enfoque especializado conocido como MLOps.

Este artículo proporciona una guía completa y práctica para directores de ingeniería (CTOs) y ingenieros senior, que abarca la arquitectura e implementación de un robusto pipeline CI/CD para modelos de aprendizaje automático utilizando GitHub Actions. Pasaremos de la teoría a ejemplos de código y patrones arquitectónicos concretos que pueden implementar directamente. El enfoque estará en automatizar todo el proceso, desde el commit de código hasta un endpoint de modelo contenedorizado y listo para producción.

🎧
Listen to this and other episodes of The 4Geeks Podcast on your favorite podcasting platform, including Apple Podcast, Spotify and YouTube.

Visión general arquitectónica: La línea de flujo de CI/CD de MLOps

El principal desafío en MLOps es gestionar el conjunto de código, datos y modelo como una sola y coherente unidad. Nuestra plataforma debe automatizar procesos que a menudo son manuales y propensos a errores, garantizando la reproducibilidad y el cumplimiento.

Servicios de Ingeniería de LLM y IA

Ofrecemos un conjunto completo de soluciones impulsadas por IA, incluyendo IA generativa, visión artificial, aprendizaje automático, procesamiento del lenguaje natural y automatización con IA.

Learn more

La arquitectura que construiremos se activa mediante un git push a la rama principal y consta de dos etapas principales orquestadas por GitHub Actions:

  1. Integración Continua (CI) y Formación Continua (CT): Esta fase es responsable de validar todo el sistema de aprendizaje automático. Incluye:
    • Validación del código: Revisión y ejecución de pruebas unitarias en el código fuente del modelo (p. ej., preprocesamiento de datos, ingeniería de características).
    • Validación de datos: Asegurar que los datos de entrenamiento cumplen con un esquema y distribución esperados.
    • Entrenamiento y evaluación del modelo: Entrenar el modelo en un conjunto de datos versionado y evaluar su rendimiento en función de métricas predefinidas (p. ej., precisión, F1-score). Si el rendimiento cumple con el umbral, el modelo entrenado se versiona y se guarda.
    • Generación de artefactos: El modelo serializado, las métricas de rendimiento y cualquier otro activo necesario se empaquetan como artefactos de construcción.
  2. Entrega Continua (CD): Esta fase se centra en empaquetar y desplegar el modelo validado.
    • Contenedorización: Crear una imagen de Docker que contenga el modelo y una capa de servicio (p. ej., una aplicación FastAPI).
    • Publicación de la imagen: Subir la imagen de Docker versionada a un registro de contenedores (p. ej., GitHub Container Registry, Docker Hub, AWS ECR).
    • Despliegue: Desplegar automáticamente el contenedor en un entorno de destino, como un clúster de Kubernetes o un servicio de contenedor en la nube.

Esta separación garantiza que solo los modelos que pasan por rigurosas pruebas automatizadas se consideren para su implementación, minimizando el riesgo de introducir errores en el entorno de producción.

Implementación paso a paso

Vamos a proceder con una implementación práctica. Utilizaremos un modelo simple de Scikit-learn, pero los principios son directamente aplicables a modelos más complejos construidos con TensorFlow, PyTorch u otros frameworks.

Estructura del repositorio

Un repositorio bien organizado es fundamental para un proyecto de MLOps de gestión.

/
├── .github/
│   └── workflows/
│       └── ci-cd.yml         # GitHub Actions workflow definition
├── data/                     # Raw data (managed by DVC)
├── models/                   # Output for serialized models
├── src/
│   ├── __init__.py
│   ├── train.py              # Model training and evaluation script
│   └── serve.py              # API server for model inference
├── tests/
│   └── test_model.py         # Unit tests for our code
├── requirements.txt          # Python dependencies
└── Dockerfile                # Docker definition for the serving image

Control de versiones de datos y modelos con DVC

Gestionar grandes conjuntos de datos y archivos de modelos directamente en Git es poco práctico. Utilizaremos Control de Versiones de Datos (DVC) para ello. DVC almacena punteros a los datos/modelos en Git, mientras que los archivos reales se almacenan en el almacenamiento de objetos remoto (como S3, GCS o incluso una unidad de red compartida).

Para inicializar DVC y realizar un seguimiento de nuestros datos:

# Install DVC
pip install dvc dvc-s3

# Initialize DVC in your Git repository
dvc init

# Configure remote storage
dvc remote add -d my-remote s3://your-bucket-name/dvc-store

# Add and track data
dvc add data/my_dataset.csv
git add data/my_dataset.csv.dvc .dvc/config
git commit -m "feat: Add initial dataset with DVC"
dvc push

Este proceso garantiza que cada commit de Git tenga una versión de los datos sobre los que se entrenó, que es permanente e inmutable.

El flujo de trabajo de CI/CD: ci-cd.yml

Este archivo es el núcleo de nuestra automatización. Define las tareas, los pasos y los disparadores para nuestro flujo de trabajo. Colócalo en github.com/tu_usuario/ci-cd.yml.

name: MLOps CI/CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'

      - name: Install Dependencies
        run: |
          pip install -r requirements.txt
          pip install dvc[s3] # Install DVC with S3 support

      - name: Authenticate with AWS for DVC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

      - name: Pull Data with DVC
        run: dvc pull

      - name: Run Unit Tests
        run: pytest tests/

      - name: Train and Evaluate Model
        id: train
        run: python src/train.py

      - name: Upload Model Artifact
        uses: actions/upload-artifact@v4
        with:
          name: model
          path: |
            models/classifier.joblib
            metrics.json

  deploy:
    needs: build-and-test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Download Model Artifact
        uses: actions/download-artifact@v4
        with:
          name: model
          path: ./

      # We assume the model is downloaded to a directory matching its name
      # Move files to their correct locations for the Docker build context
      - name: Prepare Docker Build Context
        run: |
          mkdir -p models
          mv model/classifier.joblib models/
          mv model/metrics.json ./

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and Push Docker Image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}

      # Deployment step would go here. Example for a generic script execution.
      # - name: Deploy to Production
      #   run: ./scripts/deploy.sh ghcr.io/${{ github.repository }}:${{ github.sha }}

Puntos clave en el flujo de trabajo:

  • Información confidencial: Utilizamos secrets.AWS_ACCESS_KEY_ID y secrets.GITHUB_TOKEN para la autenticación segura. Estos deben configurarse en la sección "Settings > Secrets y variables > Actions" de su repositorio.
  • Dependencias: La tarea de construcción y pruebas depende del éxito de la tarea de despliegue (needs: build-and-test), lo que garantiza que solo se desplieguen modelos validados.
  • Artefactos: actions/upload-artifact y actions/download-artifact son cruciales para pasar el modelo entrenado entre tareas, ya que cada tarea se ejecuta en un entorno limpio e aislado.
  • Etiquetado de imágenes: Etiquetamos la imagen de Docker con el SHA del commit de Git (${{ github.sha }}). Esto proporciona un seguimiento explícito desde una imagen de contenedor desplegada hasta la versión exacta de código y datos que la produjeron.

Servicios de Ingeniería de LLM y IA

Ofrecemos una completa gama de soluciones impulsadas por la IA, que incluyen IA generativa, visión artificial, aprendizaje automático, procesamiento del lenguaje natural y automatización basada en IA.

Learn more

Código de la aplicación principal

Guía de entrenamiento del modelo (src/train.py)

Este script gestiona el entrenamiento, la evaluación y la serialización.

# src/train.py
import pandas as pd
import joblib
import json
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 1. Load Data
df = pd.read_csv('data/my_dataset.csv')

# Dummy preprocessing
X = df.drop('target', axis=1)
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 2. Train Model
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# 3. Evaluate Model
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Model Accuracy: {accuracy}")

# 4. Save Metrics
with open('metrics.json', 'w') as f:
    json.dump({'accuracy': accuracy}, f)

# Performance Gate: Fail the build if accuracy is below a threshold
MINIMUM_ACCURACY = 0.85
if accuracy < MINIMUM_ACCURACY:
    raise Exception(f"Model accuracy {accuracy} is below the threshold of {MINIMUM_ACCURACY}")

# 5. Serialize Model
joblib.dump(model, 'models/classifier.joblib')

print("Training complete. Model and metrics saved.")

Dockerfile para el servicio de modelos

Este Dockerfile crea una imagen de contenedor con nuestra aplicación FastAPI y el modelo entrenado.

# Dockerfile
FROM python:3.9-slim

WORKDIR /app

# Copy dependencies and install them
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the application and model
COPY ./src /app/src
COPY ./models /app/models

# Expose port and define command
EXPOSE 8000
CMD ["uvicorn", "src.serve:app", "--host", "0.0.0.0", "--port", "8000"]

Servidor de API (src/serve.py)

Una sencilla aplicación FastAPI para cargar el modelo y realizar predicciones.

# src/serve.py
import joblib
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List

app = FastAPI(title="ML Model Server")

# Define the input data schema
class ModelInput(BaseModel):
    features: List[float]

# Load the trained model from the file system
model = joblib.load("models/classifier.joblib")

@app.post("/predict")
def predict(data: ModelInput):
    """Makes a prediction based on the input features."""
    prediction = model.predict([data.features])
    return {"prediction": int(prediction[0])}

@app.get("/")
def read_root():
    return {"status": "ML model server is running."}

Consideraciones Avanzadas y Próximos Pasos

Esta plataforma proporciona una base sólida, pero un sistema de MLOps de nivel de producción implica más componentes.

🎧
Listen to this and other episodes of The 4Geeks Podcast on your favorite podcasting platform, including Apple Podcast, Spotify and YouTube.
  • Registro de modelos: Para una gobernanza de modelos más robusta, integre un registro de modelos como MLflow o Weights & Biases. El pipeline de CI publicaría el modelo en el registro, que a su vez gestionaría el versionado, la etapa (por ejemplo, "staging", "producción") y el almacenamiento de metadatos. El pipeline de CD, a continuación, recuperaría una versión específica del modelo del registro para su implementación.
  • Almacenes de características: En entornos complejos, un almacén de características centralizado Almacén de características (por ejemplo, Feast, Tecton) garantiza la consistencia en la ingeniería de características entre el entrenamiento y la inferencia, mitigando las diferencias entre el entorno online y offline.
  • Monitoreo continuo: La implementación no es el paso final. Implemente el monitoreo tanto para métricas operativas (latencia, tasa de error) como para métricas de rendimiento del modelo (drift de concepto, drift de datos). Si el rendimiento disminuye, esto debería generar una alerta o iniciar una pipeline de reentrenamiento.
  • Estrategias de implementación sofisticadas: En lugar de una implementación directa, considere versiones en "canario" o pruebas A/B. El pipeline de CD puede extenderse para implementar el nuevo modelo en un pequeño subconjunto del tráfico, comparar su rendimiento con el modelo existente y promover o revertir automáticamente según los resultados.

Conclusión

Al automatizar el ciclo de vida del aprendizaje automático con una plataforma CI/CD, transformamos el desarrollo de modelos de una actividad artesanal en un proceso de ingeniería disciplinado y repetible. Utilizando GitHub Actions, hemos demostrado una forma práctica, potente y accesible para implementar esta capacidad.

Este enfoque reduce significativamente el tiempo de lanzamiento de nuevos modelos, mejora la colaboración entre los equipos de ciencia de datos e ingeniería, y proporciona la gobernanza y la reproducibilidad necesarias para sistemas de ML de nivel empresarial. El marco presentado aquí no es simplemente un ejercicio teórico, sino un plan directo para construir una práctica de MLOps más madura dentro de su organización.

Preguntas frecuentes

¿Qué es MLOps y cómo se diferencia de los procesos CI/CD tradicionales?

MLOps es un enfoque especializado para las tuberías CI/CD adaptado a la vida útil única de los modelos de aprendizaje automático. A diferencia de los procesos CI/CD tradicionales, que se centran principalmente en el código, MLOps gestiona el conjunto de código, datos y modelos como una unidad coherente. Automatiza procesos únicos para el aprendizaje automático, como la validación de datos, el entrenamiento de modelos y la evaluación del rendimiento.

¿Cómo automatizan las acciones de GitHub una tubería de aprendizaje automático?

Las acciones de GitHub automatizan la tubería de ML utilizando un archivo YAML de flujo de trabajo, que se activa por eventos de Git (como un push). Este flujo de trabajo define una serie de tareas. Una tarea de Integración Continua/Entrenamiento Continuo (CI/CT) valida el código, prueba los datos y entrena el modelo. Si es exitoso, una tarea de Entrega Continua (CD) toma el control para construir una imagen de Docker del modelo, subirla a un registro y desplegarla como un punto final listo para la producción.

¿Por qué es importante el versionado de datos y modelos en MLOps?

El versionado de datos y modelos es crucial para la reproducibilidad y el control. Dado que los archivos de datos y los modelos grandes no pueden almacenarse directamente en Git, se utilizan herramientas como Data Version Control (DVC). DVC almacena archivos de puntero pequeños en Git que hacen referencia a archivos de datos grandes en el almacenamiento remoto (como S3). Esto garantiza que cada commit de Git tenga una versión inmutable de los datos en los que se entrenó, lo que hace que cada experimento sea rastreable y reproducible.