New: Earn 20% as an AgentAlley affiliate. Share your link and earn on every sale you refer. Join now New: Earn 20% as an affiliate. Join now

Extend / continue a video temporally with Pusa 2.2

Video Extension (Pusa 2.2 — temporal flowmatching)

by artokun · MIT license · ★ 759 on GitHub · updated Sep 21

Video Extension (Pusa 2.2 — temporal flowmatching) cover

Extend / continue a video temporally with Pusa 2.2 in ComfyUI. Temporal flowmatching (the flowmatch_pusa scheduler + WanVideoAddPusaNoise) on the WanVideoWrapper stack with WAN 2.2 T2V A14B (HIGH/LOW) models and the Pusa V1 LoRAs,…

---
name: video-extend
description: Extend / continue a video temporally with Pusa 2.2 in ComfyUI. Temporal flowmatching (the flowmatch_pusa scheduler + WanVideoAddPusaNoise) on the WanVideoWrapper stack with WAN 2.2 T2V A14B (HIGH/LOW) models and the Pusa V1 LoRAs, conditioning on the loaded clip via WanVideoEncode so the existing motion carries into the continuation. Covers the kijai wanvideo_2_2_14B_Pusa_extension graph, model/LoRA slots + downloads, noise/length/scheduler settings, chaining multiple extensions, VRAM tiers, gotchas, and the extend→upscale handoff.
globs:
  - "**/*.json"
  - "**/packs/**"
---

# Video Extension (Pusa 2.2 — temporal flowmatching)

## Overview

Pusa extends a video temporally. It continues and lengthens an existing clip
rather than regenerating it from scratch. It does this on the
ComfyUI-WanVideoWrapper stack (kijai) using the WAN 2.2 T2V A14B dual
HIGH/LOW models you already have for `wan-t2v-video`, plus the small Pusa V1
LoRAs and a Pusa-specific sampling path: the `flowmatch_pusa` scheduler and
the `WanVideoAddPusaNoise` node. The input clip is encoded with

Overview

Pusa extends a video temporally. It continues and lengthens an existing clip rather than regenerating it from scratch. It does this on the ComfyUI-WanVideoWrapper stack (kijai) using the WAN 2.2 T2V A14B dual HIGH/LOW models you already have for wan-t2v-video, plus the small Pusa V1 LoRAs and a Pusa-specific sampling path: the flowmatch_pusa scheduler and the WanVideoAddPusaNoise node. The input clip is encoded with WanVideoEncode and injected as the first latents of the generation, which is what carries the existing motion and content into the continuation.

Manual install (npx, ZIP)
Claude Codenpx skills add artokun/comfyui-mcp --skill video-extend -g -a claude-code
Claude Code (manual)mkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/artokun/comfyui-mcp/tar.gz/1d5b12b1b499 \ | tar -xz -C ~/.claude/skills --strip-components=3 comfyui-mcp-1d5b12b1b499/plugin/skills/video-extend
Windows (PowerShell)New-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/c5ca2a0ef4d907c4295b/video-extend.zip" -OutFile "$env:TEMP\video-extend.zip"; Expand-Archive "$env:TEMP\video-extend.zip" -DestinationPath "$HOME\.claude\skills" -Force
Claude.ai / desktopDownload the ZIP and upload it under Settings → Capabilities → Skills.
Codex, Cursor, other agentsPoint them at SKILL.md. The other files are plain text.

Connects with Agent Alley MCP · agentalley.io/mcp

Files included

  • SKILL.md25.5 KB
  • references/1 file · 2.7 KB
Read the files here
artokun/1d5b12b2 files
SKILL.md
Show the full text488 lines

Video Extension (Pusa 2.2 — temporal flowmatching)

Overview

Pusa extends a video temporally. It continues and lengthens an existing clip rather than regenerating it from scratch. It does this on the ComfyUI-WanVideoWrapper stack (kijai) using the WAN 2.2 T2V A14B dual HIGH/LOW models you already have for wan-t2v-video, plus the small Pusa V1 LoRAs and a Pusa-specific sampling path: the flowmatch_pusa scheduler and the WanVideoAddPusaNoise node. The input clip is encoded with WanVideoEncode and injected as the first latents of the generation, which is what carries the existing motion and content into the continuation.

The official reference graph is kijai's wanvideo_2_2_14B_Pusa_extension_example_01.json (in ComfyUI-WanVideoWrapper/example_workflows/). This skill is built directly from that workflow plus the live node schemas.

Relationship to wan-t2v-video: Pusa rides on the exact same WanVideoWrapper stack. Same T2V A14B HIGH/LOW fp8 models, same UMT5 text encoder, same WAN VAE, same block-swap/torch-compile machinery. The only new downloads are the two Pusa V1 LoRAs (~1.9 GB total). Read wan-t2v-video first for the base stack; this skill is the temporal-extension delta on top of it.

Verification note: every node, model, LoRA filename and setting below was confirmed against the live ComfyUI /object_info (WanVideoWrapper installed) and against kijai's example workflow JSON + HF repo (June 2026). Where a value is a starting recommendation rather than a hard requirement it's flagged. Don't substitute a node you can't confirm with install_custom_node (action: "list") / create_workflow (action:"node_info").


What "temporal flowmatching" means here (why it extends, not regenerates)

WAN is a flow-matching video model: sampling integrates a velocity field from noise to a clean latent, and every frame normally shares the same denoising timestep. Pusa's contribution (Vectorized Timestep Adaptation) is to make the timestep per-frame. The frames you already have can be held at (or near) t = 0 (clean) while the new frames start from t = 1 (noise), and the model flow-matches the noisy tail conditioned on the clean head.

Concretely in the graph:

  1. WanVideoEncode turns the tail of your loaded clip into a clean latent.
  2. That latent is placed at the front of an otherwise-empty embed (WanVideoEmptyEmbeds + WanVideoAddExtraLatent), so the generation's first latents ARE your real footage.
  3. WanVideoAddPusaNoise assigns small, ramping per-latent noise multipliers to those conditioning latents (so they stay mostly clean) and full noise to the new latents. This per-frame noise schedule is the "vectorized timestep."
  4. flowmatch_pusa on WanVideoSampler integrates that mixed-timestep field.

Because the conditioning latents are real (not a single start image like I2V), the continuation inherits the existing motion, subject, camera and color, then keeps going. That's the difference from plain T2V (no memory of any clip) and from I2V (conditions on one still frame only).


VHS_LoadVideo (your clip)
      │ IMAGE (all frames)
      ▼
ImageResizeKJv2  ◄── resize to 832×480 (divisible by 16), get W/H
      │
      ├─► GetImageRangeFromBatch (tail N frames) ─► WanVideoEncode (vae, image)
      │                                                   │ LATENT  = clean
      │                                                   ▼   conditioning latents
      │                                          GetLatentSizeAndCount ─► count
      │                                                   │
WanVideoEmptyEmbeds (W,H, total_frames=81)                ▼
      │ WANVIDIMAGE_EMBEDS                       CreateScheduleFloatList
      └────────► WanVideoAddExtraLatent ◄────────┘ (per-latent noise multipliers,
                       │  (encoded clip latent at front)   ramp e.g. 0→0.2)
                       ▼ WANVIDIMAGE_EMBEDS
              WanVideoAddPusaNoise  ◄── noise_multipliers (list), noisy_steps
                       │
        ┌──────────────┴───────────────┐
        ▼ (pass 1, HIGH)               ▼ (pass 2, LOW)
 WanVideoSampler (HIGH model           WanVideoSampler (LOW model
   + Pusa HIGH LoRA + distill,           + Pusa LOW LoRA + distill,
   flowmatch_pusa, steps 6, cfg 1,       flowmatch_pusa, steps 6, cfg 1,
   shift 5, start 0 / end 3)             shift 5, start 3 / end -1)
        └──────────────┬───────────────┘
                       ▼ LATENT
                 WanVideoDecode (WAN VAE)
                       │ IMAGE
                       ▼
                 VHS_VideoCombine  ─► MP4 (16 fps)
  • VHS_LoadVideo / VHS_VideoCombine come from ComfyUI-VideoHelperSuite (installed). VHS_VideoCombine is preferred for the encode (audio passthrough).
  • Everything WanVideo* is ComfyUI-WanVideoWrapper (installed).
  • ImageResizeKJv2, GetImageRangeFromBatch, GetLatentSizeAndCount, CreateScheduleFloatList are ComfyUI-KJNodes (installed alongside the wrapper). They're convenience nodes; see "Minimal wiring" if you want fewer.
The two load-bearing nodes (confirmed schemas)

WanVideoAddPusaNoise: "Adds latent and timestep noise multipliers when using flowmatch_pusa."

Input Type Meaning
embeds WANVIDIMAGE_EMBEDS the embeds carrying your encoded clip latents
noise_multipliers FLOAT (list) per-input-latent noise; 0 = keep that latent fully clean, higher = let the model change it. In the example this is a ramp [0.0, 0.07, 0.13, 0.17, 0.19, 0.2] fed from CreateScheduleFloatList (one value per conditioning latent), so the oldest conditioning frame stays cleanest and the seam frame gets a touch of noise for smooth blending.
noisy_steps INT (default −1) how many sampling steps the extra noise is applied for; the example uses 0 on the HIGH pass and 2 on the LOW pass. −1 = all steps.

It outputs WANVIDIMAGE_EMBEDS straight into WanVideoSampler's image_embeds.

flowmatch_pusa is a value in WanVideoSampler.scheduler (confirmed present in the dropdown: ...flowmatch_distill, flowmatch_pusa, multitalk...). It must be selected on the sampler(s) for the Pusa noise schedule to be interpreted correctly. The example also wires explicit WanVideoScheduler nodes set to flowmatch_pusa, steps 6, shift 5 (one per pass, split 0 to 3 and 3 to end).

How the input clip conditions the extension (the key wire)

WanVideoEncode(vae, image=<tail frames of clip>) → LATENT → WanVideoAddExtraLatent (or WanVideoEmptyEmbeds.extra_latents, tooltip: "First latent to use for the Pusa -model"). This places the real clip's latents at the head of the embed window. The sampler then only has to generate the tail, flow-matched onto that clean head. That is the entire trick. No CLIPVision, no WanFirstLastFrameToVideo.


In practice: load → strip → re-point (DON'T hand-build) ⭐ preferred

The kijai wanvideo_2_2_14B_Pusa_extension_example_01.json is a 56-node graph thick with GetNode/SetNode buses, Reroutes, and an alternate (dead) text branch. Hand-wiring the Pusa noise / extra-latent / frame-stitch path is slow and error-prone. The reliable flow is to load the real graph, then adapt ~7 widgets:

  1. Stage the example anywhere on disk (e.g. copy into the ComfyUI workflows folder).
  2. panel_load_workflow(path: …) drops it on the canvas server-side (no 150KB JSON through chat).
  3. panel_strip_workflow(path: …) returns the resolved API graph (Get/Set/Reroute/bypass collapsed to real links). This is how you SEE what is actually wired. It exposes both the dead text branch and the silently-reset dropdowns below. (Raw UI JSON hides them.)
⚠️ TRAP 1 — the example's model paths reset to the WRONG file on load

The example references models by subfolder (WanVideo\2_2\…, WanVideo\Lightx2v\…, wanvideo\Wan2_1_VAE_bf16…). On a flat local models/ layout those don't resolve, so ComfyUI silently falls each dropdown back to the first entry in the list. E.g. both WanVideoModelLoaders land on Qwen_Image_Edit-Q8_0.gguf and the WanVideoVAELoader on LTX23_audio_vae_bf16. It looks wired but errors (wrong arch) or renders garbage. After loading, set each explicitly:

Node Set to (local)
WanVideoModelLoader HIGH Wan2_2-T2V-A14B_HIGH_fp8_e4m3fn_scaled_KJ.safetensors — note underscore before HIGH
WanVideoModelLoader LOW Wan2_2-T2V-A14B-LOW_fp8_e4m3fn_scaled_KJ.safetensors — note dash before LOW
WanVideoVAELoader wan_2.1_vae.safetensors
WanVideoLoraSelectMulti ×2, slot lora_0 Pusa HIGH/LOW — these DO resolve if you downloaded to loras/WanVideo/Pusa/
WanVideoLoraSelectMulti ×2, slot lora_1 lightx2v_T2V_14B_cfg_step_distill_v2_lora_rank128_bf16.safetensors @ 1.0
VHS_LoadVideo your clip
WanVideoTextEncodeCached positive_prompt your continuation prompt

The official HIGH-underscore / LOW-dash filename inconsistency is a real trap. Verify each one rather than copy-pasting.

⚠️ TRAP 2 — the distill LoRA silently drops to none

The example's lightx2v path is WanVideo\Lightx2v\…rank64_bf16_.safetensors (note the trailing _). Locally you usually have rank128 (…rank128_bf16), so the slot resets to none on load, which removes the speed LoRA, and 6-step / cfg-1 sampling then produces mush. Re-add it to lora_1 (strength 1.0) on BOTH WanVideoLoraSelectMulti nodes. Keep merge_loras=false on both (fp8 gotcha above).

⚠️ TRAP 3 — the active prompt is on WanVideoTextEncodeCached, not CLIPTextEncode

The example also contains a CLIPLoader → CLIPTextEncode → WanVideoTextEmbedBridge branch (the "red panda" prompt). It is NOT wired to the samplers. Both WanVideoSampler.text_embeds come from WanVideoTextEncodeCached (umt5-xxl-enc-bf16). Edit the prompt THERE; the CLIPTextEncode pair is a decoy that get_workflow (action:"strip") will show dangling.

⚠️ TRAP 4 — match the conditioning fps to WAN-native (16)

If your source clip was frame-interpolated (e.g. RIFE'd to 32/50 fps), set VHS_LoadVideo.force_rate = 16 so the conditioning frames carry motion at WAN's native cadence. Otherwise the encoded "past" runs at 2 to 3× the model's pace and you get a velocity jump at the seam, the exact artifact Pusa exists to avoid. Best practice: extend the pre-interpolation 16fps master, then interpolate/upscale the combined result afterwards, not before.

⚠️ TRAP 5 — the example assumes SageAttention + torch.compile (triton)

WanVideoModelLoader in the example sets attention_mode: sageattn and wires a WanVideoTorchCompileSettings (inductor) into compile_args. Both are optional accelerators with extra deps that a stock Windows ComfyUI usually lacks:

  • sageattn needs the sageattention package. Missing means the model loader hard-fails with ValueError: Can't import SageAttention: No module named 'sageattention' before any sampling. Fix: set attention_mode to sdpa on BOTH WanVideoModelLoaders (always available; a bit slower).
  • inductor torch.compile needs triton (no official Windows build). Missing means compile errors later. Fix: disconnect WanVideoTorchCompileSettings from each model loader's compile_args (or don't load it). Only re-enable these two if you've actually installed sageattention / triton-windows.

Check first with the ComfyUI startup log (it prints Could not load sageattention… and triton: unavailable) or install_custom_node (action: "list").

Preferred end-to-end order

Generate (or Krea2→WAN/LTX i2v), then Pusa-extend at 832×480/16fps, THEN upscale+interpolate (hand the extended clip to the video-upscale block / a saved Upscale4x-RIFE-1080p subgraph). Upscaling or interpolating before extending wastes the work and feeds Pusa an off-cadence, harder-to-match conditioning clip.


Models, LoRAs & where to get them

UNET — WAN 2.2 T2V A14B (already installed for wan-t2v-video)
Model Loader Notes
Wan2_2-T2V-A14B-HIGH_fp8_e4m3fn_scaled_KJ.safetensors WanVideoModelLoader HighNoise expert, fp8. Quantization fp8_e4m3fn_scaled.
Wan2_2-T2V-A14B-LOW_fp8_e4m3fn_scaled_KJ.safetensors WanVideoModelLoader LowNoise expert, fp8.

Text encoder + VAE: same as wan-t2v-video. UMT5 (umt5_xxl_fp8_e4m3fn_scaled / umt5_xxl_fp16) via the wrapper's text-embed path, and the WAN VAE (wan_2.1_vae) via WanVideoVAELoader. The example uses WanVideoTinyVAELoader + taew2_1.safetensors for fast preview decode; use the full WAN VAE for final-quality decode.

Pusa V1 LoRAs — the ONLY new download (~1.9 GB)

From kijai's HF repo Kijai/WanVideo_comfy, folder Pusa/. Place in models/loras/ (the example expects them under loras/WanVideo/Pusa/):

LoRA file ~Size Applies to Strength (example)
Wan22_PusaV1_lora_HIGH_resized_dynamic_avg_rank_98_bf16.safetensors ~956 MB HIGH T2V model 1.5
Wan22_PusaV1_lora_LOW_resized_dynamic_avg_rank_98_bf16.safetensors ~968 MB LOW T2V model 1.4

There is also a single-file Wan21_PusaV1_LoRA_14B_rank512_bf16.safetensors (~4.9 GB) in the same folder. That's the Wan 2.1 single-model Pusa LoRA. For the 2.2 dual HIGH/LOW extension graph, use the two Wan22_...rank_98 files above, matched to the correct expert. Upstream weights / paper: RaphaelLiu/PusaV1 on HF.

Speed LoRA (paired with Pusa in the example)

The example also stacks the lightx2v T2V distill LoRA on each model via WanVideoLoraSelectMulti, so 6-step low-CFG sampling works:

LoRA Strength From
lightx2v_T2V_14B_cfg_step_distill_v2_lora_rank64_bf16_.safetensors 1.0 Kijai/WanVideo_comfy/Lightx2v/

LoRAs are selected with WanVideoLoraSelectMulti (multi-slot) and fed into each WanVideoModelLoader's lora input. One select feeds HIGH (Pusa HIGH + distill), one feeds LOW (Pusa LOW + distill).

⚠️ CRITICAL — merge_loras=false on fp8 models (same gotcha as wan-t2v-video)

Pusa loads LoRAs onto the fp8-quantized T2V A14B models (quantization=fp8_e4m3fn_scaled). As documented in wan-t2v-video: when a LoRA is applied to an fp8 model via the wrapper's LoRA select, set merge_loras to false. The default merge_loras=true tries to bake the LoRA into the already-quantized fp8 weights and hard-crashes ComfyUI during LoRA loading with no Python traceback (looks like an unexplained restart/OOM). false applies the LoRA as a runtime patch, which is fp8-safe. This applies to BOTH the Pusa LoRAs and the lightx2v distill LoRA. Use merge_loras=true only on non-quantized bf16/fp16 models.


Settings

Sampler (from the example — distilled 6-step, two-pass HIGH→LOW)
Param HIGH pass LOW pass Notes
model HIGH + Pusa HIGH (1.5) + distill (1.0) LOW + Pusa LOW (1.4) + distill (1.0)
scheduler flowmatch_pusa flowmatch_pusa required for Pusa
steps 6 6 distilled; raise to ~20–30 for the non-distill path
cfg 1.0 1.0 distilled low-CFG; ~5–6 without distill
shift 5.0 5.0 flow-matching shift
start_step / end_step 0 / 3 3 / −1 HIGH does early steps, LOW finishes
noisy_steps (on AddPusaNoise) 0 2 extra-noise duration per pass

If you drop the distill LoRA: use steps ~20 to 30, cfg ~5 to 6, keep flowmatch_pusa and shift 5, single-pass unipc-style splitting still works HIGH→LOW.

Pusa noise (WanVideoAddPusaNoise.noise_multipliers)

This is the dial that controls how strictly the continuation honors the input clip vs. how free it is to diverge:

  • Lower multipliers (toward 0) = conditioning latents stay clean = the continuation clings tightly to the source frames (less drift, but can look "stuck" or repeat).
  • Higher multipliers = more noise on the conditioning latents = the model is freer to evolve the scene (more new motion, more drift risk).
  • The example ramps them [0.0 … 0.2] across the conditioning latents (one per encoded latent, via CreateScheduleFloatList driven by GetLatentSizeAndCount) so the oldest frame is locked and the seam frame gets a little noise for a smooth blend. Start there; nudge the top of the ramp up (~0.3) if continuations feel frozen, down if they drift.
Seam color/saturation drift → ColorMatch the generated frames ⭐

The most common quality complaint with a Pusa extension: the moment you cross the seam, the color saturates or shifts. The conditioning frames are your real footage (near-clean latents), but the generated tail comes purely from the model's prior, which biases toward higher contrast and saturation (worse with the distill LoRA and fp16_fast). Motion carries fine; the palette pops.

Two fixes, best applied together:

  1. base_precision: bf16 on both WanVideoModelLoaders instead of fp16_fast. fp16_fast's reduced precision drifts over the generated tail and compounds the saturation; bf16 is more color-stable (small speed cost).

  2. Re-grade the generated frames to the source palette with a ColorMatchV2 (KJNodes) between WanVideoDecode and the final stitch/save:

    • image_target ← WanVideoDecode (the generated window)
    • image_ref ← the resized original clip (ImageResizeKJv2 output, your real footage)
    • method: hm-mkl-hm (histogram→MKL→histogram; strongest at removing a palette jump while keeping per-frame variation), strength 1.0.
    • Re-route the downstream consumers (ImageBatchMulti / ImageConcatMulti's image_1) to take the ColorMatch output instead of the raw decode.

    Tune: if under-corrected, raise strength; if washed or over-corrected, drop to ~0.6; for an even tighter temporal lock use a single clean reference frame (the last conditioning frame) instead of the whole clip. Use ColorMatchV2 (not the deprecated ColorMatch).

This also matters for chaining. Color-match every new segment to the previous one before concat or the drift compounds hop-to-hop.

Length, frame counts & fps
  • WanVideoEmptyEmbeds.num_frames is the total window (conditioning frames + new frames). The example uses 81 total (the WAN-native 4n+1 length, ~5 s @16 fps).
  • The number of new frames added = total − conditioning frames. With ~13 tail frames conditioned and 81 total, you add ~68 new frames (~4 s) per pass.
  • num_frames step is 4 in the node; keep total on the WAN 4n+1 grid (49 / 81 / 121 …). frame_rate for output is 16 fps (WAN 2.2 native).
  • Resolution: 832×480 default (divisible by 16). ImageResizeKJv2 with crop/center and divisor 16 keeps the loaded clip on-grid.

Chaining multiple extensions

Making a long video by repeating the extension is in references/chaining.md.

VRAM tiers

Same envelope as wan-t2v-video (dual A14B fp8 + UMT5); Pusa adds only ~1.9 GB of LoRA. Use the wrapper's offload tooling.

VRAM Setup
24 GB+ Dual fp8 A14B + Pusa LoRAs + distill. WanVideoBlockSwap (offload some blocks) for headroom; WanVideoTorchCompileSettings (inductor) for speed; sageattn. 81 frames @832×480 fits.
12–16 GB More aggressive WanVideoBlockSwap; enable VAE tiling on WanVideoEncode (enable_vae_tiling=true, 272/144 tiles) and on WanVideoDecode; drop total frames to 49; consider single-pass.
8 GB Tight — heavy block swap + tiled VAE + 49 frames + tiny VAE preview decode. Expect slow.
  • WanVideoModelLoader quant fp8_e4m3fn_scaled, base precision fp16_fast, offload_device, sageattn (the example's settings).
  • Always clear_vram before switching to this from another model family.
  • Encoder VAE tiling (WanVideoEncode) matters here because you're VAE-encoding real footage in addition to decoding output.

Gotchas

  • Loading the example silently resets model/VAE/distill-LoRA dropdowns to the wrong first entry (subfolder paths don't resolve on a flat layout). This is the #1 cause of a Pusa run that errors or generates wrong content. See "In practice: load → strip → re-point" and re-point ALL of them. Use get_workflow (action:"strip") to spot it.
  • The prompt lives on WanVideoTextEncodeCached, not the CLIPTextEncode "decoy" branch (which isn't wired to the samplers).
  • Interpolated source → seam speed jump. Set VHS_LoadVideo.force_rate = 16, or condition on the pre-interpolation 16 fps master.
  • sageattn / torch.compile errors. The example assumes SageAttention + triton. On a box without them, set attention_mode=sdpa and disconnect WanVideoTorchCompileSettings from both model loaders (TRAP 5).
  • Saturation/color pop after the seam. Re-grade the generated frames with a ColorMatchV2 (hm-mkl-hm) referencing the source clip, and use bf16 not fp16_fast (see "Seam color/saturation drift").
  • Scheduler must be flowmatch_pusa. Leaving it on unipc/euler ignores the Pusa per-latent noise schedule, so the conditioning latents don't behave as clean anchors and you get a hard cut / regeneration instead of a smooth continuation.
  • merge_loras=false on fp8 (see CRITICAL above) applies to the Pusa AND distill LoRAs; default true kills the process with no traceback.
  • Match Pusa LoRA to expert: ...HIGH... → HIGH model, ...LOW... → LOW model. Crossing them degrades quality. Don't substitute the Wan 2.1 single-file rank512 LoRA into the 2.2 dual graph.
  • Frame-count grid: keep num_frames on 4n+1 (49/81/121). Off-grid totals can error or pad oddly. num_frames UI step is 4.
  • Motion drift / "frozen" continuation: tune noise_multipliers. Too low = stuck/looping; too high = subject/scene wanders. The 0→0.2 ramp is the safe middle.
  • Color/exposure drift across chained hops is the most common long-video artifact. Mitigate: modest noise, restate the prompt, and optionally color-match each new segment to the previous before concat.
  • Audio: WAN/Pusa generate silent video. The original clip's audio is not extended. Re-attach/curate audio at the end with VHS_VideoCombine (pass the source audio through) or in an editor, and note the new section has no native sound.
  • ffmpeg required for the final mux (same as the other video skills): if VHS_VideoCombine errors ffmpeg ... could not be found, run <comfy-venv>/python -m pip install imageio-ffmpeg and reboot.
  • Preview vs final VAE: taew2_1 (TinyVAE) is for fast preview decode; decode the final with the full WAN VAE for quality.

Minimal wiring (if you want fewer KJNodes)

The KJNodes (GetImageRangeFromBatch, GetLatentSizeAndCount, CreateScheduleFloatList, ImageResizeKJv2) are conveniences. The irreducible chain is:

load clip → (resize to 16-grid) → WanVideoEncode(vae, tail frames) → LATENT
WanVideoEmptyEmbeds(W,H,total) [extra_latents = that LATENT]  → embeds
embeds → WanVideoAddPusaNoise(noise_multipliers, noisy_steps) → embeds
WanVideoSampler(model+Pusa LoRA, embeds, scheduler=flowmatch_pusa, shift 5) → LATENT
WanVideoDecode(WAN VAE) → VHS_VideoCombine

You can hand a constant list to noise_multipliers instead of building a ramp; the ramp smooths the seam. Two-pass HIGH→LOW is recommended (matches WAN 2.2's MoE) but a single LOW-model pass works for quick tests.


See also

  • wan-t2v-video. The base WAN 2.2 T2V stack this builds on (model/encoder/ VAE loading, the merge_loras=false fp8 gotcha in full, block-swap/VRAM). Read it first.
  • video-upscale. The natural next step: extend, then upscale. Generate / extend at 832×480, then run the result through the downscale → SeedVR2 (temporal restore+upscale) → RIFE → VHS encode pipeline for a clean, higher-res, higher-fps final. Do the extension first, upscale last (upscaling then extending wastes the restorer's work and risks re-drift).
  • ltxv2-video. An alternative video family with its own extender variant; Pusa/WAN is the path when you want to continue an existing WAN-style clip.

Packs

No dedicated video-extend installer pack ships yet. Since Pusa reuses the installed WanVideoWrapper + KJNodes + VideoHelperSuite stack, a pack only needs to list those custom_nodes[] (kijai/ComfyUI-WanVideoWrapper, Kijai/ComfyUI-KJNodes, Kosinkadink/ComfyUI-VideoHelperSuite) plus the two Pusa V1 LoRAs in models[] (from Kijai/WanVideo_comfy/Pusa/). The big T2V A14B models are shared with wan-t2v-video; don't re-download. Install nodes ad-hoc with panel_install_node or apply a manifest with apply_manifest. Contribute a finished pack upstream (github.com/artokun/comfyui-mcp).

Sources

  • Official: none found.
  • Empirical: sampler values, wiring, and prompt notes from working graphs in packs/ and observed renders; not a vendor prompting guide.
1---
2name: video-extend
3description: Extend / continue a video temporally with Pusa 2.2 in ComfyUI. Temporal flowmatching (the flowmatch_pusa scheduler + WanVideoAddPusaNoise) on the WanVideoWrapper stack with WAN 2.2 T2V A14B (HIGH/LOW) models and the Pusa V1 LoRAs, conditioning on the loaded clip via WanVideoEncode so the existing motion carries into the continuation. Covers the kijai wanvideo_2_2_14B_Pusa_extension graph, model/LoRA slots + downloads, noise/length/scheduler settings, chaining multiple extensions, VRAM tiers, gotchas, and the extend→upscale handoff.
4globs:
5 - "**/*.json"
6 - "**/packs/**"
7---
8 
9# Video Extension (Pusa 2.2 — temporal flowmatching)
10 
11## Overview
12 
13Pusa extends a video temporally. It continues and lengthens an existing clip
14rather than regenerating it from scratch. It does this on the
15ComfyUI-WanVideoWrapper stack (kijai) using the WAN 2.2 T2V A14B dual
16HIGH/LOW models you already have for `wan-t2v-video`, plus the small Pusa V1
17LoRAs and a Pusa-specific sampling path: the `flowmatch_pusa` scheduler and
18the `WanVideoAddPusaNoise` node. The input clip is encoded with
19`WanVideoEncode` and injected as the first latents of the generation, which
20is what carries the existing motion and content into the continuation.
21 
22The official reference graph is kijai's
23`wanvideo_2_2_14B_Pusa_extension_example_01.json` (in
24`ComfyUI-WanVideoWrapper/example_workflows/`). This skill is built directly from
25that workflow plus the live node schemas.
26 
27> Relationship to `wan-t2v-video`: Pusa rides on the exact same WanVideoWrapper
28> stack. Same T2V A14B HIGH/LOW fp8 models, same UMT5 text encoder, same WAN
29> VAE, same block-swap/torch-compile machinery. The only new downloads are the
30> two Pusa V1 LoRAs (~1.9 GB total). Read `wan-t2v-video` first for the base
31> stack; this skill is the temporal-extension delta on top of it.
32 
33> Verification note: every node, model, LoRA filename and setting below was
34> confirmed against the live ComfyUI `/object_info` (WanVideoWrapper installed)
35> and against kijai's example workflow JSON + HF repo (June 2026). Where a value
36> is a starting recommendation rather than a hard requirement it's flagged. Don't
37> substitute a node you can't confirm with `install_custom_node` (`action: "list"`) /
38> `create_workflow (action:"node_info")`.
39 
40---
41 
42## What "temporal flowmatching" means here (why it extends, not regenerates)
43 
44WAN is a flow-matching video model: sampling integrates a velocity field from
45noise to a clean latent, and every frame normally shares the same denoising
46timestep. Pusa's contribution (Vectorized Timestep Adaptation) is to make the
47timestep per-frame. The frames you already have can be held at (or near)
48*t = 0 (clean)* while the new frames start from *t = 1 (noise)*, and the model
49flow-matches the noisy tail conditioned on the clean head.
50 
51Concretely in the graph:
52 
531. `WanVideoEncode` turns the tail of your loaded clip into a clean latent.
542. That latent is placed at the front of an otherwise-empty embed
55 (`WanVideoEmptyEmbeds` + `WanVideoAddExtraLatent`), so the generation's first
56 latents ARE your real footage.
573. `WanVideoAddPusaNoise` assigns small, ramping per-latent noise
58 multipliers to those conditioning latents (so they stay mostly clean) and
59 full noise to the new latents. This per-frame noise schedule is the
60 "vectorized timestep."
614. `flowmatch_pusa` on `WanVideoSampler` integrates that mixed-timestep field.
62 
63Because the conditioning latents are real (not a single start image like
64I2V), the continuation inherits the existing motion, subject, camera and
65color, then keeps going. That's the difference from plain T2V (no memory of any
66clip) and from I2V (conditions on one still frame only).
67 
68---
69 
70## ⭐ Recommended pipeline (the kijai extension graph)
71 
72```
73VHS_LoadVideo (your clip)
74 │ IMAGE (all frames)
75 ▼
76ImageResizeKJv2 ◄── resize to 832×480 (divisible by 16), get W/H
77 │
78 ├─► GetImageRangeFromBatch (tail N frames) ─► WanVideoEncode (vae, image)
79 │ │ LATENT = clean
80 │ ▼ conditioning latents
81 │ GetLatentSizeAndCount ─► count
82 │ │
83WanVideoEmptyEmbeds (W,H, total_frames=81) ▼
84 │ WANVIDIMAGE_EMBEDS CreateScheduleFloatList
85 └────────► WanVideoAddExtraLatent ◄────────┘ (per-latent noise multipliers,
86 │ (encoded clip latent at front) ramp e.g. 0→0.2)
87 ▼ WANVIDIMAGE_EMBEDS
88 WanVideoAddPusaNoise ◄── noise_multipliers (list), noisy_steps
89 │
90 ┌──────────────┴───────────────┐
91 ▼ (pass 1, HIGH) ▼ (pass 2, LOW)
92 WanVideoSampler (HIGH model WanVideoSampler (LOW model
93 + Pusa HIGH LoRA + distill, + Pusa LOW LoRA + distill,
94 flowmatch_pusa, steps 6, cfg 1, flowmatch_pusa, steps 6, cfg 1,
95 shift 5, start 0 / end 3) shift 5, start 3 / end -1)
96 └──────────────┬───────────────┘
97 ▼ LATENT
98 WanVideoDecode (WAN VAE)
99 │ IMAGE
100 ▼
101 VHS_VideoCombine ─► MP4 (16 fps)
102```
103 
104- `VHS_LoadVideo` / `VHS_VideoCombine` come from ComfyUI-VideoHelperSuite
105 (installed). `VHS_VideoCombine` is preferred for the encode (audio passthrough).
106- Everything `WanVideo*` is ComfyUI-WanVideoWrapper (installed).
107- `ImageResizeKJv2`, `GetImageRangeFromBatch`, `GetLatentSizeAndCount`,
108 `CreateScheduleFloatList` are ComfyUI-KJNodes (installed alongside the
109 wrapper). They're convenience nodes; see "Minimal wiring" if you want fewer.
110 
111### The two load-bearing nodes (confirmed schemas)
112 
113`WanVideoAddPusaNoise`: *"Adds latent and timestep noise multipliers when
114using flowmatch_pusa."*
115 
116| Input | Type | Meaning |
117|---|---|---|
118| `embeds` | `WANVIDIMAGE_EMBEDS` | the embeds carrying your encoded clip latents |
119| `noise_multipliers` | `FLOAT` (list) | per-input-latent noise; **0 = keep that latent fully clean**, higher = let the model change it. In the example this is a **ramp** `[0.0, 0.07, 0.13, 0.17, 0.19, 0.2]` fed from `CreateScheduleFloatList` (one value per conditioning latent), so the oldest conditioning frame stays cleanest and the seam frame gets a touch of noise for smooth blending. |
120| `noisy_steps` | `INT` (default −1) | how many sampling steps the extra noise is applied for; the example uses **0 on the HIGH pass and 2 on the LOW pass**. −1 = all steps. |
121 
122It outputs `WANVIDIMAGE_EMBEDS` straight into `WanVideoSampler`'s `image_embeds`.
123 
124`flowmatch_pusa` is a value in `WanVideoSampler.scheduler` (confirmed present
125in the dropdown: `...flowmatch_distill, flowmatch_pusa, multitalk...`). It must
126be selected on the sampler(s) for the Pusa noise schedule to be interpreted
127correctly. The example also wires explicit `WanVideoScheduler` nodes set to
128`flowmatch_pusa`, steps 6, shift 5 (one per pass, split 0 to 3 and 3 to end).
129 
130### How the input clip conditions the extension (the key wire)
131 
132`WanVideoEncode(vae, image=<tail frames of clip>) → LATENT` →
133`WanVideoAddExtraLatent` (or `WanVideoEmptyEmbeds.extra_latents`, tooltip:
134"First latent to use for the Pusa -model"). This places the real clip's
135latents at the head of the embed window. The sampler then only has to generate
136the tail, flow-matched onto that clean head. That is the entire trick. No
137`CLIPVision`, no `WanFirstLastFrameToVideo`.
138 
139---
140 
141## In practice: load → strip → re-point (DON'T hand-build) ⭐ preferred
142 
143The kijai `wanvideo_2_2_14B_Pusa_extension_example_01.json` is a 56-node graph
144thick with `GetNode`/`SetNode` buses, `Reroute`s, and an alternate (dead) text
145branch. Hand-wiring the Pusa noise / extra-latent / frame-stitch path is slow and
146error-prone. The reliable flow is to load the real graph, then adapt ~7 widgets:
147 
1481. Stage the example anywhere on disk (e.g. copy into the ComfyUI workflows
149 folder).
1502. `panel_load_workflow(path: …)` drops it on the canvas server-side (no
151 150KB JSON through chat).
1523. `panel_strip_workflow(path: …)` returns the resolved API graph
153 (Get/Set/Reroute/bypass collapsed to real links). This is how you SEE what is
154 actually wired. It exposes both the dead text branch and the silently-reset
155 dropdowns below. (Raw UI JSON hides them.)
156 
157### ⚠️ TRAP 1 — the example's model paths reset to the WRONG file on load
158 
159The example references models by subfolder (`WanVideo\2_2\…`,
160`WanVideo\Lightx2v\…`, `wanvideo\Wan2_1_VAE_bf16…`). On a flat local `models/`
161layout those don't resolve, so ComfyUI silently falls each dropdown back to the
162first entry in the list. E.g. both `WanVideoModelLoader`s land on
163`Qwen_Image_Edit-Q8_0.gguf` and the `WanVideoVAELoader` on `LTX23_audio_vae_bf16`.
164It looks wired but errors (wrong arch) or renders garbage. After loading, set
165each explicitly:
166 
167| Node | Set to (local) |
168|---|---|
169| `WanVideoModelLoader` **HIGH** | `Wan2_2-T2V-A14B_HIGH_fp8_e4m3fn_scaled_KJ.safetensors` — note **underscore** before HIGH |
170| `WanVideoModelLoader` **LOW** | `Wan2_2-T2V-A14B-LOW_fp8_e4m3fn_scaled_KJ.safetensors` — note **dash** before LOW |
171| `WanVideoVAELoader` | `wan_2.1_vae.safetensors` |
172| `WanVideoLoraSelectMulti` ×2, slot `lora_0` | Pusa HIGH/LOW — these DO resolve if you downloaded to `loras/WanVideo/Pusa/` |
173| `WanVideoLoraSelectMulti` ×2, slot `lora_1` | `lightx2v_T2V_14B_cfg_step_distill_v2_lora_rank128_bf16.safetensors` @ 1.0 |
174| `VHS_LoadVideo` | your clip |
175| `WanVideoTextEncodeCached` `positive_prompt` | your continuation prompt |
176 
177> The official HIGH-underscore / LOW-dash filename inconsistency is a real
178> trap. Verify each one rather than copy-pasting.
179 
180### ⚠️ TRAP 2 — the distill LoRA silently drops to `none`
181 
182The example's lightx2v path is `WanVideo\Lightx2v\…rank64_bf16_.safetensors` (note
183the trailing `_`). Locally you usually have rank128 (`…rank128_bf16`), so the
184slot resets to `none` on load, which removes the speed LoRA, and 6-step /
185cfg-1 sampling then produces mush. Re-add it to `lora_1` (strength 1.0) on BOTH
186`WanVideoLoraSelectMulti` nodes. Keep `merge_loras=false` on both (fp8 gotcha
187above).
188 
189### ⚠️ TRAP 3 — the active prompt is on `WanVideoTextEncodeCached`, not CLIPTextEncode
190 
191The example also contains a `CLIPLoader → CLIPTextEncode → WanVideoTextEmbedBridge`
192branch (the "red panda" prompt). It is NOT wired to the samplers. Both
193`WanVideoSampler.text_embeds` come from `WanVideoTextEncodeCached`
194(`umt5-xxl-enc-bf16`). Edit the prompt THERE; the CLIPTextEncode pair is a decoy
195that get_workflow (action:"strip") will show dangling.
196 
197### ⚠️ TRAP 4 — match the conditioning fps to WAN-native (16)
198 
199If your source clip was frame-interpolated (e.g. RIFE'd to 32/50 fps), set
200`VHS_LoadVideo.force_rate = 16` so the conditioning frames carry motion at
201WAN's native cadence. Otherwise the encoded "past" runs at 2 to 3× the model's
202pace and you get a velocity jump at the seam, the exact artifact Pusa exists to
203avoid. Best practice: extend the pre-interpolation 16fps master, then
204interpolate/upscale the combined result afterwards, not before.
205 
206### ⚠️ TRAP 5 — the example assumes SageAttention + torch.compile (triton)
207 
208`WanVideoModelLoader` in the example sets `attention_mode: sageattn` and wires
209a `WanVideoTorchCompileSettings` (inductor) into `compile_args`. Both are
210optional accelerators with extra deps that a stock Windows ComfyUI usually lacks:
211 
212- `sageattn` needs the `sageattention` package. Missing means the model loader
213 hard-fails with `ValueError: Can't import SageAttention: No module named
214 'sageattention'` before any sampling. Fix: set `attention_mode` to `sdpa`
215 on BOTH `WanVideoModelLoader`s (always available; a bit slower).
216- inductor `torch.compile` needs triton (no official Windows build).
217 Missing means compile errors later. Fix: disconnect `WanVideoTorchCompileSettings`
218 from each model loader's `compile_args` (or don't load it). Only re-enable
219 these two if you've actually installed sageattention / triton-windows.
220 
221Check first with the ComfyUI startup log (it prints `Could not load
222sageattention…` and `triton: unavailable`) or `install_custom_node` (`action: "list"`).
223 
224### Preferred end-to-end order
225 
226Generate (or Krea2→WAN/LTX i2v), then Pusa-extend at 832×480/16fps, THEN
227upscale+interpolate (hand the extended clip to the `video-upscale` block / a
228saved `Upscale4x-RIFE-1080p` subgraph). Upscaling or interpolating before
229extending wastes the work and feeds Pusa an off-cadence, harder-to-match
230conditioning clip.
231 
232---
233 
234## Models, LoRAs & where to get them
235 
236### UNET — WAN 2.2 T2V A14B (already installed for `wan-t2v-video`)
237 
238| Model | Loader | Notes |
239|---|---|---|
240| `Wan2_2-T2V-A14B-HIGH_fp8_e4m3fn_scaled_KJ.safetensors` | `WanVideoModelLoader` | HighNoise expert, fp8. Quantization `fp8_e4m3fn_scaled`. |
241| `Wan2_2-T2V-A14B-LOW_fp8_e4m3fn_scaled_KJ.safetensors` | `WanVideoModelLoader` | LowNoise expert, fp8. |
242 
243Text encoder + VAE: same as `wan-t2v-video`. UMT5
244(`umt5_xxl_fp8_e4m3fn_scaled` / `umt5_xxl_fp16`) via the wrapper's text-embed
245path, and the WAN VAE (`wan_2.1_vae`) via `WanVideoVAELoader`. The example uses
246`WanVideoTinyVAELoader` + `taew2_1.safetensors` for fast preview decode; use
247the full WAN VAE for final-quality decode.
248 
249### Pusa V1 LoRAs — the ONLY new download (~1.9 GB)
250 
251From kijai's HF repo `Kijai/WanVideo_comfy`, folder `Pusa/`. Place in
252`models/loras/` (the example expects them under `loras/WanVideo/Pusa/`):
253 
254| LoRA file | ~Size | Applies to | Strength (example) |
255|---|---|---|---|
256| `Wan22_PusaV1_lora_HIGH_resized_dynamic_avg_rank_98_bf16.safetensors` | ~956 MB | **HIGH** T2V model | **1.5** |
257| `Wan22_PusaV1_lora_LOW_resized_dynamic_avg_rank_98_bf16.safetensors` | ~968 MB | **LOW** T2V model | **1.4** |
258 
259> There is also a single-file `Wan21_PusaV1_LoRA_14B_rank512_bf16.safetensors`
260> (~4.9 GB) in the same folder. That's the Wan 2.1 single-model Pusa LoRA.
261> For the 2.2 dual HIGH/LOW extension graph, use the two `Wan22_...rank_98`
262> files above, matched to the correct expert. Upstream weights / paper:
263> `RaphaelLiu/PusaV1` on HF.
264 
265### Speed LoRA (paired with Pusa in the example)
266 
267The example also stacks the lightx2v T2V distill LoRA on each model via
268`WanVideoLoraSelectMulti`, so 6-step low-CFG sampling works:
269 
270| LoRA | Strength | From |
271|---|---|---|
272| `lightx2v_T2V_14B_cfg_step_distill_v2_lora_rank64_bf16_.safetensors` | 1.0 | `Kijai/WanVideo_comfy/Lightx2v/` |
273 
274LoRAs are selected with `WanVideoLoraSelectMulti` (multi-slot) and fed into
275each `WanVideoModelLoader`'s `lora` input. One select feeds HIGH (Pusa HIGH +
276distill), one feeds LOW (Pusa LOW + distill).
277 
278### ⚠️ CRITICAL — `merge_loras=false` on fp8 models (same gotcha as `wan-t2v-video`)
279 
280Pusa loads LoRAs onto the fp8-quantized T2V A14B models
281(`quantization=fp8_e4m3fn_scaled`). As documented in `wan-t2v-video`: when a LoRA
282is applied to an fp8 model via the wrapper's LoRA select, set `merge_loras` to
283`false`. The default `merge_loras=true` tries to bake the LoRA into the
284already-quantized fp8 weights and hard-crashes ComfyUI during LoRA loading with
285no Python traceback (looks like an unexplained restart/OOM). `false` applies
286the LoRA as a runtime patch, which is fp8-safe. This applies to BOTH the Pusa
287LoRAs and the lightx2v distill LoRA. Use `merge_loras=true` only on
288non-quantized bf16/fp16 models.
289 
290---
291 
292## Settings
293 
294### Sampler (from the example — distilled 6-step, two-pass HIGH→LOW)
295 
296| Param | HIGH pass | LOW pass | Notes |
297|---|---|---|---|
298| model | HIGH + Pusa HIGH (1.5) + distill (1.0) | LOW + Pusa LOW (1.4) + distill (1.0) | |
299| scheduler | `flowmatch_pusa` | `flowmatch_pusa` | **required** for Pusa |
300| steps | 6 | 6 | distilled; raise to ~20–30 for the non-distill path |
301| cfg | 1.0 | 1.0 | distilled low-CFG; ~5–6 without distill |
302| shift | 5.0 | 5.0 | flow-matching shift |
303| start_step / end_step | 0 / 3 | 3 / −1 | HIGH does early steps, LOW finishes |
304| `noisy_steps` (on AddPusaNoise) | 0 | 2 | extra-noise duration per pass |
305 
306If you drop the distill LoRA: use `steps` ~20 to 30, `cfg` ~5 to 6, keep
307`flowmatch_pusa` and `shift` 5, single-pass `unipc`-style splitting still works
308HIGH→LOW.
309 
310### Pusa noise (`WanVideoAddPusaNoise.noise_multipliers`)
311 
312This is the dial that controls how strictly the continuation honors the input
313clip vs. how free it is to diverge:
314 
315- Lower multipliers (toward 0) = conditioning latents stay clean = the
316 continuation clings tightly to the source frames (less drift, but can look
317 "stuck" or repeat).
318- Higher multipliers = more noise on the conditioning latents = the model is
319 freer to evolve the scene (more new motion, more drift risk).
320- The example ramps them `[0.0 … 0.2]` across the conditioning latents (one
321 per encoded latent, via `CreateScheduleFloatList` driven by
322 `GetLatentSizeAndCount`) so the oldest frame is locked and the seam frame
323 gets a little noise for a smooth blend. Start there; nudge the top of the ramp
324 up (~0.3) if continuations feel frozen, down if they drift.
325 
326### Seam color/saturation drift → ColorMatch the generated frames ⭐
327 
328The most common quality complaint with a Pusa extension: the moment you cross
329the seam, the color saturates or shifts. The conditioning frames are your real
330footage (near-clean latents), but the generated tail comes purely from the
331model's prior, which biases toward higher contrast and saturation (worse with the
332distill LoRA and `fp16_fast`). Motion carries fine; the palette pops.
333 
334Two fixes, best applied together:
335 
3361. `base_precision: bf16` on both `WanVideoModelLoader`s instead of
337 `fp16_fast`. fp16_fast's reduced precision drifts over the generated tail
338 and compounds the saturation; bf16 is more color-stable (small speed cost).
3392. Re-grade the generated frames to the source palette with a `ColorMatchV2`
340 (KJNodes) between `WanVideoDecode` and the final stitch/save:
341 - `image_target` ← `WanVideoDecode` (the generated window)
342 - `image_ref` ← the resized original clip (`ImageResizeKJv2` output, your
343 real footage)
344 - `method`: `hm-mkl-hm` (histogram→MKL→histogram; strongest at removing a
345 palette jump while keeping per-frame variation), `strength` 1.0.
346 - Re-route the downstream consumers (`ImageBatchMulti` / `ImageConcatMulti`'s
347 `image_1`) to take the ColorMatch output instead of the raw decode.
348 
349 Tune: if under-corrected, raise `strength`; if washed or over-corrected, drop to
350 ~0.6; for an even tighter temporal lock use a single clean reference frame
351 (the last conditioning frame) instead of the whole clip. Use `ColorMatchV2`
352 (not the deprecated `ColorMatch`).
353 
354This also matters for chaining. Color-match every new segment to the
355previous one before concat or the drift compounds hop-to-hop.
356 
357### Length, frame counts & fps
358 
359- `WanVideoEmptyEmbeds.num_frames` is the total window (conditioning frames +
360 new frames). The example uses 81 total (the WAN-native `4n+1` length, ~5 s
361 @16 fps).
362- The number of new frames added = total − conditioning frames. With ~13
363 tail frames conditioned and 81 total, you add ~68 new frames (~4 s) per pass.
364- `num_frames` step is 4 in the node; keep total on the WAN `4n+1` grid
365 (49 / 81 / 121 …). `frame_rate` for output is 16 fps (WAN 2.2 native).
366- Resolution: 832×480 default (divisible by 16). `ImageResizeKJv2` with
367 `crop`/`center` and divisor 16 keeps the loaded clip on-grid.
368 
369---
370 
371## Chaining multiple extensions
372 
373Making a long video by repeating the extension is in [`references/chaining.md`](references/chaining.md).
374 
375## VRAM tiers
376 
377Same envelope as `wan-t2v-video` (dual A14B fp8 + UMT5); Pusa adds only ~1.9 GB
378of LoRA. Use the wrapper's offload tooling.
379 
380| VRAM | Setup |
381|---|---|
382| **24 GB+** | Dual fp8 A14B + Pusa LoRAs + distill. `WanVideoBlockSwap` (offload some blocks) for headroom; `WanVideoTorchCompileSettings` (inductor) for speed; `sageattn`. 81 frames @832×480 fits. |
383| **12–16 GB** | More aggressive `WanVideoBlockSwap`; enable **VAE tiling** on `WanVideoEncode` (`enable_vae_tiling=true`, 272/144 tiles) and on `WanVideoDecode`; drop total frames to 49; consider single-pass. |
384| **8 GB** | Tight — heavy block swap + tiled VAE + 49 frames + tiny VAE preview decode. Expect slow. |
385 
386- `WanVideoModelLoader` quant `fp8_e4m3fn_scaled`, base precision `fp16_fast`,
387 `offload_device`, `sageattn` (the example's settings).
388- Always `clear_vram` before switching to this from another model family.
389- Encoder VAE tiling (`WanVideoEncode`) matters here because you're VAE-encoding
390 real footage in addition to decoding output.
391 
392---
393 
394## Gotchas
395 
396- **Loading the example silently resets model/VAE/distill-LoRA dropdowns** to the
397 wrong first entry (subfolder paths don't resolve on a flat layout). This is the
398 #1 cause of a Pusa run that errors or generates wrong content. See "In practice:
399 load → strip → re-point" and re-point ALL of them. Use `get_workflow (action:"strip")` to spot
400 it.
401- **The prompt lives on `WanVideoTextEncodeCached`**, not the CLIPTextEncode
402 "decoy" branch (which isn't wired to the samplers).
403- **Interpolated source → seam speed jump.** Set `VHS_LoadVideo.force_rate = 16`,
404 or condition on the pre-interpolation 16 fps master.
405- **`sageattn` / torch.compile errors.** The example assumes SageAttention +
406 triton. On a box without them, set `attention_mode=sdpa` and disconnect
407 `WanVideoTorchCompileSettings` from both model loaders (TRAP 5).
408- **Saturation/color pop after the seam.** Re-grade the generated frames with a
409 `ColorMatchV2` (`hm-mkl-hm`) referencing the source clip, and use `bf16` not
410 `fp16_fast` (see "Seam color/saturation drift").
411- **Scheduler must be `flowmatch_pusa`.** Leaving it on `unipc`/`euler` ignores
412 the Pusa per-latent noise schedule, so the conditioning latents don't behave as
413 clean anchors and you get a hard cut / regeneration instead of a smooth
414 continuation.
415- **`merge_loras=false` on fp8** (see CRITICAL above) applies to the Pusa
416 AND distill LoRAs; default `true` kills the process with no traceback.
417- **Match Pusa LoRA to expert**: `...HIGH...` → HIGH model, `...LOW...` → LOW
418 model. Crossing them degrades quality. Don't substitute the Wan 2.1
419 single-file `rank512` LoRA into the 2.2 dual graph.
420- **Frame-count grid**: keep `num_frames` on `4n+1` (49/81/121). Off-grid
421 totals can error or pad oddly. `num_frames` UI step is 4.
422- **Motion drift / "frozen" continuation**: tune `noise_multipliers`. Too low =
423 stuck/looping; too high = subject/scene wanders. The `0→0.2` ramp is the safe
424 middle.
425- **Color/exposure drift** across chained hops is the most common long-video
426 artifact. Mitigate: modest noise, restate the prompt, and optionally
427 color-match each new segment to the previous before concat.
428- **Audio**: WAN/Pusa generate silent video. The original clip's audio is
429 not extended. Re-attach/curate audio at the end with `VHS_VideoCombine`
430 (pass the source `audio` through) or in an editor, and note the new section
431 has no native sound.
432- **ffmpeg required** for the final mux (same as the other video skills): if
433 `VHS_VideoCombine` errors `ffmpeg ... could not be found`, run
434 `<comfy-venv>/python -m pip install imageio-ffmpeg` and reboot.
435- **Preview vs final VAE**: `taew2_1` (TinyVAE) is for fast preview decode; decode
436 the final with the full WAN VAE for quality.
437 
438---
439 
440## Minimal wiring (if you want fewer KJNodes)
441 
442The KJNodes (`GetImageRangeFromBatch`, `GetLatentSizeAndCount`,
443`CreateScheduleFloatList`, `ImageResizeKJv2`) are conveniences. The irreducible
444chain is:
445 
446```
447load clip → (resize to 16-grid) → WanVideoEncode(vae, tail frames) → LATENT
448WanVideoEmptyEmbeds(W,H,total) [extra_latents = that LATENT] → embeds
449embeds → WanVideoAddPusaNoise(noise_multipliers, noisy_steps) → embeds
450WanVideoSampler(model+Pusa LoRA, embeds, scheduler=flowmatch_pusa, shift 5) → LATENT
451WanVideoDecode(WAN VAE) → VHS_VideoCombine
452```
453 
454You can hand a constant list to `noise_multipliers` instead of building a ramp;
455the ramp smooths the seam. Two-pass HIGH→LOW is recommended (matches WAN
4562.2's MoE) but a single LOW-model pass works for quick tests.
457 
458---
459 
460## See also
461 
462- **`wan-t2v-video`.** The base WAN 2.2 T2V stack this builds on (model/encoder/
463 VAE loading, the `merge_loras=false` fp8 gotcha in full, block-swap/VRAM).
464 Read it first.
465- **`video-upscale`.** The natural next step: extend, then upscale. Generate
466 / extend at 832×480, then run the result through the
467 *downscale → SeedVR2 (temporal restore+upscale) → RIFE → VHS encode* pipeline
468 for a clean, higher-res, higher-fps final. Do the extension first, upscale
469 last (upscaling then extending wastes the restorer's work and risks re-drift).
470- **`ltxv2-video`.** An alternative video family with its own extender variant;
471 Pusa/WAN is the path when you want to continue an existing WAN-style clip.
472 
473## Packs
474 
475No dedicated `video-extend` installer pack ships yet. Since Pusa reuses the
476installed WanVideoWrapper + KJNodes + VideoHelperSuite stack, a pack only needs to
477list those `custom_nodes[]` (kijai/ComfyUI-WanVideoWrapper,
478Kijai/ComfyUI-KJNodes, Kosinkadink/ComfyUI-VideoHelperSuite) plus the two Pusa V1
479LoRAs in `models[]` (from `Kijai/WanVideo_comfy/Pusa/`). The big T2V A14B models
480are shared with `wan-t2v-video`; don't re-download. Install nodes ad-hoc with
481`panel_install_node` or apply a manifest with `apply_manifest`. Contribute a
482finished pack upstream (`github.com/artokun/comfyui-mcp`).
483 
484## Sources
485 
486- **Official:** none found.
487- **Empirical:** sampler values, wiring, and prompt notes from working graphs in `packs/` and observed renders; not a vendor prompting guide.
488 
View all files on GitHub →

Details

Updated
Sep 21, 2026
License
MIT
Stars on the repo
★ 759
Checked
Source
artokun/comfyui-mcp ↗
Creator
artokun · 44 listings
View creator

Similar skills

See all →
SkillMake Japanese TV-anime style videos with codeAnime celedenfunf/reelmimic · by edenfunfMake Japanese TV-anime style videos (MP4) with code — cel-shaded characters with tapered line art, big detailed eyes, hair clumps with a specular band, comedic anime reactions (sweat drop, anger vein, sparkle eyes, ≥< eyes, dot eyes, tears), painted skies with cumulus clouds, school/street/classroom/rooftop sets with time-of-day palettes, speed/focus lines, impact frames, dramatic zooms, smears, sakura petals and anime subtitles (CJK). Canvas 2D rendered frame by frame in headless Chrome, encoded with ffmpeg. Use when a reference video or brief calls for anime / 動畫 / 日系動畫 / アニメ / cel-shaded / slice-of-life / school romance / shōnen-style reactions, or when the video-clone router picks the anime-cel style. 2D only; characters are original (Hina, Ren) or new ones built on the same rig.★ 3.6k GitHub starsSkillDirect and produce a short film made entirely in codeLemo opuscarlemomo-ai/lemo-opuscar · by lemomo-aiDirect and produce a short film made entirely in code, in one of the styles of the Lemo-Opuscar library (e.g. Impasto Oil Painting 油画厚涂, Watercolor Brush 水彩笔刷, Ukiyo-e 浮世绘, Satellite Briefing 卫星简报, Exploded Teardown 产品拆解, Microscope Story 显微叙事). Use when the user asks for a video, film, short, promo, explainer or animation (视频、短片、动画、宣传片) in a named style, including data, science and product explainers built from real material such as satellite imagery, laser scans, CAD files or archive scans (数据解说、科普、产品拆解); when they want a film made about their own topic and haven't chosen a style (help them choose); or when they ask which film styles there are. Not for editing or converting existing video files.★ 3k GitHub starsSkillGenerate Ian-style Xiaohei illustrations for articles, postsdzhng/skills · by dzhngGenerate Ian-style Xiaohei illustrations for articles, posts, blogs, Notion documents, workflows, methods, processes, structures, states, metaphors, and opinions. Use when the user asks for weird, hand-drawn, Xiaohei, article, editorial, body illustrations, illustration ideas, shot lists, title removal, image edits, or image regeneration. By default, all image text and annotations are English, even when the source article is Chinese; only use another language when the user explicitly asks.★ 1.3k GitHub starsSkillCreating game art through Scenario MCP: spritesScenario game assetsscenario-labs/skills · by scenario-labsUse when creating game art through Scenario MCP: sprites, sprite sheets, icons, props, loot, tilesets and autotile terrain transitions, seamless tiles, isometric buildings, top-down maps, pixel art, UI buttons and panels, parallax background layers or depth planes for side-scrollers, and character or concept art; or when assets need transparent backgrounds, background removal, style-consistent variation batches, upscaling, pixel-grid cleanup, or PNG export for Unity, Godot, or Unreal.★ 854 GitHub starsSkillTrain custom LoRAs with ostris AI-ToolkitAI-Toolkit LoRA Trainer (WAN 2.2 & Z-Image)artokun/comfyui-mcp · by artokunTrain custom LoRAs with ostris AI-Toolkit. Covers WAN 2.2/2.1 (people, styles, video motion) and Z-Image (Turbo & Base, low-VRAM image LoRAs). Use when the user wants to train a WAN or Z-Image LoRA; covers local + RunPod setup, dataset prep, key params, and using the result in a ComfyUI workflow.★ 759 GitHub starsSkillAnime/illustration text-to-imageANIMA 1.0 (Anima Base Ultra) Text-to-Image Workflowsartokun/comfyui-mcp · by artokunAnime/illustration text-to-image (ANIMA 1.0, ~2B Cosmos DiT). Use for anime, manga, illustrated characters; accepts Danbooru tags + natural language; runs/trains on <6GB VRAM; includes anime inpainting via Anima-LLLite ControlNet★ 759 GitHub stars

More from artokun

SkillTrain custom LoRAs with ostris AI-ToolkitAI-Toolkit LoRA Trainer (WAN 2.2 & Z-Image)artokun/comfyui-mcp · by artokunTrain custom LoRAs with ostris AI-Toolkit. Covers WAN 2.2/2.1 (people, styles, video motion) and Z-Image (Turbo & Base, low-VRAM image LoRAs). Use when the user wants to train a WAN or Z-Image LoRA; covers local + RunPod setup, dataset prep, key params, and using the result in a ComfyUI workflow.★ 759 GitHub starsSkillAnime/illustration text-to-imageANIMA 1.0 (Anima Base Ultra) Text-to-Image Workflowsartokun/comfyui-mcp · by artokunAnime/illustration text-to-image (ANIMA 1.0, ~2B Cosmos DiT). Use for anime, manga, illustrated characters; accepts Danbooru tags + natural language; runs/trains on <6GB VRAM; includes anime inpainting via Anima-LLLite ControlNet★ 759 GitHub starsSkillAuthoring & Publishing ComfyUI Custom Nodesartokun/comfyui-mcp · by artokunAuthoring & publishing ComfyUI custom nodes to the Comfy Registry, covering node structure, pyproject.toml spec, comfy-cli publishing, and CI★ 759 GitHub starsSkillTrain a custom anime LoRA on the ANIMA base modelCitron Anima LoRA Trainerartokun/comfyui-mcp · by artokunTrain a custom anime LoRA on the ANIMA base model with Citron's local Gradio trainer (kohya sd-scripts), <6GB VRAM, character/style LoRAs; covers setup, dataset prep, training params, and using the result in the anima-base workflow★ 759 GitHub starsSkillDiscover Civitai models with the BUILT-IN downloadmodelCivitai + comfyui-mcpartokun/comfyui-mcp · by artokunDiscover Civitai models with the BUILT-IN download_model action:"search_civitai" and install/generate them locally. Find a checkpoint/LoRA/embedding on Civitai, download it into ComfyUI, and use its trigger words. Optionally pair the official Civitai MCP for community features (images browsing, posting, collections).★ 759 GitHub starsSkillDiagnose and fix video/image color OBJECTIVELYColor Correction (measure, don't eyeball)artokun/comfyui-mcp · by artokunDiagnose and fix video/image color OBJECTIVELY with the get_image (action:"analyze_color") tool (scopes/stats such as black/white points, contrast, saturation, clipping, cast) instead of eyeballing a contact sheet. Covers the "washed out" signature, why reference color-match (mkl/ColorMatch/ColorMatchAdobe) CAN'T add contrast a flat source lacks, the levels/contrast-stretch fix (core AdjustContrast / CurveEditor), the measure→fix→re-measure loop, the side-by-side sandbox pattern, and where to place the fix in a render graph (after decode, before save). Use when a render looks washed out / flat / dull / over-saturated / color-cast, or when deciding between a color-match and a contrast/levels fix.★ 759 GitHub stars