SparkDiffusion Image To Video
Animate a still with 14B Wan, four steps at a time
- runtime
- profile
- image
- video
- frames
- video_path
- metadata
Here's the thing about Wan: I2V from a good still is the community's default video workflow. Text-to-video gets the demos, but when you want a specific person, a specific room, a specific composition, you generate the frame first and animate it. That habit is exactly why a fast I2V path matters - and it's the heaviest one, which is why full-quality Wan I2V 720p was measured at 40 minutes for 81 frames on a 4090.
SparkDiffusion's answer is a distilled, sparse-attention checkpoint that does the same job in four steps. The pack's single I2V preset is wan2.1-i2v-14b-720p-s97-4step - 97% RoLA sparsity, four steps, 720P. On the author's 5090 that's the 32.8 GB checkpoint running at around 27.9 GiB peak VRAM, and he validated it on Windows-native. It's the node I'd reach for over Text To Video for anything that needs to look like it's actually about something.
How it works
Same architecture as the rest of the pack: this node is a launcher. It takes your image, writes the first frame of the batch out as a PNG, builds a job file, and starts the isolated SparkDiffusion runtime as a subprocess running the official upstream wan2pt1_i2v_distilled_infer.py. The launcher verifies the same things every run - RoLA on every block, the profile's top-k ratio, the exact CrossDistill timesteps, FP8 module count, fused kernels, compile state - and a failed verification is an error, not a result.
The inputs that matter
runtime and profile come from the Runtime and Profile nodes. Then:
- image - a normal ComfyUI IMAGE. Only the first frame of a batch is used.
- prompt - the motion description. The default is a good example of the shape: "The subject slowly turns toward the camera." You're directing movement, not re-describing the picture.
- num_frames - 81 default, 5–161 in steps of 4 (4k+1, because that's the pattern Wan's VAE accepts). 81 = 5 s at 16 fps, the distilled length.
- seed, filename_prefix (defaults to
sparkdiffusion/SparkWanI2V).
Two optional fields are the interesting ones. fixed_resolution defaults to false, meaning upstream keeps your input image's aspect ratio and fits it to the profile's pixel area - so a portrait still stays portrait. Turn it on and you force the profile resolution at 16:9, which will crop or stretch your carefully composed image into widescreen. Leave it off unless you specifically need a fixed output shape. num_videos (1–16) runs several seeds in one process. And you'll get a hard error if you feed a T2V preset to this node - that check is doing you a favour.
Outputs
video (ComfyUI VIDEO), frames (IMAGE - first frame only unless you enable load_frames), video_path (STRING), and metadata (STRING, the full verification and timing JSON). It's an output node and previews the clip in the graph. The metadata string is the one to actually read: it tells you which backend ran, whether FP8 was real, and how long each step took.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/hiroki-abe-58/ComfyUI-SparkDiffusion
or Manager → search SparkDiffusion → restart. Nothing installs into ComfyUI's Python - the heavy stuff lives in the separate runtime environment. I2V needs one extra asset beyond T2V: the CLIP encoder (models_clip_open-clip-xlm-roberta-large-vit-huge-14.pth), which is why the README lists Wan2.1-I2V-14B-720P/ as its own model-root folder. Grab the checkpoint and assets with:
python scripts/download_models.py --profile wan2.1-i2v-14b-720p-s97-4step --model-root /data/spark
There's a ready workflow at workflows/sparkdiffusion_14b_720p_i2v.json.
Where people get burned
VRAM, mostly. I2V 720P is the heaviest thing in the pack - about 28 GiB peak, and the pack's testing floor is a 32 GB card. If you're on 24 GB, expect the allocator to start spilling and your steps to double, which the author traced to the Windows driver quietly moving weights into system RAM. Close other GPU apps. The other practical annoyance is the per-run reload: each execution re-reads the checkpoint and reconverts to FP8, about 45 s from local NTFS and closer to 3 minutes through WSL2's 9P filesystem if your models sit on the Windows drive while the runtime lives in the distro. Put the model root on the distro's own disk if you can. And as with any SparkDiffusion profile, there's no LoRA or sampler slot to bolt extra control onto.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| runtime | SPARKDIFFUSION_RUNTIME | — | |
| profile | SPARKDIFFUSION_PROFILE | — | |
| image | IMAGE | — | |
| prompt | STRING | The subject slowly turns toward the camera. | — |
| seed | INT | 00–4294967295 | — |
| num_frames | INT | 815–161 | — |
| filename_prefix | STRING | sparkdiffusion/SparkWanI2V | — |
| fixed_resolutionopt | BOOLEAN | false | Off = upstream input-aspect sizing (keeps the image aspect at the profile's pixel area). On = force the profile resolution at 16:9. |
| load_framesopt | BOOLEAN | false | — |
| num_videosopt | INT | 11–16 | Videos generated in ONE runtime process with seeds seed, seed+1, ... (upstream NUM_SAMPLES). Loading and torch.compile are paid once, so extra videos are cheap. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| frames | IMAGE | — |
| video_path | STRING | — |
| metadata | STRING | — |