

 **Ajudar a melhorar esta página** 

Para contribuir com este guia de usuário, escolha o link **Editar esta página no GitHub**, disponível no painel direito de cada página.

# Usar instâncias do AWS Inferentia com o Amazon EKS para machine learning
<a name="inferentia-support"></a>

Este tópico descreve como criar um cluster do Amazon EKS com nós que executam as instâncias [Amazon EC2 Inf1](https://aws.amazon.com/ec2/instance-types/inf1/) e (opcionalmente) implantar uma aplicação de exemplo. As instâncias Inf1 do Amazon EC2 são alimentadas por chips do [AWS Inferentia](https://aws.amazon.com/machine-learning/inferentia/) que são personalizados pela AWS para fornecer alta performance e inferência de menor custo na nuvem. Os modelos de machine learning são implantados em contêineres usando o [AWS Neuron](https://aws.amazon.com/machine-learning/neuron/), um kit de desenvolvimento de software (SDK) especializado que consiste em um compilador, runtime e ferramentas de perfil que otimizam a performance de inferências de machine learning dos chips do AWS Inferentia. O Neuron é compatível com frameworks de machine learning muito usados, como TensorFlow, PyTorch e MXNet.

**nota**  
Os IDs lógicos do dispositivo Neuron devem ser contíguos. Se um pod que solicita vários dispositivos Neuron estiver agendado em um tipo de instância `inf1.6xlarge` ou `inf1.24xlarge` (que tem mais de um dispositivo Neuron), esse pod não será iniciado se o agendador do Kubernetes selecionar IDs de dispositivo não contíguos. Para obter mais informações, consulte [Device logical IDs must be contiguous](https://github.com/aws/aws-neuron-sdk/issues/110) no GitHub.

## Pré-requisitos
<a name="inferentia-prerequisites"></a>
+ Ter o `eksctl` instalado no computador. Se ele não estiver instalado, consulte [Instalação](https://eksctl.io/installation) na documentação do `eksctl`.
+ Ter o `kubectl` instalado no computador. Para obter mais informações, consulte [Configurar o `kubectl` e o `eksctl`](install-kubectl.md).
+ (Opcional) Instale o `python3` no computador. Se você não o tiver instalado, consulte as instruções de instalação de [downloads do Python](https://www.python.org/downloads/).

## Criar um cluster
<a name="create-cluster-inferentia"></a>

1. Crie um cluster com os nós da instância Inf1 do Amazon EC2. É possível substituir {{inf1.2xlarge}} por qualquer [tipo de instância Inf1](https://aws.amazon.com/ec2/instance-types/inf1/). O utilitário `eksctl` detecta que você está iniciando um grupo de nós com um tipo de instância `Inf1` e iniciará seus nós utilizando uma das AMIs aceleradas do Amazon Linux otimizadas para Amazon EKS.
**nota**  
Você não pode usar [perfis do IAM para contas de serviço](iam-roles-for-service-accounts.md) com o TensorFlow Serving.

   ```
   eksctl create cluster \
       --name inferentia \
       --region region-code \
       --nodegroup-name ng-inf1 \
       --node-type inf1.2xlarge \
       --nodes 2 \
       --nodes-min 1 \
       --nodes-max 4 \
       --ssh-access \
       --ssh-public-key your-key \
       --with-oidc
   ```
**nota**  
Observe o valor da seguinte linha da saída. Ele é usado em uma etapa posterior (opcional).

   ```
   [9]  adding identity "arn:aws:iam::111122223333:role/eksctl-inferentia-nodegroup-ng-in-NodeInstanceRole-FI7HIYS3BS09" to auth ConfigMap
   ```

   Ao iniciar um grupo de nós com instâncias `Inf1`, o `eksctl` instala automaticamente o plug-in de dispositivo Kubernetes do AWS Neuron. Este plug-in anuncia dispositivos Neuron como um recurso de sistema para o programador Kubernetes, que pode ser solicitado por um contêiner. Além das políticas padrão do IAM do nó do Amazon EKS, a política de acesso somente leitura do Amazon S3 é adicionada para que a aplicação de exemplo, abordada em uma etapa posterior, possa carregar um modelo treinado do Amazon S3.

1. Verifique se todos os pods foram iniciados corretamente.

   ```
   kubectl get pods -n kube-system
   ```

   Saída abreviada:

   ```
   NAME                                   READY   STATUS    RESTARTS   AGE
   [...]
   neuron-device-plugin-daemonset-6djhp   1/1     Running   0          5m
   neuron-device-plugin-daemonset-hwjsj   1/1     Running   0          5m
   ```

## (Opcional) Implante uma imagem da aplicação do TensorFlow Serving
<a name="deploy-tensorflow-serving-application"></a>

Um modelo treinado deve ser compilado para um destino do Inferentia antes que possa ser implantado em instâncias do Inferentia. Para continuar, você precisará de um modelo do [TensorFlow otimizado para Neuron](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/tensorflow-neuron/index.html) salvo no Amazon S3. Se você ainda não tem um SavedModel, siga o tutorial para [Criar um modelo ResNet50 compatível com Neuron](https://docs.aws.amazon.com/dlami/latest/devguide/tutorial-inferentia-tf-neuron.html) e carregue o SavedModel resultante no S3. O Resnet-50 é um modelo de machine learning popular usado para tarefas de reconhecimento de imagem. Para obter mais informações sobre a compilação de modelos Neuron, consulte [O chip AWS Inferentia com DLAMI](https://docs.aws.amazon.com/dlami/latest/devguide/tutorial-inferentia.html) no Guia do desenvolvedor de AMIs de aprendizagem profunda AWS.

O exemplo de manifesto de implantação gerencia um contêiner de serviço de inferência pré-criado para o TensorFlow fornecido pelo AWS Deep Learning Containers. Dentro do recipiente está o AWS Neuron Runtime e a aplicação TensorFlow Serving. Uma lista completa de Deep Learning Containers pré-criados otimizados para Neuron é mantida no GitHub em [Available Images](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#neuron-inference-containers) (Imagens Disponíveis). Na inicialização, o DLC buscará o modelo do Amazon S3, iniciará o Neuron TensorFlow Serving com o modelo salvo e aguardará as solicitações de previsão.

O número de dispositivos Neuron alocados para a aplicação de serviço pode ser ajustado alterando o recurso `aws.amazon.com/neuron` no yaml de implantação. Observe que a comunicação entre o TensorFlow Serving e o runtime do Neuron acontece no GRPC, o que requer a transferência do recurso `IPC_LOCK` para o contêiner.

1. Adicione a política do IAM `AmazonS3ReadOnlyAccess` à perfil de instância de nó que foi criada na etapa 1 de [Criar um cluster](#create-cluster-inferentia). Isso é necessário para que a aplicação de exemplo possa carregar um modelo treinado do Amazon S3.

   ```
   aws iam attach-role-policy \
       --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
       --role-name eksctl-inferentia-nodegroup-ng-in-NodeInstanceRole-FI7HIYS3BS09
   ```

1. Crie um arquivo denominado `rn50_deployment.yaml` com os conteúdos a seguir. Atualize o código da região e o caminho do modelo para corresponder às configurações desejadas. O nome do modelo é para fins de identificação quando um cliente faz uma solicitação ao servidor do TensorFlow. Este exemplo usa um nome de modelo para corresponder a um script de cliente ResNet50 de exemplo que será usado em uma etapa posterior para enviar solicitações de previsão.

   ```
   aws ecr list-images --repository-name neuron-rtd --registry-id 790709498068 --region us-west-2
   ```

   ```
   kind: Deployment
   apiVersion: apps/v1
   metadata:
     name: eks-neuron-test
     labels:
       app: eks-neuron-test
       role: master
   spec:
     replicas: 2
     selector:
       matchLabels:
         app: eks-neuron-test
         role: master
     template:
       metadata:
         labels:
           app: eks-neuron-test
           role: master
       spec:
         containers:
           - name: eks-neuron-test
             image: 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference-neuron:1.15.4-neuron-py37-ubuntu18.04
             command:
               - /usr/local/bin/entrypoint.sh
             args:
               - --port=8500
               - --rest_api_port=9000
               - --model_name=resnet50_neuron
               - --model_base_path=s3://${your-bucket-of-models}/resnet50_neuron/
             ports:
               - containerPort: 8500
               - containerPort: 9000
             imagePullPolicy: IfNotPresent
             env:
               - name: AWS_REGION
                 value: "us-east-1"
               - name: S3_USE_HTTPS
                 value: "1"
               - name: S3_VERIFY_SSL
                 value: "0"
               - name: S3_ENDPOINT
                 value: s3.us-east-1.amazonaws.com
               - name: AWS_LOG_LEVEL
                 value: "3"
             resources:
               limits:
                 cpu: 4
                 memory: 4Gi
                 aws.amazon.com/neuron: 1
               requests:
                 cpu: "1"
                 memory: 1Gi
             securityContext:
               capabilities:
                 add:
                   - IPC_LOCK
   ```

1. Implante o modelo.

   ```
   kubectl apply -f rn50_deployment.yaml
   ```

1. Crie um arquivo denominado `rn50_service.yaml` com o conteúdo a seguir. As portas HTTP e gRPC são abertas para aceitar solicitações de previsão.

   ```
   kind: Service
   apiVersion: v1
   metadata:
     name: eks-neuron-test
     labels:
       app: eks-neuron-test
   spec:
     type: ClusterIP
     ports:
       - name: http-tf-serving
         port: 8500
         targetPort: 8500
       - name: grpc-tf-serving
         port: 9000
         targetPort: 9000
     selector:
       app: eks-neuron-test
       role: master
   ```

1. Crie um serviço Kubernetes para a sua aplicação de modelo do TensorFlow Serving.

   ```
   kubectl apply -f rn50_service.yaml
   ```

## (Opcional) Faça previsões em relação ao serviço do TensorFlow Serving
<a name="make-predictions-against-tensorflow-service"></a>

1. Para testar localmente, encaminhe a porta gRPC para o serviço `eks-neuron-test`.

   ```
   kubectl port-forward service/eks-neuron-test 8500:8500 &
   ```

1. Crie um script Python chamado `tensorflow-model-server-infer.py` com o conteúdo a seguir. Esse script executa a inferência via gRPC, que é um framework de serviço.

   ```
   import numpy as np
   import grpc
   import tensorflow as tf
   from tensorflow.keras.preprocessing import image
   from tensorflow.keras.applications.resnet50 import preprocess_input
   from tensorflow_serving.apis import predict_pb2
   from tensorflow_serving.apis import prediction_service_pb2_grpc
   from tensorflow.keras.applications.resnet50 import decode_predictions
   
   if __name__ == '__main__':
      channel = grpc.insecure_channel('localhost:8500')
      stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
      img_file = tf.keras.utils.get_file(
          "./kitten_small.jpg",
          "https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg")
      img = image.load_img(img_file, target_size=(224, 224))
      img_array = preprocess_input(image.img_to_array(img)[None, ...])
      request = predict_pb2.PredictRequest()
      request.model_spec.name = 'resnet50_inf1'
      request.inputs['input'].CopyFrom(
          tf.make_tensor_proto(img_array, shape=img_array.shape))
      result = stub.Predict(request)
      prediction = tf.make_ndarray(result.outputs['output'])
      print(decode_predictions(prediction))
   ```

1. Execute o script para enviar previsões ao seu serviço.

   ```
   python3 tensorflow-model-server-infer.py
   ```

   Veja um exemplo de saída abaixo.

   ```
   [[(u'n02123045', u'tabby', 0.68817204), (u'n02127052', u'lynx', 0.12701613), (u'n02123159', u'tiger_cat', 0.08736559), (u'n02124075', u'Egyptian_cat', 0.063844085), (u'n02128757', u'snow_leopard', 0.009240591)]]
   ```