Machine Learning · Insper

MLOps

Abordagem avançada

O que quebra em produção sem que nenhum conjunto de teste mostre e como trocar um modelo em uso com segurança

O caminho desta parte

  1. Empacotar e servir em escalaskops e ONNX, latência por chamada
  2. Registrar cada execuçãoum registro de experimentos, um registro de modelos
  3. Detectar e reagirp-valores com dados grandes; degradar, detectar, retreinar
  4. Mudar com segurançadesalinhamento, laços de realimentação, troca com portão, testes, maturidade
Cada etapa responde a uma pergunta: o que muda quando o modelo sai do notebook? → por que este modelo foi escolhido, entre todos os testados? → que alarme é real e quando retreinar? → o que mais quebra e como trocar um modelo com segurança?
Etapa 1 · o que muda quando o modelo sai do notebook?

Um formato mais seguro: skops

Um arquivo do joblib é um pickle, então carregá-lo pode rodar código. Ao carregar, o skops só reconstrói tipos de uma lista permitida; qualquer outro tipo precisa ser declarado confiável explicitamente.

pipelinetipos não confiáveiscarregando sem confiar
scaler + one-hot + logística[]carrega, probabilidades idênticas
com uma função própria['__main__.cap_amount']UntrustedTypesFoundException

Fora do Python, o ONNX (Open Neural Network Exchange, via skl2onnx) converte um pipeline ajustado num grafo portátil para runtimes em C++, Java ou JavaScript.

Latência: paga-se por chamada, não por linha

Preveja. Pontuar uma linha por chamada ou 10.000 linhas numa só chamada: quão diferente é o custo por linha?
O tempo por chamada fica plano em cerca de 1,7 ms de 1 até cerca de 1.000 linhas e depois cresce; o custo por linha cai de 1,7 ms para 0,0006 ms

Na máquina que gerou a página: 1,724 ms/linha uma de cada vez, 0,0006 ms/linha num só lote, cerca de 2.700×. Uma chamada custa cerca de 1,7 ms quer carregue uma linha, quer mil: trabalho fixo, não aritmética.

Etapa 2 · por que este modelo foi escolhido, entre todos os testados?

Um registro de experimentos: uma linha por execução, nunca editada

dadosCAUC na VCdp na VC
68ad024c96610,010,74950,0292
68ad024c96610,100,75990,0224
68ad024c96611,000,75220,0244
68ad024c966110,000,74420,0230

VC: validação cruzada; dp: desvio padrão entre folds; AUC (area under the curve): área sob a curva ROC; C: o inverso da penalidade da regressão logística.

A vantagem de C = 0.1 sobre C = 1 (0,0077) fica muito abaixo dos desvios padrão entre folds (cerca de 0,02): trate-as como empatadas. Guarde as execuções perdedoras: elas registram quantas coisas foram tentadas. O MLflow faz o mesmo com uma interface web e um registro de modelos.
Etapa 3 · que alarme é real e quando retreinar?

p-valores com dados grandes

Preveja. A média de um atributo anda 0,02 desvio padrão (dp), uma mudança irrelevante. Quando o lote cresce de 1.000 para um milhão de linhas, o que acontece com o p-valor do KS (Kolmogorov–Smirnov)? E com o PSI?
deslocamento de 0,02 dp, n =1.00010.000100.0001.000.000
p-valor do KS0,0970,140,000491,6e-41
PSI (índice de estabilidade populacional)0,03440,00180,00040,0005
O p-valor responde "há alguma diferença?": com linhas suficientes, sempre sim. Dispare alertas por magnitude (PSI ou a estatística KS \(D\)). Com muitos atributos, corrija para testes múltiplos: 50 atributos testados a 5% dão cerca de 2,5 alarmes falsos por lote.

Degradar, detectar, retreinar

A população se move 0,3 dp por mês. Modelo estático vs um modelo retreinado sempre que o PSI da sua entrada passa de 0,25.

mêsestáticomonitoradomelhor possível
00,8010,8010,802
2 (alerta)0,7800,7800,785
60,7590,8140,830
80,6540,8220,816
120,2730,8490,850
O PSI da entrada do modelo estático passa de 4; a acurácia estática cai de 0,80 para 0,27, enquanto o modelo retreinado acompanha a melhor acurácia possível
O primeiro alerta dispara quando o modelo estático ainda vai bem: drift não é dano. E retreinar exige rótulos: com 60 dias de atraso, o modelo monitorado fica dois meses atrás.
Etapa 4 · o que mais quebra e como trocar um modelo com segurança?

Desalinhamento treino–serving, medido

Um novo aplicativo cliente manda um campo em outra unidade. O conjunto de teste, de três jeitos:

AUCsinalizadosdecisões mudadasrejeitados pelo schema
como no treino0,78320,0%0,0%1%
valor em milhares0,77514,8%5,2%100%
duração em anos0,7512,8%17,2%93%
O AUC quase não se mexe; as decisões, sim. O schema pega os dois bugs. Outras fontes: pré-processamento reimplementado em SQL (Structured Query Language) ou Java, janelas de tempo diferentes, atributos que conhecem o futuro.

Colocando um modelo novo no ar com segurança

Primeiro um portão de avaliação: vencer o modelo atual em dados recentes e rotulados que nenhum dos dois viu, por mais do que o ruído. Depois, liberar em etapas:

estratégiacomoprotege de
shadowpontua o tráfego real, respostas só registradasquedas, latência, escores estranhos
canary1–5% do tráfegoproblemas que só aparecem com usuários reais
teste A/Bdivisão aleatória, uma métrica de negócio"AUC melhor" que não é resultado melhor
rollbacko artefato anterior fica prontotodo o resto, em minutos
Laços de realimentação: o modelo de crédito só vê o pagamento dos empréstimos que aprovou. Mantenha um tráfego de holdout decidido sem o modelo.

Testes, documentação e maturidade

O ML Test Score

28 testes em 4 grupos: dados, desenvolvimento do modelo, infraestrutura, monitoramento (Breck et al., 2017). A nota é o mínimo entre os grupos.

Model card

uso pretendido, fatores, métricas, dados de treino e de avaliação, considerações éticas, ressalvas (Mitchell et al., 2019)

Uma escada sensata

  1. script + artefatos versionados
  2. CI/CD (integração e entrega contínuas): testes antes de qualquer modelo ir para produção
  3. logs, painéis, alertas de drift
  4. retreino com portões e rollback

Suba quando a dor justificar.

O panorama de ferramentas

trabalhoferramentasnesta aula
salvar um modelo ajustadojoblib, skops, ONNXjoblib e skops
servir por HTTPFastAPI, BentoMLesboço em FastAPI
empacotar o ambienteDocker, lock filesversões fixas
rastrear experimentos, registrar modelosMLflow, Weights & Biasesum log em JSON lines
versionar dadosDVC (Data Version Control), lakeFSum hash dos dados
validar dadospandera, Great Expectations, pydanticuma função de schema
monitorar driftEvidently, NannyML, whylogsPSI e KS à mão

HTTP (HyperText Transfer Protocol): o protocolo da web; JSON lines: um registro JSON por linha. O ecossistema muda rápido; os conceitos, não.

Resumo

  1. Um pickle roda código; o skops só carrega tipos confiáveis. Uma chamada custa um tempo fixo: batch sempre que der.
  2. Registre toda execução, perdedoras incluídas; empate dentro do ruído dos folds é empate.
  3. Com lotes grandes, alertas por magnitude, não por p-valor; drift não é dano e retreinar exige rótulos.
  4. O desalinhamento muda decisões enquanto o AUC mal se mexe; o schema o pega.
  5. Modelos novos passam por um portão e são liberados em etapas, com rollback pronto.
Lab avançado · cerca de 30 min, em duplas

Alertas, retreino e um model card, passos 9 a 11

  • Mesmo notebook, mesma sessão: os passos usam production, served, meta, monitor e perf dos passos 1 a 8.
  • Transformar os monitores em regras de alerta, retreinar a cada trimestre com os últimos seis meses, gerar o model card a partir dos metadados.
  • Notebook do lab, a partir do passo 9. Responda o Preveja antes de rodar.
  • Simulações: lotes mensais (passo 9) e corrija só a taxa base (passo 10).

Ritmo: passo 9 e a simulação dele em 12 min; passo 10 e a simulação dele em 13 min; passo 11 em 5 min.