Skip to content

Commit a2bfc7c

Browse files
[docs] DGX Spark (GB10) performance & tuning guide + reproduction examples (#1631)
Co-authored-by: SolitaryThinker <wlsaidhi@gmail.com>
1 parent b963a24 commit a2bfc7c

6 files changed

Lines changed: 635 additions & 0 deletions

File tree

docs/getting_started/installation.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ FastVideo supports the following hardware platforms:
55

66
- [NVIDIA CUDA](installation/gpu.md)
77
- [NVIDIA DGX Spark / GB10 (ARM64 + CUDA 13)](installation/spark.md)
8+
([performance & tuning](installation/spark_performance.md))
89
- [Apple silicon](installation/mps.md)
910

1011
## Quick Installation

docs/getting_started/installation/spark.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ If you hit other issues, please open an issue on our
137137
our [Slack community](https://join.slack.com/t/fastvideo/shared_invite/zt-3f4lao1uq-u~Ipx6Lt4J27AlD2y~IdLQ)
138138
for additional support.
139139

140+
## Next: performance & tuning
141+
142+
Installed and verified? See [DGX Spark: Performance & Tuning](spark_performance.md)
143+
for which models are practical on the GB10, what makes them faster, and what
144+
won't help on this hardware (and why) — so you don't spend a night tuning knobs
145+
that can't move here.
146+
140147
## Development Environment Setup
141148

142149
If you're planning to contribute to FastVideo please see the
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# DGX Spark (GB10): Performance & Tuning
2+
3+
You have FastVideo [installed on a DGX Spark](spark.md) — this page is what to
4+
run next. It covers **which models are practical on the GB10, what actually
5+
makes them faster, and what won't help (and why)**, so you don't burn a night
6+
tuning knobs that can't move on this hardware.
7+
8+
!!! tip "TL;DR"
9+
- **Use distilled few-step models** (e.g. `FastVideo/FastWan2.1-T2V-1.3B-Diffusers`).
10+
They run in ~40 s/video. Full-step models are 12–47 min on the GB10.
11+
- On few-step models, **VAE decode is the bottleneck**, not attention — it's
12+
bandwidth-bound on the Spark's unified memory.
13+
- **bf16 VAE decode** is the real, lossless lever (FastVideo already turns it
14+
on for Wan). **FlashAttention, linear quantization, and `torch.compile` of
15+
the VAE give little or nothing here** — see the table below.
16+
- Heavy runs can make the box unreachable — run generations with VAE tiling on
17+
and `nice -n 19`. See [Running safely](#running-safely-dont-lock-the-box).
18+
19+
## The hardware reality (this explains everything below)
20+
21+
The GB10 pairs a Blackwell GPU (`sm_121`) with **128 GB of unified LPDDR5X memory
22+
(~270 GB/s) shared between CPU and GPU**. That bandwidth is roughly **10× below a
23+
datacenter GPU's HBM**. Two consequences drive every tuning decision:
24+
25+
1. **Memory-bandwidth-bound stages hurt disproportionately.** VAE decode moves a
26+
lot of data and becomes the dominant cost on short (few-step) generations.
27+
2. **Compute-bound stages scale with step count.** Full-step diffusion (50+
28+
steps) is denoise-bound and simply takes a long time here.
29+
30+
## Use distilled few-step models
31+
32+
The single biggest lever on the GB10 is **model choice**. A 3-step distilled
33+
model is ~18× faster than the full-step version of the same architecture:
34+
35+
| Model | Steps | Time / video | Bottleneck |
36+
|---|---|---|---|
37+
| FastWan2.1-T2V-1.3B (distilled) | 3 | **~40 s** | VAE decode |
38+
| Wan2.1-T2V-1.3B (full-step) | 50 | ~12 min | denoise |
39+
| Cosmos-Predict2.5-2B (full-step) | 51 | ~47 min | denoise |
40+
| LTX2.3-distilled (+audio) | 8 | ~6 min | mixed |
41+
42+
The bottleneck flips from decode to denoise at around **4 steps**. Below that,
43+
you're paying mostly for VAE decode; above it, mostly for the denoising loop.
44+
45+
!!! note "Few-step timings are noisy — measure in-process"
46+
On a 3-step run, one-time per-process startup (Triton autotune, allocator
47+
warmup) dominates and never amortizes, so single-run totals wobble ~±30%.
48+
Compare levers **back-to-back in one process or as medians**, never as two
49+
separate single runs. The [reproduction script](#reproduce-these-numbers)
50+
does this for you.
51+
52+
## bf16 VAE decode — the real lever (already on for Wan)
53+
54+
Because few-step generation is decode-bound, VAE decode precision is where the
55+
time is. Decoding in **bf16 instead of fp32 is essentially lossless** (MS-SSIM
56+
~0.9999 vs fp32 on the identical latent) and ~1.14× faster — worth roughly
57+
5–7% end-to-end on a decode-bound few-step model.
58+
59+
**FastVideo already defaults Wan's decode to bf16** (`vae_decode_precision="bf16"`,
60+
with encode kept at fp32), so for the recommended Wan/FastWan models there's
61+
nothing to set. If you run a model that still defaults to an fp32 decode, set the
62+
decode-only override yourself:
63+
64+
```python
65+
from fastvideo.configs.pipelines.base import PipelineConfig
66+
67+
pipeline_config = PipelineConfig.from_pretrained(model_id)
68+
pipeline_config.vae_decode_precision = "bf16" # decode-only; leaves encode precision alone
69+
```
70+
71+
Decode is output-only, so lowering its precision is safe. (Encode seeds the
72+
denoising trajectory for I2V/causal models, so that stays at the pipeline's
73+
default — don't lower `vae_precision` blindly for those.)
74+
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, and the system "used"
81+
figure conflates CPU + GPU + cache, so it's only a soft upper bound — treat the
82+
whole 128 GB as one shared budget. For a per-run figure, use FastVideo's own
83+
`peak_memory_mb` (reported on the generation result and by the performance
84+
benchmark), which is measured inside the worker that runs the model.
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 the weights,
87+
activations, and KV cache — and, critically, the **VAE decode buffers**, which
88+
is why tiling matters
89+
(an untiled high-res decode can spike the pool into swap and lock the box).
90+
91+
The recommended few-step models are comfortable here: their weights are small
92+
(1.3–2 B) and few-step generation keeps activations modest — a Wan2.1-1.3B
93+
few-step generation peaks at **~8.4 GB** (measured), a small fraction of the pool.
94+
The pressure comes from **decode resolution/frames**, not the model — a
95+
1080p×121-frame untiled decode is what pushes the pool toward its ceiling, which
96+
is why VAE tiling stays
97+
on by default.
98+
99+
## What helps vs. what doesn't on the GB10
100+
101+
The honest summary — most "obvious" GPU optimizations don't move the needle on
102+
this hardware, for reasons specific to it:
103+
104+
| Lever | Effect on the GB10 | Use it? |
105+
|---|---|---|
106+
| Distilled few-step model | ~18× vs full-step |**the primary lever** |
107+
| bf16 VAE decode | ~1.14×, lossless; ~5–7% e2e on few-step | ✅ default for Wan |
108+
| VSA (video sparse attention) | works out of the box (Triton kernel auto-selects on `sm_121`) | ✅ automatic |
109+
| Building FlashAttention | **no speedup** — Torch SDPA already hits an efficient flash kernel on `sm_121`, and FA2 ties it | ❌ not worth building |
110+
| `torch.compile` of the VAE decode | recompile storm (per-frame varying shapes) → ~1.1× | ❌ dead end |
111+
| Linear (fp8 / nvfp4) quantization on long-sequence models (e.g. Cosmos) | ~nothing — see below | ❌ wrong lever here |
112+
| FP4 attention (`ATTN_QAT_INFER`) | works on `sm_121` (runtime allowlist landed in #1647; kernel build is #1598); helps, but needs a QAT-trained checkpoint | ⚠️ opt-in — see below |
113+
| FP4 linear on short-sequence models (LTX2) | up to −24% denoise at 1080p (#1594) | ⚠️ model/resolution-dependent |
114+
115+
### Why linear quantization is the wrong lever on long-sequence models
116+
117+
Quantizing the linear (GEMM) layers is a natural first instinct, but on a
118+
long-sequence video model it buys almost nothing on the GB10. A video-DiT denoise
119+
step is dominated by **O(N²) attention** at these sequence lengths (tens of
120+
thousands of tokens); the linear layers are a small single-digit fraction of the
121+
work. Quantizing them faster leaves the attention-bound total essentially
122+
unchanged — measured at ~1% on Cosmos-2.5, i.e. noise, and full-step CFG models
123+
also lose quality to per-step quantization error.
124+
125+
The same mechanism **does** help on **short-sequence** models: LTX2's aggressive
126+
VAE compression gives it short attention sequences, so FP4 linear reaches −24%
127+
there (#1594). The rule: **on the GB10, the lever that matters is attention
128+
(sparse or FP4), not the linear layers** — unless the model has short sequences.
129+
130+
### FP4 on the GB10 (opt-in)
131+
132+
Block-scaled FP4 works on `sm_121` under CUDA 13:
133+
134+
- **FP4 attention** (`FASTVIDEO_ATTENTION_BACKEND=ATTN_QAT_INFER`, #1598) is
135+
numerically correct on the GB10 and ~6% faster end-to-end generation, but it only preserves
136+
quality on a **quantization-aware-distilled checkpoint** (e.g.
137+
`FastVideo/FastWan-QAD-1.3B`) — stock weights aren't trained to tolerate it.
138+
- **FP4 linear** helps only where sequences are short (LTX2, above).
139+
140+
The [`qad_fp4_ab.py`](#reproduce-these-numbers) harness reproduces the FP4
141+
attention A/B on the QAD checkpoint.
142+
143+
## Running safely (don't lock the box)
144+
145+
The GB10 is easy to make **unreachable** — a heavy build or an untiled high-res
146+
decode starves the ~20 ARM cores and unified memory, `sshd` can't get cycles, and
147+
you're locked out at *"Connection timed out during banner exchange"* until the box
148+
is power-cycled. To avoid it:
149+
150+
- **Inference:** keep **VAE tiling on** (the default), use sane resolution/frames,
151+
and run under `nice -n 19`:
152+
153+
```bash
154+
nice -n 19 nohup python your_script.py > run.log 2>&1 &
155+
```
156+
157+
- **Builds** (flash-attn, kernel): `nice -n 19`, `MAX_JOBS=2`, `nohup`. Never a
158+
bare foreground high-parallelism build.
159+
- Leave `*_cpu_offload` at the example defaults — "CPU" offload is the *same*
160+
unified RAM on the GB10, so the win is tiling + sane resolution, not offloading.
161+
162+
## Gotchas specific to the GB10
163+
164+
A few things that surprise people on this box (beyond the memory notes above):
165+
166+
- **Don't force `TORCH_SDPA` on a VSA checkpoint** (FastWan, LTX2.3-distilled).
167+
The SDPA path builds a model without the gate weights the checkpoint carries and
168+
fails to load. Run the model natively — VSA auto-routes to its Triton kernel on
169+
`sm_121`.
170+
- **Few-step timings are noisy run-to-run** (~±30%) — one-time startup dominates a
171+
3-step run. Compare in-process / as medians, never two separate single runs (the
172+
benchmark script does this).
173+
- **`nvidia-smi` shows `[N/A]` for memory** — see [Memory](#memory-one-unified-128-gb-pool).
174+
- **Cosmos-2.5** uses a Qwen2.5-VL text encoder; make sure you're on a FastVideo
175+
build recent enough to include its `transformers`-compatibility handling before
176+
running it.
177+
178+
## Reproduce these numbers
179+
180+
Two scripts under `examples/inference/optimizations/` reproduce the claims on
181+
your own GB10:
182+
183+
```bash
184+
# Headline: few-step generation timing (median) + the bf16-vs-fp32 decode A/B.
185+
# FASTVIDEO_STAGE_LOGGING=1 also prints the denoise / decode / text split.
186+
FASTVIDEO_STAGE_LOGGING=1 nice -n 19 \
187+
python examples/inference/optimizations/spark_benchmark.py
188+
189+
# FP4 attention quality/speed A/B on the QAD checkpoint (one arm per run).
190+
QAD_LINEAR=0 FASTVIDEO_ATTENTION_BACKEND=ATTN_QAT_INFER nice -n 19 \
191+
python examples/inference/optimizations/qad_fp4_ab.py
192+
```
193+
194+
See also the [Optimizations](../../inference/optimizations.md) reference for the
195+
full list of attention backends and quantization options.

docs/inference/optimizations.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
This page describes the various options for speeding up generation times in FastVideo.
55

6+
!!! note "On a DGX Spark (GB10)?"
7+
Several options on this page behave differently on the GB10's unified-memory
8+
hardware — some give little or nothing there. See
9+
[DGX Spark: Performance & Tuning](../getting_started/installation/spark_performance.md)
10+
for what actually helps on that platform and why.
11+
612
## Table of Contents
713

814
- Optimized Attention Backends

0 commit comments

Comments
 (0)