Apostila completa de MLOps: do modelo à produção
Treinar um modelo com boa métrica no conjunto de teste é a parte fácil e conhecida. O que trava a maioria dos projetos de ML é o resto: versionar dados e experimentos, evitar vazamento, servir com latência aceitável, detectar quando o modelo apodrece em produção e re-treinar sem quebrar tudo. Esta apostila percorre o ciclo de vida completo de ML em produção — sempre com o olho no que empresas realmente pedem em vagas de ML Engineer e MLOps.
O que é MLOps e por que tantos modelos nunca chegam à produção
Objetivo: entender por que ML em produção falha por motivos de engenharia, não de modelagem, e conhecer o ciclo de vida e os níveis de maturidade de MLOps.
1.1 O código do modelo é a menor parte do sistema
Um resultado clássico da literatura de engenharia de ML (o paper "Hidden Technical Debt in Machine Learning Systems", do Google): a caixa que contém o algoritmo de ML é minúscula perto de tudo que a cerca — coleta e validação de dados, infraestrutura de features, gestão de configuração, servir, monitorar, orquestrar. É nesse entorno que os projetos morrem.
┌──────────────────────────────────────────────────────────┐
│ coleta │ validação │ config │ infra de │ gestão de │
│ de dados │ de dados │ │ serving │ recursos │
├───────────┼───────────┼────────┴────────────┼─────────────┤
│ extração │ ┌─────┐ │ monitoramento │ ferramentas│
│ de feat. │ │ ML │ │ │ de análise │
│ │ └─────┘ │ orquestração / gerenciamento │
└───────────┴───────────┴───────────────────────────────────┘
a caixa "ML" é ~5% do código de um sistema de ML em produção
MLOps é a aplicação de práticas de DevOps + engenharia de dados + governança ao ciclo de vida de ML: automatizar, versionar, testar, monitorar e reproduzir — para que um modelo saia do notebook, entre em produção e permaneça útil.
1.2 Por que ML quebra diferente de software
| Software tradicional | Sistema de ML |
|---|---|
| Comportamento definido por código | Comportamento definido por código + dados + parâmetros aprendidos |
| Testes determinísticos (passou/falhou) | Métricas estatísticas; "correto" é uma distribuição |
| Degrada só se o código muda | Degrada sozinho quando o mundo muda (drift), sem ninguém tocar em nada |
| Reproduzir bug = mesmo input | Reproduzir = mesmo código + mesmos dados + mesmo ambiente + mesma seed |
| Deploy = nova versão do binário | Deploy = novo modelo, e o pipeline de dados/features tem que casar treino e produção |
1.3 O ciclo de vida de ML
negócio ▶ dados ▶ features ▶ experimentação ▶ avaliação ▶ registro ▶ deploy ▶ monitorar
▲ │
└──────────── retraining acionado por drift / novos dados / SLA ─────┘
É um loop, não uma linha. E cada etapa precisa ser versionada e automatizável, senão o loop não fecha de forma confiável.
1.4 Níveis de maturidade (modelo do Google)
| Nível | Como é | Sinal de que você está aqui |
|---|---|---|
| MLOps 0 — manual | Notebooks, deploy manual, sem CI/CD, sem monitoramento; entrega esporádica | "Roda no meu Jupyter"; ninguém sabe qual versão está em produção |
| MLOps 1 — pipeline automatizado | Pipeline de treino reproduzível e disparável, validação de dados e modelo, entrega contínua do modelo, monitoramento com trigger de retraining | Um commit ou um alarme de drift re-treina e reavalia sozinho |
| MLOps 2 — CI/CD de pipelines | O próprio pipeline é versionado e entregue por CI/CD; múltiplos experimentos e modelos em paralelo, com governança | Times fazem deploy de novos pipelines de ML como fazem deploy de microserviços |
A maioria das empresas com ML em produção está no nível 0 ou tentando chegar ao 1. O erro comum é comprar uma plataforma de nível 2 antes de ter versionamento de dados e experiment tracking básicos. Suba um degrau por vez: reprodutibilidade → pipeline automatizado → CI/CD do pipeline.
MLOps Engineer e ML Engineer (com forte componente de produção) são vagas com muito mais demanda que oferta, porque a maioria dos cientistas de dados não domina a parte de engenharia. Perfis vêm de DevOps/SRE, de backend e de data science que "virou de engenharia". Pergunta clássica de abertura: "Por que a maioria dos modelos de ML não chega à produção?" — a resposta cita o débito técnico oculto, o drift, e a lacuna de reprodutibilidade e de pipeline.
✏️ Exercício 1 — Diagnóstico de maturidade
Uma empresa treina modelos em notebooks, salva o .pkl num bucket, e um engenheiro copia o arquivo para o servidor de API quando o cientista pede. Não há monitoramento. Qual o nível de MLOps, quais os três maiores riscos, e qual o primeiro passo?
Gabarito: Nível 0. Riscos: (1) impossível reproduzir um modelo antigo (não se sabe quais dados/código/params geraram aquele .pkl); (2) o modelo pode estar degradando há meses sem ninguém saber (sem monitoramento); (3) deploy manual é propenso a erro e não tem rollback claro. Primeiro passo: reprodutibilidade — experiment tracking (MLflow) registrando dados+código+params+métricas de cada treino, e versionamento de dados (DVC). Só depois automatizar o pipeline e adicionar monitoramento.
Dados para ML: versionamento, splits e vazamento
Objetivo: tratar dados como artefato versionado, fazer splits que não mentem, e reconhecer o data leakage — o erro que faz um modelo brilhar no teste e falhar na vida real.
2.1 Versionamento de dados
"Qual dataset gerou este modelo?" tem que ter resposta exata. Git versiona código; para dados grandes, ferramentas dedicadas:
| Ferramenta | Abordagem |
|---|---|
| DVC | Ponteiros no git para arquivos/pastas em storage remoto; pipelines reprodutíveis com dvc repro |
| lakeFS | Versionamento estilo git para o data lake inteiro (branch, commit, merge sobre S3) |
| Delta Lake / Iceberg (time travel) | Consultar a tabela "como estava" em um snapshot/timestamp — versionamento implícito |
| Hash + snapshot imutável | Congelar o dataset de treino como Parquet imutável com um hash registrado no experiment tracker |
O mínimo aceitável: cada treino registra um identificador imutável do dataset (hash, versão DVC, snapshot Iceberg) junto com o código e os parâmetros.
2.2 Splits que não mentem
- Split temporal para dados temporais: se o modelo vai prever o futuro, treine no passado e valide no futuro. Split aleatório em série temporal vaza informação do futuro para o treino e infla a métrica.
- Split por grupo: se há múltiplas linhas por entidade (usuário, paciente, loja), o mesmo grupo não pode aparecer em treino e teste — senão o modelo "reconhece" a entidade, não o padrão. Use
GroupKFold. - Estratificação por classe (e por segmentos importantes) para o teste representar a realidade.
- Conjunto de teste "trancado": um holdout que você olha pouco, para não fazer overfitting de decisões nele. O tuning acontece na validação.
2.3 Data leakage o bug nº 1 de modelos que "iam bem"
Vazamento é quando informação que não estará disponível no momento da predição entra no treino. O modelo aprende a "trapacear", a métrica fica linda, e na produção ele desaba.
| Tipo | Exemplo | Como evitar |
|---|---|---|
| Target leakage | Usar data_pagamento para prever "vai pagar?" — só existe depois do fato | Para cada feature, perguntar "isso existe no instante t da predição?" |
| Train-test contamination | Normalizar/imputar com estatísticas do dataset inteiro antes de dividir | Fit do pré-processamento só no treino; Pipeline do scikit-learn dentro do CV |
| Temporal leakage | Feature agregada com janela que cruza o ponto de predição | Point-in-time correctness (Módulo 4); janelas que só olham para trás |
| Duplicatas / near-duplicates | Mesmo registro (ou quase) em treino e teste | Deduplicar antes do split; split por grupo |
| Leakage de identificador | Um ID que correlaciona com o alvo por acaso de coleta | Remover IDs; auditar features com importância suspeitamente alta |
Métrica de validação quase perfeita, ou uma única feature com importância dominante que "não deveria saber tanto". Antes de comemorar, faça a pergunta do point-in-time: no instante em que eu preciso prever, eu teria mesmo esse valor? Se a resposta é "não" ou "não com esse valor", é vazamento.
Perguntas: "O que é data leakage e dê três exemplos", "Por que não se deve fazer split aleatório em série temporal?", "Por que o scaler deve ser ajustado só no treino?", "Como você versiona dados?". Contar uma história real de "a métrica estava boa demais e era vazamento" costuma valer mais que a definição decorada.
✏️ Exercício 2 — Ache o vazamento
Modelo para prever churn no próximo mês. Features incluídas: plano, uso_medio_90d, numero_de_tickets_suporte, data_cancelamento (nula se ativo), desconto_retencao_aplicado, meses_como_cliente. Métrica de validação: AUC 0,99. Aponte os problemas.
Gabarito: (1) data_cancelamento é o próprio alvo disfarçado — target leakage grosseiro. (2) desconto_retencao_aplicado normalmente é oferecido porque o cliente sinalizou saída ou já pediu cancelamento — leakage temporal, só existe perto do evento. (3) Possível leakage em numero_de_tickets_suporte se contar tickets abertos durante o processo de cancelamento — precisa ser cortado no instante t. AUC 0,99 é o sintoma. Correção: definir claramente o instante da predição e só usar features com valores conhecidos até ali.
Experimentação e reprodutibilidade
Objetivo: registrar cada experimento de forma que qualquer resultado possa ser reproduzido e comparado — a base sobre a qual todo o resto de MLOps se apoia.
3.1 Os quatro pilares da reprodutibilidade
Um resultado de ML só é reproduzível se você fixou e registrou os quatro:
- Código — commit hash exato (e do repositório de pipelines, não só do notebook).
- Dados — versão/hash do dataset de treino e de validação.
- Ambiente — versões de bibliotecas (lockfile), versão de CUDA/driver, container image com digest.
- Configuração — hiperparâmetros, seed aleatória, flags, splits.
Mesmo fixando a seed, operações em GPU podem ser não determinísticas (ordem de redução em paralelo). Para reprodutibilidade estrita: torch.use_deterministic_algorithms(True), cudnn.deterministic=True, variável CUBLAS_WORKSPACE_CONFIG — aceitando alguma perda de performance. Para a maioria dos casos, registrar a seed e aceitar variância pequena entre runs é suficiente; documente qual dos dois você escolheu.
3.2 Experiment tracking
| Ferramenta | Nota |
|---|---|
| MLflow | Padrão open source; Tracking + Models + Registry + Projects. Roda local ou como serviço. |
| Weights & Biases | Forte em visualização, sweeps de hiperparâmetro, colaboração; SaaS (tem self-hosted). |
| DVC / DVCLive, Neptune, Comet, ClearML | Alternativas com ênfases diferentes (git-native, escala, automação). |
# MLflow: um treino instrumentado — tudo que você vai precisar para reproduzir e comparar import mlflow mlflow.set_experiment("churn-v3") with mlflow.start_run(run_name="xgb-baseline"): mlflow.log_params({"max_depth": 6, "eta": 0.1, "seed": 42}) mlflow.log_param("dataset_hash", dataset_sha) # versão dos dados mlflow.set_tag("git_sha", git_sha) model = train(X_train, y_train, params) metrics = evaluate(model, X_val, y_val) # por segmento também! mlflow.log_metrics(metrics) mlflow.log_artifact("feature_importance.png") mlflow.xgboost.log_model(model, "model", signature=infer_signature(X_val, model.predict(X_val))) # schema de entrada/saída
3.3 Boas práticas
- Um experimento = uma hipótese. Não mude cinco coisas e registre um run — você não saberá o que causou a diferença.
- Métricas por segmento sempre, não só a agregada. E salve a matriz de confusão / curvas, não só o número.
- Baseline honesto: modelo trivial (média, classe majoritária, regra de negócio atual). Se o ML não bate isso com folga, não vale a complexidade.
- Sweeps de hiperparâmetro registrados (Optuna, W&B Sweeps, Ray Tune) — com orçamento definido, não busca infinita.
- O notebook é rascunho. O que vai para produção é código em módulos, testável e versionado; o experiment tracker é a memória institucional.
Perguntas: "O que é preciso para reproduzir um experimento de ML?" (código + dados + ambiente + config, todos versionados), "Para que serve um experiment tracker?", "Como você compara duas abordagens de forma justa?" (mesmo split, mesma métrica por segmento, baseline, e atenção à variância entre seeds). Ter usado MLflow ou W&B em um projeto real é praticamente pré-requisito.
✏️ Exercício 3 — O run que não reproduz
Seis meses depois, você precisa reproduzir um modelo em produção. O MLflow tem os hiperparâmetros e a métrica, mas o retreino dá um resultado bem diferente. Liste quatro causas prováveis e o que faltou registrar.
Gabarito: (1) Os dados mudaram — não foi registrado o hash/versão do dataset, então você está treinando com dados novos. (2) Versões de biblioteca diferentes (sem lockfile / sem imagem com digest) — comportamento de XGBoost/sklearn muda entre versões. (3) Seed não registrada ou não fixada. (4) Código do pré-processamento evoluiu e não há o git_sha do pipeline, só do notebook. Faltou: dataset versionado, ambiente containerizado com digest, seed e git_sha do pipeline completo.
Feature Store e training-serving skew
Objetivo: entender o problema que a feature store resolve — features consistentes entre treino e produção, sem vazamento temporal — e quando ela vale a complexidade.
4.1 O problema: treino e produção calculam features diferente
No treino, você calcula gasto_medio_30d com um GROUP BY em SQL sobre dados históricos. Em produção, um engenheiro reimplementa o mesmo cálculo em Java, no caminho da requisição. As duas implementações divergem — arredondamento, fuso, tratamento de nulo, janela — e o modelo recebe em produção valores diferentes dos que viu no treino. Isso é training-serving skew, e degrada silenciosamente a performance.
4.2 O que uma feature store faz
| Componente | Função |
|---|---|
| Definição única de feature | A lógica de cada feature é escrita uma vez e usada por treino e produção — fim do skew |
| Offline store | Histórico completo (warehouse/lake) para gerar datasets de treino |
| Online store | Último valor de cada feature (Redis, DynamoDB) para servir com latência de milissegundos |
| Point-in-time join | Ao montar o dataset de treino, pega o valor da feature como era no instante do rótulo — sem vazamento temporal |
| Materialização | Job que calcula as features e popula o online store |
| Catálogo / reuso | Times descobrem e reaproveitam features já prontas |
Ferramentas: Feast (open source, o mais comum), Tecton, Hopsworks, Featureform, e as feature stores nativas de SageMaker / Vertex / Databricks.
4.3 Point-in-time correctness a razão de existir da feature store
Rótulo: "cliente X deu churn em 2026-03-15"
Feature: gasto_medio_30d
ERRADO → gasto_medio_30d calculado com dados até HOJE (inclui período pós-churn) → vazamento
CERTO → gasto_medio_30d como era em 2026-03-15 (só dados até ali) → point-in-time join
Fazer esse join corretamente à mão, para dezenas de features e milhões de rótulos com timestamps diferentes, é difícil e propenso a erro. É o principal valor técnico da feature store.
4.4 Você precisa de uma feature store?
| Vale a pena quando… | É overkill quando… |
|---|---|
| Vários modelos/times compartilham features | Um modelo, um time, features simples |
| Há serving online de baixa latência com features calculadas de eventos | Predição em batch, features vêm de uma tabela pronta |
| Skew treino-produção já causou incidente | Treino e serving usam o mesmo código Python sobre o mesmo dado |
| Features com janelas temporais e muitos rótulos com datas diferentes | Sem componente temporal relevante |
Antes de adotar uma feature store, o mínimo que resolve 70% do skew: uma única função de transformação (um pacote Python) importada tanto pelo pipeline de treino quanto pelo serviço de serving, com testes. Feature store entra quando reuso entre times, online serving e point-in-time viram dor real.
Perguntas: "O que é training-serving skew e como evitar?", "O que é point-in-time correctness?", "Diferença entre online e offline store", "Quando você NÃO usaria uma feature store?" (a resposta madura reconhece que é infraestrutura pesada e nem todo projeto precisa). Feast é o nome a conhecer.
✏️ Exercício 4 — Skew na prática
Um modelo de fraude usa num_transacoes_ultima_hora. No treino, essa feature vem de uma query no data warehouse. Em produção, é calculada por um serviço que consulta o Redis. A performance em produção está 15% pior que na validação, sem drift aparente nos dados de entrada. Hipótese e correção.
Gabarito: Provável training-serving skew: a query do warehouse e o serviço Redis definem "última hora" ou contam transações de forma diferente (fuso, transações pendentes vs confirmadas, janela deslizante vs fixa, atraso de materialização no Redis). Correção: uma definição única da feature (ideal: feature store com a mesma lógica alimentando offline e online, ou ao menos a mesma biblioteca de cálculo nos dois lados), mais um teste que compara o valor da feature calculado pelos dois caminhos para os mesmos eventos e alarme se divergir além de um limiar.
Model registry, versionamento e empacotamento
Objetivo: dar ao modelo um ciclo de vida gerenciado — registrado, versionado, com estágios de promoção, assinatura de schema e empacotamento portável.
5.1 O model registry
Um catálogo central de modelos treinados, cada um com: versão, métricas de avaliação, linhagem (qual run/dados/código o gerou), assinatura de entrada/saída, model card, e um estágio (None → Staging → Production → Archived). Substitui o "qual .pkl está no servidor?" por uma fonte de verdade consultável e auditável.
- Ferramentas: MLflow Model Registry, SageMaker Model Registry, Vertex AI Model Registry, W&B Model Registry.
- Promoção como decisão explícita: mover para "Production" exige aprovação e dispara (ou libera) o deploy. Reverter é mover o ponteiro de volta.
- Linhagem ligada: do modelo em produção você chega ao experimento, aos dados e ao commit que o produziram.
5.2 Assinatura e validação de schema
O modelo deve declarar o schema que espera (nomes, tipos, ordem das features) e o que produz. Assim, o serviço rejeita uma requisição malformada com erro claro em vez de gerar uma predição silenciosamente errada. MLflow infere isso com infer_signature; frameworks de serving validam na borda.
5.3 Empacotamento: formatos e portabilidade
| Formato / abordagem | Quando |
|---|---|
| Pickle / joblib | Rápido para sklearn interno; frágil (versão da lib, inseguro para artefato não confiável) |
| ONNX | Runtime único, independente de framework; ótimo para portar PyTorch/sklearn para produção e acelerar inferência |
| SavedModel / TorchScript | Nativo de TensorFlow / PyTorch, sem dependência do código de treino |
MLflow "flavor" + pyfunc | Empacota modelo + pré-processamento + dependências; interface uniforme predict() |
| Container com o modelo dentro | Imagem OCI com digest: reprodutível, roda igual em qualquer lugar; base do serving moderno |
O artefato de deploy precisa incluir o pré-processamento (encoders, scalers, imputers ajustados no treino) e as versões exatas das libs. Servir os pesos e reimplementar o pré-processamento "na mão" no serviço é a receita mais comum de skew. Empacote o pipeline inteiro (ex.: sklearn.Pipeline ou um pyfunc), não o estimador sozinho.
Perguntas: "Para que serve um model registry?", "O que é a assinatura de um modelo e por que importa?", "Quando usaria ONNX?", "O que precisa estar no artefato além dos pesos?" (pré-processamento + dependências). Descrever o fluxo run → registro → staging → produção → rollback mostra que você pensa em ciclo de vida, não em arquivo solto.
✏️ Exercício 5 — Desenhe a promoção
Defina o processo para promover um novo modelo de recomendação de "Staging" para "Production", incluindo os gates automáticos e o que permite rollback em minutos.
Gabarito (exemplo): Gates automáticos antes de permitir a promoção: (1) métrica offline no holdout ≥ baseline em produção, por segmento; (2) testes de schema/assinatura passam; (3) teste de carga: p99 de latência e throughput dentro do SLO; (4) teste de sanidade (predições em casos conhecidos); (5) checagem de fairness/enviesamento se aplicável. Promoção move o ponteiro no registry e dispara deploy canário (5% do tráfego) com monitor de métrica online + guardrails de negócio; sobe gradual se estável. Rollback: mover o ponteiro do registry de volta para a versão anterior (que continua empacotada e pronta) — deploy re-aponta em minutos, sem re-treino.
Servir modelos: batch, online e streaming
Objetivo: escolher o padrão de serving certo para o caso, e conhecer as ferramentas e os trade-offs de latência, throughput e custo.
6.1 Os três padrões
| Padrão | Como | Use quando |
|---|---|---|
| Batch (offline) | Job periódico gera predições para todos os registros e grava numa tabela; a aplicação lê a tabela | A predição pode ser pré-calculada e não muda a cada segundo: churn diário, lead scoring, recomendações "do dia", risco de carteira |
| Online (síncrono) | Serviço com endpoint REST/gRPC; a aplicação chama e espera a predição na hora | A predição depende de input do momento da requisição: fraude no checkout, precificação, busca, ranking personalizado ao vivo |
| Streaming | Consumidor lê eventos (Kafka/Kinesis), pontua e emite resultado no fluxo | Decisão contínua sobre eventos: detecção de anomalia em telemetria, scoring de transações em tempo real |
Batch é mais simples, mais barato e mais robusto: sem SLA de latência, sem serviço 24/7, fácil de testar e reprocessar. Só vá para online quando a predição realmente depender de dados que só existem no instante da requisição, ou quando o conjunto de entidades a pontuar é grande/imprevisível demais para pré-calcular.
6.2 Ferramentas de serving online
| Ferramenta | Nota |
|---|---|
| FastAPI + o modelo | Simples e direto para um modelo leve e baixo volume; você cuida de tudo (batching, métricas, escala) |
| BentoML | Empacota modelo + código em um "bento", gera imagem, serve com adaptive batching; bom equilíbrio DX/controle |
| KServe (Kubernetes) | Serving declarativo em K8s: autoscaling (inclusive scale-to-zero), canary, várias runtimes; padrão em plataformas grandes |
| NVIDIA Triton | Alta performance, multi-framework, batching dinâmico, execução em GPU concorrente; para inferência pesada/deep learning |
| Ray Serve | Serving escalável em Python, bom para pipelines de inferência com múltiplos passos/modelos |
| Endpoints gerenciados (SageMaker, Vertex) | Menos operação, mais custo e lock-in |
6.3 Latência, throughput e custo avançado
- Dynamic batching: agrupar requisições que chegam próximas em um lote para o modelo — aumenta throughput e uso de GPU ao custo de alguns ms de latência. Triton, BentoML e Ray Serve fazem isso.
- Otimização do modelo: quantização (INT8), pruning, distilação, compilação (ONNX Runtime, TensorRT, OpenVINO) — reduzem latência e custo, às vezes com perda pequena de métrica que você mede.
- Autoscaling: por RPS ou por profundidade de fila; scale-to-zero para modelos de uso esporádico; cuidado com cold start (carregar um modelo grande demora).
- CPU vs GPU: muitos modelos clássicos (árvores, regressão, embeddings pequenos) servem melhor e mais barato em CPU. GPU só quando o modelo exige.
- Caching: se a mesma entrada se repete (mesmo usuário, mesmo item), cachear a predição.
- SLOs de serving: p50/p95/p99 de latência, throughput, taxa de erro, saturação — monitorados como qualquer serviço.
Perguntas: "Batch, online ou streaming para [cenário]?" (saber justificar pela dependência de dados do momento e pelo SLA), "Como reduzir a latência de inferência?" (batching dinâmico, quantização, ONNX/TensorRT, CPU vs GPU, caching), "O que é cold start em serving e como mitigar?". KServe e Triton são os nomes de plataforma; BentoML aparece muito em vagas de startup.
✏️ Exercício 6 — Escolha o padrão
Para cada caso, escolha batch / online / streaming e justifique: (a) recomendação de produtos na home, personalizada, atualizada 1x/dia; (b) aprovação de limite de crédito no clique de "solicitar"; (c) detecção de transação anômala num fluxo de milhões/dia; (d) previsão de demanda por SKU para a semana.
Gabarito: (a) Batch — pré-calcula de noite, grava por usuário, a home lê a tabela. (b) Online — depende dos dados que o usuário acabou de informar e precisa de resposta imediata. (c) Streaming — decisão contínua sobre eventos que chegam num fluxo. (d) Batch — horizonte semanal, roda um job e grava as previsões.
CI/CD/CT: pipelines e testes de ML
Objetivo: automatizar o caminho do commit à produção com pipelines reprodutíveis, testes específicos de ML e treinamento contínuo (CT) acionado por eventos.
7.1 As três siglas
- CI (Continuous Integration): além de lint e testes de código, valida dados e modelo — schema, distribuição, métrica mínima, ausência de regressão.
- CD (Continuous Delivery): entrega o pipeline de treino e/ou o serviço de predição automaticamente até um ambiente, com aprovação para produção.
- CT (Continuous Training): re-treina automaticamente quando disparado — por agenda, por chegada de dados novos, ou por alarme de drift/queda de performance.
7.2 Orquestradores de pipeline de ML
| Ferramenta | Nota |
|---|---|
| Kubeflow Pipelines | Pipelines em K8s, cada passo um container; pesado, poderoso, cloud-agnóstico |
| Vertex AI Pipelines / SageMaker Pipelines | Gerenciados; menos operação, mais lock-in |
| Metaflow | DX excelente em Python, da máquina local à nuvem; origem Netflix |
| ZenML | Camada de abstração que conecta seu pipeline a vários backends (orquestrador, tracker, registry) |
| Airflow / Dagster / Prefect | Orquestradores gerais; ótimos para o pipeline de dados que alimenta o de ML (ver apostila de Engenharia de Dados) |
7.3 Testes específicos de ML
| Categoria | Exemplos |
|---|---|
| Testes de dados | Schema (tipos, colunas), faixas e distribuição esperadas, taxa de nulos, cardinalidade, ausência de duplicatas, detecção de skew treino-produção — Great Expectations, TFDV, pandera |
| Testes de modelo | Métrica ≥ limiar no holdout e por segmento; não regride vs modelo em produção; invariâncias ("mudar o nome não muda a predição de risco"); testes direcionais ("mais renda ⇒ não aumenta risco"); robustez a ruído; comportamento em casos extremos |
| Testes de infra | O pipeline de treino roda ponta a ponta com dados de brinquedo; o artefato carrega e serve; a API responde no formato certo; reprodutibilidade (mesmo input ⇒ mesma saída) |
| Testes de integração | Pré-processamento de treino == de serving (mesmo resultado); latência sob carga; contrato da API |
# Gate de CI: o modelo novo só passa se não regredir em NENHUM segmento importante def test_no_regression_by_segment(new_model, prod_model, val): for seg in ["br", "latam", "novo_cliente", "alto_valor"]: s = val[val.segment == seg] auc_new = roc_auc(s.y, new_model.predict_proba(s.X)[:, 1]) auc_prod = roc_auc(s.y, prod_model.predict_proba(s.X)[:, 1]) assert auc_new >= auc_prod - 0.01, f"regressão em {seg}: {auc_new:.3f} < {auc_prod:.3f}"
7.4 Continuous Training
- Gatilhos: agenda (semanal), volume de dados novos, alarme de drift/queda de métrica, evento de negócio (novo produto).
- O pipeline de CT: valida dados → treina → avalia (gates por segmento) → compara com produção → registra → (se passar) promove para staging → canary → produção. Falhou um gate? Para e alerta, não promove.
- Champion/challenger: o modelo em produção (champion) e o recém-treinado (challenger) rodam em paralelo; o challenger só vira champion se ganhar de forma consistente em dados reais.
- Cuidado com loop de feedback: se o modelo influencia os dados que ele mesmo vai usar para re-treinar (recomendação que enviesa cliques), o CT pode amplificar viés. Injete exploração / dados não enviesados.
Perguntas: "O que muda no CI de um projeto de ML em relação a software?" (testes de dados e de modelo, gates por segmento, checagem de regressão), "O que é Continuous Training e o que dispara?", "O que é champion/challenger?", "Dê exemplos de testes de modelo além de acurácia" (invariância, direcional, robustez, por segmento). Citar Great Expectations + um orquestrador (Kubeflow/Metaflow) cobre bem.
✏️ Exercício 7 — Projete o pipeline de CT
Um modelo de previsão de atraso de entrega deve se manter atualizado. Descreva o gatilho, os passos do pipeline de retraining e os gates que impedem um modelo pior de ir para produção.
Gabarito: Gatilho: agenda semanal + gatilho extra se o monitor de MAE em produção subir X% ou se detectar drift nas features de rota/clima. Passos: (1) validar dados novos (schema, distribuição, nulos, skew); (2) montar dataset com point-in-time; (3) treinar com os hiperparâmetros versionados (ou sweep curto); (4) avaliar no holdout temporal mais recente, por região e por faixa de distância; (5) comparar com o champion nos mesmos dados. Gates: MAE ≤ MAE do champion em todos os segmentos-chave; testes direcionais (mais distância ⇒ não reduz previsão de atraso); latência de inferência dentro do SLO; sem aumento de erro na cauda. Passou tudo → registra e vai para canário (champion/challenger por 1 semana); só promove se ganhar em dados reais.
Monitoramento em produção: drift e degradação
Objetivo: detectar que o modelo apodreceu — mesmo quando os rótulos reais só chegam semanas depois — distinguindo os tipos de drift e sabendo o que cada um exige.
8.1 Por que modelos apodrecem sozinhos
O modelo aprendeu uma relação entre features e alvo na distribuição de dados de um certo período. O mundo muda: comportamento de cliente, sazonalidade, concorrência, economia, um bug num sistema upstream. A relação que o modelo capturou deixa de valer, e a performance cai — sem ninguém ter mexido em uma linha de código.
8.2 Os tipos de drift
| Tipo | O que muda | Exemplo | Resposta |
|---|---|---|---|
| Data drift (covariate shift) | A distribuição das features P(X) | Entrou um segmento novo de clientes mais jovens | Muitas vezes re-treinar com dados recentes resolve |
| Concept drift | A relação P(Y\|X) | Pós-pandemia, o mesmo perfil passou a ter risco de crédito diferente | Re-treinar é obrigatório; pode exigir novas features |
| Label drift | A distribuição do alvo P(Y) | A taxa de fraude base triplicou | Recalibrar limiar; re-treinar |
| Upstream data change | Um sistema fonte mudou (unidade, encoding, bug) | Campo que vinha em reais passou a vir em centavos | Corrigir a fonte / o pipeline; não é "drift do mundo" |
8.3 Monitorar com e sem rótulos
O desafio real: em muitos problemas o rótulo verdadeiro só chega semanas depois (o cliente deu churn? a entrega atrasou? o empréstimo tornou-se inadimplente em 90 dias?). Você não pode esperar para saber que o modelo está ruim.
| Situação | O que monitorar |
|---|---|
| Sem rótulo (ainda) | Drift das features de entrada (PSI, KS, distância de distribuição); drift das predições (a distribuição de scores mudou?); taxa de outliers / fora do domínio de treino; performance estimada sem rótulo (NannyML); métricas de proxy de negócio |
| Com rótulo (atrasado) | Métrica real (AUC, MAE, precisão\@k) numa janela deslizante, por segmento; calibração; matriz de confusão ao longo do tempo |
- PSI (Population Stability Index) e teste KS: medem quanto a distribuição de uma feature (ou do score) mudou vs a referência de treino. Regra de bolso para PSI: < 0,1 estável, 0,1–0,25 atenção, > 0,25 mudança significativa.
- Ferramentas: Evidently (open source, relatórios e testes de drift/qualidade), NannyML (estimativa de performance sem rótulo), whylogs/WhyLabs, Arize, Fiddler, Grafana + métricas próprias.
- Alarme acionável: não alarme em cada micro-variação. Defina limiares por feature, janelas, e ligue o alarme a uma ação (investigar, recalibrar, disparar CT).
Uma feature pode driftar e o modelo continuar bom (se aquela feature pesa pouco, ou se o drift é compensado). E o modelo pode piorar sem drift óbvio nas entradas (concept drift puro). Drift de entrada é um sinal de alerta para investigar, não uma prova de degradação — confirme com performance (real ou estimada) antes de re-treinar por reflexo.
8.4 O loop de retraining
monitor detecta drift/queda ▶ investiga (é o mundo? é bug upstream?) ▶
se mundo mudou ▶ dispara CT (Módulo 7) ▶ novo modelo passa nos gates ▶
canary / champion-challenger ▶ promove ▶ atualiza a referência de monitoramento
Cadência de retraining: alguns sistemas re-treinam diariamente, outros trimestralmente. Deixe os dados decidirem — meça com que velocidade a performance decai e escolha a cadência que mantém dentro do SLO, sem re-treinar à toa (custo, risco de introduzir regressão).
Tema muito cobrado: "Diferença entre data drift e concept drift", "Como você monitora um modelo cujos rótulos só chegam em 60 dias?" (drift de entrada + drift de predição + estimativa de performance + proxies de negócio), "O que é PSI?", "Drift detectado: você re-treina na hora?" (não — investiga se é mudança real do mundo ou bug upstream; confirma impacto na performance). Evidently e NannyML são os nomes a citar.
✏️ Exercício 8 — Plano de monitoramento
Modelo de risco de inadimplência; o rótulo "inadimpliu" só se confirma 90 dias após a concessão. Liste o que você monitora nos primeiros 90 dias e o que dispara cada ação.
Gabarito: Sem rótulo: (1) PSI/KS das features principais vs distribuição de treino, por semana e por segmento; (2) distribuição do score de risco emitido (deslocou para cima/baixo?); (3) taxa de solicitações fora do domínio de treino / outliers; (4) estimativa de performance sem rótulo (NannyML); (5) proxies: taxa de aprovação, ticket médio, mix de canais. Ações: PSI > 0,25 numa feature importante → investigar fonte (bug upstream vs mudança real); deslocamento forte do score → revisar calibração e limiar; estimativa de AUC caindo → preparar CT. Aos 30/60/90 dias, à medida que rótulos parciais chegam (early defaults), começar a medir performance real por safra e comparar com o esperado.
Governança, escala e custo
Objetivo: operar ML sob auditoria e regulação — linhagem, model risk management, fairness e explicabilidade — e manter custo de treino e inferência sob controle em escala.
9.1 Linhagem e auditabilidade
Para qualquer predição em produção, você deve conseguir responder: qual versão do modelo a gerou, quais dados e código o treinaram, quem aprovou a promoção, quais features entraram e com que valores. Isso exige amarrar registry + experiment tracker + versionamento de dados + logs de predição. É requisito de auditoria em setores regulados (finanças, saúde, seguros) e a base de qualquer investigação de incidente.
9.2 Model Risk Management
- Model card / ficha do modelo: propósito, dados de treino e limitações, métricas por segmento, premissas, riscos conhecidos, condições de uso e de não-uso, plano de monitoramento.
- Validação independente: em setores regulados, um time separado do que construiu revisa premissas, dados, métricas e robustez antes do go-live (princípio "SR 11-7" em bancos).
- Inventário de modelos com classificação de risco (impacto × exposição) e cadência de revisão proporcional.
- Aprovações e trilha: quem promoveu, com base em quê, quando.
9.3 Fairness e explicabilidade avançado
- Fairness: medir métricas por grupo protegido (paridade demográfica, igualdade de oportunidade, taxas de erro balanceadas) — não existe uma definição única, e algumas são mutuamente exclusivas; a escolha é do contexto e do jurídico. Ferramentas: Fairlearn, AIF360. Cuidado com proxies (CEP correlaciona com raça).
- Explicabilidade global: importância de features, SHAP summary, PDP/ALE — para entender o modelo e detectar features suspeitas (leakage, proxy).
- Explicabilidade local: SHAP/LIME por predição — para justificar uma decisão individual (exigido, ex.: negativa de crédito) e para depurar.
- Registrar explicações junto das predições de alto impacto, para auditoria e contestação.
9.4 Custo em escala
| Frente | Alavancas |
|---|---|
| Treino | Spot/preemptible instances, checkpointing para retomar, early stopping, buscar hiperparâmetro com orçamento, treinar só quando o CT justifica, tamanho de dado vs ganho marginal |
| Inferência | Batch em vez de online quando possível, CPU em vez de GPU quando cabe, quantização/distilação, batching dinâmico, autoscaling e scale-to-zero, cache de predições, escolher o modelo mais barato que atinge o SLO de métrica |
| Dados | Amostragem inteligente para treino, formatos colunares, não materializar features que ninguém usa |
| Visibilidade | Custo por modelo / por predição / por time; alarme de anomalia de custo (ver apostila de FinOps) |
9.5 Estratégias de deploy (recapitulando com foco em risco)
| Estratégia | Ideia |
|---|---|
| Shadow | Modelo novo pontua o tráfego real sem servir; compara offline antes de expor |
| Canary | Fração pequena do tráfego; monitora métrica online e de negócio; sobe ou reverte |
| Blue-green | Duas versões prontas; troca instantânea do tráfego; rollback imediato |
| Champion/challenger (A/B) | Compara em produção com métrica de negócio; promove o vencedor consistente |
Vagas sênior e em setores regulados: "O que é um model card?", "Como garantir auditabilidade de uma predição?" (linhagem completa registry↔dados↔código↔logs), "Como você mede fairness e quais os cuidados?" (métricas por grupo, definições conflitantes, proxies), "Como reduzir o custo de inferência sem perder qualidade?". Conectar com governança (NIST AI RMF, EU AI Act) e com FinOps mostra amplitude.
✏️ Exercício 9 — Prepare para auditoria
Um regulador pede: "mostre como a predição de negativa de crédito do cliente #12345, feita em 2026-02-10, foi produzida e por quê". O que seu sistema precisa ter registrado para responder?
Gabarito: (1) Log da predição com timestamp, versão do modelo e ID do registry. (2) Do registry: o run que gerou o modelo, com hash do dataset de treino, git_sha do pipeline, hiperparâmetros, métricas por segmento e o model card. (3) As features exatas usadas na predição (valores no instante t) e sua origem/linhagem. (4) A explicação local (SHAP) daquela predição, registrada junto. (5) O limiar de decisão vigente e sua justificativa. (6) Trilha de aprovação da promoção do modelo. Sem versionamento de dados e sem log de features por predição, essa pergunta é irrespondível.
Mercado de trabalho: roadmap, entrevistas e portfólio
Objetivo: converter o conteúdo dos módulos anteriores em aprovação — perfis, roadmap, banco de perguntas com respostas e projetos que geram entrevista.
10.1 Os perfis que contratam
| Perfil | Foco | Vem de |
|---|---|---|
| ML Engineer | Constrói o sistema de ML fim a fim: dados, treino, serving, monitoramento | Data science + engenharia, ou backend + ML |
| MLOps Engineer | Plataforma e automação: pipelines, CI/CD/CT, registry, infra de serving, observabilidade | DevOps/SRE, platform engineering |
| ML Platform Engineer | Constrói a plataforma interna que os times de ML usam (self-service) | Infra + ML em escala |
| Applied Scientist / Research Engineer | Modelagem forte + capacidade de levar a produção | Pesquisa + engenharia |
10.2 Roadmap de estudo (10–12 semanas)
| Semanas | Foco | Entregável |
|---|---|---|
| 1–2 | Reprodutibilidade: MLflow, versionamento de dados (DVC), splits corretos, leakage (Módulos 1–3) | Um projeto de ML com experiment tracking e dados versionados |
| 3 | Empacotamento e registry: pipeline sklearn completo, assinatura, model registry, ONNX (Módulo 5) | Modelo registrado com estágios e model card |
| 4 | Feature engineering reproduzível e (opcional) Feast; skew (Módulo 4) | Mesma lógica de feature em treino e serving, com teste de igualdade |
| 5–6 | Serving: FastAPI → BentoML → KServe; batch vs online; latência (Módulo 6) | Endpoint de predição com testes de carga e métricas |
| 7–8 | Pipelines e CI/CD/CT: um orquestrador (Metaflow/Kubeflow) + testes de dados/modelo no CI (Módulo 7) | Pipeline que treina, avalia com gates por segmento e registra |
| 9–10 | Monitoramento: Evidently/NannyML, drift, alarme, loop de retraining (Módulo 8) | Dashboard de drift + simulação de drift acionando o CT |
| 11–12 | Governança e custo (Módulo 9); consolidação e escrita do portfólio | Repositório público end-to-end + artigo técnico |
Base necessária: Python sólido, SQL, Docker, git, noções de Kubernetes e de uma nuvem (AWS ou GCP). CI (GitHub Actions) e IaC básico (Terraform) ajudam muito.
10.3 Banco de perguntas de entrevista (com a resposta que aprova)
Júnior/pleno — "O que é MLOps e por que ele existe?"
É a aplicação de DevOps + engenharia de dados + governança ao ciclo de vida de ML, para levar modelos do notebook à produção e mantê-los úteis. Existe porque o código do modelo é ~5% do sistema (débito técnico oculto), porque modelos degradam sozinhos quando o mundo muda (drift), e porque reproduzir um resultado de ML exige versionar dados, ambiente e config, não só código.
Pleno — "O que é data leakage? Dê exemplos."
É usar no treino informação que não estará disponível no momento da predição, inflando a métrica. Exemplos: target leakage (feature derivada do alvo, tipo data_pagamento para prever pagamento); contaminação treino-teste (scaler ajustado no dataset inteiro antes do split); leakage temporal (janela de agregação que cruza o instante da predição). Teste: para cada feature, "eu teria esse valor no instante t?".
Pleno — "O que é training-serving skew e como evitar?"
É quando o cálculo de features difere entre treino (ex.: SQL no warehouse) e produção (ex.: código no serviço), fazendo o modelo receber valores inconsistentes com o que viu. Evita-se com uma definição única de feature usada pelos dois caminhos — feature store, ou no mínimo uma biblioteca compartilhada — e um teste que compara os valores calculados pelos dois lados.
Pleno/sênior — "Diferença entre data drift e concept drift"
Data drift: muda a distribuição das features P(X) — ex.: novo perfil de clientes. Concept drift: muda a relação entre features e alvo P(Y|X) — ex.: o mesmo perfil passa a ter risco diferente após um choque econômico. Data drift às vezes se resolve re-treinando com dados recentes; concept drift quase sempre exige re-treino e pode exigir novas features. Ambos podem ocorrer sem nenhuma mudança de código.
Sênior — "Como monitorar um modelo cujos rótulos só chegam meses depois?"
Sem rótulo: drift das features (PSI/KS), drift da distribuição das predições, taxa de outliers/fora de domínio, estimativa de performance sem rótulo (NannyML), e proxies de negócio. Com rótulo parcial/atrasado: métrica real por safra numa janela deslizante, por segmento, e calibração. Alarmes ligados a ações (investigar bug upstream vs mudança real; disparar CT).
Sênior — "Desenhe um pipeline de CI/CD/CT para um modelo"
CI: lint + testes de código + testes de dados (schema, distribuição) + testes de modelo (métrica por segmento, invariância, direcional, regressão vs produção). CD: entrega do pipeline e/ou do serviço até staging, com aprovação para produção. CT: gatilho (agenda, dados novos, alarme de drift) → valida dados → treina → avalia com gates → compara com champion → registra → canary/champion-challenger → promove. Falha de gate para e alerta.
Armadilha — "É só colocar o .pkl atrás de um FastAPI"
Funciona para um protótipo, mas ignora: versionamento (qual modelo/dados/código?), o pré-processamento tem que ir junto (senão skew), assinatura de schema, monitoramento de drift, estratégia de rollback, testes de dados e de modelo, e o loop de retraining. Sem isso, o modelo vai degradar em silêncio e ninguém vai conseguir reproduzir nem corrigir.
10.4 Projetos de portfólio que geram entrevista
- Projeto end-to-end (âncora): um problema real (churn, previsão de demanda, fraude) com dados versionados (DVC), experiment tracking (MLflow), pipeline de treino orquestrado com gates por segmento, modelo no registry, serving (BentoML/KServe) com testes de carga, e monitoramento de drift (Evidently) que dispara retraining simulado. README + artigo explicando cada decisão.
- Demonstração de leakage: pegue um dataset conhecido, introduza (e depois corrija) três tipos de vazamento, mostrando a métrica inflada e a real. Ótimo para entrevista.
- Estudo de serving: o mesmo modelo servido de 4 formas (FastAPI, BentoML, ONNX Runtime, Triton) com benchmark de latência/throughput/custo e recomendação.
- Monitor de drift do zero: implementar PSI/KS e detecção de drift de predição sobre um stream simulado, com dashboard e alarme — mostra que você entende o mecanismo, não só a ferramenta.
10.5 Ferramentas e fontes para continuar
- Tracking / registry: MLflow, Weights & Biases, Neptune, ClearML.
- Dados: DVC, lakeFS, Great Expectations, pandera, TFDV.
- Feature store: Feast, Tecton, Hopsworks.
- Pipelines: Kubeflow, Metaflow, ZenML, Vertex/SageMaker Pipelines, Airflow/Dagster para o lado de dados.
- Serving: BentoML, KServe, NVIDIA Triton, Ray Serve, ONNX Runtime, TensorRT.
- Monitoramento: Evidently, NannyML, whylogs/WhyLabs, Arize, Fiddler.
- Leitura: Designing Machine Learning Systems (Chip Huyen); Machine Learning Design Patterns (Lakshmanan et al.); o paper "Hidden Technical Debt in ML Systems" (Google); o guia "MLOps: Continuous delivery and automation pipelines in ML" (Google Cloud); a checklist "ML Test Score" (Google).
Quatro ideias sustentam MLOps: (1) o modelo é uma fração pequena do sistema — o entorno é onde os projetos vivem ou morrem; (2) reprodutibilidade primeiro — código + dados + ambiente + config versionados, ou nada mais funciona direito; (3) modelos degradam sozinhos, então monitorar drift e fechar o loop de retraining não é opcional; (4) treino e produção precisam calcular features do mesmo jeito — skew é a degradação silenciosa mais comum. As ferramentas mudam a cada ano; esses princípios, não.