Leistung eines TensorFlow-Inferenzsystems messen und optimieren

Last reviewed 2023-11-02 UTC

In diesem Dokument wird beschrieben, wie Sie die Leistung des TensorFlow-Systems messen, das Sie unter Skalierbares TensorFlow-Inferenzsystem bereitstellen erstellt haben. Außerdem erfahren Sie, wie Sie die Parameterabstimmung anwenden, um den Systemdurchsatz zu verbessern.

Die Bereitstellung basiert auf der Referenzarchitektur, die unter Skalierbares TensorFlow-Inferenzsystem beschrieben wird.

Diese Reihe richtet sich an Entwickler, die mit Google Kubernetes Engine und ML-Frameworks (ML) vertraut sind, einschließlich TensorFlow und TensorRT.

In diesem Dokument werden nicht die Leistungsdaten eines bestimmten Systems bereitgestellt. Stattdessen erhalten Sie allgemeine Hinweise zum Vorgang der Leistungsmessung. Die angezeigten Leistungsmesswerte, z. B. Anfragen pro Sekunde (RPS) insgesamt und Antwortzeiten (ms), variieren je nach Trainingsmodell, Softwareversion und Hardwarekonfiguration, die Sie verwenden.

Architektur

Eine Architekturübersicht über das TensorFlow-Inferenzsystem finden Sie unter Skalierbares TensorFlow-Inferenzsystem.

Lernziele

  • Leistungsziel und die -Messwerte definieren
  • Referenzleistung messen
  • Grafik optimieren
  • FP16-Umwandlung messen
  • INT8-Quantisierung messen
  • Anzahl der Instanzen anpassen

Kosten

Weitere Informationen zu den Kosten für die Bereitstellung finden Sie unter Kosten.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweise

Prüfen Sie, ob Sie die Schritte unter Skalierbares TensorFlow-Inferenzsystem bereitstellen bereits ausgeführt haben.

In diesem Dokument verwenden Sie die folgenden Tools:

Verzeichnis festlegen

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

    Zu Seite „VM-Instanzen“

    Sie sehen die Instanz working-vm, die Sie erstellt haben.

  2. Klicken Sie zum Öffnen der Terminalkonsole der Instanz auf SSH.

  3. Legen Sie im SSH-Terminal das aktuelle Verzeichnis auf das Unterverzeichnis client fest:

    cd $HOME/gke-tensorflow-inference-system-tutorial/client
    

    In diesem Dokument führen Sie alle Befehle von diesem Verzeichnis her aus.

Leistungsziel definieren

Beim Messen der Leistung von Inferenzsystemen müssen Sie das Leistungsziel und entsprechende Leistungsmesswerte gemäß dem Anwendungsfall des Systems definieren. Zu Demonstrationszwecken werden in diesem Dokument die folgenden Leistungsziele verwendet:

  • Mindestens 95 % der Anfragen erhalten Antworten innerhalb von 100 ms.
  • Der Gesamtdurchsatz, der durch Anfragen pro Sekunde (RPS) dargestellt wird, verbessert sich, ohne das vorherige Ziel zu beeinträchtigen.

In Erwägung dieser Ziele messen und verbessern Sie den Durchsatz der folgenden ResNet-50-Modelle mit verschiedenen Optimierungen. Wenn ein Client Inferenzanfragen sendet, gibt er das Modell anhand des Modellnamens in dieser Tabelle an.

Modellname Optimierung
original Ursprüngliches Modell (keine Optimierung mit TF-TRT)
tftrt_fp32 Grafikoptimierung
(Batchgröße: 64, Instanzgruppen: 1)
tftrt_fp16 Konvertierung in FP16 zusätzlich zur Grafikoptimierung
(Batchgröße: 64, Instanzgruppen: 1)
tftrt_int8 Quantisierung mit INT8 zusätzlich zur Grafikoptimierung
(Batchgröße: 64, Instanzgruppen: 1)
tftrt_int8_bs16_count4 Quantisierung mit INT8 zusätzlich zur Grafikoptimierung
(Batchgröße: 16, Instanzgruppen: 4)

Referenzleistung messen

Sie verwenden zuerst TF-TRT als Referenz, um die Leistung des ursprünglichen, nicht optimierten Modells zu messen. Vergleichen Sie die Leistung anderer Modelle mit dem Original, um die Leistungsverbesserung quantitativ zu bewerten. Bei der Bereitstellung von Locust wurde es bereits so konfiguriert, dass Anfragen für das ursprüngliche Modell gesendet werden.

  1. Öffnen Sie die Locust-Konsole, die Sie unter Belastungstest-Tool bereitstellen vorbereitet haben

  2. Bestätigen Sie, dass die Anzahl der Clients (als Slaves bezeichnet) zehn ist.

    Wenn die Zahl unter zehn liegt, werden die Clients noch gestartet. Warten Sie in diesem Fall einige Minuten, bis sie zehn wird.

  3. Leistung messen:

    1. Geben Sie im Feld Anzahl der zu simulierenden Nutzer den Wert 3000 ein.
    2. Geben Sie im Feld Hatch rate den Wert 5 ein.
    3. Klicken Sie auf Swarm starten, um die Anzahl der simulierten Nutzer um 5 pro Sekunde zu erhöhen, bis sie 3.000 erreicht.

  4. Klicken Sie auf Diagramme.

    Die Grafiken zeigen die Leistungsergebnisse. Beachten Sie, dass der Wert für die Anfragen pro Sekunde insgesamt linear erhöht wird, während der Wert Antwortzeiten (ms) entsprechend ansteigt.

    Eine neue Locust-Swarm wird gestartet.

  5. Wenn der Wert 95% Perzentil der Antwortzeiten 100 ms überschreitet, klicken Sie auf Stop, um die Simulation zu beenden.

    Wenn Sie den Zeiger auf das Diagramm bewegen, können Sie die Anzahl der Anfragen pro Sekunde prüfen, in Korrespondenz zu der Zeit, als der Wert von 95 % Perzentil der Antwortzeiten 100 ms überschritt.

    Im folgenden Screenshot beträgt die Anzahl der Anfragen pro Sekunde beispielsweise 253,1.

    Grafik mit 253,1 Anfragen pro Sekunde

    Wir empfehlen, diese Messung mehrmals zu wiederholen und dabei einen Durchschnittswert zu ermitteln, der Schwankungen berücksichtigt.

  6. Starten Sie im SSH-Terminal Locust neu:

    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    
  7. Wiederholen Sie diesen Vorgang, um die Messung zu wiederholen.

Grafiken optimieren

In diesem Abschnitt messen Sie die Leistung des Modells tftrt_fp32, das mit TF-TRT für die Grafikoptimierung optimiert wird. Dies ist eine gängige Optimierung, die mit den meisten NVIDIA-GPU-Karten kompatibel ist.

  1. Starten Sie im SSH-Terminal das Belastungstest-Tool neu:

    kubectl delete configmap locust-config -n locust
    kubectl create configmap locust-config \
        --from-literal model=tftrt_fp32 \
        --from-literal saddr=${TRITON_IP} \
        --from-literal rps=10 -n locust
    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    

    Die configmap-Ressource gibt das Modell als tftrt_fp32 an.

  2. Starten Sie den Triton-Server neu:

    kubectl scale deployment/inference-server --replicas=0
    kubectl scale deployment/inference-server --replicas=1
    

    Warten Sie einige Minuten, bis die Serverprozesse bereit sind.

  3. Prüfen Sie den Serverstatus:

    kubectl get pods
    

    Die Ausgabe sieht etwa so aus, wobei in der Spalte READY der Serverstatus angezeigt wird:

    NAME                                READY   STATUS    RESTARTS   AGE
    inference-server-74b85c8c84-r5xhm   1/1     Running   0          46s
    

    Der Wert 1/1 in der Spalte READY gibt an, dass der Server bereit ist.

  4. Leistung messen:

    1. Geben Sie im Feld Anzahl der zu simulierenden Nutzer den Wert 3000 ein.
    2. Geben Sie im Feld Hatch rate den Wert 5 ein.
    3. Klicken Sie auf Swarm starten, um die Anzahl der simulierten Nutzer um 5 pro Sekunde zu erhöhen, bis sie 3.000 erreicht.

    Die Grafiken zeigen die Leistungssteigerung der TF-TRT-Grafikoptimierung.

    Ihr Diagramm könnte beispielsweise zeigen, dass die Anzahl der Anfragen pro Sekunde jetzt 381 mit einer mittleren Antwortzeit von 59 ms beträgt.

In FP16 konvertieren

In diesem Abschnitt messen Sie die Leistung des Modells tftrt_fp16, das mit TF-TRT für die Grafikoptimierung und FP16-Konvertierung optimiert ist. Diese Optimierung ist für NVIDIA T4 verfügbar.

  1. Starten Sie im SSH-Terminal das Belastungstest-Tool neu:

    kubectl delete configmap locust-config -n locust
    kubectl create configmap locust-config \
        --from-literal model=tftrt_fp16 \
        --from-literal saddr=${TRITON_IP} \
        --from-literal rps=10 -n locust
    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    
  2. Starten Sie den Triton-Server neu:

    kubectl scale deployment/inference-server --replicas=0
    kubectl scale deployment/inference-server --replicas=1
    

    Warten Sie einige Minuten, bis die Serverprozesse bereit sind.

  3. Leistung messen:

    1. Geben Sie im Feld Anzahl der zu simulierenden Nutzer den Wert 3000 ein.
    2. Geben Sie im Feld Hatch rate den Wert 5 ein.
    3. Klicken Sie auf Swarm starten, um die Anzahl der simulierten Nutzer um 5 pro Sekunde zu erhöhen, bis sie 3.000 erreicht.

    Die Diagramme zeigen neben der Leistungsverbesserung der FP16-Konvertierung auch die TF-TRT-Grafikoptimierung.

    Ein Diagramm könnte beispielsweise zeigen, dass die Anzahl der Anfragen pro Sekunde 1072,5 beträgt, während die mittlere Antwortzeit 63 ms beträgt.

Mit INT8 quantisieren

In diesem Abschnitt messen Sie die Leistung des Modells tftrt_int8, das mit TF-TRT für die Diagrammoptimierung und INT8-Quantisierung optimiert ist. Diese Optimierung ist für NVIDIA T4 verfügbar.

  1. Starten Sie im SSH-Terminal das Belastungstest-Tool neu.

    kubectl delete configmap locust-config -n locust
    kubectl create configmap locust-config \
        --from-literal model=tftrt_int8 \
        --from-literal saddr=${TRITON_IP} \
        --from-literal rps=10 -n locust
    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    
  2. Starten Sie den Triton-Server neu:

    kubectl scale deployment/inference-server --replicas=0
    kubectl scale deployment/inference-server --replicas=1
    

    Warten Sie einige Minuten, bis die Serverprozesse bereit sind.

  3. Leistung messen:

    1. Geben Sie im Feld Anzahl der zu simulierenden Nutzer den Wert 3000 ein.
    2. Geben Sie im Feld Hatch rate den Wert 5 ein.
    3. Klicken Sie auf Swarm starten, um die Anzahl der simulierten Nutzer um 5 pro Sekunde zu erhöhen, bis sie 3.000 erreicht.

    Die Grafiken zeigen die Leistungsergebnisse.

    Ein Diagramm könnte beispielsweise zeigen, dass die Anzahl der Anfragen pro Sekunde 1085,4 beträgt, während die mittlere Antwortzeit 32 ms beträgt.

    In diesem Beispiel ist das Ergebnis im Vergleich zur FP16-Conversion keine signifikante Leistungssteigerung. Theoretisch kann die NVIDIA T4-GPU schneller INT8-Quantisierungsmodelle verarbeiten als FP16-Konvertierungsmodelle. In diesem Fall kann es einen anderen Engpass als die GPU-Leistung geben. Sie können dies anhand der GPU-Auslastungsdaten im Grafana-Dashboard prüfen. Wenn die Auslastung beispielsweise unter 40 % liegt, kann das Modell die GPU-Leistung nicht vollständig nutzen.

    Wie im nächsten Abschnitt gezeigt, können Sie diesen Engpass möglicherweise beheben, indem Sie die Anzahl der Instanzgruppen erhöhen. Sie können beispielsweise die Anzahl der Instanzgruppen von 1 auf 4 erhöhen und die Batchgröße von 64 auf 16 verringern. Bei diesem Ansatz wird die Gesamtzahl der Anfragen, die auf einer einzelnen GPU verarbeitet werden, bei 64 gehalten.

Anzahl der Instanzen anpassen

In diesem Abschnitt messen Sie die Leistung des Modells tftrt_int8_bs16_count4. Dieses Modell hat die gleiche Struktur wie tftrt_int8, Sie ändern jedoch die Batchgröße und die Anzahl der Instanzgruppen wie unter Mit INT8 quantisieren beschrieben.

  1. Starten Sie im SSH-Terminal Locust neu:

    kubectl delete configmap locust-config -n locust
    kubectl create configmap locust-config \
        --from-literal model=tftrt_int8_bs16_count4 \
        --from-literal saddr=${TRITON_IP} \
        --from-literal rps=10 -n locust
    kubectl delete -f deployment_master.yaml -n locust
    kubectl delete -f deployment_slave.yaml -n locust
    kubectl apply -f deployment_master.yaml -n locust
    kubectl apply -f deployment_slave.yaml -n locust
    kubectl scale deployment/locust-slave --replicas=20 -n locust
    

    In diesem Befehl verwenden Sie die Ressource configmap, um das Modell als tftrt_int8_bs16_count4 anzugeben. Sie erhöhen außerdem die Anzahl der Locust-Client-Pods, um genügend Arbeitslasten zu generieren, um die Leistungsbeschränkung des Modells zu messen.

  2. Starten Sie den Triton-Server neu:

    kubectl scale deployment/inference-server --replicas=0
    kubectl scale deployment/inference-server --replicas=1
    

    Warten Sie einige Minuten, bis die Serverprozesse bereit sind.

  3. Leistung messen:

    1. Geben Sie im Feld Anzahl der zu simulierenden Nutzer den Wert 3000 ein.
    2. Geben Sie im Feld Hatch rate den Wert 15 ein. Bei diesem Modell kann es lange dauern, bis die Leistungsgrenze erreicht ist, wenn die Erzeugungsrate auf 5 gesetzt ist.
    3. Klicken Sie auf Swarm starten, um die Anzahl der simulierten Nutzer um 5 pro Sekunde zu erhöhen, bis sie 3.000 erreicht.

    Die Grafiken zeigen die Leistungsergebnisse.

    Ein Diagramm könnte beispielsweise zeigen, dass die Anzahl der Anfragen pro Sekunde 2236,6 beträgt, während die mittlere Antwortzeit 38 ms beträgt.

    Wenn Sie die Anzahl der Instanzen anpassen, können Sie die Zahl der Anfragen pro Sekunde fast verdoppeln. Die GPU-Auslastung hat sich im Grafana-Dashboard erhöht (z. B. könnte die Auslastung 75 % erreichen).

Leistung und mehrere Knoten

Bei der Skalierung mit mehreren Knoten messen Sie die Leistung eines einzelnen Pods. Da die Inferenzprozesse unabhängig voneinander auf verschiedenen Pods nach dem Prinzip shared-nothing ausgeführt werden, können Sie davon ausgehen, dass der Gesamtdurchsatz linear mit der Anzahl der Pods skaliert wird. Diese Annahme gilt, solange keine Engpässe wie die Netzwerkbandbreite zwischen Clients und Inferenzservern vorliegen.

Sie müssen jedoch verstehen, wie Inferenzanfragen auf mehrere Inferenzserver verteilt werden. Triton verwendet das gRPC-Protokoll, um eine TCP-Verbindung zwischen einem Client und einem Server herzustellen. Da Triton die hergestellte Verbindung zum Senden mehrerer Inferenzanfragen wiederverwendet, werden Anfragen von einem einzelnen Client immer an denselben Server gesendet. Sie müssen mehrere Clients verwenden, um Anfragen für mehrere Server zu verteilen.

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Reihe verwendeten Ressourcen nicht in Rechnung gestellt werden, können Sie das Projekt löschen:

Projekt löschen

  1. Wechseln Sie in der Google Cloud Console zur Seite Ressourcen verwalten.

    Zur Seite „Ressourcen verwalten“

  2. Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen.
  3. Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Shut down (Beenden), um das Projekt zu löschen.

Nächste Schritte