Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
GPU-Profiling-Flammendiagramme zeigen, welche Funktionen den meisten GPU-Speicher verbrauchen. In diesem Artikel wird erläutert, wie Sie die Flammendiagramme interpretieren, die von den GPU-Profilerstellungstools für Azure Kubernetes Service (AKS) generiert werden.
Important
AKS-Preview-Funktionen stehen auf Selbstbedienungs- und Opt-in-Basis zur Verfügung. Vorschauversionen werden „im Istzustand“ und „wie verfügbar“ bereitgestellt und sind von den Service Level Agreements und der eingeschränkten Garantie ausgeschlossen. AKS-Vorschauversionen werden teilweise vom Kundensupport auf Grundlage der bestmöglichen Leistung abgedeckt. Daher sind diese Funktionen nicht für die Verwendung in der Produktion vorgesehen. Weitere Informationen finden Sie in den folgenden Supportartikeln:
Bevor Sie beginnen, richten Sie die GPU-Profilerstellung ein , und vergewissern Sie sich, dass Profilerstellungsdaten in Pyroscope und Grafana verfügbar sind.
Note
Beim ersten Profiling-Durchlauf werden möglicherweise nicht alle Symbole angezeigt, einschließlich Symbolen aus Startvorgängen wie dem Laden des Modells, während der Profiler den Workload analysiert und Symbole auflöst. Führen Sie die Workload nach der ersten Analyse erneut aus, um diese Symbole in nachfolgenden Profilen zu erfassen.
Flammendiagramme verstehen
In einem Flammdiagramm werden profilierte Aufrufstapel visualisiert. Jeder Balken stellt eine Funktion dar, und die gestapelten Balken zeigen die Aufrufkette an, oder welche Funktion eine andere Funktion aufgerufen hat. Die Breite der einzelnen Balken stellt die Menge der gemessenen Ressource dar, z. B. CPU-Zeit oder zugeordneter GPU-Speicher, der durch diese Funktion fließt.
Grundregel: Je breiter ein Balken ist, desto mehr von der gemessenen Ressource fließt durch die Funktion.
Die folgenden Beispielflammendiagramme werden aus einer vLLM-Ableitungsworkload erfasst.
Tip
Verwenden Sie im Flammendiagramm-Bereich von Grafana Alle Gruppen erweitern, um den vollständigen Aufrufstapel ohne Einklappen anzuzeigen. Verwenden Sie das Suchfeld , um bestimmte Funktionen oder Schlüsselwörter zu finden. Um zu verhindern, dass das Panel erneut abstürzt, halten Sie die automatische Aktualisierung des Dashboards an, indem Sie das Aktualisierungsintervall in der oberen rechten Ecke des Grafana-Dashboards auf "Aus " festlegen, während Sie das erweiterte Flammdiagramm überprüfen.
Tip
Verwenden Sie den Fokusblock , um sich auf einen bestimmten Zuordnungspfad zu konzentrieren.
Lesen der Symbole
Flammdiagrammbeschriftungen folgen den folgenden Konventionen:
| Symbolformat | Bedeutung |
|---|---|
Foo > bar |
class Foo: method def bar() |
Foo > __init__ |
Konstruktor der Klasse Foo |
bar (allein) |
Eigenständige def bar() Funktion |
<interpreter trampoline> |
CPython-Overhead. Sie können dieses Symbol ignorieren. |
<raw-address>, zum Beispiel 0x7f151 |
Systemeigener C- oder CUDA-Code ohne Python Symbol verfügbar. |
Dazu gehören:
-
GPUModelRunner/_allocate_kv_cache_tensors: Eine Methode für eine Klasse. Lesen Sie dieses Symbol alsclass GPUModelRunner: def _allocate_kv_cache_tensors(self). -
LlamaMLP/__init__: Ein Konstruktor, der beim Erstellen einesLlamaMLP(...)Objekts aufgerufen wird. -
_compile_fx_inner: Eine eigenständige Funktion auf Modulebene, die sich nicht innerhalb einer Klasse befindet.
Eigene und Gesamtzuweisung verstehen
Verwenden Sie die Werte "Self " und " Total ", um zu bestimmen, wo die Ressource verbraucht wird:
- Total ist die Ressource, die von einer Funktion verbraucht wird, und alles, was sie aufruft. Eine Funktion kann eine große Summe aufweisen, aber nichts selbst zuordnen, da sie Teil der Anrufkette ist.
- Self bezeichnet die Ressourcen, die direkt durch die Funktion verbraucht werden, ausgenommen die ihrer untergeordneten Funktionen. Ein hoher Selbstwert bedeutet, dass diese Funktion an der Stelle ist, an der die Ressource verbraucht wird.
Wenn GPUModelRunner._allocate_kv_cache_tensors beispielsweise eine Eigenallokation von 55,1 GB hat, ist es die Funktion, die torch.empty() aufruft, um die Schlüssel-Wert-Cache-Tensoren (KV) zu erstellen.
Verwenden Sie die folgenden Navigationstechniken:
- Beginnen Sie bei den Blattknoten; das sind Balken, über denen sich nichts befindet. Ihre gesamte Breite stellt die Selbstzuweisung dar.
- Überspringen Sie breite Balken mit null Selbstzuweisung, wenn Sie nach der Quelle einer Zuordnung suchen. Diese Funktionen koordinieren Aufrufe anderer Funktionen.
- Untersuchen Sie breite Balken mit hoher Eigenallokation als potenzielle Optimierungsziele.
Größten Ressourcenverbraucher finden
Führen Sie die folgenden Schritte aus, um Hotspots zu identifizieren:
Sehen Sie sich die breitesten Balken am oberen Rand des Diagramms an. Diese Blattfunktionen weisen Speicher zu. Je breiter die Leiste, desto mehr Arbeitsspeicher verbraucht wird.
Vergleichen Sie die eigene Zuweisung mit der Gesamtzuweisung. Eine breite Leiste am unteren Rand mit
self: 0ist Teil der Aufrufkette. Folgen Sie ihr nach oben, bis Sie einen Balken mit hoher Self-Zuweisung finden.Lesen Sie den Aufrufstapel von unten nach oben, um zu verstehen, warum die Funktion aufgerufen wurde. Das folgende Beispiel endet mit der Funktion, die die Zuordnung ausführt:
<raw-address>, for example, 0x7f151 -> native code entry <interpreter trampoline> -> CPython dispatch <module> -> script top level EngineCoreProc.run_engine_core -> vLLM engine startup EngineCore.__init__ -> engine initialization EngineCore._initialize_kv_caches -> KV cache setup Worker.initialize_from_config -> worker setup GPUModelRunner.initialize_kv_cache -> model runner GPUModelRunner._allocate_kv_cache_tensors -> actual allocation
Verwenden Sie die folgende Tabelle als Kurzübersicht:
| Zielsetzung | Worauf zu achten ist |
|---|---|
| Ermitteln, was den meisten Arbeitsspeicher zuweist | Breiteste Blattleiste am oberen Rand des Stapels |
| Suchen, was für den größten Arbeitsspeicher verantwortlich ist | Breitester Balken unten im Stapel |
| Identifizieren von Optimierungszielen | Balken mit breiter Selbstzuweisung |
| Identifizieren von Funktionen, die Sie überspringen können | Breite Balken ohne eigene Allokation |