M02.01·Profiling·Core·90 minutes·3 min read

Profiler Triage Report

Turn an operator table into a concise performance report with suspects, evidence, and the next experiment.

Module
See inside the box
Objective
Read profiler output and write a focused next-step report instead of a vague optimization wishlist.

Prompt

You receive this simplified profiler table for one request:

opCUDA totalCPU totalcallsmemory
aten::matmul38.4 ms4.1 ms180 B
aten::_scaled_dot_product_flash_attention31.7 ms2.9 ms180 B
aten::copy_19.6 ms20.4 ms542.8 GiB
aten::to15.1 ms16.8 ms542.8 GiB
aten::slice1.4 ms7.9 ms4360 B
tokenizer.encode0 ms22.0 ms10 B

Workload:

model: decoder-only LLM
prompt: 4096 tokens
output: 128 tokens
dtype: bf16 weights
batch: 1
hardware: L4

Deliverable

Write a five-line report:

Workload:
Hardware:
Top CUDA time:
Top CPU / orchestration cost:
Next experiment:

Then add:

  1. Two hypotheses for why copy_ and to are present.
  2. One experiment that would confirm or reject each hypothesis.
  3. One thing you would not optimize yet, and why.

Acceptance criteria

A good answer:

  1. Separates model math from avoidable movement.
  2. Mentions that tokenizer CPU time is outside GPU execution but still affects request latency.
  3. Does not propose writing a custom attention kernel while copies and casts are unexplained.
  4. Chooses one next experiment, not five.

Stretch

Add NVTX or record_function ranges you would insert before the next run. Name the ranges exactly.

Debrief

The profiler is a discipline tool. It keeps you from choosing glamorous work before the boring evidence has been handled.

Part B — A second table, opposite smell

opCUDA totalCPU totalcallsmemory
aten::matmul6.1 ms3.4 ms2400 B
aten::add4.8 ms5.2 ms2400 B
aten::relu4.1 ms4.9 ms2400 B
aten::copy_0.4 ms0.6 ms812 MiB
Python decode loop0 ms38.0 ms1280 B

Workload: batch 1, prompt 32, decode 128, tiny hidden size, L4.

Write the same five-line report. Then contrast it with Part A in four bullets: what the top CUDA name means in each case, and why a fused attention kernel is the wrong next experiment here.

Part C — The five-line template, memorised

Without looking, write the five field names. Fill them for a fake run where aten::copy_ is 61% of CUDA time on a 7B decode. Next experiment must mention dtype or device movement, not FlashAttention.

Check

Part A: copies/casts unexplained → experiment is "who is calling to() / .cpu()", not a new attention kernel. Tokenizer is CPU-side TTFT. Part B: many tiny launches + Python loop → overhead-bound decode; compile/graphs/batch, not MMA. Five fields: Workload, Hardware, Top CUDA time, Top CPU / orchestration, Next experiment.