📌 Part of Blueprint: AI Agent & Local GPU Automation → L4: Automated AIGC & Media Pipelines

Running AI Video Locally on a 12 GB GPU: Real Numbers for Wan 2.2 and SeedVR2

· 13 min read · AI ai-videowancomfyuiseedvr2local-llmgpucost

Every guide to local AI video says the same thing about a 12 GB card: it can run the small models, sort of. None of them say what that means in minutes, or whether the output is actually 1080p, or what breaks first.

I spent a night finding out on an RTX 3060 12 GB (i9-13900K, 48 GB RAM, ComfyUI 0.41.2 running inside a Windows VM with the GPU passed through). The end result is a pipeline that turns one prompt and one start frame into a real 1920×1080 shot without paying anyone per second. It is also a pipeline I only got working after five consecutive runs failed in four different places.

This is the record of that.

What I wanted, and what it competes with

The target: short shots, 5 seconds each, stitched into something longer, at 1080p. The commercial alternative is not exotic — Kling runs about $0.112 per second for reference-to-video, so a 5-second shot is roughly $0.56. That is cheap if a shot lands first try.

The problem is that shots do not land first try. Generating video is an iterative act: I change the prompt, change the start frame, drop a seed, run it again. The cost that hurts is not the final render, it is the thirty renders that taught me what the final one should be. That is the work a local GPU is actually good at.

The models that fit in 12 GB

FileRoleSize
wan2.2_ti2v_5B_fp16.safetensorsvideo model9.99 GB
umt5_xxl_fp8_e4m3fn_scaled.safetensorstext encoder6.74 GB
wan2.2_vae.safetensorsvideo VAE1.41 GB
seedvr2_3b_int8_convrot.safetensorsupscaler3.46 GB
seedvr2_ema_vae_fp16.safetensorsupscaler VAE0.50 GB

Wan 2.2 TI2V-5B is the one that fits. It is trained around 1280×704, it does text-to-video and image-to-video with the same weights, and Apache-2.0 means the output is mine to use. The 14B variant is better and does not fit; LTX-2.3 is 22B and runs, but at a speed that turns iteration into a chore.

What it costs in time (all measured, not estimated)

5-second clips, 121 frames at 24 fps, 20 sampling steps:

ResolutionTotalSamplingDecodeVRAM peak
832×4806.1 min4.8 min1.3 min10.3 GB
1280×70417.9 min15.1 min2.8 min12.1 GB

Halving the pixel count does not halve the time — it cuts it to about a third. That is the usual superlinear scaling of a diffusion transformer, and it is the reason 480p exists as a draft tier at all.

Interactive Tool

Wan 2.2 TI2V-5B Render Time & VRAM Estimator

Simulate sampling duration, decode memory, and safe upscale segmentation based on my RTX 3060 12 GB benchmarks.

5 s (121 frames @ 24fps)
20 steps
Estimated Total Render ~17.9 min 15.1m sampling + 2.8m decode
Peak VRAM Usage 12.1 GB Tight fit on 12 GB card
SeedVR2 1.5× Split Strategy 3 segments Max 41 frames/segment to prevent crash

Failure one: the decode that runs out of host memory

The first 720p attempt sampled fine and then died in the VAE decode:

RuntimeError: DefaultCPUAllocator: not enough memory:
you tried to allocate 1308426240 bytes

That is not a VRAM error. The Wan VAE decode for 121 frames wants about 1.3 GB of CPU-side buffers in one go, and the VM had only about 12 GB free out of 48. Switching to a tiled decode — tile 272, overlap 32, temporal 32, temporal overlap 8 — dropped decode VRAM from 11.9 GB to 3.9 GB and it completed.

The lesson is not “use tiled decode everywhere”. At 25 frames the non-tiled decode needs about 0.27 GB and is faster and simpler. Match the decoder to the frame count instead of always reaching for the tiled one.

Failure two: the upscaler takes the whole server down

SeedVR2 3B produces genuinely good 1.5× output, and at 121 frames it reliably killed the process:

Windows fatal exception: access violation
  comfy/ldm/seedvr/vae.py ... decode_tiled

Not an exception I could catch — a native crash that takes the HTTP server with it, leaving the port dead. Installing triton-windows removed an earlier PatchTritonVAE requires triton import error but changed nothing about the crash. It reproduced three times at 121 frames and never once at 41.

So the workaround is a cut: split the clip into segments of at most 41 frames, upscale each, concatenate. Ugly, reliable, and the seams are invisible if every cut lands on an exact frame boundary.

Failure three, and the one command that fixed it

Two hours after a clean 5-second render, the same script started failing. Then it failed again, differently. Over five runs:

aimdo: xfer_file_read_at: GetOverlappedResult failed error=1450
HostBuffer.read_file_slice failed          ← during sampling
hostbuf_file_reader_read failed            ← during decode
Windows fatal exception: access violation  ← during model load

I did what anyone would do and blamed the thing I had just changed — the resolution. Ran a 704p control at the same frame count. It failed too. The resolution was never the problem.

The actual cause: ComfyUI keeps the 10 GB model resident after a job finishes. Idle VRAM was sitting at 9.7 GB. The next submission could not fit it, so the loader fell back to streaming weight slices from disk, and that path is broken on this machine — error 1450 is ERROR_NO_SYSTEM_RESOURCES, a host-side resource failure, not a sampling failure.

One request fixes it, and it belongs before every run:

curl -X POST http://127.0.0.1:8188/free \
  -H "Content-Type: application/json" \
  -d '{"unload_models": true, "free_memory": true}'

VRAM went 9.7 GB → 1.1 GB, and the exact job that had failed three times passed on the next attempt.

It is also worth saying which fix made things worse, because it is the one most guides suggest. Launching with --disable-dynamic-vram moved the crash earlier: the 9.99 GB model no longer fit the 8.45 GB left after the text encoder, so the loader sliced the memory map and died in torch.storage while loading. Same wall, worse side of it.

The 1080p trap: 720 is not a multiple of 32

Wan22ImageToVideoLatent requires width and height to be multiples of 32. 720 is not — 720 ÷ 32 = 22.5 — so the nearest legal height under 720 is 704, and 1280×704 is 16:8.8, not 16:9. Upscale that by 1.5 and the honest output is 1920×1056, which is not 1080p and will letterbox or stretch somewhere later.

Three ways out:

RouteResultCost
Generate 1280×736 (23×32), upscale 1.5× → 1920×1104, crop 24 pxexact 1920×1080no bars, no distortion
Keep 704, pad1920×108012 px black bars top and bottom
Keep 704, scale 1.534 then crop1920×1080loses ~2 % of the width

I took the first. 736 is a legal multiple of 32, it is much closer to 16:9 than 704, and cropping 24 rows off the top and bottom removes only the padding the model never used.

Do not stretch 1056 into 1080. Faces get 2.3 % wider and it reads as wrong instantly.

The pipeline, end to end

Draft at 480p to judge motion and composition — sharpness at 480p says nothing about the delivered shot, so it is the wrong place to judge it. Then the accepted shots go through:

# clear VRAM first, every time
curl -X POST http://127.0.0.1:8188/free -d '{"unload_models":true,"free_memory":true}'

# 1. generate 1-second shots (25 frames per the 4k+1 rule at 24fps) at 1280x736
python bench_wan.py --w 1280 --h 736 --frames 25 --steps 20 --tag final_1s --cold

# 2. upscale each <=41-frame segment to 1920x1104
python bench_upscale.py --file segment.mp4 --scale 1.5 --tsize 21 --chunk 21

# 3. crop to exact 1080p
ffmpeg -i upscaled.mp4 -vf "crop=1920:1080:0:12" -c:v libx264 -crf 16 final.mp4

This is the actual output, generated locally and hosted on my own CDN: a complete 35-second high-energy sequence (7 shots at 5 seconds each, seamlessly stitched with Chinese EDM battle music), 1920×1080, 24 fps, from a series of consistent start frames.

Wan 2.2 TI2V-5B, 1280×736 → SeedVR2 1.5× (1920×1104, 41-frame segments) → crop 1920×1080. 7 shots generated locally, stitched and paired with custom YuE2-generated Guofeng battle music, zero external rendering.

What the upscale actually buys

Measured with Laplacian variance, the upscale moves detail energy from 673 to 766 — about 14 %. Edges, hair and neon signage get visibly crisper at 1:1.

Skin does not. A 3B upscaler sharpens information that is already in the frame; it does not invent pores or fabric grain. Treating SeedVR2 as “restoration” leads to disappointment. Treating it as “make the 720p-class render hold up at 1080p” is accurate.

The result

Shot lengthGenerateUpscaleTotalCost
1 second (25 frames)3.4 min2.8 min~6 min$0
2 seconds (49 frames)5.7 min7.7 min~13 min$0
5 seconds (121 frames)17.9 min14.1 min~32 min$0

A 60-second sequence of 12 five-second shots takes roughly 6.4 hours of local compute (about half a day of continuous running), or about $5 through a commercial API — and 40 minutes instead of half a day. Both are true, and they answer different questions. The local machine is for the thirty takes nobody pays for. The API is for the one take that ships.

What I would do differently

Three things, in order of how much time they would have saved.

Instrument the VRAM before blaming the code. The five-failure detour existed because I trusted “this configuration worked two hours ago” and started changing parameters. One nvidia-smi between runs would have shown 9.7 GB resident and ended the hunt immediately.

Read the layout constraint before designing the pipeline. The 1920×1056 surprise came from not checking that the latent node wants multiples of 32. That is a five-second check that cost a full re-render.

Cut the upscale into segments from the start. A 41-frame ceiling sounds arbitrary until the first crash. Now it is just the unit of work.

The honest summary: 12 GB is enough to make 1080p AI video locally, at about 6 minutes per finished second. It is not enough to be careless about memory.


If this is the kind of thing you want running in your own business — local video generation, self-hosted AI pipelines, or the plumbing that keeps a GPU busy without an engineer babysitting it — I build these:

🚀 Automation & Custom AI Systems

Want a 24/7 bot or automation pipeline that never drops a lead?

Don't let customer inquiries slip away at midnight or on weekends. I build custom Telegram/WhatsApp AI assistants and deterministic workflows that connect directly to your catalogue, CRM, and order fulfillment.

Lee Teong Hoe

Lee Teong Hoe · Mr Hoelee

Full-stack developer & DevOps engineer based in Malaysia. I run my own production infrastructure and build web systems for small businesses — this blog is the living record.

Hiring? Profile & stack · Malaysian SME? Website design & development ↗ · All posts