Lab 80 — Custo de ML: onde o dinheiro vaza
O problema, e a empresa que o tem
Seis semanas depois do L74 entrar em produção, o relatório financeiro mensal da Cadência mostrou a fatura de SageMaker caindo bem menos do que o time esperava. O endpoint de previsão de cancelamento, que motivou aquele laboratório, estava correto: dividido nos quatro modos, cada consumidor no caminho certo. O problema é que o L74 resolveu um endpoint — e a Cadência, sem ninguém decidir isso formalmente, já tinha mais três fontes de gasto ocioso rodando ao lado dele.
A primeira: uma instância de notebook ml.g4dn.xlarge que uma cientista de dados abriu para explorar um modelo novo de recomendação de produto, e nunca desligou — ela é usada em média 4 horas por dia útil, e paga 24 horas, todo santo dia, incluindo fim de semana. A segunda: o próprio endpoint de cancelamento do L74, na janela de tempo real, está dimensionado para o pico de lançamento de produto do trimestre passado, que nunca se repetiu — o tráfego real de hoje usa uma fração da capacidade paga. A terceira: o modelo de recomendação que a cientista treinou foi para produção direto num endpoint de tempo real sempre ligado, porque copiar a configuração antiga do cancelamento pareceu mais rápido que reler a decisão do L74 — e o padrão de tráfego real desse modelo é esporádico, exatamente o caso que aquele laboratório resolveu para o consumidor errado.
A quarta fonte não é computação: é armazenamento. Cada execução dos jobs de treino do L73 grava checkpoint, dataset amostrado e artefato do modelo em s3://cadencia-ml-experimentos/ — promovido para produção ou não. Ninguém apaga nada, porque apagar um experimento parece arriscado e não há dono claro do bucket. Passados oito meses de experimentos, o volume armazenado cresce todo mês, sozinho, sem que uma única linha de código tenha mudado.
Recurso ocioso de GPU não aparece como incidente — aparece como uma linha que só cresce
Nenhum dos quatro vazamentos deste laboratório quebra nada. O notebook responde, o endpoint responde, o bucket aceita gravação. É exatamente por isso que ficam meses sem serem vistos: não existe alarme para "isto está caro e ninguém precisa disto ligado agora" — só existe fatura, um mês depois, somando um número que ninguém consegue explicar linha por linha.
O que este laboratório NÃO é
Não é sobre re-treinar, avaliar ou promover modelo — isso é o L75, o L77 e o L78. Não é sobre comprar Savings Plan ou Spot — a disciplina de medir antes de comprometer já é o L59, e aqui ela é aplicada, não reensinada. Este laboratório resolve uma coisa: dado um conjunto de recursos de ML que já existe e já funciona, ONDE o dinheiro está vazando, e como reduzir sem perder qualidade medida.
O que você vai conseguir fazer
Objetivos verificáveis: cada um se prova com uma medição concreta na seção de implantação.
- Ler uma recomendação do Compute Optimizer para um notebook e para um endpoint do SageMaker, e decidir se ela autoriza uma mudança.
- Configurar desligamento automático de uma instância de notebook ociosa fora do horário de uso real.
- Redimensionar um endpoint de tempo real pelo tráfego medido, não pelo pico lembrado.
- Migrar um endpoint do modo errado (tempo real sempre ligado) para o modo certo dentre os quatro do L74, a partir do padrão de tráfego observado.
- Configurar uma política de ciclo de vida no S3 que expira artefato de experimento não promovido sem apagar o que está em produção.
- Medir a fatura de ML da Cadência antes e depois, dividida por componente, com o Cost Explorer.
- Provar que nenhuma métrica de qualidade de modelo regrediu depois da redução de custo.
- Reconhecer os quatro padrões de vazamento — computação ociosa, instância superdimensionada, modo de inferência errado, armazenamento sem prazo — em qualquer arquitetura de ML.
O que a certificação cobra disto
| Conceito | Certificação | Como aparece aqui | O que dominar |
|---|---|---|---|
| Compute Optimizer para SageMaker (notebook e endpoint) | MLS-C01, SAA-C03 | recomendação de parar o notebook fora do uso e de redimensionar o endpoint de cancelamento | o Compute Optimizer analisa métrica real de CPU/GPU/memória e recomenda tipo — ele não aplica nada sozinho |
| Escolha de modo de inferência por padrão de tráfego | MLA-C01, MLS-C01 | o endpoint de recomendação migra de tempo real sempre ligado para serverless | reconhecer, a partir de um padrão de tráfego descrito, qual dos quatro modos do L74 elimina o custo ocioso sem quebrar o requisito do consumidor |
| Custo de armazenamento de artefato de ML no S3 | MLS-C01, SAA-C03 | regra de ciclo de vida expirando checkpoint e dataset de experimento não promovido | diferenciar artefato promovido (retém) de artefato de experimento descartado (expira) — apagar tudo por idade quebra rastreabilidade; nunca apagar nada quebra o orçamento |
| Cost Explorer com tag de alocação por modelo/projeto | CLF-C02, SAA-C03 | fatura de ML dividida por tag, comparada antes e depois da correção | custo sem tag é custo sem dono — a tag é o que transforma "a fatura subiu" em "o notebook X subiu" |
| Redução de custo sem regressão de métrica de modelo | MLS-C01, AIF-C01 (conceito geral) | AUC do modelo de cancelamento e precisão do modelo de recomendação medidas antes e depois | mudar infraestrutura de serving não muda peso de modelo — a prova de qualidade constante é o que separa rightsizing de degradação disfarçada de economia |
Onde isto costuma ser cobrado errado
A pergunta clássica descreve uma fatura de ML alta e pede a causa mais provável, oferecendo "o modelo está desatualizado" como distrator plausível. Na maioria dos cenários reais — e nos quatro deste laboratório — a causa nunca é o modelo: é infraestrutura de servir e guardar artefato que ninguém redimensionou desde que foi criada.
Requisitos, e como cada um muda o desenho
Requisito que não muda uma linha do desenho é intenção. A terceira coluna é onde cada um deixou marca.
| Requisito | Valor declarado | O que ele decide no desenho |
|---|---|---|
| Notebook não pode custar fora do horário de uso real | uso medido em ~4 h/dia útil, pago 24 h | obriga verificação periódica de ociosidade e chamada automática de parada, sem depender de alguém lembrar |
| Endpoint de cancelamento não pode ser dimensionado pelo pico lembrado | instância redimensionada pela métrica real dos últimos 14 dias | obriga o Compute Optimizer a rodar ANTES de qualquer redimensionamento manual, nunca depois |
| Endpoint de recomendação segue o mesmo checklist de modo do L74 | padrão de tráfego esporádico, não bloqueante | obriga migração para o modo serverless, não redimensionamento do modo tempo real — o defeito é o modo, não o tamanho |
| Artefato de experimento não promovido tem prazo de vida | expira 90 dias após a última execução sem promoção para o Model Registry | obriga regra de ciclo de vida no bucket, com tag distinguindo promovido de descartável |
| Nenhuma métrica de qualidade de modelo pode regredir | AUC e precisão medidas antes e depois, dentro da margem de ruído já observada | obriga medir a métrica de negócio ANTES de qualquer mudança de infraestrutura, não só depois |
| Custo de ML rastreável por modelo e por time | tag de alocação obrigatória em todo recurso novo | obriga Cost Explorer segmentado por tag, não uma linha agregada de "SageMaker" |
O requisito mais fácil de confundir com os outros três
"Endpoint com instância maior do que o tráfego justifica" e "endpoint no modo errado" parecem o mesmo problema e não são: o primeiro mantém o modo certo (tempo real, para o cancelamento, continua sendo tempo real) e troca só o tamanho; o segundo troca o modo inteiro. Aplicar rightsizing de tamanho a um endpoint que está no modo errado economiza pouco — o desperdício real está no modo, não no tipo de instância.
Arquitetura mínima: quatro recursos de ML, nenhum com tag de custo nem rightsizing
Este é o desenho que a Cadência tem hoje, seis semanas depois do L74. É literalmente o estado atual — nada aqui é hipotético — e é por isso que o defeito passa despercebido: cada peça funciona sozinha, responde quando chamada, e nenhuma delas alarma. O problema não é nenhum recurso individual; é que quatro decisões de infraestrutura nunca foram revisadas depois do dia em que alguém as criou.
- → gera hora-instância paga 24 horas por dia, sem rótulo de custo por projeto
- → cobra pelo tamanho do pico raro, não pelo tráfego que de fato chega
- → GPU sempre ligada para atender um padrão de tráfego esporádico
- → grava artefato de cada experimento, promovido ou descartado, no mesmo prefixo
- → armazenamento cresce todo mês sem nenhuma política de expiração
- → tem recomendação de parar fora do horário comercial, nunca lida
- → tem recomendação de instância menor, pronta e não aplicada
- IA e machine learning
- Armazenamento
- Gestão e governança
Cada seta pontilhada para o Cost Explorer é uma fonte de gasto que ninguém rotulou; cada seta pontilhada para o Compute Optimizer é uma recomendação pronta e nunca lida. Percorra os passos: o defeito comum aos quatro não é o preço de nenhum serviço — é a ausência de uma revisão periódica depois da criação.
- O notebook fica ligado 24 horas por dia. É usado cerca de 4 horas por dia útil pela cientista de dados — o resto das 20 horas, e os fins de semana inteiros, são hora paga sem ninguém na frente da instância.
- O endpoint de cancelamento carrega o dimensionamento de um pico que não voltou. Herdado do L74 no tamanho certo para o lançamento do trimestre passado — o tráfego de hoje é muito menor, e a instância continua no mesmo tamanho.
- O endpoint de recomendação nasceu no modo errado. Copiar a configuração antiga do cancelamento pareceu mais rápido do que aplicar o checklist de escolha de modo do L74 a um padrão de tráfego que é, na verdade, esporádico.
- Os jobs de treino do L73 gravam artefato sem distinguir o que foi promovido. Checkpoint, amostra de dado e modelo de cada execução vão para o mesmo prefixo do bucket, promovidos ou não — não há tag, não há prazo.
- O armazenamento de experimento cresce sozinho, mês após mês. Sem uma linha de código mudar, o bucket acumula ~40 GB por mês, porque apagar parece arriscado e não há dono definido para decidir o que pode sair.
- Compute Optimizer e Cost Explorer sabem, e ninguém perguntou. As duas recomendações de rightsizing estão prontas há semanas; a fatura sobe mês a mês sem tag que explique qual dos quatro vazamentos está pesando mais.
# medir_uso_real.sh -- confere o que ninguem tinha medido: quanto do que
# se paga e' de fato usado, para os quatro recursos.
REGIAO=us-east-1
# Notebook: minutos de kernel ativo nos ultimos 14 dias vs minutos pagos
aws sagemaker describe-notebook-instance \
--notebook-instance-name cadencia-notebook-recomendacao \
--query '{Status:NotebookInstanceStatus,Tipo:InstanceType}' --output table
python3 - <<'PY'
dias = 14
horas_uso_dia = 4 # medido no historico do Jupyter server log
horas_pagas_dia = 24
utilizacao = horas_uso_dia / horas_pagas_dia * 100
print(f'notebook: uso real {horas_uso_dia}h/dia -> utilizacao {utilizacao:.1f}% do que se paga')
PY
# Endpoint de cancelamento: invocacoes reais vs capacidade provisionada
aws cloudwatch get-metric-statistics \
--namespace AWS/SageMaker --metric-name Invocations \
--dimensions Name=EndpointName,Value=cadencia-cancelamento-tempo-real \
--start-time "$(date -u -d '14 days ago' +%FT%TZ)" --end-time "$(date -u +%FT%TZ)" \
--period 86400 --statistics Sum --output table
# Endpoint de recomendacao: mesma consulta, outro nome de endpoint
aws cloudwatch get-metric-statistics \
--namespace AWS/SageMaker --metric-name Invocations \
--dimensions Name=EndpointName,Value=cadencia-recomendacao-tempo-real \
--start-time "$(date -u -d '14 days ago' +%FT%TZ)" --end-time "$(date -u +%FT%TZ)" \
--period 86400 --statistics Sum --output table
# S3: volume total do prefixo de experimentos, e quanto cresceu no mes
aws s3 ls s3://cadencia-ml-experimentos/ --recursive --summarize \
| tail -2
O endpoint de recomendação está no modo errado, não só no tamanho errado
Redimensionar o endpoint de recomendação para uma instância menor, mantendo o modo tempo real sempre ligado, economizaria pouco: o padrão de tráfego real é esporádico, e é o MODO — não o tamanho — que gera hora paga sem uso. Aplicar rightsizing de tamanho onde o defeito é de modo é o erro que este laboratório existe para impedir.
Arquitetura para produção
Cada peça nova abaixo rastreia a uma linha da tabela de requisitos. A diferença estrutural em relação à mínima não é uma caixa a mais em cada canto: dois recursos mudam de MODO (o notebook ganha um ciclo de liga/desliga; o endpoint de recomendação sai do tempo real), um recurso muda de TAMANHO (o endpoint de cancelamento), e um recurso ganha PRAZO (o armazenamento de experimento) — quatro correções diferentes, porque os quatro vazamentos eram diferentes.
- → publica minutos de kernel ativo a cada 5 minutos
- → dispara a checagem de ociosidade fora do horário comercial configurado
- → lê a métrica de ociosidade antes de decidir se para a instância
- → chama StopNotebookInstance quando ociosidade e horário coincidem
- → recomendação de instância menor, aplicada depois de 14 dias medidos
- → recomendação de janela de uso, base da configuração do agendador
- → cobra por invocação e memória, sem hora paga fora de uso
- → grava artefato já com a tag de status que decide o ciclo de vida
- → custo de armazenamento entra na fatura já dividido por tag de projeto
- → custo do endpoint entra na fatura pelo tamanho novo, medido
- → alimenta o orçamento por componente, não só o total consolidado
- IA e machine learning
- Gestão e governança
- Integração de apps
- Compute
- Armazenamento
O notebook não desapareceu — ganhou um agendador e uma função que o desligam sozinhos. O endpoint de cancelamento não mudou de modo — mudou de tamanho. O endpoint de recomendação não mudou de tamanho — mudou de modo. Percorra os passos: cada correção resolve exatamente o defeito que o diagrama anterior mostrou naquele recurso, nenhuma resolve os quatro de uma vez.
- O agendador dispara a checagem de ociosidade fora do horário comercial. Sem depender de ninguém lembrar — a verificação roda sozinha, todos os dias, no fim do expediente configurado.
- A função lê a métrica de ociosidade antes de decidir. Só chama StopNotebookInstance se a ociosidade e o horário fora do expediente coincidirem — uma sessão ativa às 19h não é parada por engano.
- O endpoint de cancelamento é redimensionado pela recomendação do Compute Optimizer. Depois de 14 dias de invocação real medida — não pelo pico do trimestre passado, que já não existe no tráfego de hoje.
- O endpoint de recomendação sai do modo sempre ligado. Migra para serverless, aplicando o mesmo checklist de decisão do L74 a um padrão de tráfego que sempre foi esporádico — o defeito era o modo, e agora está corrigido.
- Os jobs de treino gravam o artefato já com a tag de status. Promovido ou não, decidido no momento da execução — não numa auditoria manual meses depois.
- O ciclo de vida do S3 expira o que não foi promovido em 90 dias. Artefato promovido para o Model Registry fica isento; o resto tem prazo, e o armazenamento para de crescer sozinho.
- Cost Explorer e Budgets fecham o ciclo, componente a componente. A fatura fica dividida por tag — notebook, cada endpoint, armazenamento — e um orçamento por componente alarma antes de qualquer um deles voltar a crescer sem explicação.
Por que o endpoint de cancelamento NÃO muda de modo aqui
O L74 já decidiu que tempo real é o modo certo para esse consumidor: o painel de atendimento não tolera esperar. Redimensionar sem trocar de modo é exatamente o comportamento certo quando o requisito de latência continua o mesmo — só o tamanho da instância estava errado, não a escolha do L74.
O ganho que aparece na fatura, e o que ele exige de disciplina contínua
A redução por componente está na seção de implantação, com número. O que não aparece automaticamente é a manutenção dela: sem a revisão trimestral que o L59 já estabeleceu, o notebook volta a crescer uso fora de horário, o endpoint volta a ficar desalinhado do tráfego, e o bucket volta a acumular artefato sem tag — nenhuma das quatro correções é definitiva por natureza.
Como funciona ponta a ponta: o desligamento automático do notebook
O caminho mais fácil de entender errado é este: parece que basta um alarme de CPU baixa. Não é — CPU baixa também acontece enquanto a cientista está lendo a saída de uma célula, e parar o kernel nesse momento perde o estado da sessão. O fluxo abaixo mede ociosidade do JEITO CERTO: minutos sem execução de célula, cruzados com uma janela de horário.
Payload que o CloudWatch entrega ao alarme de ociosidade, consumido pela Lambda antes de decidir se chama StopNotebookInstance.
{
"AlarmName": "cadencia-notebook-recomendacao-ocioso",
"NewStateValue": "ALARM",
"Trigger": {
"MetricName": "MinutosDesdeUltimaExecucaoCelula",
"Namespace": "Cadencia/MLOps",
"Dimensions": [
{"name": "NotebookInstanceName", "value": "cadencia-notebook-recomendacao"}
],
"Threshold": 30,
"ComparisonOperator": "GreaterThanThreshold"
}
}
O lifecycle config publica a métrica; ele não decide nada sozinho
A decisão de parar mora na Lambda, não no script de start-up do notebook, de propósito: cruzar ociosidade com horário exige estado (quando foi a última checagem, qual é a janela configurada para aquele time) que um lifecycle config, disparado só na criação da instância, não tem como manter.
As decisões, e o que se perde em cada uma
📋 Quatro recursos de ML da Cadência, cada um gerando gasto ocioso por um motivo diferente: notebook sempre ligado, endpoint dimensionado por um pico que não voltou, endpoint no modo errado, e armazenamento de experimento sem prazo.
Cada vazamento tinha uma causa raiz diferente, e tratar todos com a mesma receita — "desligar fora de horário", por exemplo — resolveria o notebook e ignoraria que o endpoint de recomendação nunca deveria estar num modo que se desliga por horário: ele deveria nunca ter GPU provisionada o tempo todo, em primeiro lugar.
Alt: Aplicar rightsizing de tamanho aos dois endpoints, sem mexer em modo nem em armazenamento — reduz a fatura do endpoint de cancelamento, mas deixa o de recomendação pagando hora de GPU ociosa 24 horas por dia — o defeito de modo continua intacto
Alt: Desligar o notebook manualmente todo fim de expediente, por processo, sem automação — depende de alguém lembrar todos os dias; a própria origem do problema já é "ninguém lembrou de desligar" — trocar automação por lembrete não corrige a causa
Alt: Apagar todo o bucket de experimentos mais antigo que 30 dias, sem checar promoção — remove artefato de modelo já promovido e em produção, junto com o que era descartável — quebra rastreabilidade do L73 para economizar em armazenamento barato
Alt: Migrar os dois endpoints para serverless, inclusive o de cancelamento — quebra o requisito de latência do painel de atendimento do L74 — cold start do serverless não cabe no orçamento de 300 ms que aquele consumidor exige
| Decisão | Escolha | Alternativa considerada | Motivo | O que se perde |
|---|---|---|---|---|
| Onde o notebook para | desligamento automático por ociosidade + horário | desligar manualmente todo fim de expediente | reduz de 720 para cerca de 220 horas-instância pagas por mês, sem depender de lembrete humano | sessão não salva perdida se a cientista ficar ociosa por mais de 30 minutos sem salvar |
| Onde o endpoint de cancelamento vai | redimensionado pela métrica real dos últimos 14 dias | manter o tamanho do pico do trimestre passado | reduz custo de instância sem trocar de modo — o requisito de latência do L74 continua atendido | exige nova rodada de medição se o tráfego voltar a crescer de patamar |
| Onde o endpoint de recomendação vai | migra de tempo real para serverless | manter tempo real, só redimensionado | elimina hora paga ociosa para um padrão de tráfego esporádico — é o modo, não o tamanho, que gerava o gasto | paga cold start ocasional, aceitável porque o consumidor não bloqueia esperando |
| O que acontece com o artefato de experimento | ciclo de vida por tag de promoção, expira em 90 dias o que não foi promovido | apagar tudo por idade, sem checar promoção | armazenamento para de crescer sem limite, e o que está em produção nunca expira | exige que todo job de treino grave a tag corretamente — tag ausente vira artefato não expirado por segurança, não descartado por engano |
A dívida que este módulo cria, e que ele não paga
As quatro correções são estáticas — decididas uma vez, a partir do padrão medido hoje. Se o tráfego do endpoint de recomendação virar frequente e bloqueante, ninguém detecta isso sozinho: alguém precisa notar e reaplicar o checklist do L74. Automatizar a RE-decisão de modo a partir de tráfego observado continuamente é otimização fora do escopo deste laboratório.
Construir: o notebook para sozinho quando fica ocioso fora do horário
A peça nova não é o notebook — é o par agendador + função que decide quando ele pode parar sem atrapalhar ninguém.
# desligamento-notebook.tf -- verificacao periodica de ociosidade + horario
resource "aws_scheduler_schedule" "checar_ociosidade_notebook" {
name = "${var.projeto}-checar-ociosidade-notebook"
group_name = "default"
flexible_time_window { mode = "OFF" }
schedule_expression = "rate(15 minutes)"
target {
arn = aws_lambda_function.parar_notebook_ocioso.arn
role_arn = aws_iam_role.scheduler_invoca_lambda.arn
}
}
resource "aws_lambda_function" "parar_notebook_ocioso" {
function_name = "${var.projeto}-parar-notebook-ocioso"
runtime = "python3.12"
handler = "parar_notebook.handler"
timeout = 30
role = aws_iam_role.lambda_notebook.arn
filename = data.archive_file.parar_notebook.output_path
environment {
variables = {
# Janela em que o notebook NAO pode ser parado, mesmo ocioso -- horario
# comercial declarado, nao deduzido.
HORARIO_INICIO = "08:00"
HORARIO_FIM = "19:00"
LIMIAR_OCIOSO_MIN = "30"
}
}
tags = { Projeto = var.projeto, Time = "dados" }
}
# parar_notebook.py -- roda a cada 15 min; so chama stop se ocioso E fora
# do horario configurado. Idempotente: chamar stop num notebook ja parado
# nao e erro.
import os
import boto3
from datetime import datetime, time
sagemaker = boto3.client("sagemaker")
cloudwatch = boto3.client("cloudwatch")
NOTEBOOK = "cadencia-notebook-recomendacao"
LIMIAR_OCIOSO_MIN = int(os.environ["LIMIAR_OCIOSO_MIN"])
INICIO = time.fromisoformat(os.environ["HORARIO_INICIO"])
FIM = time.fromisoformat(os.environ["HORARIO_FIM"])
def dentro_do_horario_comercial(agora: datetime) -> bool:
return INICIO <= agora.time() <= FIM and agora.weekday() < 5
def minutos_ocioso() -> float:
resp = cloudwatch.get_metric_statistics(
Namespace="Cadencia/MLOps",
MetricName="MinutosDesdeUltimaExecucaoCelula",
Dimensions=[{"Name": "NotebookInstanceName", "Value": NOTEBOOK}],
StartTime=datetime.utcnow(),
EndTime=datetime.utcnow(),
Period=300,
Statistics=["Maximum"],
)
pontos = resp.get("Datapoints", [])
return pontos[-1]["Maximum"] if pontos else 0.0
def handler(event, context):
agora = datetime.utcnow()
if dentro_do_horario_comercial(agora):
print("dentro do horario comercial -- nao para")
return
ocioso_min = minutos_ocioso()
if ocioso_min < LIMIAR_OCIOSO_MIN:
print(f"ocioso ha {ocioso_min:.0f} min -- abaixo do limiar, nao para")
return
status = sagemaker.describe_notebook_instance(
NotebookInstanceName=NOTEBOOK)["NotebookInstanceStatus"]
if status != "InService":
print(f"status atual e {status} -- nada a fazer")
return
sagemaker.stop_notebook_instance(NotebookInstanceName=NOTEBOOK)
print(f"parado: ocioso ha {ocioso_min:.0f} min, fora do horario comercial")
Parar não é destruir — mas o volume não persistente some
StopNotebookInstance preserva o volume de armazenamento anexado; bibliotecas instaladas fora dele (por exemplo, com `pip install` direto no ambiente base, em vez de num arquivo de configuração de lifecycle) somem no restart. É o mesmo hábito que a arquitetura de produção do L74 já cobrava para código de aplicação: dependência declarada, não instalada à mão.
Construir: o artefato de experimento ganha prazo de vida
A peça nova é a tag no momento da gravação — sem ela, a regra de ciclo de vida não tem como distinguir o que pode expirar do que está em produção.
# ciclo-de-vida-experimentos.tf -- expira o que nao foi promovido, preserva
# o que foi
resource "aws_s3_bucket_lifecycle_configuration" "experimentos" {
bucket = aws_s3_bucket.experimentos.id
rule {
id = "expirar-nao-promovido"
status = "Enabled"
filter {
tag {
key = "Promovido"
value = "false"
}
}
# 30 dias em Standard-IA reduz custo de armazenamento sem apagar nada;
# so aos 90 dias sem promocao o objeto e removido de fato.
transition {
days = 30
storage_class = "STANDARD_IA"
}
expiration {
days = 90
}
}
rule {
# Artefato com a tag Promovido=true nunca cai nesta regra -- sem filtro
# de tag correspondente, o S3 nao aplica expiracao a ele.
id = "preservar-promovido"
status = "Enabled"
filter {
tag {
key = "Promovido"
value = "true"
}
}
transition {
days = 90
storage_class = "STANDARD_IA"
}
}
}
# tag_experimento.sh -- roda ao fim de cada job de treino do L73, marcando
# o artefato com o status de promocao NO MOMENTO da gravacao
PREFIXO="$1" # ex: experimentos/2026-08-05-recomendacao-v14/
PROMOVIDO="${2:-false}" # 'true' so quando o job registra no Model Registry
aws s3api put-object-tagging \
--bucket cadencia-ml-experimentos \
--key "${PREFIXO}artefato-modelo.tar.gz" \
--tagging "TagSet=[{Key=Promovido,Value=${PROMOVIDO}}]"
echo "artefato ${PREFIXO} marcado Promovido=${PROMOVIDO}"
Tag ausente não vira exclusão por engano
As duas regras filtram por valor explícito de tag (`true` ou `false`); um objeto sem a tag `Promovido` não casa com nenhuma das duas e simplesmente não expira. É o comportamento mais seguro para o caso em que um job antigo, escrito antes desta correção, nunca marcou nada — silêncio na tag vira preservação, não perda.
Construir: o endpoint de recomendação sai do modo sempre ligado
A migração de modo segue exatamente o padrão que o L74 já estabeleceu para o script de análise esporádico: registrar uma segunda versão do modelo compilada para CPU, porque Serverless Inference não aceita GPU.
# endpoint-recomendacao-serverless.tf
resource "aws_sagemaker_model" "recomendacao_cpu" {
name = "${var.projeto}-recomendacao-cpu"
execution_role_arn = aws_iam_role.sagemaker_execucao.arn
primary_container {
# Mesma logica de inferencia do endpoint de tempo real -- versao
# compilada sem dependencia de CUDA, empacotada separadamente.
image = "${var.conta_ecr}.dkr.ecr.${var.regiao}.amazonaws.com/recomendacao-cpu:latest"
model_data_url = "s3://cadencia-ml-experimentos/producao/recomendacao-v14-cpu.tar.gz"
}
}
resource "aws_sagemaker_endpoint_configuration" "recomendacao_serverless" {
name = "${var.projeto}-recomendacao-serverless"
production_variants {
variant_name = "principal"
model_name = aws_sagemaker_model.recomendacao_cpu.name
serverless_config {
memory_size_in_mb = 3072
max_concurrency = 10
}
}
tags = { Projeto = var.projeto, Time = "dados", Modo = "serverless" }
}
resource "aws_sagemaker_endpoint" "recomendacao" {
name = "${var.projeto}-recomendacao"
endpoint_config_name = aws_sagemaker_endpoint_configuration.recomendacao_serverless.name
}
// ClienteRecomendacao.cs -- chamada sincrona ao endpoint serverless. O
// consumidor (pagina de produto) tolera alguns segundos de cold start
// ocasional -- diferente do painel de atendimento do L74/L79.
using Amazon.SageMakerRuntime;
using Amazon.SageMakerRuntime.Model;
namespace Cadencia.Recomendacao;
public class ClienteRecomendacao
{
private readonly AmazonSageMakerRuntimeClient _cliente = new(new AmazonSageMakerRuntimeConfig
{
Timeout = TimeSpan.FromSeconds(4), // orcamento maior que o do painel de atendimento
});
public async Task<IReadOnlyList<string>> RecomendarAsync(string payloadJson)
{
var resposta = await _cliente.InvokeEndpointAsync(new InvokeEndpointRequest
{
EndpointName = "cadencia-recomendacao",
ContentType = "application/json",
Body = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(payloadJson)),
});
using var leitor = new StreamReader(resposta.Body);
var corpo = await leitor.ReadToEndAsync();
return System.Text.Json.JsonDocument.Parse(corpo)
.RootElement.GetProperty("produtos_recomendados")
.EnumerateArray().Select(x => x.GetString()!).ToList();
}
}
O modelo em si não muda — só o empacotamento
A versão CPU é o mesmo modelo treinado no L73, recompilada sem dependência de GPU. Isso é o que permite provar, na seção de implantação, que a métrica de qualidade das recomendações não regride: os pesos são idênticos, só a forma de servir mudou.
Implantar, e provar com número
A ordem das provas segue a ordem das quatro correções
Meça a ociosidade real do notebook antes de configurar o desligamento (prova 1), confirme o rightsizing do endpoint de cancelamento pela métrica do Compute Optimizer (prova 2), confirme que o endpoint de recomendação migrou de modo sem perder qualidade (prova 3), confirme que o armazenamento parou de crescer sem limite (prova 4), e só então compare a fatura consolidada antes e depois (prova 5).
# provas.sh -- cinco medicoes; a fatura final e' consequencia das quatro
# anteriores, nao um numero solto
PROJETO=cadencia; REGIAO=us-east-1
# -- Prova 1: horas-instancia pagas do notebook, antes e depois -------------
python3 - <<'PY'
horas_pagas_antes = 24 * 30 # ligado o mes inteiro
horas_pagas_depois = 220 # medido apos 30 dias com desligamento automatico
reducao = (1 - horas_pagas_depois / horas_pagas_antes) * 100
print(f'notebook: {horas_pagas_antes}h -> {horas_pagas_depois}h pagas/mes ({reducao:.0f}% de reducao)')
PY
# -- Prova 2: instancia do endpoint de cancelamento, e a AUC do modelo -------
aws sagemaker describe-endpoint --endpoint-name cadencia-cancelamento-tempo-real \
--query 'ProductionVariants[0].{Instancia:CurrentInstanceCount,Tipo:InstanceType}' --output table
# Esperado: tipo trocado para o recomendado pelo Compute Optimizer.
# AUC do modelo: 0.83 antes, 0.83 depois -- mesmo artefato, so a instancia mudou.
# -- Prova 3: latencia e precisao do endpoint de recomendacao, antes e depois
python3 - <<'PY'
precisao_top10_antes = 0.34 # medida em holdout, endpoint tempo real
precisao_top10_depois = 0.34 # mesma metrica, mesmo holdout, endpoint serverless
ctr_producao_antes = 5.8 # % de clique real, 14 dias antes da migracao
ctr_producao_depois = 5.7 # % de clique real, 14 dias depois -- dentro do ruido
print(f'precisao@10: {precisao_top10_antes} -> {precisao_top10_depois}')
print(f'CTR real: {ctr_producao_antes}% -> {ctr_producao_depois}% (diferenca dentro do ruido)')
PY
# -- Prova 4: volume do bucket de experimentos parou de crescer sem limite ---
aws s3 ls s3://cadencia-ml-experimentos/ --recursive --summarize | tail -2
# Esperado: volume estavel em torno de 95 GB (so artefato promovido +
# experimentos dos ultimos 90 dias), contra 340 GB e subindo antes da regra.
# -- Prova 5: fatura de ML consolidada, dividida por tag de projeto ----------
aws ce get-cost-and-usage --time-period Start=2026-07-01,End=2026-08-01 \
--granularity MONTHLY --metrics UnblendedCost \
--group-by Type=TAG,Key=Projeto \
--filter '{"Dimensions":{"Key":"SERVICE","Values":["Amazon SageMaker","Amazon Simple Storage Service"]}}'
| Componente | Fatura antes (R$/mês, cenário Cadência) | Fatura depois (R$/mês) | Redução |
|---|---|---|---|
| Notebook de experimentação | R$ 6.200 | R$ 2.150 | 65% |
| Endpoint de cancelamento (rightsizing) | R$ 4.900 | R$ 3.050 | 38% |
| Endpoint de recomendação (modo) | R$ 7.900 | R$ 640 | 92% |
| Armazenamento de experimentos | R$ 1.800 | R$ 480 | 73% |
| Total de ML medido neste laboratório | R$ 20.800 | R$ 6.320 | 70% |
70% de redução, com AUC e precisão idênticas às medidas antes da mudança
A queda de R$ 20.800 para R$ 6.320 por mês, no cenário desta Cadência fictícia, não veio de nenhum modelo mais simples nem de menos cobertura de caso de uso: veio de quatro decisões de infraestrutura sobre recursos que já existiam. AUC do modelo de cancelamento (0,83 → 0,83) e precisão@10 do modelo de recomendação (0,34 → 0,34) ficaram estáveis porque nenhum peso de modelo foi tocado — só a forma de servir e de guardar o que já estava treinado.
Quebrar de propósito
Três falhas provocadas, com o sintoma que cada uma produz e onde a investigação começa.
| Falha provocada | Sintoma | Onde olhar | Correção |
|---|---|---|---|
| Alterar a variável HORARIO_FIM da Lambda para um horário antes do fim real do expediente | Notebook para no meio de uma sessão ativa, perdendo trabalho não salvo | log da Lambda mostrando o horário configurado versus o log de uso real do Jupyter server | ajustar a janela com folga sobre o horário real de uso, não sobre o horário nominal do contrato |
| Remover a tag Promovido do artefato mais recente antes de aplicar o ciclo de vida | Artefato em produção expira em 90 dias, mesmo estando ativo no Model Registry | verificar se o S3 Lifecycle removeu um objeto cujo ARN ainda aparece no Model Registry | reaplicar a tag Promovido=true a qualquer artefato referenciado por uma versão ativa no registro |
| Trocar o modo do endpoint de recomendação de volta para tempo real, sem atualizar o cliente .NET | Cliente continua funcionando, mas a fatura volta a subir sem nenhum alarme disparar | comparar tipo de endpoint configurado no Terraform com o custo por hora reportado no Cost Explorer | o orçamento por tag (Budgets) é o que deveria ter alarmado — revisar o limiar configurado para esse componente |
Um endpoint de tempo real recebe em média 8 chamadas por dia, espalhadas sem padrão previsível, e nenhuma delas pode esperar mais de 4 segundos. A equipe redimensiona a instância para um tipo menor, mas mantém o modo tempo real sempre ligado, e a fatura cai pouco. Qual é a causa mais provável de a redução ter sido pequena?
Segurança: quem pode parar um notebook e quem pode apagar um artefato
| Risco | Probabilidade | Impacto | Prevenção | Detecção | Resposta |
|---|---|---|---|---|---|
| Função de desligamento para o notebook errado por nome mal configurado | Baixa | Médio — interrupção de sessão de outro time | nome do notebook validado por tag `Time` antes de qualquer StopNotebookInstance | CloudTrail em `sagemaker:StopNotebookInstance` | reverter a configuração, iniciar o notebook de volta |
| Tag Promovido removida por engano, artefato de produção expira | Baixa | Alto — perda de artefato referenciado por modelo em produção | IAM restringe `s3:PutObjectTagging` no prefixo de produção a um role específico do pipeline de promoção | CloudTrail em `PutObjectTagging` e `DeleteObject` no bucket de experimentos | restaurar de versão anterior se o versionamento do bucket estiver habilitado |
| Credencial de longa duração usada pelo script de tag no job de treino | Média | Alto — acesso de escrita ao bucket de experimentos | IAM Role de execução do SageMaker via instance profile, nunca chave estática | GuardDuty e IAM Access Analyzer | rotação da role, revogação de sessão ativa |
| Endpoint de recomendação exposto sem autenticação a partir do cliente .NET | Baixa | Médio — invocação não autorizada gerando custo | IAM restrito à execution role da aplicação; SigV4 obrigatório na chamada | CloudTrail em `InvokeEndpoint` com origem fora da role esperada | revogar credencial, revisar política de menor privilégio |
Observabilidade: as perguntas que o painel de custo de ML tem de responder
- Quantas horas o notebook ficou ligado hoje, e quantas foram realmente usadas?
- O endpoint de cancelamento está dentro do tamanho recomendado pelo Compute Optimizer, ou já desalinhou de novo?
- O endpoint de recomendação está no modo certo para o tráfego que ele recebe hoje?
- Qual percentual do bucket de experimentos é artefato promovido versus descartável ainda não expirado?
- Algum dos quatro componentes voltou a crescer acima do orçamento configurado neste mês?
- A precisão do modelo de recomendação e a AUC do modelo de cancelamento seguem estáveis desde a última mudança de infraestrutura?
| Alarme | Métrica | Limiar inicial |
|---|---|---|
| Notebook parado repetidamente no mesmo horário configurado | contagem de StopNotebookInstance | 3 vezes seguidas no mesmo horário — sinal de janela mal ajustada |
| Endpoint de cancelamento desalinhado da recomendação do Compute Optimizer | diferença entre tipo provisionado e tipo recomendado | qualquer diferença por mais de 30 dias |
| Endpoint de recomendação de volta a hora paga ociosa | InvocationsPerInstance (SageMaker) | abaixo do limiar esperado para o modo serverless configurado |
| Orçamento por componente estourado | AWS Budgets por tag de Projeto | acima de 110% do orçamento mensal do componente |
Escala: de um notebook a uma frota de modelos
| Ordem de grandeza | O que muda |
|---|---|
| 1 notebook, 2 endpoints | o desenho deste laboratório basta: uma função de desligamento, rightsizing manual revisado a cada trimestre |
| 10 notebooks, 10 modelos em produção | desligamento automático vira política padrão de conta (lifecycle config obrigatório na criação), não configuração por instância |
| 100 modelos, múltiplos times | cada time tem orçamento e tag próprios; painel do Cost Explorer segmentado por time, não só por componente |
| Falha de uma AZ | notebook e endpoints de tempo real ficam indisponíveis na AZ afetada; serverless e Batch Transform, sem estado provisionado, redistribuem sozinhos |
Rightsizing não escala por instância — escala por política
Com 100 modelos, revisar o Compute Optimizer instância por instância deixa de ser viável. A disciplina que sobrevive é a mesma do L59: cadência trimestral automatizada, com a decisão de aplicar ou não ainda humana, mas o LEVANTAMENTO da recomendação disparado por agendador, não por memória de alguém.
Custo: as dimensões, e por que armazenamento é diferente de computação
| Cenário | O que domina o custo | Onde a atenção deve ir primeiro |
|---|---|---|
| Protótipo (1 modelo, 1 notebook) | notebook ocioso é a maior fatia — nenhum endpoint ainda justifica atenção | configurar o desligamento automático antes de qualquer outra otimização |
| Produção pequena (2 a 5 modelos) | escolha de modo de inferência passa a dominar — GPU ociosa em modo errado custa mais que instância superdimensionada no modo certo | revisar o checklist do L74 para cada endpoint novo, antes de medir tamanho |
| Alta escala (dezenas de modelos) | armazenamento de experimento cresce mais rápido do que qualquer endpoint individual, porque cada experimento — promovido ou não — grava artefato | ciclo de vida por tag vira obrigatório desde o primeiro job de treino, não uma correção posterior |
Computação cobra por hora ligada; armazenamento cobra por byte guardado — a alavanca é diferente
Desligar um notebook ocioso interrompe o gasto na hora seguinte. Um objeto órfão no S3 continua cobrando até alguém — ou uma regra — apagá-lo; não existe "ficar ocioso" que reduza o custo de armazenamento sozinho. É por isso que este laboratório trata os dois com peças diferentes: função de desligamento para computação, regra de ciclo de vida para armazenamento.
Well-Architected nos seis pilares
| Pilar | Situação | Risco | Melhoria | Prioridade |
|---|---|---|---|---|
| Otimização de custo | quatro recursos de ML sem revisão desde a criação | fatura cresce sem explicação por componente | tag de alocação + Compute Optimizer + ciclo de vida, revisados por cadência | Alta |
| Excelência operacional | desligamento e rightsizing dependiam de alguém lembrar | correção manual esquecida em semanas de pico de trabalho | automação por agendador, decisão humana só na revisão trimestral | Alta |
| Confiabilidade | endpoint de recomendação sem observabilidade de modo próprio | regressão para modo antigo passa despercebida | alarme por componente no orçamento, não só total consolidado | Média |
| Segurança | tag de promoção gravável por qualquer role de treino | artefato de produção poderia ser desmarcado por engano | IAM restringe escrita de tag no prefixo de produção a role específica | Média |
| Eficiência de desempenho | endpoint de cancelamento dimensionado por pico raro | capacidade provisionada não reflete o tráfego real | rightsizing pela métrica de 14 dias, revisado por cadência | Alta |
| Sustentabilidade | GPU provisionada 24h para tráfego esporádico | consumo de energia desproporcional ao uso real do modelo | migração de modo elimina hora de GPU sem uso | Média |
Evolução em níveis
Um notebook e um endpoint de tempo real, sem tag, sem opt-in do Compute Optimizer.Desligamento manual ocasional do notebook, rightsizing feito uma vez e nunca revisitado.Desligamento automático por ociosidade, rightsizing pelo Compute Optimizer, modo de inferência escolhido pelo checklist do L74, ciclo de vida por tag no armazenamento.Política de conta obrigando lifecycle config e tag em toda instância nova; revisão trimestral automatizada do Compute Optimizer para toda a frota de modelos.FinOps de ML como função central: chargeback por time, orçamento por modelo, bloqueio de deploy de endpoint novo sem passar pelo checklist de modo do L74.A mesma disciplina aplicada ao custo de IA generativa: cache de prompt e lote no Bedrock (L89) entram na mesma revisão de orçamento, e o MODELO certo por tarefa é escolhido pelos MESMOS dados de utilização que hoje decidem modo de inferência clássico — não por quanto ele "parece" caro.Onde IA entra nesta arquitetura, e onde não entra
Aqui, IA já está — só que operada pela AWS, não construída por você
O Compute Optimizer já usa aprendizado de máquina internamente para analisar o padrão de uso de notebook e endpoint e recomendar tipo de instância. Você não constrói esse modelo — você lê a saída dele, e este laboratório é inteiro sobre LER essa saída antes de agir, não sobre substituí-la.
Onde IA não entra: usar um modelo de linguagem para "adivinhar" se um notebook está ocioso a partir de uma descrição textual do que a cientista estava fazendo é pior do que a métrica direta de execução de célula que este laboratório usa — troca um sinal preciso por uma inferência incerta sobre algo que já se mede exatamente. O lugar certo para IA neste domínio de custo é outro: gasto de token e cache de prompt em sistemas de IA generativa, que é o assunto do L89.
Anti-padrões deste laboratório
| Antipadrão | Por que alguém faz | Sintoma em produção | Forma correta |
|---|---|---|---|
| Deixar o notebook ligado "só por precaução" | esquece de desligar, e retomar o contexto de uma sessão salva parece mais rápido que reabrir do zero; a conta chega um mês depois, difícil de ligar à causa específica | hora-instância paga sem nenhuma sessão ativa por dias seguidos | desligamento automático por ociosidade cruzada com horário, sem depender de lembrete |
| Copiar a configuração de um endpoint existente para um modelo novo | "funcionou para o outro modelo" parece validação suficiente, e reler o checklist de decisão de modo do L74 parece trabalho redundante | GPU sempre ligada para um padrão de tráfego que nunca precisou de tempo real | aplicar o checklist de modo a CADA modelo novo, mesmo que outro já resolvido pareça similar |
| Nunca apagar artefato de experimento | apagar parece arriscado ("e se eu precisar depois"), e não há dono claro do bucket que force uma decisão | armazenamento cresce todo mês, sem nenhum objeto individual parecer culpado | ciclo de vida por tag de promoção, decidida no momento em que o artefato é gravado |
| Redimensionar instância só pela métrica de CPU/GPU, sem checar métrica de negócio antes | a recomendação do Compute Optimizer é um número só, e correlacionar com AUC ou CTR parece etapa extra | custo cai, e uma regressão de qualidade só aparece semanas depois num relatório de negócio | medir a métrica de modelo ANTES de qualquer mudança de infraestrutura, não só depois |
| Tratar a redução de custo como projeto único, fechado quando a fatura cai | uma vitória anunciada de "reduzimos X%" parece encerrar o assunto, e não há lembrete automático cobrando revisão | o mesmo padrão de desperdício reaparece dois ou três trimestres depois, com um modelo novo | cadência trimestral de revisão, a mesma que o L59 já estabeleceu para o resto da conta |
Quando algo não funciona
| Sintoma | Causa provável | Como investigar | Log/métrica | Correção |
|---|---|---|---|---|
| Notebook continua ligado depois da janela de ociosidade configurada | métrica de MinutosDesdeUltimaExecucaoCelula não está sendo publicada pelo lifecycle config | checar se o script de lifecycle foi anexado à instância na criação | ausência total de datapoints no CloudWatch para essa métrica | reanexar o lifecycle config; instância precisa ser recriada, config não se aplica retroativamente |
| Endpoint de recomendação em serverless com latência p99 muito acima do esperado | cold start acontecendo com mais frequência do que o padrão de tráfego sugeria | medir intervalo entre chamadas consecutivas no CloudWatch, comparar com o tempo de reciclagem do container | métrica ModelLatency separada de OverheadLatency no SageMaker | aumentar MaxConcurrency ou reconsiderar se o padrão real não é mais esporádico o suficiente para serverless |
| Artefato promovido expirou mesmo com a tag correta | regra de ciclo de vida aplicada antes da tag ser gravada, ou tag gravada num prefixo diferente do que a regra filtra | comparar o prefixo exato da regra do Terraform com o prefixo real onde o job grava | S3 Inventory ou CloudTrail em DeleteObject correlacionado com a regra de lifecycle | corrigir o prefixo da regra; restaurar de versão anterior se o bucket tiver versionamento habilitado |
| Fatura de ML não caiu apesar das quatro correções aplicadas | orçamento por tag não está capturando todos os recursos — algum componente sem a tag Projeto ficou fora da segmentação | comparar soma dos componentes rotulados no Cost Explorer com o total consolidado do serviço | diferença entre UnblendedCost total e a soma agrupada por tag | auditar recursos sem tag e aplicar retroativamente antes de reavaliar a redução |
Limpeza: o que o destroy leva, e o que continua cobrando ou some para sempre
#!/usr/bin/env bash
# limpeza.sh -- o que o destroy leva, e os dois casos que ele NAO resolve
set -euo pipefail
PROJETO="${PROJETO:?defina PROJETO}"
# 1. Notebook -- pare antes de destruir; terraform destroy em cima de uma
# instancia InService pode falhar dependendo do provider.
aws sagemaker stop-notebook-instance --notebook-instance-name "${PROJETO}-notebook-recomendacao" || true
# 2. Endpoints -- cada um deixado no ar continua cobrando hora de instancia
# ou concorrencia reservada, exatamente como no L74.
for MODO in cancelamento-tempo-real recomendacao; do
aws sagemaker delete-endpoint --endpoint-name "${PROJETO}-${MODO}" || true
aws sagemaker delete-endpoint-config --endpoint-config-name "${PROJETO}-${MODO}" || true
done
terraform destroy -auto-approve
# 3. O ARTEFATO PROMOVIDO no S3 NAO sai no destroy nem na regra de ciclo de
# vida -- e nao deveria: e o modelo em producao. So o nao-promovido expira,
# e so depois de 90 dias, nao no destroy.
echo "aviso: artefato com tag Promovido=true continua no bucket -- correto."
# 4. Prova final: nada com o nome do projeto de pe fora do esperado.
aws resourcegroupstaggingapi get-resources \
--tag-filters Key=Projeto,Values="${PROJETO}" \
--query "ResourceTagMappingList[].ResourceARN" --output table
| Recurso | O `destroy` remove? | Continua cobrando/existindo depois? |
|---|---|---|
| Função Lambda, agendador EventBridge, alarme CloudWatch | Sim | Não |
| Endpoints e configurações de endpoint | Sim, se deletados antes do destroy | Sim, se esquecidos — hora de instância ou concorrência reservada continua cobrando |
| Notebook (instância parada, não deletada) | Não — o Terraform não gerencia deleção de notebook por padrão neste desenho | Sim, cobra armazenamento do volume mesmo parado |
| Artefato com tag Promovido=true no S3 | Não — a regra de ciclo de vida exclui explicitamente | Sim, por design — é o modelo em produção |
| Artefato sem promoção, dentro dos 90 dias | Não — expira pela regra, não pelo destroy | Sim, até completar o prazo configurado |
Artefato expirado pelo ciclo de vida não volta — nem com o destroy nem depois
A expiração do S3 Lifecycle é permanente: passado o prazo sem a tag Promovido=true, o objeto é removido e não existe operação de limpeza deste laboratório que o traga de volta. É por isso que a tag é gravada no MOMENTO do treino, não numa auditoria manual meses depois — o prazo corre a partir do dia em que o artefato nasce, com ou sem alguém revisando.
Resumo: os quatro vazamentos da banda 8, e onde cada um foi resolvido antes
Este laboratório fecha a banda 8 medindo o custo do que os nove anteriores construíram. O L71 estabeleceu a pergunta "vale a pena usar ML aqui"; o L73 deu reprodutibilidade ao treino, e é esse mesmo pipeline que grava o artefato que este módulo agora expira por prazo. O L74 deu os quatro modos de servir, e é o checklist DELE que resolve o endpoint de recomendação aqui — não um checklist novo. O L78 e o L79, ainda à frente na numeração mas já desenhados no catálogo, tratam de avaliação honesta e de consumo resiliente; este módulo prova que otimizar custo sem tocar a métrica de negócio que aqueles dois cobram é possível — e é o único tipo de redução que se sustenta.
| Problema | Peça | Motivo |
|---|---|---|
| Notebook ligado 24h, usado 4h/dia | agendador + Lambda de desligamento por ociosidade+horário | reação local e automática não depende de ninguém lembrar de desligar |
| Endpoint dimensionado pelo pico que não voltou | rightsizing pela recomendação do Compute Optimizer | métrica de 14 dias substitui memória de pico antigo, sem trocar de modo |
| Endpoint no modo errado para o tráfego real | migração de tempo real para serverless, pelo checklist do L74 | o defeito era o modo, não o tamanho — resolver tamanho não resolveria isto |
| Artefato de experimento acumulando sem prazo | ciclo de vida por tag de promoção | armazenamento não tem "ficar ocioso" — só prazo evita crescimento sem limite |
- Compute Optimizer analisa 14+ dias de métrica real do notebook e do endpoint de cancelamento.
- A recomendação decide se há o que redimensionar — não aplica nada sozinha.
- O agendador dispara a checagem de ociosidade do notebook fora do horário comercial.
- O endpoint de recomendação migra de tempo real para serverless, seguindo o checklist do L74.
- Cada job de treino grava o artefato já com a tag de status de promoção.
- O ciclo de vida do S3 expira em 90 dias o que não foi promovido, preserva o que foi.
- A fatura consolidada é comparada componente a componente, antes e depois.
- AUC do modelo de cancelamento e precisão do modelo de recomendação são medidas e comparadas — sem regressão, a redução conta como válida.
Perguntas frequentes
❓ Por que só redimensionar o endpoint de recomendação não resolveu o vazamento de custo?
❓ Compute Optimizer analisa instâncias de notebook do SageMaker, ou só EC2 tradicional?
❓ Como o ciclo de vida do S3 diferencia artefato promovido do descartável?
❓ Migrar para serverless piora a experiência de quem vê a recomendação?
❓ Por que o artefato promovido para produção nunca expira, mesmo com anos de idade?
❓ É seguro configurar o desligamento automático do notebook sem avisar quem usa ele?
❓ A redução de custo medida neste laboratório se aplica a qualquer conta AWS com SageMaker?
❓ Qual desses quatro vazamentos costuma pesar mais numa conta real?
Fixando
Uma regra de ciclo de vida do S3 expira, em 90 dias, todo objeto com a tag `Promovido=false`. Um artefato de modelo que está em produção há oito meses, referenciado por uma versão ativa no Model Registry, aparece marcado `Promovido=false` por um erro no script de treino. O que acontece?
Depois de aplicar as quatro correções deste laboratório, a fatura de ML da Cadência caiu 70%. Antes de declarar a redução válida, o time também mediu AUC do modelo de cancelamento e precisão@10 do modelo de recomendação, e as duas ficaram estáveis. Por que essa segunda medição é necessária, já que nenhuma das quatro correções alterou o treino do modelo?
Conhecimentos, próximo módulo e documentação
| Item | Conteúdo |
|---|---|
| Conhecimentos anteriores necessários | L59 (Compute Optimizer antes de compromisso) e L74 (os quatro modos de servir um modelo) concluídos; opt-in do Compute Optimizer feito na conta |
| Conhecimentos adquiridos | desligamento automático de notebook por ociosidade+horário; rightsizing de endpoint pela métrica real; migração de modo de inferência a partir do checklist do L74; ciclo de vida de artefato de experimento por tag de promoção; medir métrica de negócio antes e depois de mudança de infraestrutura |
| Limitação que fica | as quatro correções são estáticas — dependem de reaplicação manual se o padrão de tráfego ou de uso mudar; automatizar a RE-decisão continuamente fica para um ciclo futuro |
| Próximo exemplo recomendado | L89 — custo e latência de GenAI, que aplica a mesma disciplina de medir antes de otimizar à escolha de modelo e ao cache de prompt no Bedrock |
| Também habilitado por este módulo | a banda 8 fecha aqui: L73 (reprodutibilidade), L74 (quatro modos) e este laboratório formam o ciclo completo de treinar, servir e pagar por um modelo com disciplina de engenharia |
| Data da última validação técnica | 8 de agosto de 2026 |
Documentação oficial consultada: What is AWS Compute Optimizer? — recursos suportados incluindo instâncias de notebook e endpoints do SageMaker, período padrão de 14 dias e exigência de opt-in; Amazon SageMaker Serverless Inference — limites de memória e concorrência do modo serverless, já cobertos em detalhe no L74; Amazon S3 Lifecycle configuration — filtro por tag, transição de classe de armazenamento e expiração de objeto; documentação de StopNotebookInstance e do lifecycle config de notebook instances. Valores em reais aparecem por decisão editorial específica deste módulo, como medição do cenário fictício da Cadência — não são preço publicado pela AWS; confira o AWS Pricing Calculator e o Cost Explorer da sua própria conta antes de projetar redução semelhante.
O que não foi verificado, e você deve conferir na sua conta
As 4 horas de uso real do notebook, os 340 GB acumulados de experimento e os valores em reais da fatura antes/depois são medições do cenário de exemplo desta Cadência fictícia — meça o seu próprio padrão de uso antes de configurar limiares. O suporte do Compute Optimizer a instâncias de notebook e a endpoints do SageMaker pode variar por região; confirme a disponibilidade no console antes de assumir a recomendação pronta. `serverless_config` e os limites de `memory_size_in_mb` também merecem checagem na documentação atual do provedor Terraform antes de aplicar em produção.
Terminou de ler?
Marcar como concluído registra o XP, mantém sua sequência e coloca 3 cartas deste módulo na fila de revisão espaçada.
Próximos passos sugeridos
Temas deste módulo
Discussão
Carregando comentários…