

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
<a name="large-model-inference-tutorials-torchserve"></a>

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-30b](https://huggingface.co/facebook/opt-30b)modelo 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](https://pytorch.org/serve/large_model_inference.html#).

## Contenedores de aprendizaje profundo con TorchServe
<a name="large-model-inference-tutorials-torchserve-dlcs"></a>

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](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only) con. TorchServe


| Categoría DLC | Marcos | Hardware | URL de ejemplo | 
| --- | --- | --- | --- | 
| [SageMaker Contenedores AI Framework](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only) | 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](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-graviton-containers-sm-support-only) | 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](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#stabilityai-inference-containers) | 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](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#neuron-containers) | 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
<a name="large-model-inference-tutorials-torchserve-getting-started"></a>

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
<a name="large-model-inference-tutorials-torchserve-getting-started-prereqs"></a>

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

1. Asegúrese de tener acceso a una cuenta. AWS [Configure su entorno](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) 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:
   + [AmazonEC2ContainerRegistryFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess)
   + [AmazonEC2FullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonEC2FullAccess)
   + [AWSServiceRoleForAmazonEKSNodegroup](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AWSServiceRoleForAmazonEKSNodegroup)
   + [AmazonSageMakerFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonSageMakerFullAccess)
   + [AmazonS3FullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonS3FullAccess)

   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](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) en la *AWS Guía del usuario de IAM*.

1. 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
      ```

   1. 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
<a name="large-model-inference-tutorials-torchserve-getting-started-config"></a>

TorchServe se utiliza [https://pytorch.org/docs/stable/elastic/run.html](https://pytorch.org/docs/stable/elastic/run.html)para 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](https://github.com/pytorch/serve/blob/5ee02e4f050c9b349025d87405b246e970ee710b/model-archiver/README.md?plain=1#L164) y, a continuación`nproc_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 ](https://huggingface.co/facebook/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 ](https://github.com/pytorch/serve/blob/2bf505bae3046b0f7d0900727ec36e611bb5dca3/docs/configuration.md?plain=1#L267) 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
<a name="large-model-inference-tutorials-torchserve-getting-started-handlers"></a>

TorchServe ofrece [controladores básicos](https://github.com/pytorch/serve/tree/master/ts/torch_handler/distributed) y [utilidades de manejo](https://github.com/pytorch/serve/tree/master/ts/handler_utils) para la inferencia de modelos grandes creados con bibliotecas populares. [El siguiente ejemplo demuestra cómo la clase de controlador personalizada [TransformersSeqClassifierHandler](https://github.com/pytorch/serve/blob/ab69b69a59d6ca6074df7e6d4014f07eb48dedba/examples/large_models/deepspeed/custom_handler.py#L16C7-L16C39)amplía [BaseDeepSpeedHandler](https://github.com/pytorch/serve/blob/ab69b69a59d6ca6074df7e6d4014f07eb48dedba/ts/torch_handler/distributed/base_deepspeed_handler.py#L8)y utiliza las utilidades de controlador.](https://github.com/pytorch/serve/blob/master/ts/handler_utils/distributed/deepspeed.py) Para ver un ejemplo de código completo, consulta el [`custom_handler.py`código de la PyTorch GitHub documentación](https://github.com/pytorch/serve/blob/master/examples/large_models/deepspeed/custom_handler.py).

```
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
<a name="large-model-inference-tutorials-torchserve-artifacts"></a>

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](https://github.com/pytorch/serve/blob/master/model-archiver/README.md) 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](https://github.com/pytorch/serve/blob/master/examples/large_models/utils/Download_model.py)

```
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
<a name="large-model-inference-tutorials-torchserve-deploy"></a>

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](https://docs.aws.amazon.com/sagemaker/latest/dg/realtime-endpoints-test-endpoints.html).

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}')
   ```

1. 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)
   ```

1. 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
   )
   ```

1. 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
   ```

1. 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](realtime-single-model.md)