Wan2.1 SCAIL
One-Touch SCAIL Pose Control based on the composition of the Reference Image
Inside the workflow
A read-only preview of the source template. Open it in Cloud to explore the nodes and make changes.
Loading the graph
Open full-size workflow preview- Output
- Video
- Author
- ComfyUI
Call this model from your code
The request below uses the same prepared graph and settings as the Playground. Each submission can start a paid run; do not automatically retry a submission whose outcome is unknown.
What you need
- Runs on
- Comfy Cloud
- Key
- COMFY_API_KEY
- Your files
- Uploaded by the code from their urls
Needs a paid Cloud plan and credits.
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"390": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image_FILENAME"
},
"_meta": {
"title": "Load Image: Reference"
}
},
"399": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"385:395",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"408": {
"class_type": "LoadVideo",
"inputs": {
"file": "UPLOADED_video_FILENAME"
},
"_meta": {
"title": "Load Video"
}
},
"385:107": {
"class_type": "ImageResizeKJv2",
"inputs": {
"crop_position": "center",
"device": "cpu",
"divisible_by": 32,
"height": 480,
"image": [
"390",
0
],
"keep_proportion": "crop",
"pad_color": "255,255,255",
"upscale_method": "lanczos",
"width": 832
},
"_meta": {
"title": "Resize Image v2"
}
},
"385:131": {
"class_type": "ImageResizeKJv2",
"inputs": {
"crop_position": "center",
"device": "cpu",
"divisible_by": 32,
"height": 480,
"image": [
"385:406",
0
],
"keep_proportion": "crop",
"pad_color": "0, 0, 0",
"upscale_method": "lanczos",
"width": 832
},
"_meta": {
"title": "Resize Image v2"
}
},
"385:22": {
"class_type": "WanVideoModelLoader",
"inputs": {
"attention_mode": "sdpa",
"base_precision": "fp16_fast",
"load_device": "offload_device",
"model": "Wan21-14B-SCAIL-preview_comfy_bf16.safetensors",
"quantization": "disabled",
"rms_norm_function": "default"
},
"_meta": {
"title": "WanVideo Model Loader"
}
},
"385:28": {
"class_type": "WanVideoDecode",
"inputs": {
"enable_vae_tiling": False,
"normalization": "default",
"samples": [
"385:348",
0
],
"tile_stride_x": 144,
"tile_stride_y": 128,
"tile_x": 272,
"tile_y": 272,
"vae": [
"385:38",
0
]
},
"_meta": {
"title": "WanVideo Decode"
}
},
"385:324": {
"class_type": "WanVideoAddSCAILPoseEmbeds",
"inputs": {
"embeds": [
"385:350",
0
],
"end_percent": 0.5,
"pose_images": [
"385:362",
0
],
"start_percent": 0,
"strength": 1,
"vae": [
"385:38",
0
]
},
"_meta": {
"title": "WanVideo Add SCAIL Pose Embeds"
}
},
"385:326": {
"class_type": "CLIPVisionLoader",
"inputs": {
"clip_name": "clip_vision_h.safetensors"
},
"_meta": {
"title": "Load CLIP Vision"
}
},
"385:327": {
"class_type": "WanVideoClipVisionEncode",
"inputs": {
"clip_vision": [
"385:326",
0
],
"combine_embeds": "average",
"crop": "center",
"force_offload": True,
"image_1": [
"385:107",
0
],
"ratio": 0.5,
"strength_1": 1,
"strength_2": 1,
"tiles": 0
},
"_meta": {
"title": "WanVideo ClipVision Encode"
}
},
"385:334": {
"class_type": "NLFPredict",
"inputs": {
"images": [
"385:131",
0
],
"model": [
"385:384",
0
],
"per_batch": -1
},
"_meta": {
"title": "NLF Predict"
}
},
"385:348": {
"class_type": "WanVideoSamplerv2",
"inputs": {
"add_noise_to_samples": False,
"cfg": 1,
"extra_args": [
"385:354",
0
],
"force_offload": True,
"image_embeds": [
"385:324",
0
],
"model": [
"385:80",
0
],
"scheduler": [
"385:349",
0
],
"seed": 42,
"text_embeds": [
"385:368",
0
]
},
"_meta": {
"title": "WanVideo Sampler v2"
}
},
"385:349": {
"class_type": "WanVideoSchedulerv2",
"inputs": {
"end_step": -1,
"enhance_hf": False,
"scheduler": "dpm++_sde",
"shift": 7,
"start_step": 0,
"steps": 6
},
"_meta": {
"title": "WanVideo Scheduler v2"
}
},
"385:35": {
"class_type": "WanVideoTorchCompileSettings",
"inputs": {
"allow_unmerged_lora_compile": False,
"backend": "inductor",
"compile_transformer_blocks_only": True,
"dynamic": False,
"dynamo_cache_size_limit": 64,
"dynamo_recompile_limit": 128,
"force_parameter_static_shapes": False,
"fullgraph": False,
"mode": "default"
},
"_meta": {
"title": "WanVideo Torch Compile Settings"
}
},
"385:350": {
"class_type": "WanVideoAddSCAILReferenceEmbeds",
"inputs": {
"clip_embeds": [
"385:327",
0
],
"embeds": [
"385:99",
0
],
"end_percent": 1,
"ref_image": [
"385:107",
0
],
"start_percent": 0,
"strength": 1,
"vae": [
"385:38",
0
]
},
"_meta": {
"title": "WanVideo Add SCAIL Reference Embeds"
}
},
"385:354": {
"class_type": "WanVideoSamplerExtraArgs",
"inputs": {
"context_options": [
"385:355",
0
],
"riflex_freq_index": 0,
"rope_function": "comfy"
},
"_meta": {
"title": "WanVideoSampler v2 Extra Args"
}
},
"385:355": {
"class_type": "WanVideoContextOptions",
"inputs": {
"context_frames": 81,
"context_overlap": 48,
"context_schedule": "uniform_standard",
"context_stride": 4,
"freenoise": True,
"fuse_method": "linear",
"verbose": False
},
"_meta": {
"title": "WanVideo Context Options"
}
},
"385:362": {
"class_type": "RenderNLFPoses",
"inputs": {
"draw_face": True,
"draw_hands": True,
"dw_poses": [
"385:363",
0
],
"height": [
"385:383",
0
],
"nlf_poses": [
"385:334",
0
],
"ref_dw_pose": [
"385:365",
0
],
"render_backend": "taichi",
"render_device": "gpu",
"scale_hands": True,
"width": [
"385:382",
0
]
},
"_meta": {
"title": "Render NLF Poses"
}
},
"385:363": {
"class_type": "PoseDetectionVitPoseToDWPose",
"inputs": {
"images": [
"385:131",
0
],
"vitpose_model": [
"385:364",
0
]
},
"_meta": {
"title": "Pose Detection VitPose to DWPose"
}
},
"385:364": {
"class_type": "OnnxDetectionModelLoader",
"inputs": {
"onnx_device": "CUDAExecutionProvider",
"vitpose_model": "vitpose-l-wholebody.onnx",
"yolo_model": "yolov10m.onnx"
},
"_meta": {
"title": "ONNX Detection Model Loader"
}
},
"385:365": {
"class_type": "PoseDetectionVitPoseToDWPose",
"inputs": {
"images": [
"385:107",
0
],
"vitpose_model": [
"385:364",
0
]
},
"_meta": {
"title": "Pose Detection VitPose to DWPose"
}
},
"385:368": {
"class_type": "WanVideoTextEncodeCached",
"inputs": {
"device": "gpu",
"model_name": "umt5_xxl_fp16.safetensors",
"negative_prompt": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
"positive_prompt": "The young star-mapper in saffron and indigo robes dances alone on the shining salt flat at twilight, following the dancer's exact moves: she lands lightly from a leap, swivels her heels and kicks, spins with her arms flung wide so her layered robes and fringed sash flare out, hops to the side with a playful shoulder shimmy, and finishes with one arm raised toward the two pale moons. Her braided coronets swing with each turn and her brass cuffs catch the lilac light. The camera holds still and the painterly storybook style, the purple mineral ridges and the soft lavender mist stay exactly as in the reference image.",
"precision": "bf16",
"quantization": "disabled",
"use_disk_cache": False
},
"_meta": {
"title": "WanVideo TextEncode Cached"
}
},
"385:38": {
"class_type": "WanVideoVAELoader",
"inputs": {
"model_name": "wan_2.1_vae.safetensors",
"precision": "bf16",
"use_cpu_cache": False,
"verbose": False
},
"_meta": {
"title": "WanVideo VAE Loader"
}
},
"385:382": {
"class_type": "SimpleMath+",
"inputs": {
"a": 832,
"b": 0,
"value": "a / 2"
},
"_meta": {
"title": "🔧 Simple Math"
}
},
"385:383": {
"class_type": "SimpleMath+",
"inputs": {
"a": 480,
"b": 0,
"value": "a / 2"
},
"_meta": {
"title": "🔧 Simple Math"
}
},
"385:384": {
"class_type": "LoadNLFModel",
"inputs": {
"nlf_model": "nlf_l_multi_0.3.2.torchscript",
"warmup": True
},
"_meta": {
"title": "Load NLF Model"
}
},
"385:395": {
"class_type": "CreateVideo",
"inputs": {
"audio": [
"385:405",
1
],
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": 24,
"images": [
"385:28",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"385:405": {
"class_type": "GetVideoComponents",
"inputs": {
"video": [
"408",
0
]
},
"_meta": {
"title": "Get Video Components"
}
},
"385:406": {
"class_type": "ImageFromBatch",
"inputs": {
"batch_index": 0,
"image": [
"385:405",
0
],
"length": 121
},
"_meta": {
"title": "Get Image from Batch"
}
},
"385:56": {
"class_type": "WanVideoLoraSelect",
"inputs": {
"lora": "lightx2v_T2V_14B_cfg_step_distill_v2_lora_rank64_bf16.safetensors",
"low_mem_load": False,
"merge_loras": False,
"strength": 1
},
"_meta": {
"title": "WanVideo Lora Select"
}
},
"385:80": {
"class_type": "WanVideoSetLoRAs",
"inputs": {
"lora": [
"385:56",
0
],
"model": [
"385:22",
0
]
},
"_meta": {
"title": "WanVideo Set LoRAs"
}
},
"385:99": {
"class_type": "WanVideoEmptyEmbeds",
"inputs": {
"height": [
"385:107",
2
],
"num_frames": 121,
"width": [
"385:107",
1
]
},
"_meta": {
"title": "WanVideo Empty Embeds"
}
}
})
workflow.set_input("390", "image", client.assets.from_url("https://comfy.org/catalog-media/74255c19-ca65-4b6f-b045-a5c7058292ff/4b4d7584-ec11-463f-a645-910ff0860587"))
workflow.set_input("408", "file", client.assets.from_url("https://comfy.org/catalog-media/e2a9954d-e846-4452-b43f-facd4f913c68/891e0580-1de5-4870-a8a7-31922ced1730"))
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)
for output in job.get_outputs("399"):
output.to_file(output.name)Try an example
About this workflow
The Wan2.1 SCAIL workflow in ComfyUI is designed to seamlessly transfer motion and pose information from a video source onto a reference image, while maintaining the original composition of the image. This is achieved using the Wan2.1 SCAIL model, which excels in adapting pose data to fit the proportions and framing of the reference image.
The workflow utilizes several custom nodes, including ComfyUI-WanAnimatePreprocess and ComfyUI-WanVideoWrapper, to preprocess and wrap video data efficiently. These nodes work in conjunction with the comfyui-scail-pose node, which is responsible for the precise scaling and alignment of pose data. By leveraging these tools, users can create dynamic animations that preserve the aesthetic qualities of the original reference image.
This workflow is particularly useful for applications that require high fidelity in pose transfer, such as creating animated sequences from static images or enhancing video content with consistent stylistic elements. The integration of nodes like LoadImage, SaveVideo, and LoadVideo ensures a smooth workflow from input to output, allowing users to easily import their media, apply the SCAIL technique, and export the final animated video. This makes the workflow not only technically robust but also user-friendly, providing a one-touch solution for complex pose control tasks.
Questions & answers
Videos with clear and distinct motion patterns are ideal, as the workflow relies on accurately capturing and transferring pose data.
Yes, the LoadImage node supports various image formats, allowing flexibility in choosing your reference image.
Yes, the comfyui-scail-pose node allows for adjustments in pose scaling and alignment to match your desired intensity.
Ensure your source video and reference image are of high resolution, and configure the SaveVideo node to export in a high-quality format.