Machine Learning Ops (MLOps): deploy de modelos em produção

1. Fundamentos do MLOps e o Ciclo de Vida do Modelo

Machine Learning Operations (MLOps) é um conjunto de práticas que visa unificar o desenvolvimento de modelos de machine learning com sua operação contínua em produção. Diferentemente do DevOps tradicional, o MLOps precisa lidar com a natureza experimental e não determinística dos modelos, além do versionamento de dados, parâmetros e experimentos.

Enquanto o DevOps foca em código e infraestrutura, o MLOps adiciona camadas de complexidade como:
- Versionamento de datasets e features
- Rastreamento de experimentos e hiperparâmetros
- Monitoramento de deriva de dados e conceitos
- Retreinamento automatizado

O ciclo de vida de um modelo em MLOps compreende:
1. Preparação e validação de dados
2. Treinamento e registro de experimentos
3. Validação e teste do modelo
4. Deploy em produção
5. Monitoramento contínuo
6. Retreinamento e re-deploy

2. Infraestrutura e Versionamento para Modelos

Para garantir rastreabilidade e reprodutibilidade, ferramentas como MLflow, DVC e Kubeflow são fundamentais. O versionamento de dados pode ser feito com DVC:

# Exemplo de versionamento de dados com DVC
dvc init
dvc add dados/treino.csv
git add dados/treino.csv.dvc .gitignore
git commit -m "Adiciona dataset de treino v1.0"
dvc push

Para modelos, utilizamos Model Registries:

# Registro de modelo no MLflow
import mlflow

with mlflow.start_run():
    mlflow.log_param("learning_rate", 0.01)
    mlflow.log_metric("accuracy", 0.95)
    mlflow.sklearn.log_model(model, "modelo_xgboost")
    mlflow.register_model("runs:/<run_id>/modelo_xgboost", "ChurnPrediction")

A infraestrutura como código (IaC) com Terraform permite provisionar clusters Kubernetes de forma declarativa:

resource "kubernetes_namespace" "mlops" {
  metadata {
    name = "ml-producao"
  }
}

resource "kubernetes_deployment" "model_serving" {
  metadata {
    name = "model-serve"
    namespace = kubernetes_namespace.mlops.metadata[0].name
  }
  spec {
    replicas = 3
    selector {
      match_labels = {
        app = "model-serve"
      }
    }
    template {
      metadata {
        labels = {
          app = "model-serve"
        }
      }
      spec {
        container {
          image = "registry.exemplo.com/modelo:v1.2.3"
          name  = "model"
          resources {
            limits = {
              cpu    = "2"
              memory = "4Gi"
            }
          }
        }
      }
    }
  }
}

3. Pipelines de CI/CD para Machine Learning

Um pipeline de CI/CD para ML deve incluir etapas de validação de dados, treinamento, teste e deploy. Exemplo com GitHub Actions:

name: MLOps Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  train-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Validar dados
      run: python scripts/validate_data.py

    - name: Treinar modelo
      run: python scripts/train.py

    - name: Testar modelo
      run: python scripts/test_model.py --threshold 0.85

    - name: Registrar no MLflow
      run: python scripts/register_model.py

    - name: Deploy canário
      run: kubectl set image deployment/model-serve model=registry.exemplo.com/modelo:${{ github.sha }}

Estratégias de deploy incluem:
- Blue-Green: duas versões completas, tráfego trocado instantaneamente
- Canário: liberação gradual para uma fração dos usuários
- Rolling update: substituição progressiva de pods

4. Estratégias de Deploy de Modelos em Produção

Para inferência em tempo real, APIs REST com FastAPI são eficientes:

from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import numpy as np

app = FastAPI()
modelo = joblib.load("modelo_churn.pkl")

class Cliente(BaseModel):
    idade: int
    renda: float
    tempo_conta: int

@app.post("/predict")
async def predict(cliente: Cliente):
    features = np.array([[cliente.idade, cliente.renda, cliente.tempo_conta]])
    proba = modelo.predict_proba(features)[0][1]
    return {"probabilidade_churn": round(proba, 4), "risco": "alto" if proba > 0.5 else "baixo"}

Para inferência em lote (batch), utilizamos jobs agendados:

# Script de batch inference
import pandas as pd
from datetime import datetime

clientes = pd.read_parquet("dados/clientes_dia.parquet")
previsoes = modelo.predict_proba(clientes)
clientes["score_churn"] = previsoes[:, 1]
clientes.to_parquet(f"resultados/predict_{datetime.now().date()}.parquet")

Em Kubernetes, configuramos scaling horizontal automático:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: model-serve-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: model-serve
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

5. Monitoramento e Governança Contínua

O monitoramento vai além de métricas de infraestrutura. Precisamos detectar deriva de dados (data drift) e de conceito (concept drift):

# Exemplo com Evidently AI
from evidently.report import Report
from evidently.metric_preset import DataDriftPreset

referencia = pd.read_parquet("dados/referencia.parquet")
atual = pd.read_parquet("dados/producao.parquet")

drift_report = Report(metrics=[DataDriftPreset()])
drift_report.run(reference_data=referencia, current_data=atual)
drift_report.save_html("relatorios/drift_$(date).html")

if drift_report.as_dict()["metrics"][0]["result"]["drift_score"] > 0.1:
    print("ALERTA: Data drift detectado!")

Métricas essenciais:
- Acurácia e F1-score (quando labels chegam)
- Latência p50/p99 da API
- Throughput (requisições por segundo)
- Taxa de degradação comparada ao baseline

6. Segurança, Privacidade e Compliance em MLOps

Gerenciamento de segredos com Kubernetes Secrets:

apiVersion: v1
kind: Secret
metadata:
  name: ml-secrets
type: Opaque
stringData:
  MLFLOW_TRACKING_URI: "https://mlflow.internal:5000"
  DB_PASSWORD: "senha_segura_42"
  MODEL_API_KEY: "sk-prod-abc123"

Para conformidade com LGPD/GDPR, implementamos explicabilidade:

import shap

explainer = shap.TreeExplainer(modelo)
shap_values = explainer.shap_values(cliente_df)
print(f"Feature mais impactante: {cliente_df.columns[shap_values.argmax()]}")

Proteção contra ataques adversarial inclui validação de entrada e sanitização de dados de treino.

7. Ferramentas e Ecossistema de MLOps

O ecossistema atual oferece opções para diferentes necessidades:

  • Kubeflow: orquestração completa de pipelines em Kubernetes
  • MLflow: gerenciamento de experimentos e modelos
  • Seldon Core: deploy e monitoramento avançado
  • BentoML: empacotamento e deploy simplificado
  • Serviços gerenciados: AWS SageMaker, Google Vertex AI, Azure ML

Tendências para 2025 incluem:
- MLOps serverless com Knative e AWS Lambda
- Edge ML para inferência em dispositivos IoT
- Modelos fundacionais (LLMs) em produção com ferramentas como LangServe e vLLM


Referências