Running NVIDIA's SANA-WM video world model on a home RTX 5090
A world model is the strange, fun corner of generative AI: you hand it a single still image and a trajectory — move forward, pan left, look up — and it dreams the video of moving through that scene. NVIDIA's SANA-WM does exactly this: image + a text prompt + a camera/action path in, a 720p clip out.
We wanted to know one thing: does this run at home, on a single consumer GPU? Here's the build log — what it took, where one RTX 5090 starts to sweat, and the gotchas that cost real debugging time.
What SANA-WM actually is
SANA-WM is a ~2.6B-parameter controllable video world model from NVIDIA's efficient-diffusion line. You give it a starting frame, a prompt, and an action string — something like w-80,jw-40,w-40 ("walk forward, turn while walking, walk forward") — and it generates a short clip that obeys that camera path. It's part video generator, part interactive world: the steering is the whole point.
The hardware
One RTX 5090 (32 GB, Blackwell sm_120) in an ordinary Windows workstation, with the model running inside WSL2. No datacenter, no second box — a single desktop GPU you could buy off a shelf.
Where the 32 GB bites
This is the part that shapes everything. SANA-WM has a two-stage pipeline — a base generator and a refiner. The refiner wants roughly 75 GB of VRAM. On a 32 GB card, that's simply not happening, so we run stage-1 only (--no_refiner). You give up the final polish pass; you keep a working video world model on a home GPU. For an experiment, that's the right trade.
| Thing | Number |
|---|---|
| Model | SANA-WM ~2.6B (bidirectional), stage-1 / --no_refiner |
| GPU | 1× RTX 5090, 32 GB (Blackwell sm_120), in WSL2 |
| Output | 81 frames @ 60 steps → 1280×704 clip |
| Time | ~3.5 minutes per clip |
| Stack | NVLabs Sana repo, PyTorch 2.9 / CUDA 12.8 (Blackwell), Python 3.11 |
The gotchas (the part worth reading)
- Do not enable the expandable-segments allocator. Setting
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True— usually a harmless memory-fragmentation win — throws aCUDA driver error: unknown errordeep in the VAE decode on WSL2 + Blackwell. The default allocator is fine; the "optimization" is the bug. - flash-attn won't build, and doesn't need to. Compiling flash-attention runs the 32 GB box out of system RAM. Good news: world-model inference uses flash-linear-attention instead, so you can skip it entirely.
- Mind the file-descriptor cap. A default
ulimit -nof 1024 gets tripped during VAE decode and cleanup. Raise it before you run, or watch a finished generation fall over at the last step.
A little dashboard to drive it
Command-line flags are a clumsy way to explore a generative model, so it's fronted by a small FastAPI dashboard with two tabs — Images (text→image) and Videos (image→video, the world model) — and an "Animate this →" button that hands a freshly generated still straight to the video form. Because it's one GPU, there's a single serial worker: an image and a video job never fight over the card.
Grab the run script
The run script and the full gotcha list — sanitized, ready to adapt — are on GitHub:
👉 github.com/teriansilva/sana-wm-single-gpu
You'll still need the NVlabs SANA code and a Python 3.11 / CUDA 12.8 environment for Blackwell; the script handles the env quirks (allocator, FD limit) and runs the stage-1, single-GPU inference.
One more thing
The image side of this exact rig is also our blog's art department. The cubist piece at the top of this post, and the aurora on our MiniMax-M3 write-up, were both generated on this 5090 — same box, same gateway, just the text-to-image half. The world model is the experiment; the image generator quietly earned its keep.
This is the kind of thing we do at superstatus.io — professionally self-hosted infrastructure, owned end to end, right down to running NVIDIA's research models on hardware we can reach out and touch. If owning your stack (AI included) sounds better than renting someone else's, that's our wheelhouse.
// COMMS