Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
APPLIES TO :
Extension Azure ML CLI v2 (actuelle)
Kit de développement logiciel (SDK) Python azure-ai-ml v2 (préversion)
Les points de terminaison par lots vous permettent de déployer des modèles qui effectuent une inférence de longue durée à grande échelle. Lors du déploiement de modèles, vous devez créer et spécifier un script de scoring (également appelé script de pilote batch) pour indiquer comment utiliser le modèle sur les données d’entrée pour créer des prédictions. Dans cet article, vous allez apprendre à utiliser des scripts de scoring dans les déploiements de modèles pour différents scénarios. Vous découvrez également les meilleures pratiques pour les points de terminaison de traitement par lots.
Conseil
Les modèles MLflow ne nécessitent pas de script de scoring. Le service le génère automatiquement pour vous. Pour plus d’informations sur le fonctionnement des points de terminaison par lots avec les modèles MLflow, consultez le tutoriel dédié Utilisation de modèles MLflow dans les déploiements par lots.
Avertissement
Pour déployer un modèle AutoML dans le cadre d'un point de terminaison par lot, notez qu'AutoML fournit un script de scoring qui fonctionne uniquement pour les points de terminaison en ligne. Ce script de scoring n’est pas conçu pour l’exécution par lots. Pour plus d’informations sur la création d’un script de scoring personnalisé pour ce que fait votre modèle, consultez les instructions suivantes.
Présentation le script de scoring
Le script de scoring est un fichier Python (.py) qui spécifie comment exécuter le modèle et lire les données d’entrée envoyées par l’exécuteur de déploiement par lots. Chaque modèle de déploiement fournit le script de scoring (ainsi que toutes autres dépendances nécessaires) au moment de la création. Le script de scoring ressemble généralement à ceci :
deployment.yml
code_configuration:
code: code
scoring_script: batch_driver.py
Le script de scoring doit contenir deux méthodes :
La méthode init
Utilisez la méthode init() pour toute préparation coûteuse ou courante. Par exemple, utilisez-la pour charger le modèle en mémoire. Le début de l’ensemble du programme de traitement par lots appelle cette fonction une fois. Les fichiers de votre modèle sont disponibles dans un chemin d’accès déterminé par la variable d’environnement AZUREML_MODEL_DIR. Selon la façon dont vous avez inscrit votre modèle, ses fichiers peuvent être contenus dans un dossier. Dans l’exemple suivant, le modèle comporte plusieurs fichiers dans un dossier nommé model. Pour plus d’informations, consultez Déterminer le dossier utilisé par votre modèle.
def init():
global model
# AZUREML_MODEL_DIR is an environment variable created during deployment
# The path "model" is the name of the registered model's folder
model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")
# load the model
model = load_model(model_path)
Dans cet exemple, vous placez le modèle dans la variable modelglobale. Pour rendre disponible les ressources nécessaires à l’inférence sur votre fonction de scoring, utilisez ds variables globales.
La méthode run
Utilisez la méthode run(mini_batch: List[str]) -> Union[List[Any], pandas.DataFrame] pour gérer le scoring de chaque mini-lot généré par le déploiement par lots. Cette méthode est appelée une fois pour chaque mini_batch généré pour vos données d’entrée. Les déploiements batch lisent les données par lots en fonction de la façon dont vous configurez le déploiement.
import pandas as pd
from typing import List, Any, Union
def run(mini_batch: List[str]) -> Union[List[Any], pd.DataFrame]:
results = []
for file in mini_batch:
(...)
return pd.DataFrame(results)
La méthode reçoit une liste de chemins de fichiers comme paramètre (mini_batch). Vous pouvez utiliser cette liste pour itérer et traiter individuellement chaque fichier, ou pour lire l’intégralité du lot et le traiter d’un seul coup. La meilleure option dépend de votre mémoire de calcul et du débit que vous devez obtenir. Pour obtenir un exemple de lecture de lots de données entiers en même temps, consultez Déploiements à haut débit.
Remarque
Comment le travail est-il distribué ?
Les déploiements par lots distribuent le travail au niveau des fichiers, ce qui signifie qu’un dossier contenant 100 fichiers, avec des mini-lots de 10 fichiers, génère 10 lots de 10 fichiers chacun. Notez que la taille des fichiers concernés n’a aucune importance. Pour les fichiers trop volumineux à traiter dans des mini-lots volumineux, fractionnez les fichiers en fichiers plus petits pour atteindre un niveau plus élevé de parallélisme, ou diminuez le nombre de fichiers par mini-lot. À ce stade, le déploiement par lots ne peut pas tenir compte des asymétries dans la distribution de la taille du fichier.
La méthode run() doit retourner un Pandas DataFrame ou un tableau/une liste. Chaque élément de sortie retourné indique une exécution réussie d’un élément d’entrée dans le mini_batch. Pour des ressources de données de fichier ou de dossier, chaque ligne/élément retourné représente un seul fichier traité. Pour une ressource de données tabulaires, chaque ligne/élément retourné représente une ligne dans un fichier traité.
Important
Comment écrire des prédictions ?
Tout ce que la run() fonction retourne est ajouté dans le fichier de prédictions de sortie généré par le travail de traitement par lots. Il est important de retourner le type de données approprié à partir de cette fonction. Retournez des tableaux quand vous avez besoin de générer une seule prédiction. Retournez des DataFrames Pandas quand vous avez besoin de retourner divers éléments d’information. Par exemple, pour les données tabulaires, vous pouvez ajouter vos prédictions à l’enregistrement d’origine. Utilisez un DataFrame pandas pour effectuer cette opération. Même si un DataFrame pandas peut contenir des noms de colonnes, le fichier de sortie n’inclut pas ces noms.
Pour écrire des prédictions de différentes manières, vous pouvez personnaliser les sorties dans les déploiements par lots.
Avertissement
Dans la fonction run, ne générez pas de types de données complexes (ni de listes de types de données complexes) au lieu de pandas.DataFrame. Ces sorties sont transformées en chaînes et deviennent difficiles à lire.
Le DataFrame ou le tableau résultant est ajouté au fichier de sortie indiqué. Il n’y a aucune exigence sur la cardinalité des résultats. Un fichier peut générer une ou plusieurs lignes/éléments dans la sortie. Tous les éléments du dataframe ou du tableau de résultats sont écrits dans le fichier de sortie en l’état (en considérant que output_action n’est pas summary_only).
Packages Python pour le scoring
Vous devez indiquer toute bibliothèque dont votre script de scoring a besoin pour s’exécuter dans l’environnement dans lequel votre déploiement par lots s’exécute. Pour les scripts de scoring, indiquez les environnements par déploiement. En règle générale, vous indiquez vos exigences en utilisant un fichier de dépendances conda.yml qui peut se présenter comme ceci :
mnist/environment/conda.yaml
name: mnist-env
channels:
- conda-forge
dependencies:
- python=3.8.5
- pip<22.0
- pip:
- torch==1.13.0
- torchvision==0.14.0
- pytorch-lightning
- pandas
- azureml-core
- azureml-dataset-runtime[fuse]
Pour plus d’informations sur la façon d’indiquer l’environnement de votre modèle, consultez Créer un déploiement par lots.
Écriture de prédictions d’une autre manière
Par défaut, le déploiement par lots écrit les prédictions du modèle dans un seul fichier, comme indiqué dans le déploiement. Toutefois, dans certains cas, vous devez écrire les prédictions dans plusieurs fichiers. Par exemple, pour les données d’entrée partitionnée, vous souhaiterez probablement également générer une sortie partitionnée. Dans ces cas, vous pouvez personnaliser les sorties dans les déploiements par lots pour indiquer :
- Le format de fichier (CSV, parquet, json, etc.) utilisé pour écrire des prédictions
- Le mode de partitionnement des données dans la sortie
Pour plus d’informations, consultez Personnaliser les sorties dans les déploiements par lots.
Contrôle de code source des scripts de scoring
Placez des scripts de scoring sous contrôle de code source.
Meilleures pratiques pour l’écriture de scripts de scoring
Lors de l’écriture de scripts de scoring qui gèrent de grandes quantités de données, tenez compte de plusieurs facteurs, notamment
- La taille de chaque fichier
- Quantité de données dans chaque fichier
- La quantité de mémoire nécessaire pour lire chaque fichier
- La quantité de mémoire nécessaire pour lire un lot entier de fichiers
- L’empreinte mémoire du modèle
- Empreinte mémoire du modèle lors de l’exécution sur les données d’entrée
- La mémoire disponible dans votre calcul
Les déploiements par lots distribuent le travail au niveau des fichiers. Cette distribution signifie qu’un dossier contenant 100 fichiers, dans des mini-lots de 10 fichiers, génère 10 lots de 10 fichiers chacun (quelle que soit la taille des fichiers impliqués). Pour les fichiers trop volumineux à traiter dans des mini-lots volumineux, fractionnez les fichiers en fichiers plus petits pour atteindre un niveau plus élevé de parallélisme, ou diminuez le nombre de fichiers par mini-lot. À ce stade, le déploiement par lots ne peut pas tenir compte des asymétries dans la distribution de taille de fichier.
Relation entre le degré de parallélisme et le script de scoring
Votre configuration de déploiement contrôle à la fois la taille de chaque mini-lot et le nombre de rôles de travail sur chaque nœud. Cette configuration est importante lorsque vous décidez de lire l’intégralité du mini-lot pour effectuer l’inférence, exécuter le fichier d’inférence par fichier ou exécuter la ligne d’inférence par ligne (pour tabulaire). Pour plus d’informations, consultez Exécution de l’inférence au niveau du mini-lot, du fichier ou de la ligne.
Lorsque vous exécutez plusieurs workers sur la même instance, n’oubliez pas que tous les workers partagent de la mémoire. Si vous augmentez le nombre de travailleurs par nœud, vous devez généralement diminuer la taille du mini-lot ou modifier la stratégie de notation si la taille des données et la référence UGS de calcul restent les mêmes.
Exécution de l’inférence au niveau du mini-lot, du fichier ou de la ligne
Les points de terminaison par lots appellent la fonction run() dans un script de scoring une fois par mini-lot. Cependant, vous pouvez décider si vous souhaitez exécuter l’inférence sur l’ensemble du lot, sur un fichier à la fois ou sur une ligne à la fois pour les données tabulaires.
Niveau du mini-lot
En règle générale, vous exécutez l’inférence sur l’ensemble du lot pour obtenir un débit élevé dans votre processus de scoring par lots. Cette approche fonctionne bien si vous exécutez l’inférence sur un GPU, où vous souhaitez saturer l’appareil d’inférence. Vous pouvez également utiliser un chargeur de données capable de gérer le traitement par lot lui-même si les données ne tiennent pas dans la mémoire, comme les chargeurs de données TensorFlow ou PyTorch. Dans ces cas, vous exécutez l’inférence sur l’ensemble du lot.
Avertissement
L’exécution de l’inférence au niveau du lot peut nécessiter un contrôle étroit sur la taille des données d’entrée afin de prendre correctement en compte les exigences en matière de mémoire et éviter les exceptions de mémoire insuffisante. La possibilité ou non de charger l’intégralité du mini-lot en mémoire dépend de la taille du mini-lot, de la taille des instances dans le cluster et du nombre de rôles de travail sur chaque nœud.
Consultez Déploiements à débit élevé pour savoir comment y parvenir. Cet exemple traite un lot entier de fichiers à la fois.
Niveau du fichier
L’une des façons les plus simples d’effectuer l’inférence consiste à itérer sur tous les fichiers du mini-lot, puis à exécuter le modèle sur chaque fichier. Dans certains cas, comme le traitement d’images, cette approche fonctionne bien. Pour les données tabulaires, vous devez estimer le nombre de lignes dans chaque fichier. Cette estimation indique si votre modèle peut gérer les besoins en mémoire pour charger toutes les données entières en mémoire et effectuer une inférence sur celle-ci. Certains modèles (en particulier ceux basés sur des réseaux neuronaux récurrents) déplient et présentent une empreinte mémoire avec un nombre de lignes potentiellement non linéaire. Pour un modèle avec une consommation de mémoire haute, envisagez d’exécuter l’inférence au niveau de la ligne.
Conseil
Envisagez de décomposer les fichiers trop volumineux à lire simultanément dans plusieurs fichiers plus petits, afin d’améliorer la parallélisation.
Pour plus d’informations sur cette procédure, consultez Traitement d’images avec des déploiements par lots. Cet exemple traite un fichier à la fois.
Niveau de la ligne (tabulaire)
Pour les modèles qui présentent des défis dus à leurs tailles d’entrée, vous pouvez exécuter l’inférence au niveau de la ligne. Votre déploiement par lots fournit toujours votre script de scoring avec un mini-lot de fichiers. Toutefois, vous lisez un fichier, une ligne à la fois. Cette approche peut sembler inefficace, mais pour certains modèles d’apprentissage profond, il peut s’agir du seul moyen d’effectuer l’inférence sans effectuer de scale-up de vos ressources matérielles.
Pour plus d’informations sur cette procédure, consultez Traitement de texte avec des déploiements par lots. Cet exemple traite une ligne à la fois.
Utilisation de modèles qui sont des dossiers
La AZUREML_MODEL_DIR variable d’environnement contient le chemin d’accès à l’emplacement du modèle sélectionné. La init() fonction l’utilise généralement pour charger le modèle en mémoire. Toutefois, certains modèles peuvent contenir leurs fichiers dans un dossier et vous devrez peut-être tenir compte de cette structure lors du chargement. Vous pouvez identifier la structure du dossier de votre modèle comme indiqué ci-dessous :
Accédez au portail Azure Machine Learning.
Accédez à la section Modèles.
Sélectionnez le modèle à déployer et sélectionnez l’onglet Artefacts.
Notez le dossier affiché. Ce dossier est indiqué lorsque le modèle est enregistré.
Utilisez ce chemin d’accès pour charger le modèle :
def init():
global model
# AZUREML_MODEL_DIR is an environment variable created during deployment
# The path "model" is the name of the registered model's folder
model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")
model = load_model(model_path)