Module 4 — Tâches d'entraînement et conteneurs intégrés
Les données sont sur S3 au format Parquet, organisées par canal. Ce module lance la première tâche d'entraînement du fil rouge avec l'algorithme intégré XGBoost — celui qu'AWS fournit clef en main, sans que vous ayez à construire d'image — puis explique comment tirer parti des instances Spot pour diviser la facture par trois.
Ce qu'est une tâche d'entraînement, mécaniquement
Une TrainingJob est une machine EC2 éphémère, provisionnée à la demande, sur laquelle SageMaker :
- tire une image Docker depuis
ECR(l'algorithme intégré) ; - télécharge les données des canaux depuis S3 vers
/opt/ml/input/data/<canal>/; - exécute le conteneur avec vos hyperparamètres, écrits dans
/opt/ml/input/config/hyperparameters.json; - copie le contenu de
/opt/ml/model/verss3://<output_path>/<job>/output/model.tar.gz; - arrête et libère l'instance.
Vous êtes facturé pour la durée totale entre l'étape 2 et l'étape 4. Le provisionnement (étape 1) et le téléversement final (étape 4) prennent typiquement 60 à 120 secondes chacun, et sont inclus dans la facturation ; une tâche d'une minute utile peut donc coûter 3 minutes d'instance. Ce détail rend absurde le lancement de dizaines de mini-tâches ; il vaut mieux regrouper.
L'estimateur XGBoost intégré, ligne par ligne
Sur le fil rouge, train.parquet contient 240 000 lignes et 42 variables ; la cible a_resilie vaut 0 ou 1. Voici la tâche complète :
import sagemaker
from sagemaker.xgboost.estimator import XGBoost
from sagemaker.inputs import TrainingInput
session = sagemaker.Session()
role = "arn:aws:iam::123456789012:role/SageMakerExecution"
estimateur = XGBoost(
entry_point=None, # None = algorithme intégré pur
framework_version="1.7-1",
role=role,
instance_count=1,
instance_type="ml.m5.2xlarge", # 0,46 $/h dans us-east-1
volume_size=20, # Go du disque local
max_run=3600, # coupe la tâche au-delà d'une heure
output_path="s3://resiliation-modeles/xgboost/",
hyperparameters={
"objective": "binary:logistic",
"num_round": 200,
"max_depth": 5,
"eta": 0.1,
"subsample": 0.8,
"eval_metric": "auc",
},
)
canaux = {
"train": TrainingInput("s3://resiliation-donnees/prepare/v3/train.parquet",
content_type="application/x-parquet"),
"validation": TrainingInput("s3://resiliation-donnees/prepare/v3/valid.parquet",
content_type="application/x-parquet"),
}
estimateur.fit(canaux, job_name="resiliation-xgb-2026-09-01")
Neuf éléments décident du résultat, et chacun mérite d'être justifié.
framework_version="1.7-1" : la version du conteneur intégré. 1.7-1 supporte Parquet en entrée, ce qui n'était pas le cas des versions antérieures.
instance_type="ml.m5.2xlarge" : 8 vCPU, 32 Go de RAM. Pour 240 000 lignes et 42 variables, un ml.m5.xlarge (4 vCPU, 16 Go) suffirait — le double a été choisi ici pour raccourcir la tâche de 8 à 3 minutes, à coût quasi identique (8 vCPU × 3 min ≈ 4 vCPU × 6 min).
volume_size=20 : le disque local reçoit les fichiers de données et les vérifications intermédiaires. Trop petit, la tâche échoue avec NoSpaceLeftOnDevice ; trop grand, on paie du EBS pour rien.
max_run=3600 : garde-fou qui coupe une tâche partie en vrille. Sans lui, un bug d'hyperparamètre peut coûter des heures avant que quelqu'un s'en rende compte.
num_round=200 et eta=0.1 : nombre d'arbres et taux d'apprentissage. Le choix vient de la validation sur valid.parquet ; le réglage automatique du module 6 les redéfinira.
eval_metric="auc" : la classe minoritaire (résiliation) est rare (~7 %), donc l'exactitude est trompeuse ; AUC-ROC est le choix classique et sera repris à l'évaluation.
job_name : identifiant unique. AWS interdit deux tâches du même nom, ce qui empêche par construction d'écraser un artefact.
Les journaux, dans CloudWatch
Pendant l'exécution, chaque ligne écrite sur stdout par le conteneur remonte dans un groupe de journaux CloudWatch nommé /aws/sagemaker/TrainingJobs. Vous y voyez :
[0] train-auc:0.7412 validation-auc:0.7284
[10] train-auc:0.8156 validation-auc:0.7910
[50] train-auc:0.8792 validation-auc:0.8021
[100]train-auc:0.8988 validation-auc:0.8033
[199]train-auc:0.9124 validation-auc:0.8018
Deux lectures immédiates : l'écart entre train et validation se creuse à partir du 50ᵉ tour — signe de surajustement — et le gain sur validation s'aplatit après 100. La conclusion utile pour le module 6 : la plage à explorer pour num_round sera 50 à 150, pas 200 à 500.
Le modèle sur S3 : model.tar.gz
À la fin, SageMaker crée s3://resiliation-modeles/xgboost/resiliation-xgb-2026-09-01/output/model.tar.gz. C'est une archive tar.gz qui contient, pour XGBoost, un seul fichier xgboost-model — le modèle sérialisé.
aws s3 cp s3://resiliation-modeles/xgboost/resiliation-xgb-2026-09-01/output/model.tar.gz .
tar -xzf model.tar.gz
# xgboost-model
Ce format model.tar.gz est le contrat commun de SageMaker : c'est ce que consommeront la transformation par lots (module 8) et les points de terminaison (module 7). Un script d'entraînement personnalisé (module 5) devra écrire ses artefacts dans /opt/ml/model/ avec la structure attendue par le conteneur d'inférence correspondant.
Instances Spot : jusqu'à 70 % de remise, avec un piège
AWS revend à prix cassé la capacité EC2 inutilisée, et peut la reprendre à tout moment avec 2 minutes de préavis. Sur SageMaker, cela s'active en trois arguments :
estimateur = XGBoost(
...,
use_spot_instances=True,
max_run=3600, # temps utile maximum
max_wait=7200, # temps total incluant les attentes et reprises
checkpoint_s3_uri="s3://resiliation-modeles/checkpoints/xgb/",
)
Trois règles pour ne pas se faire piéger :
max_wait ≥ max_run, obligatoirement, sinon le SDK lève une erreur. La différence est le temps que vous acceptez d'attendre en cas d'interruption et de reprise.
Point de reprise sur S3 : sans checkpoint_s3_uri, une interruption au 150ᵉ tour redémarre à 0. Avec, l'algorithme reprend au dernier point sauvé. XGBoost sait charger un modèle intermédiaire ; un script personnalisé doit gérer cela lui-même (module 5).
Ne pas utiliser Spot en production quand la fenêtre de livraison est critique. Un entraînement mensuel avec 6 heures de tolérance ? Spot idéal. Une tâche urgente à livrer avant la démonstration de 15 h ? Pas Spot.
Sur le fil rouge, l'entraînement XGBoost prend 3 minutes en instance à la demande à 0,023 $, ou 3 à 5 minutes en Spot à environ 0,007 $. La différence paraît dérisoire pour une tâche unique ; elle devient significative sur les 400 tâches du réglage automatique du module 6.
Une interruption apparaît dans les journaux CloudWatch (Spot instance was terminated) et dans le statut final de la tâche (Stopped puis relance automatique). Aucune notification ne part par défaut. Pour un pipeline surveillé, brancher EventBridge sur les événements SageMaker Training Job State Change et rediriger vers SNS — l'inverse ferait perdre la trace des tâches interrompues, ce qui rend le débogage impossible.
Entraînement distribué, en une phrase
Passer instance_count=4 répartit les données entre quatre instances qui synchronisent leurs gradients. Pour XGBoost intégré, la synchronisation est gérée par le conteneur ; pour un script personnalisé, il faut la coder ou utiliser torch.distributed / horovod (module 5). Sur 240 000 lignes, la distribution est contre-productive — la synchronisation coûte plus cher que le calcul économisé. Elle devient utile à partir de 20 millions de lignes.
En résumé
- Une tâche d'entraînement est une instance éphémère provisionnée, exécutée puis libérée ; sa facturation inclut le provisionnement et le téléversement final.
- L'
XGBoostintégré prend unParqueten entrée, écrit son artefact danss3://.../model.tar.gzet exposera cette même archive aux modules 7 et 8. - Les journaux
CloudWatchlivrent la courbetrain/validationen direct ; c'est là qu'on lit surajustement et plage d'exploration pour le réglage. - Les instances Spot offrent 60 à 70 % de remise ; elles exigent
max_wait ≥ max_runet un point de reprise S3 pour ne pas perdre l'entraînement en cas d'interruption.
Module suivant : quitter l'algorithme intégré pour un script scikit-learn en mode script, avec les variables d'environnement SageMaker et le débogage local.