Implantar workloads de inferência de ML com o AWSInferentia no Amazon EKS - Amazon EKS

Ajudar a melhorar esta página

Quer contribuir para este guia do usuário? Role até o final desta página e selecione Editar esta página no GitHub. Suas contribuições ajudarão a tornar nosso guia do usuário melhor para todos.

Implantar workloads de inferência de ML com o AWSInferentia no Amazon EKS

Este tópico descreve como criar um cluster do Amazon EKS com nós que executam as instâncias Amazon EC2 Inf1 e (opcionalmente) implantar uma aplicação de exemplo. As instâncias Inf1 do Amazon EC2 são alimentadas por chips do AWS 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, 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 têm 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 (IDS lógicos de dispositivos não devem ser contíguos) no GitHub.

Pré-requisitos

  • Ter o eksctl instalado no computador. Se ele não estiver instalado, consulte Instalação na documentação do eksctl.

  • Ter o kubectl instalado no computador. Para ter mais informações, consulte Configurar o kubectl e o eksctl.

  • (Opcional) Instale o python3 no computador. Se você não o tiver instalado, consulte as instruções de instalação de downloads do Python.

Criar um cluster

Para criar um cluster com os nós da instância Inf1 do Amazon EC2
  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. 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 funções do IAM para contas de serviço 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 AWS Neuron Kubernetes. Este plug-in anuncia dispositivos Neuron como um recurso de sistema para o agendador do 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.

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

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 salvo no Amazon S3. Se você ainda não tem um SavedModel, siga o tutorial para Criar um modelo ResNet50 compatível com Neuron 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 como compilar modelos do Neuron, consulte The AWS Inferentia Chip With DLAMI no Manual do desenvolvedor do AWS Deep Learning AMI.

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 contêiners de aprendizado profundo criados previamente e otimizados para o Neuron é mantida no GitHub em Available Images (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 AmazonS3ReadOnlyAccess do política do IAM à função de instância do nó que foi criada na etapa 1 do Criar um cluster. 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
  2. Crie um arquivo denominado rn50_deployment.yaml com o seguinte conteúdo: 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
  3. Implante o modelo.

    kubectl apply -f rn50_deployment.yaml
  4. 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
  5. Crie um serviço Kubernetes para a aplicação de fornecimento de modelos TensorFlow.

    kubectl apply -f rn50_service.yaml

(Opcional) Faça previsões em relação ao serviço do TensorFlow Serving

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

    kubectl port-forward service/eks-neuron-test 8500:8500 &
  2. 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))
  3. 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)]]