View a markdown version of this page

Implementa modelli di grandi dimensioni per l'inferenza con TorchServe - Amazon SageMaker AI

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 AI con TorchServe le GPU. Questo esempio distribuisce il modello su un'istanza OPT-30b. ml.g5 È possibile modificarlo per utilizzarlo con altri modelli e tipi di istanze. Negli esempi, sostituire italicized placeholder text con le tue informazioni.

TorchServe è una potente piattaforma aperta per l'inferenza di modelli distribuiti di grandi dimensioni. Supportando librerie popolari come PyTorch PipPy native e HuggingFace Accelerate DeepSpeed, offre API di gestione uniformi che rimangono coerenti tra scenari di inferenza distribuiti di modelli di grandi dimensioni e modelli non distribuiti. Per ulteriori informazioni, consulta TorchServe la documentazione sull'inferenza di modelli di grandi dimensioni.

Contenitori di deep learning con TorchServe

Per implementare un modello di grandi dimensioni con TorchServe un' SageMaker intelligenza artificiale, puoi utilizzare uno dei contenitori di deep learning (DLC) SageMaker AI. Per impostazione predefinita, TorchServe è installato in tutti i AWS PyTorch DLC. 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 DLC SageMaker AI con. TorchServe

Categoria DLC Framework Hardware URL di esempio

SageMaker Contenitori AI Framework

PyTorch 2.0.0+

CPU, GPU

763104351884.dkr.ecr.us-east-1.amazonaws. com/pytorch- inferenza: 2.0.1-gpu-py310-cu118-ubuntu20.04-sagemaker

SageMaker Contenitori Graviton AI Framework

PyTorch 2.0.0+

CPU

763104351884.dkr.ecr.us-east-1.amazonaws. com/pytorch-inferenza-graviton:2.0.1-cpu-py310-ubuntu20.04 - sagemaker

Container di inferenza StabilityAI

PyTorch 2.0.0+

GPU

763104351884.dkr.ecr.us-east-1.amazonaws. com/stabilityai-pytorch-inferenza: 2.0.1-sgm0.1.0-gpu-py310-cu118-ubuntu20.04-sagemaker

Container Neuron

PyTorch 1.13.1

Neuronx

763104351884.dkr.ecr.us-west-2.amazonaws. com/pytorch-neurone di inferenza: 1.13.1-neuron-py310-sdk2.12.0-ubuntu20.04

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:

  1. Assicurati di avere accesso a un account. AWS Configura il tuo ambiente in modo che AWS CLI possano accedere al tuo account tramite un utente AWS IAM o un ruolo IAM. Consigliamo di utilizzare un ruolo IAM. Ai fini del test nel tuo account personale, puoi collegare le seguenti policy di autorizzazione gestita al ruolo IAM:

    Per ulteriori informazioni sul collegamento di policy IAM a un ruolo, consulta Adding and removing IAM identity permissions nella AWS Guida per l'utente IAM.

  2. Configurazione locale delle dipendenze, come indicato negli esempi seguenti:

    1. 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
    2. Installa SageMaker AI 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

Configurazione delle impostazioni e dei parametri del modello

TorchServe utilizza torchrunper configurare l'ambiente distribuito per l'elaborazione parallela dei modelli. TorchServe ha la capacità di supportare più lavoratori per un modello di grandi dimensioni. Per impostazione predefinita, TorchServe utilizza un algoritmo round-robin per assegnare le GPU a un worker su un host. Nel caso di inferenza di modelli di grandi dimensioni, il numero di GPU assegnate a ciascun worker viene calcolato automaticamente in base al numero di GPU specificato nel file model_config.yaml. La variabile di ambiente CUDA_VISIBLE_DEVICES, che specifica gli ID dei dispositivi GPU visibili in un determinato momento, viene impostata in base a questo numero.

Ad esempio, supponiamo che ci siano otto GPU su un nodo e che un worker abbia bisogno di quattro GPU su un nodo (nproc_per_node=4). In questo caso, TorchServe assegna quattro GPU al primo worker (CUDA_VISIBLE_DEVICES="0,1,2,3") e quattro GPU al secondo worker (). CUDA_VISIBLE_DEVICES="4,5,6,7”

Oltre a questo comportamento predefinito, TorchServe offre agli utenti la flessibilità di specificare le GPU per un lavoratore. Ad esempio, se impostate la variabile deviceIds: [2,3,4,5] nel file YAML di configurazione del modello e impostatenproc_per_node=2, la TorchServe assegnate al primo worker e CUDA_VISIBLE_DEVICES=”2,3” CUDA_VISIBLE_DEVICES="4,5” al secondo worker.

Nell'model_config.yamlesempio seguente, configuriamo i parametri front-end e back-end per il modello. OPT-30b I parametri di front-end configurati sono parallelType, deviceType, deviceIds e torchrun. Per informazioni più dettagliate sui parametri di front-end che è possibile configurare, consulta la documentazione. PyTorch GitHub La configurazione del back-end si basa su una mappa YAML che consente la personalizzazione in stile libero. Per i parametri di back-end, definiamo la DeepSpeed configurazione e i parametri aggiuntivi utilizzati dal codice del gestore personalizzato.

# 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 base e utilità di gestione per l'inferenza di modelli di grandi dimensioni creati con le librerie più diffuse. L'esempio seguente dimostra come la classe TransformersSeqClassifierHandlerCustom Handler estende e utilizza le utilità Handler. BaseDeepSpeedHandler Per un esempio completo di codice, consultate il custom_handler.pycodice 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 sull' SageMaker intelligenza artificiale, è necessario impacchettare gli artefatti del modello. Per i modelli di grandi dimensioni, ti consigliamo di utilizzare lo strumento PyTorch torch-model-archiver con l'argomento, che salta la compressione degli artefatti del modello. --archive-format no-archive 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

Una volta creata la opt/ cartella, scaricate il modello nella cartella utilizzando lo OPT-30b strumento. PyTorch Download_model

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 essere distribuiti su un endpoint di intelligenza artificiale. SageMaker

Distribuisci il modello utilizzando SageMaker Python SDK

Dopo aver preparato gli artefatti del modello, puoi distribuirlo su un endpoint di hosting AI. SageMaker In questa sezione viene spiegato come distribuire 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:

  1. Crea una sessione SageMaker AI, come mostrato 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 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}')
  2. Crea un modello non compresso in SageMaker AI, come mostrato 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)
  3. Implementare un modello su un’istanza di Amazon EC2, 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 )
  4. 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
  5. 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 endpoint di SageMaker intelligenza artificiale e dovresti essere in grado di richiamarlo per le risposte. Per ulteriori informazioni sugli endpoint SageMaker AI in tempo reale, consulta. Single-model punti finali