Comment utiliser des conteneurs custom dans SageMaker pour l'inférence avec LightGBM (guide pas à pas)
AWS Machine Learning

Comment utiliser des conteneurs custom dans SageMaker pour l'inférence avec LightGBM (guide pas à pas)

Fernando Loor
Fernando Loor | | 14 min de lecture

Quand on travaille avec des modèles de machine learning en production, on se concentre souvent sur le fait de servir des prédictions en temps réel. Mais que se passe-t-il quand on doit traiter de gros volumes de données de façon offline ? Dans ces cas-là, on utilise l’inférence en batch.

Dans le cloud AWS, le service conçu pour ce type d’opérations est SageMaker Batch Transform, une solution qui permet d’appliquer des modèles sur des datasets entiers, sans avoir besoin de monter un endpoint d’inférence.

Or, Amazon SageMaker supporte nativement plusieurs frameworks comme XGBoost, TensorFlow ou PyTorch, mais des modèles comme LightGBM (un modèle assez courant dans la discipline) ne figurent pas parmi les conteneurs préconstruits d’AWS. C’est pourquoi, si on veut l’utiliser pour de l’inférence batch, il faut construire notre propre conteneur.

Expliquer la méthode pour y arriver est l’objectif de ce tutoriel. Dans ce guide pas à pas, on va montrer comment :

  • Préparer un code local pour prédire avec un modèle LightGBM.
  • L’empaqueter dans une image Docker compatible avec SageMaker.
  • Pousser cette image sur Amazon ECR et utiliser Batch Transform pour exécuter l’inférence sur des fichiers stockés dans S3.

Le tout sans magie, avec des explications claires pour que vous puissiez l’adapter à vos propres projets.

Qu’est-ce qu’AWS SageMaker AI ?

Amazon SageMaker est une plateforme intégrale de machine learning (ML) sur AWS qui simplifie et accélère le workflow pour les data scientists et les professionnels MLOps. Elle abstrait la complexité de l’infrastructure, permettant de se concentrer sur le déploiement d’opérations IA plutôt que sur la gestion des ressources.

Elle couvre chaque étape du cycle de vie d’un modèle de machine learning, de la préparation des données avec intégration aux services AWS comme S3 et Glue, jusqu’à l’entraînement flexible et scalable avec des frameworks populaires (TensorFlow, PyTorch, etc.) sur des instances CPU/GPU gérées automatiquement. Elle offre l’entraînement distribué, l’optimisation des hyperparamètres et la gestion d’expériences.

Elle facilite le déploiement en production avec du hosting en temps réel pour la faible latence et du traitement batch pour les gros datasets. De plus, elle fournit un monitoring continu pour détecter des problèmes comme la dérive des données et la dégradation des performances.

SageMaker inclut des outils intégrés comme des notebooks bases sur Jupyter et SageMaker Pipelines pour automatiser et orchestrer les workflows, améliorant la productivité.

Qu’est-ce que SageMaker Batch Transform et en quoi ça diffère de l’inférence en temps réel ?

Quand on met un modèle en production, il y a deux façons principales de servir des prédictions : l’inférence en temps réel ou l’inférence batch.

  • L’inférence en temps réel implique d’exposer le modèle via un endpoint HTTPS (comme une API). Chaque fois qu’une requête arrive, SageMaker traite les données et renvoie une prédiction instantanée. Cette approche est idéale pour les applications interactives, comme les systèmes de recommandation ou la détection de fraude en temps réel, où la latence est critique.

  • D’un autre côté, SageMaker Batch Transform est conçu pour les scénarios où on n’a pas besoin de réponses immédiates, mais d’appliquer le modèle à de gros volumes de données de façon massive et offline. Au lieu d’envoyer des enregistrements un par un, Batch Transform prend des fichiers entiers depuis S3 (par exemple, un CSV avec des milliers ou millions de lignes), exécute les prédictions en parallèle et stocke les résultats également dans S3. Pas besoin de laisser un endpoint actif ni de se soucier de la disponibilité du modèle.

En résumant tout ça dans un tableau simple :

Caractéristique Inférence en Temps Réel Batch Transform
Latence Faible Élevée (traitement par lots)
Coûts Continus (endpoint actif) À l’usage (selon le job exécuté)
Idéal pour APIs, applications en live Jobs périodiques ou massifs
Input/Output JSON par requête Fichiers dans S3

Au boulot !

C’est un tutoriel un peu plus intermédiaire, mais pas de panique, on ne va pas vous lâcher en route. On va aussi vous laisser quelques liens au cas où il y aurait des sujets à revoir.

Tout le code nécessaire pour suivre le tutoriel se trouve dans le repo par ici.

Prérequis

Avant de plonger dans ce tutoriel, il est préférable d’avoir :

Ressources nécessaires

  • Un compte AWS avec les permissions pour utiliser SageMaker et ECR (il peut y avoir un coût associé de 1 ou 2 USD, principalement pour les images Docker stockées dans AWS ECR)
  • Installation locale de Docker
  • Installation locale de Python
  • Installation locale de Poetry
  • Installation locale de aws cli
  • Installation locale de VSCode (optionnel)

Environnement Python

On installe les dépendances dans un environnement Poetry. En ouvrant un terminal dans le répertoire de travail qu’on va utiliser pour ce tutoriel, on utilise les commandes :

poetry init
poetry add numpy lightgbm scikit-learn pandas kagglehub

Pour travailler avec des jupyter notebooks dans VSCode, il faudra aussi installer le package ipykernel. VSCode proposera de le faire la première fois qu’on lancera le notebook.

Une autre option est de prendre le project.toml du dépôt, le coller dans notre répertoire de travail, et exécuter poetry install dans le shell. Ça créera l’environnement avec les dépendances nécessaires automatiquement.

Préparation du dataset

  • On choisit le dataset. Dans notre cas, fraud détection dataset. On peut le télécharger en installant kagglehub dans notre environnement Python local.

  • C’est un dataset pour un problème de classification, où il s’agit de prédire, à partir de features issues d’une PCA, plus une variable temporelle et le montant de transaction, si la transaction était frauduleuse ou non.

  • On télécharge le dataset localement, on s’assure de séparer les features du target et à partir de là, on fait le split train et test, et on sauvegarde les deux datasets en format csv.

  • Tout cela est réalisé dans le notebook dataset/prepare_data.ipynb.

Étape 1 : Code local pour l’inférence avec LightGBM

1.1 Entraîner le modèle

Le point de départ est un notebook qui fait le training et le testing (sagemaker-batch-transform-tutorial/local_code/01_train_and_test.ipynb). Ce notebook charge simplement le dataset, fait le split en train data et test data, entraîne le modèle et sauvegarde le modèle entraîné.

Mais on a besoin de le séparer en deux parties : le script d’entraînement et celui de test. De cette façon, on sauvegarde le modèle à part, et on peut commencer à paramétrer les chemins des datasets et du modèle.

Le script d’entraînement charge les données d’entraînement, sépare les features et le target du modèle, définit et entraîne le modèle, et sauvegarde localement le modèle entraîné dans un fichier pickle dans le dossier spécifié.

Chargement du gist...

Le script de test charge les données de test, sépare les features et le target du modèle, charge le modèle déjà entraîné, effectue les prédictions et affiche la précision du modèle.

Chargement du gist...

Les scripts locaux sont la base fonctionnelle (rapide à itérer et déboguer). À l’Étape 2, on va les adapter pour qu’ils prennent les données/modèle depuis S3 et tournent dans un conteneur Docker compatible avec SageMaker, pour passer de “test local” à des jobs reproductibles (Training/Batch Transform) sans réécrire la logique. Voyons comment :

Étape 2 : Créer un conteneur Docker pour l’inférence avec LightGBM

Dans cette section, on prend les scripts développés précédemment, on les parametrise pour qu’ils prennent les chemins des fichiers depuis S3, et on construit les dockerfile et les scripts qui seront les entrypoints pour train et test.

On a la structure de dossiers suivante :

Chargement du gist...
  • On crée des dossiers pour train, test et models. Le dossier “dataset” restera plus haut.
  • Il faut uploader les fichiers CSV utilisés pour l’entraînement et le test vers S3. Il faut créer un bucket et remplacer le nom la où c’est nécessaire : tout au long du tutoriel vous le verrez comme <bucket-propio>. À l’intérieur, un dossier datasets, et des dossiers train_data et test_data, où on uploade les fichiers csv générés.
  • La structure doit ressembler à : s3://<bucket-propio>/datasets/train_data/train.csv

2.1 Construire l’image

Depuis le répertoire containers, on exécute la commande pour construire l’image, selon les instructions du Dockerfile (c’est très standard, rien d’inhabituel).

docker build -t lightgbm-train ./train

Pour l’exécuter, on prépare un script shell qui charge les access keys AWS et passe en paramètres les adresses S3 nécessaires pour obtenir les données et sauvegarder le modèle.

Chargement du gist...

Maintenant vient la partie amusante. Ce script est conçu pour s’exécuter à l’intérieur d’un conteneur dans SageMaker : il prend les données d’entraînement depuis S3, entraîne le modèle LightGBM et uploade le résultat de nouveau vers S3. C’est ni plus ni moins la base pour pouvoir l’intégrer dans un SageMaker Training Job reproductible.

Chargement du gist...

Pour lancer l’entraînement, on exécute simplement le script shell d’entraînement :

$./train.sh

2.2. Exécuter l’inférence

Pour lancer le conteneur d’inférence, on prépare un script shell qui charge les access keys AWS configurées localement, et passe en paramètre l’adresse S3 nécessaire pour obtenir le modèle.

Chargement du gist...

Avec ça en place, on peut build l’image avec :

docker build -t lightgbm-test ./test

Et que contient le script de test ?

Chargement du gist...

Ce qu’il fait :

  • Télécharge le dataset de test et le modèle entraîné depuis S3.
  • Charge les deux en mémoire.
  • Exécute les prédictions avec predict_proba() de LightGBM.
  • Affiche les probabilités de la classe positive.

Étape 3 : Pousser les images vers ECR et exécuter dans SageMaker

En résumé, dans cette section on verra :

  • Comment construire des conteneurs pour entraîner notre modèle avec un SageMaker Training Job,
  • Comment l’enregistrer dans le SageMaker Model Registry,
  • Comment l’utiliser pour faire de l’inférence en Batch sur des données dans S3.

Pour les Jobs d’entraînement et d’inférence, on fera de petits ajustements sur nos conteneurs, et pour déclencher les jobs et enregistrer les modèles, on utilisera des fonctions Lambda. Mais d’abord on doit être authentifié avec notre compte AWS et avoir l’AWS CLI installé et configuré.

De façon graphique, les étapes à réaliser pour développer l’entraînement avec un SageMaker Training Job et l’inférence avec un SageMaker Batch Transform Job sont décrites dans les figures suivantes :

Diagramme du processus d’entrainement dans SageMaker avec LightGBM

Diagramme du processus d’inference batch avec LightGBM dans SageMaker

3.1. Login à ECR et création des repos

La première étape est de créer le repo, ce qu’on ne fait qu’une seule fois. Ici aussi il faudra remplacer certains caractères et IDs par ceux de votre compte :

aws ecr create-repository --repository-name lightgbm-testing-container

Conservez l’URI renvoyé par la commande, qu’on va appeler <repo-uri> à partir de maintenant. Ça devrait ressembler à :

`<id-de-nuestra-cuenta>`.dkr.ecr.us-east-2.amazonaws.com/lightgbm-testing-container

Maintenant on se connecte avec Docker :

aws ecr get-login-password | docker login --username AWS --password-stdin `<id-de-nuestra-cuenta>`.dkr.ecr.`<region>`.amazonaws.com

3.2. Build & Push

On se place dans le dossier containers_sagemaker/ et depuis la on exécute :

docker build -t lightgbm-test-sm ./test

Avec ça fait, on tag et on push l’image :

docker tag lightgbm-test-sm:latest <repo-uri>
docker push <repo-uri>

3.3. Héberger les données

Enfin, il faut déposer les données dans un bucket S3, idéalement dans un chemin de ce style :

s3://<bucket-propio>/datasets/train_data/train.csv

3.4. Fonction Lambda : Training Job

Maintenant on va utiliser une Lambda pour déclencher le job d’entraînement.

Important : il faut avoir un rôle IAM avec la capacité d’accéder et d’exécuter sur S3 et SageMaker. Pour l’exemple, on en a créé un appelé free-tier-sagemaker-full-access-role avec les politiques AmazonS3FullAccess et SagemakerFullAccess.

Chargement du gist...

Maintenant il faut créer la Lambda lgbm_sm_launch_training_job. Cette Lambda a une layer SageMaker (voici un article de chez nous où on explique aussi comment les utiliser, au cas où), donc il faut installer les requirements localement et créer un package qui sera uploade avec la fonction. Comme le package pèse plus de 50 Mo à la création, il faut l’uploader dans un emplacement S3 et le charger dans le service Lambda depuis S3.

Un détail important du requirements.txt de cette Lambda : on a besoin de la version sagemaker==2.215, sinon on obtiendra l’erreur : “No module named ‘rpds.rpds’”. Ce genre d’erreurs et avertissements est très courant quand on installe des packages de différentes sources.

Chargement du gist...

Remarquez comment on installe les dépendances : le -t package/ à la fin fait en sorte qu’au lieu d’installer les bibliothèques dans l’environnement global ou virtuel (site-packages), elles sont installées dans le dossier local package/. C’est courant dans des projets comme celui-ci, où on a besoin d’empaqueter les dépendances avec notre code (comme c’est souvent nécessaire dans une Lambda).

Pour que la fonction puisse utiliser les dépendances empaquetées, il faut les associer comme Lambda Layer. Ça se fait depuis la console AWS Lambda, dans l’onglet Layers, en créant une nouvelle layer et en y uploadant le fichier lambda_package.zip (ou en indiquant l’emplacement dans S3).

Une fois créée, la layer est disponible et on peut l’attacher à notre fonction lgbm_sm_launch_training_job depuis la même console ou via AWS CLI. De cette façon, la Lambda aura accès aux bibliothèques nécessaires (dans ce cas, sagemaker==2.215) sans dépasser la limite de taille du deployment package.

Un autre détail important est de faire correspondre la version de Python de la Lambda locale avec la version de Python définie à la création de la Lambda dans la console (UI) d’AWS.

Après l’exécution réussie de la Lambda, on pourra voir que un SageMaker Training Job a été déclenché, et une fois terminé, notre modèle fraîchement entraîné sera stocké dans le répertoire spécifié dans la Lambda (dans notre cas, s3://<bucket-propio>/models_sm/).

3.5. Fonction Lambda pour enregistrer le modèle

Ici on cherche à enregistrer le modèle dans le SageMaker Model Registry, pour lier l’image Docker hébergée dans ECR avec l’ARN du modèle entraîné via le SageMaker Training Job. Ainsi, par la suite, en invoquant l’image, le modèle déjà spécifié sera utilisé.

Chargement du gist...

Le point central est l’appel à create_model pour enregistrer un nouveau SageMaker Model, en liant :

  • Le conteneur d’inférence (image Docker dans ECR).
  • L’artefact entraîné (modèle dans S3).
  • Le rôle IAM qui autorise l’exécution.

Avec ça, le modèle est enregistré dans SageMaker et disponible pour être utilisé dans des endpoints ou des Batch Transform Jobs.

3.6. Fonction Lambda pour lancer le Batch Transform Job

Dans ce cas, on va créer un transformer qui recevra comme paramètre principal le nom du modèle tel qu’il a été enregistré dans le SageMaker Model Registry à l’étape précédente. Notez qu’on ne fait référence à aucune autre donnée ou emplacement du modèle entraîné : tout sera obtenu depuis le Registry de SageMaker.

Le Batch Transform Job sera créé en utilisant la méthode transform() du Transformer. Cette méthode permet de spécifier quelles colonnes du dataset d’entrée seront envoyées au modèle pour l’inférence, et comment sera composé le fichier de prédictions : on peut choisir de livrer uniquement les prédictions, ou d’incorporer aussi les features utilisées pour l’inférence, et la colonne d’ID qui identifie chaque enregistrement d’entrée (si elle existe).

Chargement du gist...

Après le job, les résultats seront dans notre bucket S3. Si on le souhaite, en suivant la nomenclature du bucket utilisé, on peut les télécharger avec :

aws s3 cp s3://<bucket-propio>/predictions/test.csv.out .

En conclusion…

On a créé une solution personnalisée et scalable pour faire de l’inférence batch avec des modèles LightGBM dans SageMaker. Cette architecture permet de réutiliser des modèles entraînés et de maintenir des pipelines reproductibles dans un environnement MLOps professionnel.

Dans les prochains volets, on pourra voir des opérations complémentaires à l’inférence elle-même, nécessaires pour obtenir un modèle productif robuste.

Des questions ou des suggestions ? Vous pouvez écrire à fernando@deployr.ai ou laisser un commentaire sur le blog.


Références supplémentaires :

  1. Fraud detection dataset
  2. Batch transform for inference with Amazon SageMaker AI
  3. Exemple : Customer Churn Prediction with XGBoost
  4. Batch Transform Input and Output Filters
  5. Tabular classification with Amazon SageMaker LightGBM and CatBoost algorithm
  6. SageMaker Batch Transform – Emily Webber from AWS
  7. Conteneurs pour Batch transform et pour inférence
  8. Amazon – Adapt your own inference container
  9. SageMaker – Bring your own container
Fernando Loor

Fernando Loor

ML Engineer @ deployr

Partager

Vous avez un vrai problème technique ?

On ne vend pas de solutions génériques. Parlons de ce que vous devez résoudre.

Parlons-en