View a markdown version of this page

Implemente modelos de gran tamaño para realizar inferencias con TorchServe - Amazon SageMaker AI

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Implemente modelos de gran tamaño para realizar inferencias con TorchServe

En este tutorial se muestra cómo implementar modelos grandes y realizar inferencias en Amazon SageMaker AI sin TorchServe GPU. En este ejemplo, se implementa el OPT-30bmodelo en una instancia. ml.g5 Puede modificarlo para que funcione con otros modelos y tipos de instancias. En el ejemplo, sustituya italicized placeholder text por su propia información.

TorchServe es una potente plataforma abierta para la inferencia de modelos distribuidos de gran tamaño. Al ser compatible con bibliotecas populares PyTorch, como PiPPY nativa y HuggingFace Accelerate DeepSpeed, ofrece API de manejo uniformes que mantienen la coherencia en todos los escenarios de inferencia de modelos distribuidos de gran tamaño y no distribuidos. Para obtener más información, consulte la extensa documentación TorchServede inferencia de modelos.

Contenedores de aprendizaje profundo con TorchServe

Para implementar un modelo grande sin TorchServe SageMaker IA, puedes usar uno de los contenedores de aprendizaje profundo (DLC) de SageMaker IA. De forma predeterminada, TorchServe está instalado en todos los AWS PyTorch DLC. Durante la carga del modelo, TorchServe puede instalar bibliotecas especializadas diseñadas para modelos grandes, como PiPPY, Deepspeed y Accelerate.

En la siguiente tabla se muestran todos los DLC de SageMaker IA con. TorchServe

Categoría DLC Marcos Hardware URL de ejemplo

SageMaker Contenedores AI Framework

PyTorch 2.0.0+

CPU, GPU

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

SageMaker Contenedores Graviton de AI Framework

PyTorch 2.0.0+

CPU

763104351884.dkr.ecr.us-east-1.amazonaws. com/pytorch- inference-graviton: 2.0.1-cpu-py310-ubuntu 20.04-sagemaker

Contenedores de inferencias de StabilityAI

PyTorch 2.0.0+

GPU

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

Contenedores Neuron

PyTorch 1.13.1

Neuronx

763104351884.dkr.ecr.us-west-2.amazonaws. com/pytorch- neurona de inferencia: 1.13.1-neuron-py310-sdk2.12.0-ubuntu20.04

Introducción

Antes de implementar el modelo, complete los requisitos previos. También se pueden configurar los parámetros del modelo y personalizar el código del controlador.

Requisitos previos

Antes de comenzar, compruebe que cumple los siguientes requisitos previos:

  1. Asegúrese de tener acceso a una cuenta. AWS Configure su entorno para que AWS CLI pueda acceder a su cuenta a través de un usuario de AWS IAM o un rol de IAM. Recomendamos utilizar un rol de IAM. Para realizar pruebas en su cuenta personal, puede asociar las siguientes políticas de permisos gestionados al rol de IAM:

    Para obtener información sobre cómo asociar políticas de IAM a un rol, consulte Incorporación y eliminación de permisos de identidad de IAM en la AWS Guía del usuario de IAM.

  2. Configure sus dependencias de forma local, como se muestra en los siguientes ejemplos.

    1. Instale la versión 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
    2. Instale SageMaker AI y el cliente 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

Configure los ajustes y los parámetros del modelo

TorchServe se utiliza torchrunpara configurar el entorno distribuido para el procesamiento paralelo de modelos. TorchServe tiene la capacidad de admitir a varios trabajadores en un modelo grande. De forma predeterminada, TorchServe utiliza un algoritmo por turnos para asignar las GPU a un trabajador de un host. En el caso de inferencias de modelos grandes, la cantidad de GPU asignadas a cada trabajador se calcula automáticamente en función de la cantidad de GPU especificada en el archivo model_config.yaml. La variable de entorno CUDA_VISIBLE_DEVICES, que especifica los ID de los dispositivos de GPU que están visibles en un momento específico, se establece en función de este número.

Por ejemplo, supongamos que hay 8 GPU en un nodo y un trabajador necesita 4 GPU en un nodo (nproc_per_node=4). En este caso, TorchServe asigna cuatro GPU al primer trabajador (CUDA_VISIBLE_DEVICES="0,1,2,3") y cuatro GPU al segundo trabajador (). CUDA_VISIBLE_DEVICES="4,5,6,7”

Además de este comportamiento predeterminado, TorchServe proporciona a los usuarios la flexibilidad de especificar las GPU para un trabajador. Por ejemplo, si estableces la variable deviceIds: [2,3,4,5] en el archivo YAML de configuración del modelo y la estableces y, a continuaciónnproc_per_node=2, la TorchServe asignas CUDA_VISIBLE_DEVICES=”2,3” al primer elemento de trabajo y CUDA_VISIBLE_DEVICES="4,5” al segundo elemento de trabajo.

En el siguiente model_config.yaml ejemplo, configuramos los parámetros de front-end y back-end del modelo. OPT-30b Los parámetros de front-end configurados son parallelType, deviceType, deviceIds y torchrun. Para obtener información más detallada sobre los parámetros de interfaz que puede configurar, consulte la documentación. PyTorch GitHub La configuración de back-end se basa en un mapa YAML que permite una personalización de estilo libre. Para los parámetros de back-end, definimos la DeepSpeed configuración y los parámetros adicionales que se utilizan en el código de controlador personalizado.

# 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

Personalización de controladores

TorchServe ofrece controladores básicos y utilidades de manejo para la inferencia de modelos grandes creados con bibliotecas populares. El siguiente ejemplo demuestra cómo la clase de controlador personalizada TransformersSeqClassifierHandleramplía BaseDeepSpeedHandlery utiliza las utilidades de controlador. Para ver un ejemplo de código completo, consulta el custom_handler.pycódigo de la PyTorch GitHub documentación.

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. """

Preparación de los artefactos de su modelo

Antes de implementar el modelo en la SageMaker IA, debe empaquetar los artefactos del modelo. En el caso de modelos grandes, le recomendamos que utilice la herramienta PyTorch torch-model-archiver con el argumento--archive-format no-archive, ya que evita comprimir los artefactos del modelo. El siguiente ejemplo guarda todos los artefactos del modelo en una nueva carpeta denominada 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 vez creada la opt/ carpeta, descargue el OPT-30b modelo a la carpeta con la herramienta. PyTorch Download_model

cd opt python path_to/Download_model.py --model_path model --model_name facebook/opt-30b --revision main

Por último, cargue los artefactos del modelo en un bucket de Amazon S3.

aws s3 cp opt {your_s3_bucket}/opt --recursive

Ahora debería tener los artefactos del modelo almacenados en Amazon S3 que estén listos para implementarse en un punto final de SageMaker IA.

Implemente el modelo mediante el SDK de SageMaker Python

Tras preparar los artefactos del modelo, puede implementarlo en un punto final de SageMaker AI Hosting. En esta sección se describe cómo implementar un único modelo grande en un punto de conexión y realizar predicciones de respuesta en transmisión. Para obtener más información sobre la transmisión de las respuestas desde los puntos de conexión, consulte Invocar puntos de conexión en tiempo real.

Para implementar el modelo, siga los pasos que se describen a continuación:

  1. Cree una sesión de SageMaker IA, como se muestra en el siguiente ejemplo.

    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. Cree un modelo sin comprimir en SageMaker IA, como se muestra en el siguiente ejemplo.

    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. Implemente el modelo en una instancia de Amazon EC2, como se muestra en el siguiente ejemplo.

    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. Inicie una clase para procesar la respuesta de transmisión, como se muestra en el siguiente ejemplo.

    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. Pruebe una predicción de respuesta de transmisión, como se muestra en el siguiente ejemplo.

    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=' ')

Ahora ha implementado su modelo en un punto final de SageMaker IA y debería poder invocarlo para obtener respuestas. Para obtener más información sobre los puntos finales de la SageMaker IA en tiempo real, consulte. Single-model puntos finales