HyperAI

Offizieller PyTorch-Blog: Detaillierte Erklärung Von PyTorch Profiler V1.9

vor 4 Jahren
Populärwissenschaft
Yang Bai
特色图像


Die Verbesserungen in Profiler v1.9 konzentrieren sich auf die Ausführungsschritte, die hinsichtlich Laufzeit und/oder Speicher am energieintensivsten sind, und visualisieren gleichzeitig die Arbeitslastverteilung zwischen GPU und CPU.

Profiler v1.9 fügt fünf neue Hauptfunktionen hinzu, darunter:

1. Verteilte Trainingsansicht: Auf diese Weise können Sie besser nachvollziehen, wie viel Zeit und Speicher verteilte Trainingsaufgaben beanspruchen. Angenommen, Sie haben ein Trainingsmodell. Wenn Sie die Last auf Arbeitsknoten aufteilen und diese parallel ausführen, kann dies wie eine Blackbox wirken und es können verschiedene Probleme auftreten. Das Gesamtziel des Modells besteht darin, die Trainingsgeschwindigkeit zu erhöhen. Diese verteilte Trainingsansicht hilft Ihnen bei der Diagnose und Fehlerbehebung von Problemen innerhalb eines einzelnen Knotens.

2. Speicheransicht: Diese Ansicht bietet Ihnen einen besseren Überblick über die Speichernutzung. Dieses Tool kann die aktive Speicherzuweisung des Programms in verschiedenen Betriebsphasen anzeigen und Ihnen so dabei helfen, Speicherfehler zu vermeiden.

3. GPU-Anwendungsvisualisierung: Dieses Tool stellt sicher, dass die GPU vollständig genutzt wird.

4. Cloud-Speicher-Unterstützung: Das Tensorboard-Plugin kann jetzt analysierte Daten aus Azure Blob Storage, Amazon S3 und Google Cloud Platform lesen.

5. Zum Quellcode springen: Diese Funktion unterstützt die Visualisierung von Stacktrace-Informationen und ermöglicht den direkten Sprung zum Quellcode. Auf diese Weise können Sie Ihren Code basierend auf den Profilerstellungsergebnissen schnell optimieren und iterieren.

PyTorch Profiler Colab Portal

Chinesische Version des Colab-Portals

Colab-Inhalte im Überblick:

  • Daten und Modelle vorbereiten
  • Aufzeichnen von Ausführungsereignissen mit Profiler
  • Profiler ausführen
  • Verwenden Sie TensorBoard, um Ergebnisse anzuzeigen und die Modellleistung zu analysieren
  • Verbessern der Leistung mit Profiler
  • Analysieren Sie die Leistung mithilfe anderer erweiterter Funktionen

Erste Schritte mit PyTorch Profiling

Erste:

$ pip installiere Torch-TB-Profiler

import torch.profiler as profiler
With profiler.profile(XXXX)

Bemerkung: Weitere Informationen zu CUDA und CPU-Analyse finden Sie unter Hier

with torch.profiler.profile( 
activities=[ 
torch.profiler.ProfilerActivity.CPU, 
torch.profiler.ProfilerActivity.CUDA],
  • profiler.record_function("$NAME"): ermöglicht das Hinzufügen von Dekoratoren zu Funktionsblöcken.
  • Der Parameter Profile_memory=True unter profiler.profile kann die Speichernutzung der CPU und GPU analysieren.

Visualisierung der PyTorch-Modellleistung

### Verteiltes Training

Jüngste Fortschritte im Bereich Deep Learning haben den Wert großer Datensätze und großer Modelle gezeigt, was jedoch auch bedeutet, dass das Modelltraining mehr Rechenressourcen erfordert.

Distributed Data Parallelism (DDP) und NVIDIA Multi-Card Communication Framework (NCCL) sind in PyTorch weit verbreitete Paradigmen zur Beschleunigung des Deep-Learning-Trainings.

In dieser Version von PyTorch Profiler wird jetzt DDP mit NCCL-Backend unterstützt.
Bildbeschreibung hier einfügen

Computer-/Kommunikationsübersicht

In der „Compute/Communication Overview“ der verteilten Trainingsansicht können Benutzer das Berechnungs- und Kommunikationsverhältnis der „Load Balancer“-Knoten zwischen allen Workern beobachten, das entsprechend der Granularität gemessen wird.

Links zum Load Balancer: Hier

Szenario 1:

Wenn die Berechnungs- und Überlappungszeit eines Workers länger ist als die anderer Worker, kann dies auf ein Problem beim Workload-Balancing hinweisen oder darauf, dass ein Knoten ein Nachzügler ist. Die Berechnung ist die Summe der GPU-Kernelzeit abzüglich der Überlappungszeit. Unter Überlappungszeit versteht man die Zeitersparnis durch die Verschachtelung der Kommunikation während des Berechnungsprozesses.

Eine längere Überlappung weist auf eine bessere Parallelität zwischen Berechnung und Kommunikation hin.Im Idealfall würden Berechnung und Kommunikation vollständig überlappen. Kommunikation ist die gesamte Kommunikationszeit abzüglich der Überlappungszeit.

Das folgende Beispiel zeigt, wie dies auf Tensorboard aussehen könnte.
Bildbeschreibung hier einfügen
Nachzügler-Beispiel

Szenario 2:

Wenn die Batchgröße klein ist (d. h. die Berechnungen aller Worker sind klein) oder die zu übertragenden Daten groß sind, kann auch das Verhältnis von Berechnung zu Kommunikation klein sein, und die GPU-Auslastungsrate und die Wartezeit können im Profiler angezeigt werden.

Benutzer können den Code basierend auf dieser Berechnungs-/Kommunikationsperspektive überprüfen und die Kommunikation reduzieren, indem sie eine Gradientenakkumulation anwenden oder die Batchgröße erhöhen, um das Kommunikationsverhältnis zu verringern. Die DDP-Kommunikationszeit hängt von der Modellgröße ab. Die Batchgröße hat nichts mit der Modellgröße zu tun. Daher kann eine Erhöhung der Batchgröße zu einer längeren Rechenzeit und größeren Rechen-Kommunikationsinstanzen führen.

### Synchronisation/Kommunikation Übersicht

In der Synchronisierungs-/Kommunikationsansicht können Benutzer die Kommunikationseffizienz beobachten. Diese wird berechnet, indem die Rechen- und Kommunikationszeit von der Schrittzeit abgezogen wird. Die Synchronisierungszeit ist der Teil der gesamten Kommunikationszeit, der mit Warten und Synchronisieren mit anderen Mitarbeitern verbracht wird. Die Synchronisierungs-/Kommunikationsansicht umfasst Initialisierung, Datenlader, CPU-Berechnung usw.

Aus dieser Ansicht können wir Folgendes erkennen:Welcher Anteil des gesamten Kommunikationsvolumens wird tatsächlich für den Datenaustausch verwendet und wie hoch ist die Leerlaufzeit, die darauf wartet, dass andere Mitarbeiter Daten bereitstellen?

Bildbeschreibung hier einfügen

Wenn es beispielsweise zu einer ineffizienten Verteilung der Arbeitslast oder zu Problemen mit Nachzüglern kommt, können diese in der Synchronisierungs-/Kommunikationsansicht erkannt werden. Diese Ansicht zeigt, dass einige Arbeitnehmer länger warten müssen als andere.

Bild

Aus der obigen Tabelle können wir die detaillierten Statistiken aller Kommunikationsbetreiber in jedem Knoten entnehmen. Mithilfe dieser Tabelle können Sie nachvollziehen, welche Operatortypen aufgerufen werden, wie oft jeder Operator aufgerufen wird, wie groß die von jedem Operator übertragenen Daten sind usw.

Speicheransicht

Mit diesem Tool kann der Hardwareressourcenverbrauch von Operatoren im Modell verstanden werden. Das Verständnis des Zeit- und Speicherverbrauchs auf Operatorebene kann dazu beitragen, Leistungsengpässe zu beheben und die Modellausführung zu beschleunigen.Angesichts der begrenzten GPU-Speichergröße hilft die Optimierung der Speichernutzungseffizienz:

  • Ermöglicht das Ausführen größerer Modelle und eine bessere Leistung bei Aufgaben auf Terminalebene.
  • Ermöglicht größere Batchgrößen und erhöht die Trainingsgeschwindigkeit.

Der Profiler zeichnet alle Speicherzuweisungen während des Profiler-Intervalls auf. Wählen Sie „Gerät“ aus, um die Speichernutzungsdetails jedes Operators auf der GPU-Seite oder der Hostseite anzuzeigen.

HINWEIS: profile_memory=True muss aktiviert sein, um die folgenden Speicherdaten zu generieren.

Verwandte Links: Hier

With torch.profiler.profile(
Profiler_memory=True # this will take 1 – 2 minutes to complete. 
)

Wichtige Definitionen:

  • „Größenzunahme“ zeigt die Summe aller zugewiesenen Bytes abzüglich aller freigegebenen Speicherbytes.
  • „Zuweisungsgröße“ zeigt die Summe aller zugewiesenen Bytes ohne Speicherfreigabe.
  • „Selbst“ bedeutet, dass der zugewiesene Speicher nicht von einem untergeordneten Operator stammt, sondern vom Operator selbst zugewiesen wird.
Bild

GPU-Metriken auf einer Zeitachse

Mit dieser Funktion können Sie Leistungsprobleme einfach beheben, wenn eine oder mehrere GPUs nicht ausgelastet sind. Idealerweise sollte Ihr Programm eine hohe GPU-Auslastung (bis zu 100% GPU-Auslastung), minimale CPU-zu-GPU-Kommunikationskosten und keinen Stromverbrauch aufweisen.

Überblick: Auf der Übersichtsseite werden die Ergebnisse von drei wichtigen GPU-Nutzungsindikatoren (GPU-Auslastung, geschätzte SM-Effizienz und geschätzte erreichte Belegung) auf verschiedenen Ebenen hervorgehoben.

Im Wesentlichen verfügt jede GPU über viele SMs und jeder SM über viele Warps, die viele Threads gleichzeitig ausführen können. Die Warp-Ausführung hat viele Threads, da ihre Anzahl von der GPU abhängt. Aus einer übergeordneten Perspektive können GPU-Metriken auf einer Zeitachse Entwicklern helfen, einen ganzheitlichen Überblick über den gesamten Stack zu erhalten, was sehr wichtig ist.

Wenn die GPU-Auslastung niedrig ist, deutet dies auf ein potenzielles Problem mit Ihrem Modell hin. Zu den häufigsten Ursachen gehören:

  • Unzureichende Parallelität im Kernel, d. h. die Batchgröße ist zu klein
  • Das Aufrufen des kleinen Kernels in einer Schleife bedeutet, dass der Startaufwand nicht amortisiert wird.
  • CPU- oder I/O-Engpässe führen zu unzureichender Arbeitslast und geringer GPU-Auslastung

Auf der Übersichtsseite enthält der Abschnitt „Leistungsempfehlungen“ umsetzbare Vorschläge zur Verbesserung der GPU-Auslastung. In diesem Beispiel ist die GPU-Auslastung gering, daher besteht der Vorschlag aus Leistungsgründen darin, die Batchgröße zu erhöhen. Gemäß der Leistungsempfehlung erhöhte eine Erhöhung der Batchgröße von 4 auf 32 die GPU-Auslastung um 60,681 TP3T.

GPU-Auslastung: Im Profiler wird eine Schrittintervallzeit angezeigt, wenn die GPU-Engine eine Arbeitslast ausführt. Je höher der Auslastungsgrad, desto besser. Es ist nicht genau, Leistungsengpässe nur anhand der GPU-Auslastung zu beurteilen. Damit können Sie nicht ermitteln, wie viele Streaming-Multiprozessoren ausgeführt werden.

Beachten Sie, dass diese Metrik zwar hilfreich ist, um Leerlaufzeiten zu erkennen, ein hoher Wert jedoch nicht unbedingt bedeutet, dass die GPU sehr effizient genutzt wird. Beispielsweise hat ein kontinuierlich laufender Single-Thread-Kernel eine GPU-Auslastung von 100%.

Ein detaillierterer Indikator ist die geschätzte Effizienz des Stream-Prozessors (Est. SM Efficiency). Es zeigt den Prozentsatz des SM an, der während der Ablaufverfolgung verwendet wurde, den Prozentsatz der Zeit, in der mindestens ein Warp auf dem SM aktiv war, und die Warps, die im Leerlauf waren.

NVIDIA-Dokumentation: Hier

Gegr. Auch die SM-Effizienz unterliegt Einschränkungen. Beispielsweise kann ein Kernel mit nur einem Thread pro Block nicht alle SMs vollständig nutzen. Die Auslastung jedes SM kann nicht allein anhand der SM-Effizienz ermittelt werden. Es sind nur die von jedem SM ausgeführten Vorgänge bekannt, einschließlich Pausen beim Warten auf die Ergebnisse des Speicherladevorgangs.

Um eine hohe Auslastung des SM aufrechtzuerhalten, muss sichergestellt sein, dass bei einem Stillstand eine ausreichende Anzahl fertiger Wraps ausgeführt wird.

Bei Problemen mit der Leistungsdiagnose, Est. Die erreichte Belegung ist genauer als die geschätzte. SM-Effizienz und GPU-Auslastung. Die geschätzte erreichte Belegung gibt an, wie viele Warps pro SM gleichzeitig aktiv sein können. Eine ausreichende Anzahl aktiver Warps ist oft der Schlüssel zum Erreichen eines guten Durchsatzes. Anders als bei der GPU-Auslastung und der SM-Effizienz besteht das ultimative Ziel nicht darin, diesen Wert so hoch wie möglich zu halten.

Aus empirischer Sicht können durch eine Erhöhung dieses Indikators auf 15% oder mehr gute Durchsatzgewinne erzielt werden. Aber irgendwann stoßen Sie auf abnehmende Erträge. Hat der Wert beispielsweise 30% erreicht, sind die nachfolgenden Leistungen ungewiss. Diese Metrik zeigt den Durchschnitt aller Warp-Scheduler während der Kernel-Ausführung.

NVIDIA-Dokumentation: Hier

Je größer der Wert von Est. Je höher die Auslastung, desto besser.

Bild

Details: Resnet50_batchsize4

Bild

Details: Resnet50_batchsize32

Kernel-Ansicht: Der Kernel verfügt über „Blöcke pro SM“ und „Geschätzte erreichte Belegung“.

Gegr. Die erreichte Belegung ist ein nützliches Tool zum Vergleichen der Leistung von Modellen.

Bild

Durchschnittliche Blöcke pro SM:

Die Anzahl der Blöcke pro SM = Anzahl der Blöcke des Kernels / Anzahl der SMs der GPU. Wenn diese Zahl kleiner als 1 ist, weist dies darauf hin, dass der GPU-Multiprozessor nicht vollständig genutzt wird. „Mittlere Blöcke pro SM“ ist der gewichtete Durchschnitt aller Läufe dieses Kernelnamens, wobei die Dauer jedes Laufs als Gewicht verwendet wird.

Durchschnittliche Schätzung Erreichte Belegung

Die Definition von Est. Die erreichte Belegung ist die gleiche wie oben beschrieben. Durchschnittliche Schätzung Die erreichte Belegung ist der gewichtete Durchschnitt aller Läufe des Kernelnamens, wobei die Dauer jedes Laufs als Gewichtung verwendet wird.

Tracking-Ansicht:

In der Trace-Ansicht wird eine Zeitleiste angezeigt, die die Dauer der Operatoren im Modell und das System zeigt, das den Vorgang ausgeführt hat. Mithilfe dieser Ansicht können Sie einen hohen Overhead und lange Ausführungszeiten erkennen, unabhängig davon, ob diese durch die Eingabe oder das Modelltraining verursacht werden. Derzeit zeigt die Ablaufverfolgungsansicht die GPU-Auslastung und die geschätzte GPU-Auslastung an. SM-Effizienz in einer Zeitleiste.

Bild

Im obigen Beispiel ist die GPU-Auslastung während „ProfilerStep5“ im Thread 28022 höher als während „Optimizer.step“. Sie können hineinzoomen, um die Ursache zu sehen.

Bild

Wie aus der obigen Abbildung ersichtlich ist, ist der Kernel des ersteren länger als der des letzteren. Die Kernel-Ausführungszeit des letzteren ist zu kurz, was zu einer geringen GPU-Auslastung führt.

Gegr. SM-Effizienz: Jeder Kern hat eine berechnete EST. SM-Effizienz zwischen 0–100%. Beispielsweise hat der Kernel unten nur 64 Kacheln und der SM dieser GPU beträgt 80, sodass seine „geschätzte SM-Effizienz“ 64/80 beträgt, also 0,8.

Bild

Cloud-Speicherunterstützung

Nachdem Sie „pip install tensorboard“ ausgeführt haben, können Sie zum Lesen von Daten über einen Cloud-Anbieter Folgendes ausführen:

torch-tb-profiler[blob] 
torch-tb-profiler[gs] 
torch-tb-profiler[s3]

Sie können pip install torch-tb-profiler[blob], pip install torch-tb-profiler[gs] oder pip install torch-tb-profiler[S3] verwenden, um Daten von einem Cloud-Anbieter zu lesen.

Weitere Informationen finden Sie unter: Hier

Zum Quellcode springen

Einer der großen Vorteile der direkten Integration von TensorBoard und PyTorch Profiler in Visual Studio Code (VS Code) ist die Möglichkeit, vom Profiler-Stacktrace direkt zum Quellcode (Datei und Zeile) zu springen. Die VS Code Python-Erweiterung unterstützt jetzt die TensorBoard-Integration.

Der Sprung zum Quellcode ist nur verfügbar, wenn Tensorboard in VS Code ausgeführt wird. Wenn die Profilerstellung mit_stack=True erfolgt, wird der Stapelüberwachungsverlauf in der Benutzeroberfläche des Plug-Ins angezeigt. Klicken Sie im PyTorch Profiler auf den Stacktrace. VS Code öffnet die entsprechende Datei und springt zum Debuggen direkt zum entsprechenden Code. Dadurch kann der Code anhand der Analyseergebnisse und Vorschläge schnell optimiert und geändert werden.

Bild

Springen Sie mit der Visual Studio Code Plug-In-Benutzeroberfläche zum Quellcode

Weitere Informationen zur Optimierung der Batchgrößenleistung finden Sie im ausführlichen Tutorial: Hier

PyTorch Profiler kann auch in PyTorch Lightning integriert werden. Starten Sie einfach eine Lightning-Trainingsaufgabe mit trainer.profiler=pytorch, um eine Ablaufverfolgung zu generieren.

Ausführliches Beispiel: Hier

Ursprüngliche Adresse: Hier