Inferenza del machine learning utilizzando AWS Inferentia - Amazon EKS

Inferenza del machine learning utilizzando AWS Inferentia

In questo argomento viene descritto come creare un cluster Amazon EKS con nodi che eseguono istanze Amazon EC2 Inf1 e (facoltativo) come implementare un'applicazione di esempio. Le istanze Amazon EC2 Inf1 sono alimentate da chip AWS Inferentia creati su misura da AWS per fornire prestazioni elevate e inferenze a costi contenuti nel cloud. I modelli di Machine Learning vengono implementati nei container utilizzando AWS Neuron, un software development kit (SDK) specializzato costituito da compilatore, tempo di esecuzione e strumenti di profilazione che ottimizzano le prestazioni di inferenza del machine learning dei chip Inferentia. AWS Neuron supporta i più diffusi framework di machine learning come TensorFlow, PyTorch e MXNet.

Nota

Gli ID logici dei dispositivi neuronali devono essere contigui. Se un pod che richiede più dispositivi Neuron è pianificato su un tipo di istanza inf1.6xlarge o inf1.24xlarge (che ha più di un dispositivo Neuron), il pod non si avvia se lo scheduler Kubernetes seleziona ID dispositivo non contigui. Per ulteriori informazioni, vedere Gli ID logici del dispositivo devono essere contigui su GitHub.

Prerequisiti

  • Avere eksctl installato sul computer. Se non è installato, vedi Installazione di eksctl per le istruzioni di installazione.

  • Avere kubectl installato sul computer. Per ulteriori informazioni, consulta . Installazione di kubectl.

  • (Facoltativo) Avere python3 installato sul computer. Se non lo hai installato, consulta i download di Python per le istruzioni di installazione.

Creazione di un cluster

Per creare un cluster Amazon EKS con nodi di istanze Amazon EC2 Inf1

  1. Creare un cluster con nodi di istanze Amazon EC2 Inf1. È possibile sostituire <inf1.2xlarge> con qualsiasi tipo di istanza Inf1. Eksctl rileva che si sta avviando un gruppo di nodi con un tipo di istanza Inf1 e avvierà i nodi utilizzando uno dei AMI Amazon Linux accelerata e ottimizzata per Amazon EKS.

    Nota

    Non è possibile utilizzare i ruoli IAM per gli account di servizio con 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

    Notare il valore della seguente riga dell'output. Viene utilizzato in un passaggio successivo (facoltativo).

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

    Quando si avvia un gruppo di nodi con istanze Inf1, eksctl installa automaticamente il plug-in del dispositivo AWS Neuron Kubernetes. Questo plugin pubblicizza i dispositivi Neuron come risorsa di sistema allo scheduler Kubernetes, che può essere richiesto da un container. Oltre alle policy IAM dei nodi Amazon EKS di default, viene aggiunta la policy di accesso di sola lettura Amazon S3 in modo che l'applicazione di esempio, che verrà trattata in un passaggio successivo, possa caricare un modello addestrato da Amazon S3.

  2. Assicurarsi che tutti i pod siano stati avviati correttamente.

    kubectl get pods -n kube-system

    Output abbreviato

    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

(Facoltativo) Distribuire un'immagine dell'applicazione TensorFlow Serving

Un modello addestrato deve essere compilato in un target Inferentia prima di poter essere distribuito nelle istanze di Inf1. Per continuare, è necessario salvare un modello TensorFlow ottimizzato per Neuron in Amazon S3. Se non si dispone già un modello salvato, seguire il tutorial per la creazione di un modello ResNet50 compatibile con Neuron e caricare il modello salvato risultante su S3. ResNet-50 è un modello popolare di machine learning utilizzato per i processi di riconoscimento delle immagini. Per ulteriori informazioni sulla compilazione dei modelli Neuron, vedere Chip AWS Inferentia con DLAMI nella Guida AWS Deep Learning AMI per gli sviluppatori.

Il manifesto di implementazione di esempio gestisce un container pre-costruito di servizio di inferenza per TensorFlow fornito da AWS Deep Learning Containers. All'interno del container si trovano il tempo di esecuzione di AWS Neuron e l'applicazione TensorFlow Serving. Un elenco completo di Deep Learning Containers pre-costruiti ottimizzati per Neuron è consultabile su GitHub in Immagini disponibili. All'avvio, il DLC recupererà il modello da Amazon S3, avvierà Neuron TensorFlow Serving con il modello salvato e attenderà le richieste di previsione.

Il numero di dispositivi Neuron assegnati all'applicazione di servizio può essere regolato modificando la risorsa aws.amazon.com/neuron nella implementazione yaml. Tenere presente che la comunicazione tra TensorFlow Serving e il tempo di esecuzione di Neuron avviene su GRPC, il che richiede il passaggio della capacità IPC_LOCK al container.

  1. Aggiungere la policy AmazonS3ReadOnlyAccess IAM al ruolo di istanza del nodo creato nel passaggio 1 di Creazione di un cluster. Ciò è necessario affinché l'applicazione di esempio possa caricare un modello formato da 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. Crea un file denominato rn50_deployment.yaml con il contenuto riportato di seguito. Aggiornare il codice di Regione e il percorso del modello in modo che corrispondano alle impostazioni desiderate. Il nome del modello è a scopo di identificazione quando un client effettua una richiesta al server TensorFlow. In questo esempio viene utilizzato un nome modello in maniera che corrisponda a un esempio di script client RetNet50 che verrà utilizzato in un passaggio successivo per l'invio di richieste di previsione.

    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. Distribuzione del modello.

    kubectl apply -f rn50_deployment.yaml
  4. Creare un file denominato rn50_service.yaml con i seguenti contenuti. Le porte HTTP e gRPC vengono aperte per accettare le richieste di previsione.

    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. Creare un servizio Kubernetes per l'applicazione di servizio modello TensorFlow.

    kubectl apply -f rn50_service.yaml

(Facoltativo) Effettuare previsioni rispetto al servizio TensorFlow Serving

  1. Per testare localmente, inoltrare la porta gRPC al servizio eks-neuron-test.

    kubectl port-forward service/eks-neuron-test 8500:8500 &
  2. Creare uno script Python chiamato tensorflow-model-server-infer.py con il seguente contenuto. Questo script esegue inferenza tramite gRPC, che è framework di servizio.

    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. Eseguire lo script per inviare previsioni al servizio.

    python3 tensorflow-model-server-infer.py

    Output

    [[(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)]]