Profiling a demo
Nsight Systems shows the model thread, the UI thread and the GPU on one
timeline, so you can see what each of them was doing at the same moment. If you
only need numbers for each step, such as stage timings, frame rates and input
latency, use --stats-path instead.
Collecting a report
First install the model package, then launch the app through
flashdreams-profile:
uv sync --package flashdreams-self-forcing
uv run flashdreams-profile -- t2v-self-forcing-wan2.1-t2v-1.3b --timeout 300 \
--output-path artifacts/run.mp4 -- --prompt "A city street at night" --total-blocks 7
If the model takes longer to compile, increase --timeout.
The report is saved in artifacts/profiles/. To save it somewhere else, pass
--report-path. By default the report records CUDA, NVTX, OS runtime and
Vulkan activity; to record something different, pass --trace.
To time each stage, --stats-path (or FLASHDREAMS_SYNC_AND_PROFILE=1)
makes the CPU wait for the GPU twice per step. This adds a slight delay to each
step, so the timeline differs slightly from a normal run.
Reading the report
To read the report, open the .nsys-rep file in the Nsight Systems GUI. For a
quick summary in the terminal instead, run:
nsys stats --report nvtx_sum artifacts/profiles/<report>.nsys-rep
Each row of the summary is one of the ranges below, with how many times it ran
and how long it took. These durations are CPU time and include waiting. For the
GPU work that each range launched, use --report nvtx_gpu_proj_sum instead.
| Range | Meaning |
|---|---|
model.pace |
Waiting to hold the step rate. |
model.step[i] |
One autoregressive step. |
model.publish |
Handing the chunk to presentation. |
pipeline.encode / diffuse / decode |
Encode, denoising loop, VAE decode. |
pipeline.finalize |
KV-cache update for the next step. |
ui.step |
One UI loop iteration. |
input.wait |
From an input arriving to the first frame that shows it. |
Besides these ranges, the timeline has a mark each time a frame is generated
(model.frame) or shown (present.frame). Each mark includes the step that
produced the frame, such as present.frame [step 5], so you can follow a frame
on screen back to the step that made it.
FlashVSR and SwiftVR use their own generate method, so their reports have no
pipeline.* ranges.
Using your own profiler
A session runs with the profiler the application runner creates. To use your
own, assign it at the start of init(), before registering a loop:
def init(self):
self._profiler = MyProfiler()
The session's loops get it as self.profiler, so a model loop can record its
own ranges and events:
with self.profiler.range("my_stage"):
...
self.profiler.event("my_event")
To profile a pipeline on its own, see Profiling a pipeline.