Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Déployez de grands modèles à des fins d'inférence avec TorchServe
Ce didacticiel explique comment déployer de grands modèles et effectuer des inférences dans Amazon SageMaker AI à l'aide de TorchServe GPU intégrés. Cet exemple déploie le OPT-30b ml.g5 instance. Vous pouvez le modifier pour l'adapter à d'autres modèles et types d'instance. Dans les exemples, remplacez par vos propres informations.italicized placeholder text
TorchServe est une puissante plateforme ouverte pour l'inférence de modèles distribués à grande échelle. En prenant en charge des bibliothèques populaires telles que PyTorch PippY native et HuggingFace Accelerate, il propose des API de gestion uniformes qui restent cohérentes dans les scénarios d'inférence de modèles distribués et non distribués. DeepSpeed Pour plus d'informations, consultez TorchServe la documentation
Conteneurs de deep learning avec TorchServe
Pour déployer un grand modèle sans TorchServe SageMaker IA, vous pouvez utiliser l'un des conteneurs d'apprentissage en profondeur (DLC) SageMaker AI. Par défaut, TorchServe il est installé dans tous les AWS PyTorch DLC. Pendant le chargement du modèle, TorchServe vous pouvez installer des bibliothèques spécialisées adaptées aux grands modèles tels que PippY, Deepspeed et Accelerate.
Le tableau suivant répertorie tous les DLC SageMaker AI avec TorchServe
| Catégorie de DLC | Cadre | Matériel | Exemple d'URL |
|---|---|---|---|
|
PyTorch 2,0,0 et versions supérieures |
CPU, GPU |
763104351884.dkr.ecr.us-east-1.amazonaws. com/pytorch-inférence : 2.0.1-gpu-py310-cu118-ubuntu20.04-sagemaker |
|
|
PyTorch 2,0,0 et versions supérieures |
CPU |
763104351884.dkr.ecr.us-east-1.amazonaws. com/pytorch-inférence-graviton : 2.0.1-cpu-py310-ubuntu20.04-sagemaker |
|
|
PyTorch 2,0,0 et versions supérieures |
GPU |
763104351884.dkr.ecr.us-east-1.amazonaws. com/stabilityai-pytorch-inference:2.0.1-sgm0.1.0-gpu-py310-cu118-ubuntu20.04-sagemaker |
|
PyTorch 1,13,1 |
Neuronx |
763104351884.dkr.ecr.us-west-2.amazonaws. com/pytorch-inférence-neuron:1.13.1-neuron-py310-sdk2.12.0-ubuntu20.04 |
Prise en main
Avant de déployer votre modèle, respectez les prérequis. Vous pouvez également configurer les paramètres de votre modèle et personnaliser le code du gestionnaire.
Conditions préalables
Avant de démarrer, vérifiez que les conditions préalables suivantes sont respectées :
-
Assurez-vous d'avoir accès à un AWS compte. Configurez votre environnement de manière à ce qu'il AWS CLI puisse accéder à votre compte via un utilisateur AWS IAM ou un rôle IAM. Nous vous recommandons d'utiliser un rôle IAM. À des fins de test dans votre compte personnel, vous pouvez associer les politiques d'autorisations gérées suivantes au rôle IAM :
Pour plus d’informations sur la façon d’attacher des politiques IAM à un rôle, consultez Ajout et suppression d’autorisations basées sur l’identité IAM dans le Guide de l’utilisateur IAM AWS .
-
Configurez vos dépendances de façon locale, comme indiqué dans les exemples suivants.
-
Installez la version 2 de AWS CLI :
# Install the latest AWS CLI v2 if it is not installed !curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" !unzip awscliv2.zip #Follow the instructions to install v2 on the terminal !cat aws/README.md -
Installez SageMaker AI et le client Boto3 :
# If already installed, update your client #%pip install sagemaker pip --upgrade --quiet !pip install -U sagemaker !pip install -U boto !pip install -U botocore !pip install -U boto3
-
Configuration des paramètres et des réglages du modèle
TorchServe permet torchrunmodel_config.yaml. La variable d’environnement CUDA_VISIBLE_DEVICES, qui spécifie les ID des dispositifs GPU visibles à un moment donné, est définie en fonction de ce nombre.
Par exemple, supposons qu’il y ait 8 GPU sur un nœud et qu’une application de travail requiert 4 GPU sur un nœud (nproc_per_node=4). Dans ce cas, TorchServe affecte quatre GPU au premier travailleur (CUDA_VISIBLE_DEVICES="0,1,2,3") et quatre GPU au second travailleur (). CUDA_VISIBLE_DEVICES="4,5,6,7”
Outre ce comportement par défaut, TorchServe offre aux utilisateurs la possibilité de spécifier des GPU pour un travailleur. Par exemple, si vous définissez la variable deviceIds: [2,3,4,5] dans le fichier YAML de configuration du nproc_per_node=2, puis que vous TorchServe l'CUDA_VISIBLE_DEVICES=”2,3”assignez au premier travailleur et CUDA_VISIBLE_DEVICES="4,5” au second.
Dans l'model_config.yamlexemple suivant, nous configurons à la fois les paramètres frontaux et principaux du OPT-30b parallelType, deviceType, deviceIds et torchrun. Pour plus d'informations sur les paramètres frontaux que vous pouvez configurer, consultez la PyTorch GitHub documentation
# TorchServe front-end parameters minWorkers: 1 maxWorkers: 1 maxBatchDelay: 100 responseTimeout: 1200 parallelType: "tp" deviceType: "gpu" # example of user specified GPU deviceIds deviceIds: [0,1,2,3] # sets CUDA_VISIBLE_DEVICES torchrun: nproc-per-node: 4 # TorchServe back-end parameters deepspeed: config: ds-config.json checkpoint: checkpoints.json handler: # parameters for custom handler code model_name: "facebook/opt-30b" model_path: "model/models--facebook--opt-30b/snapshots/ceea0a90ac0f6fae7c2c34bcb40477438c152546" max_length: 50 max_new_tokens: 10 manual_seed: 40
Personnalisation des gestionnaires
TorchServe propose des gestionnaires de base custom_handler.py code dans la PyTorch GitHub documentation
class TransformersSeqClassifierHandler(BaseDeepSpeedHandler, ABC): """ Transformers handler class for sequence, token classification and question answering. """ def __init__(self): super(TransformersSeqClassifierHandler, self).__init__() self.max_length = None self.max_new_tokens = None self.tokenizer = None self.initialized = False def initialize(self, ctx: Context): """In this initialize function, the HF large model is loaded and partitioned using DeepSpeed. Args: ctx (context): It is a JSON Object containing information pertaining to the model artifacts parameters. """ super().initialize(ctx) model_dir = ctx.system_properties.get("model_dir") self.max_length = int(ctx.model_yaml_config["handler"]["max_length"]) self.max_new_tokens = int(ctx.model_yaml_config["handler"]["max_new_tokens"]) model_name = ctx.model_yaml_config["handler"]["model_name"] model_path = ctx.model_yaml_config["handler"]["model_path"] seed = int(ctx.model_yaml_config["handler"]["manual_seed"]) torch.manual_seed(seed) logger.info("Model %s loading tokenizer", ctx.model_name) self.tokenizer = AutoTokenizer.from_pretrained(model_name) self.tokenizer.pad_token = self.tokenizer.eos_token config = AutoConfig.from_pretrained(model_name) with torch.device("meta"): self.model = AutoModelForCausalLM.from_config( config, torch_dtype=torch.float16 ) self.model = self.model.eval() ds_engine = get_ds_engine(self.model, ctx) self.model = ds_engine.module logger.info("Model %s loaded successfully", ctx.model_name) self.initialized = True def preprocess(self, requests): """ Basic text preprocessing, based on the user's choice of application mode. Args: requests (list): A list of dictionaries with a "data" or "body" field, each containing the input text to be processed. Returns: tuple: A tuple with two tensors: the batch of input ids and the batch of attention masks. """ def inference(self, input_batch): """ Predicts the class (or classes) of the received text using the serialized transformers checkpoint. Args: input_batch (tuple): A tuple with two tensors: the batch of input ids and the batch of attention masks, as returned by the preprocess function. Returns: list: A list of strings with the predicted values for each input text in the batch. """ def postprocess(self, inference_output): """Post Process Function converts the predicted response into Torchserve readable format. Args: inference_output (list): It contains the predicted response of the input text. Returns: (list): Returns a list of the Predictions and Explanations. """
Préparation des artefacts de votre modèle
Avant de déployer votre modèle sur l' SageMaker IA, vous devez empaqueter les artefacts de votre modèle. Pour les grands modèles, nous vous recommandons d'utiliser l'outil PyTorch --archive-format
no-archive, qui ignore la compression des artefacts du modèle. L’exemple suivant enregistre tous les artefacts du modèle dans un nouveau dossier nommé opt/.
torch-model-archiver --model-name opt --version 1.0 --handler custom_handler.py --extra-files ds-config.json -r requirements.txt --config-file opt/model-config.yaml --archive-format no-archive
Une fois le opt/ dossier créé, téléchargez le OPT-30b modèle dans le dossier à l'aide de l' PyTorch Download_model
cd opt python path_to/Download_model.py --model_path model --model_name facebook/opt-30b --revision main
Enfin, chargez les artefacts du modèle sur un compartiment Amazon S3.
aws s3 cp opt{your_s3_bucket}/opt --recursive
Vous devriez maintenant avoir des artefacts de modèle stockés dans Amazon S3, prêts à être déployés sur un point de terminaison SageMaker IA.
Déployez le modèle à l'aide du SDK SageMaker Python
Après avoir préparé les artefacts de votre modèle, vous pouvez déployer votre modèle sur un point de terminaison SageMaker AI Hosting. Cette section explique comment déployer un grand modèle sur un point de terminaison et effectuer des prédictions de réponse en streaming. Pour plus d’informations sur le streaming des réponses provenant des points de terminaison, consultez Invoquer des points de terminaison en temps réel.
Pour déployer votre modèle, procédez comme suit :
-
Créez une session SageMaker AI, comme illustré dans l'exemple suivant.
import boto3 import sagemaker from sagemaker.core.resources import Model from sagemaker.core import image_uris from sagemaker.core.helper.session_helper import get_execution_role, Session boto3_session=boto3.session.Session(region_name="us-west-2") smr = boto3.client('sagemaker-runtime-demo') sm = boto3.client('sagemaker') role = get_execution_role() # execution role for the endpoint sess= Session(boto3_session, sagemaker_client=sm, sagemaker_runtime_client=smr) # SageMaker AI session for interacting with different AWS APIs region = sess._region_name # region name of the current SageMaker Studio Classic environment account = sess.account_id() # account_id of the current SageMaker Studio Classic environment # Configuration: bucket_name = sess.default_bucket() prefix = "torchserve" output_path = f"s3://{bucket_name}/{prefix}" print(f'account={account}, region={region}, role={role}, output_path={output_path}') -
Créez un modèle non compressé dans SageMaker AI, comme illustré dans l'exemple suivant.
from datetime import datetime instance_type = "ml.g5.24xlarge" endpoint_name = sagemaker.utils.name_from_base("ts-opt-30b") s3_uri = {your_s3_bucket}/opt model = Model( name="torchserve-opt-30b" + datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), # Enable SageMaker uncompressed model artifacts model_data={ "S3DataSource": { "S3Uri": s3_uri, "S3DataType": "S3Prefix", "CompressionType": "None", } }, image_uri=container, role=role, sagemaker_session=sess, env={"TS_INSTALL_PY_DEP_PER_MODEL": "true"}, ) print(model) -
Déployez le modèle sur une instance Amazon EC2, comme illustré dans l’exemple suivant.
model.deploy( initial_instance_count=1, instance_type=instance_type, endpoint_name=endpoint_name, volume_size_in_gb=512, # increase the size to store large model model_data_download_timeout=3600, # increase the timeout to download large model container_startup_health_check_timeout=600, # increase the timeout to load large model ) -
Initialisez une classe pour traiter la réponse en streaming, comme illustré dans l’exemple suivant.
import io class Parser: """ A helper class for parsing the byte stream input. The output of the model will be in the following format: ``` b'{"outputs": [" a"]}\n' b'{"outputs": [" challenging"]}\n' b'{"outputs": [" problem"]}\n' ... ``` While usually each PayloadPart event from the event stream will contain a byte array with a full json, this is not guaranteed and some of the json objects may be split across PayloadPart events. For example: ``` {'PayloadPart': {'Bytes': b'{"outputs": '}} {'PayloadPart': {'Bytes': b'[" problem"]}\n'}} ``` This class accounts for this by concatenating bytes written via the 'write' function and then exposing a method which will return lines (ending with a '\n' character) within the buffer via the 'scan_lines' function. It maintains the position of the last read position to ensure that previous bytes are not exposed again. """ def __init__(self): self.buff = io.BytesIO() self.read_pos = 0 def write(self, content): self.buff.seek(0, io.SEEK_END) self.buff.write(content) data = self.buff.getvalue() def scan_lines(self): self.buff.seek(self.read_pos) for line in self.buff.readlines(): if line[-1] != b'\n': self.read_pos += len(line) yield line[:-1] def reset(self): self.read_pos = 0 -
Testez une prédiction de réponse en streaming, comme illustré dans l’exemple suivant.
import json body = "Today the weather is really nice and I am planning on".encode('utf-8') resp = smr.invoke_endpoint_with_response_stream(EndpointName=endpoint_name, Body=body, ContentType="application/json") event_stream = resp['Body'] parser = Parser() for event in event_stream: parser.write(event['PayloadPart']['Bytes']) for line in parser.scan_lines(): print(line.decode("utf-8"), end=' ')
Vous avez maintenant déployé votre modèle sur un terminal d' SageMaker IA et vous devriez être en mesure de l'invoquer pour obtenir des réponses. Pour plus d'informations sur les points de terminaison en temps réel de l' SageMaker IA, consultezSingle-model points de terminaison.