

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Implemente modelos grandes para inferência com TorchServe
<a name="large-model-inference-tutorials-torchserve"></a>

Este tutorial demonstra como implantar modelos grandes e fornecer inferência na Amazon SageMaker AI sem TorchServe GPUs. Este exemplo implanta o [OPT-30b](https://huggingface.co/facebook/opt-30b)modelo em uma `ml.g5` instância. Você pode modificar isso para funcionar com outros modelos e tipos de instância. Nos exemplos, substitua `{{italicized placeholder text}}` com suas próprias informações.

TorchServe é uma plataforma aberta poderosa para inferência de modelos distribuídos de grande porte. Ao oferecer suporte a bibliotecas populares como PyTorch PiPPy nativo e HuggingFace Accelerate DeepSpeed, ele oferece APIs de manipulador uniformes que permanecem consistentes em cenários de inferência de modelos grandes e não distribuídos. Para obter mais informações, consulte [TorchServea grande documentação de inferência de modelos](https://pytorch.org/serve/large_model_inference.html#).

## Contêineres de aprendizado profundo com TorchServe
<a name="large-model-inference-tutorials-torchserve-dlcs"></a>

Para implantar um modelo grande sem TorchServe SageMaker IA, você pode usar um dos contêineres de aprendizado profundo (DLCs) de SageMaker IA. Por padrão, TorchServe é instalado em todos os AWS PyTorch DLCs. Durante o carregamento do modelo, TorchServe pode instalar bibliotecas especializadas personalizadas para modelos grandes, como PiPPy, Deepspeed e Accelerate.

A tabela a seguir lista todos os [DLCs de SageMaker AI com TorchServe](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only).


| Categoria DLC | Framework | Hardware | Exemplo de URL | 
| --- | --- | --- | --- | 
| [SageMaker Contêineres de estrutura de](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- inferência: 2.0.1-gpu-py310-cu118-ubuntu 20.04 - sagemaker | 
| [SageMaker Contêineres AI Framework Graviton](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-inferência-graviton: 2.0.1-cpu-py310-ubuntu 20.04 - sagemaker | 
| [Contêineres de inferência 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 | 
| [Contêineres de neurônios](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-neurônio-inferência: 1.13.1-neuron-py310-sdk2.12.0-ubuntu 20.04 | 

## Introdução
<a name="large-model-inference-tutorials-torchserve-getting-started"></a>

Antes de implantar seu modelo, preencha os pré-requisitos. Você também pode configurar os parâmetros do modelo e personalizar o código do manipulador.

### Pré-requisitos
<a name="large-model-inference-tutorials-torchserve-getting-started-prereqs"></a>

Para começar, verifique se você tem os seguintes pré-requisitos:

1. Certifique-se de ter acesso a uma AWS conta. [Configure seu ambiente](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) para que eles AWS CLI possam acessar sua conta por meio de um usuário AWS do IAM ou de uma função do IAM. Recomendamos usar uma perfil do IAM. Para fins de teste em sua conta pessoal, você pode anexar as seguintes políticas de permissões gerenciadas à perfil do 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 obter informações sobre como anexar políticas a identidades do IAM, consulte [Adicionar e remover permissões de identidade do IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) no *Guia do usuário do IAM AWS *.

1. Configure suas dependências localmente, conforme mostrado nos exemplos a seguir.

   1. Instale a versão 2 do 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 a SageMaker IA e o 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
      ```

### Configurar parâmetros e configurações do modelo
<a name="large-model-inference-tutorials-torchserve-getting-started-config"></a>

TorchServe usa [https://pytorch.org/docs/stable/elastic/run.html](https://pytorch.org/docs/stable/elastic/run.html)para configurar o ambiente distribuído para processamento paralelo de modelos. TorchServe tem a capacidade de oferecer suporte a vários trabalhadores em um modelo grande. Por padrão, TorchServe usa um algoritmo round-robin para atribuir GPUs a um trabalhador em um host. No caso de inferência de modelos grandes, o número de GPUs atribuídas a cada operador é calculado automaticamente com base no número de GPUs especificado no arquivo `model_config.yaml`. A variável de ambiente `CUDA_VISIBLE_DEVICES`, que especifica as IDs dos dispositivos da GPU que estão visíveis em um determinado momento é definida com base nesse número.

Por exemplo, suponha que haja oito GPUs em um nó, e um operador precise de quatro GPUs em um nó (`nproc_per_node=4`). Nesse caso, TorchServe atribui quatro GPUs ao primeiro trabalhador (`CUDA_VISIBLE_DEVICES="0,1,2,3"`) e quatro GPUs ao segundo trabalhador (). `CUDA_VISIBLE_DEVICES="4,5,6,7”`

Além desse comportamento padrão, TorchServe fornece a flexibilidade para os usuários especificarem GPUs para um trabalhador. Por exemplo, se você definir a variável `deviceIds: [2,3,4,5]` no [arquivo YAML de configuração do modelo](https://github.com/pytorch/serve/blob/5ee02e4f050c9b349025d87405b246e970ee710b/model-archiver/README.md?plain=1#L164) e definir`nproc_per_node=2`, TorchServe atribuirá `CUDA_VISIBLE_DEVICES=”2,3”` ao primeiro trabalhador e `CUDA_VISIBLE_DEVICES="4,5”` ao segundo trabalhador.

No `model_config.yaml` exemplo a seguir, configuramos os parâmetros de front-end e back-end para o modelo. [OPT-30b ](https://huggingface.co/facebook/opt-30b) Os parâmetros de front-end configurados são `parallelType`, `deviceType`, `deviceIds ` e `torchrun`. [Para obter informações mais detalhadas sobre os parâmetros de front-end que você pode configurar, consulte a PyTorch GitHub documentação.](https://github.com/pytorch/serve/blob/2bf505bae3046b0f7d0900727ec36e611bb5dca3/docs/configuration.md?plain=1#L267) A configuração de backend é baseada em um mapa YAML que permite a personalização em estilo livre. Para os parâmetros de back-end, definimos a DeepSpeed configuração e os parâmetros adicionais usados pelo código do manipulador 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
```

### Personalizar manipuladores
<a name="large-model-inference-tutorials-torchserve-getting-started-handlers"></a>

TorchServe oferece [manipuladores básicos](https://github.com/pytorch/serve/tree/master/ts/torch_handler/distributed) e [utilitários de manipulador](https://github.com/pytorch/serve/tree/master/ts/handler_utils) para inferência de modelos grandes criados com bibliotecas populares. O exemplo a seguir demonstra como a classe do manipulador personalizado [TransformersSeqClassifierHandler](https://github.com/pytorch/serve/blob/ab69b69a59d6ca6074df7e6d4014f07eb48dedba/examples/large_models/deepspeed/custom_handler.py#L16C7-L16C39)estende [BaseDeepSpeedHandler](https://github.com/pytorch/serve/blob/ab69b69a59d6ca6074df7e6d4014f07eb48dedba/ts/torch_handler/distributed/base_deepspeed_handler.py#L8)e usa os utilitários do [manipulador](https://github.com/pytorch/serve/blob/master/ts/handler_utils/distributed/deepspeed.py). Para ver um exemplo de código completo, consulte o [`custom_handler.py`código na PyTorch GitHub documentação](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.
        """
```

## Prepare seus artefatos de modelo
<a name="large-model-inference-tutorials-torchserve-artifacts"></a>

Antes de implantar seu modelo na SageMaker IA, você deve empacotar seus artefatos de modelo. Para modelos grandes, recomendamos que você use a ferramenta PyTorch [torch-model-archiver](https://github.com/pytorch/serve/blob/master/model-archiver/README.md) com o argumento`--archive-format no-archive`, que ignora a compactação de artefatos do modelo. O exemplo a seguir salva todos os artefatos do modelo em uma nova pasta chamada `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
```

Depois que a `opt/` pasta for criada, baixe o OPT-30b modelo para a pasta usando a PyTorch [Download\_model](https://github.com/pytorch/serve/blob/master/examples/large_models/utils/Download_model.py)ferramenta.

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

Por fim, faça upload dos artefatos do modelo para um bucket do Amazon S3. 

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

Agora você deve ter artefatos de modelo armazenados no Amazon S3 prontos para serem implantados em SageMaker um endpoint de IA.

## Implante o modelo usando o SDK do SageMaker Python
<a name="large-model-inference-tutorials-torchserve-deploy"></a>

Depois de preparar seus artefatos de modelo, você pode implantar seu modelo em um endpoint de hospedagem de SageMaker IA. Esta seção descreve como implantar um único modelo grande em um endpoint e fazer predições de resposta de streaming. Para obter mais informações sobre streaming de respostas de endpoints, consulte [Invocar endpoints em tempo real](https://docs.aws.amazon.com/sagemaker/latest/dg/realtime-endpoints-test-endpoints.html).

Para implantar seu modelo, conclua as seguintes etapas:

1. Crie uma sessão de SageMaker IA, conforme mostrado no exemplo a seguir.

   ```
   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. Crie um modelo não compactado na SageMaker IA, conforme mostrado no exemplo a seguir.

   ```
   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. Implante o modelo em uma instância do Amazon EC2, conforme mostrado no exemplo a seguir.

   ```
   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. Inicialize uma classe para processar a resposta de streaming, conforme mostrado no exemplo a seguir.

   ```
   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. Teste uma predição de resposta de streaming, conforme mostrado no exemplo a seguir.

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

Agora você implantou seu modelo em um endpoint de SageMaker IA e deve ser capaz de invocá-lo para obter respostas. Para obter mais informações sobre endpoints de SageMaker IA em tempo real, consulte[Single-model endpoints](realtime-single-model.md).