Module 9 — SageMaker Pipelines et registre de modèles
Les modules 3 à 8 ont livré des briques indépendantes : préparation, entraînement, réglage, endpoint, batch. En production, ces briques doivent s'enchaîner de façon déterministe, être rejouables et laisser une trace. C'est ce que fait SageMaker Pipelines — un orchestrateur natif — combiné au registre de modèles, où chaque version validée attend une approbation avant d'aller en production.
Ce qu'un pipeline apporte que ne donne pas un carnet
Un carnet qui enchaîne les étapes en séquence est fragile. Il dépend de l'environnement Python courant, ne garde pas trace de qui a lancé quoi, ne peut pas se rejouer sur un mois passé sans réécriture. Un pipeline SageMaker règle ces trois manques :
Représentation en graphe : chaque étape a des entrées, des sorties et des dépendances. Le pipeline se rejoue à l'identique.
Journal automatique : chaque exécution laisse une trace horodatée dans la console SageMaker, avec les paramètres utilisés et les artefacts produits.
Paramétrisation : le même pipeline sert pour l'entraînement mensuel de septembre et pour un rejeu de janvier, en changeant un paramètre mois_execution.
Intégration native : les étapes utilisent les mêmes objets que les modules précédents (SKLearn, XGBoost, Transformer), sans nouvelle abstraction à apprendre.
Les cinq types d'étapes utilisées sur le fil rouge
Le pipeline du fil rouge, illustré ci-dessous, en utilise cinq — la moitié de ce qu'offre le catalogue SageMaker, mais celles qui reviennent dans 90 % des cas.
[ProcessingStep] --> [TrainingStep] --> [ProcessingStep] --> [ConditionStep]
preparation entrainement evaluation seuil AUC ?
| |
v v
[ModelStep] (fin)
enregistrer
au registre
| Étape | Type | Ce qu'elle fait |
|---|---|---|
| Préparation | ProcessingStep | Nettoie et découpe en train/valid/test |
| Entraînement | TrainingStep | Lance une TrainingJob sur train/valid |
| Évaluation | ProcessingStep | Calcule AUC sur test, écrit un JSON |
| Décision | ConditionStep | Compare AUC à un seuil (0,80) |
| Enregistrement | ModelStep | Enregistre au registre si le seuil est franchi |
Le pipeline, en code
from sagemaker.workflow.pipeline import Pipeline
from sagemaker.workflow.parameters import ParameterString, ParameterFloat
from sagemaker.workflow.steps import ProcessingStep, TrainingStep
from sagemaker.workflow.conditions import ConditionGreaterThanOrEqualTo
from sagemaker.workflow.condition_step import ConditionStep
from sagemaker.workflow.model_step import ModelStep
seuil_auc = ParameterFloat(name="SeuilAUC", default_value=0.80)
mois = ParameterString(name="MoisExecution", default_value="2026-09")
etape_prep = ProcessingStep(name="Preparation", processor=processeur,
inputs=[...], outputs=[...], code="prepare.py")
etape_train = TrainingStep(name="Entrainement", estimator=estimateur,
inputs={"train": etape_prep.properties.ProcessingOutputConfig.Outputs["train"].S3Output.S3Uri,
"validation": etape_prep.properties.ProcessingOutputConfig.Outputs["valid"].S3Output.S3Uri})
etape_eval = ProcessingStep(name="Evaluation", processor=processeur,
inputs=[etape_train.properties.ModelArtifacts.S3ModelArtifacts, ...],
outputs=[...], code="evaluer.py",
property_files=[PropertyFile(name="rapport", path="rapport.json")])
condition_seuil = ConditionGreaterThanOrEqualTo(
left=JsonGet(step_name="Evaluation", property_file="rapport", json_path="metrics.auc"),
right=seuil_auc,
)
etape_enreg = ModelStep(name="Enregistrer",
step_args=modele.register(model_package_group_name="ResiliationClients",
approval_status="PendingManualApproval"))
etape_condition = ConditionStep(
name="AUCsuffisant",
conditions=[condition_seuil],
if_steps=[etape_enreg],
else_steps=[],
)
pipeline = Pipeline(
name="resiliation-mensuel",
parameters=[seuil_auc, mois],
steps=[etape_prep, etape_train, etape_eval, etape_condition],
sagemaker_session=session,
)
pipeline.upsert(role_arn=role)
pipeline.start(parameters={"MoisExecution": "2026-09"})
Cette définition tient en une trentaine de lignes utiles, produit un graphe visible dans SageMaker Studio Pipelines, et se déclenche par un start() ou par un événement EventBridge.
L'étape de condition et le seuil
ConditionStep est le pivot. Sans elle, un modèle dont l'AUC est retombée à 0,72 partirait au registre exactement comme un modèle à 0,84. Le fil rouge fixe le seuil à 0,80 — la ligne de base du module 4 était à 0,802, on refuse tout modèle en régression.
Le seuil vient d'un ParameterFloat, donc modifiable à chaque exécution sans reconstruire le pipeline. Un modèle qui ne franchit pas la condition emprunte la branche else_steps (vide dans le fil rouge, mais qui pourrait envoyer une alerte SNS à l'équipe data science).
Le PropertyFile est la mécanique qui transmet un chiffre entre l'étape d'évaluation et la condition. Le script evaluer.py écrit /opt/ml/processing/evaluation/rapport.json :
{
"metrics": {"auc": 0.821, "brier": 0.083, "n_test": 24000}
}
JsonGet(json_path="metrics.auc") extrait 0,821, la condition compare à 0,80, la branche if s'exécute.
Le registre de modèles
ModelPackageGroup est un dossier dans lequel s'empilent toutes les versions d'un modèle. Chaque ModelPackage porte :
- un artefact
model.tar.gzsur S3 ; - l'image
ECRd'inférence ; - les métriques d'évaluation issues du pipeline ;
- un statut :
PendingManualApproval,Approved,Rejected.
Le statut par défaut à l'enregistrement est PendingManualApproval : le modèle attend qu'un humain — ou un pipeline de déploiement automatique — le fasse passer à Approved.
import boto3
sm = boto3.client("sagemaker")
sm.update_model_package(
ModelPackageArn="arn:aws:sagemaker:us-east-1:...:model-package/ResiliationClients/12",
ModelApprovalStatus="Approved",
ApprovalDescription="Validé par équipe data science, revue du 15/09/2026",
)
Cette action est journalisée dans CloudTrail, ce qui donne une piste d'audit : qui a approuvé quelle version, quand. C'est la trace qui manque toujours quand on déploie « à la main ».
Déclencher le pipeline
Trois déclencheurs sont utiles :
Manuel depuis Studio ou depuis le SDK : pour tester et déboguer.
Planifié par EventBridge Scheduler : « tous les 1ᵉʳ du mois à 4 h ». Le pipeline s'exécute, produit un modèle, l'enregistre en attente d'approbation.
Sur événement S3 : dès qu'un nouveau fichier resiliation.csv apparaît dans le préfixe brut/. Utile quand la fréquence des livraisons est irrégulière.
# EventBridge Scheduler : 1er du mois à 04:00 UTC
schedule = {
"ScheduleExpression": "cron(0 4 1 * ? *)",
"Target": {
"Arn": "arn:aws:sagemaker:us-east-1:...:pipeline/resiliation-mensuel",
"RoleArn": "arn:aws:iam::...:role/PipelineTrigger",
"Input": '{"PipelineParameters": [{"Name": "MoisExecution", "Value": "auto"}]}'
}
}
Déploiement automatique après approbation
L'approbation d'un modèle peut elle-même déclencher un pipeline de déploiement (souvent construit avec EventBridge → CodePipeline) qui :
- remplace l'
EndpointConfigdu point de terminaison temps réel par une nouvelle version pointant sur le nouveau modèle ; - surveille les métriques d'invocation pendant une fenêtre de canari (10 % du trafic pendant 24 h) ;
- bascule à 100 % ou fait un retour arrière si
Invocation5XXErrorsdépasse un seuil.
Cette chaîne rejoint le module 20 (CI/CD MLOps) et sort du strict périmètre de SageMaker Pipelines, mais elle est la fin logique du parcours.
Une erreur classique : le script evaluer.py écrit rapport.json dans /opt/ml/output/data/, mais la déclaration PropertyFile(path="rapport.json") attend le fichier dans le dossier de sortie déclaré par outputs=[...]. Le pipeline réussit toutes ses étapes, JsonGet renvoie None, la comparaison None >= 0.80 échoue silencieusement, la branche if n'est jamais empruntée. Aucun modèle n'atterrit au registre pendant des semaines sans que personne ne s'en aperçoive, jusqu'à ce que l'équipe métier remarque que la version en production n'a pas changé. Toujours vérifier le contenu du PropertyFile dans une exécution manuelle avant la mise en planification.
En résumé
- Un pipeline SageMaker enchaîne des étapes typées (préparation, entraînement, évaluation, condition, enregistrement) réutilisables et rejouables.
- L'étape
ConditionStepavec unPropertyFileextrait une métrique du rapport d'évaluation et évite qu'un modèle en régression n'atterrisse au registre. - Le registre stocke chaque version avec un statut d'approbation ; l'action
Approvedest journalisée dansCloudTrailet fournit la traçabilité manquante d'un déploiement manuel. - Le déclenchement se fait à la main, par
EventBridgeplanifié ou sur événement S3 ; l'approbation peut chaîner un pipeline de déploiement canari en aval.
Module suivant : la surveillance de ce que produit ce pipeline en production — dérive des données, dérive de la qualité et budget qui ne dépasse pas.