Four timeline smells
Four traces. Name the idle pattern, name the cause class, and name the first experiment that would shrink the white space.
- Lesson
- Reading the GPU timeline
- Module
- See inside the box
- Objective
- Read GPU idle as launch tax, host island, copy-on-critical-path, or sync cliff — and pick a fix at the right level.
A dense GPU lane means the kernels can be the story. White space means they are not. Classify first; do not rewrite attention in the blank regions.
The four traces (ASCII is enough)
Trace 1 — picket fence
GPU: k k k k k k k k k k
^gaps of 8–20 µs between 3 µs kernels, repeating 128 times (decode)
CPU: python loop visible between launches
Trace 2 — host island
GPU: [==== prefill 42 ms ====] [==== decode step ====]
CPU: [-- tokenize 28 ms --][-- json 9 ms --]
Trace 3 — copy on the path
GPU: [H2D 6 ms][kernel 4 ms][D2H 5 ms][kernel 4 ms]
CPU: np.array ← tensor.cpu() then later tensor(batch)
Trace 4 — sync cliff
GPU: [matmul][attn] [matmul][attn]
CPU: .item() wait .item() wait
Part A — Cards
For each trace write:
Smell:
Cause class: launch | host | copy | sync
Why the GPU is empty:
First experiment:
Forbidden next step:
Part B — Decode product
Which two traces are the default decode failure modes at batch 1? What serving change attacks both at once?
Part C — Protocol
Copy the six-step protocol from the lesson from memory. Apply it to Trace 3 as if this were a Monday incident.
Acceptance
- Trace 1: graphs/compile/batch; not a new MMA kernel.
- Trace 2: move tokenize/post off the request critical path or overlap; not cuBLAS.
- Trace 3: keep tensors on device;
.cpu()/ numpy is the bug. - Trace 4:
.item()/ print / implicit sync; CUDA events instead. - Continuous batching + compiled/graph decode is the "both" answer for 1 and 4.
Stretch
Add NVTX range names you would inject for a prefill+128 decode run. At least: tokenize, prefill, decode_step, sample, detokenize.
Check
Picket fence = launch tax. Host island = GPU starved by CPU. H2D/D2H on the critical path = accidental copies. .item() = sync cliff. Decode at b=1 is 1+4 until you batch.
Debrief
If the GPU is empty, a faster kernel makes the emptiness larger as a fraction of wall time. Feed the machine first.