← Blog

MLOps na prática: MLflow, DVC e versionamento de modelos

2024-07-08MLOpsMLflowDVC

O que é MLOps e por que importa

MLOps é a disciplina de levar modelos de machine learning para produção com o mesmo rigor que engenharia de software aplica a aplicações web. No notebook, tudo funciona: você carrega um CSV, treina um modelo, olha o AUC e segue em frente. Em produção, surgem perguntas que o notebook não responde: qual versão dos dados treinou esse modelo? Quais hiperparâmetros foram usados? Como reproduzir o resultado daqui a seis meses?

Sem versionamento e rastreabilidade, cada retreino vira uma aposta. O modelo novo pode ter piorado e ninguém percebe até o negócio reclamar. MLOps resolve isso com três pilares: versionar dados, registrar experimentos e promover artefatos de forma controlada.

Duas ferramentas cobrem a maior parte do caminho em projetos Python: DVC para dados e pipelines, MLflow para tracking e model registry. Este post mostra como usá-las juntas.

O ciclo MLOps em quatro etapas

Todo projeto MLOps maduro passa por um ciclo repetível:

  1. Dados versionados — snapshot rastreável do dataset de treino
  2. Treino reprodutível — script com parâmetros fixos e seed
  3. Tracking de experimentos — métricas, parâmetros e artefatos logados
  4. Deploy do artefato — modelo aprovado promovido para produção
Ciclo MLOps

DVC versiona datasets e features. Cada commit de dados fica rastreável e reprodutível — você sabe exatamente com qual snapshot o modelo foi treinado.

in → dvc pull · data/v1out → data/v1.dvc

Cada etapa produz um artefato que alimenta a próxima. Quebrar a cadeia em qualquer ponto — dados sem versão, treino manual, métricas em planilha — é o que transforma MLOps em buzzword.

Versionando dados com DVC

DVC (Data Version Control) trata datasets como Git trata código. Em vez de commitar CSVs de 2 GB no repositório, você commita um arquivo .dvc que aponta para o storage remoto (S3, GCS, local).

# Inicializar DVC no projeto
dvc init
dvc remote add -d storage s3://meu-bucket/dvc-store

# Versionar um dataset
dvc add data/train.parquet
git add data/train.parquet.dvc data/.gitignore
git commit -m "add training data v1"
dvc push

Para reproduzir o ambiente de treino em outra máquina ou no CI:

git checkout abc1234        # commit com data v1
dvc pull                    # baixa o dataset correspondente
python src/train.py         # treina com os mesmos dados

O arquivo dvc.yaml define o pipeline como stages encadeados:

stages:
  prepare:
    cmd: python src/prepare.py
    deps:
      - src/prepare.py
      - data/raw/transactions.csv
    outs:
      - data/processed/train.parquet

  train:
    cmd: python src/train.py
    deps:
      - src/train.py
      - data/processed/train.parquet
    outs:
      - models/model.pkl
    metrics:
      - metrics.json

dvc repro executa apenas os stages que mudaram — igual a um Makefile para ML.

Registrando experimentos com MLflow

MLflow Tracking loga tudo que importa de cada execução de treino: parâmetros, métricas, artefatos e tags.

import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_auc_score

mlflow.set_tracking_uri("http://localhost:5000")
mlflow.set_experiment("credit-score")

with mlflow.start_run(run_name="rf-baseline-v2"):
    params = {"n_estimators": 200, "max_depth": 8, "class_weight": "balanced"}

    model = RandomForestClassifier(**params, random_state=42)
    model.fit(X_train, y_train)

    auc = roc_auc_score(y_test, model.predict_proba(X_test)[:, 1])
    mlflow.log_params(params)
    mlflow.log_metric("auc_roc", auc)
    mlflow.log_metric("auc_pr", average_precision_score(y_test, model.predict_proba(X_test)[:, 1]))
    mlflow.sklearn.log_model(model, "model", registered_model_name="credit-score")

A UI do MLflow (mlflow ui) permite comparar runs lado a lado — essencial para decidir qual modelo promover.

O Model Registry adiciona estágios: NoneStagingProduction. Promover um modelo é uma ação auditável, não um cp model.pkl /prod/.

Integrando DVC e MLflow

O fluxo ideal combina as duas ferramentas:

import subprocess
import mlflow

# Garantir dados versionados antes do treino
subprocess.run(["dvc", "repro", "train"], check=True)

with mlflow.start_run():
    mlflow.log_param("data_version", subprocess.check_output(
        ["git", "rev-parse", "HEAD"]
    ).decode().strip())
    # ... treino e log de métricas

Logar o hash do commit Git e a versão DVC como parâmetros do MLflow cria rastreabilidade completa: para qualquer run, você sabe exatamente qual código e qual dataset foram usados.

Exemplo prático: estrutura de projeto

mlops-credit/
├── data/
│   ├── raw/              # gitignored, rastreado por DVC
│   └── processed/
├── models/               # gitignored, output do pipeline
├── src/
│   ├── prepare.py
│   └── train.py
├── dvc.yaml
├── dvc.lock
├── metrics.json
├── requirements.txt
└── .github/workflows/    # CI (próximo post)

Regras simples que evitam dor:

  • Nunca commitar datasets brutos no Git — use DVC
  • Nunca treinar sem logar no MLflow — mesmo em experimentos descartáveis
  • metrics.json versionado pelo DVC permite comparar métricas entre commits

Além do básico: pontos de atenção

Armadilhas comuns ao adotar MLOps:

  • DVC sem remote — versionar localmente não ajuda se o disco morre; configure S3 ou equivalente
  • MLflow sem servidormlflow ui local funciona para um dev; em time, use MLflow server ou Databricks
  • Logar tudo menos o preprocessador — o artefato de produção é o pipeline completo, não só o classificador
  • Métricas offline sem validação temporal — em crédito, split por data é obrigatório
  • Ignorar dvc.lock — commitar o lock garante reprodutibilidade exata do pipeline

Boas práticas:

  • Taggear releases no Git quando promover modelo para produção
  • Automatizar dvc repro + treino no CI (coberto no post de GitHub Actions)
  • Documentar no README como reproduzir qualquer experimento em três comandos

Conclusão

MLOps começa com versionamento: dados via DVC, experimentos via MLflow, código via Git. O ciclo Dados → Treino → Tracking → Deploy transforma cada retreino de aposta em processo auditável.

O próximo passo natural é automatizar esse ciclo no CI/CD — o tema do post sobre GitHub Actions para pipelines de ML.

Referencias

  1. DVC — Documentação oficial
  2. DVC — Pipelines
  3. MLflow — Tracking
  4. MLflow — Model Registry
  5. MLflow — Scikit-learn integration
  6. Google — Rules of Machine Learning (Rule #32: Reuse code)