Optimisez vos tâches d'inférence à l'aide de l'inférence dynamique par lots avec TorchServe sur Amazon SageMaker

Nœud source: 1884601

Dans l'apprentissage en profondeur, le traitement par lots fait référence à l'alimentation de plusieurs entrées dans un modèle. Bien que cela soit essentiel pendant la formation, il peut également être très utile de gérer les coûts et d'optimiser le débit pendant le temps d'inférence. Les accélérateurs matériels sont optimisés pour le parallélisme, et le traitement par lots aide à saturer la capacité de calcul et conduit souvent à un débit plus élevé.

Le traitement par lots peut être utile dans plusieurs scénarios lors du déploiement du modèle en production. Ici, nous les classons globalement en deux cas d'utilisation :

  • Applications en temps réel où plusieurs demandes d'inférence sont reçues de différents clients et sont dynamiquement regroupées et transmises au modèle de service. La latence est généralement importante dans ces cas d'utilisation.
  • Applications hors ligne où plusieurs entrées ou requêtes sont regroupées côté client et envoyées au modèle de service. Un débit plus élevé est souvent l'objectif de ces cas d'utilisation, ce qui permet de gérer les coûts. Des exemples de cas d'utilisation incluent l'analyse vidéo et l'évaluation de modèles.

Amazon Sage Maker fournit deux options populaires pour vos travaux d'inférence. Pour les applications en temps réel, SageMaker Hosting utilise TorchServe comme bibliothèque de service backend qui gère le traitement par lots dynamique des demandes reçues. Pour les applications hors ligne, vous pouvez utiliser les tâches de transformation par lots SageMaker. Dans cet article, nous passons en revue un exemple de chaque option pour vous aider à démarrer.

Parce que TorchServe est nativement intégré à SageMaker via le Boîte à outils d'inférence SageMaker PyTorch, vous pouvez facilement déployer un modèle PyTorch sur TorchServe à l'aide de l'hébergement SageMaker. Il peut également arriver que vous ayez besoin de personnaliser davantage votre environnement à l'aide d'images Docker personnalisées. Dans cet article, nous montrons d'abord comment déployer un point de terminaison en temps réel à l'aide de la boîte à outils d'inférence native SageMaker PyTorch et comment configurer la taille du lot pour optimiser le débit. Dans le deuxième exemple, nous montrons comment utiliser une image Docker personnalisée pour configurer des configurations TorchServe avancées qui ne sont pas disponibles en tant que variable d'environnement pour optimiser votre travail d'inférence par lots.

Meilleures pratiques pour l'inférence par lots

Le traitement par lots peut augmenter le débit et optimiser vos ressources car il permet de réaliser un plus grand nombre d'inférences dans un certain laps de temps au détriment de la latence. Pour optimiser le déploiement du modèle pour un débit plus élevé, la règle générale consiste à augmenter la taille du lot jusqu'à ce que le débit diminue. Cela convient le plus souvent aux applications hors ligne, où plusieurs entrées sont regroupées (telles que des images vidéo, des images ou du texte) pour obtenir des sorties de prédiction.

Pour les applications en temps réel, la latence est souvent une préoccupation majeure. Il existe un compromis entre un débit plus élevé et une taille et une latence de lot accrues ; vous devrez peut-être ajuster au besoin pour respecter votre SLA de latence. En termes de meilleures pratiques sur le cloud, le coût par un certain nombre d'inférences est une indication utile pour prendre une décision éclairée qui répond aux besoins de votre entreprise. L'un des facteurs contribuant à la gestion des coûts est le choix du bon accélérateur. Pour plus d'informations, voir Choisissez le meilleur accélérateur d'IA et la compilation de modèles pour l'inférence de vision par ordinateur avec Amazon SageMaker.

Dosage dynamique TorchServe sur SageMaker

TorcheServe est la bibliothèque native PyTorch pour servir des modèles en production à grande échelle. C'est un développement conjoint de Facebook et AWS. TorchServe vous permet de surveiller, d'ajouter des métriques personnalisées, de prendre en charge plusieurs modèles, d'augmenter et de réduire le nombre de travailleurs via des API de gestion sécurisées et de fournir des points de terminaison d'inférence et d'explication.

Pour prendre en charge le traitement par lots, TorchServe fournit une fonction de traitement par lots dynamique. Il regroupe les demandes reçues dans un délai spécifié, les regroupe et envoie le lot pour inférence. Les demandes reçues sont traitées via le Manipulateurs dans TorchServe. TorchServe a plusieurs gestionnaires par défaut, et vous pouvez créer un gestionnaire personnalisé si votre cas d'utilisation n'est pas couvert. Lorsque vous utilisez un gestionnaire personnalisé, assurez-vous que la logique d'inférence par lots a été implémentée dans le gestionnaire. Un exemple de gestionnaire personnalisé avec prise en charge de l'inférence par lots est disponible sur GitHub.

Vous pouvez configurer le traitement par lot dynamique à l'aide de deux paramètres, batch_size ainsi que max_batch_delay, soit via des variables d'environnement dans SageMaker, soit via le config.properties fichier dans TorchServe (si vous utilisez un conteneur personnalisé). TorchServe utilise l'un des paramètres qui vient en premier, soit la taille de lot maximale (batch_size) ou la fenêtre de temps spécifiée pour attendre le lot de demandes via max_batch_delay.

Grâce aux intégrations TorchServe avec SageMaker, vous pouvez désormais déployer des modèles PyTorch de manière native sur SageMaker, où vous pouvez définir un modèle SageMaker PyTorch. Vous pouvez ajouter une logique de chargement, d'inférence et de prétraitement et de post-traitement de modèle personnalisé dans un script transmis comme point d'entrée à SageMaker PyTorch (voir l'exemple de code suivant). Vous pouvez également utiliser un conteneur personnalisé pour déployer vos modèles. Pour plus d'informations, voir Le serveur de modèles SageMaker PyTorch.

Vous pouvez définir la taille du lot pour les modèles PyTorch sur SageMaker via des variables d'environnement. Si vous choisissez d'utiliser un conteneur personnalisé, vous pouvez regrouper Paramétres in config.properties avec votre modèle lors de l'emballage de votre modèle dans TorchServe. L'extrait de code suivant montre comment définir la taille du lot à l'aide de variables d'environnement et comment déployer un modèle PyTorch sur SageMaker :

from SageMaker.pytorch.model import PyTorchModel env_variables_dict = { "SAGEMAKER_TS_BATCH_SIZE": "3", "SAGEMAKER_TS_MAX_BATCH_DELAY": "100000"
} pytorch_model = PyTorchModel( model_data=model_artifact, role=role, source_dir="code", framework_version='1.9', entry_point="inference.py", env=env_variables_dict
) predictor = pytorch_model.deploy(initial_instance_count=1, instance_type="ml.c5.2xlarge", serializer=SageMaker.serializers.JSONSerializer(), deserializer=SageMaker.deserializers.BytesDeserializer())

Dans l'extrait de code, model_artifact fait référence à tous les fichiers requis pour recharger le modèle formé, qui est archivé dans un fichier .tar et poussé dans un Service de stockage simple Amazon (Amazon S3). Le inference.py est similaire au gestionnaire personnalisé TorchServe ; il comporte plusieurs fonctions que vous pouvez remplacer pour prendre en charge l'initialisation du modèle, le prétraitement et le post-traitement des demandes reçues et la logique d'inférence.

cahier montre un exemple complet de déploiement d'un modèle BERT Hugging Face.

Si vous avez besoin d'un conteneur personnalisé, vous pouvez créer une image de conteneur personnalisée et la pousser vers le Registre des conteneurs élastiques Amazon (Amazon ECR). L'artefact de modèle dans ce cas peut être un fichier TorchServe .mar qui regroupe les artefacts de modèle avec le gestionnaire. Nous le démontrons dans la section suivante, où nous utilisons une tâche de transformation par lots SageMaker.

Tâche de transformation par lots SageMaker

Pour les cas d'utilisation hors ligne où les requêtes sont regroupées à partir d'une source de données telle qu'un ensemble de données, SageMaker fournit tâches de transformation par lots. Ces tâches vous permettent de lire les données d'un compartiment S3 et d'écrire les résultats dans un compartiment S3 cible. Pour plus d'informations, voir Utiliser la transformation par lots pour obtenir des inférences à partir de grands ensembles de données. Un exemple complet d'inférence par lots à l'aide de tâches de transformation par lots peut être trouvé dans ce qui suit cahier, où nous utilisons un modèle de traduction automatique du concours FLORES. Dans cet exemple, nous montrons comment utiliser un conteneur personnalisé pour évaluer notre modèle à l'aide de SageMaker. L'utilisation d'un conteneur d'inférence personnalisé vous permet de personnaliser davantage votre configuration TorchServe. Dans cet exemple, nous voulons modifier et désactiver le décodage JSON, ce que nous pouvons faire via le TorchServe config.properties fichier.

Lors de l'utilisation d'un gestionnaire personnalisé pour TorchServe, nous devons nous assurer que le gestionnaire implémente la logique d'inférence par lots. Chaque gestionnaire peut avoir des fonctions personnalisées pour effectuer le prétraitement, l'inférence et le post-traitement. Un exemple de gestionnaire personnalisé avec prise en charge de l'inférence par lots est disponible sur GitHub.

Nous utilisons notre conteneur personnalisé pour regrouper les artefacts de modèle avec le gestionnaire comme nous le faisons dans TorchServe (créer un fichier .mar). Nous avons également besoin d'un point d'entrée vers le conteneur Docker qui démarre TorchServe avec la taille du lot et le décodage JSON définis dans config.properties. Nous le démontrons dans l'exemple cahier.

Le travail de transformation par lots SageMaker nécessite l'accès aux fichiers d'entrée à partir d'un compartiment S3, où il divise les fichiers d'entrée en mini-lots et les envoie pour inférence. Tenez compte des points suivants lors de la configuration de la tâche de transformation par lots :

  • Placez les fichiers d'entrée (tels qu'un ensemble de données) dans un compartiment S3 et définissez-le comme source de données dans les paramètres de la tâche.
  • Attribuez un compartiment S3 dans lequel enregistrer les résultats de la tâche de transformation par lots.
  • Ensemble Stratégie par lots à MultiRecord ainsi que SplitType à Line si vous avez besoin du travail de transformation par lots pour créer des mini-lots à partir du fichier d'entrée. S'il ne peut pas diviser automatiquement l'ensemble de données en mini-lots, vous pouvez le diviser en mini-lots en plaçant chaque lot dans un fichier d'entrée séparé, placé dans le compartiment S3 de la source de données.
  • Assurez-vous que la taille du lot tient dans la mémoire. SageMaker gère généralement cela automatiquement ; cependant, lors de la division manuelle des lots, cela doit être réglé en fonction de la mémoire.

Le code suivant est un exemple de tâche de transformation par lot :

s3_bucket_name= 'SageMaker-us-west-2-XXXXXXXX'
batch_input = f"s3://{s3_bucket_name}/folder/jobename_TorchServe_SageMaker/"
batch_output = f"s3://{s3_bucket_name}/folder/jobname_TorchServe_SageMaker_output/" batch_job_name = 'job-batch' + time.strftime("%Y-%m-%d-%H-%M-%S", time.gmtime())
batch_job_name request = { "ModelClientConfig": { "InvocationsTimeoutInSeconds": 3600, "InvocationsMaxRetries": 1, }, "TransformJobName": batch_job_name, "ModelName": model_name, "MaxConcurrentTransforms":1, "BatchStrategy": "MultiRecord", "TransformOutput": {"S3OutputPath": batch_output, "AssembleWith": "Line", "Accept": "application/json"}, "TransformInput": { "DataSource": { "S3DataSource": {"S3DataType": "S3Prefix", "S3Uri": batch_input} }, "SplitType" : "Line", "ContentType": "application/json", }, "TransformResources": {"InstanceType": "ml.p2.xlarge", "InstanceCount": 1},
}

Lorsque nous utilisons les paramètres précédents et lançons notre tâche de transformation, il lit les fichiers d'entrée du compartiment S3 source par lots et les envoie pour inférence. Les résultats sont réécrits dans le compartiment S3 spécifié dans les sorties.

L'extrait de code suivant montre comment créer et lancer une tâche à l'aide des paramètres précédents :

sm.create_transform_job(**request) while True: response = sm.describe_transform_job(TransformJobName=batch_job_name) status = response["TransformJobStatus"] if status == "Completed": print("Transform job ended with status: " + status) break if status == "Failed": message = response["FailureReason"] print("Transform failed with the following error: {}".format(message)) raise Exception("Transform job failed") print("Transform job is still in status: " + status) time.sleep(30)

Conclusion

Dans cet article, nous avons passé en revue les deux modes proposés par SageMaker pour l'inférence en ligne et hors ligne. Le premier utilise le traitement par lots dynamique fourni dans TorchServe pour regrouper les demandes de plusieurs clients. Ce dernier utilise une tâche de transformation SageMaker pour regrouper les demandes des fichiers d'entrée dans un compartiment S3 et exécuter l'inférence.

Nous avons également montré comment servir des modèles sur SageMaker à l'aide d'images de conteneurs natives de la boîte à outils d'inférence SageMaker PyTorch, et comment utiliser des conteneurs personnalisés pour les cas d'utilisation qui nécessitent des paramètres de configuration TorchServe avancés.

Alors que TorchServe continue d'évoluer pour répondre aux besoins de la communauté PyTorch, de nouvelles fonctionnalités sont intégrées à SageMaker pour fournir des moyens performants de servir des modèles en production. Pour plus d'informations, consultez le Dépôt TorchServe GitHub et par Exemples SageMaker.


À propos des auteurs

Phi Nguyen est un architecte de solutions chez AWS qui aide les clients dans leur parcours cloud avec un accent particulier sur le lac de données, l'analyse, les technologies sémantiques et l'apprentissage automatique. Pendant son temps libre, vous pouvez le trouver en vélo pour se rendre au travail, entraîner l'équipe de football de son fils ou profiter d'une promenade dans la nature avec sa famille.

Nikhil Kulkarni est un développeur de logiciels avec AWS Machine Learning, qui se concentre sur l'amélioration des performances des charges de travail d'apprentissage automatique sur le cloud et est co-créateur d'AWS Deep Learning Containers pour la formation et l'inférence. Il est passionné par les systèmes d'apprentissage profond distribués. En dehors du travail, il aime lire des livres, jouer de la guitare et faire des pizzas.

Hamid Shojanazeri est un ingénieur partenaire chez Pytorch travaillant sur l'optimisation et le service de modèles OSS haute performance. Hamid est titulaire d'un doctorat en vision par ordinateur et a travaillé comme chercheur dans des laboratoires multimédias en Australie, en Malaisie et en tant que responsable de la PNL chez Opus.ai. Il aime trouver des solutions plus simples à des problèmes difficiles et est un passionné d'art à ses heures perdues.

Geeta Chauhan dirige l'ingénierie des partenaires IA chez Meta AI avec une expertise dans la construction de plates-formes distribuées résilientes, anti-fragiles et à grande échelle pour les startups et les Fortune 500. Son équipe travaille avec des partenaires stratégiques, des leaders de l'apprentissage automatique de l'industrie et tous les principaux fournisseurs de services cloud pour créer et lancer de nouveaux services et expériences de produits d'IA ; et en faisant passer les modèles PyTorch de la recherche à la production. Elle est passionnée par la promotion de l'utilisation de l'IA pour le bien.

Source : https://aws.amazon.com/blogs/machine-learning/optimize-your-inference-jobs-using-dynamic-batch-inference-with-torchserve-on-amazon-sagemaker/

Horodatage:

Plus de Blog sur l'apprentissage automatique AWS