Machine Learning-InferenzAWSInferentia - Amazon EKS

Machine Learning-InferenzAWSInferentia

In diesem Thema wird beschrieben, wie Sie einen Amazon EKS-Cluster mit Worker-Knoten erstellen, die Amazon EC2 Inf1 ausführen, und wie Sie (optional) eine Beispielanwendung bereitstellen. Amazon EC2 Inf1-Instances werden von AWS-Inferentia-Chips unterstützt. Diese werden von AWS eigens entwickelt, um eine hohe Leistung bei möglichst geringen Kosten in der Cloud bereitzustellen. Machine Learning-Modelle werden in Containern mithilfe von AWS Neuron in Containern bereitgestellt. Dabei handelt es sich um einen spezialisierten Software Development Kit (SDK) mit Compiler-, Laufzeit- und Profilerstellungs-Tools zur Optimierung der Machine Learning-Inferenzleistung von Inferentia-Chips. AWS Neuron unterstützt verbreitete Machine Learning-Frameworks wie TensorFlow, PyTorch und MXNet.

Anmerkung

Die logischen IDs von Neuron-Geräten müssen konsekutiv sein. Wenn ein Pod, der mehrere Neuron-Geräte anfordert, auf den Instance-Typen inf1.6xlarge oder inf1.24xlarge geplant wird (die mehr als ein Neuron-Gerät besitzen), wird dieser Pod nicht gestartet, wenn der Kubernetes Scheduler keine konsekutiven Geräte-IDs auswählt. Weitere Informationen finden Sie unter Logische Geräte-IDs müssen konsekutiv sein auf GitHub.

Prerequisites

  • eksctl ist auf Ihrem Computer installiert. Installationsanweisungen finden Sie ggf. unter Das eksctl-Befehlszeilen-Dienstprogramm.

  • kubectl ist auf Ihrem Computer installiert. Weitere Informationen finden Sie unter Installieren von kubectl.

  • Installieren Sie python3 auf Ihrem Computer (optional). Wenn dies nicht installiert ist, finden Sie unter Python-Downloads entsprechende Installationsanweisungen.

Erstellen eines Clusters

Erstellen Sie einen Cluster mit Amazon-EC2-Instance-Knoten, auf denen Inf1-Instances ausgeführt werden.

  1. Erstellen Sie einen Cluster mit Knoten, auf denen Inf1 Amazon EC2-Instances ausgeführt werden. Sie können inf1.2xlarge durch einen beliebigen Inf1-Instance-Typersetzen. Eksctl erkennt, dass Sie eine Knotengruppe mit einem Inf1-Instance-Typ starten, und startet daher Ihre Worker-Knoten mit dem Inf1für EKS optimierten beschleunigten AMIAmazon EKS-optimiertes beschleunigtes Amazon-Linux-AMI.

    Anmerkung

    Sie können mit TensorFlow Serving keine IAM-Rollen für Servicekonten verwenden.

    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
    Anmerkung

    Notieren Sie den Wert der folgenden Ausgabezeile. Dieser wird in einem späteren (optionalen) Schritt verwendet werden.

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

    Beim Starten einer Knotengruppe mit Inf1-Instances wird eksctl automatisch das AWS Neuron-Plugin für Kubernetes-Geräte installieren. Dieses Plugin zeigt dem Kubernetes Scheduler Neuron-Geräte als Systemressourcen an, die von einem Container angefordert werden können. Zusätzlich zu den Standardrichtlinien für Amazon EKS-Knoten wird die IAM-Richtlinie für den schreibgeschützten Zugriff von Amazon S3 hinzugefügt. So kann die in einem späteren Schritt behandelte Beispielanwendung ein trainiertes Modell aus Amazon S3 laden.

  2. Überprüfen Sie, ob alle Pods korrekt gestartet wurden.

    kubectl get pods -n kube-system

    Gekürzte Ausgabe

    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

(Optional) Bereitstellung eines TensorFlow Serving-Anwendungsabbilds

Ein trainiertes Modell muss für ein Inferentia-Ziel kompiliert werden, bevor es auf Inferentia-Instances bereitgestellt werden kann. Um fortzufahren, benötigen Sie ein Neuron-optimiertes TensorFlow-Modell, das in Amazon S3 gespeichert ist. Wenn Sie noch kein SavedModel haben, folgen Sie bitte dem TutorialErstellen eines Neuron-kompatiblen ResNet50-Modellsund laden Sie das resultierende SavedModel in S3 hoch. RESnet-50 ist ein verbreitetes Machine Learning-Modell und wird verwendet, um Bilder-Erkennungsaufgaben zu verwenden Weitere Informationen zum Kompilieren von Neuron-Modellen finden Sie unter Der AWS Inferentia-Chip mit DLAMI im AWS Deep Learning AMI-Entwicklerhandbuch.

Das Beispielbereitstellungsmanifest verwaltet einen vordefinierten Inferenz-Server-Container für TensorFlow, der vonAWSDeep Learning Containers Innerhalb des Containers befindet sich dieAWSNeuron Runtime und die TensorFlow Serving Anwendung. Eine vollständige Liste der vorgefertigten Deep Learning Containers, die für Neuron optimiert sind, wird auf GitHub unterVerfügbare Imagesaus. Beim Start ruft das Anwendungsabbild das Modell aus Amazon S3 ab, startet Neuron TensorFlow Serving mit dem gespeicherten Modell und wartet auf Prognoseanfragen.

Die Anzahl der Neuron-Geräte, die Ihrer Servieranwendung zugewiesen sind, kann angepasst werden, indem Sie dieaws.amazon.com/neuronRessource in der Bereitstellung yaml. Bitte beachten Sie, dass die Kommunikation zwischen TensorFlow Serving und der Neuron Runtime über GRPC erfolgt, was dieIPC_LOCK-Fähigkeit auf den Container.

  1. Fügen Sie die IAM Richtlinie AmazonS3ReadOnlyAccess der Worker-Knoten-Instance-Rolle hinzu, die in Schritt 1 unter Erstellen eines Clusters erstellt wurde. Dies ist notwendig, damit die Beispielanwendung ein trainiertes Modell aus Amazon S3 laden kann.

    aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \ --role-name eksctl-<inferentia>-<nodegroup-ng-in>-NodeInstanceRole-<FI7HIYS3BS09>
  2. Erstellen Sie eine Datei mit dem Namen rn50_deployment.yaml und den unten angegebenen Inhalten. Aktualisieren Sie den Regionscode und den Modellpfad entsprechend den gewünschten Einstellungen. Der Modellname dient Identifikationszwecken, wenn ein Client eine Anforderung an den TensorFlow-Server stellt. In diesem Beispiel wird ein Modellname einem BERT-Client-Beispielskript zugeordnet, das in einem späteren Schritt zum Senden von Prognoseanforderungen verwendet wird.

    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. Stellen Sie das Modell bereit.

    kubectl apply -f rn50_deployment.yaml
  4. Erstellen Sie eine Datei mit dem Namen rn50_service.yaml und dem folgenden Inhalt. Die HTTP- und gRPC-Ports werden für die Annahme von Prognoseanforderungen geöffnet.

    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. Erstellen Sie einen Kubernetes-Service für Ihre TensorFlow Serving-Modellanwendung.

    kubectl apply -f rn50_service.yaml

(Optional) Erstellung von Prognosen für den TensorFlow Serving-Service

  1. Um dies lokal zu testen, leiten Sie den gRPC-Port an den Service eks-neuron-test weiter.

    kubectl port-forward service/eks-neuron-test 8500:8500 &
  2. Erstellen Sie das Python-Skript namens tensorflow-model-server-infer.py mit folgendem Inhalt. Dieses Skript führt die Inferenz über gRPC (Service-Framework) aus.

    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. Führen Sie das Skript aus, um Prognosen an den Service zu senden.

    python3 tensorflow-model-server-infer.py

    Ausgabe

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