Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Implementa modelli di grandi dimensioni per l'inferenza con TorchServe
Questo tutorial dimostra come distribuire modelli di grandi dimensioni e fornire inferenza in Amazon SageMaker con on. TorchServe GPUs Questo esempio distribuisce il modello OPT-30bml.g5
È possibile modificarlo per utilizzarlo con altri modelli e tipi di istanze. Negli esempi, sostituire
con le tue informazioni.italicized placeholder text
TorchServe è una potente piattaforma aperta per l'inferenza di modelli distribuiti di grandi dimensioni. Supportando librerie popolari come PyTorch native P e HuggingFace Accelerate iPPy DeepSpeed, offre un gestore uniforme APIs che rimane coerente tra scenari di inferenza distribuiti di modelli di grandi dimensioni e modelli non distribuiti. Per ulteriori informazioni, consulta la documentazione sull'inferenza TorchServedi modelli di grandi dimensioni
Contenitori di deep learning con TorchServe
Per distribuire un modello di grandi dimensioni con TorchServe on SageMaker, puoi utilizzare uno dei contenitori di SageMaker deep learning (DLCs). Per impostazione predefinita, TorchServe è installato in tutti AWS PyTorchDLCs. Durante il caricamento del modello, TorchServe può installare librerie specializzate su misura per modelli di grandi dimensioni come PiPPy, Deepspeed e Accelerate.
La tabella seguente elenca tutti i SageMaker DLCscon TorchServe
DLCcategoria | Framework | Hardware | Esempio 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 |
Neuronx |
763104351884.dkr. ecr.us-west-2.amazonaws.com /:1.13.1-neuron-py310-sdk2.12.0-ubuntu20.04 pytorch-inference-neuron |
Nozioni di base
Prima di distribuire il modello, completa i prerequisiti. È inoltre possibile configurare i parametri del modello e personalizzare il codice del gestore.
Prerequisiti
Per iniziare, assicurati di rispettare le seguenti condizioni fondamentali:
-
Assicurati di avere accesso a un account. AWS Configura il tuo ambiente in modo che AWS CLI possano accedere al tuo account tramite un AWS IAM utente o un IAM ruolo. Ti consigliamo di utilizzare un IAM ruolo. Ai fini del test nel tuo account personale, puoi allegare al IAM ruolo le seguenti politiche di autorizzazioni gestite:
Per ulteriori informazioni sull'associazione di IAM politiche a un ruolo, consulta Aggiungere e rimuovere le autorizzazioni di IAM identità nella Guida per l'utente.AWS IAM
-
Configurazione locale delle dipendenze, come indicato negli esempi seguenti:
-
Installa la versione 2 di: 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
-
Installa SageMaker e il 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
-
Configura le impostazioni e i parametri del modello
TorchServe utilizza torchrun
model_config.yaml
La variabile di ambienteCUDA_VISIBLE_DEVICES
, che specifica i GPU dispositivi IDs visibili in un determinato momento, viene impostata in base a questo numero.
Ad esempio, supponiamo che ce ne siano 8 GPUs su un nodo e che un lavoratore ne abbia bisogno 4 GPUs su un nodo ()nproc_per_node=4
. In questo caso, ne TorchServe GPUs assegna quattro al primo worker (CUDA_VISIBLE_DEVICES="0,1,2,3"
) e quattro GPUs al secondo worker (CUDA_VISIBLE_DEVICES="4,5,6,7”
).
Oltre a questo comportamento predefinito, TorchServe offre agli utenti la flessibilità di specificare GPUs un lavoratore. Ad esempio, se impostate la variabile deviceIds: [2,3,4,5]
nel YAMLfile di configurazione del modellonproc_per_node=2
, la TorchServe assegnate CUDA_VISIBLE_DEVICES=”2,3”
al primo lavoratore e CUDA_VISIBLE_DEVICES="4,5”
al secondo lavoratore.
Nell'model_config.yaml
esempio seguente, configuriamo i parametri front-end e back-end per il modello -30b. OPTparallelType
, deviceType
, deviceIds
e torchrun
. Per informazioni più dettagliate sui parametri di front-end che è possibile configurare, consulta la documentazione. PyTorch GitHub
# 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
Personalizzazione di gestori
TorchServe offre gestori di basecustom_handler.py
codice nella documentazione. PyTorch GitHub
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. """
Preparazione degli artefatti di un modello
Prima di distribuire il modello su SageMaker, è necessario impacchettare gli artefatti del modello. Per i modelli di grandi dimensioni, ti consigliamo di utilizzare PyTorch torch-model-archiver--archive-format
no-archive
, che salta la compressione degli artefatti del modello. L'esempio seguente salva tutti gli artefatti del modello in una nuova cartella denominata 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
Infine, puoi caricare gli artefatti del modello su un bucket Amazon S3.
aws s3 cp opt
{your_s3_bucket}
/opt --recursive
Ora dovresti avere artefatti del modello archiviati in Amazon S3 pronti per la distribuzione su un endpoint. SageMaker
Implementa il modello usando Python SageMaker SDK
Dopo aver preparato gli artefatti del modello, puoi distribuirlo su un endpoint di hosting. SageMaker Questa sezione descrive come implementare un unico modello di grandi dimensioni su un endpoint ed effettuare previsioni di risposta in streaming. Per ulteriori informazioni sullo streaming delle risposte dagli endpoint, consulta Invoke real-time endpoints.
Per distribuire il modello, completa le seguenti fasi.
-
Create una SageMaker sessione, come illustrato nell'esempio seguente.
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 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}')
-
Create un modello non compresso in SageMaker, come illustrato nell'esempio seguente.
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)
-
Implementa il modello su un'EC2istanza Amazon, come illustrato nell'esempio seguente.
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 )
-
Inizializzare una classe per l'elaborazione di una risposta in streaming, come illustrato nell'esempio seguente.
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
-
Testare una previsione di risposta in streaming, come mostrato nell'esempio seguente.
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=' ')
Ora hai distribuito il tuo modello su un SageMaker endpoint e dovresti essere in grado di richiamarlo per le risposte. Per ulteriori informazioni sugli endpoint SageMaker in tempo reale, consulta. Endpoint a modello singolo