diff --git a/__init__.py b/__init__.py
index 24bd3b0..268b90a 100644
--- a/__init__.py
+++ b/__init__.py
@@ -28,7 +28,8 @@ from .nodes import (
MMAudioModelLoader, MMAudioFeatureUtilsLoader, MMAudioSampler,
PulidModelLoader, PulidInsightFaceLoader, PulidEvaClipLoader,
HyVideoModelLoader, HyVideoVAELoader, DownloadAndLoadHyVideoTextEncoder,
- WanVideoModelLoader, WanVideoVAELoader, LoadWanVideoT5TextEncoder
+ WanVideoModelLoader, WanVideoVAELoader, LoadWanVideoT5TextEncoder, LoadWanVideoClipTextEncoder,
+ WanVideoTextEncode, WanVideoBlockSwap, WanVideoModelLoader_TWO
)
current_device = mm.get_torch_device()
@@ -41,6 +42,7 @@ def get_torch_device_patched():
device = torch.device("cpu")
else:
device = torch.device(current_device)
+ logging.info(f"[MultiGPU get_torch_device_patched] Returning device: {device} (current_device={current_device})")
return device
def text_encoder_device_patched():
@@ -49,10 +51,15 @@ def text_encoder_device_patched():
device = torch.device("cpu")
else:
device = torch.device(current_text_encoder_device)
+ logging.info(f"[MultiGPU text_encoder_device_patched] Returning device: {device} (current_text_encoder_device={current_text_encoder_device})")
return device
+logging.info(f"[MultiGPU] Patching mm.get_torch_device and mm.text_encoder_device")
+logging.info(f"[MultiGPU] Initial current_device: {current_device}")
+logging.info(f"[MultiGPU] Initial current_text_encoder_device: {current_text_encoder_device}")
mm.get_torch_device = get_torch_device_patched
mm.text_encoder_device = text_encoder_device_patched
+logging.info(f"[MultiGPU] Patches applied successfully")
def create_model_hash(model, caller):
@@ -528,10 +535,18 @@ def override_class(cls):
def override(self, *args, device=None, **kwargs):
global current_device
+
+ logging.info(f"[MultiGPU override_class] Called with device={device}, current_device={current_device}")
+
if device is not None:
current_device = device
+ logging.info(f"[MultiGPU override_class] Setting current_device to {device}")
+
fn = getattr(super(), cls.FUNCTION)
+ logging.info(f"[MultiGPU override_class] Calling wrapped function: {cls.__name__}.{cls.FUNCTION}")
out = fn(*args, **kwargs)
+ logging.info(f"[MultiGPU override_class] Wrapped function completed successfully")
+
return out
return NodeOverride
@@ -552,10 +567,13 @@ def override_class_clip(cls):
def override(self, *args, device=None, **kwargs):
global current_text_encoder_device
+
if device is not None:
current_text_encoder_device = device
+
fn = getattr(super(), cls.FUNCTION)
out = fn(*args, **kwargs)
+
return out
return NodeOverride
@@ -741,9 +759,14 @@ if check_module_exists("ComfyUI-HunyuanVideoWrapper") or check_module_exists("co
NODE_CLASS_MAPPINGS["DownloadAndLoadHyVideoTextEncoderMultiGPU"] = override_class(DownloadAndLoadHyVideoTextEncoder)
if check_module_exists("ComfyUI-WanVideoWrapper") or check_module_exists("comfyui-wanvideowrapper"):
- NODE_CLASS_MAPPINGS["WanVideoModelLoaderMultiGPU"] = override_class(WanVideoModelLoader)
- NODE_CLASS_MAPPINGS["WanVideoVAELoaderMultiGPU"] = override_class(WanVideoVAELoader)
- NODE_CLASS_MAPPINGS["LoadWanVideoT5TextEncoderMultiGPU"] = override_class(LoadWanVideoT5TextEncoder)
+ # WanVideo uses custom implementation, not the standard override
+ NODE_CLASS_MAPPINGS["WanVideoModelLoaderMultiGPU"] = WanVideoModelLoader
+ NODE_CLASS_MAPPINGS["WanVideoModelLoaderMultiGPU_TWO"] = WanVideoModelLoader_TWO
+ NODE_CLASS_MAPPINGS["WanVideoVAELoaderMultiGPU"] = WanVideoVAELoader
+ NODE_CLASS_MAPPINGS["LoadWanVideoT5TextEncoderMultiGPU"] = LoadWanVideoT5TextEncoder
+ NODE_CLASS_MAPPINGS["LoadWanVideoClipTextEncoderMultiGPU"] = LoadWanVideoClipTextEncoder
+ NODE_CLASS_MAPPINGS["WanVideoTextEncodeMultiGPU"] = WanVideoTextEncode
+ NODE_CLASS_MAPPINGS["WanVideoBlockSwapMultiGPU"] = WanVideoBlockSwap
logging.info(f"MultiGPU: Registration complete. Final mappings: {', '.join(NODE_CLASS_MAPPINGS.keys())}")
diff --git a/claude_json.json b/claude_json.json
new file mode 100755
index 0000000..87b50f4
--- /dev/null
+++ b/claude_json.json
@@ -0,0 +1,1387 @@
+{
+ "id": "c6e410bc-5e2c-460b-ae81-c91b6094fbb1",
+ "revision": 0,
+ "last_node_id": 62,
+ "last_link_id": 67,
+ "nodes": [
+ {
+ "id": 11,
+ "type": "LoadWanVideoT5TextEncoder",
+ "pos": [
+ -390,
+ -70
+ ],
+ "size": [
+ 377.1661376953125,
+ 130
+ ],
+ "flags": {},
+ "order": 0,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "wan_t5_model",
+ "type": "WANTEXTENCODER",
+ "slot_index": 0,
+ "links": [
+ 15
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LoadWanVideoT5TextEncoder",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ "umt5-xxl-enc-bf16.safetensors",
+ "bf16",
+ "offload_device",
+ "disabled"
+ ],
+ "color": "#332922",
+ "bgcolor": "#593930"
+ },
+ {
+ "id": 37,
+ "type": "WanVideoEmptyEmbeds",
+ "pos": [
+ 1305.26708984375,
+ -571.7843627929688
+ ],
+ "size": [
+ 315,
+ 126
+ ],
+ "flags": {},
+ "order": 1,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "control_embeds",
+ "shape": 7,
+ "type": "WANVIDIMAGE_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "extra_latents",
+ "shape": 7,
+ "type": "LATENT",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "image_embeds",
+ "type": "WANVIDIMAGE_EMBEDS",
+ "links": [
+ 42
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoEmptyEmbeds",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ 832,
+ 480,
+ 81
+ ]
+ },
+ {
+ "id": 50,
+ "type": "CLIPTextEncode",
+ "pos": [
+ 450.84735107421875,
+ 852.1167602539062
+ ],
+ "size": [
+ 400,
+ 200
+ ],
+ "flags": {},
+ "order": 19,
+ "mode": 2,
+ "inputs": [
+ {
+ "name": "clip",
+ "type": "CLIP",
+ "link": 53
+ }
+ ],
+ "outputs": [
+ {
+ "name": "CONDITIONING",
+ "type": "CONDITIONING",
+ "slot_index": 0,
+ "links": [
+ 55
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "CLIPTextEncode",
+ "cnr_id": "comfy-core",
+ "ver": "0.3.47"
+ },
+ "widgets_values": [
+ "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 48,
+ "type": "CLIPLoader",
+ "pos": [
+ 90.8473129272461,
+ 602.1166381835938
+ ],
+ "size": [
+ 315,
+ 106
+ ],
+ "flags": {},
+ "order": 2,
+ "mode": 2,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "CLIP",
+ "type": "CLIP",
+ "slot_index": 0,
+ "links": [
+ 52,
+ 53
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "CLIPLoader",
+ "cnr_id": "comfy-core",
+ "ver": "0.3.47"
+ },
+ "widgets_values": [
+ "umt5_xxl_fp16.safetensors",
+ "wan",
+ "default"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 51,
+ "type": "Note",
+ "pos": [
+ 120.8473129272461,
+ 432.1158752441406
+ ],
+ "size": [
+ 253.16725158691406,
+ 88
+ ],
+ "flags": {},
+ "order": 3,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "You can also use native ComfyUI text encoding with these nodes instead of the original, the models are node specific and can't otherwise be mixed."
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 49,
+ "type": "CLIPTextEncode",
+ "pos": [
+ 450.84735107421875,
+ 602.1166381835938
+ ],
+ "size": [
+ 400,
+ 200
+ ],
+ "flags": {},
+ "order": 18,
+ "mode": 2,
+ "inputs": [
+ {
+ "name": "clip",
+ "type": "CLIP",
+ "link": 52
+ }
+ ],
+ "outputs": [
+ {
+ "name": "CONDITIONING",
+ "type": "CONDITIONING",
+ "slot_index": 0,
+ "links": [
+ 54
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "CLIPTextEncode",
+ "cnr_id": "comfy-core",
+ "ver": "0.3.47"
+ },
+ "widgets_values": [
+ "high quality nature video featuring a red panda balancing on a bamboo stem while a bird lands on it's head, on the background there is a waterfall"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 33,
+ "type": "Note",
+ "pos": [
+ -760,
+ -50
+ ],
+ "size": [
+ 359.0753479003906,
+ 88
+ ],
+ "flags": {},
+ "order": 4,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "Models:\nhttps://huggingface.co/Kijai/WanVideo_comfy/tree/main"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 35,
+ "type": "WanVideoTorchCompileSettings",
+ "pos": [
+ -390,
+ -710
+ ],
+ "size": [
+ 390.5999755859375,
+ 202
+ ],
+ "flags": {},
+ "order": 5,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "torch_compile_args",
+ "type": "WANCOMPILEARGS",
+ "slot_index": 0,
+ "links": []
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoTorchCompileSettings",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ "inductor",
+ false,
+ "default",
+ false,
+ 64,
+ true,
+ 128
+ ]
+ },
+ {
+ "id": 44,
+ "type": "Note",
+ "pos": [
+ -710,
+ -710
+ ],
+ "size": [
+ 303.0501403808594,
+ 88
+ ],
+ "flags": {},
+ "order": 6,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "If you have Triton installed, connect this for ~30% speed increase"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 30,
+ "type": "VHS_VideoCombine",
+ "pos": [
+ 2068.651611328125,
+ -582.5413818359375
+ ],
+ "size": [
+ 1245.8460693359375,
+ 1055.2188720703125
+ ],
+ "flags": {},
+ "order": 25,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "images",
+ "type": "IMAGE",
+ "link": 36
+ },
+ {
+ "name": "audio",
+ "shape": 7,
+ "type": "AUDIO",
+ "link": null
+ },
+ {
+ "name": "meta_batch",
+ "shape": 7,
+ "type": "VHS_BatchManager",
+ "link": null
+ },
+ {
+ "name": "vae",
+ "shape": 7,
+ "type": "VAE",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "Filenames",
+ "type": "VHS_FILENAMES",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "VHS_VideoCombine",
+ "cnr_id": "comfyui-videohelpersuite",
+ "ver": "330bce6c3c0d47ebdedcc0348d9ab355707b7523"
+ },
+ "widgets_values": {
+ "frame_rate": 16,
+ "loop_count": 0,
+ "filename_prefix": "WanVideo2_1_T2V",
+ "format": "video/h264-mp4",
+ "pix_fmt": "yuv420p",
+ "crf": 19,
+ "save_metadata": true,
+ "trim_to_audio": false,
+ "pingpong": false,
+ "save_output": true,
+ "videopreview": {
+ "hidden": false,
+ "paused": false,
+ "params": {
+ "filename": "WanVideo2_1_T2V_00003.mp4",
+ "subfolder": "",
+ "type": "output",
+ "format": "video/h264-mp4",
+ "frame_rate": 16,
+ "workflow": "WanVideo2_1_T2V_00003.png",
+ "fullpath": "/home/johnj/ComfyUI/output/WanVideo2_1_T2V_00003.mp4"
+ }
+ }
+ }
+ },
+ {
+ "id": 46,
+ "type": "WanVideoTextEmbedBridge",
+ "pos": [
+ 900.8475341796875,
+ 592.1166381835938
+ ],
+ "size": [
+ 315,
+ 46
+ ],
+ "flags": {},
+ "order": 21,
+ "mode": 2,
+ "inputs": [
+ {
+ "name": "positive",
+ "type": "CONDITIONING",
+ "link": 54
+ },
+ {
+ "name": "negative",
+ "shape": 7,
+ "type": "CONDITIONING",
+ "link": 55
+ }
+ ],
+ "outputs": [
+ {
+ "name": "text_embeds",
+ "type": "WANVIDEOTEXTEMBEDS",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoTextEmbedBridge",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": []
+ },
+ {
+ "id": 28,
+ "type": "WanVideoDecode",
+ "pos": [
+ 1692.973876953125,
+ -404.8614501953125
+ ],
+ "size": [
+ 315,
+ 198
+ ],
+ "flags": {},
+ "order": 24,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "vae",
+ "type": "WANVAE",
+ "link": 43
+ },
+ {
+ "name": "samples",
+ "type": "LATENT",
+ "link": 33
+ }
+ ],
+ "outputs": [
+ {
+ "name": "images",
+ "type": "IMAGE",
+ "slot_index": 0,
+ "links": [
+ 36
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoDecode",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ false,
+ 272,
+ 272,
+ 144,
+ 128,
+ "default"
+ ],
+ "color": "#322",
+ "bgcolor": "#533"
+ },
+ {
+ "id": 56,
+ "type": "WanVideoSetBlockSwap",
+ "pos": [
+ 882.7855834960938,
+ -362.668701171875
+ ],
+ "size": [
+ 201.76815795898438,
+ 46
+ ],
+ "flags": {},
+ "order": 22,
+ "mode": 4,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 62
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": 58
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 60
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSetBlockSwap",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 58,
+ "type": "WanVideoSetLoRAs",
+ "pos": [
+ 630.5015869140625,
+ -367.1865234375
+ ],
+ "size": [
+ 174.53378295898438,
+ 46
+ ],
+ "flags": {},
+ "order": 20,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 67
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": 64
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 62
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSetLoRAs",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 27,
+ "type": "WanVideoSampler",
+ "pos": [
+ 1315.2401123046875,
+ -401.48028564453125
+ ],
+ "size": [
+ 315,
+ 902
+ ],
+ "flags": {},
+ "order": 23,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 60
+ },
+ {
+ "name": "image_embeds",
+ "type": "WANVIDIMAGE_EMBEDS",
+ "link": 42
+ },
+ {
+ "name": "text_embeds",
+ "shape": 7,
+ "type": "WANVIDEOTEXTEMBEDS",
+ "link": 30
+ },
+ {
+ "name": "samples",
+ "shape": 7,
+ "type": "LATENT",
+ "link": null
+ },
+ {
+ "name": "feta_args",
+ "shape": 7,
+ "type": "FETAARGS",
+ "link": 57
+ },
+ {
+ "name": "context_options",
+ "shape": 7,
+ "type": "WANVIDCONTEXT",
+ "link": null
+ },
+ {
+ "name": "cache_args",
+ "shape": 7,
+ "type": "CACHEARGS",
+ "link": null
+ },
+ {
+ "name": "flowedit_args",
+ "shape": 7,
+ "type": "FLOWEDITARGS",
+ "link": null
+ },
+ {
+ "name": "slg_args",
+ "shape": 7,
+ "type": "SLGARGS",
+ "link": null
+ },
+ {
+ "name": "loop_args",
+ "shape": 7,
+ "type": "LOOPARGS",
+ "link": null
+ },
+ {
+ "name": "experimental_args",
+ "shape": 7,
+ "type": "EXPERIMENTALARGS",
+ "link": null
+ },
+ {
+ "name": "sigmas",
+ "shape": 7,
+ "type": "SIGMAS",
+ "link": null
+ },
+ {
+ "name": "unianimate_poses",
+ "shape": 7,
+ "type": "UNIANIMATE_POSE",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_embeds",
+ "shape": 7,
+ "type": "FANTASYTALKING_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "uni3c_embeds",
+ "shape": 7,
+ "type": "UNI3C_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "multitalk_embeds",
+ "shape": 7,
+ "type": "MULTITALK_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "freeinit_args",
+ "shape": 7,
+ "type": "FREEINITARGS",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "samples",
+ "type": "LATENT",
+ "slot_index": 0,
+ "links": [
+ 33
+ ]
+ },
+ {
+ "name": "denoised_samples",
+ "type": "LATENT",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSampler",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ 6,
+ 1,
+ 5,
+ 42,
+ "fixed",
+ true,
+ "dpm++_sde",
+ 0,
+ 1,
+ false,
+ "comfy",
+ 0,
+ -1,
+ false
+ ]
+ },
+ {
+ "id": 55,
+ "type": "WanVideoEnhanceAVideo",
+ "pos": [
+ 1292.82177734375,
+ -760.1163330078125
+ ],
+ "size": [
+ 315,
+ 106
+ ],
+ "flags": {},
+ "order": 7,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "feta_args",
+ "type": "FETAARGS",
+ "links": [
+ 57
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoEnhanceAVideo",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ 2,
+ 0,
+ 1
+ ]
+ },
+ {
+ "id": 54,
+ "type": "Note",
+ "pos": [
+ 1279.785888671875,
+ -927.4588012695312
+ ],
+ "size": [
+ 327.61932373046875,
+ 88
+ ],
+ "flags": {},
+ "order": 8,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "Enhance-a-video can increase the fidelity of the results, too high values lead to noisy results."
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 42,
+ "type": "Note",
+ "pos": [
+ -340.0147399902344,
+ -394.8644104003906
+ ],
+ "size": [
+ 312.98052978515625,
+ 92.32489013671875
+ ],
+ "flags": {},
+ "order": 9,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "Adjust the blocks to swap based on your VRAM, this is a tradeoff between speed and memory usage."
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 61,
+ "type": "MarkdownNote",
+ "pos": [
+ 30.22911262512207,
+ -955.12451171875
+ ],
+ "size": [
+ 510.2661437988281,
+ 245.62203979492188
+ ],
+ "flags": {},
+ "order": 10,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "Models:\n\n[https://huggingface.co/Kijai/WanVideo_comfy_fp8_scaled/blob/main/T2V/Wan2_1-T2V-14B_fp8_e4m3fn_scaled_KJ.safetensors](https://huggingface.co/Kijai/WanVideo_comfy_fp8_scaled/blob/main/T2V/Wan2_1-T2V-14B_fp8_e4m3fn_scaled_KJ.safetensors)\n\nIf you want to use torch compile on GPUs prior to 4000 series:\n\n[https://huggingface.co/Kijai/WanVideo_comfy_fp8_scaled/blob/main/T2V/Wan2_1-T2V-14B_fp8_e5m2_scaled_KJ.safetensors](https://huggingface.co/Kijai/WanVideo_comfy_fp8_scaled/blob/main/T2V/Wan2_1-T2V-14B_fp8_e5m2_scaled_KJ.safetensors)\n\nLoRA:\n\n[https://huggingface.co/Kijai/WanVideo_comfy/blob/main/Lightx2v/lightx2v_T2V_14B_cfg_step_distill_v2_lora_rank64_bf16.safetensors](https://huggingface.co/Kijai/WanVideo_comfy/blob/main/Lightx2v/lightx2v_T2V_14B_cfg_step_distill_v2_lora_rank64_bf16.safetensors)"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 36,
+ "type": "Note",
+ "pos": [
+ 110,
+ -630
+ ],
+ "size": [
+ 374.3061828613281,
+ 171.9547576904297
+ ],
+ "flags": {},
+ "order": 11,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "fp_16_fast enables \"Full FP16 Accmumulation in FP16 GEMMs\" feature available in the very latest pytorch nightly, this is around 20% speed boost. \n\nSageattn if you have it installed can be used for almost double inference speed at higher resolutions\n\nRadial attention is even faster but has worst quality, it should be used along with Set Radial Attention node to control which steps/blocks it's applied on to balance quality and speed."
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 38,
+ "type": "WanVideoVAELoader",
+ "pos": [
+ 1687.4093017578125,
+ -582.2750854492188
+ ],
+ "size": [
+ 315,
+ 82
+ ],
+ "flags": {},
+ "order": 12,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "vae",
+ "type": "WANVAE",
+ "slot_index": 0,
+ "links": [
+ 43
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoVAELoader",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ "wan_2.1_vae.safetensors",
+ "bf16"
+ ],
+ "color": "#322",
+ "bgcolor": "#533"
+ },
+ {
+ "id": 60,
+ "type": "WanVideoLoraSelectMulti",
+ "pos": [
+ 573.026123046875,
+ -824.0180053710938
+ ],
+ "size": [
+ 332.3269348144531,
+ 342
+ ],
+ "flags": {},
+ "order": 13,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "prev_lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "blocks",
+ "shape": 7,
+ "type": "SELECTEDBLOCKS",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "lora",
+ "type": "WANVIDLORA",
+ "links": [
+ 64
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoLoraSelectMulti",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ "Wan21_T2V_14B_lightx2v_cfg_step_distill_lora_rank32.safetensors",
+ 1,
+ "none",
+ 1,
+ "none",
+ 1,
+ "none",
+ 1,
+ "none",
+ 1,
+ false,
+ false
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 22,
+ "type": "WanVideoModelLoader",
+ "pos": [
+ 10,
+ -390
+ ],
+ "size": [
+ 477.4410095214844,
+ 274
+ ],
+ "flags": {},
+ "order": 14,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": null
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": null
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "vram_management_args",
+ "shape": 7,
+ "type": "VRAM_MANAGEMENTARGS",
+ "link": null
+ },
+ {
+ "name": "vace_model",
+ "shape": 7,
+ "type": "VACEPATH",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_model",
+ "shape": 7,
+ "type": "FANTASYTALKINGMODEL",
+ "link": null
+ },
+ {
+ "name": "multitalk_model",
+ "shape": 7,
+ "type": "MULTITALKMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "slot_index": 0,
+ "links": []
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoModelLoader",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ "Wan2_1-T2V-14B_fp8_e5m2.safetensors",
+ "fp16",
+ "fp8_e5m2",
+ "main_device",
+ "sdpa"
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 39,
+ "type": "WanVideoBlockSwap",
+ "pos": [
+ 569.0033569335938,
+ -245.12271118164062
+ ],
+ "size": [
+ 315,
+ 154
+ ],
+ "flags": {},
+ "order": 15,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "block_swap_args",
+ "type": "BLOCKSWAPARGS",
+ "slot_index": 0,
+ "links": [
+ 58
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoBlockSwap",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ 20,
+ false,
+ false,
+ false,
+ 0
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 16,
+ "type": "WanVideoTextEncode",
+ "pos": [
+ 70,
+ -70
+ ],
+ "size": [
+ 420.30511474609375,
+ 261.5306701660156
+ ],
+ "flags": {},
+ "order": 17,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "t5",
+ "shape": 7,
+ "type": "WANTEXTENCODER",
+ "link": 15
+ },
+ {
+ "name": "model_to_offload",
+ "shape": 7,
+ "type": "WANVIDEOMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "text_embeds",
+ "type": "WANVIDEOTEXTEMBEDS",
+ "slot_index": 0,
+ "links": [
+ 30
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoTextEncode",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "5406a72f62adf4a31a8a0a0e4923cc5288399652"
+ },
+ "widgets_values": [
+ "high quality nature video featuring a red panda balancing on a bamboo stem while a bird lands on it's head, on the background there is a waterfall",
+ "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
+ true,
+ false,
+ "cpu"
+ ],
+ "color": "#332922",
+ "bgcolor": "#593930"
+ },
+ {
+ "id": 62,
+ "type": "WanVideoModelLoaderMultiGPU",
+ "pos": [
+ 806.5021362304688,
+ -18.34801483154297
+ ],
+ "size": [
+ 361.5178527832031,
+ 298
+ ],
+ "flags": {},
+ "order": 16,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": null
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": null
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "vram_management_args",
+ "shape": 7,
+ "type": "VRAM_MANAGEMENTARGS",
+ "link": null
+ },
+ {
+ "name": "vace_model",
+ "shape": 7,
+ "type": "VACEPATH",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_model",
+ "shape": 7,
+ "type": "FANTASYTALKINGMODEL",
+ "link": null
+ },
+ {
+ "name": "multitalk_model",
+ "shape": 7,
+ "type": "MULTITALKMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 67
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoModelLoaderMultiGPU"
+ },
+ "widgets_values": [
+ "Wan2_1-T2V-14B_fp8_e5m2.safetensors",
+ "fp16",
+ "fp8_e5m2",
+ "main_device",
+ "sdpa",
+ "cuda:1"
+ ]
+ }
+ ],
+ "links": [
+ [
+ 15,
+ 11,
+ 0,
+ 16,
+ 0,
+ "WANTEXTENCODER"
+ ],
+ [
+ 30,
+ 16,
+ 0,
+ 27,
+ 2,
+ "WANVIDEOTEXTEMBEDS"
+ ],
+ [
+ 33,
+ 27,
+ 0,
+ 28,
+ 1,
+ "LATENT"
+ ],
+ [
+ 36,
+ 28,
+ 0,
+ 30,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 42,
+ 37,
+ 0,
+ 27,
+ 1,
+ "WANVIDIMAGE_EMBEDS"
+ ],
+ [
+ 43,
+ 38,
+ 0,
+ 28,
+ 0,
+ "VAE"
+ ],
+ [
+ 52,
+ 48,
+ 0,
+ 49,
+ 0,
+ "CLIP"
+ ],
+ [
+ 53,
+ 48,
+ 0,
+ 50,
+ 0,
+ "CLIP"
+ ],
+ [
+ 54,
+ 49,
+ 0,
+ 46,
+ 0,
+ "CONDITIONING"
+ ],
+ [
+ 55,
+ 50,
+ 0,
+ 46,
+ 1,
+ "CONDITIONING"
+ ],
+ [
+ 57,
+ 55,
+ 0,
+ 27,
+ 4,
+ "FETAARGS"
+ ],
+ [
+ 58,
+ 39,
+ 0,
+ 56,
+ 1,
+ "BLOCKSWAPARGS"
+ ],
+ [
+ 60,
+ 56,
+ 0,
+ 27,
+ 0,
+ "WANVIDEOMODEL"
+ ],
+ [
+ 62,
+ 58,
+ 0,
+ 56,
+ 0,
+ "WANVIDEOMODEL"
+ ],
+ [
+ 64,
+ 60,
+ 0,
+ 58,
+ 1,
+ "WANVIDLORA"
+ ],
+ [
+ 67,
+ 62,
+ 0,
+ 58,
+ 0,
+ "WANVIDEOMODEL"
+ ]
+ ],
+ "groups": [
+ {
+ "id": 1,
+ "title": "ComfyUI text encoding alternative",
+ "bounding": [
+ 28.03142547607422,
+ 288.1825866699219,
+ 1210.621337890625,
+ 805.9080810546875
+ ],
+ "color": "#3f789e",
+ "font_size": 24,
+ "flags": {}
+ }
+ ],
+ "config": {},
+ "extra": {
+ "ds": {
+ "scale": 0.8954302432552947,
+ "offset": [
+ 573.1206723177218,
+ 778.9430746140687
+ ]
+ },
+ "frontendVersion": "1.23.4",
+ "node_versions": {
+ "ComfyUI-WanVideoWrapper": "5a2383621a05825d0d0437781afcb8552d9590fd",
+ "comfy-core": "0.3.26",
+ "ComfyUI-VideoHelperSuite": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
+ },
+ "VHS_latentpreview": false,
+ "VHS_latentpreviewrate": 0,
+ "VHS_MetadataImage": true,
+ "VHS_KeepIntermediate": true
+ },
+ "version": 0.4
+}
\ No newline at end of file
diff --git a/examples/wanvideo2_2_I2V_A14B_example_WIP_Multigpu.json b/examples/wanvideo2_2_I2V_A14B_example_WIP_Multigpu.json
new file mode 100755
index 0000000..7235812
--- /dev/null
+++ b/examples/wanvideo2_2_I2V_A14B_example_WIP_Multigpu.json
@@ -0,0 +1,2416 @@
+{
+ "id": "c6e410bc-5e2c-460b-ae81-c91b6094fbb1",
+ "revision": 0,
+ "last_node_id": 103,
+ "last_link_id": 178,
+ "nodes": [
+ {
+ "id": 50,
+ "type": "CLIPTextEncode",
+ "pos": [
+ 354.00396728515625,
+ 922.6547241210938
+ ],
+ "size": [
+ 400,
+ 200
+ ],
+ "flags": {},
+ "order": 18,
+ "mode": 2,
+ "inputs": [
+ {
+ "name": "clip",
+ "type": "CLIP",
+ "link": 53
+ }
+ ],
+ "outputs": [
+ {
+ "name": "CONDITIONING",
+ "type": "CONDITIONING",
+ "slot_index": 0,
+ "links": [
+ 55
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "CLIPTextEncode",
+ "cnr_id": "comfy-core",
+ "ver": "0.3.44"
+ },
+ "widgets_values": [
+ "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 48,
+ "type": "CLIPLoader",
+ "pos": [
+ -5.996182441711426,
+ 672.6546020507812
+ ],
+ "size": [
+ 315,
+ 106
+ ],
+ "flags": {},
+ "order": 0,
+ "mode": 2,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "CLIP",
+ "type": "CLIP",
+ "slot_index": 0,
+ "links": [
+ 52,
+ 53
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "CLIPLoader",
+ "cnr_id": "comfy-core",
+ "ver": "0.3.44"
+ },
+ "widgets_values": [
+ "umt5_xxl_fp16.safetensors",
+ "wan",
+ "default"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 51,
+ "type": "Note",
+ "pos": [
+ 24.003835678100586,
+ 502.65411376953125
+ ],
+ "size": [
+ 253.16725158691406,
+ 88
+ ],
+ "flags": {},
+ "order": 1,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "You can also use native ComfyUI text encoding with these nodes instead of the original, the models are node specific and can't otherwise be mixed."
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 49,
+ "type": "CLIPTextEncode",
+ "pos": [
+ 354.00396728515625,
+ 672.6546020507812
+ ],
+ "size": [
+ 400,
+ 200
+ ],
+ "flags": {},
+ "order": 17,
+ "mode": 2,
+ "inputs": [
+ {
+ "name": "clip",
+ "type": "CLIP",
+ "link": 52
+ }
+ ],
+ "outputs": [
+ {
+ "name": "CONDITIONING",
+ "type": "CONDITIONING",
+ "slot_index": 0,
+ "links": [
+ 54
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "CLIPTextEncode",
+ "cnr_id": "comfy-core",
+ "ver": "0.3.44"
+ },
+ "widgets_values": [
+ "high quality nature video featuring a red panda balancing on a bamboo stem while a bird lands on it's head, on the background there is a waterfall"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 46,
+ "type": "WanVideoTextEmbedBridge",
+ "pos": [
+ 804.0042724609375,
+ 662.6546020507812
+ ],
+ "size": [
+ 315,
+ 46
+ ],
+ "flags": {},
+ "order": 27,
+ "mode": 2,
+ "inputs": [
+ {
+ "name": "positive",
+ "type": "CONDITIONING",
+ "link": 54
+ },
+ {
+ "name": "negative",
+ "shape": 7,
+ "type": "CONDITIONING",
+ "link": 55
+ }
+ ],
+ "outputs": [
+ {
+ "name": "text_embeds",
+ "type": "WANVIDEOTEXTEMBEDS",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoTextEmbedBridge",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": []
+ },
+ {
+ "id": 44,
+ "type": "Note",
+ "pos": [
+ -960,
+ -810
+ ],
+ "size": [
+ 303.0501403808594,
+ 88
+ ],
+ "flags": {},
+ "order": 2,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "properties": {},
+ "widgets_values": [
+ "If you have Triton installed, connect this for ~30% speed increase"
+ ],
+ "color": "#432",
+ "bgcolor": "#653"
+ },
+ {
+ "id": 92,
+ "type": "WanVideoSetBlockSwap",
+ "pos": [
+ 538.2930908203125,
+ -699.6842041015625
+ ],
+ "size": [
+ 201.76815795898438,
+ 46
+ ],
+ "flags": {},
+ "order": 23,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 170
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": 176
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 157
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSetBlockSwap",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "7e290c67bff1f906cdab84523018573f6c9d4d7f"
+ },
+ "widgets_values": [],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 79,
+ "type": "WanVideoSetLoRAs",
+ "pos": [
+ 969.6483764648438,
+ -216.53614807128906
+ ],
+ "size": [
+ 222.27981567382812,
+ 46
+ ],
+ "flags": {},
+ "order": 28,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 161
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": 169
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 144
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSetLoRAs",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 38,
+ "type": "WanVideoVAELoader",
+ "pos": [
+ 1373.9725341796875,
+ -991.5189208984375
+ ],
+ "size": [
+ 315,
+ 82
+ ],
+ "flags": {},
+ "order": 3,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "vae",
+ "type": "WANVAE",
+ "slot_index": 0,
+ "links": []
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoVAELoader",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ "wanvideo\\Wan2_1_VAE_bf16.safetensors",
+ "bf16"
+ ],
+ "color": "#322",
+ "bgcolor": "#533"
+ },
+ {
+ "id": 28,
+ "type": "WanVideoDecode",
+ "pos": [
+ 2620.946533203125,
+ -519.3373413085938
+ ],
+ "size": [
+ 315,
+ 198
+ ],
+ "flags": {},
+ "order": 33,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "vae",
+ "type": "WANVAE",
+ "link": 178
+ },
+ {
+ "name": "samples",
+ "type": "LATENT",
+ "link": 151
+ }
+ ],
+ "outputs": [
+ {
+ "name": "images",
+ "type": "IMAGE",
+ "slot_index": 0,
+ "links": [
+ 76
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoDecode",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ false,
+ 272,
+ 272,
+ 144,
+ 128,
+ "default"
+ ],
+ "color": "#322",
+ "bgcolor": "#533"
+ },
+ {
+ "id": 91,
+ "type": "INTConstant",
+ "pos": [
+ 1554.34130859375,
+ 293.0675964355469
+ ],
+ "size": [
+ 210,
+ 58
+ ],
+ "flags": {},
+ "order": 4,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "value",
+ "type": "INT",
+ "links": [
+ 153,
+ 154
+ ]
+ }
+ ],
+ "title": "Split_step",
+ "properties": {
+ "Node name for S&R": "INTConstant",
+ "cnr_id": "comfyui-kjnodes",
+ "ver": "a6b867b63a29ca48ddb15c589e17a9f2d8530d57"
+ },
+ "widgets_values": [
+ 3
+ ],
+ "color": "#1b4669",
+ "bgcolor": "#29699c"
+ },
+ {
+ "id": 80,
+ "type": "WanVideoSetLoRAs",
+ "pos": [
+ 985.8822021484375,
+ -458.0684814453125
+ ],
+ "size": [
+ 222.27981567382812,
+ 46
+ ],
+ "flags": {},
+ "order": 29,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 157
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": 110
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 109
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSetLoRAs",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 69,
+ "type": "GetImageSizeAndCount",
+ "pos": [
+ 2725.78076171875,
+ -249.85873413085938
+ ],
+ "size": [
+ 240.41265869140625,
+ 86
+ ],
+ "flags": {},
+ "order": 34,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "link": 76
+ }
+ ],
+ "outputs": [
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "links": [
+ 77
+ ]
+ },
+ {
+ "label": "704 width",
+ "name": "width",
+ "type": "INT",
+ "links": null
+ },
+ {
+ "label": "704 height",
+ "name": "height",
+ "type": "INT",
+ "links": null
+ },
+ {
+ "label": "81 count",
+ "name": "count",
+ "type": "INT",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "GetImageSizeAndCount",
+ "cnr_id": "comfyui-kjnodes",
+ "ver": "a6b867b63a29ca48ddb15c589e17a9f2d8530d57"
+ },
+ "widgets_values": []
+ },
+ {
+ "id": 27,
+ "type": "WanVideoSampler",
+ "pos": [
+ 1833.1953125,
+ -394.93426513671875
+ ],
+ "size": [
+ 315,
+ 975
+ ],
+ "flags": {},
+ "order": 31,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 109
+ },
+ {
+ "name": "image_embeds",
+ "type": "WANVIDIMAGE_EMBEDS",
+ "link": 138
+ },
+ {
+ "name": "text_embeds",
+ "shape": 7,
+ "type": "WANVIDEOTEXTEMBEDS",
+ "link": 171
+ },
+ {
+ "name": "samples",
+ "shape": 7,
+ "type": "LATENT",
+ "link": null
+ },
+ {
+ "name": "feta_args",
+ "shape": 7,
+ "type": "FETAARGS",
+ "link": null
+ },
+ {
+ "name": "context_options",
+ "shape": 7,
+ "type": "WANVIDCONTEXT",
+ "link": null
+ },
+ {
+ "name": "cache_args",
+ "shape": 7,
+ "type": "CACHEARGS",
+ "link": null
+ },
+ {
+ "name": "flowedit_args",
+ "shape": 7,
+ "type": "FLOWEDITARGS",
+ "link": null
+ },
+ {
+ "name": "slg_args",
+ "shape": 7,
+ "type": "SLGARGS",
+ "link": null
+ },
+ {
+ "name": "loop_args",
+ "shape": 7,
+ "type": "LOOPARGS",
+ "link": null
+ },
+ {
+ "name": "experimental_args",
+ "shape": 7,
+ "type": "EXPERIMENTALARGS",
+ "link": null
+ },
+ {
+ "name": "sigmas",
+ "shape": 7,
+ "type": "SIGMAS",
+ "link": null
+ },
+ {
+ "name": "unianimate_poses",
+ "shape": 7,
+ "type": "UNIANIMATE_POSE",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_embeds",
+ "shape": 7,
+ "type": "FANTASYTALKING_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "uni3c_embeds",
+ "shape": 7,
+ "type": "UNI3C_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "multitalk_embeds",
+ "shape": 7,
+ "type": "MULTITALK_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "freeinit_args",
+ "shape": 7,
+ "type": "FREEINITARGS",
+ "link": null
+ },
+ {
+ "name": "steps",
+ "type": "INT",
+ "widget": {
+ "name": "steps"
+ },
+ "link": 163
+ },
+ {
+ "name": "cfg",
+ "type": "FLOAT",
+ "widget": {
+ "name": "cfg"
+ },
+ "link": 167
+ },
+ {
+ "name": "end_step",
+ "shape": 7,
+ "type": "INT",
+ "widget": {
+ "name": "end_step"
+ },
+ "link": 153
+ }
+ ],
+ "outputs": [
+ {
+ "name": "samples",
+ "type": "LATENT",
+ "slot_index": 0,
+ "links": [
+ 143
+ ]
+ },
+ {
+ "name": "denoised_samples",
+ "type": "LATENT",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSampler",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ 6,
+ 1,
+ 8,
+ 43,
+ "fixed",
+ true,
+ "dpm++_sde",
+ 0,
+ 1,
+ false,
+ "comfy",
+ 0,
+ 10,
+ ""
+ ]
+ },
+ {
+ "id": 90,
+ "type": "WanVideoSampler",
+ "pos": [
+ 2206.047119140625,
+ -393.0194396972656
+ ],
+ "size": [
+ 315,
+ 975
+ ],
+ "flags": {},
+ "order": 32,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 144
+ },
+ {
+ "name": "image_embeds",
+ "type": "WANVIDIMAGE_EMBEDS",
+ "link": 149
+ },
+ {
+ "name": "text_embeds",
+ "shape": 7,
+ "type": "WANVIDEOTEXTEMBEDS",
+ "link": 172
+ },
+ {
+ "name": "samples",
+ "shape": 7,
+ "type": "LATENT",
+ "link": 143
+ },
+ {
+ "name": "feta_args",
+ "shape": 7,
+ "type": "FETAARGS",
+ "link": null
+ },
+ {
+ "name": "context_options",
+ "shape": 7,
+ "type": "WANVIDCONTEXT",
+ "link": null
+ },
+ {
+ "name": "cache_args",
+ "shape": 7,
+ "type": "CACHEARGS",
+ "link": null
+ },
+ {
+ "name": "flowedit_args",
+ "shape": 7,
+ "type": "FLOWEDITARGS",
+ "link": null
+ },
+ {
+ "name": "slg_args",
+ "shape": 7,
+ "type": "SLGARGS",
+ "link": null
+ },
+ {
+ "name": "loop_args",
+ "shape": 7,
+ "type": "LOOPARGS",
+ "link": null
+ },
+ {
+ "name": "experimental_args",
+ "shape": 7,
+ "type": "EXPERIMENTALARGS",
+ "link": null
+ },
+ {
+ "name": "sigmas",
+ "shape": 7,
+ "type": "SIGMAS",
+ "link": null
+ },
+ {
+ "name": "unianimate_poses",
+ "shape": 7,
+ "type": "UNIANIMATE_POSE",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_embeds",
+ "shape": 7,
+ "type": "FANTASYTALKING_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "uni3c_embeds",
+ "shape": 7,
+ "type": "UNI3C_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "multitalk_embeds",
+ "shape": 7,
+ "type": "MULTITALK_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "freeinit_args",
+ "shape": 7,
+ "type": "FREEINITARGS",
+ "link": null
+ },
+ {
+ "name": "steps",
+ "type": "INT",
+ "widget": {
+ "name": "steps"
+ },
+ "link": 164
+ },
+ {
+ "name": "start_step",
+ "shape": 7,
+ "type": "INT",
+ "widget": {
+ "name": "start_step"
+ },
+ "link": 154
+ }
+ ],
+ "outputs": [
+ {
+ "name": "samples",
+ "type": "LATENT",
+ "slot_index": 0,
+ "links": [
+ 151
+ ]
+ },
+ {
+ "name": "denoised_samples",
+ "type": "LATENT",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSampler",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ 6,
+ 1,
+ 8,
+ 43,
+ "fixed",
+ true,
+ "dpm++_sde",
+ 0,
+ 1,
+ false,
+ "comfy",
+ 10,
+ -1,
+ ""
+ ]
+ },
+ {
+ "id": 94,
+ "type": "INTConstant",
+ "pos": [
+ 1446.0140380859375,
+ -77.41889953613281
+ ],
+ "size": [
+ 210,
+ 58
+ ],
+ "flags": {},
+ "order": 5,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "value",
+ "type": "INT",
+ "links": [
+ 163,
+ 164,
+ 165
+ ]
+ }
+ ],
+ "title": "Steps",
+ "properties": {
+ "Node name for S&R": "INTConstant",
+ "cnr_id": "comfyui-kjnodes",
+ "ver": "a6b867b63a29ca48ddb15c589e17a9f2d8530d57"
+ },
+ "widgets_values": [
+ 6
+ ],
+ "color": "#1b4669",
+ "bgcolor": "#29699c"
+ },
+ {
+ "id": 95,
+ "type": "CreateCFGScheduleFloatList",
+ "pos": [
+ 1455.8336181640625,
+ 44.19880294799805
+ ],
+ "size": [
+ 298.3199157714844,
+ 178
+ ],
+ "flags": {},
+ "order": 19,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "steps",
+ "type": "INT",
+ "widget": {
+ "name": "steps"
+ },
+ "link": 165
+ }
+ ],
+ "outputs": [
+ {
+ "name": "float_list",
+ "type": "FLOAT",
+ "links": [
+ 167
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "CreateCFGScheduleFloatList",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "7e290c67bff1f906cdab84523018573f6c9d4d7f"
+ },
+ "widgets_values": [
+ 30,
+ 2,
+ 2,
+ "linear",
+ 0,
+ 0.01
+ ]
+ },
+ {
+ "id": 60,
+ "type": "VHS_VideoCombine",
+ "pos": [
+ 3150,
+ -390
+ ],
+ "size": [
+ 698.6392211914062,
+ 334
+ ],
+ "flags": {},
+ "order": 35,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "images",
+ "type": "IMAGE",
+ "link": 77
+ },
+ {
+ "name": "audio",
+ "shape": 7,
+ "type": "AUDIO",
+ "link": null
+ },
+ {
+ "name": "meta_batch",
+ "shape": 7,
+ "type": "VHS_BatchManager",
+ "link": null
+ },
+ {
+ "name": "vae",
+ "shape": 7,
+ "type": "VAE",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "Filenames",
+ "type": "VHS_FILENAMES",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "VHS_VideoCombine",
+ "cnr_id": "comfyui-videohelpersuite",
+ "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
+ },
+ "widgets_values": {
+ "frame_rate": 16,
+ "loop_count": 0,
+ "filename_prefix": "WanVideo2_2_I2V",
+ "format": "video/h264-mp4",
+ "pix_fmt": "yuv420p",
+ "crf": 19,
+ "save_metadata": true,
+ "trim_to_audio": false,
+ "pingpong": false,
+ "save_output": false,
+ "videopreview": {
+ "hidden": false,
+ "paused": false,
+ "params": {
+ "filename": "WanVideo2_2_I2V_00006.mp4",
+ "subfolder": "",
+ "type": "temp",
+ "format": "video/h264-mp4",
+ "frame_rate": 16,
+ "workflow": "WanVideo2_2_I2V_00006.png",
+ "fullpath": "N:\\AI\\ComfyUI\\temp\\WanVideo2_2_I2V_00006.mp4"
+ }
+ }
+ }
+ },
+ {
+ "id": 89,
+ "type": "WanVideoImageToVideoEncode",
+ "pos": [
+ 1401.11962890625,
+ -698.7300415039062
+ ],
+ "size": [
+ 308.2320251464844,
+ 390
+ ],
+ "flags": {},
+ "order": 30,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "vae",
+ "type": "WANVAE",
+ "link": 177
+ },
+ {
+ "name": "clip_embeds",
+ "shape": 7,
+ "type": "WANVIDIMAGE_CLIPEMBEDS",
+ "link": null
+ },
+ {
+ "name": "start_image",
+ "shape": 7,
+ "type": "IMAGE",
+ "link": 139
+ },
+ {
+ "name": "end_image",
+ "shape": 7,
+ "type": "IMAGE",
+ "link": null
+ },
+ {
+ "name": "control_embeds",
+ "shape": 7,
+ "type": "WANVIDIMAGE_EMBEDS",
+ "link": null
+ },
+ {
+ "name": "temporal_mask",
+ "shape": 7,
+ "type": "MASK",
+ "link": null
+ },
+ {
+ "name": "extra_latents",
+ "shape": 7,
+ "type": "LATENT",
+ "link": null
+ },
+ {
+ "name": "add_cond_latents",
+ "shape": 7,
+ "type": "ADD_COND_LATENTS",
+ "link": null
+ },
+ {
+ "name": "width",
+ "type": "INT",
+ "widget": {
+ "name": "width"
+ },
+ "link": 141
+ },
+ {
+ "name": "height",
+ "type": "INT",
+ "widget": {
+ "name": "height"
+ },
+ "link": 142
+ }
+ ],
+ "outputs": [
+ {
+ "name": "image_embeds",
+ "type": "WANVIDIMAGE_EMBEDS",
+ "links": [
+ 138,
+ 149
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoImageToVideoEncode",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "7e290c67bff1f906cdab84523018573f6c9d4d7f"
+ },
+ "widgets_values": [
+ 832,
+ 480,
+ 81,
+ 0,
+ 1,
+ 1,
+ true,
+ false,
+ false
+ ],
+ "color": "#322",
+ "bgcolor": "#533"
+ },
+ {
+ "id": 68,
+ "type": "ImageResizeKJv2",
+ "pos": [
+ 696.0801391601562,
+ -1143.5843505859375
+ ],
+ "size": [
+ 270,
+ 336
+ ],
+ "flags": {},
+ "order": 26,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "link": 71
+ },
+ {
+ "name": "mask",
+ "shape": 7,
+ "type": "MASK",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "IMAGE",
+ "type": "IMAGE",
+ "links": [
+ 139
+ ]
+ },
+ {
+ "name": "width",
+ "type": "INT",
+ "links": [
+ 141
+ ]
+ },
+ {
+ "name": "height",
+ "type": "INT",
+ "links": [
+ 142
+ ]
+ },
+ {
+ "name": "mask",
+ "type": "MASK",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "ImageResizeKJv2",
+ "cnr_id": "comfyui-kjnodes",
+ "ver": "a6b867b63a29ca48ddb15c589e17a9f2d8530d57"
+ },
+ "widgets_values": [
+ 720,
+ 720,
+ "lanczos",
+ "crop",
+ "0, 0, 0",
+ "center",
+ 32,
+ "cpu",
+ "
| Output: | 1 x 704 x 704 | 5.67MB |
"
+ ]
+ },
+ {
+ "id": 35,
+ "type": "WanVideoTorchCompileSettings",
+ "pos": [
+ -607.4757080078125,
+ -680.7272338867188
+ ],
+ "size": [
+ 390.5999755859375,
+ 202
+ ],
+ "flags": {},
+ "order": 6,
+ "mode": 4,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "torch_compile_args",
+ "type": "WANCOMPILEARGS",
+ "slot_index": 0,
+ "links": [
+ 111,
+ 112
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoTorchCompileSettings",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ "inductor",
+ false,
+ "default",
+ false,
+ 64,
+ true,
+ 128
+ ]
+ },
+ {
+ "id": 22,
+ "type": "WanVideoModelLoader",
+ "pos": [
+ -753.6970825195312,
+ -1178.89697265625
+ ],
+ "size": [
+ 477.4410095214844,
+ 274
+ ],
+ "flags": {},
+ "order": 20,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": 111
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": null
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "vram_management_args",
+ "shape": 7,
+ "type": "VRAM_MANAGEMENTARGS",
+ "link": null
+ },
+ {
+ "name": "vace_model",
+ "shape": 7,
+ "type": "VACEPATH",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_model",
+ "shape": 7,
+ "type": "FANTASYTALKINGMODEL",
+ "link": null
+ },
+ {
+ "name": "multitalk_model",
+ "shape": 7,
+ "type": "MULTITALKMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "slot_index": 0,
+ "links": []
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoModelLoader",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ "WanVideo\\2_2\\Wan2_2-I2V-A14B-HIGH_fp8_e4m3fn_scaled_KJ.safetensors",
+ "fp16_fast",
+ "fp8_e4m3fn_scaled",
+ "offload_device",
+ "sageattn"
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 71,
+ "type": "WanVideoModelLoader",
+ "pos": [
+ -243.86578369140625,
+ -1195.5584716796875
+ ],
+ "size": [
+ 477.4410095214844,
+ 274
+ ],
+ "flags": {},
+ "order": 21,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": 112
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": null
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "vram_management_args",
+ "shape": 7,
+ "type": "VRAM_MANAGEMENTARGS",
+ "link": null
+ },
+ {
+ "name": "vace_model",
+ "shape": 7,
+ "type": "VACEPATH",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_model",
+ "shape": 7,
+ "type": "FANTASYTALKINGMODEL",
+ "link": null
+ },
+ {
+ "name": "multitalk_model",
+ "shape": 7,
+ "type": "MULTITALKMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "slot_index": 0,
+ "links": []
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoModelLoader",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ "WanVideo\\2_2\\Wan2_2-I2V-A14B-LOW_fp8_e4m3fn_scaled_KJ.safetensors",
+ "fp16_fast",
+ "fp8_e4m3fn_scaled",
+ "offload_device",
+ "sageattn"
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 101,
+ "type": "WanVideoModelLoaderMultiGPU",
+ "pos": [
+ -48.42073440551758,
+ -270.9344787597656
+ ],
+ "size": [
+ 517.1905517578125,
+ 274
+ ],
+ "flags": {},
+ "order": 7,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": null
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": null
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "vram_management_args",
+ "shape": 7,
+ "type": "VRAM_MANAGEMENTARGS",
+ "link": null
+ },
+ {
+ "name": "vace_model",
+ "shape": 7,
+ "type": "VACEPATH",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_model",
+ "shape": 7,
+ "type": "FANTASYTALKINGMODEL",
+ "link": null
+ },
+ {
+ "name": "multitalk_model",
+ "shape": 7,
+ "type": "MULTITALKMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 174
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoModelLoaderMultiGPU"
+ },
+ "widgets_values": [
+ "Wan2_2-I2V-A14B-LOW_fp8_e4m3fn_scaled_KJ.safetensors",
+ "fp16_fast",
+ "fp8_e4m3fn_scaled",
+ "cuda:1",
+ "sageattn"
+ ],
+ "color": "#233",
+ "bgcolor": "#355"
+ },
+ {
+ "id": 39,
+ "type": "WanVideoBlockSwap",
+ "pos": [
+ -686.1574096679688,
+ -1163.7584228515625
+ ],
+ "size": [
+ 315,
+ 154
+ ],
+ "flags": {},
+ "order": 8,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "block_swap_args",
+ "type": "BLOCKSWAPARGS",
+ "slot_index": 0,
+ "links": []
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoBlockSwap",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ 20,
+ false,
+ false,
+ false,
+ 1
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 93,
+ "type": "WanVideoSetBlockSwap",
+ "pos": [
+ 585.5255737304688,
+ -328.9944152832031
+ ],
+ "size": [
+ 201.76815795898438,
+ 46
+ ],
+ "flags": {},
+ "order": 22,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "link": 174
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": 175
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 161
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoSetBlockSwap",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "7e290c67bff1f906cdab84523018573f6c9d4d7f"
+ },
+ "widgets_values": [],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 98,
+ "type": "WanVideoModelLoaderMultiGPU",
+ "pos": [
+ -66.14433288574219,
+ -761.9495849609375
+ ],
+ "size": [
+ 517.1905517578125,
+ 274
+ ],
+ "flags": {},
+ "order": 9,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": null
+ },
+ {
+ "name": "block_swap_args",
+ "shape": 7,
+ "type": "BLOCKSWAPARGS",
+ "link": null
+ },
+ {
+ "name": "lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "vram_management_args",
+ "shape": 7,
+ "type": "VRAM_MANAGEMENTARGS",
+ "link": null
+ },
+ {
+ "name": "vace_model",
+ "shape": 7,
+ "type": "VACEPATH",
+ "link": null
+ },
+ {
+ "name": "fantasytalking_model",
+ "shape": 7,
+ "type": "FANTASYTALKINGMODEL",
+ "link": null
+ },
+ {
+ "name": "multitalk_model",
+ "shape": 7,
+ "type": "MULTITALKMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "model",
+ "type": "WANVIDEOMODEL",
+ "links": [
+ 170
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoModelLoaderMultiGPU"
+ },
+ "widgets_values": [
+ "Wan2_2-I2V-A14B-HIGH_fp8_e4m3fn_scaled_KJ.safetensors",
+ "fp16_fast",
+ "fp8_e4m3fn_scaled",
+ "cuda:0",
+ "sageattn"
+ ],
+ "color": "#233",
+ "bgcolor": "#355"
+ },
+ {
+ "id": 102,
+ "type": "WanVideoBlockSwapMultiGPU",
+ "pos": [
+ 511.4704895019531,
+ -106.43546295166016
+ ],
+ "size": [
+ 292.8716735839844,
+ 202
+ ],
+ "flags": {},
+ "order": 10,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "block_swap_args",
+ "type": "BLOCKSWAPARGS",
+ "links": [
+ 175,
+ 176
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoBlockSwapMultiGPU"
+ },
+ "widgets_values": [
+ 5,
+ "cuda:2",
+ "cpu",
+ false,
+ false,
+ false,
+ 0
+ ],
+ "color": "#233",
+ "bgcolor": "#355"
+ },
+ {
+ "id": 100,
+ "type": "LoadWanVideoT5TextEncoderMultiGPU",
+ "pos": [
+ -690.5611572265625,
+ 159.14117431640625
+ ],
+ "size": [
+ 348.9195251464844,
+ 130
+ ],
+ "flags": {},
+ "order": 11,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "wan_t5_model",
+ "type": "WANTEXTENCODER",
+ "links": [
+ 173
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LoadWanVideoT5TextEncoderMultiGPU"
+ },
+ "widgets_values": [
+ "umt5-xxl-enc-bf16.safetensors",
+ "bf16",
+ "cpu",
+ "disabled"
+ ],
+ "color": "#233",
+ "bgcolor": "#355"
+ },
+ {
+ "id": 99,
+ "type": "WanVideoTextEncodeMultiGPU",
+ "pos": [
+ -255.53073120117188,
+ 146.2587890625
+ ],
+ "size": [
+ 400,
+ 234
+ ],
+ "flags": {},
+ "order": 24,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "t5",
+ "shape": 7,
+ "type": "WANTEXTENCODER",
+ "link": 173
+ },
+ {
+ "name": "model_to_offload",
+ "shape": 7,
+ "type": "WANVIDEOMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "text_embeds",
+ "type": "WANVIDEOTEXTEMBEDS",
+ "links": [
+ 171,
+ 172
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoTextEncodeMultiGPU"
+ },
+ "widgets_values": [
+ "old man gets up and jumps into the lake",
+ "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
+ "cpu",
+ false,
+ false
+ ],
+ "color": "#233",
+ "bgcolor": "#355"
+ },
+ {
+ "id": 16,
+ "type": "WanVideoTextEncode",
+ "pos": [
+ 965.2448120117188,
+ 229.54461669921875
+ ],
+ "size": [
+ 474.3573303222656,
+ 316.48370361328125
+ ],
+ "flags": {},
+ "order": 25,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "t5",
+ "shape": 7,
+ "type": "WANTEXTENCODER",
+ "link": 15
+ },
+ {
+ "name": "model_to_offload",
+ "shape": 7,
+ "type": "WANVIDEOMODEL",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "text_embeds",
+ "type": "WANVIDEOTEXTEMBEDS",
+ "slot_index": 0,
+ "links": []
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoTextEncode",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ "old man gets up and jumps into the lake",
+ "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
+ true,
+ false,
+ "gpu"
+ ],
+ "color": "#332922",
+ "bgcolor": "#593930"
+ },
+ {
+ "id": 11,
+ "type": "LoadWanVideoT5TextEncoder",
+ "pos": [
+ 619.16357421875,
+ 344.40069580078125
+ ],
+ "size": [
+ 377.1661376953125,
+ 130
+ ],
+ "flags": {},
+ "order": 12,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "wan_t5_model",
+ "type": "WANTEXTENCODER",
+ "slot_index": 0,
+ "links": [
+ 15
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LoadWanVideoT5TextEncoder",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ "umt5-xxl-enc-bf16.safetensors",
+ "bf16",
+ "offload_device",
+ "disabled"
+ ],
+ "color": "#332922",
+ "bgcolor": "#593930"
+ },
+ {
+ "id": 56,
+ "type": "WanVideoLoraSelect",
+ "pos": [
+ -765.4373168945312,
+ -481.49810791015625
+ ],
+ "size": [
+ 659.4812622070312,
+ 150
+ ],
+ "flags": {},
+ "order": 13,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "prev_lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "blocks",
+ "shape": 7,
+ "type": "SELECTEDBLOCKS",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "lora",
+ "type": "WANVIDLORA",
+ "links": [
+ 110
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoLoraSelect",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ "lightx2v_I2V_14B_480p_cfg_step_distill_rank64_bf16.safetensors",
+ 3,
+ false,
+ false
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 97,
+ "type": "WanVideoLoraSelect",
+ "pos": [
+ -717.8909301757812,
+ -252.48538208007812
+ ],
+ "size": [
+ 624.4888305664062,
+ 150
+ ],
+ "flags": {},
+ "order": 14,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "prev_lora",
+ "shape": 7,
+ "type": "WANVIDLORA",
+ "link": null
+ },
+ {
+ "name": "blocks",
+ "shape": 7,
+ "type": "SELECTEDBLOCKS",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "lora",
+ "type": "WANVIDLORA",
+ "links": [
+ 169
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoLoraSelect",
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "998a69cc0acbec503001b8b0ce0a5d5404420e1e"
+ },
+ "widgets_values": [
+ "lightx2v_I2V_14B_480p_cfg_step_distill_rank64_bf16.safetensors",
+ 1,
+ false,
+ false
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
+ },
+ {
+ "id": 67,
+ "type": "LoadImage",
+ "pos": [
+ 330.2861633300781,
+ -1144.739013671875
+ ],
+ "size": [
+ 274.080078125,
+ 314
+ ],
+ "flags": {},
+ "order": 15,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "IMAGE",
+ "type": "IMAGE",
+ "links": [
+ 71
+ ]
+ },
+ {
+ "name": "MASK",
+ "type": "MASK",
+ "links": null
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LoadImage",
+ "cnr_id": "comfy-core",
+ "ver": "0.3.44"
+ },
+ "widgets_values": [
+ "Google_AI_Studio_2025-08-05T15_03_28.397Z.png",
+ "image"
+ ]
+ },
+ {
+ "id": 103,
+ "type": "WanVideoVAELoaderMultiGPU",
+ "pos": [
+ 2108.89453125,
+ -1214.3260498046875
+ ],
+ "size": [
+ 294.1841735839844,
+ 106
+ ],
+ "flags": {},
+ "order": 16,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "compile_args",
+ "shape": 7,
+ "type": "WANCOMPILEARGS",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "vae",
+ "type": "WANVAE",
+ "links": [
+ 177,
+ 178
+ ]
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "WanVideoVAELoaderMultiGPU"
+ },
+ "widgets_values": [
+ "wan_2.1_vae.safetensors",
+ "cuda:0",
+ "bf16"
+ ]
+ }
+ ],
+ "links": [
+ [
+ 15,
+ 11,
+ 0,
+ 16,
+ 0,
+ "WANTEXTENCODER"
+ ],
+ [
+ 52,
+ 48,
+ 0,
+ 49,
+ 0,
+ "CLIP"
+ ],
+ [
+ 53,
+ 48,
+ 0,
+ 50,
+ 0,
+ "CLIP"
+ ],
+ [
+ 54,
+ 49,
+ 0,
+ 46,
+ 0,
+ "CONDITIONING"
+ ],
+ [
+ 55,
+ 50,
+ 0,
+ 46,
+ 1,
+ "CONDITIONING"
+ ],
+ [
+ 71,
+ 67,
+ 0,
+ 68,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 76,
+ 28,
+ 0,
+ 69,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 77,
+ 69,
+ 0,
+ 60,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 109,
+ 80,
+ 0,
+ 27,
+ 0,
+ "WANVIDEOMODEL"
+ ],
+ [
+ 110,
+ 56,
+ 0,
+ 80,
+ 1,
+ "WANVIDLORA"
+ ],
+ [
+ 111,
+ 35,
+ 0,
+ 22,
+ 0,
+ "WANCOMPILEARGS"
+ ],
+ [
+ 112,
+ 35,
+ 0,
+ 71,
+ 0,
+ "WANCOMPILEARGS"
+ ],
+ [
+ 138,
+ 89,
+ 0,
+ 27,
+ 1,
+ "WANVIDIMAGE_EMBEDS"
+ ],
+ [
+ 139,
+ 68,
+ 0,
+ 89,
+ 2,
+ "IMAGE"
+ ],
+ [
+ 141,
+ 68,
+ 1,
+ 89,
+ 8,
+ "INT"
+ ],
+ [
+ 142,
+ 68,
+ 2,
+ 89,
+ 9,
+ "INT"
+ ],
+ [
+ 143,
+ 27,
+ 0,
+ 90,
+ 3,
+ "LATENT"
+ ],
+ [
+ 144,
+ 79,
+ 0,
+ 90,
+ 0,
+ "WANVIDEOMODEL"
+ ],
+ [
+ 149,
+ 89,
+ 0,
+ 90,
+ 1,
+ "WANVIDIMAGE_EMBEDS"
+ ],
+ [
+ 151,
+ 90,
+ 0,
+ 28,
+ 1,
+ "LATENT"
+ ],
+ [
+ 153,
+ 91,
+ 0,
+ 27,
+ 19,
+ "INT"
+ ],
+ [
+ 154,
+ 91,
+ 0,
+ 90,
+ 18,
+ "INT"
+ ],
+ [
+ 157,
+ 92,
+ 0,
+ 80,
+ 0,
+ "WANVIDEOMODEL"
+ ],
+ [
+ 161,
+ 93,
+ 0,
+ 79,
+ 0,
+ "WANVIDEOMODEL"
+ ],
+ [
+ 163,
+ 94,
+ 0,
+ 27,
+ 17,
+ "INT"
+ ],
+ [
+ 164,
+ 94,
+ 0,
+ 90,
+ 17,
+ "INT"
+ ],
+ [
+ 165,
+ 94,
+ 0,
+ 95,
+ 0,
+ "INT"
+ ],
+ [
+ 167,
+ 95,
+ 0,
+ 27,
+ 18,
+ "FLOAT"
+ ],
+ [
+ 169,
+ 97,
+ 0,
+ 79,
+ 1,
+ "WANVIDLORA"
+ ],
+ [
+ 170,
+ 98,
+ 0,
+ 92,
+ 0,
+ "WANVIDEOMODEL"
+ ],
+ [
+ 171,
+ 99,
+ 0,
+ 27,
+ 2,
+ "WANVIDEOTEXTEMBEDS"
+ ],
+ [
+ 172,
+ 99,
+ 0,
+ 90,
+ 2,
+ "WANVIDEOTEXTEMBEDS"
+ ],
+ [
+ 173,
+ 100,
+ 0,
+ 99,
+ 0,
+ "WANTEXTENCODER"
+ ],
+ [
+ 174,
+ 101,
+ 0,
+ 93,
+ 0,
+ "WANVIDEOMODEL"
+ ],
+ [
+ 175,
+ 102,
+ 0,
+ 93,
+ 1,
+ "BLOCKSWAPARGS"
+ ],
+ [
+ 176,
+ 102,
+ 0,
+ 92,
+ 1,
+ "BLOCKSWAPARGS"
+ ],
+ [
+ 177,
+ 103,
+ 0,
+ 89,
+ 0,
+ "WANVAE"
+ ],
+ [
+ 178,
+ 103,
+ 0,
+ 28,
+ 0,
+ "WANVAE"
+ ]
+ ],
+ "groups": [
+ {
+ "id": 1,
+ "title": "ComfyUI text encoding alternative",
+ "bounding": [
+ -68.81207275390625,
+ 358.7208251953125,
+ 1210.621337890625,
+ 805.9080810546875
+ ],
+ "color": "#3f789e",
+ "font_size": 24,
+ "flags": {}
+ }
+ ],
+ "config": {},
+ "extra": {
+ "ds": {
+ "scale": 0.8140274938684497,
+ "offset": [
+ -669.4490760716634,
+ 1291.4569748042109
+ ]
+ },
+ "frontendVersion": "1.23.4",
+ "node_versions": {
+ "ComfyUI-WanVideoWrapper": "5a2383621a05825d0d0437781afcb8552d9590fd",
+ "comfy-core": "0.3.26",
+ "ComfyUI-VideoHelperSuite": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
+ },
+ "VHS_latentpreview": false,
+ "VHS_latentpreviewrate": 0,
+ "VHS_MetadataImage": true,
+ "VHS_KeepIntermediate": true
+ },
+ "version": 0.4
+}
\ No newline at end of file
diff --git a/nodes.py b/nodes.py
index 25456df..ff4a9c7 100644
--- a/nodes.py
+++ b/nodes.py
@@ -495,18 +495,20 @@ class DownloadAndLoadHyVideoTextEncoder:
class WanVideoModelLoader:
@classmethod
def INPUT_TYPES(s):
+ # Use the existing get_device_list function
+ from . import get_device_list
+ devices = get_device_list()
+
return {
"required": {
- "model": (folder_paths.get_filename_list("diffusion_models"),
+ "model": (folder_paths.get_filename_list("unet_gguf") + folder_paths.get_filename_list("diffusion_models"),
{"tooltip": "These models are loaded from the 'ComfyUI/models/diffusion_models' folder",}),
"base_precision": (["fp32", "bf16", "fp16", "fp16_fast"], {"default": "bf16"}),
"quantization": (
- ['disabled', 'fp8_e4m3fn', 'fp8_e4m3fn_fast', 'fp8_e5m2', 'fp8_scaled',
- 'torchao_fp8dq', "torchao_fp8dqrow", "torchao_int8dq", "torchao_fp6",
- "torchao_int4", "torchao_int8"],
- {"default": 'disabled', "tooltip": "optional quantization method"}
+ ["disabled", "fp8_e4m3fn", "fp8_e4m3fn_fast", "fp8_e5m2", "fp8_e4m3fn_fast_no_ffn", "fp8_e4m3fn_scaled", "fp8_e5m2_scaled"],
+ {"default": "disabled", "tooltip": "optional quantization method"}
),
- "load_device": (["main_device"], {"default": "main_device"}),
+ "device": (devices, {"default": devices[1] if len(devices) > 1 else devices[0], "tooltip": "Device to load the model to"}),
},
"optional": {
"attention_mode": ([
@@ -514,12 +516,17 @@ class WanVideoModelLoader:
"flash_attn_2",
"flash_attn_3",
"sageattn",
+ "sageattn_3",
+ "flex_attention",
+ "radial_sage_attention",
], {"default": "sdpa"}),
"compile_args": ("WANCOMPILEARGS", ),
"block_swap_args": ("BLOCKSWAPARGS", ),
"lora": ("WANVIDLORA", {"default": None}),
- "vram_management_args": ("VRAM_MANAGEMENTARGS",
- {"default": None, "tooltip": "Alternative offloading method"}),
+ "vram_management_args": ("VRAM_MANAGEMENTARGS", {"default": None, "tooltip": "Alternative offloading method from DiffSynth-Studio, more aggressive in reducing memory use than block swapping, but can be slower"}),
+ "vace_model": ("VACEPATH", {"default": None, "tooltip": "VACE model to use when not using model that has it included"}),
+ "fantasytalking_model": ("FANTASYTALKINGMODEL", {"default": None, "tooltip": "FantasyTalking model https://github.com/Fantasy-AMAP"}),
+ "multitalk_model": ("MULTITALKMODEL", {"default": None, "tooltip": "Multitalk model"}),
}
}
@@ -528,24 +535,98 @@ class WanVideoModelLoader:
FUNCTION = "loadmodel"
CATEGORY = "WanVideoWrapper"
- def loadmodel(self, model, base_precision, load_device, quantization,
- compile_args=None, attention_mode="sdpa", block_swap_args=None, lora=None, vram_management_args=None):
+ def loadmodel(self, model, base_precision, device, quantization,
+ compile_args=None, attention_mode="sdpa", block_swap_args=None, lora=None, vram_management_args=None, vace_model=None, fantasytalking_model=None, multitalk_model=None):
+ import logging
+ import comfy.model_management as mm
+ import torch
+
+ logging.info(f"[MultiGPU WanVideoModelLoader] ========== CUSTOM IMPLEMENTATION ==========")
+ logging.info(f"[MultiGPU WanVideoModelLoader] User selected device: {device}")
+
+ # Convert device string to torch device
+ selected_device = torch.device(device)
+ logging.info(f"[MultiGPU WanVideoModelLoader] Torch device: {selected_device}")
+
+ # Determine load_device parameter for original loader
+ # If user selected CPU, use "offload_device", otherwise use "main_device"
+ load_device = "offload_device" if device == "cpu" else "main_device"
+ logging.info(f"[MultiGPU WanVideoModelLoader] Mapped to load_device: {load_device}")
+
from nodes import NODE_CLASS_MAPPINGS
original_loader = NODE_CLASS_MAPPINGS["WanVideoModelLoader"]()
- return original_loader.loadmodel(model, base_precision, load_device, quantization,
- compile_args, attention_mode, block_swap_args, lora, vram_management_args)
+
+ # Patch BOTH WanVideo modules with the selected device
+ import sys
+ import inspect
+ loader_module = inspect.getmodule(original_loader)
+
+ if loader_module:
+ logging.info(f"[MultiGPU WanVideoModelLoader] Patching WanVideo modules to use {selected_device}")
+
+ # Save original devices
+ original_device = getattr(loader_module, 'device', None)
+ original_offload = getattr(loader_module, 'offload_device', None)
+
+ # Check if there's a model offload device override (from block swap config)
+ model_offload_override = getattr(loader_module, '_model_offload_device_override', None)
+
+ # Patch nodes_model_loading.py module
+ setattr(loader_module, 'device', selected_device)
+ if model_offload_override:
+ # Use the model offload override for offload_device
+ setattr(loader_module, 'offload_device', model_offload_override)
+ logging.info(f"[MultiGPU WanVideoModelLoader] Using model offload override: {model_offload_override}")
+ elif device == "cpu":
+ setattr(loader_module, 'offload_device', selected_device)
+
+ # Patch nodes.py module as well
+ nodes_module_name = loader_module.__name__.replace('.nodes_model_loading', '.nodes')
+ if nodes_module_name in sys.modules:
+ nodes_module = sys.modules[nodes_module_name]
+ setattr(nodes_module, 'device', selected_device)
+
+ # Check for model offload override in nodes module too
+ nodes_model_offload_override = getattr(nodes_module, '_model_offload_device_override', None)
+ if nodes_model_offload_override:
+ setattr(nodes_module, 'offload_device', nodes_model_offload_override)
+ logging.info(f"[MultiGPU WanVideoModelLoader] Using model offload override for nodes.py: {nodes_model_offload_override}")
+ elif device == "cpu":
+ setattr(nodes_module, 'offload_device', selected_device)
+ logging.info(f"[MultiGPU WanVideoModelLoader] Both modules patched successfully")
+
+ # Call original loader with our patches in place
+ logging.info(f"[MultiGPU WanVideoModelLoader] Calling original loader with patched device")
+ result = original_loader.loadmodel(model, base_precision, load_device, quantization,
+ compile_args, attention_mode, block_swap_args, lora, vram_management_args, vace_model, fantasytalking_model, multitalk_model)
+
+ # Leave patches in place for subsequent operations
+ logging.info(f"[MultiGPU WanVideoModelLoader] Model loaded on {selected_device}")
+ logging.info(f"[MultiGPU WanVideoModelLoader] ========== COMPLETE ==========")
+
+ return result
+ else:
+ logging.error(f"[MultiGPU WanVideoModelLoader] Could not patch modules, falling back")
+ return original_loader.loadmodel(model, base_precision, load_device, quantization,
+ compile_args, attention_mode, block_swap_args, lora, vram_management_args, vace_model, fantasytalking_model, multitalk_model)
class WanVideoVAELoader:
@classmethod
def INPUT_TYPES(s):
+ from . import get_device_list
+ devices = get_device_list()
+
return {
"required": {
"model_name": (folder_paths.get_filename_list("vae"),
{"tooltip": "These models are loaded from 'ComfyUI/models/vae'"}),
+ "device": (devices, {"default": devices[1] if len(devices) > 1 else devices[0],
+ "tooltip": "Device to load the VAE to"}),
},
"optional": {
"precision": (["fp16", "fp32", "bf16"], {"default": "bf16"}),
+ "compile_args": ("WANCOMPILEARGS", ),
}
}
@@ -553,25 +634,62 @@ class WanVideoVAELoader:
RETURN_NAMES = ("vae", )
FUNCTION = "loadmodel"
CATEGORY = "WanVideoWrapper"
- DESCRIPTION = "Loads Wan VAE model from 'ComfyUI/models/vae'"
+ DESCRIPTION = "Loads Wan VAE model with explicit device selection"
- def loadmodel(self, model_name, precision):
+ def loadmodel(self, model_name, device, precision="bf16", compile_args=None):
+ import logging
+ import torch
+
+ logging.info(f"[MultiGPU WanVideoVAELoader] User selected device: {device}")
+
from nodes import NODE_CLASS_MAPPINGS
original_loader = NODE_CLASS_MAPPINGS["WanVideoVAELoader"]()
- return original_loader.loadmodel(model_name, precision)
+
+ # Patch BOTH modules with selected device
+ import sys
+ import inspect
+ loader_module = inspect.getmodule(original_loader)
+
+ if loader_module:
+ selected_device = torch.device(device)
+ logging.info(f"[MultiGPU WanVideoVAELoader] Patching modules to use {selected_device}")
+
+ # For VAE, we want to control where it loads initially
+ # Set offload_device to our selected device
+ setattr(loader_module, 'offload_device', selected_device)
+ setattr(loader_module, 'device', selected_device)
+
+ # Also patch nodes.py
+ nodes_module_name = loader_module.__name__.replace('.nodes_model_loading', '.nodes')
+ if nodes_module_name in sys.modules:
+ nodes_module = sys.modules[nodes_module_name]
+ setattr(nodes_module, 'device', selected_device)
+ setattr(nodes_module, 'offload_device', selected_device)
+
+ result = original_loader.loadmodel(model_name, precision, compile_args)
+
+ logging.info(f"[MultiGPU WanVideoVAELoader] VAE loaded on {selected_device}")
+ return result
+ else:
+ logging.error(f"[MultiGPU WanVideoVAELoader] Could not patch modules")
+ return original_loader.loadmodel(model_name, precision, compile_args)
class LoadWanVideoT5TextEncoder:
@classmethod
def INPUT_TYPES(s):
+ from . import get_device_list
+ devices = get_device_list()
+
return {
"required": {
"model_name": (folder_paths.get_filename_list("text_encoders"),
{"tooltip": "These models are loaded from 'ComfyUI/models/text_encoders'"}),
- "precision": (["fp16", "fp32", "bf16"], {"default": "bf16"}),
+ "precision": (["fp32", "bf16"], {"default": "bf16"}),
+ "device": (devices, {"default": devices[1] if len(devices) > 1 else devices[0],
+ "tooltip": "Device to load the text encoder to"}),
},
"optional": {
- "load_device": (["main_device"], {"default": "main_device"}),
"quantization": (['disabled', 'fp8_e4m3fn'],
{"default": 'disabled', "tooltip": "optional quantization method"}),
}
@@ -581,9 +699,400 @@ class LoadWanVideoT5TextEncoder:
RETURN_NAMES = ("wan_t5_model", )
FUNCTION = "loadmodel"
CATEGORY = "WanVideoWrapper"
- DESCRIPTION = "Loads Wan text_encoder model from 'ComfyUI/models/LLM'"
+ DESCRIPTION = "Loads Wan text_encoder model from 'ComfyUI/models/text_encoders'"
- def loadmodel(self, model_name, precision, load_device="offload_device", quantization="disabled"):
+ def loadmodel(self, model_name, precision, device, quantization="disabled"):
+ import logging
+ import torch
+
+ logging.info(f"[MultiGPU LoadWanVideoT5TextEncoder] ========== CUSTOM IMPLEMENTATION ==========")
+ logging.info(f"[MultiGPU LoadWanVideoT5TextEncoder] User selected device: {device}")
+
+ selected_device = torch.device(device)
+ load_device = "offload_device" if device == "cpu" else "main_device"
+ logging.info(f"[MultiGPU LoadWanVideoT5TextEncoder] Mapped to load_device: {load_device}")
+
from nodes import NODE_CLASS_MAPPINGS
original_loader = NODE_CLASS_MAPPINGS["LoadWanVideoT5TextEncoder"]()
- return original_loader.loadmodel(model_name, precision, load_device, quantization)
+
+ # Patch BOTH WanVideo modules
+ import sys
+ import inspect
+ loader_module = inspect.getmodule(original_loader)
+
+ if loader_module:
+ logging.info(f"[MultiGPU LoadWanVideoT5TextEncoder] Patching WanVideo modules to use {selected_device}")
+
+ # Patch nodes_model_loading.py
+ setattr(loader_module, 'device', selected_device)
+ if device == "cpu":
+ setattr(loader_module, 'offload_device', selected_device)
+
+ # Patch nodes.py module as well
+ nodes_module_name = loader_module.__name__.replace('.nodes_model_loading', '.nodes')
+ if nodes_module_name in sys.modules:
+ nodes_module = sys.modules[nodes_module_name]
+ setattr(nodes_module, 'device', selected_device)
+ if device == "cpu":
+ setattr(nodes_module, 'offload_device', selected_device)
+ logging.info(f"[MultiGPU LoadWanVideoT5TextEncoder] Both modules patched successfully")
+
+ result = original_loader.loadmodel(model_name, precision, load_device, quantization)
+
+ logging.info(f"[MultiGPU LoadWanVideoT5TextEncoder] Text encoder loaded on {selected_device}")
+ logging.info(f"[MultiGPU LoadWanVideoT5TextEncoder] ========== COMPLETE ==========")
+
+ return result
+ else:
+ logging.error(f"[MultiGPU LoadWanVideoT5TextEncoder] Could not patch modules, falling back")
+ return original_loader.loadmodel(model_name, precision, load_device, quantization)
+
+class WanVideoTextEncode:
+ @classmethod
+ def INPUT_TYPES(s):
+ from . import get_device_list
+ devices = get_device_list()
+
+ return {"required": {
+ "positive_prompt": ("STRING", {"default": "", "multiline": True} ),
+ "negative_prompt": ("STRING", {"default": "", "multiline": True} ),
+ "device": (devices, {"default": devices[1] if len(devices) > 1 else devices[0],
+ "tooltip": "Device to run the text encoding on"}),
+ },
+ "optional": {
+ "t5": ("WANTEXTENCODER",),
+ "force_offload": ("BOOLEAN", {"default": True}),
+ "model_to_offload": ("WANVIDEOMODEL", {"tooltip": "Model to move to offload_device before encoding"}),
+ "use_disk_cache": ("BOOLEAN", {"default": False, "tooltip": "Cache the text embeddings to disk for faster re-use"}),
+ }
+ }
+
+ RETURN_TYPES = ("WANVIDEOTEXTEMBEDS", )
+ RETURN_NAMES = ("text_embeds",)
+ FUNCTION = "process"
+ CATEGORY = "WanVideoWrapper"
+ DESCRIPTION = "Encodes text prompts with explicit device selection"
+
+ def process(self, positive_prompt, negative_prompt, device, t5=None, force_offload=True,
+ model_to_offload=None, use_disk_cache=False):
+ import logging
+ import torch
+
+ logging.info(f"[MultiGPU WanVideoTextEncode] User selected device: {device}")
+
+ # Map to original device parameter
+ original_device = "gpu" if device != "cpu" else "cpu"
+
+ from nodes import NODE_CLASS_MAPPINGS
+ original_encoder = NODE_CLASS_MAPPINGS["WanVideoTextEncode"]()
+
+ # Patch the modules
+ import sys
+ import inspect
+ encoder_module = inspect.getmodule(original_encoder)
+
+ if encoder_module:
+ selected_device = torch.device(device)
+ logging.info(f"[MultiGPU WanVideoTextEncode] Patching module to use {selected_device}")
+ setattr(encoder_module, 'device', selected_device)
+
+ # Also patch nodes_model_loading if needed
+ model_loading_name = encoder_module.__name__.replace('.nodes', '.nodes_model_loading')
+ if model_loading_name in sys.modules:
+ model_loading_module = sys.modules[model_loading_name]
+ setattr(model_loading_module, 'device', selected_device)
+
+ result = original_encoder.process(positive_prompt, negative_prompt, t5=t5,
+ force_offload=force_offload, model_to_offload=model_to_offload,
+ use_disk_cache=use_disk_cache, device=original_device)
+
+ logging.info(f"[MultiGPU WanVideoTextEncode] Encoding completed on {selected_device}")
+ return result
+ else:
+ return original_encoder.process(positive_prompt, negative_prompt, t5=t5,
+ force_offload=force_offload, model_to_offload=model_to_offload,
+ use_disk_cache=use_disk_cache, device=original_device)
+
+class LoadWanVideoClipTextEncoder:
+ @classmethod
+ def INPUT_TYPES(s):
+ from . import get_device_list
+ devices = get_device_list()
+
+ return {
+ "required": {
+ "model_name": (folder_paths.get_filename_list("clip_vision") + folder_paths.get_filename_list("text_encoders"),
+ {"tooltip": "These models are loaded from 'ComfyUI/models/clip_vision'"}),
+ "precision": (["fp16", "fp32", "bf16"], {"default": "fp16"}),
+ "device": (devices, {"default": devices[1] if len(devices) > 1 else devices[0],
+ "tooltip": "Device to load the CLIP encoder to"}),
+ }
+ }
+
+ RETURN_TYPES = ("CLIP_VISION",)
+ RETURN_NAMES = ("clip_vision", )
+ FUNCTION = "loadmodel"
+ CATEGORY = "WanVideoWrapper"
+ DESCRIPTION = "Loads Wan CLIP text encoder model from 'ComfyUI/models/clip_vision'"
+
+ def loadmodel(self, model_name, precision, device):
+ import logging
+ import torch
+
+ logging.info(f"[MultiGPU LoadWanVideoClipTextEncoder] ========== CUSTOM IMPLEMENTATION ==========")
+ logging.info(f"[MultiGPU LoadWanVideoClipTextEncoder] User selected device: {device}")
+
+ selected_device = torch.device(device)
+ load_device = "offload_device" if device == "cpu" else "main_device"
+ logging.info(f"[MultiGPU LoadWanVideoClipTextEncoder] Mapped to load_device: {load_device}")
+
+ from nodes import NODE_CLASS_MAPPINGS
+ original_loader = NODE_CLASS_MAPPINGS["LoadWanVideoClipTextEncoder"]()
+
+ # Patch BOTH WanVideo modules
+ import sys
+ import inspect
+ loader_module = inspect.getmodule(original_loader)
+
+ if loader_module:
+ logging.info(f"[MultiGPU LoadWanVideoClipTextEncoder] Patching WanVideo modules to use {selected_device}")
+
+ # Patch nodes_model_loading.py
+ setattr(loader_module, 'device', selected_device)
+ if device == "cpu":
+ setattr(loader_module, 'offload_device', selected_device)
+
+ # Patch nodes.py module as well
+ nodes_module_name = loader_module.__name__.replace('.nodes_model_loading', '.nodes')
+ if nodes_module_name in sys.modules:
+ nodes_module = sys.modules[nodes_module_name]
+ setattr(nodes_module, 'device', selected_device)
+ if device == "cpu":
+ setattr(nodes_module, 'offload_device', selected_device)
+ logging.info(f"[MultiGPU LoadWanVideoClipTextEncoder] Both modules patched successfully")
+
+ result = original_loader.loadmodel(model_name, precision, load_device)
+
+ logging.info(f"[MultiGPU LoadWanVideoClipTextEncoder] CLIP encoder loaded on {selected_device}")
+ logging.info(f"[MultiGPU LoadWanVideoClipTextEncoder] ========== COMPLETE ==========")
+
+ return result
+ else:
+ logging.error(f"[MultiGPU LoadWanVideoClipTextEncoder] Could not patch modules, falling back")
+ return original_loader.loadmodel(model_name, precision, load_device)
+
+
+class WanVideoModelLoader_TWO:
+ """Second instance of WanVideoModelLoader for multi-model workflows to avoid race conditions"""
+ @classmethod
+ def INPUT_TYPES(s):
+ # Exact same inputs as WanVideoModelLoader
+ from . import get_device_list
+ devices = get_device_list()
+
+ return {
+ "required": {
+ "model": (folder_paths.get_filename_list("unet_gguf") + folder_paths.get_filename_list("diffusion_models"),
+ {"tooltip": "These models are loaded from the 'ComfyUI/models/diffusion_models' folder",}),
+ "base_precision": (["fp32", "bf16", "fp16", "fp16_fast"], {"default": "bf16"}),
+ "quantization": (
+ ["disabled", "fp8_e4m3fn", "fp8_e4m3fn_fast", "fp8_e5m2", "fp8_e4m3fn_fast_no_ffn", "fp8_e4m3fn_scaled", "fp8_e5m2_scaled"],
+ {"default": "disabled", "tooltip": "optional quantization method"}
+ ),
+ "device": (devices, {"default": devices[1] if len(devices) > 1 else devices[0], "tooltip": "Device to load the model to"}),
+ },
+ "optional": {
+ "attention_mode": ([
+ "sdpa",
+ "flash_attn_2",
+ "flash_attn_3",
+ "sageattn",
+ "sageattn_3",
+ "flex_attention",
+ "radial_sage_attention",
+ ], {"default": "sdpa"}),
+ "compile_args": ("WANCOMPILEARGS", ),
+ "block_swap_args": ("BLOCKSWAPARGS", ),
+ "lora": ("WANVIDLORA", {"default": None}),
+ "vram_management_args": ("VRAM_MANAGEMENTARGS", {"default": None, "tooltip": "Alternative offloading method from DiffSynth-Studio, more aggressive in reducing memory use than block swapping, but can be slower"}),
+ "vace_model": ("VACEPATH", {"default": None, "tooltip": "VACE model to use when not using model that has it included"}),
+ "fantasytalking_model": ("FANTASYTALKINGMODEL", {"default": None, "tooltip": "FantasyTalking model https://github.com/Fantasy-AMAP"}),
+ "multitalk_model": ("MULTITALKMODEL", {"default": None, "tooltip": "Multitalk model"}),
+ }
+ }
+ RETURN_TYPES = ("WANVIDEOMODEL",)
+ RETURN_NAMES = ("model", )
+ FUNCTION = "loadmodel"
+ CATEGORY = "WanVideoWrapper"
+ DESCRIPTION = "Second model loader for multi-model workflows - avoids race conditions when loading multiple models"
+
+ def loadmodel(self, model, base_precision, device, quantization,
+ compile_args=None, attention_mode="sdpa", block_swap_args=None, lora=None, vram_management_args=None, vace_model=None, fantasytalking_model=None, multitalk_model=None):
+ # Just call the first loader's implementation directly
+ import logging
+ import comfy.model_management as mm
+ import torch
+
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] ========== CUSTOM IMPLEMENTATION ==========")
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] User selected device: {device}")
+
+ # Convert device string to torch device
+ selected_device = torch.device(device)
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] Torch device: {selected_device}")
+
+ # Determine load_device parameter for original loader
+ # If user selected CPU, use "offload_device", otherwise use "main_device"
+ load_device = "offload_device" if device == "cpu" else "main_device"
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] Mapped to load_device: {load_device}")
+
+ from nodes import NODE_CLASS_MAPPINGS
+ original_loader = NODE_CLASS_MAPPINGS["WanVideoModelLoader"]()
+
+ # Patch BOTH WanVideo modules with the selected device
+ import sys
+ import inspect
+ loader_module = inspect.getmodule(original_loader)
+
+ if loader_module:
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] Patching WanVideo modules to use {selected_device}")
+
+ # Save original devices
+ original_device = getattr(loader_module, 'device', None)
+ original_offload = getattr(loader_module, 'offload_device', None)
+
+ # Check if there's a model offload device override (from block swap config)
+ model_offload_override = getattr(loader_module, '_model_offload_device_override', None)
+
+ # Patch nodes_model_loading.py module
+ setattr(loader_module, 'device', selected_device)
+ if model_offload_override:
+ # Use the model offload override for offload_device
+ setattr(loader_module, 'offload_device', model_offload_override)
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] Using model offload override: {model_offload_override}")
+ elif device == "cpu":
+ setattr(loader_module, 'offload_device', selected_device)
+
+ # Patch nodes.py module as well
+ nodes_module_name = loader_module.__name__.replace('.nodes_model_loading', '.nodes')
+ if nodes_module_name in sys.modules:
+ nodes_module = sys.modules[nodes_module_name]
+ setattr(nodes_module, 'device', selected_device)
+
+ # Check for model offload override in nodes module too
+ nodes_model_offload_override = getattr(nodes_module, '_model_offload_device_override', None)
+ if nodes_model_offload_override:
+ setattr(nodes_module, 'offload_device', nodes_model_offload_override)
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] Using model offload override for nodes.py: {nodes_model_offload_override}")
+ elif device == "cpu":
+ setattr(nodes_module, 'offload_device', selected_device)
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] Both modules patched successfully")
+
+ # Call original loader with our patches in place
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] Calling original loader with patched device")
+ result = original_loader.loadmodel(model, base_precision, load_device, quantization,
+ compile_args, attention_mode, block_swap_args, lora, vram_management_args, vace_model, fantasytalking_model, multitalk_model)
+
+ # Leave patches in place for subsequent operations
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] Model loaded on {selected_device}")
+ logging.info(f"[MultiGPU WanVideoModelLoader_TWO] ========== COMPLETE ==========")
+
+ return result
+ else:
+ logging.error(f"[MultiGPU WanVideoModelLoader_TWO] Could not patch modules, falling back")
+ return original_loader.loadmodel(model, base_precision, load_device, quantization,
+ compile_args, attention_mode, block_swap_args, lora, vram_management_args, vace_model, fantasytalking_model, multitalk_model)
+
+
+class WanVideoBlockSwap:
+ @classmethod
+ def INPUT_TYPES(s):
+ from . import get_device_list
+ devices = get_device_list()
+
+ return {
+ "required": {
+ "blocks_to_swap": ("INT", {"default": 20, "min": 0, "max": 40, "step": 1,
+ "tooltip": "Number of transformer blocks to swap, the 14B model has 40, while the 1.3B model has 30 blocks"}),
+ "swap_device": (devices, {"default": "cpu",
+ "tooltip": "Device to swap blocks to during sampling (default: cpu for standard behavior)"}),
+ "model_offload_device": (devices, {"default": "cpu",
+ "tooltip": "Device to offload entire model to when done (default: cpu)"}),
+ "offload_img_emb": ("BOOLEAN", {"default": False, "tooltip": "Offload img_emb to swap_device"}),
+ "offload_txt_emb": ("BOOLEAN", {"default": False, "tooltip": "Offload time_emb to swap_device"}),
+ },
+ "optional": {
+ "use_non_blocking": ("BOOLEAN", {"default": False,
+ "tooltip": "Use non-blocking memory transfer for offloading, reserves more RAM but is faster"}),
+ "vace_blocks_to_swap": ("INT", {"default": 0, "min": 0, "max": 15, "step": 1,
+ "tooltip": "Number of VACE blocks to swap, the VACE model has 15 blocks"}),
+ },
+ }
+
+ RETURN_TYPES = ("BLOCKSWAPARGS",)
+ RETURN_NAMES = ("block_swap_args",)
+ FUNCTION = "setargs"
+ CATEGORY = "WanVideoWrapper"
+ DESCRIPTION = "Block swap settings with explicit device selection for memory management across GPUs"
+
+ def setargs(self, blocks_to_swap, swap_device, model_offload_device, offload_img_emb, offload_txt_emb,
+ use_non_blocking=False, vace_blocks_to_swap=0):
+ import logging
+ import torch
+ import comfy.model_management as mm
+
+ logging.info(f"[MultiGPU WanVideoBlockSwap] ========== CONFIGURATION ==========")
+ logging.info(f"[MultiGPU WanVideoBlockSwap] User selected swap device: {swap_device}")
+ logging.info(f"[MultiGPU WanVideoBlockSwap] User selected model offload device: {model_offload_device}")
+ logging.info(f"[MultiGPU WanVideoBlockSwap] Blocks to swap: {blocks_to_swap}")
+
+ # Convert device strings to torch devices
+ selected_swap_device = torch.device(swap_device)
+ selected_offload_device = torch.device(model_offload_device)
+ logging.info(f"[MultiGPU WanVideoBlockSwap] Torch swap device: {selected_swap_device}")
+ logging.info(f"[MultiGPU WanVideoBlockSwap] Torch model offload device: {selected_offload_device}")
+
+ # Patch the offload_device in WanVideo modules to use our selected swap device
+ # This needs to persist through model loading
+ import sys
+
+ # Find the actual module paths (without the custom_nodes prefix)
+ for module_name in sys.modules.keys():
+ if 'WanVideoWrapper' in module_name and 'nodes_model_loading' in module_name:
+ module = sys.modules[module_name]
+ original_offload = getattr(module, 'offload_device', None)
+ # For model loading, use the model offload device
+ setattr(module, 'offload_device', selected_offload_device)
+ # Store the block swap device separately
+ setattr(module, '_block_swap_device_override', selected_swap_device)
+ setattr(module, '_model_offload_device_override', selected_offload_device)
+ logging.info(f"[MultiGPU WanVideoBlockSwap] Patched {module_name}")
+ logging.info(f" - offload_device: {original_offload} -> {selected_offload_device}")
+ logging.info(f" - _block_swap_device_override: {selected_swap_device}")
+
+ if 'WanVideoWrapper' in module_name and module_name.endswith('.nodes'):
+ module = sys.modules[module_name]
+ original_offload = getattr(module, 'offload_device', None)
+ # For nodes.py, set the model offload device
+ setattr(module, 'offload_device', selected_offload_device)
+ setattr(module, '_block_swap_device_override', selected_swap_device)
+ setattr(module, '_model_offload_device_override', selected_offload_device)
+ logging.info(f"[MultiGPU WanVideoBlockSwap] Patched {module_name}")
+ logging.info(f" - offload_device: {original_offload} -> {selected_offload_device}")
+
+ # Also store in block_swap_args so it can be used directly
+ block_swap_args = {
+ "blocks_to_swap": blocks_to_swap,
+ "offload_img_emb": offload_img_emb,
+ "offload_txt_emb": offload_txt_emb,
+ "use_non_blocking": use_non_blocking,
+ "vace_blocks_to_swap": vace_blocks_to_swap,
+ "swap_device": swap_device, # For block swapping
+ "model_offload_device": model_offload_device, # For full model offload
+ }
+
+ logging.info(f"[MultiGPU WanVideoBlockSwap] Block swap configuration complete")
+ logging.info(f"[MultiGPU WanVideoBlockSwap] Stored swap_device in args: {swap_device}")
+ logging.info(f"[MultiGPU WanVideoBlockSwap] Stored model_offload_device in args: {model_offload_device}")
+ logging.info(f"[MultiGPU WanVideoBlockSwap] ========== COMPLETE ==========")
+
+ return (block_swap_args,)