← Engineering creative generation pipelines

Part 3 of 6 · 5 min read

Wan 2.1 image-to-video: an inspectable ComfyUI graph

The complete 13-node API graph, image conditioning, sampling parameters, ordered frames and runtime validation.

Arunank Sharan · Kuzushi Labs ·

In this article

The reference motion stage takes an approved image and generates a short product shot. It uses Wan 2.1 I2V through ComfyUI’s native nodes, with the graph saved in API format rather than only as editor coordinates.

The complete graph JSON is an authored reference. Its structure and dependencies are checked offline. It has not been executed on a GPU during preparation of this publication, so no generation time, quality score or peak-memory result is claimed.

Choose the correct task and checkpoint

Wan 2.1 includes different task/model combinations. The small 1.3B text-to-video result should not be used to infer the memory requirements of the 14B image-to-video model. The official project’s 8.19 GB claim refers to its T2V-1.3B configuration, not the I2V graph here. Wan 2.1 repository

The reference selects wan2.1_i2v_480p_14B_fp16.safetensors, a UMT5 text encoder, clip_vision_h.safetensors and wan_2.1_vae.safetensors. Their expected ComfyUI folders are diffusion models, text encoders, CLIP Vision and VAE respectively. Official ComfyUI model setup

Trace the graph by responsibility

NodesResponsibility
1–4Load diffusion model, text encoder, VAE and vision encoder
5–6Load the approved image and encode its visual conditioning
7–8Encode positive and negative motion prompts
9Construct image-to-video conditioning and the latent allocation
10–11Apply the sampling shift and run the sampler
12–13Decode frames and save them under an attempt-specific prefix

The key connection is node 9. It returns positive conditioning, negative conditioning and the latent representation; those three outputs feed the sampler. Passing the raw text conditioning directly to the sampler would bypass the intended image-to-video conditioning path.

The central node, in API format

{
  "9": {
    "class_type": "WanImageToVideo",
    "inputs": {
      "positive": ["7", 0],
      "negative": ["8", 0],
      "vae": ["3", 0],
      "width": 832,
      "height": 480,
      "length": 81,
      "batch_size": 1,
      "clip_vision_output": ["6", 0],
      "start_image": ["5", 0]
    }
  }
}

This excerpt is part of the full graph. References such as ["7", 0] identify an upstream node and output slot. They are not filenames or literal embeddings.

The inspected upstream implementation allocates a latent with temporal depth ((length - 1) // 4) + 1. The 81-frame choice follows a 4n + 1 form. At 832 × 480, the spatial latent dimensions are 104 × 60 for this path. That latent tensor is only a small part of total memory; model weights and intermediate activations dominate the broader resource calculation. Pinned node implementation

Sampling parameters are a baseline, not a promise

The example uses 30 steps, CFG 6, an Euler sampler, a simple scheduler and shift 3.0, with batch size one. These are explicit starting parameters for this reference. A validated checkpoint-specific recipe should determine the production values.

Keep the seed fixed when comparing one parameter change. Then evaluate across several seeds to avoid overfitting the choice to one favorable clip. Low-step distillation adapters may require different guidance and schedules; do not add one to the baseline while retaining all settings by habit.

A stronger negative prompt is not a substitute for an appropriate input image. The positive motion description should also remain modest: stable product, slow camera movement, consistent light and one continuous shot.

Save frames before encoding

The graph ends in the native SaveImage node. This avoids assuming a particular third-party video-combine extension and preserves the generated frames for inspection.

Read the successful output node’s history to obtain the actual frame filenames. Require 81 frames, keep their sequence, and stage only that attempt’s frames for encoding. Never glob a shared output directory where another job may have written similarly named images.

At 16 fps, 81 encoded frames occupy 5.0625 seconds. Their first-to-last timestamp span is five seconds. The difference matters when joining clips or aligning audio.

A finishing worker can encode H.264 with a broadly compatible pixel format and then probe the resulting file. Adding frame interpolation changes cadence; it does not create an equivalent amount of newly generated motion or repair distorted product geometry.

Validate against the installed runtime

The kit records the upstream ComfyUI revision inspected for the node contract. Before execution, compare the graph with the worker’s /object_info: required inputs, available nodes and installed model filenames must agree. A workflow that parses as JSON can still fail because a node or model is missing.

Next run a budgeted smoke generation with a non-client image. Record peak VRAM, cold-start time, generation time, output dimensions and frame count. Only then promote the worker profile.

The provided validator performs offline contract checks and offers a read-only runtime-schema check. It does not submit paid generation work.

Control and adaptation remain model-specific

An SDXL ControlNet cannot be inserted into this Wan graph as a generic motion-control stage. Wan-specific control or VACE paths have their own conditioning and checkpoints. Likewise, a video LoRA must match the model family and task.

Start from the working baseline and introduce one compatible control mechanism at a time. The value of a small, inspectable graph is that failures can be located at the conditioning, sampling, decoding or delivery boundary instead of being hidden in a large editor workflow.