Skip to content

Commit 1df0a68

Browse files
Mister-RaggsSolitaryThinker
authored andcommitted
[docs] Spark guide: add memory section, gotchas, and peak-memory to the benchmark
- spark_performance.md: "Memory: one unified 128 GB pool" section (nvidia-smi N/A, torch reserved as the real footprint, decode buffers as the pressure) and a GB10-specific "Gotchas" section. - spark_benchmark.py: report peak GPU memory (torch reserved) + unified pool free/total alongside the timing.
1 parent afbbd3b commit 1df0a68

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

docs/getting_started/installation/spark_performance.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,27 @@ Decode is output-only, so lowering its precision is safe. (Encode seeds the
7272
denoising trajectory for I2V/causal models, so that stays at the pipeline's
7373
default — don't lower `vae_precision` blindly for those.)
7474

75+
## Memory: one unified 128 GB pool
76+
77+
The GB10 has **no separate VRAM** — CPU and GPU share one 128 GB LPDDR5X pool
78+
(~118 GB usable). Two practical consequences:
79+
80+
- **`nvidia-smi` reports memory as `[N/A]`** on the GB10. For a model's real
81+
GPU-side footprint use torch's allocator high-water mark
82+
(`torch.cuda.max_memory_reserved()`); the system "used" figure conflates
83+
CPU + GPU + cache and is only a soft upper bound. `spark_benchmark.py` prints
84+
the torch figure for you.
85+
- **The 128 GB is a *working-set* ceiling, not storage** — the model cache lives
86+
on the NVMe (3.7 TB, ample). What has to fit in 128 GB is weights + activations
87+
+ KV, and — critically — the **VAE decode buffers**, which is why tiling matters
88+
(an untiled high-res decode can spike the pool into swap and lock the box).
89+
90+
The recommended few-step models are comfortable here: their weights are small
91+
(1.3–2 B) and few-step generation keeps activations modest. The pressure comes
92+
from **decode resolution/frames**, not the model — a 1080p×121-frame untiled
93+
decode is what pushes the pool toward its ceiling. Run `spark_benchmark.py` to see
94+
the peak figure for your exact config.
95+
7596
## What helps vs. what doesn't on the GB10
7697

7798
The honest summary — most "obvious" GPU optimizations don't move the needle on
@@ -133,6 +154,22 @@ is power-cycled. To avoid it:
133154
- Leave `*_cpu_offload` at the example defaults — "CPU" offload is the *same*
134155
unified RAM on the GB10, so the win is tiling + sane resolution, not offloading.
135156

157+
## Gotchas specific to the GB10
158+
159+
A few things that surprise people on this box (beyond the memory notes above):
160+
161+
- **Don't force `TORCH_SDPA` on a VSA checkpoint** (FastWan, LTX2.3-distilled).
162+
The SDPA path builds a model without the gate weights the checkpoint carries and
163+
fails to load. Run the model natively — VSA auto-routes to its Triton kernel on
164+
`sm_121`.
165+
- **Few-step timings are noisy run-to-run** (~±30%) — one-time startup dominates a
166+
3-step run. Compare in-process / as medians, never two separate single runs (the
167+
benchmark script does this).
168+
- **`nvidia-smi` shows `[N/A]` for memory** — see [Memory](#memory-one-unified-128-gb-pool).
169+
- **Cosmos-2.5** uses a Qwen2.5-VL text encoder; make sure you're on a FastVideo
170+
build recent enough to include its `transformers`-compatibility handling before
171+
running it.
172+
136173
## Reproduce these numbers
137174

138175
Two scripts under `examples/inference/optimizations/` reproduce the claims on

examples/inference/optimizations/spark_benchmark.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,25 @@ def _gen():
9898
for _ in range(args.warmup):
9999
_gen()
100100

101+
# Peak GPU memory: report torch's own allocator high-water mark, not
102+
# nvidia-smi. On the GB10's unified pool nvidia-smi reads [N/A] and the
103+
# system "used" figure conflates CPU+GPU+cache; torch.cuda.max_memory_reserved
104+
# is the model's actual GPU-side footprint.
105+
torch.cuda.reset_peak_memory_stats()
106+
101107
times = []
102108
for i in range(args.runs):
103109
dt = _gen()
104110
times.append(dt)
105111
_p(f"gen run {i + 1}/{args.runs}: {dt:.2f}s")
106112

107113
med = statistics.median(times)
114+
peak_gb = torch.cuda.max_memory_reserved() / 1e9
115+
free_b, total_b = torch.cuda.mem_get_info()
108116
_p(f"median generation time over {args.runs} runs "
109117
f"({args.warmup} warmup, {args.steps} steps): {med:.2f}s")
118+
_p(f"peak GPU memory (torch reserved): {peak_gb:.1f} GB "
119+
f"| unified pool free/total: {free_b / 1e9:.1f}/{total_b / 1e9:.1f} GB")
110120
_p("set FASTVIDEO_STAGE_LOGGING=1 to see the denoise / decode / text split "
111121
"(few-step generation is VAE-decode-bound on the GB10).")
112122
generator.shutdown()

0 commit comments

Comments
 (0)