Mit Triton-Inferenzserver und Tesla T4 ein skalierbares TensorFlow-Inferenzsystem erstellen

In dieser Anleitung wird gezeigt, wie Sie ein skalierbares TensorFlow-Inferenzsystem erstellen, das NVIDIA Tesla T4 und Triton Inference Server (bisher TensorRT-Inferenzserver genannt) verwendet. Eine Architekturübersicht über das System und die Terminologie, die in dieser Reihe verwendet wird, finden Sie in Teil 1 dieser Reihe. Informationen zum Messen der Leistung und zum Optimieren des Systems finden Sie in Teil 3 dieser Reihe.

Ziele

  • Laden Sie ein vortrainiertes ResNet-50-Modell herunter und verwenden Sie die TensorFlow-Integration mit TensorRT (TF-TRT), um Optimierungen anzuwenden.
  • Mithilfe von Triton ein Inferenzserversystem für das ResNet-50-Modell erstellen
  • Erstellen Sie mithilfe von Prometheus und Grafana ein Monitoringsystem für Triton.
  • Erstellen Sie mit Locust ein Tool für Lasttests.

Kosten

Zusätzlich zur Verwendung der NVIDIA T4-GPU werden in dieser Anleitung die folgenden kostenpflichtigen Komponenten von Google Cloud verwendet:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.

Löschen Sie nach Abschluss dieser Anleitung die von Ihnen erstellten Ressourcen nicht. Sie benötigen diese Ressourcen in Teil 3 dieser Reihe.

Hinweis

  1. Melden Sie sich bei Ihrem Google Cloud-Konto an. Wenn Sie mit Google Cloud noch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  3. Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.

  4. Aktivieren Sie die GKE API.

    Aktivieren Sie die API

  5. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  6. Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.

  7. Aktivieren Sie die GKE API.

    Aktivieren Sie die API

ResNet-50-Modell vorbereiten

In dieser Anleitung stellen Sie ein ResNet-50-Modell mithilfe des Inferenzsystems bereit. Im nächsten Abschnitt laden Sie das vortrainierte Modell herunter. Wenn Sie dieses vortrainierte Modell verwenden möchten, können Sie diesen Abschnitt überspringen. Wenn Sie das gleiche Modell selbst erstellen möchten, folgen Sie den Schritten in diesem Abschnitt.

Sie trainieren ein ResNet-50-Modell und exportieren es im SavedModel-Format, indem Sie Training ResNet auf Cloud TPU trainieren und die folgenden Änderungen vornehmen:

  1. Ersetzen Sie die Bereitstellungseingabefunktion image_serving_input_fn in /usr/share/tpu/models/official/resnet/imagenet_input.py durch die folgende Funktion:

    def image_serving_input_fn():
      """Serving input fn for raw images."""
    
      # The shape of input tensor is changed to NWHC.
      input_tensor = tf.placeholder(
          shape=[None, 224, 224, 3],
          dtype=tf.float32,
          name='input_tensor')
    
      # this line is just for simplicity
      images = input_tensor
    
      return tf.estimator.export.TensorServingInputReceiver(
          features=images, receiver_tensors=input_tensor)
    

    Da Triton das Base64-Stringformat nicht effizient als Eingabedaten verarbeiten kann, müssen Sie das Format des Eingabetensors von base64 in NWHC ändern (N, Breite, Höhe, Kanal). Die erste Dimension der Option shape (6. Zeile im Code) sollte None sein. Wenn Sie diese Dimension auf eine konstante Zahl setzen, wird das Modell im nächsten Schritt nicht richtig mit INT8 quantifiziert.

  2. Führen Sie den Schritt ResNet-50-Modell mit fake_imagenet ausführen aus, anstatt das vollständige ImageNet-Dataset zu verwenden, da es einige Tage dauert. um den Vorgang abzuschließen, wenn Sie das vollständige Dataset verwenden. Das Modell, das mithilfe der gefälschten Bildflecken für den Zweck dieser Anleitung trainiert wurde.

  3. Ändern Sie die Anzahl der Trainingsschritte und die Anzahl der Iterationen pro Schleife in der Konfigurationsdatei, um die Trainingszeit zu reduzieren. Sie können zum Beispiel /usr/share/tpu/models/official/resnet/configs/cloud/v2-8.yaml so ändern:

    train_steps: 100
    train_batch_size: 1024
    eval_batch_size: 1024
    iterations_per_loop: 100
    skip_host_call: True
    num_cores: 8
    
  4. Geben Sie beim Ausführen des Trainingsskripts mit der Option --export_dir den Exportpfad an. Mit dieser Option wird das Skript angewiesen, das trainierte Modell im SavedModel-Format zu exportieren:

    export PYTHONPATH="$PYTHONPATH:/usr/share/tpu/models"
    python /usr/share/tpu/models/official/resnet/resnet_main.py \
        --tpu=${TPU_NAME} \
        --mode=train \
        --data_dir=gs://cloud-tpu-test-datasets/fake_imagenet/ \
        --model_dir=${MODEL_DIR} \
        --export_dir=${MODEL_DIR}/export \
        --config_file=/usr/share/tpu/models/official/resnet/configs/cloud/v2-8.yaml
    

    In diesem Beispiel wird das trainierte Modell nach Abschluss des Trainingsskripts im SavedModel-Format unter ${MODEL_DIR}/export in Cloud Storage exportiert.

Im folgenden Abschnitt wird angenommen, dass das Modell mit dem falschen Dataset unter gs://cloud-tpu-test-datasets/fake_imagenet/ trainiert und in gs://solutions-public-assets/tftrt-tutorial/resnet/export/1584366419/ exportiert wird. In den folgenden Schritten ändern Sie diesen URI gemäß Ihrer Einrichtung.

Optimierte Modelle mit TF-TRT erstellen

In diesem Abschnitt optimieren und quantifizieren Sie das vortrainierte Modell. In den folgenden Abschnitten wird die Arbeitsumgebung verwendet, die Sie in diesem Abschnitt erstellen.

Arbeitsumgebung erstellen

Sie erstellen Ihre Arbeitsumgebung, indem Sie mithilfe des Deep Learning-VM-Image eine Compute Engine-Instanz erstellen. Sie optimieren und quantifizieren das ResNet-50-Modell mit TensorRT auf dieser Instanz.

  1. Cloud Shell öffnen

    Zu Cloud Shell

  2. Stellen Sie eine Instanz bereit. Ersetzen Sie dabei PROJECT_ID durch die Projekt-ID des Cloud-Projekts, das Sie zuvor erstellt haben:

    gcloud config set project PROJECT_ID
    gcloud config set compute/zone us-west1-b
    gcloud compute instances create working-vm \
        --scopes cloud-platform \
        --image-family common-cu101 \
        --image-project deeplearning-platform-release \
        --machine-type n1-standard-8 \
        --min-cpu-platform="Intel Skylake" \
        --accelerator=type=nvidia-tesla-t4,count=1 \
        --boot-disk-size=200GB \
        --maintenance-policy=TERMINATE \
        --metadata="install-nvidia-driver=True"
    

    Dieser Befehl startet eine Google Cloud-Instanz mit Tesla T4. Beim ersten Start wird der NVIDIA GPU-Treiber, der mit TensorRT 5.1.5 kompatibel ist, automatisch installiert.

Modelldateien mit unterschiedlichen Optimierungen erstellen

Wenden Sie die folgenden Optimierungen mithilfe von TF-TRT auf das ursprüngliche ResNet-50-Modell an:

  • Grafikoptimierung
  • Konvertierung in FP16 zusätzlich zur Grafikoptimierung
  • Quantisieren mit INT8 zusätzlich zur Grafikoptimierung

Diese Optimierungen werden in Teil 1 dieser Reihe im Abschnitt Leistungsoptimierung erläutert.

  1. Gehen Sie in der Cloud Console zu Compute Engine > VM-Instanzen.

    Zur Seite „VM-Instanzen“

    Sie sehen die Instanz, die Sie im vorherigen Abschnitt erstellt haben.

  2. Klicken Sie auf SSH, um die Terminalkonsole der Instanz zu öffnen. Sie verwenden dieses Terminal, um die Befehle in dieser Anleitung auszuführen.

  3. Klonen Sie im Terminal das für diese Anleitung benötigte Repository und ändern Sie das aktuelle Verzeichnis:

    cd $HOME
    git clone https://github.com/GoogleCloudPlatform/gke-tensorflow-inference-system-tutorial
    cd gke-tensorflow-inference-system-tutorial/server
    
  4. Laden Sie ein vortrainiertes ResNet-50-Modell herunter oder kopieren Sie das von Ihnen erstellte Modell in ein lokales Verzeichnis:

    mkdir -p models/resnet/original/00001
    gsutil cp -R gs://solutions-public-assets/tftrt-tutorial/resnet/export/1584366419/* models/resnet/original/00001
    
  5. Erstellen Sie ein Container-Image, das Optimierungstools für TF-TRT enthält:

    docker build ./ -t trt-optimizer
    docker image list
    

    Der letzte Befehl zeigt die Bild-IDs. Kopieren Sie die Image-ID mit dem Repository-Namen tft-optimizer. Im folgenden Beispiel lautet die Image-ID 3fa16b1b864c.

    REPOSITORY                     TAG                 IMAGE ID            CREATED              SIZE
    trt-optimizer                  latest              3fa16b1b864c        About a minute ago   6.96GB
    nvcr.io/nvidia/tensorflow      19.05-py3           01c8c4b0d7ff        2 months ago         6.96GB
    gcr.io/inverting-proxy/agent   <none>              81311f835221        2 months ago         856MB
    
  6. Wenden Sie die Optimierungen auf das ursprüngliche Modell an und ersetzen Sie IMAGE-ID durch die Bild-ID, die Sie im vorherigen Schritt kopiert haben:

    export IMAGE_ID=IMAGE-ID
    
    nvidia-docker run --rm \
        -v `pwd`/models/:/workspace/models ${IMAGE_ID} \
        --input-model-dir='models/resnet/original/00001' \
        --output-dir='models/resnet' \
        --precision-mode='FP32' \
        --batch-size=64
    
    nvidia-docker run --rm \
        -v `pwd`/models/:/workspace/models ${IMAGE_ID} \
        --input-model-dir='models/resnet/original/00001' \
        --output-dir='models/resnet' \
        --precision-mode='FP16' \
        --batch-size=64
    
    nvidia-docker run --rm \
        -v `pwd`/models/:/workspace/models ${IMAGE_ID} \
        --input-model-dir='models/resnet/original/00001' \
        --output-dir='models/resnet' \
        --precision-mode='INT8' \
        --batch-size=64 \
        --calib-image-dir='gs://cloud-tpu-test-datasets/fake_imagenet/' \
        --calibration-epochs=10
    

    Die drei vorhergehenden Befehle entsprechen den drei Optimierungen: Grafikoptimierung, Konvertierung in FP16 und Quantisierung mit INT8. Es gibt einen zusätzlichen Prozess namens Kalibration für INT8 Quantisierung. Für diesen Prozess müssen Sie Trainingsdaten bereitstellen, indem Sie in den letzten drei Befehlen die Option --calib-image-dir angeben. Sie verwenden die Trainingsdaten, die Sie zum Trainieren des ursprünglichen Modells verwendet haben. Der Kalibrierungsprozess dauert nur etwa fünf Minuten.

    Nach Abschluss der Befehle werden optimierte Modell-Binärdateien im Verzeichnis ./models/resnet gespeichert. Die Struktur des Verzeichnisses lautet wie folgt:

    models
    └── resnet
        ├── FP16
        │   └── 00001
        │       ├── saved_model.pb
        │       └── variables
        ├── FP32
        │   └── 00001
        │       ├── saved_model.pb
        │       └── variables
        ├── INT8
        │   └── 00001
        │       ├── saved_model.pb
        │       └── variables
        └── original
            └── 00001
                ├── saved_model.pb
                └── variables
                    ├── variables.data-00000-of-00001
                    └── variables.index
    

In der folgenden Tabelle wird die Beziehung zwischen Verzeichnissen und Optimierungen zusammengefasst.

Verzeichnis Optimierung
original Ursprüngliches Modell (keine Optimierung mit TF-TRT)
FP32 Grafikoptimierung
FP16 Konvertierung in FP16 zusätzlich zur Grafikoptimierung
INT8 Quantisieren mit INT8 zusätzlich zur Grafikoptimierung

Inferenzserver bereitstellen

In diesem Abschnitt stellen Sie Triton-Server mit fünf Modellen bereit. Zuerst laden Sie die im vorherigen Abschnitt erstellte Modell-Binärdatei in Cloud Storage hoch. Dann erstellen Sie einen GKE-Cluster und stellen Triton-Server im Cluster bereit.

Modellbinärdatei hochladen

  1. Laden Sie die Binärdateien des Modells in einen Storage-Bucket hoch. Ersetzen Sie dabei PROJECT_ID durch die Projekt-ID Ihres Google Cloud-Projekts:

    export PROJECT_ID=PROJECT_ID
    export BUCKET_NAME=${PROJECT_ID}-models
    
    mkdir -p original/1/model/
    cp -r models/resnet/original/00001/* original/1/model/
    cp original/config.pbtxt original/1/model/
    cp original/imagenet1k_labels.txt original/1/model/
    
    mkdir -p tftrt_fp32/1/model/
    cp -r models/resnet/FP32/00001/* tftrt_fp32/1/model/
    cp tftrt_fp32/config.pbtxt tftrt_fp32/1/model/
    cp tftrt_fp32/imagenet1k_labels.txt tftrt_fp32/1/model/
    
    mkdir -p tftrt_fp16/1/model/
    cp -r models/resnet/FP16/00001/* tftrt_fp16/1/model/
    cp tftrt_fp16/config.pbtxt tftrt_fp16/1/model/
    cp tftrt_fp16/imagenet1k_labels.txt tftrt_fp16/1/model/
    
    mkdir -p tftrt_int8/1/model/
    cp -r models/resnet/INT8/00001/* tftrt_int8/1/model/
    cp tftrt_int8/config.pbtxt tftrt_int8/1/model/
    cp tftrt_int8/imagenet1k_labels.txt tftrt_int8/1/model/
    
    mkdir -p tftrt_int8_bs16_count4/1/model/
    cp -r models/resnet/INT8/00001/* tftrt_int8_bs16_count4/1/model/
    cp tftrt_int8_bs16_count4/config.pbtxt tftrt_int8_bs16_count4/1/model/
    cp tftrt_int8_bs16_count4/imagenet1k_labels.txt tftrt_int8_bs16_count4/1/model/
    
    gsutil mb gs://${BUCKET_NAME}
    gsutil -m cp -R original tftrt_fp32 tftrt_fp16 tftrt_int8 tftrt_int8_bs16_count4 \
        gs://${BUCKET_NAME}/resnet/
    

    In diesem Schritt haben Sie zusätzlich zur Modellbinärdatei die Konfigurationsdatei config.pbtxt hochgeladen. Im Folgenden wird beispielsweise der Inhalt von original/1/model/config.pbtxt angezeigt:

    name: "original"
    platform: "tensorflow_savedmodel"
    max_batch_size: 64
    input {
        name: "input"
        data_type: TYPE_FP32
        format: FORMAT_NHWC
        dims: [ 224, 224, 3 ]
    }
    output {
        name: "probabilities"
        data_type: TYPE_FP32
        dims: 1000
        label_filename: "imagenet1k_labels.txt"
    }
    default_model_filename: "model"
    instance_group [
      {
        count: 1
        kind: KIND_GPU
      }
    ]
    dynamic_batching {
      preferred_batch_size: [ 64 ]
      max_queue_delay_microseconds: 20000
    }
    

In dieser Datei werden die folgenden Abstimmungsparameter angegeben. Die Batchgröße und die Anzahl der Instanzgruppen werden in Teil 1 dieser Reihe im Abschnitt zur Leistungsoptimierung erläutert.

  • Modellname
  • Name des Tensors und des Ausgabetensors
  • GPU-Zuweisung für jedes Modell
  • Batchgröße und Anzahl von Instanzgruppen

In der folgenden Tabelle sind die fünf Modelle aufgeführt, die Sie in diesem Abschnitt bereitgestellt haben.

Modellname Optimierung
original Ursprüngliches Modell (keine Optimierung mit TF-TRT)
tftrt_fp32 Grafikoptimierung
(Batch-Größe=64, Instanzgruppen=1)
tftrt_fp16 Konvertierung in FP16 zusätzlich zur Grafikoptimierung
(Batch-Größe=64, Instanzgruppen=1)
tftrt_int8 Quantisieren mit INT8 zusätzlich zur Grafikoptimierung
(Batch-Größe=64, Instanzgruppen=1)
tftrt_int8_bs16_count4 Quantisieren mit INT8 zusätzlich zur Grafikoptimierung
(Batch-Größenbereich, Instanzgruppen=4)

Inferenzserver mithilfe von Triton bereitstellen

  1. GKE-Cluster mit Compute-Knoten mit NVIDIA Tesla T4 erstellen

    gcloud auth login
    gcloud config set compute/zone us-west1-b
    gcloud container clusters create tensorrt-cluster \
        --num-nodes=20
    gcloud container node-pools create t4-pool \
        --num-nodes=1 \
        --machine-type=n1-standard-8 \
        --cluster=tensorrt-cluster \
        --accelerator type=nvidia-tesla-t4,count=1
    

    Diese Befehle erstellen einen GKE-Cluster mit 20 Knoten und fügen einen GPU-Knotenpool gpu-pool hinzu. Der GPU-Knotenpool besteht aus einer einzelnen n1-standard-8-Instanz mit NVIDIA Tesla T4-GPU. Die Anzahl der GPU-Instanzen sollte gleich oder größer sein als die Anzahl der Inferenz-Server-Pods, da die NVIDIA Tesla T4-GPU nicht von mehreren Pods in derselben Instanz gemeinsam genutzt werden kann. Die Option --num-nodes im vorherigen Befehl gibt die Anzahl der Instanzen an.

  2. Rufen Sie die Clusterinformationen auf:

    gcloud container clusters list
    

    Die Ausgabe sieht etwa so aus:

    NAME              LOCATION    MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION    NUM_NODES  STATUS
    tensorrt-cluster  us-west1-b  1.14.10-gke.17  XX.XX.XX.XX    n1-standard-1  1.14.10-gke.17  21         RUNNING
    
  3. Zeigen Sie die Knotenpoolinformationen an:

    gcloud container node-pools list --cluster tensorrt-cluster
    

    Die Ausgabe sieht etwa so aus:

    NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
    default-pool  n1-standard-1  100           1.14.10-gke.17
    t4-pool       n1-standard-8  100           1.14.10-gke.17
    
  4. Aktivieren Sie die Arbeitslast daemonSet:

    gcloud container clusters get-credentials tensorrt-cluster
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/cos/daemonset-preloaded.yaml
    

    Mit diesem Befehl wird der NVIDIA GPU-Treiber auf den Knoten im GPU-Knotenpool geladen. Der Treiber wird auch automatisch geladen, wenn Sie dem GPU-Knotenpool einen neuen Knoten hinzufügen.

  5. Inferenzserver im Cluster bereitstellen:

    sed -i.bak "s/YOUR-BUCKET-NAME/${PROJECT_ID}-models/" trtis_deploy.yaml
    kubectl create -f trtis_service.yaml
    kubectl create -f trtis_deploy.yaml
    
  6. Warten Sie einige Minuten, bis die Dienste verfügbar sind.

  7. Rufen Sie die clusterIP-Adresse von Triton ab und speichern Sie sie in der Umgebungsvariablen, die Sie in den folgenden Schritten verwenden:

    export TRITON_IP=$(kubectl get svc inference-server \
      -o "jsonpath={.spec['clusterIP']}")
    echo ${TRITON_IP}
    

An diesem Punkt liefert der Inferenzserver vier ResNet-50-Modelle, die Sie im Abschnitt Modelldateien mit unterschiedlichen Optimierungen erstellen erstellt haben. Clients können das Modell angeben, das beim Senden von Inferenzanfragen verwendet werden soll.

Monitoring-Server mit Prometheus und Grafana bereitstellen

  1. Stellen Sie Prometheus-Server im Cluster bereit:

    sed -i.bak "s/CLUSTER-IP/${TRITON_IP}/" prometheus-configmap.yml
    kubectl create namespace monitoring
    kubectl apply -f prometheus-service.yml -n monitoring
    kubectl create -f clusterRole.yml
    kubectl create -f prometheus-configmap.yml -n monitoring
    kubectl create -f prometheus-deployment.yml -n monitoring
    
  2. Rufen Sie die Endpunkt-URL des Prometheus-Dienstes ab. Kopieren Sie den Endpunkt, da Sie damit in den folgenden Schritten Grafana konfigurieren.

    ip_port=$(kubectl get svc prometheus-service \
      -o "jsonpath={.spec['clusterIP']}:{.spec['ports'][0]['port']}" -n monitoring)
    echo "http://${ip_port}"
    
  3. Stellen Sie Grafana-Server im Cluster bereit:

    kubectl create -f grafana-service.yml -n monitoring
    kubectl create -f grafana-deployment.yml -n monitoring
    
  4. Warten Sie einige Minuten, bis alle Dienste verfügbar sind.

  5. Rufen Sie die Endpunkt-URL des Grafana-Dienstes ab.

    ip_port=$(kubectl get svc grafana-service \
      -o "jsonpath={.status['loadBalancer']['ingress'][0]['ip']}:{.spec['ports'][0]['port']}" -n monitoring)
    echo "http://${ip_port}"
    
  6. Öffnen Sie diese URL in einem Webbrowser und melden Sie sich mit der Standard-Nutzer-ID und dem Passwort (admin und admin) an. Sie werden aufgefordert, das Standardpasswort zu ändern.

  7. Klicken Sie auf das Symbol Erste Datenquelle hinzufügen und wählen Sie in der Liste Zeitachsendatenbanken die Option Prometheus aus.

  8. Legen Sie auf dem Tab Einstellungen im Feld URL die Endpunkt-URL des Prometheus-Dienstes fest. Die Endpunkt-URL ist die URL, die Sie in Schritt 2 notiert haben.

    Endpunkt-URL des Prometheus-Dienstes.

  9. Klicken Sie auf Speichern und Testen und dann auf das Grafana-Symbol, um zum Startbildschirm zurückzukehren.

  10. Klicken Sie auf das Symbol Erstes Dashboard erstellen und dann auf Neues Feld hinzufügen, um einen Monitoring-Messwert hinzuzufügen.

  11. Geben Sie auf dem Tab Abfrage für Messwerte nv_gpu_utilization ein.

    Legen Sie einen Messwert für das Monitoring der GPU-Nutzung fest.

  12. Geben Sie auf dem Tab Feld für Feldtitel GPU Utilization ein. Klicken Sie dann auf den Linkspfeil.

    Legen Sie den Feldtitel für die GPU-Nutzung fest.

    Sie sehen die Grafik für die GPU-Nutzung.

    Grafik für die GPU-Nutzung

  13. Klicken Sie auf das Symbol Feld hinzufügen, dann auf Neues Feld hinzufügen und wiederholen Sie die Schritte ab Schritt 11, um ein Diagramm für den Messwert nv_gpu_memory_used_bytes mit dem Titel GPU Memory Used hinzuzufügen.

Lasttesttool bereitstellen

In diesem Abschnitt stellen Sie das Locust-Lasttest-Tool in GKE bereit und generieren Arbeitslasten, um die Leistung der Inferenzserver zu messen.

  1. Erstellen Sie ein Docker-Image, das die Triton-Clientbibliotheken enthält, und laden Sie es in Container Registry hoch:

    cd ../client
    git clone https://github.com/triton-inference-server/server
    cd server
    git checkout r19.05
    docker build -t tritonserver_client -f Dockerfile.client .
    gcloud auth configure-docker
    docker tag tritonserver_client \
        gcr.io/${PROJECT_ID}/tritonserver_client
    docker push gcr.io/${PROJECT_ID}/tritonserver_client
    

    Der Erstellungsprozess dauert etwas länger als fünf Minuten.

  2. Erstellen Sie ein Docker-Image, um Testarbeitslasten zu generieren, und laden Sie es in Container Registry hoch:

    cd ..
    sed -i.bak "s/YOUR-PROJECT-ID/${PROJECT_ID}/" Dockerfile
    docker build -t locust_tester -f Dockerfile .
    docker tag locust_tester gcr.io/${PROJECT_ID}/locust_tester
    docker push gcr.io/${PROJECT_ID}/locust_tester
    

    Dieses Image wird aus dem Image erstellt, das Sie im vorherigen Schritt erstellt haben.

  3. Stellen Sie die Locust-Dateien service_master.yaml und deployment_master.yaml bereit:

    sed -i.bak "s/YOUR-PROJECT-ID/${PROJECT_ID}/" deployment_master.yaml
    sed -i.bak "s/CLUSTER-IP-TRTIS/${TRITON_IP}/" deployment_master.yaml
    
    kubectl create namespace locust
    kubectl create configmap locust-config --from-literal model=original --from-literal saddr=${TRITON_IP} --from-literal rps=10 -n locust
    
    kubectl apply -f service_master.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    

    Die Ressource configmap wird verwendet, um das ML-Modell anzugeben, an das Clients Anfragen zur Inferenz senden.

  4. Warten Sie einige Minuten, bis die Dienste verfügbar sind.

  5. Rufen Sie die clusterIP-Adresse von locust-master ab und speichern Sie diese Adresse in einer Umgebungsvariablen:

    export LOCUST_MASTER_IP=$(kubectl get svc locust-master -n locust \
        -o "jsonpath={.spec['clusterIP']}")
    echo ${LOCUST_MASTER_IP}
    
  6. Stellen Sie den Locust-Client bereit:

    sed -i.bak "s/YOUR-PROJECT-ID/${PROJECT_ID}/" deployment_slave.yaml
    sed -i.bak "s/CLUSTER-IP-LOCUST-MASTER/${LOCUST_MASTER_IP}/" deployment_slave.yaml
    kubectl apply -f deployment_slave.yaml -n locust
    

    Mit diesen Befehlen werden zehn Locust-Client-Pods bereitgestellt, mit denen Sie Testarbeitslasten generieren können. Wenn Sie mit der aktuellen Anzahl von Clients nicht genügend Anfragen generieren können, können Sie die Anzahl der Pods mit dem folgenden Befehl ändern:

    kubectl scale deployment/locust-slave --replicas=20 -n locust
    

    Wenn in einem Standardcluster nicht genügend Kapazität vorhanden ist, um die Anzahl der Replikate zu erhöhen, empfehlen wir, die Anzahl der Knoten im GKE-Cluster zu erhöhen.

  7. Kopieren Sie die URL der Locust-Konsole und öffnen Sie diese URL in einem Webbrowser:

    export LOCUST_IP=$(kubectl get svc locust-master -n locust \
         -o "jsonpath={.status.loadBalancer.ingress[0].ip}")
    echo "http://${LOCUST_IP}:8089"
    

    Die folgende Konsole wird angezeigt. Sie können Testarbeitslasten über diese Konsole generieren.

    Locust-Konsole zum Generieren von Testarbeitslasten

Sie haben das Inferenzserver-System erstellt. Sie können die ausgeführten Pods prüfen:

  1. Prüfen Sie den Inferenzserver-Pod:

    kubectl get pods
    

    Die Ausgabe sieht etwa so aus:

    NAME                                READY   STATUS    RESTARTS   AGE
    inference-server-67786cddb4-qrw6r   1/1     Running   0          83m
    
  2. Prüfen Sie die Locust-Pods:

    kubectl get pods -n locust
    

    Die Ausgabe sieht etwa so aus:

    NAME                                READY   STATUS    RESTARTS   AGE
    locust-master-75f6f6d4bc-ttllr      1/1     Running   0          10m
    locust-slave-76ddb664d9-8275p       1/1     Running   0          2m36s
    locust-slave-76ddb664d9-f45ww       1/1     Running   0          2m36s
    locust-slave-76ddb664d9-q95z9       1/1     Running   0          2m36s
    
  3. Prüfen Sie die Monitoring-Pods:

    kubectl get pods -n monitoring
    

    Die Ausgabe sieht etwa so aus:

    NAME                                     READY   STATUS    RESTARTS   AGE
    grafana-deployment-644bbcb84-k6t7v       1/1     Running   0          79m
    prometheus-deployment-544b9b9f98-hl7q8   1/1     Running   0          81m
    

Im nächsten Teil dieser Reihe nutzen Sie dieses Inferenzserversystem, um zu lernen, wie verschiedene Optimierungen die Leistung verbessern und diese Optimierungen zu interpretieren sind.

Nächste Schritte