wan-mem-opt
Run Wan2.1 T2V 1.3B with optimized memory usage on AMD UMA/ROCm. Use when the user says /wan-mem-opt, wants low-memory Wan 2.1 1.3B video generation, CPU UMT5/text-encoder placement, tiled VAE decode,
SKILL.mdwan-mem-opt/SKILL.md
GitHub/wan-mem-opt — low-memory Wan2.1 1.3B runner
This skill runs Wan2.1 T2V 1.3B in a direct Python process using ComfyUI's PyTorch backend, without launching the ComfyUI web server/API.
It is optimized for this AMD APU/iGPU UMA machine:
- Default low-memory mode keeps UMT5 / CLIP text encoder on CPU to avoid the GPU text-encoder transient peak.
- Alternative faster mode:
--clip-device default --free-clip-after-encodeloads UMT5 on GPU, encodes prompts, then immediately deletes it and callstorch.cuda.empty_cache(). - Use tiled VAE decode by default to reduce VAE decode peak.
- Measure real UMA memory pressure via
/proc/meminfoMemAvailabledrop.
Installed files
/home/chihmin/.pi/agent/skills/wan-mem-opt/SKILL.md
/home/chihmin/.pi/agent/skills/wan-mem-opt/scripts/wan_mem_opt.sh
/home/chihmin/.pi/agent/skills/wan-mem-opt/scripts/run_wan21_direct_optimized.py
/home/chihmin/.pi/agent/skills/wan-mem-opt/scripts/profile_uma_memory.py
Required local environment
Expected paths:
/home/chihmin/src/ComfyUI
/home/chihmin/src/ComfyUI/.venv/bin/python
/home/chihmin/src/ComfyUI/models/diffusion_models/wan2.1_t2v_1.3B_fp16.safetensors
/home/chihmin/src/ComfyUI/models/text_encoders/umt5_xxl_fp8_e4m3fn_scaled.safetensors
/home/chihmin/src/ComfyUI/models/vae/wan_2.1_vae.safetensors
The model is not GGUF. It is a PyTorch/safetensors fp16 model:
wan2.1_t2v_1.3B_fp16.safetensors
Environment variables set by the launcher
The wrapper sets these defaults:
export TORCH_ROCM_AOTRITON_ENABLE_EXPERIMENTAL=1
export MIOPEN_FIND_MODE=FAST
export MIOPEN_USER_DB_PATH=/home/chihmin/.cache/miopen-wan21
export PYTHONUTF8=1
Override if needed:
COMFY_PY=/path/to/python \
COMFY_DIR=/path/to/ComfyUI \
MIOPEN_USER_DB_PATH=/custom/cache \
/home/chihmin/.pi/agent/skills/wan-mem-opt/scripts/wan_mem_opt.sh ...
Quick run
Lowest-memory default cat run, with UMA profile:
/home/chihmin/.pi/agent/skills/wan-mem-opt/scripts/wan_mem_opt.sh \
--profile \
--output /home/chihmin/generated/wan21_memopt_cat.mp4 \
--steps 12 \
--vae-mode tiled \
--tile-size 256
If no runner args are provided, the wrapper generates a default cat video into a timestamped output directory.
Warmup / precompile mode
Use --warmup to run an unsaved same-shape warmup pass inside the same Python process before the real generation. This is safer than torch.compile for the Comfy/Wan graph and helps populate ROCm/Triton/MIOpen caches for the exact resolution/frame shape.
/home/chihmin/.pi/agent/skills/wan-mem-opt/scripts/wan_mem_opt.sh \
--profile \
--warmup \
--warmup-steps 1 \
--output /home/chihmin/generated/wan21_memopt_warm.mp4 \
--steps 12 \
--clip-device default \
--free-clip-after-encode \
--vae-mode tiled --tile-size 256
Warmup behavior:
same width/height/frames/vae mode as the real run
1 warmup sampling step by default
VAE warmup decode enabled by default
warmup output is not saved
warmup tensors are deleted and torch.cuda.empty_cache() is called before the real run
The first --warmup run can take longer overall because it includes the warmup pass. The benefit is mainly for repeated same-shape runs or avoiding first-use kernel/cache stalls during the measured real generation.
Custom prompt
/home/chihmin/.pi/agent/skills/wan-mem-opt/scripts/wan_mem_opt.sh \
--profile \
--output /home/chihmin/generated/wan21_custom.mp4 \
--prompt 'A cute cat is eating food from a small bowl on a cozy kitchen floor, close-up, realistic soft fur, gentle chewing motion, warm natural light, cinematic, stable camera, high quality video' \
--width 832 --height 480 --frames 17 --fps 16 \
--steps 12 --seed 2026070118 \
--clip-device cpu \
--vae-mode tiled --tile-size 256 --overlap 64 --temporal-size 16 --temporal-overlap 4
Frame rule: Wan video length should be 4n+1, e.g. 17, 49, 73.
Runner options
Important options:
--clip-device cpu Lowest peak memory. Keep UMT5 on CPU.
--clip-device default Faster prompt encoding; loads UMT5 on GPU temporarily.
--free-clip-after-encode Default. Delete UMT5/CLIP after pos/neg prompt encoding and call empty_cache().
--no-free-clip-after-encode Debug only; keeps text encoder resident and wastes memory.
--warmup Wrapper option: append --warmup-steps 1 for same-process cache/kernel warmup.
--warmup-steps N Number of unsaved warmup sampling steps before the real run.
--warmup-decode Default. Also warm VAE decode kernels.
--no-warmup-decode Warm sampler only, skip warmup VAE decode.
--vae-mode regular Faster VAE decode, higher peak memory.
--vae-mode tiled Default. Lower peak memory, slower decode.
--tile-size 256 Known-good low-memory tile size.
--steps 12 Visual sanity quality; 1 step is only for profiling/kernel tests.
GPU text encoder with explicit cleanup works and is faster if you have enough transient headroom:
/home/chihmin/.pi/agent/skills/wan-mem-opt/scripts/wan_mem_opt.sh \
--profile \
--output /home/chihmin/generated/wan21_gpuclip_free.mp4 \
--steps 12 \
--clip-device default \
--free-clip-after-encode \
--vae-mode tiled --tile-size 256
Known benchmark on this host
All runs: 832x480, 17 frames, 12 steps.
| Setup | Actual UMA RAM drop | Peak ROCm GTT | Runtime |
|---|---|---|---|
| Original default: GPU CLIP + regular VAE | ~19.82 GiB | ~18.55 GiB | ~48.7 s |
| CPU CLIP + regular VAE | ~13.73 GiB | ~12.28 GiB | ~57.2 s |
| CPU CLIP + tiled VAE | ~7.60 GiB | ~5.53 GiB | ~62.7 s |
Primary metric for UMA systems:
actual UMA memory cost = baseline MemAvailable - minimum MemAvailable
Do not blindly add GTT + RSS on UMA; they are different accounting views and can overlap.
Output/profile files
With --profile, the wrapper writes:
<outdir>/uma_profile.csv
<outdir>/uma_profile.csv.summary
<outdir>/uma_profile.csv.stdout
<outdir>/uma_profile.csv.stderr
The .summary file contains:
baseline_MemAvailable_GiB
min_MemAvailable_GiB
MemAvailable_drop_GiB
peak_rss_GiB
peak_rocm_gtt_GiB
peak_rocm_vram_GiB
Troubleshooting
- If model files are missing, the launcher prints the missing path and exits.
- If output is low quality, increase
--steps; memory should not grow much with steps, but runtime scales. - If memory is still too high, ensure
--clip-device cpuand--vae-mode tiledare both set. - If tiled VAE has seams or differences, compare with
--vae-mode regular; the tested 0.55s frame mean RGB diff was small (~2–3/255).