diff --git a/examples/wannvideowrapper/wanvideo_1_3B_control_lora_example_01_MultiGPU.json b/examples/wannvideowrapper/wanvideo_1_3B_control_lora_example_01_MultiGPU.json new file mode 100755 index 0000000..9bf08bf --- /dev/null +++ b/examples/wannvideowrapper/wanvideo_1_3B_control_lora_example_01_MultiGPU.json @@ -0,0 +1,1165 @@ +{ + "id": "04f1de76-e363-4c27-bec7-eb184ac6e476", + "revision": 0, + "last_node_id": 111, + "last_link_id": 161, + "nodes": [ + { + "id": 36, + "type": "Note", + "pos": [ + 160, + -1010 + ], + "size": [ + 374.3061828613281, + 171.9547576904297 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": {}, + "widgets_values": [ + "fp8_fast seems to cause huge quality degradation\n\nfp_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" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 35, + "type": "WanVideoTorchCompileSettings", + "pos": [ + -276.8500671386719, + -1050.6326904296875 + ], + "size": [ + 390.5999755859375, + 202 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "torch_compile_args", + "type": "WANCOMPILEARGS", + "slot_index": 0, + "links": [] + } + ], + "properties": { + "Node name for S&R": "WanVideoTorchCompileSettings" + }, + "widgets_values": [ + "inductor", + false, + "default", + false, + 64, + true, + 128 + ], + "color": "#223", + "bgcolor": "#335" + }, + { + "id": 44, + "type": "Note", + "pos": [ + -620.9041137695312, + -1049.732421875 + ], + "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": 53, + "type": "Note", + "pos": [ + 1329.0076904296875, + -810.7708740234375 + ], + "size": [ + 324.64129638671875, + 159.47401428222656 + ], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": {}, + "widgets_values": [ + "TeaCache could be considered to be sort of an automated step skipper \n\nThe relative l1 threshold -value determines how aggressive this is, higher values are faster but quality suffers more. Very first steps should NEVER be skipped with this model or it kills the motion. When using the pre-calculated coefficients, the treshold value should be much higher than with the default coefficients." + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 28, + "type": "WanVideoDecode", + "pos": [ + 1704.86572265625, + -604.0441284179688 + ], + "size": [ + 315, + 198 + ], + "flags": {}, + "order": 17, + "mode": 0, + "inputs": [ + { + "name": "vae", + "type": "WANVAE", + "link": 159 + }, + { + "name": "samples", + "type": "LATENT", + "link": 154 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 145 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoDecode" + }, + "widgets_values": [ + false, + 272, + 272, + 144, + 128, + "default" + ], + "color": "#322", + "bgcolor": "#533" + }, + { + "id": 30, + "type": "VHS_VideoCombine", + "pos": [ + 1709.29345703125, + -334.3517150878906 + ], + "size": [ + 1037.934326171875, + 856.9671630859375 + ], + "flags": {}, + "order": 19, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 146 + }, + { + "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" + }, + "widgets_values": { + "frame_rate": 16, + "loop_count": 0, + "filename_prefix": "WanVideoWrapper_I2V", + "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": "WanVideoWrapper_I2V_00004.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 16, + "workflow": "WanVideoWrapper_I2V_00004.png", + "fullpath": "/home/johnj/ComfyUI/output/WanVideoWrapper_I2V_00004.mp4" + } + } + } + }, + { + "id": 97, + "type": "VHS_LoadVideo", + "pos": [ + -257.8260498046875, + 26.503103256225586 + ], + "size": [ + 247.455078125, + 551.455078125 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "meta_batch", + "shape": 7, + "type": "VHS_BatchManager", + "link": null + }, + { + "name": "vae", + "shape": 7, + "type": "VAE", + "link": null + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 147 + ] + }, + { + "name": "frame_count", + "type": "INT", + "links": null + }, + { + "name": "audio", + "type": "AUDIO", + "links": null + }, + { + "name": "video_info", + "type": "VHS_VIDEOINFO", + "links": null + } + ], + "properties": { + "Node name for S&R": "VHS_LoadVideo" + }, + "widgets_values": { + "video": "wolf_interpolated.mp4", + "force_rate": 0, + "custom_width": 0, + "custom_height": 0, + "frame_load_cap": 0, + "skip_first_frames": 0, + "select_every_nth": 1, + "format": "AnimateDiff", + "choose video to upload": "image", + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "wolf_interpolated.mp4", + "type": "input", + "format": "video/mp4", + "force_rate": 0, + "custom_width": 0, + "custom_height": 0, + "frame_load_cap": 0, + "skip_first_frames": 0, + "select_every_nth": 1 + } + } + } + }, + { + "id": 95, + "type": "WanVideoEncode", + "pos": [ + 280.9074401855469, + -116.20671844482422 + ], + "size": [ + 315, + 242 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "vae", + "type": "WANVAE", + "link": 158 + }, + { + "name": "image", + "type": "IMAGE", + "link": 148 + }, + { + "name": "mask", + "shape": 7, + "type": "MASK", + "link": null + } + ], + "outputs": [ + { + "name": "samples", + "type": "LATENT", + "links": [ + 132 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoEncode" + }, + "widgets_values": [ + false, + 272, + 272, + 144, + 128, + 0, + 1.0000000000000002 + ] + }, + { + "id": 104, + "type": "ImageBlur", + "pos": [ + 89.50601959228516, + 217.970947265625 + ], + "size": [ + 315, + 82 + ], + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 147 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 148, + 149 + ] + } + ], + "properties": { + "Node name for S&R": "ImageBlur" + }, + "widgets_values": [ + 4, + 1 + ] + }, + { + "id": 103, + "type": "ImageConcatMulti", + "pos": [ + 2055.855224609375, + -543.0326538085938 + ], + "size": [ + 315, + 150 + ], + "flags": {}, + "order": 18, + "mode": 0, + "inputs": [ + { + "name": "image_1", + "type": "IMAGE", + "link": 149 + }, + { + "name": "image_2", + "shape": 7, + "type": "IMAGE", + "link": 145 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "slot_index": 0, + "links": [ + 146 + ] + } + ], + "properties": {}, + "widgets_values": [ + 2, + "right", + false, + null + ] + }, + { + "id": 33, + "type": "Note", + "pos": [ + 170, + -1150 + ], + "size": [ + 359.0753479003906, + 88 + ], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": {}, + "widgets_values": [ + "Models:\nhttps://huggingface.co/Kijai/WanVideo_comfy/tree/main" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 96, + "type": "WanVideoControlEmbeds", + "pos": [ + 784.249755859375, + -17.228534698486328 + ], + "size": [ + 289.79998779296875, + 102 + ], + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "name": "latents", + "type": "LATENT", + "link": 132 + }, + { + "name": "fun_ref_image", + "shape": 7, + "type": "LATENT", + "link": null + } + ], + "outputs": [ + { + "name": "image_embeds", + "type": "WANVIDIMAGE_EMBEDS", + "slot_index": 0, + "links": [ + 151 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoControlEmbeds" + }, + "widgets_values": [ + 0, + 0.7 + ] + }, + { + "id": 52, + "type": "WanVideoTeaCache", + "pos": [ + 1334.42626953125, + -588.2476196289062 + ], + "size": [ + 315, + 178 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "cache_args", + "type": "CACHEARGS", + "links": [ + 153 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoTeaCache" + }, + "widgets_values": [ + 0.1, + 1, + -1, + "offload_device", + "true", + "e" + ] + }, + { + "id": 64, + "type": "WanVideoTorchCompileSettings", + "pos": [ + -276.8500671386719, + -1050.6326904296875 + ], + "size": [ + 390.5999755859375, + 202 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "torch_compile_args", + "type": "WANCOMPILEARGS", + "slot_index": 0, + "links": [ + 157 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoTorchCompileSettings" + }, + "widgets_values": [ + "inductor", + false, + "default", + false, + 64, + true, + 128 + ] + }, + { + "id": 109, + "type": "WanVideoVAELoaderMultiGPU", + "pos": [ + -246.82862854003906, + -338.9017333984375 + ], + "size": [ + 368.710693359375, + 106 + ], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "compile_args", + "shape": 7, + "type": "WANCOMPILEARGS", + "link": null + } + ], + "outputs": [ + { + "name": "vae", + "type": "WANVAE", + "links": [ + 158, + 159 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoVAELoaderMultiGPU" + }, + "widgets_values": [ + "wan_2.1_vae.safetensors", + "cuda:0", + "bf16" + ], + "color": "#233", + "bgcolor": "#355" + }, + { + "id": 111, + "type": "LoadWanVideoT5TextEncoderMultiGPU", + "pos": [ + 334.64263916015625, + -356.91937255859375 + ], + "size": [ + 348.9195251464844, + 130 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "wan_t5_model", + "type": "WANTEXTENCODER", + "links": [ + 161 + ] + } + ], + "properties": { + "Node name for S&R": "LoadWanVideoT5TextEncoderMultiGPU" + }, + "widgets_values": [ + "umt5-xxl-enc-bf16.safetensors", + "bf16", + "cuda:0", + "disabled" + ], + "color": "#233", + "bgcolor": "#355" + }, + { + "id": 110, + "type": "WanVideoTextEncodeMultiGPU", + "pos": [ + 750.6812744140625, + -392.9539794921875 + ], + "size": [ + 400, + 234 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "t5", + "shape": 7, + "type": "WANTEXTENCODER", + "link": 161 + }, + { + "name": "model_to_offload", + "shape": 7, + "type": "WANVIDEOMODEL", + "link": null + } + ], + "outputs": [ + { + "name": "text_embeds", + "type": "WANVIDEOTEXTEMBEDS", + "links": [ + 160 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoTextEncodeMultiGPU" + }, + "widgets_values": [ + "video of a wolf", + "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走", + "cuda:0", + false, + false + ], + "color": "#233", + "bgcolor": "#355" + }, + { + "id": 108, + "type": "WanVideoSamplerMultiGPU", + "pos": [ + 1322.1207275390625, + -347.0115051269531 + ], + "size": [ + 327.80859375, + 902 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "model", + "type": "WANVIDEOMODEL", + "link": 155 + }, + { + "name": "image_embeds", + "type": "WANVIDIMAGE_EMBEDS", + "link": 151 + }, + { + "name": "text_embeds", + "shape": 7, + "type": "WANVIDEOTEXTEMBEDS", + "link": 160 + }, + { + "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": 153 + }, + { + "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", + "links": [ + 154 + ] + }, + { + "name": "denoised_samples", + "type": "LATENT", + "links": null + } + ], + "properties": { + "Node name for S&R": "WanVideoSamplerMultiGPU" + }, + "widgets_values": [ + 30, + 6, + 5, + 0, + "fixed", + false, + "unipc", + 0, + 1, + false, + "comfy", + 0, + -1, + false + ], + "color": "#233", + "bgcolor": "#355" + }, + { + "id": 107, + "type": "WanVideoModelLoaderMultiGPU", + "pos": [ + 295.29010009765625, + -723.5640258789062 + ], + "size": [ + 400.63916015625, + 274 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "name": "compile_args", + "shape": 7, + "type": "WANCOMPILEARGS", + "link": 157 + }, + { + "name": "block_swap_args", + "shape": 7, + "type": "BLOCKSWAPARGS", + "link": null + }, + { + "name": "lora", + "shape": 7, + "type": "WANVIDLORA", + "link": 156 + }, + { + "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": [ + 155 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoModelLoaderMultiGPU" + }, + "widgets_values": [ + "wan2.1_t2v_1.3B_bf16.safetensors", + "bf16", + "disabled", + "cuda:1", + "sdpa" + ], + "color": "#233", + "bgcolor": "#355" + }, + { + "id": 98, + "type": "WanVideoLoraSelect", + "pos": [ + -161.7538604736328, + -680.8223876953125 + ], + "size": [ + 315, + 150 + ], + "flags": {}, + "order": 10, + "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": [ + 156 + ] + } + ], + "properties": { + "Node name for S&R": "WanVideoLoraSelect" + }, + "widgets_values": [ + "wan2.1-1.3b-control-lora-tile-v1.1_comfy.safetensors", + 1, + false, + true + ] + } + ], + "links": [ + [ + 132, + 95, + 0, + 96, + 0, + "LATENT" + ], + [ + 145, + 28, + 0, + 103, + 1, + "IMAGE" + ], + [ + 146, + 103, + 0, + 30, + 0, + "IMAGE" + ], + [ + 147, + 97, + 0, + 104, + 0, + "IMAGE" + ], + [ + 148, + 104, + 0, + 95, + 1, + "IMAGE" + ], + [ + 149, + 104, + 0, + 103, + 0, + "IMAGE" + ], + [ + 151, + 96, + 0, + 108, + 1, + "WANVIDIMAGE_EMBEDS" + ], + [ + 153, + 52, + 0, + 108, + 6, + "CACHEARGS" + ], + [ + 154, + 108, + 0, + 28, + 1, + "LATENT" + ], + [ + 155, + 107, + 0, + 108, + 0, + "WANVIDEOMODEL" + ], + [ + 156, + 98, + 0, + 107, + 2, + "WANVIDLORA" + ], + [ + 157, + 64, + 0, + 107, + 0, + "WANCOMPILEARGS" + ], + [ + 158, + 109, + 0, + 95, + 0, + "WANVAE" + ], + [ + 159, + 109, + 0, + 28, + 0, + "WANVAE" + ], + [ + 160, + 110, + 0, + 108, + 2, + "WANVIDEOTEXTEMBEDS" + ], + [ + 161, + 111, + 0, + 110, + 0, + "WANTEXTENCODER" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 0.814027493868451, + "offset": [ + 714.8717021081054, + 1253.694882650272 + ] + }, + "node_versions": { + "ComfyUI-WanVideoWrapper": "5a2383621a05825d0d0437781afcb8552d9590fd", + "ComfyUI-VideoHelperSuite": "0a75c7958fe320efcb052f1d9f8451fd20c730a8", + "comfy-core": "0.3.26", + "ComfyUI-KJNodes": "a5bd3c86c8ed6b83c55c2d0e7a59515b15a0137f" + }, + "VHS_latentpreview": false, + "VHS_latentpreviewrate": 0, + "VHS_MetadataImage": true, + "VHS_KeepIntermediate": true, + "frontendVersion": "1.25.11" + }, + "version": 0.4 +} \ No newline at end of file diff --git a/wanvideo.py b/wanvideo.py index a49c2b0..3ddb952 100644 --- a/wanvideo.py +++ b/wanvideo.py @@ -158,6 +158,10 @@ class WanVideoVAELoader: result = original_loader.loadmodel(model_name, precision, compile_args) + # Attach device info to VAE object for downstream nodes + if result and len(result) > 0: + result[0].load_device = selected_device + logging.info(f"[MultiGPU] WanVideo VAE loaded on {selected_device}") return result else: @@ -383,6 +387,33 @@ class WanVideoSampler: original_sampler = NODE_CLASS_MAPPINGS["WanVideoSampler"]() return original_sampler.process(model, **kwargs) +class WanVideoVACEEncode: + @classmethod + def INPUT_TYPES(s): + from nodes import NODE_CLASS_MAPPINGS + original_types = NODE_CLASS_MAPPINGS["WanVideoVACEEncode"].INPUT_TYPES() + return original_types + + RETURN_TYPES = ("LATENT",) + RETURN_NAMES = ("latent",) + FUNCTION = "process" + CATEGORY = "WanVideoWrapper" + DESCRIPTION = "MultiGPU-aware VACE encoder that uses device from input VAE" + + def process(self, vae, **kwargs): + # Get device from VAE object + vae_device = vae.load_device + logging.info(f"[MultiGPU] WanVideoVACEEncode: Processing on device: {vae_device}") + + # Patch all WanVideo modules to use the VAE's device + for module_name in sys.modules.keys(): + if 'WanVideoWrapper' in module_name and hasattr(sys.modules[module_name], 'device'): + sys.modules[module_name].device = vae_device + + from nodes import NODE_CLASS_MAPPINGS + original_encoder = NODE_CLASS_MAPPINGS["WanVideoVACEEncode"]() + return original_encoder.process(vae, **kwargs) + class WanVideoBlockSwap: @classmethod def INPUT_TYPES(s):