Merge pull request #127 from pollockjj/issue/#125

Issue/#125
This commit is contained in:
John Pollock
2025-10-13 19:50:18 -05:00
committed by GitHub
23 changed files with 3219 additions and 194 deletions
+8 -15
View File
@@ -137,7 +137,7 @@ All MultiGPU nodes available for your install can be found in the "multigpu" cat
## Node Documentation
Detailed technical documentation is available for all **automatically-detected core MultiGPU and DisTorch2 nodes**, covering 36+ documented nodes with comprehensive parameter details, output specifications, and DisTorch2 allocation guidance where applicable.
Detailed technical documentation is available for all **automatically-detected core MultiGPU and DisTorch2 nodes**, covering 70+ documented nodes with comprehensive parameter details, output specifications, and DisTorch2 allocation guidance where applicable.
- **To access documentation**: Click on any core MultiGPU or DisTorch2 node in ComfyUI and select "Help" (question mark inside a circle) from the resultant menu
- **Coverage**: All standard ComfyUI loader nodes (UNet, VAE, Checkpoints, CLIP, ControlNet, Diffusers) plus popular GGUF loader variants
@@ -253,19 +253,6 @@ All workflows have been tested on a 2x 3090 + 1060ti linux setup, a 4070 win 11
</tr>
</table>
### Florence2
<table>
<tr>
<td align="center">
<a href="example_workflows/ComfyUI-Florence2%20detailed_caption%20to%20flux.json">
<img src="example_workflows/ComfyUI-Florence2%20detailed_caption%20to%20flux.jpg" alt="Florence2 Detailed Caption to FLUX Pipeline" style="max-width:160px; max-height:160px;">
<div>Florence2 Detailed Caption to FLUX Pipeline</div>
</a>
</td>
</tr>
</table>
### GGUF
<table>
@@ -286,7 +273,7 @@ All workflows have been tested on a 2x 3090 + 1060ti linux setup, a 4070 win 11
</tr>
</table>
### HunyuanVideoWrapper
### HunyuanVideoWrapper / Florence2
<table>
<tr>
@@ -296,6 +283,12 @@ All workflows have been tested on a 2x 3090 + 1060ti linux setup, a 4070 win 11
<div>HunyuanVideoWrapper DisTorch (Legacy, Deprecated)</div>
</a>
</td>
<td align="center">
<a href="example_workflows/ComfyUI-Florence2%20detailed_caption%20to%20flux.json">
<img src="example_workflows/ComfyUI-Florence2%20detailed_caption%20to%20flux.jpg" alt="Florence2 Detailed Caption to FLUX Pipeline" style="max-width:160px; max-height:160px;">
<div>Florence2 Detailed Caption to FLUX Pipeline</div>
</a>
</td>
</tr>
</table>
-2
View File
@@ -269,8 +269,6 @@ from .wrappers import (
override_class_with_distorch_safetensor_v2_clip_no_device,
)
from .distorch_2 import (
safetensor_allocation_store,
create_safetensor_model_hash,
register_patched_safetensor_modelpatcher,
analyze_safetensor_loading,
calculate_safetensor_vvram_allocation,
+7 -11
View File
@@ -9,7 +9,7 @@ import comfy.clip_vision
from comfy.sd import VAE, CLIP
from .device_utils import get_device_list, soft_empty_cache_multigpu
from .model_management_mgpu import multigpu_memory_log
from .distorch_2 import safetensor_allocation_store, safetensor_settings_store, create_safetensor_model_hash, register_patched_safetensor_modelpatcher
from .distorch_2 import register_patched_safetensor_modelpatcher
logger = logging.getLogger("MultiGPU")
@@ -108,12 +108,10 @@ def patched_load_state_dict_guess_config(sd, output_vae=True, output_clip=True,
if distorch_config and 'unet_allocation' in distorch_config:
register_patched_safetensor_modelpatcher()
model_hash = create_safetensor_model_hash(model_patcher, "checkpoint_loader_unet")
safetensor_allocation_store[model_hash] = distorch_config['unet_allocation']
safetensor_settings_store[model_hash] = distorch_config.get('unet_settings','')
model.is_distorch = True
inner_model = model_patcher.model
inner_model._distorch_v2_meta = {"full_allocation": distorch_config['unet_allocation']}
logger.info(f"[CHECKPOINT_META] UNET inner_model id=0x{id(inner_model):x}")
model._distorch_high_precision_loras = distorch_config.get('high_precision_loras', True)
logger.mgpu_mm_log(f"Stored DisTorch2 config for UNet (hash {model_hash[:8]}): {distorch_config['unet_allocation']}")
model.load_model_weights(sd, diffusion_model_prefix)
multigpu_memory_log(f"unet:{config_hash[:8]}", "post-weights")
@@ -145,12 +143,10 @@ def patched_load_state_dict_guess_config(sd, output_vae=True, output_clip=True,
if distorch_config and 'clip_allocation' in distorch_config:
if hasattr(clip, 'patcher'):
register_patched_safetensor_modelpatcher()
clip_hash = create_safetensor_model_hash(clip.patcher, "checkpoint_loader_clip")
safetensor_allocation_store[clip_hash] = distorch_config['clip_allocation']
safetensor_settings_store[clip_hash] = distorch_config.get('clip_settings','')
clip.patcher.model.is_distorch = True
inner_clip = clip.patcher.model
inner_clip._distorch_v2_meta = {"full_allocation": distorch_config['clip_allocation']}
logger.info(f"[CHECKPOINT_META] CLIP inner_model id=0x{id(inner_clip):x}")
clip.patcher.model._distorch_high_precision_loras = distorch_config.get('high_precision_loras', True)
logger.info(f"Stored DisTorch2 config for CLIP (hash {clip_hash[:8]}): {distorch_config['clip_allocation']}")
m, u = clip.load_sd(clip_sd, full_model=True) # This respects the patched text_encoder_device
if len(m) > 0: logger.warning(f"CLIP missing keys: {m}")
@@ -0,0 +1,245 @@
{
"6": {
"inputs": {
"text": [
"47",
2
],
"clip": [
"39",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"13",
0
],
"vae": [
"40",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"9": {
"inputs": {
"filename_prefix": "MultiGPU",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"13": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"22",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"16": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "KSamplerSelect"
}
},
"17": {
"inputs": {
"scheduler": "simple",
"steps": 20,
"denoise": 1,
"model": [
"30",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "BasicScheduler"
}
},
"22": {
"inputs": {
"model": [
"30",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "BasicGuider"
}
},
"25": {
"inputs": {
"noise_seed": 66527593966288
},
"class_type": "RandomNoise",
"_meta": {
"title": "RandomNoise"
}
},
"26": {
"inputs": {
"guidance": 3.5,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"27": {
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 1
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"30": {
"inputs": {
"max_shift": 1.15,
"base_shift": 0.5,
"width": 1024,
"height": 1024,
"model": [
"38",
0
]
},
"class_type": "ModelSamplingFlux",
"_meta": {
"title": "ModelSamplingFlux"
}
},
"38": {
"inputs": {
"unet_name": "flux1-dev-fp8.safetensors",
"weight_dtype": "default",
"device": "cuda:0"
},
"class_type": "UNETLoaderMultiGPU",
"_meta": {
"title": "UNETLoaderMultiGPU"
}
},
"39": {
"inputs": {
"clip_name1": "t5xxl_fp8_e4m3fn_scaled.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "cpu"
},
"class_type": "DualCLIPLoaderMultiGPU",
"_meta": {
"title": "DualCLIPLoaderMultiGPU"
}
},
"40": {
"inputs": {
"vae_name": "ae.safetensors",
"device": "cuda:1"
},
"class_type": "VAELoaderMultiGPU",
"_meta": {
"title": "VAELoaderMultiGPU"
}
},
"44": {
"inputs": {
"image": "ComfyUI-Florence2 detailed_caption to flux.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"45": {
"inputs": {
"model": "MiaoshouAI/Florence-2-large-PromptGen-v2.0",
"precision": "fp16",
"attention": "sdpa",
"convert_to_safetensors": "cuda:1",
"device": "cuda:1",
"offload_device": "cpu"
},
"class_type": "DownloadAndLoadFlorence2ModelMultiGPU",
"_meta": {
"title": "DownloadAndLoadFlorence2ModelMultiGPU"
}
},
"47": {
"inputs": {
"text_input": "",
"task": "detailed_caption",
"fill_mask": true,
"keep_model_loaded": true,
"max_new_tokens": 4096,
"num_beams": 3,
"do_sample": true,
"output_mask_select": "",
"seed": 61577449829591,
"image": [
"44",
0
],
"florence2_model": [
"45",
0
]
},
"class_type": "Florence2Run",
"_meta": {
"title": "Florence2Run"
}
}
}
@@ -0,0 +1,193 @@
{
"6": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, with \"GGUF\" emblazoned across its surface in massive neon blue-green mixed with purple letters that illuminate the surrounding buildings. The text occupies the central third of the frame, crafted from glowing plasma tubes and crackling energy. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"45",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"13",
0
],
"vae": [
"40",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"9": {
"inputs": {
"filename_prefix": "MultiGPU",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"13": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"22",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"16": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "KSamplerSelect"
}
},
"17": {
"inputs": {
"scheduler": "simple",
"steps": 20,
"denoise": 1,
"model": [
"30",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "BasicScheduler"
}
},
"22": {
"inputs": {
"model": [
"30",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "BasicGuider"
}
},
"25": {
"inputs": {
"noise_seed": 411099137945992
},
"class_type": "RandomNoise",
"_meta": {
"title": "RandomNoise"
}
},
"26": {
"inputs": {
"guidance": 3.5,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"27": {
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 1
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"30": {
"inputs": {
"max_shift": 1.15,
"base_shift": 0.5,
"width": 1024,
"height": 1024,
"model": [
"44",
0
]
},
"class_type": "ModelSamplingFlux",
"_meta": {
"title": "ModelSamplingFlux"
}
},
"40": {
"inputs": {
"vae_name": "ae.safetensors",
"device": "cuda:1"
},
"class_type": "VAELoaderMultiGPU",
"_meta": {
"title": "VAELoaderMultiGPU"
}
},
"44": {
"inputs": {
"unet_name": "flux1-dev-Q4_K_S.gguf",
"device": "cuda:0"
},
"class_type": "UnetLoaderGGUFMultiGPU",
"_meta": {
"title": "UnetLoaderGGUFMultiGPU"
}
},
"45": {
"inputs": {
"clip_name1": "t5-v1_1-xxl-encoder-Q4_K_S.gguf",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "cpu"
},
"class_type": "DualCLIPLoaderGGUFMultiGPU",
"_meta": {
"title": "DualCLIPLoaderGGUFMultiGPU"
}
}
}
@@ -0,0 +1,146 @@
{
"3": {
"inputs": {
"seed": 174815108394042,
"steps": 20,
"cfg": 2.5,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"66",
0
],
"positive": [
"6",
0
],
"negative": [
"7",
0
],
"latent_image": [
"58",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, with \"GGUF DisTorch 2\" emblazoned across its surface in massive neon blue-green mixed with purple letters that illuminate the surrounding buildings. The text occupies the central third of the frame, crafted from glowing plasma tubes and crackling energy. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"76",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"7": {
"inputs": {
"text": " ",
"clip": [
"76",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"70",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"58": {
"inputs": {
"width": 1328,
"height": 1328,
"batch_size": 1
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"60": {
"inputs": {
"filename_prefix": "MultiGPU",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"66": {
"inputs": {
"shift": 3.1000000000000005,
"model": [
"77",
0
]
},
"class_type": "ModelSamplingAuraFlow",
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"70": {
"inputs": {
"vae_name": "qwen_image_vae.safetensors",
"device": "cuda:1"
},
"class_type": "VAELoaderMultiGPU",
"_meta": {
"title": "VAELoaderMultiGPU"
}
},
"76": {
"inputs": {
"clip_name": "Qwen2.5-VL-7B-Instruct-Q4_K_S.gguf",
"type": "qwen_image",
"device": "cuda:1"
},
"class_type": "CLIPLoaderGGUFMultiGPU",
"_meta": {
"title": "CLIPLoaderGGUFMultiGPU"
}
},
"77": {
"inputs": {
"unet_name": "qwen-image-Q3_K_S.gguf",
"compute_device": "cuda:0",
"virtual_vram_gb": 4.2,
"donor_device": "cpu",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "UnetLoaderGGUFDisTorch2MultiGPU",
"_meta": {
"title": "UnetLoaderGGUFDisTorch2MultiGPU"
}
}
}
@@ -0,0 +1,427 @@
{
"56": {
"inputs": {
"lora": "Wan2.2-I2V-A14B-4steps-lora-rank64-Seko-V1/high_noise_model.safetensors",
"strength": 3,
"low_mem_load": false,
"merge_loras": false
},
"class_type": "WanVideoLoraSelect",
"_meta": {
"title": "WanVideo Lora Select"
}
},
"60": {
"inputs": {
"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": true,
"images": [
"69",
0
]
},
"class_type": "VHS_VideoCombine",
"_meta": {
"title": "Video Combine 🎥🅥🅗🅢"
}
},
"67": {
"inputs": {
"image": "sd15 checkpoint loader simple.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"68": {
"inputs": {
"width": 720,
"height": 720,
"upscale_method": "lanczos",
"keep_proportion": "resize",
"pad_color": "0, 0, 0",
"crop_position": "center",
"divisible_by": 32,
"device": "cpu",
"image": [
"67",
0
]
},
"class_type": "ImageResizeKJv2",
"_meta": {
"title": "Resize Image v2"
}
},
"69": {
"inputs": {
"image": [
"115",
0
]
},
"class_type": "GetImageSizeAndCount",
"_meta": {
"title": "Get Image Size & Count"
}
},
"79": {
"inputs": {
"model": [
"93",
0
],
"lora": [
"97",
0
]
},
"class_type": "WanVideoSetLoRAs",
"_meta": {
"title": "WanVideo Set LoRAs"
}
},
"80": {
"inputs": {
"model": [
"92",
0
],
"lora": [
"56",
0
]
},
"class_type": "WanVideoSetLoRAs",
"_meta": {
"title": "WanVideo Set LoRAs"
}
},
"91": {
"inputs": {
"value": 3
},
"class_type": "INTConstant",
"_meta": {
"title": "Split_step"
}
},
"92": {
"inputs": {
"block_swap_args": [
"116",
0
]
},
"class_type": "WanVideoSetBlockSwap",
"_meta": {
"title": "WanVideo Set BlockSwap"
}
},
"93": {
"inputs": {
"model": [
"108",
0
],
"block_swap_args": [
"116",
0
]
},
"class_type": "WanVideoSetBlockSwap",
"_meta": {
"title": "WanVideo Set BlockSwap"
}
},
"94": {
"inputs": {
"value": 6
},
"class_type": "INTConstant",
"_meta": {
"title": "Steps"
}
},
"95": {
"inputs": {
"steps": [
"94",
0
],
"cfg_scale_start": 2,
"cfg_scale_end": 2,
"interpolation": "linear",
"start_percent": 0,
"end_percent": 0.01
},
"class_type": "CreateCFGScheduleFloatList",
"_meta": {
"title": "Create CFG Schedule Float List"
}
},
"97": {
"inputs": {
"lora": "Wan2.2-I2V-A14B-4steps-lora-rank64-Seko-V1/low_noise_model.safetensors",
"strength": 1,
"low_mem_load": false,
"merge_loras": false
},
"class_type": "WanVideoLoraSelect",
"_meta": {
"title": "WanVideo Lora Select"
}
},
"99": {
"inputs": {
"model_name": "umt5-xxl-enc-bf16.safetensors",
"precision": "bf16",
"device": "cuda:0",
"quantization": "disabled"
},
"class_type": "LoadWanVideoT5TextEncoderMultiGPU",
"_meta": {
"title": "LoadWanVideoT5TextEncoderMultiGPU"
}
},
"100": {
"inputs": {
"positive_prompt": "The words \"ComfyUI-WanVideoWrapper\" emblazoned across the scene of an animated cyberpunk cityscape",
"negative_prompt": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
"force_offload": "cpu",
"use_disk_cache": false,
"t5": [
"99",
0
],
"load_device": [
"99",
1
]
},
"class_type": "WanVideoTextEncodeMultiGPU",
"_meta": {
"title": "WanVideoTextEncodeMultiGPU"
}
},
"105": {
"inputs": {
"steps": [
"94",
0
],
"cfg": [
"95",
0
],
"shift": 8.000000000000002,
"seed": 20843471366611,
"force_offload": true,
"scheduler": "dpm++_sde",
"riflex_freq_index": 0,
"denoise_strength": 1,
"batched_cfg": false,
"rope_function": "comfy",
"start_step": 0,
"end_step": [
"91",
0
],
"add_noise_to_samples": false,
"model": [
"109",
0
],
"compute_device": [
"109",
1
],
"image_embeds": [
"112",
0
],
"text_embeds": [
"100",
0
]
},
"class_type": "WanVideoSamplerMultiGPU",
"_meta": {
"title": "WanVideoSamplerMultiGPU"
}
},
"106": {
"inputs": {
"steps": [
"94",
0
],
"cfg": 1.0000000000000002,
"shift": 8.000000000000002,
"seed": 645006682079046,
"force_offload": true,
"scheduler": "dpm++_sde",
"riflex_freq_index": 0,
"denoise_strength": 1,
"batched_cfg": false,
"rope_function": "comfy",
"start_step": [
"91",
0
],
"end_step": -1,
"add_noise_to_samples": false,
"model": [
"79",
0
],
"compute_device": [
"108",
1
],
"image_embeds": [
"112",
0
],
"text_embeds": [
"100",
0
],
"samples": [
"105",
0
]
},
"class_type": "WanVideoSamplerMultiGPU",
"_meta": {
"title": "WanVideoSamplerMultiGPU"
}
},
"108": {
"inputs": {
"model": "Wan2.2-I2V-A14B-LowNoise-Q5_K_M.gguf",
"base_precision": "fp16_fast",
"quantization": "disabled",
"load_device": "offload_device",
"compute_device": "cuda:0",
"attention_mode": "sdpa",
"rms_norm_function": "default"
},
"class_type": "WanVideoModelLoaderMultiGPU",
"_meta": {
"title": "WanVideoModelLoaderMultiGPU"
}
},
"109": {
"inputs": {
"model": "Wan2.2-I2V-A14B-HighNoise-Q5_K_M.gguf",
"base_precision": "fp16_fast",
"quantization": "disabled",
"load_device": "offload_device",
"compute_device": "cuda:0",
"attention_mode": "sdpa",
"rms_norm_function": "default"
},
"class_type": "WanVideoModelLoaderMultiGPU",
"_meta": {
"title": "WanVideoModelLoaderMultiGPU"
}
},
"112": {
"inputs": {
"width": [
"68",
1
],
"height": [
"68",
2
],
"num_frames": 81,
"noise_aug_strength": 0,
"start_latent_strength": 1,
"end_latent_strength": 1,
"force_offload": true,
"fun_or_fl2v_model": false,
"tiled_vae": false,
"vae": [
"114",
0
],
"load_device": [
"114",
1
],
"start_image": [
"68",
0
]
},
"class_type": "WanVideoImageToVideoEncodeMultiGPU",
"_meta": {
"title": "WanVideoImageToVideoEncodeMultiGPU"
}
},
"114": {
"inputs": {
"model_name": "wan_2.1_vae.safetensors",
"load_device": "cuda:0",
"precision": "bf16"
},
"class_type": "WanVideoVAELoaderMultiGPU",
"_meta": {
"title": "WanVideoVAELoaderMultiGPU"
}
},
"115": {
"inputs": {
"enable_vae_tiling": false,
"tile_x": 272,
"tile_y": 272,
"tile_stride_x": 144,
"tile_stride_y": 128,
"normalization": "default",
"vae": [
"114",
0
],
"load_device": [
"114",
1
],
"samples": [
"106",
0
]
},
"class_type": "WanVideoDecodeMultiGPU",
"_meta": {
"title": "WanVideoDecodeMultiGPU"
}
},
"116": {
"inputs": {
"blocks_to_swap": 40,
"offload_img_emb": true,
"offload_txt_emb": true,
"use_non_blocking": false,
"vace_blocks_to_swap": 0,
"prefetch_blocks": 0,
"block_swap_debug": false,
"swap_device": "cuda:1"
},
"class_type": "WanVideoBlockSwapMultiGPU",
"_meta": {
"title": "WanVideoBlockSwapMultiGPU"
}
}
}
@@ -0,0 +1,270 @@
{
"30": {
"inputs": {
"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,
"images": [
"103",
0
]
},
"class_type": "VHS_VideoCombine",
"_meta": {
"title": "Video Combine 🎥🅥🅗🅢"
}
},
"52": {
"inputs": {
"rel_l1_thresh": 0.1,
"start_step": 1,
"end_step": -1,
"cache_device": "offload_device",
"use_coefficients": "true",
"mode": "e"
},
"class_type": "WanVideoTeaCache",
"_meta": {
"title": "WanVideo TeaCache"
}
},
"96": {
"inputs": {
"start_percent": 0,
"end_percent": 0.7,
"latents": [
"112",
0
]
},
"class_type": "WanVideoControlEmbeds",
"_meta": {
"title": "WanVideo Control Embeds"
}
},
"97": {
"inputs": {
"video": "ComfyUI-WanVideoWrapper wanvideo_1_3B control_lora.webm",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 0,
"skip_first_frames": 0,
"select_every_nth": 1,
"format": "AnimateDiff"
},
"class_type": "VHS_LoadVideo",
"_meta": {
"title": "Load Video (Upload) 🎥🅥🅗🅢"
}
},
"98": {
"inputs": {
"lora": "wan2.1-1.3b-control-lora-tile-v1.1_comfy.safetensors",
"strength": 1,
"low_mem_load": false,
"merge_loras": true
},
"class_type": "WanVideoLoraSelect",
"_meta": {
"title": "WanVideo Lora Select"
}
},
"103": {
"inputs": {
"inputcount": 2,
"direction": "right",
"match_image_size": false,
"Update inputs": null,
"image_1": [
"104",
0
],
"image_2": [
"114",
0
]
},
"class_type": "ImageConcatMulti",
"_meta": {
"title": "Image Concatenate Multi"
}
},
"104": {
"inputs": {
"blur_radius": 4,
"sigma": 1,
"image": [
"97",
0
]
},
"class_type": "ImageBlur",
"_meta": {
"title": "Image Blur"
}
},
"108": {
"inputs": {
"steps": 30,
"cfg": 6,
"shift": 5,
"seed": 0,
"force_offload": false,
"scheduler": "unipc",
"riflex_freq_index": 0,
"denoise_strength": 1,
"batched_cfg": false,
"rope_function": "comfy",
"start_step": 0,
"end_step": -1,
"add_noise_to_samples": false,
"model": [
"113",
0
],
"compute_device": [
"113",
1
],
"image_embeds": [
"96",
0
],
"text_embeds": [
"110",
0
],
"cache_args": [
"52",
0
]
},
"class_type": "WanVideoSamplerMultiGPU",
"_meta": {
"title": "WanVideoSamplerMultiGPU"
}
},
"109": {
"inputs": {
"model_name": "wan_2.1_vae.safetensors",
"load_device": "cuda:1",
"precision": "bf16"
},
"class_type": "WanVideoVAELoaderMultiGPU",
"_meta": {
"title": "WanVideoVAELoaderMultiGPU"
}
},
"110": {
"inputs": {
"positive_prompt": "video of a cyberpunk city street",
"negative_prompt": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
"force_offload": "cuda:0",
"use_disk_cache": false,
"t5": [
"111",
0
],
"load_device": [
"111",
1
]
},
"class_type": "WanVideoTextEncodeMultiGPU",
"_meta": {
"title": "WanVideoTextEncodeMultiGPU"
}
},
"111": {
"inputs": {
"model_name": "umt5-xxl-enc-bf16.safetensors",
"precision": "bf16",
"device": "cuda:1",
"quantization": "fp8_e4m3fn"
},
"class_type": "LoadWanVideoT5TextEncoderMultiGPU",
"_meta": {
"title": "LoadWanVideoT5TextEncoderMultiGPU"
}
},
"112": {
"inputs": {
"enable_vae_tiling": false,
"tile_x": 272,
"tile_y": 272,
"tile_stride_x": 144,
"tile_stride_y": 128,
"noise_aug_strength": 0,
"latent_strength": 1,
"vae": [
"109",
0
],
"load_device": [
"109",
1
],
"image": [
"104",
0
]
},
"class_type": "WanVideoEncodeMultiGPU",
"_meta": {
"title": "WanVideoEncodeMultiGPU"
}
},
"113": {
"inputs": {
"model": "Wan2_1-T2V-1_3B_bf16.safetensors",
"base_precision": "bf16",
"quantization": "disabled",
"load_device": "offload_device",
"compute_device": "cuda:0",
"attention_mode": "sdpa",
"rms_norm_function": "default",
"lora": [
"98",
0
]
},
"class_type": "WanVideoModelLoaderMultiGPU",
"_meta": {
"title": "WanVideoModelLoaderMultiGPU"
}
},
"114": {
"inputs": {
"enable_vae_tiling": false,
"tile_x": 272,
"tile_y": 272,
"tile_stride_x": 144,
"tile_stride_y": 128,
"normalization": "default",
"vae": [
"109",
0
],
"load_device": [
"109",
1
],
"samples": [
"108",
0
]
},
"class_type": "WanVideoDecodeMultiGPU",
"_meta": {
"title": "WanVideoDecodeMultiGPU"
}
}
}
@@ -0,0 +1,263 @@
{
"37": {
"inputs": {
"width": 832,
"height": 480,
"num_frames": 81
},
"class_type": "WanVideoEmptyEmbeds",
"_meta": {
"title": "WanVideo Empty Embeds"
}
},
"52": {
"inputs": {
"rel_l1_thresh": 0.25,
"start_step": 1,
"end_step": -1,
"cache_device": "offload_device",
"use_coefficients": false,
"mode": "e"
},
"class_type": "WanVideoTeaCache",
"_meta": {
"title": "WanVideo TeaCache"
}
},
"55": {
"inputs": {
"weight": 2,
"start_percent": 0,
"end_percent": 1
},
"class_type": "WanVideoEnhanceAVideo",
"_meta": {
"title": "WanVideo Enhance-A-Video"
}
},
"60": {
"inputs": {
"model_name": "umt5-xxl-enc-bf16.safetensors",
"precision": "bf16",
"device": "cuda:1",
"quantization": "disabled"
},
"class_type": "LoadWanVideoT5TextEncoderMultiGPU",
"_meta": {
"title": "LoadWanVideoT5TextEncoderMultiGPU"
}
},
"61": {
"inputs": {
"positive_prompt": "A towering technological monolith in a cyberpunk cityscape at night, with \"WanVideoWrapper\" and \"T2V\" emblazoned across its surface in massive neon blue-green mixed with purple letters that illuminate the surrounding buildings. The text occupies the center of the frame, crafted from glowing plasma tubes and crackling energy. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"negative_prompt": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
"force_offload": "cpu",
"use_disk_cache": false,
"t5": [
"60",
0
],
"load_device": [
"60",
1
]
},
"class_type": "WanVideoTextEncodeMultiGPU",
"_meta": {
"title": "WanVideoTextEncodeMultiGPU"
}
},
"62": {
"inputs": {
"model_name": "wan_2.1_vae.safetensors",
"load_device": "cuda:0",
"precision": "bf16"
},
"class_type": "WanVideoVAELoaderMultiGPU",
"_meta": {
"title": "WanVideoVAELoaderMultiGPU"
}
},
"63": {
"inputs": {
"steps": 25,
"cfg": 6,
"shift": 5,
"seed": 60,
"force_offload": true,
"scheduler": "unipc",
"riflex_freq_index": 0,
"denoise_strength": 1,
"batched_cfg": false,
"rope_function": "comfy",
"start_step": 0,
"end_step": -1,
"add_noise_to_samples": false,
"model": [
"66",
0
],
"compute_device": [
"72",
1
],
"image_embeds": [
"37",
0
],
"text_embeds": [
"61",
0
],
"feta_args": [
"55",
0
],
"cache_args": [
"52",
0
]
},
"class_type": "WanVideoSamplerMultiGPU",
"_meta": {
"title": "WanVideoSamplerMultiGPU"
}
},
"65": {
"inputs": {
"blocks_to_swap": 21,
"offload_img_emb": "cuda:2",
"offload_txt_emb": "cpu",
"use_non_blocking": false,
"vace_blocks_to_swap": false,
"prefetch_blocks": false,
"block_swap_debug": 0,
"swap_device": "cuda:1"
},
"class_type": "WanVideoBlockSwapMultiGPU",
"_meta": {
"title": "WanVideoBlockSwapMultiGPU"
}
},
"66": {
"inputs": {
"model": [
"72",
0
],
"block_swap_args": [
"65",
0
]
},
"class_type": "WanVideoSetBlockSwap",
"_meta": {
"title": "WanVideo Set BlockSwap"
}
},
"69": {
"inputs": {
"image": [
"75",
0
]
},
"class_type": "GetImageSizeAndCount",
"_meta": {
"title": "Get Image Size & Count"
}
},
"70": {
"inputs": {
"frame_rate": 16,
"loop_count": 0,
"filename_prefix": "MultiGPU",
"format": "video/h264-mp4",
"pix_fmt": "yuv420p",
"crf": 19,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true,
"images": [
"69",
0
]
},
"class_type": "VHS_VideoCombine",
"_meta": {
"title": "Video Combine 🎥🅥🅗🅢"
}
},
"72": {
"inputs": {
"model": "Wan2_1-T2V-14B_fp8_e5m2.safetensors",
"base_precision": "bf16",
"quantization": "disabled",
"load_device": "offload_device",
"compute_device": "cuda:0",
"attention_mode": "sdpa",
"rms_norm_function": "default",
"compile_args": [
"78",
0
]
},
"class_type": "WanVideoModelLoaderMultiGPU",
"_meta": {
"title": "WanVideoModelLoaderMultiGPU"
}
},
"74": {
"inputs": {
"model_name": "wan_2.1_vae.safetensors",
"load_device": "cuda:1",
"precision": "bf16"
},
"class_type": "WanVideoVAELoaderMultiGPU",
"_meta": {
"title": "WanVideoVAELoaderMultiGPU"
}
},
"75": {
"inputs": {
"enable_vae_tiling": false,
"tile_x": 272,
"tile_y": 272,
"tile_stride_x": 144,
"tile_stride_y": 128,
"normalization": "default",
"vae": [
"74",
0
],
"load_device": [
"74",
1
],
"samples": [
"63",
0
]
},
"class_type": "WanVideoDecodeMultiGPU",
"_meta": {
"title": "WanVideoDecodeMultiGPU"
}
},
"78": {
"inputs": {
"backend": "inductor",
"fullgraph": false,
"mode": "default",
"dynamic": false,
"dynamo_cache_size_limit": 64,
"compile_transformer_blocks_only": true,
"dynamo_recompile_limit": 128
},
"class_type": "WanVideoTorchCompileSettings",
"_meta": {
"title": "WanVideo Torch Compile Settings"
}
}
}
@@ -0,0 +1,194 @@
{
"6": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, with \"MultiGPU\" emblazoned across its surface in massive neon blue-green mixed with purple letters that illuminate the surrounding buildings. The text occupies the central third of the frame, crafted from glowing plasma tubes and crackling energy. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"39",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"13",
0
],
"vae": [
"40",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"9": {
"inputs": {
"filename_prefix": "MultiGPU",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"13": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"22",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"16": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "KSamplerSelect"
}
},
"17": {
"inputs": {
"scheduler": "simple",
"steps": 20,
"denoise": 1,
"model": [
"30",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "BasicScheduler"
}
},
"22": {
"inputs": {
"model": [
"30",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "BasicGuider"
}
},
"25": {
"inputs": {
"noise_seed": 653376826227025
},
"class_type": "RandomNoise",
"_meta": {
"title": "RandomNoise"
}
},
"26": {
"inputs": {
"guidance": 3.5,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "FluxGuidance"
}
},
"27": {
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 1
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"30": {
"inputs": {
"max_shift": 1.15,
"base_shift": 0.5,
"width": 1024,
"height": 1024,
"model": [
"38",
0
]
},
"class_type": "ModelSamplingFlux",
"_meta": {
"title": "ModelSamplingFlux"
}
},
"38": {
"inputs": {
"unet_name": "flux1-dev-fp8.safetensors",
"weight_dtype": "default",
"device": "cuda:0"
},
"class_type": "UNETLoaderMultiGPU",
"_meta": {
"title": "UNETLoaderMultiGPU"
}
},
"39": {
"inputs": {
"clip_name1": "t5xxl_fp8_e4m3fn_scaled.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "cpu"
},
"class_type": "DualCLIPLoaderMultiGPU",
"_meta": {
"title": "DualCLIPLoaderMultiGPU"
}
},
"40": {
"inputs": {
"vae_name": "ae.safetensors",
"device": "cuda:1"
},
"class_type": "VAELoaderMultiGPU",
"_meta": {
"title": "VAELoaderMultiGPU"
}
}
}
@@ -0,0 +1,215 @@
{
"6": {
"inputs": {
"text": "The sun, having just dipped below the horizon, casts a deep twilight blue across the urban canyon. The air is thick with the hush of the approaching night, punctuated only by the distant hum of the city. A gentle drizzle has just passed, leaving the asphalt slick and reflective, mirroring the neon glow from the towering buildings.\n\nIn the foreground, the street stretches out, a dark ribbon reflecting the faint reds and purples of brake lights and storefronts. Small puddles shimmer, disturbed only by the occasional ripple from a lingering raindrop or the almost imperceptible air current.\n\nAs the 3 seconds pass, a barely noticeable shift occurs. The light in the sky ever so subtly deepens, transitioning from a soft, almost ethereal blue to a richer, more profound indigo. The neon signs, which were already bright, seem to gain a fractional intensity, their colors bleeding slightly more vividly onto the wet pavement below. The faint glint on the parked cars, particularly the red one, catches the ambient light just a touch more, highlighting the curves of its wet surface.\n\nIt's a moment of serene transition, a quiet breath as the city fully embraces the night, its artificial lights beginning their nightly dominance against the fading natural world.",
"clip": [
"97",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"7": {
"inputs": {
"text": "low quality, worst quality, deformed, distorted, disfigured, motion smear, motion artifacts, fused fingers, bad anatomy, weird hand, ugly",
"clip": [
"97",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"72",
0
],
"vae": [
"96",
2
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"41": {
"inputs": {
"filename_prefix": "MultiGPU",
"fps": 25,
"lossless": false,
"quality": 90,
"method": "default",
"images": [
"8",
0
]
},
"class_type": "SaveAnimatedWEBP",
"_meta": {
"title": "SaveAnimatedWEBP"
}
},
"69": {
"inputs": {
"frame_rate": 25,
"positive": [
"95",
0
],
"negative": [
"95",
1
]
},
"class_type": "LTXVConditioning",
"_meta": {
"title": "LTXVConditioning"
}
},
"71": {
"inputs": {
"steps": 30,
"max_shift": 2.05,
"base_shift": 0.95,
"stretch": true,
"terminal": 0.1,
"latent": [
"95",
2
]
},
"class_type": "LTXVScheduler",
"_meta": {
"title": "LTXVScheduler"
}
},
"72": {
"inputs": {
"add_noise": true,
"noise_seed": 871180669305010,
"cfg": 3,
"model": [
"96",
0
],
"positive": [
"69",
0
],
"negative": [
"69",
1
],
"sampler": [
"73",
0
],
"sigmas": [
"71",
0
],
"latent_image": [
"95",
2
]
},
"class_type": "SamplerCustom",
"_meta": {
"title": "SamplerCustom"
}
},
"73": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "KSamplerSelect"
}
},
"78": {
"inputs": {
"image": "ltxvideo checkpointloadersimple distorch2.jpg"
},
"class_type": "LoadImage",
"_meta": {
"title": "Load Image"
}
},
"82": {
"inputs": {
"img_compression": 40,
"image": [
"78",
0
]
},
"class_type": "LTXVPreprocess",
"_meta": {
"title": "LTXVPreprocess"
}
},
"95": {
"inputs": {
"width": 512,
"height": 768,
"length": 97,
"batch_size": 1,
"strength": 1,
"positive": [
"6",
0
],
"negative": [
"7",
0
],
"vae": [
"96",
2
],
"image": [
"82",
0
]
},
"class_type": "LTXVImgToVideo",
"_meta": {
"title": "LTXVImgToVideo"
}
},
"96": {
"inputs": {
"ckpt_name": "ltx-video-2b-v0.9.5.safetensors",
"compute_device": "cuda:0",
"virtual_vram_gb": 5,
"donor_device": "cuda:1",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "CheckpointLoaderSimpleDisTorch2MultiGPU",
"_meta": {
"title": "CheckpointLoaderSimpleDisTorch2MultiGPU"
}
},
"97": {
"inputs": {
"clip_name": "t5xxl_fp16.safetensors",
"type": "ltxv",
"device": "cuda:1"
},
"class_type": "CLIPLoaderMultiGPU",
"_meta": {
"title": "CLIPLoaderMultiGPU"
}
}
}
@@ -0,0 +1,122 @@
{
"3": {
"inputs": {
"seed": 363535877769015,
"steps": 30,
"cfg": 4.5,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"44",
0
],
"positive": [
"6",
0
],
"negative": [
"7",
0
],
"latent_image": [
"21",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "A neon blue-green frog with vibrant neon purple spots stares forward with its left eye moving subtly. The frog's skin is textured with small bumps, and its spots appear in irregular patterns across its head and face. The eye is round and black with a subtle shine. The head is slightly tilted to its left, and the body is barely visible. The background is a flat, solid deep blue color, extending beyond the frog in all directions. The camera zooms in slowly on the frog's eye and the frog looks directly at the viewer. The overall lighting is bright and diffused, creating a soft appearance.",
"clip": [
"44",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"clip": [
"44",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"44",
2
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"21": {
"inputs": {
"width": 848,
"height": 480,
"length": 25,
"batch_size": 1
},
"class_type": "EmptyMochiLatentVideo",
"_meta": {
"title": "EmptyMochiLatentVideo"
}
},
"28": {
"inputs": {
"filename_prefix": "MultiGPU",
"fps": 24,
"lossless": false,
"quality": 90,
"method": "default",
"images": [
"8",
0
]
},
"class_type": "SaveAnimatedWEBP",
"_meta": {
"title": "SaveAnimatedWEBP"
}
},
"44": {
"inputs": {
"ckpt_name": "mochi_preview_fp8_scaled.safetensors",
"unet_compute_device": "cuda:0",
"unet_virtual_vram_gb": 5,
"unet_donor_device": "cpu",
"clip_compute_device": "cuda:1",
"clip_virtual_vram_gb": 2,
"clip_donor_device": "cpu",
"vae_device": "cuda:1",
"unet_expert_mode_allocations": "",
"clip_expert_mode_allocations": "",
"high_precision_loras": true
},
"class_type": "CheckpointLoaderAdvancedDisTorch2MultiGPU",
"_meta": {
"title": "CheckpointLoaderAdvancedDisTorch2MultiGPU"
}
}
}
@@ -0,0 +1,151 @@
{
"3": {
"inputs": {
"seed": 133236841455355,
"steps": 20,
"cfg": 2.5,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"model": [
"66",
0
],
"positive": [
"6",
0
],
"negative": [
"7",
0
],
"latent_image": [
"58",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"6": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, with \"QWEN Image DisTorch 2\" emblazoned across its surface in massive neon blue-green mixed with purple letters that illuminate the surrounding buildings. The text occupies the central third of the frame, crafted from glowing plasma tubes and crackling energy. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"79",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"7": {
"inputs": {
"text": " ",
"clip": [
"79",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"70",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"58": {
"inputs": {
"width": 1328,
"height": 1328,
"batch_size": 1
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"60": {
"inputs": {
"filename_prefix": "MultiGPU",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"66": {
"inputs": {
"shift": 3.1000000000000005,
"model": [
"78",
0
]
},
"class_type": "ModelSamplingAuraFlow",
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"70": {
"inputs": {
"vae_name": "qwen_image_vae.safetensors",
"device": "cuda:1"
},
"class_type": "VAELoaderMultiGPU",
"_meta": {
"title": "VAELoaderMultiGPU"
}
},
"78": {
"inputs": {
"unet_name": "qwen_image_fp8_e4m3fn.safetensors",
"weight_dtype": "default",
"compute_device": "cuda:0",
"virtual_vram_gb": 14,
"donor_device": "cpu",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "UNETLoaderDisTorch2MultiGPU",
"_meta": {
"title": "UNETLoaderDisTorch2MultiGPU"
}
},
"79": {
"inputs": {
"clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
"type": "qwen_image",
"device": "cuda:1",
"virtual_vram_gb": 3.9,
"donor_device": "cpu",
"expert_mode_allocations": "",
"eject_models": false
},
"class_type": "CLIPLoaderDisTorch2MultiGPU",
"_meta": {
"title": "CLIPLoaderDisTorch2MultiGPU"
}
}
}
@@ -0,0 +1,108 @@
{
"2": {
"inputs": {
"seed": 768019607311046,
"steps": 20,
"cfg": 8,
"sampler_name": "dpmpp_2m_sde_gpu",
"scheduler": "karras",
"denoise": 1,
"model": [
"19",
0
],
"positive": [
"21",
0
],
"negative": [
"25",
0
],
"latent_image": [
"8",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"5": {
"inputs": {
"samples": [
"2",
0
],
"vae": [
"19",
2
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"8": {
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 1
},
"class_type": "EmptyLatentImage",
"_meta": {
"title": "Empty Latent Image"
}
},
"19": {
"inputs": {
"ckpt_name": "sd1.5-real-dream-16.safetensors",
"device": "cuda:1"
},
"class_type": "CheckpointLoaderSimpleMultiGPU",
"_meta": {
"title": "CheckpointLoaderSimpleMultiGPU"
}
},
"21": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, neon blue-green mixed with purple illuminate the surrounding buildings. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"19",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"25": {
"inputs": {
"text": "",
"clip": [
"19",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"28": {
"inputs": {
"filename_prefix": "MultiGPU",
"images": [
"5",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
}
}
@@ -0,0 +1,110 @@
{
"2": {
"inputs": {
"seed": 1018829187018126,
"steps": 20,
"cfg": 8,
"sampler_name": "dpmpp_2m_sde_gpu",
"scheduler": "karras",
"denoise": 1,
"model": [
"27",
0
],
"positive": [
"21",
0
],
"negative": [
"25",
0
],
"latent_image": [
"8",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"5": {
"inputs": {
"samples": [
"2",
0
],
"vae": [
"27",
2
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"8": {
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 1
},
"class_type": "EmptyLatentImage",
"_meta": {
"title": "Empty Latent Image"
}
},
"21": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, neon blue-green mixed with purple illuminate the surrounding buildings. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"27",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"23": {
"inputs": {
"filename_prefix": "MultiGPU",
"images": [
"5",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"25": {
"inputs": {
"text": "",
"clip": [
"27",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"27": {
"inputs": {
"ckpt_name": "Juggernaut-XL_v9_RunDiffusionPhoto_v2.safetensors",
"unet_device": "cuda:0",
"clip_device": "cpu",
"vae_device": "cuda:1"
},
"class_type": "CheckpointLoaderAdvancedMultiGPU",
"_meta": {
"title": "CheckpointLoaderAdvancedMultiGPU"
}
}
}
@@ -0,0 +1,232 @@
{
"6": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, with \"Wan 2.2 DisTorch 2\" emblazoned across its surface in massive neon blue-green mixed with purple letters that illuminate the surrounding buildings. The text occupies the center of the frame, crafted from glowing plasma tubes and crackling energy. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"68",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"7": {
"inputs": {
"text": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
"clip": [
"68",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"58",
0
],
"vae": [
"67",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"28": {
"inputs": {
"filename_prefix": "MultiGPU",
"fps": 16,
"lossless": false,
"quality": 80,
"method": "default",
"images": [
"8",
0
]
},
"class_type": "SaveAnimatedWEBP",
"_meta": {
"title": "SaveAnimatedWEBP"
}
},
"47": {
"inputs": {
"filename_prefix": "MultiGPU",
"codec": "vp9",
"fps": 16.000000000000004,
"crf": 13.3333740234375,
"images": [
"8",
0
]
},
"class_type": "SaveWEBM",
"_meta": {
"title": "SaveWEBM"
}
},
"54": {
"inputs": {
"shift": 8.000000000000002,
"model": [
"62",
0
]
},
"class_type": "ModelSamplingSD3",
"_meta": {
"title": "ModelSamplingSD3"
}
},
"55": {
"inputs": {
"shift": 8,
"model": [
"70",
0
]
},
"class_type": "ModelSamplingSD3",
"_meta": {
"title": "ModelSamplingSD3"
}
},
"57": {
"inputs": {
"add_noise": "enable",
"noise_seed": 868525555974331,
"steps": 20,
"cfg": 3.5,
"sampler_name": "euler",
"scheduler": "simple",
"start_at_step": 0,
"end_at_step": 10,
"return_with_leftover_noise": "enable",
"model": [
"54",
0
],
"positive": [
"6",
0
],
"negative": [
"7",
0
],
"latent_image": [
"61",
0
]
},
"class_type": "KSamplerAdvanced",
"_meta": {
"title": "KSampler (Advanced)"
}
},
"58": {
"inputs": {
"add_noise": "disable",
"noise_seed": 0,
"steps": 20,
"cfg": 3.5,
"sampler_name": "euler",
"scheduler": "simple",
"start_at_step": 10,
"end_at_step": 10000,
"return_with_leftover_noise": "disable",
"model": [
"55",
0
],
"positive": [
"6",
0
],
"negative": [
"7",
0
],
"latent_image": [
"57",
0
]
},
"class_type": "KSamplerAdvanced",
"_meta": {
"title": "KSampler (Advanced)"
}
},
"61": {
"inputs": {
"width": 1280,
"height": 704,
"length": 57,
"batch_size": 1
},
"class_type": "EmptyHunyuanLatentVideo",
"_meta": {
"title": "EmptyHunyuanLatentVideo"
}
},
"62": {
"inputs": {
"unet_name": "wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
"weight_dtype": "default",
"compute_device": "cuda:0",
"virtual_vram_gb": 9,
"donor_device": "cuda:1",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "UNETLoaderDisTorch2MultiGPU",
"_meta": {
"title": "UNETLoaderDisTorch2MultiGPU"
}
},
"67": {
"inputs": {
"vae_name": "wan_2.1_vae.safetensors",
"device": "cuda:1"
},
"class_type": "VAELoaderMultiGPU",
"_meta": {
"title": "VAELoaderMultiGPU"
}
},
"68": {
"inputs": {
"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors",
"type": "wan",
"device": "cuda:1"
},
"class_type": "CLIPLoaderMultiGPU",
"_meta": {
"title": "CLIPLoaderMultiGPU"
}
},
"70": {
"inputs": {
"unet_name": "wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
"weight_dtype": "default",
"compute_device": "cuda:0",
"virtual_vram_gb": 9,
"donor_device": "cuda:1",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "UNETLoaderDisTorch2MultiGPU",
"_meta": {
"title": "UNETLoaderDisTorch2MultiGPU"
}
}
}
@@ -0,0 +1,223 @@
{
"3": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, with \"WAN 2.2\" and \"T2I\" emblazoned across its surface in massive neon blue-green mixed with purple letters that illuminate the surrounding buildings, with a smaller \"lightx2v\" underneath, bursting with color. The text occupies the central third of the frame, crafted from glowing plasma tubes and crackling energy. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"29",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "Positive Prompt"
}
},
"4": {
"inputs": {
"text": "",
"clip": [
"29",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "Negative Prompt"
}
},
"5": {
"inputs": {
"width": 1536,
"height": 1536,
"length": 1,
"batch_size": 1
},
"class_type": "EmptyHunyuanLatentVideo",
"_meta": {
"title": "EmptyHunyuanLatentVideo"
}
},
"9": {
"inputs": {
"samples": [
"36",
0
],
"vae": [
"55",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"10": {
"inputs": {
"filename_prefix": "MultiGPU",
"images": [
"9",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
},
"29": {
"inputs": {
"lora_name": "Wan2.2-T2V-A14B-4steps-lora-rank64-Seko-V1.1/high_noise.safetensors",
"strength_model": 1,
"strength_clip": 1,
"model": [
"50",
0
],
"clip": [
"51",
0
]
},
"class_type": "LoraLoader",
"_meta": {
"title": "Load LoRA"
}
},
"35": {
"inputs": {
"add_noise": "enable",
"noise_seed": 38613268423774,
"steps": 8,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"start_at_step": 0,
"end_at_step": 4,
"return_with_leftover_noise": "disable",
"model": [
"29",
0
],
"positive": [
"3",
0
],
"negative": [
"4",
0
],
"latent_image": [
"5",
0
]
},
"class_type": "KSamplerAdvanced",
"_meta": {
"title": "KSampler (Advanced)"
}
},
"36": {
"inputs": {
"add_noise": "enable",
"noise_seed": 8496083239430,
"steps": 8,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"start_at_step": 4,
"end_at_step": 8,
"return_with_leftover_noise": "disable",
"model": [
"44",
0
],
"positive": [
"3",
0
],
"negative": [
"4",
0
],
"latent_image": [
"35",
0
]
},
"class_type": "KSamplerAdvanced",
"_meta": {
"title": "KSampler (Advanced)"
}
},
"44": {
"inputs": {
"lora_name": "Wan2.2-T2V-A14B-4steps-lora-rank64-Seko-V1.1/low_noise.safetensors",
"strength_model": 1,
"model": [
"52",
0
]
},
"class_type": "LoraLoaderModelOnly",
"_meta": {
"title": "LoraLoaderModelOnly"
}
},
"50": {
"inputs": {
"unet_name": "wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
"weight_dtype": "default",
"compute_device": "cuda:0",
"virtual_vram_gb": 9,
"donor_device": "cpu",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "UNETLoaderDisTorch2MultiGPU",
"_meta": {
"title": "UNETLoaderDisTorch2MultiGPU"
}
},
"51": {
"inputs": {
"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors",
"type": "wan",
"device": "cuda:0"
},
"class_type": "CLIPLoaderMultiGPU",
"_meta": {
"title": "CLIPLoaderMultiGPU"
}
},
"52": {
"inputs": {
"unet_name": "wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
"weight_dtype": "default",
"compute_device": "cuda:0",
"virtual_vram_gb": 9,
"donor_device": "cpu",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "UNETLoaderDisTorch2MultiGPU",
"_meta": {
"title": "UNETLoaderDisTorch2MultiGPU"
}
},
"55": {
"inputs": {
"vae_name": "wan_2.1_vae.safetensors",
"compute_device": "cuda:0",
"virtual_vram_gb": 0,
"donor_device": "cpu",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "VAELoaderDisTorch2MultiGPU",
"_meta": {
"title": "VAELoaderDisTorch2MultiGPU"
}
}
}
@@ -0,0 +1,227 @@
{
"3": {
"inputs": {
"text": "A towering technological monolith in a cyberpunk cityscape at night, with \"WAN 2.2\" and \"T2V\" emblazoned across its surface in massive neon blue-green mixed with purple letters that illuminate the surrounding buildings, with a smaller \"lightx2v\" underneath, bursting with color. The text occupies the central third of the frame, crafted from glowing plasma tubes and crackling energy. Rain-slicked streets below reflect the brilliant signage, while holographic advertisements and flying vehicles populate the background. Moody atmospheric lighting, heavy contrast, photorealistic textures, cinematic color grading. ",
"clip": [
"29",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "Positive Prompt"
}
},
"4": {
"inputs": {
"text": "",
"clip": [
"29",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "Negative Prompt"
}
},
"5": {
"inputs": {
"width": 768,
"height": 768,
"length": 81,
"batch_size": 1
},
"class_type": "EmptyHunyuanLatentVideo",
"_meta": {
"title": "EmptyHunyuanLatentVideo"
}
},
"9": {
"inputs": {
"samples": [
"36",
0
],
"vae": [
"55",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"29": {
"inputs": {
"lora_name": "Wan2.2-T2V-A14B-4steps-lora-rank64-Seko-V1.1/high_noise.safetensors",
"strength_model": 1,
"strength_clip": 1,
"model": [
"50",
0
],
"clip": [
"51",
0
]
},
"class_type": "LoraLoader",
"_meta": {
"title": "Load LoRA"
}
},
"35": {
"inputs": {
"add_noise": "enable",
"noise_seed": 463363085190188,
"steps": 8,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"start_at_step": 0,
"end_at_step": 4,
"return_with_leftover_noise": "disable",
"model": [
"29",
0
],
"positive": [
"3",
0
],
"negative": [
"4",
0
],
"latent_image": [
"5",
0
]
},
"class_type": "KSamplerAdvanced",
"_meta": {
"title": "KSampler (Advanced)"
}
},
"36": {
"inputs": {
"add_noise": "enable",
"noise_seed": 989059799892359,
"steps": 8,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"start_at_step": 4,
"end_at_step": 8,
"return_with_leftover_noise": "disable",
"model": [
"44",
0
],
"positive": [
"3",
0
],
"negative": [
"4",
0
],
"latent_image": [
"35",
0
]
},
"class_type": "KSamplerAdvanced",
"_meta": {
"title": "KSampler (Advanced)"
}
},
"44": {
"inputs": {
"lora_name": "Wan2.2-T2V-A14B-4steps-lora-rank64-Seko-V1.1/low_noise.safetensors",
"strength_model": 1,
"model": [
"52",
0
]
},
"class_type": "LoraLoaderModelOnly",
"_meta": {
"title": "LoraLoaderModelOnly"
}
},
"50": {
"inputs": {
"unet_name": "wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
"weight_dtype": "default",
"compute_device": "cuda:0",
"virtual_vram_gb": 13,
"donor_device": "cuda:1",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "UNETLoaderDisTorch2MultiGPU",
"_meta": {
"title": "UNETLoaderDisTorch2MultiGPU"
}
},
"51": {
"inputs": {
"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors",
"type": "wan",
"device": "cuda:0"
},
"class_type": "CLIPLoaderMultiGPU",
"_meta": {
"title": "CLIPLoaderMultiGPU"
}
},
"52": {
"inputs": {
"unet_name": "wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
"weight_dtype": "default",
"compute_device": "cuda:0",
"virtual_vram_gb": 13,
"donor_device": "cpu",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "UNETLoaderDisTorch2MultiGPU",
"_meta": {
"title": "UNETLoaderDisTorch2MultiGPU"
}
},
"55": {
"inputs": {
"vae_name": "wan_2.1_vae.safetensors",
"compute_device": "cuda:0",
"virtual_vram_gb": 0,
"donor_device": "cpu",
"expert_mode_allocations": "",
"eject_models": true
},
"class_type": "VAELoaderDisTorch2MultiGPU",
"_meta": {
"title": "VAELoaderDisTorch2MultiGPU"
}
},
"58": {
"inputs": {
"filename_prefix": "MultiGPU",
"fps": 16,
"lossless": false,
"quality": 80,
"method": "default",
"images": [
"9",
0
]
},
"class_type": "SaveAnimatedWEBP",
"_meta": {
"title": "SaveAnimatedWEBP"
}
}
}
+3 -16
View File
@@ -235,30 +235,17 @@ original_soft_empty_cache = mm.soft_empty_cache
def soft_empty_cache_distorch2_patched(force=False):
"""Patched mm.soft_empty_cache managing VRAM across all devices, CPU RAM with adaptive thresholding, and DisTorch store pruning."""
from .model_management_mgpu import multigpu_memory_log, check_cpu_memory_threshold, trigger_executor_cache_reset
from .distorch_2 import safetensor_allocation_store, create_safetensor_model_hash
is_distorch_active = False
# Detect DisTorch2-managed models
# logger.mgpu_mm_log(f"[DETECT_DEBUG] Checking DisTorch2 active status - loaded models: {len(mm.current_loaded_models)}, store entries: {len(safetensor_allocation_store)}")
for i, lm in enumerate(mm.current_loaded_models):
mp = lm.model # weakref call to ModelPatcher
mp = lm.model
if mp is not None:
model_hash = create_safetensor_model_hash(mp, "cache_patch_check")
in_store = model_hash in safetensor_allocation_store
alloc_value = safetensor_allocation_store.get(model_hash, "")
model_name = type(getattr(mp, 'model', mp)).__name__
unload_distorch_model = getattr(getattr(mp, 'model', None), '_mgpu_unload_distorch_model', False)
inner_model = mp.model
#logger.mgpu_mm_log(f"[DETECT_DEBUG] Model {i}: {model_name}, hash={model_hash[:8]}, in_store={in_store}, alloc_value='{alloc_value}', unload_distorch_model={unload_distorch_model}")
if in_store and alloc_value:
if hasattr(inner_model, '_distorch_v2_meta'):
is_distorch_active = True
#logger.mgpu_mm_log(f"[DETECT_DEBUG] DisTorch2 ACTIVE detected on model: {model_name}")
break
#logger.mgpu_mm_log(f"[DETECT_DEBUG] Final DisTorch2 active status: {is_distorch_active}")
# Phase 2: adaptive CPU memory management
check_cpu_memory_threshold()
+39 -59
View File
@@ -20,38 +20,6 @@ from .device_utils import get_device_list, soft_empty_cache_multigpu
from .model_management_mgpu import multigpu_memory_log, force_full_system_cleanup
safetensor_allocation_store = {}
safetensor_settings_store = {}
def create_safetensor_model_hash(model, caller):
"""Create a unique hash for a safetensor model to track allocations"""
if hasattr(model, 'model'):
# For ModelPatcher objects
actual_model = model.model
model_type = type(actual_model).__name__
# Use ComfyUI's model_size if available
if hasattr(model, 'model_size'):
model_size = model.model_size()
else:
model_size = sum(p.numel() * p.element_size() for p in actual_model.parameters())
if hasattr(model, 'model_state_dict'):
first_layers = str(list(model.model_state_dict().keys())[:3])
else:
first_layers = str(list(actual_model.state_dict().keys())[:3])
else:
# Direct model
model_type = type(model).__name__
model_size = sum(p.numel() * p.element_size() for p in model.parameters())
first_layers = str(list(model.state_dict().keys())[:3])
identifier = f"{model_type}_{model_size}_{first_layers}"
final_hash = hashlib.sha256(identifier.encode()).hexdigest()
# DEBUG STATEMENT - ALWAYS LOG THE HASH
logger.debug(f"[MultiGPU DisTorch V2] Created hash for {caller}: {final_hash[:8]}...")
return final_hash
def register_patched_safetensor_modelpatcher():
"""Register and patch the ModelPatcher for distributed safetensor loading"""
from comfy.model_patcher import wipe_lowvram_weight, move_weight_functions
@@ -128,23 +96,35 @@ def register_patched_safetensor_modelpatcher():
device = loaded_model.device
base_memory = loaded_model.model_memory_required(device)
# Check DisTorch flags
is_distorch = hasattr(loaded_model.model.model, '_mgpu_virtual_vram_gb')
has_eject = hasattr(loaded_model.model.model, '_mgpu_eject_models')
if has_eject:
eject_device = device
logger.mgpu_mm_log("DisTorch eject_models=True, is_distorch=True - MAX memory eviction")
if is_distorch:
# is_distorch=True: use compute device allocation size
virtual_vram_gb = loaded_model.model.model._mgpu_virtual_vram_gb
inner_model = loaded_model.model.model
if hasattr(inner_model, '_distorch_v2_meta'):
meta = inner_model._distorch_v2_meta
allocation_str = meta['full_allocation']
# Parse allocation string: "expert#compute_device;virtual_vram_gb;donors"
parts = allocation_str.split('#')
virtual_vram_gb = 0.0
has_eject = False
if len(parts) > 1:
virtual_vram_str = parts[1]
virtual_info = virtual_vram_str.split(';')
if len(virtual_info) > 1:
virtual_vram_gb = float(virtual_info[1])
if len(virtual_info) > 2 and virtual_info[2]:
has_eject = True
if has_eject:
eject_device = device
logger.mgpu_mm_log("DisTorch eject_models detected - MAX memory eviction")
virtual_vram_bytes = virtual_vram_gb * (1024**3)
adjusted_memory = max(0, base_memory - virtual_vram_bytes)
total_memory_required[device] = total_memory_required.get(device, 0) + adjusted_memory
logger.mgpu_mm_log(f"DisTorch is_distorch=True, model adjusted {(base_memory - virtual_vram_bytes)/(1024**3):.2f}GB for device {device}")
logger.mgpu_mm_log(f"DisTorch model adjusted {(base_memory - virtual_vram_bytes)/(1024**3):.2f}GB for device {device}")
else:
# is_distorch=False: use full model size
# Standard model: use full model size
total_memory_required[device] = total_memory_required.get(device, 0) + base_memory
logger.mgpu_mm_log(f"[LOAD_MODELS_GPU] Standard model {(base_memory)/(1024**3):.2f}GB for device {device}")
@@ -209,23 +189,24 @@ def register_patched_safetensor_modelpatcher():
original_partially_load = comfy.model_patcher.ModelPatcher.partially_load
def new_partially_load(self, device_to, extra_memory=0, full_load=False, force_patch_weights=False, **kwargs):
"""Override to use our static device assignments"""
global safetensor_allocation_store
debug_hash = create_safetensor_model_hash(self, "partial_load")
multigpu_memory_log(f"safetensor:{debug_hash[:8]}", "pre-load")
allocations = safetensor_allocation_store.get(debug_hash)
# Set default precision flag before checking
if not hasattr(self.model, '_distorch_high_precision_loras'):
self.model._distorch_high_precision_loras = True
if not allocations:
"""Override to use direct model annotation for allocation"""
mp_id = id(self)
mp_patches_uuid = self.patches_uuid
inner_model = self.model
inner_model_id = id(inner_model)
if not hasattr(inner_model, "_distorch_v2_meta"):
logger.debug(f"[DISTORCH_SKIP] ModelPatcher=0x{mp_id:x} inner_model=0x{inner_model_id:x} type={type(inner_model).__name__} - no metadata, using standard loading")
result = original_partially_load(self, device_to, extra_memory, force_patch_weights)
multigpu_memory_log(f"safetensor:{debug_hash[:8]}", "post-load")
if hasattr(self, '_distorch_block_assignments'):
del self._distorch_block_assignments
return result
allocations = inner_model._distorch_v2_meta['full_allocation']
if not hasattr(self.model, '_distorch_high_precision_loras'):
self.model._distorch_high_precision_loras = True
if not hasattr(self.model, 'current_weight_patches_uuid'):
self.model.current_weight_patches_uuid = None
@@ -308,7 +289,6 @@ def register_patched_safetensor_modelpatcher():
logger.info("[MultiGPU DisTorch V2] DisTorch loading completed.")
logger.info(f"[MultiGPU DisTorch V2] Total memory: {mem_counter / (1024 * 1024):.2f}MB")
multigpu_memory_log(f"safetensor:{debug_hash[:8]}", "post-load")
return 0
-21
View File
@@ -22,30 +22,9 @@ logger = logging.getLogger("MultiGPU")
# Model Analysis and Store Management (DisTorch V1 & V2)
# ==========================================================================================
# DisTorch V2 SafeTensor stores
safetensor_allocation_store = {}
safetensor_settings_store = {}
# DisTorch V1 GGUF stores (backwards compatibility)
model_allocation_store = {}
def create_safetensor_model_hash(model, caller):
"""Create a unique hash for a safetensor model to track allocations"""
if hasattr(model, 'model'):
actual_model = model.model
model_type = type(actual_model).__name__
model_size = model.model_size() if hasattr(model, 'model_size') else sum(p.numel() * p.element_size() for p in actual_model.parameters())
first_layers = str(list(model.model_state_dict().keys() if hasattr(model, 'model_state_dict') else actual_model.state_dict().keys())[:3])
else:
model_type = type(model).__name__
model_size = sum(p.numel() * p.element_size() for p in model.parameters())
first_layers = str(list(model.state_dict().keys())[:3])
identifier = f"{model_type}_{model_size}_{first_layers}"
final_hash = hashlib.sha256(identifier.encode()).hexdigest()
logger.debug(f"[MultiGPU DisTorch V2] Created hash for {caller}: {final_hash[:8]}...")
return final_hash
def create_model_hash(model, caller):
"""Create a unique hash for a GGUF model to track allocations (DisTorch V1)"""
model_type = type(model.model).__name__
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-multigpu"
description = "Provides a suite of custom nodes to manage multiple GPUs for ComfyUI, including advanced model offloading for both GGUF and Safetensor formats with DisTorch, and bespoke MultiGPU support for WanVideoWrapper and other custom nodes."
version = "2.5.5"
version = "2.5.6"
license = {file = "LICENSE"}
[project.urls]
+35 -69
View File
@@ -17,12 +17,7 @@ logger = logging.getLogger("MultiGPU")
def _create_distorch_safetensor_v2_override(cls, device_param_name, device_setter_func, apply_device_kwarg_workaround, eject_models_default=True):
"""Internal factory function creating DisTorch2 override class with parameterized device selection behavior."""
from .distorch_2 import (
register_patched_safetensor_modelpatcher,
safetensor_allocation_store,
safetensor_settings_store,
create_safetensor_model_hash
)
from .distorch_2 import register_patched_safetensor_modelpatcher
from .model_management_mgpu import force_full_system_cleanup
class NodeOverrideDisTorchSafetensorV2(cls):
@@ -118,51 +113,10 @@ def _create_distorch_safetensor_v2_override(cls, device_param_name, device_sette
model_to_check = out[0].patcher
if model_to_check:
model_hash = create_safetensor_model_hash(model_to_check, "override_store")
settings_str = f"{device_value}{virtual_vram_gb}{donor_device}{expert_mode_allocations}"
settings_hash = hashlib.sha256(settings_str.encode()).hexdigest()
safetensor_allocation_store[model_hash] = full_allocation
safetensor_settings_store[model_hash] = settings_hash
logger.debug(f"[MultiGPU DisTorch V2] Stored allocation for model {model_hash[:8]}: {full_allocation}")
inner_model = model_to_check.model
inner_model._distorch_v2_meta = {"full_allocation": full_allocation}
logger.info(f"[MultiGPU DisTorch V2] Full allocation string: {full_allocation}")
logger.mgpu_mm_log(f"[MODEL_SETUP] Setting DisTorch model properties: virtual_vram_gb={virtual_vram_gb}")
if hasattr(out[0], 'model'):
mp = out[0]
mp_id = id(mp)
inner_model = getattr(mp, 'model', None)
inner_model_id = id(inner_model) if inner_model else None
inner_model_name = type(inner_model).__name__ if inner_model else "None"
inner_id_str = f"0x{inner_model_id:x}" if inner_model_id is not None else "None"
logger.mgpu_mm_log(f"[OBJECT_CHAIN_SET] ModelPatcher: mp_id=0x{mp_id:x}, inner_model_id={inner_id_str}, inner_model_type={inner_model_name}")
# SET VIRTUAL VRAM PROPERTY FOR MEMORY CALCULATION
if inner_model:
inner_model._mgpu_virtual_vram_gb = virtual_vram_gb
logger.mgpu_mm_log(f"[VIRTUAL_VRAM_SET] Set _mgpu_virtual_vram_gb={virtual_vram_gb}GB on inner model (id=0x{inner_model_id:x}) for memory assessment")
# SET EJECT MODELS PROPERTY IF ENABLED
if eject_models and inner_model:
inner_model._mgpu_eject_models = True
logger.mgpu_mm_log(f"[EJECT_FLAG_SET] Set _mgpu_eject_models=True on inner model (id=0x{inner_model_id:x}) - will trigger ejection during load_models_gpu")
elif hasattr(out[0], 'patcher') and hasattr(out[0].patcher, 'model'):
mp = out[0].patcher
mp_id = id(mp)
inner_model = getattr(mp, 'model', None)
inner_model_id = id(inner_model) if inner_model else None
inner_model_name = type(inner_model).__name__ if inner_model else "None"
inner_id_str = f"0x{inner_model_id:x}" if inner_model_id is not None else "None"
logger.mgpu_mm_log(f"[OBJECT_CHAIN_SET] ModelPatcher via patcher: mp_id=0x{mp_id:x}, inner_model_id={inner_id_str}, inner_model_type={inner_model_name}")
# SET VIRTUAL VRAM PROPERTY FOR MEMORY CALCULATION
if inner_model:
inner_model._mgpu_virtual_vram_gb = virtual_vram_gb
logger.mgpu_mm_log(f"[VIRTUAL_VRAM_SET] Set _mgpu_virtual_vram_gb={virtual_vram_gb}GB on inner model (id=0x{inner_model_id:x}) for memory assessment")
return out
@@ -211,7 +165,7 @@ def override_class_with_distorch_safetensor_v2_clip_no_device(cls):
def override_class_with_distorch_gguf(cls):
"""DisTorch V1 Legacy wrapper - maintains V1 UI but calls V2 backend"""
from . import set_current_device
from .distorch_2 import register_patched_safetensor_modelpatcher, safetensor_allocation_store, create_safetensor_model_hash
from .distorch_2 import register_patched_safetensor_modelpatcher
class NodeOverrideDisTorchGGUFLegacy(cls):
@classmethod
@@ -257,12 +211,15 @@ def override_class_with_distorch_gguf(cls):
fn = getattr(super(), cls.FUNCTION)
out = fn(*args, **clean_kwargs)
model_to_check = None
if hasattr(out[0], 'model'):
model_hash = create_safetensor_model_hash(out[0], "v1_compat")
safetensor_allocation_store[model_hash] = full_allocation
model_to_check = out[0]
elif hasattr(out[0], 'patcher') and hasattr(out[0].patcher, 'model'):
model_hash = create_safetensor_model_hash(out[0].patcher, "v1_compat")
safetensor_allocation_store[model_hash] = full_allocation
model_to_check = out[0].patcher
if model_to_check:
inner_model = model_to_check.model
inner_model._distorch_v2_meta = {"full_allocation": full_allocation}
return out
@@ -272,7 +229,7 @@ def override_class_with_distorch_gguf(cls):
def override_class_with_distorch_gguf_v2(cls):
"""DisTorch V2 wrapper for GGUF models"""
from . import set_current_device
from .distorch_2 import register_patched_safetensor_modelpatcher, safetensor_allocation_store, create_safetensor_model_hash
from .distorch_2 import register_patched_safetensor_modelpatcher
class NodeOverrideDisTorchGGUFv2(cls):
@classmethod
@@ -316,12 +273,15 @@ def override_class_with_distorch_gguf_v2(cls):
fn = getattr(super(), cls.FUNCTION)
out = fn(*args, **clean_kwargs)
model_to_check = None
if hasattr(out[0], 'model'):
model_hash = create_safetensor_model_hash(out[0], "v2_gguf")
safetensor_allocation_store[model_hash] = full_allocation
model_to_check = out[0]
elif hasattr(out[0], 'patcher') and hasattr(out[0].patcher, 'model'):
model_hash = create_safetensor_model_hash(out[0].patcher, "v2_gguf")
safetensor_allocation_store[model_hash] = full_allocation
model_to_check = out[0].patcher
if model_to_check:
inner_model = model_to_check.model
inner_model._distorch_v2_meta = {"full_allocation": full_allocation}
return out
@@ -331,7 +291,7 @@ def override_class_with_distorch_gguf_v2(cls):
def override_class_with_distorch_clip(cls):
"""DisTorch V1 wrapper for CLIP models - calls V2 backend"""
from . import set_current_text_encoder_device
from .distorch_2 import register_patched_safetensor_modelpatcher, safetensor_allocation_store, create_safetensor_model_hash
from .distorch_2 import register_patched_safetensor_modelpatcher
class NodeOverrideDisTorchClip(cls):
@classmethod
@@ -377,12 +337,15 @@ def override_class_with_distorch_clip(cls):
fn = getattr(super(), cls.FUNCTION)
out = fn(*args, **clean_kwargs)
model_to_check = None
if hasattr(out[0], 'model'):
model_hash = create_safetensor_model_hash(out[0], "v1_clip")
safetensor_allocation_store[model_hash] = full_allocation
model_to_check = out[0]
elif hasattr(out[0], 'patcher') and hasattr(out[0].patcher, 'model'):
model_hash = create_safetensor_model_hash(out[0].patcher, "v1_clip")
safetensor_allocation_store[model_hash] = full_allocation
model_to_check = out[0].patcher
if model_to_check:
inner_model = model_to_check.model
inner_model._distorch_v2_meta = {"full_allocation": full_allocation}
return out
@@ -392,7 +355,7 @@ def override_class_with_distorch_clip(cls):
def override_class_with_distorch_clip_no_device(cls):
"""DisTorch V1 wrapper for Triple/Quad CLIP models - calls V2 backend"""
from . import set_current_text_encoder_device
from .distorch_2 import register_patched_safetensor_modelpatcher, safetensor_allocation_store, create_safetensor_model_hash
from .distorch_2 import register_patched_safetensor_modelpatcher
class NodeOverrideDisTorchClipNoDevice(cls):
@classmethod
@@ -438,12 +401,15 @@ def override_class_with_distorch_clip_no_device(cls):
fn = getattr(super(), cls.FUNCTION)
out = fn(*args, **clean_kwargs)
model_to_check = None
if hasattr(out[0], 'model'):
model_hash = create_safetensor_model_hash(out[0], "v1_clip_nodev")
safetensor_allocation_store[model_hash] = full_allocation
model_to_check = out[0]
elif hasattr(out[0], 'patcher') and hasattr(out[0].patcher, 'model'):
model_hash = create_safetensor_model_hash(out[0].patcher, "v1_clip_nodev")
safetensor_allocation_store[model_hash] = full_allocation
model_to_check = out[0].patcher
if model_to_check:
inner_model = model_to_check.model
inner_model._distorch_v2_meta = {"full_allocation": full_allocation}
return out