Sexto post da série. No anterior, automatizamos provisioning de clusters GPU. Agora entra a parte que começa depois do hardware pronto: como um modelo sai do “funciona no meu notebook” e vira algo que roda em produção com SLA.

tl;dr: Modelo não é arquivo solto. Registre versão, valide em staging, publique com canary e deixe rollback pronto.

O modelo que chegou sem certidão de nascimento

Um data scientist manda uma mensagem no canal do time com um link pra um shared drive: “Aqui está o modelo. É um checkpoint PyTorch de 15 GB. Precisamos em produção até sexta.”

Você abre a pasta e encontra um único arquivo: model_final_v2_FIXED.pt.

Começa a perguntar. Qual versão? Treinado com quais dados? Plano de rollback se as predições derem errado? SLAs de latência e throughput? Qual framework e versão de CUDA? As respostas são vagas. “É o último. Funciona na minha máquina. Só coloca atrás de uma API.”

Esse filme você já viu antes, só com atores diferentes. Developers costumavam te dar um binário compilado e dizer “deploya isso”. Esse caos levou a indústria a construir container registries, pipelines CI/CD, semantic versioning e rollback automatizado. Modelos não são diferentes. São artefatos: grandes, versionados, dependentes de ambiente. Merecem o mesmo lifecycle management.

Modelos são artefatos: trate como tal

Se você já puxou uma imagem de um container registry, tageou um release no Git, ou promoveu um build de staging pra produção, já entende os conceitos básicos de lifecycle de modelo.

Conceito de InfraEquivalente ML
Container imageModel checkpoint (arquivo de pesos)
Container registry (ACR)Model registry (Azure ML, MLflow)
CI buildTraining run
CD release pipelineModel deployment pipeline
Dockerfile (build manifest)Training config (hyperparameters, data version, framework version)
Artifact signatureModel provenance e lineage
Blue/green deploymentA/B testing com traffic splitting

Um arquivo de modelo sem metadados é como uma container image sem tag. Você pode deployar, mas não reproduzir, auditar, ou fazer rollback seguro.

Model registries

O registry vira a referência oficial pros modelos da organização. Ele guarda o artefato e os metadados que importam: versão, métricas de training, lineage e status de deployment.

Azure Machine Learning Model Registry

# Registrar modelo de arquivo local
az ml model create \
  --name sentiment-classifier \
  --version 3 \
  --path ./outputs/model.pt \
  --type custom_model \
  --tags task=sentiment framework=pytorch \
  --resource-group ml-prod-rg \
  --workspace-name ml-prod-ws

# Listar versões do modelo
az ml model list \
  --name sentiment-classifier \
  --resource-group ml-prod-rg \
  --workspace-name ml-prod-ws \
  --output table

# Ver lineage: qual job produziu esse modelo
az ml model show \
  --name sentiment-classifier \
  --version 3 \
  --resource-group ml-prod-rg \
  --workspace-name ml-prod-ws \
  --query "properties.jobName" \
  --output tsv

MLflow (open-source, multi-framework)

MLflow é o padrão open-source pra experiment tracking e model management. Framework-agnostic, wrapa PyTorch, TensorFlow, scikit-learn. Azure ML integra nativamente com MLflow.

# Servidor MLflow local (dev/test)
mlflow server \
  --backend-store-uri sqlite:///mlflow.db \
  --default-artifact-root ./mlruns \
  --host 0.0.0.0 --port 5000

# Registrar modelo via CLI
mlflow models register \
  --model-uri runs:/<run-id>/model \
  --name sentiment-classifier

# Promover pra produção
mlflow models set-alias \
  --name sentiment-classifier \
  --version 3 \
  --alias Production

Container Registry pra model serving

Quando modelos são servidos via containers (Triton, TorchServe, FastAPI wrapper), a imagem vira o artefato deployável:

# Build e push do container de serving
az acr build \
  --registry mlmodelsacr \
  --image sentiment-classifier:v3 \
  --file Dockerfile.serve .

# Verificar imagem
az acr repository show-tags \
  --name mlmodelsacr \
  --repository sentiment-classifier \
  --output table

Qual registry usar?

CritérioAzure ML RegistryMLflow RegistryACR (Container)
Melhor praTimes Azure-nativeMulti-cloud / OSSServing containerizado
VersionamentoBuilt-in, imutávelBuilt-in com stagesImage tags
Lineage trackingProfundo (jobs, data, env)Run-levelDockerfile only
Infra overheadManagedSelf-hosted ou Azure MLManaged (ACR)
Quando evitarNecessidade multi-cloudPrecisa deep Azure integrationModelos sem containers

Cuidado: Nunca use shared file systems ou blob storage como “registry”. Sem versões imutáveis e APIs de metadata, você acaba com model_final_v2_FIXED_actually_final.pt.

CI/CD pra modelos: o pipeline de promoção

Pipeline de promoção de modelosDiagrama com os stages DEV, STAGING e PRODUCTION, mostrando responsabilidades e infraestrutura de cada etapa.DEVTrainTrackVersionInfraGPU ComputeBlob StorageExperiment TrackingSTAGINGValidateBenchmarkSecurityInfraInference InfraTest Data AccessIsolated NetworkPRODUCTIONServeMonitorAuto-rollbackInfraLoad BalancedMulti-replicaProd NetworkSLA-bound

Validation gates entre stages

GateO que verificaInfra necessária
Accuracy thresholdMétricas ≥ baseline (ex: F1 > 0.92)Storage de test dataset, compute pra avaliação
Latency benchmarkP95 ≤ SLA (ex: < 200ms)Infra de load testing
Throughput testRequests/sec ≥ target sob cargaLoad generator (k6, Locust)
Security scanSem deps vulneráveis, artefato assinadoContainer scanning (Defender)
Cost estimateCusto projetado dentro do budgetCost modeling baseado no SKU

GitHub Actions workflow pra deploy de modelo

Assumindo que o endpoint e os arquivos base de deployment já estão versionados no repositório:

name: Model Deployment Pipeline

on:
  workflow_dispatch:
    inputs:
      model_name:
        description: 'Model name in registry'
        required: true
      model_version:
        description: 'Model version to deploy'
        required: true

env:
  AZURE_RG: ml-prod-rg
  AZURE_ML_WS: ml-prod-ws

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: Download model from registry
        run: |
          az ml model download \
            --name ${{ inputs.model_name }} \
            --version ${{ inputs.model_version }} \
            --download-path ./model \
            --resource-group ${{ env.AZURE_RG }} \
            --workspace-name ${{ env.AZURE_ML_WS }}
      - name: Run accuracy validation
        run: |
          python scripts/validate_model.py \
            --model-path ./model \
            --test-data ./data/holdout.csv \
            --min-accuracy 0.92

  deploy-staging:
    needs: validate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: Deploy to staging endpoint
        run: |
          az ml online-deployment create \
            --file ./.azureml/staging-deployment.yml \
            --set name=staging-${{ inputs.model_version }} \
            --set endpoint_name=sentiment-staging \
            --set model=azureml:${{ inputs.model_name }}:${{ inputs.model_version }} \
            --set instance_type=Standard_NC4as_T4_v3 \
            --set instance_count=1 \
            --resource-group ${{ env.AZURE_RG }} \
            --workspace-name ${{ env.AZURE_ML_WS }}

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: Deploy canary (10% traffic)
        run: |
          az ml online-deployment create \
            --file ./.azureml/prod-deployment.yml \
            --set name=prod-${{ inputs.model_version }} \
            --set endpoint_name=sentiment-prod \
            --set model=azureml:${{ inputs.model_name }}:${{ inputs.model_version }} \
            --set instance_type=Standard_NC4as_T4_v3 \
            --set instance_count=2 \
            --resource-group ${{ env.AZURE_RG }} \
            --workspace-name ${{ env.AZURE_ML_WS }}

          az ml online-endpoint update \
            --name sentiment-prod \
            --set traffic.prod-stable=90 traffic.prod-${{ inputs.model_version }}=10 \
            --resource-group ${{ env.AZURE_RG }} \
            --workspace-name ${{ env.AZURE_ML_WS }}

Tradução infra ↔ AI: Isso é seu pipeline blue/green, mas pra model weights ao invés de container images. O --set traffic.* funciona exatamente como weighted routing no Azure Front Door: você shifta percentual de requests pro novo modelo enquanto o antigo continua servindo.

Suas responsabilidades em cada stage

Como engenheiro de infra, você acaba cobrindo o pipeline inteiro:

  • Compute provisioning: GPU node pools pra training (Dev), VMs de inference pra validação (Staging), clusters GPU com autoscaling pra serving (Prod)
  • Networking: VNets isoladas pra staging, private endpoints pro model registry, load balancer pra traffic splitting
  • Storage: High-throughput blob pra dados de training, low-latency pra model artifacts, retention policies pra versões antigas
  • Secrets management: Key Vault pra API keys, managed identity pra auth do pipeline, RBAC pro model registry
  • Monitoring: Dashboards de deployment health, alerting de latência, triggers de rollback automatizado

Traffic splitting: canary e blue/green pra modelos

Deploy de modelo não é evento binário. Você vai mudando o tráfego aos poucos:

PadrãoComo funcionaQuando usar
Canary5-10% do tráfego pro novo modelo, aumenta gradualmenteDefault pra a maioria dos deployments
Blue/GreenAmbiente completo paralelo, switch instantâneoQuando precisa rollback instantâneo
ShadowNovo modelo recebe tráfego real mas respostas são descartadasQuando quer testar sem impactar usuários
# Promover canary pra 100% após validação
az ml online-endpoint update \
  --name sentiment-prod \
  --set traffic.prod-v3=100 \
  --resource-group ml-prod-rg \
  --workspace-name ml-prod-ws

No próximo post

Agora que modelos estão deployados e servindo tráfego, como saber se estão saudáveis? Se outro model_final_v2_FIXED.pt aparecer na sexta, você já tem registry, validação e rollback pra não entrar em pânico. No próximo post: monitoramento e observabilidade pra AI, incluindo model drift, GPU metrics, e como detectar degradação antes que o usuário perceba.

Leitura complementar