Generate a PyTorch performance report#
2026-07-21
6 min read time
Turn a torch.profiler Chrome trace into a multi-sheet Excel (or CSV)
performance report, then read the sheets to find what dominates GPU time.
Before you begin#
Before generating a report, confirm you have the following:
TraceLens installed (see Install TraceLens).
A
torch.profilerChrome trace (.jsonor.json.gz).
Note
If you don’t have a trace yet, see the
PyTorch profiling walkthrough
for instructions on capturing one with torch.profiler.
Generate the report#
Pass the trace path to generate the default Excel report:
TraceLens_generate_perf_report_pytorch --profile_json_path path/to/trace.json
Set a custom Excel path, or write per-sheet CSVs instead:
# Custom Excel path
TraceLens_generate_perf_report_pytorch \
--profile_json_path path/to/trace.json \
--output_xlsx_path report.xlsx
# Per-sheet CSVs instead of Excel
TraceLens_generate_perf_report_pytorch \
--profile_json_path path/to/trace.json \
--output_csvs_dir ./report_csvs
Output behavior: By default a single Excel workbook is written next to the
trace, with the name inferred from the trace (profile.json →
profile_perf_report.xlsx). --output_xlsx_path changes that location.
--output_csvs_dir writes one CSV per sheet; passing it alone replaces the Excel
output, while passing it together with --output_xlsx_path produces both. The
openpyxl package is only needed for Excel output and is auto-installed if
missing.
The report sheets#
The generated workbook contains the following sheets:
Sheet |
Description |
|---|---|
|
End-to-end GPU activity: computation, communication, memory copy, and idle time. |
|
Compute time grouped by operation category (GEMM, SDPA_fwd, elementwise, and so on) — the most aggregated view. |
|
Per-operation aggregate; one row per unique operation name. |
|
Most detailed view; one row per unique (operation name, argument) combination. |
|
Unified perf metrics for ops with perf models or leaf ops that launch kernels — |
|
Collective-communication analysis (enabled by default; disable with |
Roofline sheets |
One per operation category ( |
|
Per-kernel summary — added with |
|
Short-kernel table and duration histogram — added with |
For the GPU timeline, a low computation percentage with significant idle time
indicates poor compute/communication overlap; use --micro_idle_thresh_us to
split very short idle gaps into their own category.
See Performance report column reference for what each column means.
Roofline classification#
Every per-category roofline sheet includes operation-intensity columns by
default: GFLOPS, Data Moved (MB), FLOPS/Byte, TFLOPS/s, and TB/s.
To add the roofline bound classification, supply a GPU architecture spec. This adds:
Compute Spec:combined compute type and precision (for example,matrix_bf16,vector_fp32).Roofline Time (µs):theoretical minimum time from the GPU’s peak capabilities.Roofline Bound:COMPUTE_BOUNDorMEMORY_BOUND.Pct Roofline:how close the measured kernel time runs to the roofline.TraceLens_generate_perf_report_pytorch \ --profile_json_path path/to/trace.json \ --gpu_arch_platform MI300X
--gpu_arch_platformtakes a bundled platform name (MI300X,MI325X, underTraceLens/Agent/Analysis/utils/arch/); use--gpu_arch_json_pathto supply your own spec. The two flags are mutually exclusive.An operation is classified by comparing its compute time (
FLOPs / peak FLOPS) against its memory time (bytes / peak bandwidth): the larger term wins. Equivalently, operations whose arithmetic intensity (FLOPs/byte) sits below the roofline knee point (peak FLOPS / peak bandwidth) are memory-bound; those above it are compute-bound.Add
--enable-origamito use Origami-simulated GEMM/SDPA times when a GPU arch spec is provided.
The arch JSON specifies Max Achievable FLOPS (MAF) per compute type and
precision; see the
GPU architecture example
for the format and the
AMD MAF measurements
for reference values. To plot roofline charts for specific operators through the
SDK, see the
roofline_plots_example.ipynb
notebook.
Detect activation recompute#
When training with activation checkpointing (torch.utils.checkpoint), some
forward-pass ops are recomputed during the backward pass to save memory.
--detect_recompute identifies these and adds an is_recompute column so you
can see how much GPU time and compute is spent on recomputation:
TraceLens_generate_perf_report_pytorch \
--profile_json_path path/to/trace.json \
--detect_recompute
TraceLens walks the CPU call-stack tree and marks all ops under
recompute_fn subtrees (python_function events from torch/utils/checkpoint.py)
as is_recompute=True. This requires python_function events in the trace,
which the flag enables automatically. The is_recompute column is added to the
gpu_timeline, ops_summary_by_category, ops_summary, ops_unique_args, and
unified_perf_summary sheets, splitting rows into recompute vs non-recompute.
Use it to answer questions like what percentage of GPU time is
recomputation, which layers are recomputed and at what cost, and whether the
overhead is acceptable for the memory saved. When the flag is not set there is
zero overhead — no extra columns and no python_function parsing.
The same split is available through the SDK:
from TraceLens.TreePerf import TreePerfAnalyzer
analyzer = TreePerfAnalyzer.from_file("trace.json", detect_recompute=True)
df = analyzer.get_df_kernel_launchers(include_kernel_details=True)
print(df["is_recompute"].value_counts())
Extend the report (custom hooks)#
--extension_file injects custom logic into the report pipeline — useful for
pseudo-op injection, custom perf models, or new op categories. The Python file
can define any of:
Symbol |
Type |
Purpose |
|---|---|---|
|
|
Called with |
|
|
Map op name → custom perf-model class; overrides or extends built-in models. |
|
|
Map category-only op names to final categories, so an op appears in unified reports without a perf model. |
TraceLens_generate_perf_report_pytorch \
--profile_json_path path/to/trace.json \
--extension_file my_extension.py
See the example extension file for MegatronLM in the
examples/ directory.
Optional arguments#
The following table describes all optional arguments.
Argument |
Default |
Description |
|---|---|---|
|
auto-inferred |
Excel output path (see output behavior above). |
|
|
Write each sheet as a CSV in this directory. |
|
|
Bundled GPU arch for roofline classification ( |
|
|
Custom GPU arch JSON (mutually exclusive with |
|
|
Use Origami-simulated GEMM/SDPA times when an arch is provided. |
|
|
Add an |
|
|
Custom tree / perf-model / op-category hooks (see above). |
|
|
Add the |
|
|
Add the short-kernel study sheets. |
|
|
Threshold (µs) to classify a kernel as “short”. |
|
|
Number of bins for the short-kernel histogram. |
|
|
Augment the tree with pseudo-ops to isolate kernels (for example, |
|
|
Add kernel-overlap sheets. |
|
|
Include kernels not linked to a host call stack in the GPU timeline. |
|
|
Split idle gaps shorter than this into a separate micro-idle category. |
|
(on) |
Disable the |
|
|
Cap rows in the unique-args ( |
|
|
Cap rows in the short-kernel table. |
|
|
Cap rows in the roofline sheets. |