Für Teams, Einzelnutzer, Kanzleien und Transkription – derselbe Mindverse Look, klar aufgeteilt nach Anwendungsfall.
für Teams und Unternehmen
Die Plattform für Unternehmen, die eigene KI-Workflows, Wissensdatenbanken und Assistenten produktiv einsetzen möchten.
für Einzelnutzer und Creator
Der einfachste Einstieg in das Mindverse-Ökosystem für Content, Recherche, Bilder, Audio und produktives Arbeiten.
für Juristen und Kanzleien
Die spezialisierte KI-Lösung für juristische Recherche, Vertragsarbeit und kanzleispezifische Workflows.
für Audio, Meetings und Transkription
Schnelle KI-Transkription für Audiodateien und Meetings – ideal zum sofortigen Start oder für regelmäßige Nutzung.
Von der ersten Idee bis zur voll integrierten KI-Lösung – strukturiert, sicher und mit messbarem Erfolg
Wir analysieren Ihre Geschäftsprozesse und identifizieren konkrete Use Cases mit dem höchsten ROI-Potenzial.
✓ Messbare KPIs definiert
Vollständige Datenschutz-Analyse und Implementierung sicherer Datenverarbeitungsprozesse nach EU-Standards.
✓ 100% DSGVO-konform
Maßgeschneiderte Auswahl der optimalen KI-Lösung – von Azure OpenAI bis zu Open-Source-Alternativen.
✓ Beste Lösung für Ihren Fall
Schneller Proof of Concept mit nahtloser Integration in Ihre bestehende IT-Infrastruktur und Workflows.
✓ Ergebnisse in 4-6 Wochen
Unternehmensweiter Rollout mit umfassenden Schulungen für maximale Akzeptanz und Produktivität.
✓ Ihr Team wird KI-fit
torch.profiler ist ein essenzielles Werkzeug zur Leistungsanalyse und Fehlerbehebung in PyTorch-Modellen.torch.compile kann zur Optimierung von PyTorch-Code durch Graphenerfassung und -optimierung eingesetzt werden, wobei Profiling essenziell ist, um die Effektivität zu überprüfen.torch.profilertorch.profiler ins Spiel – ein leistungsstarkes Werkzeug, das detaillierte Einblicke in die Ausführung von PyTorch-Operationen bietet.
Dieser Artikel bietet Ihnen einen umfassenden Leitfaden für den Einstieg in die Welt des PyTorch Profilings mit torch.profiler. Wir werden die grundlegenden Konzepte erläutern, die Interpretation der Profiling-Ergebnisse schulen und aufzeigen, wie diese Erkenntnisse in konkrete Optimierungsmaßnahmen umgesetzt werden können. Unser Fokus liegt dabei auf einer neutralen und analytischen Darstellung, die Ihnen klare Handlungsempfehlungen für Ihre eigenen Projekte liefert.
torch.profiler ermöglicht es, diese "unsichtbaren" Engpässe zu identifizieren, die sich nicht allein aus Verlustkurven oder der allgemeinen GPU-Auslastung ableiten lassen. Dazu gehören:
torch.profilertorch.profiler ist ein integriertes API-Modul in PyTorch. Es ermöglicht die Erfassung von Zeit- und Speicherinformationen für verschiedene PyTorch-Operationen. Die Ergebnisse können sowohl in tabellarischer Form als auch als JSON-Trace-Datei ausgegeben werden, die eine visuelle Analyse in Tools wie TensorBoard oder Perfetto ermöglicht.
def fn(x, w, b):
return torch.add(torch.matmul(x, w), b)
Diese Funktion bildet ab, wie Gewichte und Biases in einem Neuron interagieren, und wird uns später beim Verständnis der Kompilierung helfen.
fn) muss definiert sein.profiler.record_function("label"), um spezifische Codeblöcke zu kennzeichnen. Dies erleichtert die Navigation in den Traces.
def step():
with torch.profiler.record_function("matmul_add"):
return fn(x, w, b)
torch.profiler.profile-Kontextmanager eingebettet. Hier werden auch die zu erfassenden Aktivitäten (z.B. CPU, CUDA) und der Zeitplan (schedule) festgelegt.
with torch.profiler.profile(
activities=[
torch.profiler.ProfilerActivity.CPU,
torch.profiler.ProfilerActivity.CUDA,
],
) as prof:
# Es wird empfohlen, Ereignisse mehrfach auszuführen, um die GPUs aufzuwärmen.
for _ in range(5):
step()
prof.step()
prof.key_averages().table()) oder als Chrome-Trace-Datei (prof.export_chrome_trace(trace_path)) exportiert werden.uv run 01_matmul_add.py --size 64
Die resultierende Profiler-Tabelle (siehe Abbildung 1 im Originalartikel) zeigt eine detaillierte Aufschlüsselung der Ereignisse. Wichtige Spalten sind "Name" (Operation), "Self CPU %", "Self CPU", "Self CUDA %", "Self CUDA" und "# of Calls".
Self CPU time total: 2.314ms
Self CUDA time total: 23.104us
Die CPU-Zeit wird in Millisekunden (ms) und die GPU-Zeit in Mikrosekunden (µs) gemessen. Die GPU-Zeit ist hier weniger als 1% der CPU-Zeit. Dies deutet auf einen Overhead-Bound-Algorithmus hin: Die meiste Zeit wird mit der Vorbereitung und dem Start der Kernel auf der GPU sowie dem Datentransfer verbracht, während die eigentliche GPU-Berechnung sehr schnell erfolgt. Die GPU ist die meiste Zeit untätig.
uv run 01_matmul_add.py --size 4096
Die Profiler-Tabelle (siehe Abbildung 2 im Originalartikel) zeigt nun:
Self CPU time total: 4.908ms
Self CUDA time total: 4.495ms
Beide Zeiten liegen nun im Millisekundenbereich. Dies bedeutet, dass wir den Algorithmus von "overhead-bound" zu "compute-bound" verschoben haben. Die GPU ist nun der primäre Engpass, was bei rechenintensiven Aufgaben wünschenswert ist.
ProfilerStep#2 so lange?ProfileStep#2 deutlich länger als die folgenden Schritte. Eine genauere Betrachtung zeigt eine "Dead Window" von ca. 228 µs zwischen dem Start von record_function("matmul_add") und dem Dispatch von aten::matmul. Dies kann durch Arbeitsbereichsallokationen, cuBLAS-Heuristiken oder verzögertes Laden von Modulen verursacht werden.
Um diese einmaligen Overheads nicht zu profilieren, wird ein "Warm-up" durchgeführt. Dies bedeutet, dass die Operationen mehrmals vor dem eigentlichen Profiling ausgeführt werden.
uv run 01_matmul_add.py --warmup
Nach dem Warm-up (siehe Abbildung 7 im Originalartikel) zeigen alle Profilschritte ähnliche Dauern, da die initialen Overheads nicht mehr erfasst werden.
schedule(wait=0, warmup=0, active=3, repeat=1) zeigt eine Activity Buffer Request in der GPU-Spur (Abbildung 9 im Originalartikel). Dies deutet darauf hin, dass der Profiler Puffer für die Ereignisaufzeichnung allokiert hat, was zu einer Verzögerung führte. Durch das Profiling über mehr Iterationen (z.B. active=20) kann bestätigt werden, dass diese Lücke nur einmal auftritt und somit ein Profiler-Artefakt ist (Abbildung 11 im Originalartikel).
ProfileStep#, gefolgt von der annotierten matmul_add-Operation. Diese wiederum besteht aus aten::matmul und aten::add.
Interessanterweise verzweigt aten::matmul zu aten::mm für 2D-Matrizen und zu aten::bmm (batched matrix multiplication) für 3D-Batched-Tensoren (Abbildung 13 im Originalartikel). Dies verdeutlicht die internen Heuristiken von cuBLAS, um den optimalen Kernel auszuwählen.
matmul einen zusätzlichen CUDA-Runtime-Aufruf?aten::mm sehen wir zwei CUDA-Runtime-Aufrufe: cudaOccupancyMaxActiveBlocksPerMultiprocessor und cudaLaunchKernel. Bei aten::add hingegen nur cudaLaunchKernel.
cudaOccupancyMaxActiveBlocksPerMultiprocessor ist ein Planungsaufruf auf CPU-Seite. Er ermittelt, wie viele Blöcke eines Kernels gleichzeitig auf einem Streaming Multiprocessor (SM) residieren können, basierend auf Kernel-Funktion, Blockgröße und Shared Memory. Dies ist notwendig für Matrixmultiplikationen, da deren Ressourcenbedarf (Register pro Thread, Shared Memory) dynamisch ist und cuBLAS Hunderte von Kernel-Varianten mit heuristikgesteuerten Startpfaden bereitstellt (Abbildung 15 im Originalartikel).
Bei der Addition (Abbildung 16 im Originalartikel) ist der Ressourcenbedarf (32 Register, null Shared Memory) trivial, sodass keine solche Abfrage erforderlich ist. Dies dient als schnelle Diagnose: Das Vorhandensein von cudaOccupancyMaxActiveBlocksPerMultiprocessor deutet auf einen "schwergewichtigen, adaptiv gestarteten" Kernel hin, während dessen Fehlen auf einen ressourcenleichten Kernel verweist.
cudaDeviceSynchronize so groß (~1.78 ms)?cudaDeviceSynchronize blockiert die CPU, bis alle GPU-Arbeiten auf dem Gerät abgeschlossen sind. Der Profiler sendet diesen Synchronisationsbefehl am Ende des aktiven Fensters, um Ereignisse zu leeren. Eine 1.78 ms lange Synchronisation für nur 26 µs tatsächlicher GPU-Arbeit zeigt, dass der Lauf zu 98 % im Leerlauf war – ein klassisches Symptom eines Overhead-Bound-Systems.
torch.compile in Aktiontorch.compile ist ein Feature, das normalen PyTorch-Code durch das Erfassen von Tensor-lastigen Regionen in Graphen, deren Optimierung und die Ausführung von generiertem Code beschleunigt. Der Standard-Backend ist oft TorchInductor.
uv run 01_matmul_add.py --size 4096 --warmup --compile
Bei kompilierter Ausführung (Abbildung 19 im Originalartikel) erscheinen neue CPU-Zeilen wie Torch-Compiled Region: 0/0, die auf die Verwendung kompilierter Funktionen hinweisen.
torch.compile die Operationen in einen einzigen aten::addmm(b, x, w)-Aufruf umgeschrieben hat. Dies ist eine Operator-Fusion auf Graphenebene. Es wurde jedoch kein neuer, fusionierter CUDA-Kernel erstellt; die eigentliche GPU-Arbeit bleibt derselbe cuBLAS-Kernel wie im Eager-Modus. Die "Fusion" findet hier auf Dispatcher-Ebene statt.
Es ist wichtig zu verstehen, dass addmm die Berechnung out = α·A·B + β·C durchführt. Der GEMM-Epilog von cuBLAS schreibt in einen Zielpuffer, der bereits den Bias enthalten muss. Daher führt der generierte Code von Inductor:
out = copy(C) ← Das ist der DtoD-Memcpy (32 MB, dauert ~33 µs).out = α·(A·B) + β·out ← GEMM mit α=β=1, das den Bias-Add in den Writeback fusioniert.aten::addmm-Dispatch. Die Kompilierungspipeline ist für ML-Modelle mit Dutzenden von Operationen konzipiert, bei denen sich der Overhead pro Aufruf amortisiert. Bei einer einzelnen Operation ist dies eine zusätzliche Belastung.
Self CPU time total ≫ Self CUDA time total (CPU in ms, GPU in µs): Overhead-bound. CPU verbringt mehr Zeit mit Dispatching als GPU mit Berechnen. Erhöhen Sie die Arbeitslast oder fusionieren Sie Aufrufe.Self CPU time total ≈ Self CUDA time total, beide in ms: Compute-bound. GPU ist der Engpass, was meist wünschenswert ist.CUDA total: Dies ist Ihr Hotspot. Beginnen Sie dort mit der Optimierung.# of Calls: Potenzieller Engpass, auch wenn jeder Aufruf günstig ist. Prüfen Sie, ob es fusioniert oder gebatcht werden kann.CPU total ≫ Self CPU für eine Zeile: Die meisten Kosten liegen in Kind-Operationen. Untersuchen Sie die verschachtelten Ereignisse.ProfileStep viel breiter als der Rest: Kaltstart-Overhead. Fügen Sie Warm-up-Iterationen hinzu.record_function("...") Start und dem ersten aten::*: Gleicher Kaltstart-Overhead, aber näher betrachtet.cudaOccupancyMaxActiveBlocksPerMultiprocessor vor cudaLaunchKernel: Schwergewichtiger, adaptiv gestarteter Kernel (GEMM, Conv).cudaLaunchKernel ohne vorherige Occupancy-Abfrage: Elementweiser oder Reduktions-Kernel mit festem, ressourcenleichtem Fußabdruck.cudaDeviceSynchronize am Ende des aktiven Fensters: Profiler leert Ereignisse. Meist ein Symptom eines Overhead-Bound-Systems.cudaMemcpyAsync, das Sie nicht geschrieben haben: Oft eine versteckte Device-to-Device-Kopie, z.B. für addmm.Activity Buffer Request in der GPU-Spur: Profiler allokiert/füllt eigenen Ereignispuffer.ampere_bf16_s16816gemm_...: Die tatsächliche cuBLAS-GPU-Arbeit für eine Matmul.Memcpy DtoD unmittelbar vor einem GEMM: Die Bias-Kopie für einen addmm-Epilog.ProfileStep#N → → aten::* → aten::mm / aten::bmm / aten::add: Die kanonische verschachtelte Aufrufhierarchie.aten::matmul löst zu aten::mm auf: 2D × 2D Matrixmultiplikation.aten::matmul löst zu aten::bmm auf: Batched Matmul auf 3D+-Tensoren.aten::addmm(b, x, w) statt separatem aten::add + aten::mm: Operator-Fusion auf Dispatcher-Ebene.torch.compileTorch-Compiled Region: K/M-Zeile in der CPU-Spur: Sie befinden sich in einer kompilierten Funktion.TorchDynamo Cache Lookup bei jedem Schritt: Dynamo verifiziert, dass Formen/Datentypen/Geräte mit der zwischengespeicherten Kompilierung übereinstimmen.AOTDispatcher Runtime Wrapper Prologue auch ohne Gradienten: AOTAutograds Runtime-Wrapper ist immer im Stack.## Call CompiledFxGraph mit demselben Hash über Schritte hinweg: Cache-Treffer auf dem generierten Code.torch.compile als eager für eine winzige Operation: Erwartet, da der Dynamo → AOTAutograd → Inductor-Stack ein Overhead ist.matmul + add-Beispiels mit dem torch.profiler hat uns grundlegende Modelle für die Interpretation von Profiling-Daten vermittelt. Wir haben gelernt, wie man sowohl die statistischen Tabellen als auch die zeitlichen Traces liest, identifiziert Engpässe und versteht die Auswirkungen von Optimierungstechniken wie torch.compile.
Dieses Wissen ist nicht nur für die Optimierung kleiner Operationen relevant, sondern lässt sich auch auf komplexere Modelle und Workloads übertragen. In den folgenden Teilen dieser Reihe werden wir die Komplexität schrittweise erhöhen und die Anwendung des Profilers auf größere Bausteine und schließlich auf reale Modelle eingehend betrachten. So können Sie Ihre PyTorch-Modelle effizienter gestalten und neue Leistungspotenziale erschließen.
Bibliography:
- PyTorch Tutorials (2023). Profiling your PyTorch Module. Available at: https://docs.pytorch.org/tutorials/beginner/profiler.html
- PyTorch Tutorials (2023). PyTorch Profiler. Available at: https://docs.pytorch.org/tutorials/recipes/recipes/profiler_recipe.html
- pytorch/tutorials (n.d.). beginner_source/profiler.py at main. Available at: https://github.com/pytorch/tutorials/blob/main/beginner_source/profiler.py
- Quentin-Anthony (2025). Quentin-Anthony/torch-profiling-tutorial. Available at: https://github.com/Quentin-Anthony/torch-profiling-tutorial?tab=readme-ov-file
- PyTorch (n.d.). torch.profiler. Available at: https://docs.pytorch.org/docs/main/profiler.html
- mljourney (2026). How to Use torch.profiler to Find Training Bottlenecks. Available at: https://mljourney.com/how-to-use-torch-profiler-to-find-training-bottlenecks/
- PyTorch (n.d.). Introducing PyTorch Profiler – the new and improved performance tool. Available at: https://pytorch.org/blog/introducing-pytorch-profiler-the-new-and-improved-performance-tool/
- PyTorch Tutorials (2023). PyTorch Profiler With TensorBoard. Available at: https://docs.pytorch.org/tutorials/intermediate/tensorboard_profiler_tutorial.html?highlight=tensorboard
- Smai, Sabrina (n.d.). What’s New in PyTorch Profiler 1.9?. Available at: https://pytorch.org/blog/pytorch-profiler-1-9-released/
- huggingface.co (2026). Profiling in PyTorch (Part 1): A Beginner's Guide to torch.profiler. Available at: https://huggingface.co/blog/torch-profilerLernen Sie in nur 30 Minuten kennen, wie Ihr Team mit KI mehr erreichen kann – live und persönlich.
🚀 Demo jetzt buchen