Nodes/ComfyUI-CustomNodeKit/Wan SCAIL-2 Phase Sampler
ComfyUI Node

Wan SCAIL-2 Phase Sampler

The SCAIL-2 chunk loop, without the sampler chaining

By user2318·Created 4 months ago·Updated about a month ago· 56
Wan SCAIL-2 Phase Sampler
  • model1
  • positive
  • negative
  • vae
  • latent
  • model2
  • previous_frames
  • latent
width512
height896
seed0
steps6
cfg1.0
sampler_nameeuler
schedulernormal
denoise1.00
split_step2
phase1_noise0.500
phase2_noise0.100
previous_frame_count5

SCAIL-2 is Z.ai's motion-transfer model on a Wan 2.1 base, and it's expensive in the way that matters: several minutes per 81-frame clip on a mid-range card, and past 81 frames you have to chain chunks by hand. The stock workflow's chain is sampler → decode → re-anchor → sampler again, with the arithmetic of when to step and how many frames to carry. This node is the pack's attempt to make that whole dance a single node: a complete two-phase sampler that takes pixel frames as its anchor input and internally does the VAE encoding, the anchor write-back, and the noise-mask management.

Think of it as a self-contained KSampler you can point at the same conditioning and latent your chunk node produces. When it's just a single chunk, it behaves like a normal sampler. When you connect the previous chunk's decoded tail frames, it switches into the two-phase SCAIL-2 continuation mode that the model was actually trained with - 81-frame chunks with a 76-frame step and a 5-frame anchor.

How the two phases work

The mechanism, from the source: it takes the tail previous_frame_count frames of previous_frames, upscales them to your target resolution, VAE-encodes them, and writes them into the front of the latent as an anchor. It builds a noise mask where the anchor region is set to phase1_noise and everything else is 1 (free). Phase 1 samples from your noise down to split_step. Then it force-overwrites the anchor region with the original encoded frames - this is what pins the chunk to the previous video - updates the mask to phase2_noise, and samples phase 2 from empty noise to the end. phase1_noise around 0.5 means the anchor is partially free during composition; phase2_noise around 0.1 means it's mostly frozen at the end.

The inputs that matter

  • model1 - the Phase 1 model; model2 (optional) - a different model for Phase 2 (e.g. a distilled speed variant), falling back to model1 if not provided.
  • positive / negative / vae / latent - your conditioning and the latent from the SCAIL conditioning node (WanSCAILToVideoMultiRef).
  • steps / cfg / sampler_name / scheduler / denoise / seed / width / height - standard sampler knobs. Width and height step by 32 (SCAIL is coarser than WanAnimate's 16).
  • split_step (default 2) - where the phases split. 0 = single phase. Two-phase only activates when split_step > 0, it's less than steps, and previous_frames is connected.
  • phase1_noise / phase2_noise - the anchor freeze values described above (0 = frozen, 1 = free).
  • previous_frame_count (default 5) - how many tail frames of previous_frames become the anchor. SCAIL-2 was trained at 5.
  • previous_frames - the previous chunk's decoded frames. Without it, the node quietly degrades to single-phase.

The one output is latent - the sampled result, ready for VAE decode or to become the next chunk's previous_frames.

Reality check

This doesn't make SCAIL-2 cheap - nothing does. What it removes is the workflow cost: no manual sampler chaining, no off-by-one frame arithmetic, and the anchor behavior matches the model's training setup. Set previous_frame_count to 5, keep length at 81, and let the loop advance. And remember the community's standing advice if faces wander across chunks: drop the speed LoRAs and raise steps and CFG before you blame the sampler.

Install

Part of ComfyUI-CustomNodeKit. ComfyUI Manager → search "ComfyUI-CustomNodeKit", or:

cd ComfyUI/custom_nodes
git clone https://github.com/user2318/ComfyUI-CustomNodeKit.git
cd ComfyUI-CustomNodeKit
pip install -r requirements.txt

Restart ComfyUI. It drives your existing SCAIL-2 model - no extra weights from the pack.

Categorysampling

Inputs (19)

NameTypeDefaultDescription
model1MODELPhase 1 模型。
positiveCONDITIONING正向条件。
negativeCONDITIONING负向条件。
vaeVAEVAE,用于锚定帧编解码。
latentLATENT输入的 latent(来自 conditioning 节点)。
widthINT51232–8192
heightINT89632–8192
seedINT00–18446744073709550000
stepsINT61–10000
cfgFLOAT1.00–100
sampler_nameCOMBOeuler44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBOnormal9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
denoiseFLOAT1.000–1
split_stepINT20–10000分割步数。0=单阶段;>0且<steps且接入了previous_frames时启用两阶段。
phase1_noiseFLOAT0.5000–1Phase 1 锚定帧 noise_mask 值。0=冻结,1=自由。
phase2_noiseFLOAT0.1000–1Phase 2 锚定帧 noise_mask 值。0=冻结,1=自由。
previous_frame_countINT51–4096从 previous_frames 尾部取多少帧作为锚定。
model2optMODELPhase 2 使用的模型,不提供时使用 model1。
previous_framesoptIMAGE上一段解码后的尾部像素帧。不接时退化为单阶段。

Outputs (1)

NameTypeDescription
latentLATENT