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 utiliser des inférences dans Amazon SageMaker AI avec TorchServe on GPUs. Cet exemple déploie le modèle OPT-30bml.g5
Vous pouvez le modifier pour l'adapter à d'autres modèles et types d'instance. Remplacez les informations figurant
dans les exemples 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 les bibliothèques populaires telles que PyTorch Pi PPy native et HuggingFace Accelerate, il offre un gestionnaire uniforme APIs qui reste cohérent entre les scénarios d'inférence de grands modèles distribués et de modèles non distribués. DeepSpeed Pour plus d'informations, consultez TorchServela documentation sur l'inférence de grands modèles
Conteneurs de deep learning avec TorchServe
Pour déployer un modèle de grande taille TorchServe sans SageMaker IA, vous pouvez utiliser l'un des conteneurs d'apprentissage profond pour SageMaker IA (DLCs). Par défaut, TorchServe est installé dans tous AWS PyTorch DLCs. 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 toutes les SageMaker IA DLCs avec TorchServe
Catégorie DLC | Framework | Matériel | Exemple d'URL |
---|---|---|---|
PyTorch 2,0.0+ |
CPU, GPU |
763104351884.dkr. ecr.us-east-1.amazonaws.com /pytorch-inference:2.0.1-gpu-py310-cu118-ubuntu20.04-sagemaker |
|
PyTorch 2,0.0+ |
CPU |
763104351884.dkr. ecr.us-east-1.amazonaws.com /:2.0.1-cpu-py310-ubuntu20.04-sagemaker pytorch-inference-graviton |
|
PyTorch 2,0.0+ |
GPU |
763104351884.dkr. ecr.us-east-1.amazonaws.com /:2.0.1-sgm0.1.0-gpu-py310-cu118-ubuntu20.04-sagemaker stabilityai-pytorch-inference |
|
PyTorch 1.13.1 |
Neurones |
763104351884.dkr. ecr.us-west-2.amazonaws.com /:1.13.1-neuron-py310-sdk2.12.0-ubuntu20.04 pytorch-inference-neuron |
Premiers pas
Avant de déployer votre modèle, remplissez les conditions préalables. Vous pouvez également configurer les paramètres de votre modèle et personnaliser le code du gestionnaire.
Prérequis
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'ils AWS CLI puissent 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 l'attachement de politiques IAM à un rôle, consultez la section Ajouter et supprimer des autorisations d'identité IAM dans le Guide de l'utilisateur AWS IAM.
-
Configurez vos dépendances localement, 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 paramètres du modèle
TorchServe permet torchrun
model_config.yaml
fichier. La variable d'environnementCUDA_VISIBLE_DEVICES
, qui spécifie le périphérique IDs GPU visible à un moment donné, est définie en fonction de ce nombre.
Par exemple, supposons qu'il y en ait 8 GPUs sur un nœud et qu'un travailleur en ait besoin de 4 GPUs sur un nœud (nproc_per_node=4
). Dans ce cas, en TorchServe attribue quatre GPUs au premier travailleur (CUDA_VISIBLE_DEVICES="0,1,2,3"
) et quatre GPUs au second travailleur (CUDA_VISIBLE_DEVICES="4,5,6,7”
).
Outre ce comportement par défaut, TorchServe offre aux utilisateurs la flexibilité de spécifier GPUs pour un travailleur. Par exemple, si vous définissez la variable deviceIds: [2,3,4,5]
dans le fichier YAML de configuration du modèlenproc_per_node=2
, puis que vous l' TorchServe CUDA_VISIBLE_DEVICES=”2,3”
assignez au premier et CUDA_VISIBLE_DEVICES="4,5”
au second programme de travail.
Dans l'model_config.yaml
exemple suivant, nous configurons les paramètres frontaux et principaux pour le modèle OPT-30bparallelType
deviceType
, deviceIds
ettorchrun
. Pour des informations plus détaillées 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
Personnaliser les gestionnaires
TorchServe propose des gestionnaires de base et descustom_handler.py
code figurant 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 modèles de grande taille, nous vous recommandons d'utiliser l' PyTorch torch-model-archiver--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
cd opt python path_to/Download_model.py --model_path model --model_name facebook/opt-30b --revision main
Enfin, téléchargez les artefacts du modèle dans 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 d' 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 d'hébergement SageMaker AI. Cette section explique comment déployer un seul grand modèle sur un point de terminaison et établir des prévisions de réponse au streaming. Pour plus d'informations sur le streaming des réponses provenant des points de terminaison, consultez la section 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 indiqué dans l'exemple suivant.
import boto3 import sagemaker from sagemaker import Model, image_uris, serializers, deserializers boto3_session=boto3.session.Session(region_name="us-west-2") smr = boto3.client('sagemaker-runtime-demo') sm = boto3.client('sagemaker') role = sagemaker.get_execution_role() # execution role for the endpoint sess= sagemaker.session.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 indiqué 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 EC2 instance Amazon, comme illustré dans l'exemple suivant.
model.deploy( initial_instance_count=1, instance_type=instance_type, endpoint_name=endpoint_name, volume_size=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 de streaming, comme indiqué 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 au 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 point de terminaison d' SageMaker IA et vous devriez pouvoir l'invoquer pour obtenir des réponses. Pour plus d'informations sur les points de terminaison en temps réel de l' SageMaker IA, consultezPoints de terminaison à modèle unique.