From dcae850b96a34fa0cf6490e607c7a0bf7afe2b79 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Wed, 24 Dec 2025 17:07:59 +0200
Subject: [PATCH 01/22] Allow higher lora scale
---
nodes_model_loading.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nodes_model_loading.py b/nodes_model_loading.py
index e7c95e6..b8aa419 100644
--- a/nodes_model_loading.py
+++ b/nodes_model_loading.py
@@ -364,7 +364,7 @@ class WanVideoLoraSelect:
"required": {
"lora": (folder_paths.get_filename_list("loras"),
{"tooltip": "LORA models are expected to be in ComfyUI/models/loras with .safetensors extension"}),
- "strength": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.0001, "tooltip": "LORA strength, set to 0.0 to unmerge the LORA"}),
+ "strength": ("FLOAT", {"default": 1.0, "min": -1000.0, "max": 1000.0, "step": 0.0001, "tooltip": "LORA strength, set to 0.0 to unmerge the LORA"}),
},
"optional": {
"prev_lora":("WANVIDLORA", {"default": None, "tooltip": "For loading multiple LoRAs"}),
From c42bf94b07f67bb67eea724638ea9c3c7956c207 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Wed, 24 Dec 2025 17:58:30 +0200
Subject: [PATCH 02/22] Automatically adjust LoRA alpha for Peft rs_lora
weights
At least the original StoryMem -LoRAs need this
---
nodes_model_loading.py | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/nodes_model_loading.py b/nodes_model_loading.py
index b8aa419..f669f99 100644
--- a/nodes_model_loading.py
+++ b/nodes_model_loading.py
@@ -178,7 +178,7 @@ def standardize_lora_key_format(lora_sd):
new_key += f".{component}"
- # Handle weight type - this is the critical fix
+ # Handle weight type
if weight_type:
if weight_type == 'alpha':
new_key += '.alpha'
@@ -209,12 +209,12 @@ def standardize_lora_key_format(lora_sd):
new_key = new_key.replace('time_embedding', 'time.embedding')
new_key = new_key.replace('time_projection', 'time.projection')
- # Replace remaining underscores with dots, carefully
+ # Replace remaining underscores with dots
parts = new_key.split('.')
final_parts = []
for part in parts:
if part in ['img_emb', 'self_attn', 'cross_attn']:
- final_parts.append(part) # Keep these intact
+ final_parts.append(part)
else:
final_parts.append(part.replace('_', '.'))
new_key = '.'.join(final_parts)
@@ -274,6 +274,20 @@ def standardize_lora_key_format(lora_sd):
new_sd[k] = v
return new_sd
+def compensate_rs_lora_format(lora_sd):
+ rank = lora_sd["base_model.model.blocks.0.cross_attn.k.lora_A.weight"].shape[0]
+ alpha = torch.tensor(2 * 128 * rank ** 0.5)
+ log.info(f"Detected rank stabilized peft lora format with rank {rank}, setting alpha to {alpha} to compensate.")
+ new_sd = {}
+ for k, v in lora_sd.items():
+ if k.endswith(".lora_A.weight"):
+ new_sd[k] = v
+ new_k = k.replace(".lora_A.weight", ".alpha")
+ new_sd[new_k] = alpha
+ else:
+ new_sd[k] = v
+ return new_sd
+
class WanVideoBlockSwap:
@classmethod
def INPUT_TYPES(s):
@@ -756,6 +770,8 @@ class WanVideoSetLoRAs:
lora_sd = load_torch_file(lora_path, safe_load=True)
if "dwpose_embedding.0.weight" in lora_sd: #unianimate
raise NotImplementedError("Unianimate LoRA patching is not implemented in this node.")
+ if "base_model.model.blocks.0.cross_attn.k.lora_A.weight" in lora_sd: # assume rs_lora
+ lora_sd = compensate_rs_lora_format(lora_sd)
lora_sd = standardize_lora_key_format(lora_sd)
if l["blocks"]:
@@ -967,7 +983,8 @@ def add_lora_weights(patcher, lora, base_dtype, merge_loras=False):
from .unianimate.nodes import update_transformer
log.info("Unianimate LoRA detected, patching model...")
patcher.model.diffusion_model, unianimate_sd = update_transformer(patcher.model.diffusion_model, lora_sd)
-
+ if "base_model.model.blocks.0.cross_attn.k.lora_A.weight" in lora_sd: # assume rs_lora
+ lora_sd = compensate_rs_lora_format(lora_sd)
lora_sd = standardize_lora_key_format(lora_sd)
if l["blocks"]:
From 95255c7ffa29d90af6b0597b10d59a7946618b61 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Wed, 24 Dec 2025 18:44:05 +0200
Subject: [PATCH 03/22] Add node to add story memory latents
---
nodes.py | 23 +++++++++++++++++++++++
nodes_sampler.py | 18 ++++++++++++++----
2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/nodes.py b/nodes.py
index 0c78f44..8ca9031 100644
--- a/nodes.py
+++ b/nodes.py
@@ -888,6 +888,27 @@ class WanVideoAddMTVMotion:
updated["mtv_crafter_motion"] = new_entry
return (updated,)
+class WanVideoAddStoryMemLatents:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "embeds": ("WANVIDIMAGE_EMBEDS",),
+ "memory_latents": ("LATENT",),
+ }
+ }
+
+ RETURN_TYPES = ("WANVIDIMAGE_EMBEDS",)
+ RETURN_NAMES = ("image_embeds",)
+ FUNCTION = "add"
+ CATEGORY = "WanVideoWrapper"
+
+ def add(self, embeds, memory_latents):
+ updated = dict(embeds)
+ samples = memory_latents["samples"][0]
+ updated["story_mem_latents"] = samples
+
+ return (updated,)
+
#region I2V encode
class WanVideoImageToVideoEncode:
@classmethod
@@ -2255,6 +2276,7 @@ NODE_CLASS_MAPPINGS = {
"TextImageEncodeQwenVL": TextImageEncodeQwenVL,
"WanVideoUniLumosEmbeds": WanVideoUniLumosEmbeds,
"WanVideoAddTTMLatents": WanVideoAddTTMLatents,
+ "WanVideoAddStoryMemLatents": WanVideoAddStoryMemLatents,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -2296,4 +2318,5 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"WanVideoAddBindweaveEmbeds": "WanVideo Add Bindweave Embeds",
"WanVideoUniLumosEmbeds": "WanVideo UniLumos Embeds",
"WanVideoAddTTMLatents": "WanVideo Add TTMLatents",
+ "WanVideoAddStoryMemLatents": "WanVideo Add StoryMem Latents",
}
diff --git a/nodes_sampler.py b/nodes_sampler.py
index a1ec60f..40c16a8 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -301,14 +301,20 @@ class WanVideoSampler:
has_ref = image_embeds.get("has_ref", False)
#I2V
+ story_mem_latents = image_embeds.get("story_mem_latents", None)
image_cond = image_embeds.get("image_embeds", None)
if image_cond is not None:
if transformer.in_dim == 16:
raise ValueError("T2V (text to video) model detected, encoded images only work with I2V (Image to video) models")
elif transformer.in_dim not in [48, 32]: # fun 2.1 models don't use the mask
image_cond_mask = image_embeds.get("mask", None)
- if image_cond_mask is not None:
- image_cond = torch.cat([image_cond_mask, image_cond])
+ # StoryMem
+ if story_mem_latents is not None:
+ image_cond = torch.cat([story_mem_latents.to(image_cond), image_cond], dim=1)
+ image_cond_mask = torch.cat([torch.ones_like(story_mem_latents)[:4], image_cond_mask], dim=1) if image_cond_mask is not None else None
+
+ if image_cond_mask is not None:
+ image_cond = torch.cat([image_cond_mask, image_cond])
else:
image_cond[:, 1:] = 0
@@ -336,10 +342,12 @@ class WanVideoSampler:
end_image = image_embeds.get("end_image", None)
fun_or_fl2v_model = image_embeds.get("fun_or_fl2v_model", False)
-
+ latent_frames = (image_embeds["num_frames"] - 1) // 4
+ latent_frames = latent_frames + (2 if end_image is not None and not fun_or_fl2v_model else 1)
+ latent_frames = latent_frames + story_mem_latents.shape[1] if story_mem_latents is not None else latent_frames
noise = torch.randn( #C, T, H, W
48 if is_5b else 16,
- (image_embeds["num_frames"] - 1) // 4 + (2 if end_image is not None and not fun_or_fl2v_model else 1),
+ latent_frames,
image_embeds["lat_h"],
image_embeds["lat_w"],
dtype=torch.float32,
@@ -3248,6 +3256,8 @@ class WanVideoSampler:
latent = latent[:,:-humo_reference_count]
if longcat_ref_latent is not None:
latent = latent[:, longcat_ref_latent.shape[1]:]
+ if story_mem_latents is not None:
+ latent = latent[:, story_mem_latents.shape[1]:]
cache_states = None
if cache_args is not None:
From f988d19fdbc1582678255cce3ebb5bd40aa8014b Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Thu, 25 Dec 2025 20:44:37 +0200
Subject: [PATCH 04/22] StoryMem latents are supposed to be encoded one by one
---
nodes.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/nodes.py b/nodes.py
index 8ca9031..d754566 100644
--- a/nodes.py
+++ b/nodes.py
@@ -892,8 +892,9 @@ class WanVideoAddStoryMemLatents:
@classmethod
def INPUT_TYPES(s):
return {"required": {
+ "vae": ("WANVAE",),
"embeds": ("WANVIDIMAGE_EMBEDS",),
- "memory_latents": ("LATENT",),
+ "memory_images": ("IMAGE",),
}
}
@@ -902,11 +903,10 @@ class WanVideoAddStoryMemLatents:
FUNCTION = "add"
CATEGORY = "WanVideoWrapper"
- def add(self, embeds, memory_latents):
+ def add(self, vae, embeds, memory_images):
updated = dict(embeds)
- samples = memory_latents["samples"][0]
- updated["story_mem_latents"] = samples
-
+ story_mem_latents, = WanVideoEncodeLatentBatch().encode(vae, memory_images)
+ updated["story_mem_latents"] = story_mem_latents["samples"].squeeze(2).permute(1, 0, 2, 3) # [C, T, H, W]
return (updated,)
#region I2V encode
@@ -2143,7 +2143,7 @@ class WanVideoEncodeLatentBatch:
CATEGORY = "WanVideoWrapper"
DESCRIPTION = "Encodes a batch of images individually to create a latent video batch where each video is a single frame, useful for I2V init purposes, for example as multiple context window inits"
- def encode(self, vae, images, enable_vae_tiling, tile_x, tile_y, tile_stride_x, tile_stride_y, latent_strength=1.0):
+ def encode(self, vae, images, enable_vae_tiling=False, tile_x=272, tile_y=272, tile_stride_x=144, tile_stride_y=128, latent_strength=1.0):
vae.to(device)
images = images.clone()
From 264212dddbc0c2d3b28474d15035e0182f6524e4 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 01:27:48 +0200
Subject: [PATCH 05/22] Fix uncond variable name when using zero star or fresca
---
nodes_sampler.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/nodes_sampler.py b/nodes_sampler.py
index 40c16a8..1adcc22 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -1742,7 +1742,7 @@ class WanVideoSampler:
base_params['y'] = [image_cond_input] * 2 if image_cond_input is not None else None
base_params['clip_fea'] = torch.cat([clip_fea, clip_fea], dim=0)
cache_state_uncond = None
- [noise_pred_cond, noise_pred_uncond], _, cache_state_cond = transformer(
+ [noise_pred_cond, noise_pred_uncond_text], _, cache_state_cond = transformer(
context=positive_embeds + negative_embeds, is_uncond=False,
pred_id=cache_state[0] if cache_state else None,
**base_params
@@ -1759,7 +1759,7 @@ class WanVideoSampler:
if use_cfg_zero_star:
alpha = optimized_scale(
noise_pred_cond.view(batch_size, -1),
- noise_pred_uncond.view(batch_size, -1)
+ noise_pred_uncond_text.view(batch_size, -1)
).view(batch_size, 1, 1, 1)
noise_pred_uncond_text = noise_pred_uncond_text * alpha
@@ -1774,7 +1774,7 @@ class WanVideoSampler:
#https://github.com/WikiChao/FreSca
if use_fresca:
- filtered_cond = fourier_filter(noise_pred_cond - noise_pred_uncond, fresca_scale_low, fresca_scale_high, fresca_freq_cutoff)
+ filtered_cond = fourier_filter(noise_pred_cond - noise_pred_uncond_text, fresca_scale_low, fresca_scale_high, fresca_freq_cutoff)
noise_pred = noise_pred_uncond_text + cfg_scale * filtered_cond * alpha
else:
noise_pred = noise_pred_uncond_text + cfg_scale * (noise_pred_cond - noise_pred_uncond_text)
From 74f337e06cebb1c5ed8acbccac4e871cdf30d19e Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 01:41:32 +0200
Subject: [PATCH 06/22] Adjust StoryMem lora scaling
This was probably too high afterall
---
nodes_model_loading.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nodes_model_loading.py b/nodes_model_loading.py
index f669f99..1f9a1d8 100644
--- a/nodes_model_loading.py
+++ b/nodes_model_loading.py
@@ -276,7 +276,7 @@ def standardize_lora_key_format(lora_sd):
def compensate_rs_lora_format(lora_sd):
rank = lora_sd["base_model.model.blocks.0.cross_attn.k.lora_A.weight"].shape[0]
- alpha = torch.tensor(2 * 128 * rank ** 0.5)
+ alpha = torch.tensor(rank * rank // rank ** 0.5)
log.info(f"Detected rank stabilized peft lora format with rank {rank}, setting alpha to {alpha} to compensate.")
new_sd = {}
for k, v in lora_sd.items():
From 20942b8fd9bfb9eba5b6b454d72275300cd25f97 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 12:51:22 +0200
Subject: [PATCH 07/22] Cleanup: Remove flowedit code, restructure some other
code
Due to lack of use and code maintainability
---
multitalk/multitalk_loop.py | 483 +++++++++++++++++
nodes.py | 28 -
nodes_sampler.py | 891 ++++----------------------------
utils.py | 88 +++-
wanvideo/schedulers/__init__.py | 2 +-
5 files changed, 673 insertions(+), 819 deletions(-)
create mode 100644 multitalk/multitalk_loop.py
diff --git a/multitalk/multitalk_loop.py b/multitalk/multitalk_loop.py
new file mode 100644
index 0000000..ed8b0af
--- /dev/null
+++ b/multitalk/multitalk_loop.py
@@ -0,0 +1,483 @@
+import torch
+import os
+import gc
+from PIL import Image
+import numpy as np
+from ..latent_preview import prepare_callback
+from ..wanvideo.schedulers import get_scheduler
+from .multitalk import timestep_transform, add_noise
+from ..utils import log, print_memory, temporal_score_rescaling, offload_transformer, init_blockswap
+from comfy.utils import load_torch_file
+from ..nodes_model_loading import load_weights
+from ..HuMo.nodes import get_audio_emb_window
+import comfy.model_management as mm
+from tqdm import tqdm
+import copy
+
+VAE_STRIDE = (4, 8, 8)
+PATCH_SIZE = (1, 2, 2)
+vae_upscale_factor = 16
+script_directory = os.path.dirname(os.path.abspath(__file__))
+
+device = mm.get_torch_device()
+offload_device = mm.unet_offload_device()
+
+def multitalk_loop(self, **kwargs):
+ # Unpack kwargs into local variables
+ (latent, total_steps, steps, start_step, end_step, shift, cfg, denoise_strength,
+ sigmas, weight_dtype, transformer, patcher, block_swap_args, model, vae, dtype,
+ scheduler, scheduler_step_args, text_embeds, image_embeds, multitalk_embeds,
+ multitalk_audio_embeds, unianim_data, dwpose_data, unianimate_poses, uni3c_embeds,
+ humo_image_cond, humo_image_cond_neg, humo_audio, humo_reference_count,
+ add_noise_to_samples, audio_stride, use_tsr, tsr_k, tsr_sigma, fantasy_portrait_input,
+ noise, timesteps, force_offload, add_cond, control_latents, audio_proj,
+ control_camera_latents, samples, masks, seed_g, gguf_reader, predict_func
+ ) = (kwargs.get(k) for k in (
+ 'latent', 'total_steps', 'steps', 'start_step', 'end_step', 'shift', 'cfg',
+ 'denoise_strength', 'sigmas', 'weight_dtype', 'transformer', 'patcher',
+ 'block_swap_args', 'model', 'vae', 'dtype', 'scheduler', 'scheduler_step_args',
+ 'text_embeds', 'image_embeds', 'multitalk_embeds', 'multitalk_audio_embeds',
+ 'unianim_data', 'dwpose_data', 'unianimate_poses', 'uni3c_embeds',
+ 'humo_image_cond', 'humo_image_cond_neg', 'humo_audio', 'humo_reference_count',
+ 'add_noise_to_samples', 'audio_stride', 'use_tsr', 'tsr_k', 'tsr_sigma',
+ 'fantasy_portrait_input', 'noise', 'timesteps', 'force_offload', 'add_cond',
+ 'control_latents', 'audio_proj', 'control_camera_latents', 'samples', 'masks',
+ 'seed_g', 'gguf_reader', 'predict_with_cfg'
+ ))
+
+ mode = image_embeds.get("multitalk_mode", "multitalk")
+ if mode == "auto":
+ mode = transformer.multitalk_model_type.lower()
+ log.info(f"Multitalk mode: {mode}")
+ cond_frame = None
+ offload = image_embeds.get("force_offload", False)
+ offloaded = False
+ tiled_vae = image_embeds.get("tiled_vae", False)
+ frame_num = clip_length = image_embeds.get("frame_window_size", 81)
+
+ clip_embeds = image_embeds.get("clip_context", None)
+ if clip_embeds is not None:
+ clip_embeds = clip_embeds.to(dtype)
+ colormatch = image_embeds.get("colormatch", "disabled")
+ motion_frame = image_embeds.get("motion_frame", 25)
+ target_w = image_embeds.get("target_w", None)
+ target_h = image_embeds.get("target_h", None)
+ original_images = cond_image = image_embeds.get("multitalk_start_image", None)
+ if original_images is None:
+ original_images = torch.zeros([noise.shape[0], 1, target_h, target_w], device=device)
+
+ output_path = image_embeds.get("output_path", "")
+ img_counter = 0
+
+ if len(multitalk_embeds['audio_features'])==2 and (multitalk_embeds['ref_target_masks'] is None):
+ face_scale = 0.1
+ x_min, x_max = int(target_h * face_scale), int(target_h * (1 - face_scale))
+ lefty_min, lefty_max = int((target_w//2) * face_scale), int((target_w//2) * (1 - face_scale))
+ righty_min, righty_max = int((target_w//2) * face_scale + (target_w//2)), int((target_w//2) * (1 - face_scale) + (target_w//2))
+ human_mask1, human_mask2 = (torch.zeros([target_h, target_w]) for _ in range(2))
+ human_mask1[x_min:x_max, lefty_min:lefty_max] = 1
+ human_mask2[x_min:x_max, righty_min:righty_max] = 1
+ background_mask = torch.where((human_mask1 + human_mask2) > 0, torch.tensor(0), torch.tensor(1))
+ human_masks = [human_mask1, human_mask2, background_mask]
+ ref_target_masks = torch.stack(human_masks, dim=0)
+ multitalk_embeds['ref_target_masks'] = ref_target_masks
+
+ gen_video_list = []
+ is_first_clip = True
+ arrive_last_frame = False
+ cur_motion_frames_num = 1
+ audio_start_idx = iteration_count = step_iteration_count = 0
+ audio_end_idx = (audio_start_idx + clip_length) * audio_stride
+ indices = (torch.arange(4 + 1) - 2) * 1
+ current_condframe_index = 0
+
+ audio_embedding = multitalk_audio_embeds
+ human_num = len(audio_embedding)
+ audio_embs = None
+ cond_frame = None
+
+ uni3c_data = None
+ if uni3c_embeds is not None:
+ transformer.controlnet = uni3c_embeds["controlnet"]
+ uni3c_data = uni3c_embeds.copy()
+
+ encoded_silence = None
+
+ try:
+ silence_path = os.path.join(script_directory, "encoded_silence.safetensors")
+ encoded_silence = load_torch_file(silence_path)["audio_emb"].to(dtype)
+ except:
+ log.warning("No encoded silence file found, padding with end of audio embedding instead.")
+
+ total_frames = len(audio_embedding[0])
+ estimated_iterations = total_frames // (frame_num - motion_frame) + 1
+ callback = prepare_callback(patcher, estimated_iterations)
+
+ if frame_num >= total_frames:
+ arrive_last_frame = True
+ estimated_iterations = 1
+
+ log.info(f"Sampling {total_frames} frames in {estimated_iterations} windows, at {latent.shape[3]*vae_upscale_factor}x{latent.shape[2]*vae_upscale_factor} with {steps} steps")
+
+ while True: # start video generation iteratively
+ self.cache_state = [None, None]
+
+ cur_motion_frames_latent_num = int(1 + (cur_motion_frames_num-1) // 4)
+ if mode == "infinitetalk":
+ cond_image = original_images[:, :, current_condframe_index:current_condframe_index+1] if cond_image is not None else None
+ if multitalk_embeds is not None:
+ audio_embs = []
+ # split audio with window size
+ for human_idx in range(human_num):
+ center_indices = torch.arange(audio_start_idx, audio_end_idx, audio_stride).unsqueeze(1) + indices.unsqueeze(0)
+ center_indices = torch.clamp(center_indices, min=0, max=audio_embedding[human_idx].shape[0]-1)
+ audio_emb = audio_embedding[human_idx][center_indices].unsqueeze(0).to(device)
+ audio_embs.append(audio_emb)
+ audio_embs = torch.concat(audio_embs, dim=0).to(dtype)
+
+ h, w = (cond_image.shape[-2], cond_image.shape[-1]) if cond_image is not None else (target_h, target_w)
+ lat_h, lat_w = h // VAE_STRIDE[1], w // VAE_STRIDE[2]
+ latent_frame_num = (frame_num - 1) // 4 + 1
+
+ noise = torch.randn(
+ 16, latent_frame_num,
+ lat_h, lat_w, dtype=torch.float32, device=torch.device("cpu"), generator=seed_g).to(device)
+
+ # Calculate the correct latent slice based on current iteration
+ if is_first_clip:
+ latent_start_idx = 0
+ latent_end_idx = noise.shape[1]
+ else:
+ new_frames_per_iteration = frame_num - motion_frame
+ new_latent_frames_per_iteration = ((new_frames_per_iteration - 1) // 4 + 1)
+ latent_start_idx = iteration_count * new_latent_frames_per_iteration
+ latent_end_idx = latent_start_idx + noise.shape[1]
+
+ if samples is not None:
+ noise_mask = samples.get("noise_mask", None)
+ input_samples = samples["samples"]
+ if input_samples is not None:
+ input_samples = input_samples.squeeze(0).to(noise)
+ # Check if we have enough frames in input_samples
+ if latent_end_idx > input_samples.shape[1]:
+ # We need more frames than available - pad the input_samples at the end
+ pad_length = latent_end_idx - input_samples.shape[1]
+ last_frame = input_samples[:, -1:].repeat(1, pad_length, 1, 1)
+ input_samples = torch.cat([input_samples, last_frame], dim=1)
+ input_samples = input_samples[:, latent_start_idx:latent_end_idx]
+ if noise_mask is not None:
+ original_image = input_samples.to(device)
+
+ assert input_samples.shape[1] == noise.shape[1], f"Slice mismatch: {input_samples.shape[1]} vs {noise.shape[1]}"
+
+ if add_noise_to_samples:
+ latent_timestep = timesteps[0]
+ noise = noise * latent_timestep / 1000 + (1 - latent_timestep / 1000) * input_samples
+ else:
+ noise = input_samples
+
+ # diff diff prep
+ if noise_mask is not None:
+ if len(noise_mask.shape) == 4:
+ noise_mask = noise_mask.squeeze(1)
+ if audio_end_idx > noise_mask.shape[0]:
+ noise_mask = noise_mask.repeat(audio_end_idx // noise_mask.shape[0], 1, 1)
+ noise_mask = noise_mask[audio_start_idx:audio_end_idx]
+ noise_mask = torch.nn.functional.interpolate(
+ noise_mask.unsqueeze(0).unsqueeze(0), # Add batch and channel dims [1,1,T,H,W]
+ size=(noise.shape[1], noise.shape[2], noise.shape[3]),
+ mode='trilinear',
+ align_corners=False
+ ).repeat(1, noise.shape[0], 1, 1, 1)
+
+ thresholds = torch.arange(len(timesteps), dtype=original_image.dtype) / len(timesteps)
+ thresholds = thresholds.reshape(-1, 1, 1, 1, 1).to(device)
+ masks = (1-noise_mask.repeat(len(timesteps), 1, 1, 1, 1).to(device)) > thresholds
+
+ # zero padding and vae encode for img cond
+ if cond_image is not None or cond_frame is not None:
+ cond_ = cond_image if (is_first_clip or humo_image_cond is None) else cond_frame
+ cond_frame_num = cond_.shape[2]
+ video_frames = torch.zeros(1, 3, frame_num-cond_frame_num, target_h, target_w, device=device, dtype=vae.dtype)
+ padding_frames_pixels_values = torch.concat([cond_.to(device, vae.dtype), video_frames], dim=2)
+
+ # encode
+ vae.to(device)
+ y = vae.encode(padding_frames_pixels_values, device=device, tiled=tiled_vae, pbar=False).to(dtype)[0]
+
+ if mode == "multitalk":
+ latent_motion_frames = y[:, :cur_motion_frames_latent_num] # C T H W
+ else:
+ cond_ = cond_image if is_first_clip else cond_frame
+ latent_motion_frames = vae.encode(cond_.to(device, vae.dtype), device=device, tiled=tiled_vae, pbar=False).to(dtype)[0]
+
+ vae.to(offload_device)
+
+ #motion_frame_index = cur_motion_frames_latent_num if mode == "infinitetalk" else 1
+ msk = torch.zeros(4, latent_frame_num, lat_h, lat_w, device=device, dtype=dtype)
+ msk[:, :1] = 1
+ y = torch.cat([msk, y]) # 4+C T H W
+ mm.soft_empty_cache()
+ else:
+ y = None
+ latent_motion_frames = noise[:, :1]
+
+ partial_humo_cond_input = partial_humo_cond_neg_input = partial_humo_audio = partial_humo_audio_neg = None
+ if humo_image_cond is not None:
+ partial_humo_cond_input = humo_image_cond[:, :latent_frame_num]
+ partial_humo_cond_neg_input = humo_image_cond_neg[:, :latent_frame_num]
+ if y is not None:
+ partial_humo_cond_input[:, :1] = y[:, :1]
+ if humo_reference_count > 0:
+ partial_humo_cond_input[:, -humo_reference_count:] = humo_image_cond[:, -humo_reference_count:]
+ partial_humo_cond_neg_input[:, -humo_reference_count:] = humo_image_cond_neg[:, -humo_reference_count:]
+
+ if humo_audio is not None:
+ if is_first_clip:
+ audio_embs = None
+
+ partial_humo_audio, _ = get_audio_emb_window(humo_audio, frame_num, frame0_idx=audio_start_idx)
+ #zero_audio_pad = torch.zeros(humo_reference_count, *partial_humo_audio.shape[1:], device=partial_humo_audio.device, dtype=partial_humo_audio.dtype)
+ partial_humo_audio[-humo_reference_count:] = 0
+ partial_humo_audio_neg = torch.zeros_like(partial_humo_audio, device=partial_humo_audio.device, dtype=partial_humo_audio.dtype)
+
+ if scheduler == "multitalk":
+ timesteps = list(np.linspace(1000, 1, steps, dtype=np.float32))
+ timesteps.append(0.)
+ timesteps = [torch.tensor([t], device=device) for t in timesteps]
+ timesteps = [timestep_transform(t, shift=shift, num_timesteps=1000) for t in timesteps]
+ else:
+ if isinstance(scheduler, dict):
+ sample_scheduler = copy.deepcopy(scheduler["sample_scheduler"])
+ timesteps = scheduler["timesteps"]
+ else:
+ sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, total_steps, start_step, end_step, shift, device, transformer.dim, denoise_strength, sigmas=sigmas)
+ timesteps = [torch.tensor([float(t)], device=device) for t in timesteps] + [torch.tensor([0.], device=device)]
+
+ # sample videos
+ latent = noise
+
+ # injecting motion frames
+ if not is_first_clip and mode == "multitalk":
+ latent_motion_frames = latent_motion_frames.to(latent.dtype).to(device)
+ motion_add_noise = torch.randn(latent_motion_frames.shape, device=torch.device("cpu"), generator=seed_g).to(device).contiguous()
+ add_latent = add_noise(latent_motion_frames, motion_add_noise, timesteps[0])
+ latent[:, :add_latent.shape[1]] = add_latent
+
+ if offloaded:
+ # Load weights
+ if transformer.patched_linear and gguf_reader is None:
+ load_weights(patcher.model.diffusion_model, patcher.model["sd"], weight_dtype, base_dtype=dtype, transformer_load_device=device, block_swap_args=block_swap_args)
+ elif gguf_reader is not None: #handle GGUF
+ load_weights(transformer, patcher.model["sd"], base_dtype=dtype, transformer_load_device=device, patcher=patcher, gguf=True, reader=gguf_reader, block_swap_args=block_swap_args)
+ #blockswap init
+ init_blockswap(transformer, block_swap_args, model)
+
+ # Use the appropriate prompt for this section
+ if len(text_embeds["prompt_embeds"]) > 1:
+ prompt_index = min(iteration_count, len(text_embeds["prompt_embeds"]) - 1)
+ positive = [text_embeds["prompt_embeds"][prompt_index]]
+ log.info(f"Using prompt index: {prompt_index}")
+ else:
+ positive = text_embeds["prompt_embeds"]
+
+ # uni3c slices
+ if uni3c_embeds is not None:
+ vae.to(device)
+ # Pad original_images if needed
+ num_frames = original_images.shape[2]
+ if audio_end_idx > num_frames:
+ pad_len = audio_end_idx - num_frames
+ last_frame = original_images[:, :, -1:].repeat(1, 1, pad_len, 1, 1)
+ padded_images = torch.cat([original_images, last_frame], dim=2)
+ else:
+ padded_images = original_images
+ render_latent = vae.encode(
+ padded_images[:, :, audio_start_idx:audio_end_idx].to(device, vae.dtype),
+ device=device, tiled=tiled_vae
+ ).to(dtype)
+
+ vae.to(offload_device)
+ uni3c_data['render_latent'] = render_latent
+
+ # unianimate slices
+ partial_unianim_data = None
+ if unianim_data is not None:
+ partial_dwpose = dwpose_data[:, :, latent_start_idx:latent_end_idx]
+ partial_unianim_data = {
+ "dwpose": partial_dwpose,
+ "random_ref": unianim_data["random_ref"],
+ "strength": unianimate_poses["strength"],
+ "start_percent": unianimate_poses["start_percent"],
+ "end_percent": unianimate_poses["end_percent"]
+ }
+
+ # fantasy portrait slices
+ partial_fantasy_portrait_input = None
+ if fantasy_portrait_input is not None:
+ adapter_proj = fantasy_portrait_input["adapter_proj"]
+ if latent_end_idx > adapter_proj.shape[1]:
+ pad_len = latent_end_idx - adapter_proj.shape[1]
+ last_frame = adapter_proj[:, -1:, :, :].repeat(1, pad_len, 1, 1)
+ padded_proj = torch.cat([adapter_proj, last_frame], dim=1)
+ else:
+ padded_proj = adapter_proj
+ partial_fantasy_portrait_input = fantasy_portrait_input.copy()
+ partial_fantasy_portrait_input["adapter_proj"] = padded_proj[:, latent_start_idx:latent_end_idx]
+
+ mm.soft_empty_cache()
+ gc.collect()
+ # sampling loop
+ sampling_pbar = tqdm(total=len(timesteps)-1, desc=f"Sampling audio indices {audio_start_idx}-{audio_end_idx}", position=0, leave=True)
+ for i in range(len(timesteps)-1):
+ timestep = timesteps[i]
+ latent_model_input = latent.to(device)
+ if mode == "infinitetalk":
+ if humo_image_cond is None or not is_first_clip:
+ latent_model_input[:, :cur_motion_frames_latent_num] = latent_motion_frames
+
+ noise_pred, _, self.cache_state = predict_func(
+ latent_model_input, cfg[min(i, len(timesteps)-1)], positive, text_embeds["negative_prompt_embeds"],
+ timestep, i, y, clip_embeds, control_latents, None, partial_unianim_data, audio_proj, control_camera_latents, add_cond,
+ cache_state=self.cache_state, multitalk_audio_embeds=audio_embs, fantasy_portrait_input=partial_fantasy_portrait_input,
+ humo_image_cond=partial_humo_cond_input, humo_image_cond_neg=partial_humo_cond_neg_input, humo_audio=partial_humo_audio, humo_audio_neg=partial_humo_audio_neg,
+ uni3c_data = uni3c_data)
+
+ if callback is not None:
+ callback_latent = (latent_model_input.to(device) - noise_pred.to(device) * timestep.to(device) / 1000).detach().permute(1,0,2,3)
+ callback(step_iteration_count, callback_latent, None, estimated_iterations*(len(timesteps)-1))
+ del callback_latent
+
+ sampling_pbar.update(1)
+ step_iteration_count += 1
+
+ # update latent
+ if use_tsr:
+ noise_pred = temporal_score_rescaling(noise_pred, latent, timestep, tsr_k, tsr_sigma)
+ if scheduler == "multitalk":
+ noise_pred = -noise_pred
+ dt = (timesteps[i] - timesteps[i + 1]) / 1000
+ latent = latent + noise_pred * dt[:, None, None, None]
+ else:
+ latent = sample_scheduler.step(noise_pred.unsqueeze(0), timestep, latent.unsqueeze(0).to(noise_pred.device), **scheduler_step_args)[0].squeeze(0)
+ del noise_pred, latent_model_input, timestep
+
+ # differential diffusion inpaint
+ if masks is not None:
+ if i < len(timesteps) - 1:
+ image_latent = add_noise(original_image.to(device), noise.to(device), timesteps[i+1])
+ mask = masks[i].to(latent)
+ latent = image_latent * mask + latent * (1-mask)
+
+ # injecting motion frames
+ if not is_first_clip and mode == "multitalk":
+ latent_motion_frames = latent_motion_frames.to(latent.dtype).to(device)
+ motion_add_noise = torch.randn(latent_motion_frames.shape, device=torch.device("cpu"), generator=seed_g).to(device).contiguous()
+ add_latent = add_noise(latent_motion_frames, motion_add_noise, timesteps[i+1])
+ latent[:, :add_latent.shape[1]] = add_latent
+ else:
+ if humo_image_cond is None or not is_first_clip:
+ latent[:, :cur_motion_frames_latent_num] = latent_motion_frames
+
+ del noise, latent_motion_frames
+ if offload:
+ offload_transformer(transformer, remove_lora=False)
+ offloaded = True
+ if humo_image_cond is not None and humo_reference_count > 0:
+ latent = latent[:,:-humo_reference_count]
+ vae.to(device)
+ videos = vae.decode(latent.unsqueeze(0).to(device, vae.dtype), device=device, tiled=tiled_vae, pbar=False)[0].cpu()
+
+ vae.to(offload_device)
+
+ sampling_pbar.close()
+
+ # optional color correction (less relevant for InfiniteTalk)
+ if colormatch != "disabled":
+ videos = videos.permute(1, 2, 3, 0).float().numpy()
+ from color_matcher import ColorMatcher
+ cm = ColorMatcher()
+ cm_result_list = []
+ for img in videos:
+ if mode == "multitalk":
+ cm_result = cm.transfer(src=img, ref=original_images[0].permute(1, 2, 3, 0).squeeze(0).cpu().float().numpy(), method=colormatch)
+ else:
+ cm_result = cm.transfer(src=img, ref=cond_image[0].permute(1, 2, 3, 0).squeeze(0).cpu().float().numpy(), method=colormatch)
+ cm_result_list.append(torch.from_numpy(cm_result).to(vae.dtype))
+
+ videos = torch.stack(cm_result_list, dim=0).permute(3, 0, 1, 2)
+
+ # optionally save generated samples to disk
+ if output_path:
+ video_np = videos.clamp(-1.0, 1.0).add(1.0).div(2.0).mul(255).cpu().float().numpy().transpose(1, 2, 3, 0).astype('uint8')
+ num_frames_to_save = video_np.shape[0] if is_first_clip else video_np.shape[0] - cur_motion_frames_num
+ log.info(f"Saving {num_frames_to_save} generated frames to {output_path}")
+ start_idx = 0 if is_first_clip else cur_motion_frames_num
+ for i in range(start_idx, video_np.shape[0]):
+ im = Image.fromarray(video_np[i])
+ im.save(os.path.join(output_path, f"frame_{img_counter:05d}.png"))
+ img_counter += 1
+ else:
+ gen_video_list.append(videos if is_first_clip else videos[:, cur_motion_frames_num:])
+
+ current_condframe_index += 1
+ iteration_count += 1
+
+ # decide whether is done
+ if arrive_last_frame:
+ break
+
+ # update next condition frames
+ is_first_clip = False
+ cur_motion_frames_num = motion_frame
+
+ cond_ = videos[:, -cur_motion_frames_num:].unsqueeze(0)
+ if mode == "infinitetalk":
+ cond_frame = cond_
+ else:
+ cond_image = cond_
+
+ del videos, latent
+
+ # Repeat audio emb
+ if multitalk_embeds is not None:
+ audio_start_idx += (frame_num - cur_motion_frames_num - humo_reference_count)
+ audio_end_idx = audio_start_idx + clip_length
+ if audio_end_idx >= len(audio_embedding[0]):
+ arrive_last_frame = True
+ miss_lengths = []
+ source_frames = []
+ for human_inx in range(human_num):
+ source_frame = len(audio_embedding[human_inx])
+ source_frames.append(source_frame)
+ if audio_end_idx >= len(audio_embedding[human_inx]):
+ log.warning(f"Audio embedding for subject {human_inx} not long enough: {len(audio_embedding[human_inx])}, need {audio_end_idx}, padding...")
+ miss_length = audio_end_idx - len(audio_embedding[human_inx]) + 3
+ log.warning(f"Padding length: {miss_length}")
+ if encoded_silence is not None:
+ add_audio_emb = encoded_silence[-1*miss_length:]
+ else:
+ add_audio_emb = torch.flip(audio_embedding[human_inx][-1*miss_length:], dims=[0])
+ audio_embedding[human_inx] = torch.cat([audio_embedding[human_inx], add_audio_emb.to(device, dtype)], dim=0)
+ miss_lengths.append(miss_length)
+ else:
+ miss_lengths.append(0)
+ if mode == "infinitetalk" and current_condframe_index >= original_images.shape[2]:
+ last_frame = original_images[:, :, -1:, :, :]
+ miss_length = 1
+ original_images = torch.cat([original_images, last_frame.repeat(1, 1, miss_length, 1, 1)], dim=2)
+
+ if not output_path:
+ gen_video_samples = torch.cat(gen_video_list, dim=1)
+ else:
+ gen_video_samples = torch.zeros(3, 1, 64, 64) # dummy output
+
+ if force_offload:
+ if not model["auto_cpu_offload"]:
+ offload_transformer(transformer)
+ try:
+ print_memory(device)
+ torch.cuda.reset_peak_memory_stats(device)
+ except:
+ pass
+ return {"video": gen_video_samples.permute(1, 2, 3, 0), "output_path": output_path},
diff --git a/nodes.py b/nodes.py
index d754566..67f5142 100644
--- a/nodes.py
+++ b/nodes.py
@@ -1847,33 +1847,7 @@ class WanVideoContextOptions:
}
return (context_options,)
-
-
-class WanVideoFlowEdit:
- @classmethod
- def INPUT_TYPES(s):
- return {"required": {
- "source_embeds": ("WANVIDEOTEXTEMBEDS", ),
- "skip_steps": ("INT", {"default": 4, "min": 0}),
- "drift_steps": ("INT", {"default": 0, "min": 0}),
- "drift_flow_shift": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 30.0, "step": 0.01}),
- "source_cfg": ("FLOAT", {"default": 6.0, "min": 0.0, "max": 30.0, "step": 0.01}),
- "drift_cfg": ("FLOAT", {"default": 6.0, "min": 0.0, "max": 30.0, "step": 0.01}),
- },
- "optional": {
- "source_image_embeds": ("WANVIDIMAGE_EMBEDS", ),
- }
- }
- RETURN_TYPES = ("FLOWEDITARGS", )
- RETURN_NAMES = ("flowedit_args",)
- FUNCTION = "process"
- CATEGORY = "WanVideoWrapper"
- DESCRIPTION = "Flowedit options for WanVideo"
-
- def process(self, **kwargs):
- return (kwargs,)
-
class WanVideoLoopArgs:
@classmethod
def INPUT_TYPES(s):
@@ -2249,7 +2223,6 @@ NODE_CLASS_MAPPINGS = {
"WanVideoEnhanceAVideo": WanVideoEnhanceAVideo,
"WanVideoContextOptions": WanVideoContextOptions,
"WanVideoTextEmbedBridge": WanVideoTextEmbedBridge,
- "WanVideoFlowEdit": WanVideoFlowEdit,
"WanVideoControlEmbeds": WanVideoControlEmbeds,
"WanVideoSLG": WanVideoSLG,
"WanVideoLoopArgs": WanVideoLoopArgs,
@@ -2292,7 +2265,6 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"WanVideoEnhanceAVideo": "WanVideo Enhance-A-Video",
"WanVideoContextOptions": "WanVideo Context Options",
"WanVideoTextEmbedBridge": "WanVideo TextEmbed Bridge",
- "WanVideoFlowEdit": "WanVideo FlowEdit",
"WanVideoControlEmbeds": "WanVideo Control Embeds",
"WanVideoSLG": "WanVideo SLG",
"WanVideoLoopArgs": "WanVideo Loop Args",
diff --git a/nodes_sampler.py b/nodes_sampler.py
index 1adcc22..e1216a9 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -3,16 +3,14 @@ import torch
import numpy as np
from tqdm import tqdm
import inspect
-from PIL import Image
-from diffusers.schedulers import FlowMatchEulerDiscreteScheduler
-from .wanvideo.schedulers.fm_solvers import get_sampling_sigmas, retrieve_timesteps
from .wanvideo.modules.model import rope_params
from .custom_linear import remove_lora_from_module, set_lora_params, _replace_linear
from .wanvideo.schedulers import get_scheduler, scheduler_list
from .gguf.gguf import set_lora_params_gguf
-from .multitalk.multitalk import timestep_transform, add_noise
+from .multitalk.multitalk import add_noise
from .utils import(log, print_memory, apply_lora, fourier_filter, optimized_scale, setup_radial_attention,
- compile_model, dict_to_device, tangential_projection, get_raag_guidance, temporal_score_rescaling)
+ compile_model, dict_to_device, tangential_projection, get_raag_guidance, temporal_score_rescaling, offload_transformer, init_blockswap)
+from .multitalk.multitalk_loop import multitalk_loop
from .cache_methods.cache_methods import cache_report
from .nodes_model_loading import load_weights
from .enhance_a_video.globals import set_enhance_weight, set_num_frames
@@ -20,7 +18,7 @@ from .WanMove.trajectory import replace_feature
from contextlib import nullcontext
from comfy import model_management as mm
-from comfy.utils import ProgressBar, load_torch_file
+from comfy.utils import ProgressBar
from comfy.cli_args import args, LatentPreviewMethod
script_directory = os.path.dirname(os.path.abspath(__file__))
@@ -33,82 +31,6 @@ rope_functions = ["default", "comfy", "comfy_chunked"]
VAE_STRIDE = (4, 8, 8)
PATCH_SIZE = (1, 2, 2)
-try:
- from .gguf.gguf import GGUFParameter
-except:
- pass
-
-class MetaParameter(torch.nn.Parameter):
- def __new__(cls, dtype, quant_type=None):
- data = torch.empty(0, dtype=dtype)
- self = torch.nn.Parameter(data, requires_grad=False)
- self.quant_type = quant_type
- return self
-
-def offload_transformer(transformer, remove_lora=True):
- transformer.teacache_state.clear_all()
- transformer.magcache_state.clear_all()
- transformer.easycache_state.clear_all()
-
- if transformer.patched_linear:
- for name, param in transformer.named_parameters():
- if "loras" in name or "controlnet" in name:
- continue
- module = transformer
- subnames = name.split('.')
- for subname in subnames[:-1]:
- module = getattr(module, subname)
- attr_name = subnames[-1]
- if param.data.is_floating_point():
- meta_param = torch.nn.Parameter(torch.empty_like(param.data, device='meta'), requires_grad=False)
- setattr(module, attr_name, meta_param)
- elif isinstance(param.data, GGUFParameter):
- quant_type = getattr(param, 'quant_type', None)
- setattr(module, attr_name, MetaParameter(param.data.dtype, quant_type))
- else:
- pass
- if remove_lora:
- remove_lora_from_module(transformer)
- else:
- transformer.to(offload_device)
-
- for block in transformer.blocks:
- block.kv_cache = None
- if transformer.audio_model is not None and hasattr(block, 'audio_block'):
- block.audio_block = None
-
- mm.soft_empty_cache()
- gc.collect()
-
-
-def init_blockswap(transformer, block_swap_args, model):
- if not transformer.patched_linear:
- if block_swap_args is not None:
- for name, param in transformer.named_parameters():
- if "block" not in name or "control_adapter" in name or "face" in name:
- param.data = param.data.to(device)
- elif block_swap_args["offload_txt_emb"] and "txt_emb" in name:
- param.data = param.data.to(offload_device)
- elif block_swap_args["offload_img_emb"] and "img_emb" in name:
- param.data = param.data.to(offload_device)
-
- transformer.block_swap(
- block_swap_args["blocks_to_swap"] - 1 ,
- block_swap_args["offload_txt_emb"],
- block_swap_args["offload_img_emb"],
- vace_blocks_to_swap = block_swap_args.get("vace_blocks_to_swap", None),
- )
- elif model["auto_cpu_offload"]:
- for module in transformer.modules():
- if hasattr(module, "offload"):
- module.offload()
- if hasattr(module, "onload"):
- module.onload()
- for block in transformer.blocks:
- block.modulation = torch.nn.Parameter(block.modulation.to(device))
- transformer.head.modulation = torch.nn.Parameter(transformer.head.modulation.to(device))
- else:
- transformer.to(device)
class WanVideoSampler:
@classmethod
@@ -132,7 +54,7 @@ class WanVideoSampler:
"feta_args": ("FETAARGS", ),
"context_options": ("WANVIDCONTEXT", ),
"cache_args": ("CACHEARGS", ),
- "flowedit_args": ("FLOWEDITARGS", ),
+ "flowedit_args": ("FLOWEDITARGS", {"tooltip": "FlowEdit support has been deprecated"}),
"batched_cfg": ("BOOLEAN", {"default": False, "tooltip": "Batch cond and uncond for faster sampling, possibly faster on some hardware, uses more memory"}),
"slg_args": ("SLGARGS", ),
"rope_function": (rope_functions, {"default": "comfy", "tooltip": "Comfy's RoPE implementation doesn't use complex numbers and can thus be compiled, that should be a lot faster when using torch.compile. Chunked version has reduced peak VRAM usage when not using torch.compile"}),
@@ -159,7 +81,8 @@ class WanVideoSampler:
force_offload=True, samples=None, feta_args=None, denoise_strength=1.0, context_options=None,
cache_args=None, teacache_args=None, flowedit_args=None, batched_cfg=False, slg_args=None, rope_function="default", loop_args=None,
experimental_args=None, sigmas=None, unianimate_poses=None, fantasytalking_embeds=None, uni3c_embeds=None, multitalk_embeds=None, freeinit_args=None, start_step=0, end_step=-1, add_noise_to_samples=False):
-
+ if flowedit_args is not None:
+ raise Exception("FlowEdit support has been deprecated and removed due to lack of use and code maintainability")
patcher = model
model = model.model
transformer = model.diffusion_model
@@ -253,7 +176,7 @@ class WanVideoSampler:
timesteps = scheduler["timesteps"]
start_step = scheduler.get("start_step", start_step)
elif scheduler != "multitalk":
- sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, steps, start_step, end_step, shift, device, transformer.dim, flowedit_args, denoise_strength, sigmas=sigmas, log_timesteps=True)
+ sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, steps, start_step, end_step, shift, device, transformer.dim, denoise_strength, sigmas=sigmas, log_timesteps=True)
log.info(f"sigmas: {sample_scheduler.sigmas}")
else:
timesteps = torch.tensor([1000, 750, 500, 250], device=device)
@@ -994,43 +917,6 @@ class WanVideoSampler:
if transformer.attention_mode == "radial_sage_attention":
setup_radial_attention(transformer, transformer_options, latent, seq_len, latent_video_length, context_options=context_options)
- # FlowEdit setup
- if flowedit_args is not None:
- source_embeds = flowedit_args["source_embeds"]
- source_embeds = dict_to_device(source_embeds, device)
- source_image_embeds = flowedit_args.get("source_image_embeds", image_embeds)
- source_image_cond = source_image_embeds.get("image_embeds", None)
- source_clip_fea = source_image_embeds.get("clip_fea", clip_fea)
- if source_image_cond is not None:
- source_image_cond = source_image_cond.to(dtype)
- skip_steps = flowedit_args["skip_steps"]
- drift_steps = flowedit_args["drift_steps"]
- source_cfg = flowedit_args["source_cfg"]
- if not isinstance(source_cfg, list):
- source_cfg = [source_cfg] * (steps +1)
- drift_cfg = flowedit_args["drift_cfg"]
- if not isinstance(drift_cfg, list):
- drift_cfg = [drift_cfg] * (steps +1)
-
- x_init = samples["samples"].clone().squeeze(0).to(device)
- x_tgt = samples["samples"].squeeze(0).to(device)
-
- sample_scheduler = FlowMatchEulerDiscreteScheduler(
- num_train_timesteps=1000,
- shift=flowedit_args["drift_flow_shift"],
- use_dynamic_shifting=False)
-
- sampling_sigmas = get_sampling_sigmas(steps, flowedit_args["drift_flow_shift"])
-
- drift_timesteps, _ = retrieve_timesteps(
- sample_scheduler,
- device=device,
- sigmas=sampling_sigmas)
-
- if drift_steps > 0:
- drift_timesteps = torch.cat([drift_timesteps, torch.tensor([0]).to(drift_timesteps.device)]).to(drift_timesteps.device)
- timesteps[-drift_steps:] = drift_timesteps[-drift_steps:]
-
# Experimental args
use_cfg_zero_star = use_tangential = use_fresca = bidirectional_sampling = use_tsr = False
raag_alpha = 0.0
@@ -1834,7 +1720,7 @@ class WanVideoSampler:
# FreeInit noise reinitialization (after first iteration)
if freeinit_args is not None and iter_idx > 0:
# restart scheduler for each iteration
- sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, steps, start_step, end_step, shift, device, transformer.dim, flowedit_args, denoise_strength, sigmas=sigmas)
+ sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, steps, start_step, end_step, shift, device, transformer.dim, denoise_strength, sigmas=sigmas)
# Re-apply start_step and end_step logic to timesteps and sigmas
if end_step != -1:
@@ -1884,9 +1770,6 @@ class WanVideoSampler:
pbar = ProgressBar(len(timesteps) - ttm_start_step)
#region main loop start
for idx, t in enumerate(tqdm(timesteps[ttm_start_step:], disable=multitalk_sampling or wananimate_loop)):
- if flowedit_args is not None:
- if idx < skip_steps:
- continue
if bidirectional_sampling:
latent_flipped = torch.flip(latent, dims=[1])
@@ -1941,129 +1824,6 @@ class WanVideoSampler:
enhance_enabled = False
if feta_args is not None and feta_start_percent <= current_step_percentage <= feta_end_percent:
enhance_enabled = True
-
- #flow-edit
- if flowedit_args is not None:
- sigma = t / 1000.0
- sigma_prev = (timesteps[idx + 1] if idx < len(timesteps) - 1 else timesteps[-1]) / 1000.0
- noise = torch.randn(x_init.shape, generator=seed_g, device=torch.device("cpu"))
- if idx < len(timesteps) - drift_steps:
- cfg = drift_cfg
-
- zt_src = (1-sigma) * x_init + sigma * noise.to(t)
- zt_tgt = x_tgt + zt_src - x_init
-
- #source
- if idx < len(timesteps) - drift_steps:
- if context_options is not None:
- counter = torch.zeros_like(zt_src, device=intermediate_device)
- vt_src = torch.zeros_like(zt_src, device=intermediate_device)
- context_queue = list(context(idx, steps, latent_video_length, context_frames, context_stride, context_overlap))
- for c in context_queue:
- window_id = self.window_tracker.get_window_id(c)
-
- if cache_args is not None:
- current_teacache = self.window_tracker.get_teacache(window_id, self.cache_state)
- else:
- current_teacache = None
-
- prompt_index = min(int(max(c) / section_size), num_prompts - 1)
- if context_options["verbose"]:
- log.info(f"Prompt index: {prompt_index}")
-
- if len(source_embeds["prompt_embeds"]) > 1:
- positive = source_embeds["prompt_embeds"][prompt_index]
- else:
- positive = source_embeds["prompt_embeds"]
-
- partial_img_emb = None
- if source_image_cond is not None:
- partial_img_emb = source_image_cond[:, c, :, :]
- partial_img_emb[:, 0, :, :] = source_image_cond[:, 0, :, :].to(intermediate_device)
-
- partial_zt_src = zt_src[:, c, :, :]
- vt_src_context, _, new_teacache = predict_with_cfg(
- partial_zt_src, cfg[idx],
- positive, source_embeds["negative_prompt_embeds"],
- timestep, idx, partial_img_emb, control_latents,
- source_clip_fea, current_teacache)
-
- if cache_args is not None:
- self.window_tracker.cache_states[window_id] = new_teacache
-
- window_mask = create_window_mask(vt_src_context, c, latent_video_length, context_overlap)
- vt_src[:, c, :, :] += vt_src_context * window_mask
- counter[:, c, :, :] += window_mask
- vt_src /= counter
- else:
- vt_src, _, self.cache_state_source = predict_with_cfg(
- zt_src, cfg[idx],
- source_embeds["prompt_embeds"],
- source_embeds["negative_prompt_embeds"],
- timestep, idx, source_image_cond,
- source_clip_fea, control_latents,
- cache_state=self.cache_state_source)
- else:
- if idx == len(timesteps) - drift_steps:
- x_tgt = zt_tgt
- zt_tgt = x_tgt
- vt_src = 0
- #target
- if context_options is not None:
- counter = torch.zeros_like(zt_tgt, device=intermediate_device)
- vt_tgt = torch.zeros_like(zt_tgt, device=intermediate_device)
- context_queue = list(context(idx, steps, latent_video_length, context_frames, context_stride, context_overlap))
- for c in context_queue:
- window_id = self.window_tracker.get_window_id(c)
-
- if cache_args is not None:
- current_teacache = self.window_tracker.get_teacache(window_id, self.cache_state)
- else:
- current_teacache = None
-
- prompt_index = min(int(max(c) / section_size), num_prompts - 1)
- if context_options["verbose"]:
- log.info(f"Prompt index: {prompt_index}")
-
- if len(text_embeds["prompt_embeds"]) > 1:
- positive = text_embeds["prompt_embeds"][prompt_index]
- else:
- positive = text_embeds["prompt_embeds"]
-
- partial_img_emb = None
- partial_control_latents = None
- if image_cond is not None:
- partial_img_emb = image_cond[:, c, :, :]
- partial_img_emb[:, 0, :, :] = image_cond[:, 0, :, :].to(intermediate_device)
- if control_latents is not None:
- partial_control_latents = control_latents[:, c, :, :]
-
- partial_zt_tgt = zt_tgt[:, c, :, :]
- vt_tgt_context, _, new_teacache = predict_with_cfg(
- partial_zt_tgt, cfg[idx],
- positive, text_embeds["negative_prompt_embeds"],
- timestep, idx, partial_img_emb, partial_control_latents,
- clip_fea, current_teacache)
-
- if cache_args is not None:
- self.window_tracker.cache_states[window_id] = new_teacache
-
- window_mask = create_window_mask(vt_tgt_context, c, latent_video_length, context_overlap)
- vt_tgt[:, c, :, :] += vt_tgt_context * window_mask
- counter[:, c, :, :] += window_mask
- vt_tgt /= counter
- else:
- vt_tgt, _,self.cache_state = predict_with_cfg(
- zt_tgt, cfg[idx],
- text_embeds["prompt_embeds"],
- text_embeds["negative_prompt_embeds"],
- timestep, idx, image_cond, clip_fea, control_latents,
- cache_state=self.cache_state)
- v_delta = vt_tgt - vt_src
- x_tgt = x_tgt.to(torch.float32)
- v_delta = v_delta.to(torch.float32)
- x_tgt = x_tgt + (sigma_prev - sigma) * v_delta
- x0 = x_tgt
#region context windowing
elif context_options is not None:
counter = torch.zeros_like(latent_model_input, device=intermediate_device)
@@ -2258,443 +2018,7 @@ class WanVideoSampler:
noise_pred /= counter
#region multitalk
elif multitalk_sampling:
- mode = image_embeds.get("multitalk_mode", "multitalk")
- if mode == "auto":
- mode = transformer.multitalk_model_type.lower()
- log.info(f"Multitalk mode: {mode}")
- cond_frame = None
- offload = image_embeds.get("force_offload", False)
- offloaded = False
- tiled_vae = image_embeds.get("tiled_vae", False)
- frame_num = clip_length = image_embeds.get("frame_window_size", 81)
-
- clip_embeds = image_embeds.get("clip_context", None)
- if clip_embeds is not None:
- clip_embeds = clip_embeds.to(dtype)
- colormatch = image_embeds.get("colormatch", "disabled")
- motion_frame = image_embeds.get("motion_frame", 25)
- target_w = image_embeds.get("target_w", None)
- target_h = image_embeds.get("target_h", None)
- original_images = cond_image = image_embeds.get("multitalk_start_image", None)
- if original_images is None:
- original_images = torch.zeros([noise.shape[0], 1, target_h, target_w], device=device)
-
- output_path = image_embeds.get("output_path", "")
- img_counter = 0
-
- if len(multitalk_embeds['audio_features'])==2 and (multitalk_embeds['ref_target_masks'] is None):
- face_scale = 0.1
- x_min, x_max = int(target_h * face_scale), int(target_h * (1 - face_scale))
- lefty_min, lefty_max = int((target_w//2) * face_scale), int((target_w//2) * (1 - face_scale))
- righty_min, righty_max = int((target_w//2) * face_scale + (target_w//2)), int((target_w//2) * (1 - face_scale) + (target_w//2))
- human_mask1, human_mask2 = (torch.zeros([target_h, target_w]) for _ in range(2))
- human_mask1[x_min:x_max, lefty_min:lefty_max] = 1
- human_mask2[x_min:x_max, righty_min:righty_max] = 1
- background_mask = torch.where((human_mask1 + human_mask2) > 0, torch.tensor(0), torch.tensor(1))
- human_masks = [human_mask1, human_mask2, background_mask]
- ref_target_masks = torch.stack(human_masks, dim=0)
- multitalk_embeds['ref_target_masks'] = ref_target_masks
-
- gen_video_list = []
- is_first_clip = True
- arrive_last_frame = False
- cur_motion_frames_num = 1
- audio_start_idx = iteration_count = step_iteration_count = 0
- audio_end_idx = (audio_start_idx + clip_length) * audio_stride
- indices = (torch.arange(4 + 1) - 2) * 1
- current_condframe_index = 0
-
- audio_embedding = multitalk_audio_embeds
- human_num = len(audio_embedding)
- audio_embs = None
- cond_frame = None
-
- uni3c_data = uni3c_data_input = None
- if uni3c_embeds is not None:
- transformer.controlnet = uni3c_embeds["controlnet"]
- uni3c_data = uni3c_embeds.copy()
-
- encoded_silence = None
-
- try:
- silence_path = os.path.join(script_directory, "multitalk", "encoded_silence.safetensors")
- encoded_silence = load_torch_file(silence_path)["audio_emb"].to(dtype)
- except:
- log.warning("No encoded silence file found, padding with end of audio embedding instead.")
-
- total_frames = len(audio_embedding[0])
- estimated_iterations = total_frames // (frame_num - motion_frame) + 1
- callback = prepare_callback(patcher, estimated_iterations)
-
- if frame_num >= total_frames:
- arrive_last_frame = True
- estimated_iterations = 1
-
- log.info(f"Sampling {total_frames} frames in {estimated_iterations} windows, at {latent.shape[3]*vae_upscale_factor}x{latent.shape[2]*vae_upscale_factor} with {steps} steps")
-
- while True: # start video generation iteratively
- self.cache_state = [None, None]
-
- cur_motion_frames_latent_num = int(1 + (cur_motion_frames_num-1) // 4)
- if mode == "infinitetalk":
- cond_image = original_images[:, :, current_condframe_index:current_condframe_index+1] if cond_image is not None else None
- if multitalk_embeds is not None:
- audio_embs = []
- # split audio with window size
- for human_idx in range(human_num):
- center_indices = torch.arange(audio_start_idx, audio_end_idx, audio_stride).unsqueeze(1) + indices.unsqueeze(0)
- center_indices = torch.clamp(center_indices, min=0, max=audio_embedding[human_idx].shape[0]-1)
- audio_emb = audio_embedding[human_idx][center_indices].unsqueeze(0).to(device)
- audio_embs.append(audio_emb)
- audio_embs = torch.concat(audio_embs, dim=0).to(dtype)
-
- h, w = (cond_image.shape[-2], cond_image.shape[-1]) if cond_image is not None else (target_h, target_w)
- lat_h, lat_w = h // VAE_STRIDE[1], w // VAE_STRIDE[2]
- seq_len = ((frame_num - 1) // VAE_STRIDE[0] + 1) * lat_h * lat_w // (PATCH_SIZE[1] * PATCH_SIZE[2])
- latent_frame_num = (frame_num - 1) // 4 + 1
-
- noise = torch.randn(
- 16, latent_frame_num,
- lat_h, lat_w, dtype=torch.float32, device=torch.device("cpu"), generator=seed_g).to(device)
-
- # Calculate the correct latent slice based on current iteration
- if is_first_clip:
- latent_start_idx = 0
- latent_end_idx = noise.shape[1]
- else:
- new_frames_per_iteration = frame_num - motion_frame
- new_latent_frames_per_iteration = ((new_frames_per_iteration - 1) // 4 + 1)
- latent_start_idx = iteration_count * new_latent_frames_per_iteration
- latent_end_idx = latent_start_idx + noise.shape[1]
-
- if samples is not None:
- noise_mask = samples.get("noise_mask", None)
- input_samples = samples["samples"]
- if input_samples is not None:
- input_samples = input_samples.squeeze(0).to(noise)
- # Check if we have enough frames in input_samples
- if latent_end_idx > input_samples.shape[1]:
- # We need more frames than available - pad the input_samples at the end
- pad_length = latent_end_idx - input_samples.shape[1]
- last_frame = input_samples[:, -1:].repeat(1, pad_length, 1, 1)
- input_samples = torch.cat([input_samples, last_frame], dim=1)
- input_samples = input_samples[:, latent_start_idx:latent_end_idx]
- if noise_mask is not None:
- original_image = input_samples.to(device)
-
- assert input_samples.shape[1] == noise.shape[1], f"Slice mismatch: {input_samples.shape[1]} vs {noise.shape[1]}"
-
- if add_noise_to_samples:
- latent_timestep = timesteps[0]
- noise = noise * latent_timestep / 1000 + (1 - latent_timestep / 1000) * input_samples
- else:
- noise = input_samples
-
- # diff diff prep
- if noise_mask is not None:
- if len(noise_mask.shape) == 4:
- noise_mask = noise_mask.squeeze(1)
- if audio_end_idx > noise_mask.shape[0]:
- noise_mask = noise_mask.repeat(audio_end_idx // noise_mask.shape[0], 1, 1)
- noise_mask = noise_mask[audio_start_idx:audio_end_idx]
- noise_mask = torch.nn.functional.interpolate(
- noise_mask.unsqueeze(0).unsqueeze(0), # Add batch and channel dims [1,1,T,H,W]
- size=(noise.shape[1], noise.shape[2], noise.shape[3]),
- mode='trilinear',
- align_corners=False
- ).repeat(1, noise.shape[0], 1, 1, 1)
-
- thresholds = torch.arange(len(timesteps), dtype=original_image.dtype) / len(timesteps)
- thresholds = thresholds.reshape(-1, 1, 1, 1, 1).to(device)
- masks = (1-noise_mask.repeat(len(timesteps), 1, 1, 1, 1).to(device)) > thresholds
-
- # zero padding and vae encode for img cond
- if cond_image is not None or cond_frame is not None:
- cond_ = cond_image if (is_first_clip or humo_image_cond is None) else cond_frame
- cond_frame_num = cond_.shape[2]
- video_frames = torch.zeros(1, 3, frame_num-cond_frame_num, target_h, target_w, device=device, dtype=vae.dtype)
- padding_frames_pixels_values = torch.concat([cond_.to(device, vae.dtype), video_frames], dim=2)
-
- # encode
- vae.to(device)
- y = vae.encode(padding_frames_pixels_values, device=device, tiled=tiled_vae, pbar=False).to(dtype)[0]
-
- if mode == "multitalk":
- latent_motion_frames = y[:, :cur_motion_frames_latent_num] # C T H W
- else:
- cond_ = cond_image if is_first_clip else cond_frame
- latent_motion_frames = vae.encode(cond_.to(device, vae.dtype), device=device, tiled=tiled_vae, pbar=False).to(dtype)[0]
-
- vae.to(offload_device)
-
- #motion_frame_index = cur_motion_frames_latent_num if mode == "infinitetalk" else 1
- msk = torch.zeros(4, latent_frame_num, lat_h, lat_w, device=device, dtype=dtype)
- msk[:, :1] = 1
- y = torch.cat([msk, y]) # 4+C T H W
- mm.soft_empty_cache()
- else:
- y = None
- latent_motion_frames = noise[:, :1]
-
- partial_humo_cond_input = partial_humo_cond_neg_input = partial_humo_audio = partial_humo_audio_neg = None
- if humo_image_cond is not None:
- partial_humo_cond_input = humo_image_cond[:, :latent_frame_num]
- partial_humo_cond_neg_input = humo_image_cond_neg[:, :latent_frame_num]
- if y is not None:
- partial_humo_cond_input[:, :1] = y[:, :1]
- if humo_reference_count > 0:
- partial_humo_cond_input[:, -humo_reference_count:] = humo_image_cond[:, -humo_reference_count:]
- partial_humo_cond_neg_input[:, -humo_reference_count:] = humo_image_cond_neg[:, -humo_reference_count:]
-
- if humo_audio is not None:
- if is_first_clip:
- audio_embs = None
-
- partial_humo_audio, _ = get_audio_emb_window(humo_audio, frame_num, frame0_idx=audio_start_idx)
- #zero_audio_pad = torch.zeros(humo_reference_count, *partial_humo_audio.shape[1:], device=partial_humo_audio.device, dtype=partial_humo_audio.dtype)
- partial_humo_audio[-humo_reference_count:] = 0
- partial_humo_audio_neg = torch.zeros_like(partial_humo_audio, device=partial_humo_audio.device, dtype=partial_humo_audio.dtype)
-
- if scheduler == "multitalk":
- timesteps = list(np.linspace(1000, 1, steps, dtype=np.float32))
- timesteps.append(0.)
- timesteps = [torch.tensor([t], device=device) for t in timesteps]
- timesteps = [timestep_transform(t, shift=shift, num_timesteps=1000) for t in timesteps]
- else:
- if isinstance(scheduler, dict):
- sample_scheduler = copy.deepcopy(scheduler["sample_scheduler"])
- timesteps = scheduler["timesteps"]
- else:
- sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, total_steps, start_step, end_step, shift, device, transformer.dim, flowedit_args, denoise_strength, sigmas=sigmas)
- timesteps = [torch.tensor([float(t)], device=device) for t in timesteps] + [torch.tensor([0.], device=device)]
-
- # sample videos
- latent = noise
-
- # injecting motion frames
- if not is_first_clip and mode == "multitalk":
- latent_motion_frames = latent_motion_frames.to(latent.dtype).to(device)
- motion_add_noise = torch.randn(latent_motion_frames.shape, device=torch.device("cpu"), generator=seed_g).to(device).contiguous()
- add_latent = add_noise(latent_motion_frames, motion_add_noise, timesteps[0])
- latent[:, :add_latent.shape[1]] = add_latent
-
- if offloaded:
- # Load weights
- if transformer.patched_linear and gguf_reader is None:
- load_weights(patcher.model.diffusion_model, patcher.model["sd"], weight_dtype, base_dtype=dtype, transformer_load_device=device, block_swap_args=block_swap_args)
- elif gguf_reader is not None: #handle GGUF
- load_weights(transformer, patcher.model["sd"], base_dtype=dtype, transformer_load_device=device, patcher=patcher, gguf=True, reader=gguf_reader, block_swap_args=block_swap_args)
- #blockswap init
- init_blockswap(transformer, block_swap_args, model)
-
- # Use the appropriate prompt for this section
- if len(text_embeds["prompt_embeds"]) > 1:
- prompt_index = min(iteration_count, len(text_embeds["prompt_embeds"]) - 1)
- positive = [text_embeds["prompt_embeds"][prompt_index]]
- log.info(f"Using prompt index: {prompt_index}")
- else:
- positive = text_embeds["prompt_embeds"]
-
- # uni3c slices
- if uni3c_embeds is not None:
- vae.to(device)
- # Pad original_images if needed
- num_frames = original_images.shape[2]
- if audio_end_idx > num_frames:
- pad_len = audio_end_idx - num_frames
- last_frame = original_images[:, :, -1:].repeat(1, 1, pad_len, 1, 1)
- padded_images = torch.cat([original_images, last_frame], dim=2)
- else:
- padded_images = original_images
- render_latent = vae.encode(
- padded_images[:, :, audio_start_idx:audio_end_idx].to(device, vae.dtype),
- device=device, tiled=tiled_vae
- ).to(dtype)
-
- vae.to(offload_device)
- uni3c_data['render_latent'] = render_latent
-
- # unianimate slices
- partial_unianim_data = None
- if unianim_data is not None:
- partial_dwpose = dwpose_data[:, :, latent_start_idx:latent_end_idx]
- partial_unianim_data = {
- "dwpose": partial_dwpose,
- "random_ref": unianim_data["random_ref"],
- "strength": unianimate_poses["strength"],
- "start_percent": unianimate_poses["start_percent"],
- "end_percent": unianimate_poses["end_percent"]
- }
-
- # fantasy portrait slices
- partial_fantasy_portrait_input = None
- if fantasy_portrait_input is not None:
- adapter_proj = fantasy_portrait_input["adapter_proj"]
- if latent_end_idx > adapter_proj.shape[1]:
- pad_len = latent_end_idx - adapter_proj.shape[1]
- last_frame = adapter_proj[:, -1:, :, :].repeat(1, pad_len, 1, 1)
- padded_proj = torch.cat([adapter_proj, last_frame], dim=1)
- else:
- padded_proj = adapter_proj
- partial_fantasy_portrait_input = fantasy_portrait_input.copy()
- partial_fantasy_portrait_input["adapter_proj"] = padded_proj[:, latent_start_idx:latent_end_idx]
-
- mm.soft_empty_cache()
- gc.collect()
- # sampling loop
- sampling_pbar = tqdm(total=len(timesteps)-1, desc=f"Sampling audio indices {audio_start_idx}-{audio_end_idx}", position=0, leave=True)
- for i in range(len(timesteps)-1):
- timestep = timesteps[i]
- latent_model_input = latent.to(device)
- if mode == "infinitetalk":
- if humo_image_cond is None or not is_first_clip:
- latent_model_input[:, :cur_motion_frames_latent_num] = latent_motion_frames
-
- noise_pred, _, self.cache_state = predict_with_cfg(
- latent_model_input, cfg[min(i, len(timesteps)-1)], positive, text_embeds["negative_prompt_embeds"],
- timestep, i, y, clip_embeds, control_latents, None, partial_unianim_data, audio_proj, control_camera_latents, add_cond,
- cache_state=self.cache_state, multitalk_audio_embeds=audio_embs, fantasy_portrait_input=partial_fantasy_portrait_input,
- humo_image_cond=partial_humo_cond_input, humo_image_cond_neg=partial_humo_cond_neg_input, humo_audio=partial_humo_audio, humo_audio_neg=partial_humo_audio_neg,
- uni3c_data = uni3c_data)
-
- if callback is not None:
- callback_latent = (latent_model_input.to(device) - noise_pred.to(device) * t.to(device) / 1000).detach().permute(1,0,2,3)
- callback(step_iteration_count, callback_latent, None, estimated_iterations*(len(timesteps)-1))
- del callback_latent
-
- sampling_pbar.update(1)
- step_iteration_count += 1
-
- # update latent
- if use_tsr:
- noise_pred = temporal_score_rescaling(noise_pred, latent, timestep, tsr_k, tsr_sigma)
- if scheduler == "multitalk":
- noise_pred = -noise_pred
- dt = (timesteps[i] - timesteps[i + 1]) / 1000
- latent = latent + noise_pred * dt[:, None, None, None]
- else:
- latent = sample_scheduler.step(noise_pred.unsqueeze(0), timestep, latent.unsqueeze(0).to(noise_pred.device), **scheduler_step_args)[0].squeeze(0)
- del noise_pred, latent_model_input, timestep
-
- # differential diffusion inpaint
- if masks is not None:
- if i < len(timesteps) - 1:
- image_latent = add_noise(original_image.to(device), noise.to(device), timesteps[i+1])
- mask = masks[i].to(latent)
- latent = image_latent * mask + latent * (1-mask)
-
- # injecting motion frames
- if not is_first_clip and mode == "multitalk":
- latent_motion_frames = latent_motion_frames.to(latent.dtype).to(device)
- motion_add_noise = torch.randn(latent_motion_frames.shape, device=torch.device("cpu"), generator=seed_g).to(device).contiguous()
- add_latent = add_noise(latent_motion_frames, motion_add_noise, timesteps[i+1])
- latent[:, :add_latent.shape[1]] = add_latent
- else:
- if humo_image_cond is None or not is_first_clip:
- latent[:, :cur_motion_frames_latent_num] = latent_motion_frames
-
- del noise, latent_motion_frames
- if offload:
- offload_transformer(transformer, remove_lora=False)
- offloaded = True
- if humo_image_cond is not None and humo_reference_count > 0:
- latent = latent[:,:-humo_reference_count]
- vae.to(device)
- videos = vae.decode(latent.unsqueeze(0).to(device, vae.dtype), device=device, tiled=tiled_vae, pbar=False)[0].cpu()
-
- vae.to(offload_device)
-
- sampling_pbar.close()
-
- # optional color correction (less relevant for InfiniteTalk)
- if colormatch != "disabled":
- videos = videos.permute(1, 2, 3, 0).float().numpy()
- from color_matcher import ColorMatcher
- cm = ColorMatcher()
- cm_result_list = []
- for img in videos:
- if mode == "multitalk":
- cm_result = cm.transfer(src=img, ref=original_images[0].permute(1, 2, 3, 0).squeeze(0).cpu().float().numpy(), method=colormatch)
- else:
- cm_result = cm.transfer(src=img, ref=cond_image[0].permute(1, 2, 3, 0).squeeze(0).cpu().float().numpy(), method=colormatch)
- cm_result_list.append(torch.from_numpy(cm_result).to(vae.dtype))
-
- videos = torch.stack(cm_result_list, dim=0).permute(3, 0, 1, 2)
-
- # optionally save generated samples to disk
- if output_path:
- video_np = videos.clamp(-1.0, 1.0).add(1.0).div(2.0).mul(255).cpu().float().numpy().transpose(1, 2, 3, 0).astype('uint8')
- num_frames_to_save = video_np.shape[0] if is_first_clip else video_np.shape[0] - cur_motion_frames_num
- log.info(f"Saving {num_frames_to_save} generated frames to {output_path}")
- start_idx = 0 if is_first_clip else cur_motion_frames_num
- for i in range(start_idx, video_np.shape[0]):
- im = Image.fromarray(video_np[i])
- im.save(os.path.join(output_path, f"frame_{img_counter:05d}.png"))
- img_counter += 1
- else:
- gen_video_list.append(videos if is_first_clip else videos[:, cur_motion_frames_num:])
-
- current_condframe_index += 1
- iteration_count += 1
-
- # decide whether is done
- if arrive_last_frame:
- break
-
- # update next condition frames
- is_first_clip = False
- cur_motion_frames_num = motion_frame
-
- cond_ = videos[:, -cur_motion_frames_num:].unsqueeze(0)
- if mode == "infinitetalk":
- cond_frame = cond_
- else:
- cond_image = cond_
-
- del videos, latent
-
- # Repeat audio emb
- if multitalk_embeds is not None:
- audio_start_idx += (frame_num - cur_motion_frames_num - humo_reference_count)
- audio_end_idx = audio_start_idx + clip_length
- if audio_end_idx >= len(audio_embedding[0]):
- arrive_last_frame = True
- miss_lengths = []
- source_frames = []
- for human_inx in range(human_num):
- source_frame = len(audio_embedding[human_inx])
- source_frames.append(source_frame)
- if audio_end_idx >= len(audio_embedding[human_inx]):
- log.warning(f"Audio embedding for subject {human_inx} not long enough: {len(audio_embedding[human_inx])}, need {audio_end_idx}, padding...")
- miss_length = audio_end_idx - len(audio_embedding[human_inx]) + 3
- log.warning(f"Padding length: {miss_length}")
- if encoded_silence is not None:
- add_audio_emb = encoded_silence[-1*miss_length:]
- else:
- add_audio_emb = torch.flip(audio_embedding[human_inx][-1*miss_length:], dims=[0])
- audio_embedding[human_inx] = torch.cat([audio_embedding[human_inx], add_audio_emb.to(device, dtype)], dim=0)
- miss_lengths.append(miss_length)
- else:
- miss_lengths.append(0)
- if mode == "infinitetalk" and current_condframe_index >= original_images.shape[2]:
- last_frame = original_images[:, :, -1:, :, :]
- miss_length = 1
- original_images = torch.cat([original_images, last_frame.repeat(1, 1, miss_length, 1, 1)], dim=2)
-
- if not output_path:
- gen_video_samples = torch.cat(gen_video_list, dim=1)
- else:
- gen_video_samples = torch.zeros(3, 1, 64, 64) # dummy output
-
- if force_offload:
- if not model["auto_cpu_offload"]:
- offload_transformer(transformer)
- try:
- print_memory(device)
- torch.cuda.reset_peak_memory_stats(device)
- except:
- pass
- return {"video": gen_video_samples.permute(1, 2, 3, 0), "output_path": output_path},
+ return multitalk_loop(**locals())
# region framepack loop
elif framepack:
framepack_out = []
@@ -2779,7 +2103,7 @@ class WanVideoSampler:
sample_scheduler = copy.deepcopy(scheduler["sample_scheduler"])
timesteps = scheduler["timesteps"]
else:
- sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, total_steps, start_step, end_step, shift, device, transformer.dim, flowedit_args, denoise_strength, sigmas=sigmas)
+ sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, total_steps, start_step, end_step, shift, device, transformer.dim, denoise_strength, sigmas=sigmas)
latent = noise.to(device)
for i, t in enumerate(tqdm(timesteps, desc=f"Sampling audio indices {left_idx}-{right_idx}", position=0)):
@@ -2959,12 +2283,12 @@ class WanVideoSampler:
if input_samples is not None:
input_samples = input_samples.squeeze(0).to(noise)
# Check if we have enough frames in input_samples
- if latent_end_idx > input_samples.shape[1]:
- # We need more frames than available - pad the input_samples at the end
- pad_length = latent_end_idx - input_samples.shape[1]
- last_frame = input_samples[:, -1:].repeat(1, pad_length, 1, 1)
- input_samples = torch.cat([input_samples, last_frame], dim=1)
- input_samples = input_samples[:, latent_start_idx:latent_end_idx]
+ # if latent_end_idx > input_samples.shape[1]:
+ # # We need more frames than available - pad the input_samples at the end
+ # pad_length = latent_end_idx - input_samples.shape[1]
+ # last_frame = input_samples[:, -1:].repeat(1, pad_length, 1, 1)
+ # input_samples = torch.cat([input_samples, last_frame], dim=1)
+ # input_samples = input_samples[:, latent_start_idx:latent_end_idx]
if noise_mask is not None:
original_image = input_samples.to(device)
@@ -3000,7 +2324,7 @@ class WanVideoSampler:
sample_scheduler = copy.deepcopy(scheduler["sample_scheduler"])
timesteps = scheduler["timesteps"]
else:
- sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, total_steps, start_step, end_step, shift, device, transformer.dim, flowedit_args, denoise_strength, sigmas=sigmas)
+ sample_scheduler, timesteps,_,_ = get_scheduler(scheduler, total_steps, start_step, end_step, shift, device, transformer.dim, denoise_strength, sigmas=sigmas)
# sample videos
latent = noise
@@ -3096,17 +2420,17 @@ class WanVideoSampler:
current_ref_images = videos[:, -refert_num:].clone().detach()
# optionally save generated samples to disk
- if output_path:
- video_np = videos.clamp(-1.0, 1.0).add(1.0).div(2.0).mul(255).cpu().float().numpy().transpose(1, 2, 3, 0).astype('uint8')
- num_frames_to_save = video_np.shape[0] if is_first_clip else video_np.shape[0] - cur_motion_frames_num
- log.info(f"Saving {num_frames_to_save} generated frames to {output_path}")
- start_idx = 0 if is_first_clip else cur_motion_frames_num
- for i in range(start_idx, video_np.shape[0]):
- im = Image.fromarray(video_np[i])
- im.save(os.path.join(output_path, f"frame_{img_counter:05d}.png"))
- img_counter += 1
- else:
- gen_video_list.append(videos)
+ # if output_path:
+ # video_np = videos.clamp(-1.0, 1.0).add(1.0).div(2.0).mul(255).cpu().float().numpy().transpose(1, 2, 3, 0).astype('uint8')
+ # num_frames_to_save = video_np.shape[0] if is_first_clip else video_np.shape[0] - cur_motion_frames_num
+ # log.info(f"Saving {num_frames_to_save} generated frames to {output_path}")
+ # start_idx = 0 if is_first_clip else cur_motion_frames_num
+ # for i in range(start_idx, video_np.shape[0]):
+ # im = Image.fromarray(video_np[i])
+ # im.save(os.path.join(output_path, f"frame_{img_counter:05d}.png"))
+ # img_counter += 1
+ # else:
+ gen_video_list.append(videos)
del videos
@@ -3155,94 +2479,87 @@ class WanVideoSampler:
noise_pred = torch.cat([noise_pred[:, latent_video_length - shift_idx:]] + [noise_pred[:, :latent_video_length - shift_idx]], dim=1)
shift_idx = (shift_idx + latent_skip) % latent_video_length
+ latent = latent.to(intermediate_device)
- if flowedit_args is None:
- latent = latent.to(intermediate_device)
+ if self.noise_front_pad_num > 0:
+ noise_pred = noise_pred[:, self.noise_front_pad_num:]
- if self.noise_front_pad_num > 0:
- noise_pred = noise_pred[:, self.noise_front_pad_num:]
+ if use_tsr:
+ noise_pred = temporal_score_rescaling(noise_pred, latent, timestep, tsr_k, tsr_sigma)
- if use_tsr:
- noise_pred = temporal_score_rescaling(noise_pred, latent, timestep, tsr_k, tsr_sigma)
+ if transformer.is_longcat:
+ noise_pred = -noise_pred
- if transformer.is_longcat:
- noise_pred = -noise_pred
-
- if len(timestep.shape) != 1 and clean_latent_indices and not is_pusa: #5b and longcat, skip clean latents for scheduler step
- step_process_indices = [i for i in range(latent.shape[1]) if i not in clean_latent_indices]
- latent[:, step_process_indices] = sample_scheduler.step(noise_pred[:, step_process_indices].unsqueeze(0), orig_timestep,
- latent[:, step_process_indices].unsqueeze(0), **scheduler_step_args)[0].squeeze(0)
- else:
- if latents_to_not_step > 0:
- raw_latent = latent[:, :latents_to_not_step]
- noise_pred_in = noise_pred[:, latents_to_not_step:]
- latent = latent[:, latents_to_not_step:]
- elif recammaster is not None or mocha_embeds is not None:
- noise_pred_in = noise_pred[:, :orig_noise_len]
- latent = latent[:, :orig_noise_len]
- else:
- noise_pred_in = noise_pred
- latent = sample_scheduler.step(noise_pred_in.unsqueeze(0), timestep, latent.unsqueeze(0), **scheduler_step_args)[0].squeeze(0)
- if noise_pred_flipped is not None:
- latent_backwards = sample_scheduler_flipped.step(noise_pred_flipped.unsqueeze(0), timestep, latent_flipped.unsqueeze(0), **scheduler_step_args)[0].squeeze(0)
- latent_backwards = torch.flip(latent_backwards, dims=[1])
- latent = latent * 0.5 + latent_backwards * 0.5
- if latents_to_not_step > 0:
- latent = torch.cat([raw_latent, latent], dim=1)
-
- if latent_ovi is not None:
- latent_ovi = sample_scheduler_ovi.step(noise_pred_ovi.unsqueeze(0), t, latent_ovi.to(device).unsqueeze(0), **scheduler_step_args)[0].squeeze(0)
-
- #InfiniteTalk first frame handling
- if (extra_latents is not None
- and not multitalk_sampling
- and transformer.multitalk_model_type=="InfiniteTalk"):
- for entry in extra_latents:
- add_index = entry["index"]
- num_extra_frames = entry["samples"].shape[2]
- latent[:, add_index:add_index+num_extra_frames] = entry["samples"].to(latent)
-
- # differential diffusion inpaint
- if masks is not None:
- if idx < len(timesteps) - 1:
- noise_timestep = timesteps[idx+1]
- image_latent = sample_scheduler.scale_noise(
- original_image.to(device), torch.tensor([noise_timestep]), noise.to(device)
- )
- mask = masks[idx].to(latent)
- latent = image_latent * mask + latent * (1-mask)
-
- # TTM
- if ttm_reference_latents is not None and (idx + ttm_start_step) < ttm_end_step:
- if idx + ttm_start_step + 1 < len(sample_scheduler.all_timesteps):
- noisy_latents = add_noise(ttm_reference_latents, noise, sample_scheduler.all_timesteps[idx + ttm_start_step + 1].to(noise.device)).to(latent)
- latent = latent * (1 - motion_mask) + noisy_latents * motion_mask
- else:
- latent = latent * (1 - motion_mask) + ttm_reference_latents.to(latent) * motion_mask
-
- if freeinit_args is not None:
- current_latent = latent.clone()
-
- if callback is not None:
- if recammaster is not None or mocha_embeds is not None:
- callback_latent = (latent_model_input[:, :orig_noise_len].to(device) - noise_pred[:, :orig_noise_len].to(device) * t.to(device) / 1000).detach()
- #elif phantom_latents is not None:
- # callback_latent = (latent_model_input[:,:-phantom_latents.shape[1]].to(device) - noise_pred[:,:-phantom_latents.shape[1]].to(device) * t.to(device) / 1000).detach()
- elif humo_reference_count > 0:
- callback_latent = (latent_model_input[:,:-humo_reference_count].to(device) - noise_pred[:,:-humo_reference_count].to(device) * t.to(device) / 1000).detach()
- elif "rcm" in sample_scheduler.__class__.__name__.lower():
- callback_latent = (latent_model_input.to(device) - noise_pred.to(device) * t.to(device)).detach()
- else:
- callback_latent = (latent_model_input.to(device) - noise_pred.to(device) * t.to(device) / 1000).detach()
- callback(idx, callback_latent.permute(1,0,2,3), None, len(timesteps))
- else:
- pbar.update(1)
+ if len(timestep.shape) != 1 and clean_latent_indices and not is_pusa: #5b and longcat, skip clean latents for scheduler step
+ step_process_indices = [i for i in range(latent.shape[1]) if i not in clean_latent_indices]
+ latent[:, step_process_indices] = sample_scheduler.step(noise_pred[:, step_process_indices].unsqueeze(0), orig_timestep,
+ latent[:, step_process_indices].unsqueeze(0), **scheduler_step_args)[0].squeeze(0)
else:
- if callback is not None:
- callback_latent = (zt_tgt.to(device) - vt_tgt.to(device) * t.to(device) / 1000).detach()
- callback(idx, callback_latent.permute(1,0,2,3), None, len(timesteps))
+ if latents_to_not_step > 0:
+ raw_latent = latent[:, :latents_to_not_step]
+ noise_pred_in = noise_pred[:, latents_to_not_step:]
+ latent = latent[:, latents_to_not_step:]
+ elif recammaster is not None or mocha_embeds is not None:
+ noise_pred_in = noise_pred[:, :orig_noise_len]
+ latent = latent[:, :orig_noise_len]
else:
- pbar.update(1)
+ noise_pred_in = noise_pred
+ latent = sample_scheduler.step(noise_pred_in.unsqueeze(0), timestep, latent.unsqueeze(0), **scheduler_step_args)[0].squeeze(0)
+ if noise_pred_flipped is not None:
+ latent_backwards = sample_scheduler_flipped.step(noise_pred_flipped.unsqueeze(0), timestep, latent_flipped.unsqueeze(0), **scheduler_step_args)[0].squeeze(0)
+ latent_backwards = torch.flip(latent_backwards, dims=[1])
+ latent = latent * 0.5 + latent_backwards * 0.5
+ if latents_to_not_step > 0:
+ latent = torch.cat([raw_latent, latent], dim=1)
+
+ if latent_ovi is not None:
+ latent_ovi = sample_scheduler_ovi.step(noise_pred_ovi.unsqueeze(0), t, latent_ovi.to(device).unsqueeze(0), **scheduler_step_args)[0].squeeze(0)
+
+ #InfiniteTalk first frame handling
+ if (extra_latents is not None
+ and not multitalk_sampling
+ and transformer.multitalk_model_type=="InfiniteTalk"):
+ for entry in extra_latents:
+ add_index = entry["index"]
+ num_extra_frames = entry["samples"].shape[2]
+ latent[:, add_index:add_index+num_extra_frames] = entry["samples"].to(latent)
+
+ # differential diffusion inpaint
+ if masks is not None:
+ if idx < len(timesteps) - 1:
+ noise_timestep = timesteps[idx+1]
+ image_latent = sample_scheduler.scale_noise(
+ original_image.to(device), torch.tensor([noise_timestep]), noise.to(device)
+ )
+ mask = masks[idx].to(latent)
+ latent = image_latent * mask + latent * (1-mask)
+
+ # TTM
+ if ttm_reference_latents is not None and (idx + ttm_start_step) < ttm_end_step:
+ if idx + ttm_start_step + 1 < len(sample_scheduler.all_timesteps):
+ noisy_latents = add_noise(ttm_reference_latents, noise, sample_scheduler.all_timesteps[idx + ttm_start_step + 1].to(noise.device)).to(latent)
+ latent = latent * (1 - motion_mask) + noisy_latents * motion_mask
+ else:
+ latent = latent * (1 - motion_mask) + ttm_reference_latents.to(latent) * motion_mask
+
+ if freeinit_args is not None:
+ current_latent = latent.clone()
+
+ if callback is not None:
+ if recammaster is not None or mocha_embeds is not None:
+ callback_latent = (latent_model_input[:, :orig_noise_len].to(device) - noise_pred[:, :orig_noise_len].to(device) * t.to(device) / 1000).detach()
+ #elif phantom_latents is not None:
+ # callback_latent = (latent_model_input[:,:-phantom_latents.shape[1]].to(device) - noise_pred[:,:-phantom_latents.shape[1]].to(device) * t.to(device) / 1000).detach()
+ elif humo_reference_count > 0:
+ callback_latent = (latent_model_input[:,:-humo_reference_count].to(device) - noise_pred[:,:-humo_reference_count].to(device) * t.to(device) / 1000).detach()
+ elif "rcm" in sample_scheduler.__class__.__name__.lower():
+ callback_latent = (latent_model_input.to(device) - noise_pred.to(device) * t.to(device)).detach()
+ else:
+ callback_latent = (latent_model_input.to(device) - noise_pred.to(device) * t.to(device) / 1000).detach()
+ callback(idx, callback_latent.permute(1,0,2,3), None, len(timesteps))
+ else:
+ pbar.update(1)
+
except Exception as e:
log.error(f"Error during sampling: {e}")
if force_offload:
diff --git a/utils.py b/utils.py
index ddfb1c1..243e5a6 100644
--- a/utils.py
+++ b/utils.py
@@ -4,17 +4,99 @@ import logging
import math
from tqdm import tqdm
from pathlib import Path
-import os
+import gc
import types, collections
from comfy.utils import ProgressBar, copy_to_param, set_attr_param
from comfy.model_patcher import get_key_weight, string_to_seed
from comfy.lora import calculate_weight
-from comfy.model_management import cast_to_device
+
from comfy.float import stochastic_rounding
+from .custom_linear import remove_lora_from_module
import folder_paths
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
log = logging.getLogger(__name__)
+import comfy.model_management as mm
+device = mm.get_torch_device()
+offload_device = mm.unet_offload_device()
+
+try:
+ from .gguf.gguf import GGUFParameter
+except:
+ pass
+
+class MetaParameter(torch.nn.Parameter):
+ def __new__(cls, dtype, quant_type=None):
+ data = torch.empty(0, dtype=dtype)
+ self = torch.nn.Parameter(data, requires_grad=False)
+ self.quant_type = quant_type
+ return self
+
+def offload_transformer(transformer, remove_lora=True):
+ transformer.teacache_state.clear_all()
+ transformer.magcache_state.clear_all()
+ transformer.easycache_state.clear_all()
+
+ if transformer.patched_linear:
+ for name, param in transformer.named_parameters():
+ if "loras" in name or "controlnet" in name:
+ continue
+ module = transformer
+ subnames = name.split('.')
+ for subname in subnames[:-1]:
+ module = getattr(module, subname)
+ attr_name = subnames[-1]
+ if param.data.is_floating_point():
+ meta_param = torch.nn.Parameter(torch.empty_like(param.data, device='meta'), requires_grad=False)
+ setattr(module, attr_name, meta_param)
+ elif isinstance(param.data, GGUFParameter):
+ quant_type = getattr(param, 'quant_type', None)
+ setattr(module, attr_name, MetaParameter(param.data.dtype, quant_type))
+ else:
+ pass
+ if remove_lora:
+ remove_lora_from_module(transformer)
+ else:
+ transformer.to(offload_device)
+
+ for block in transformer.blocks:
+ block.kv_cache = None
+ if transformer.audio_model is not None and hasattr(block, 'audio_block'):
+ block.audio_block = None
+
+ mm.soft_empty_cache()
+ gc.collect()
+
+
+def init_blockswap(transformer, block_swap_args, model):
+ if not transformer.patched_linear:
+ if block_swap_args is not None:
+ for name, param in transformer.named_parameters():
+ if "block" not in name or "control_adapter" in name or "face" in name:
+ param.data = param.data.to(device)
+ elif block_swap_args["offload_txt_emb"] and "txt_emb" in name:
+ param.data = param.data.to(offload_device)
+ elif block_swap_args["offload_img_emb"] and "img_emb" in name:
+ param.data = param.data.to(offload_device)
+
+ transformer.block_swap(
+ block_swap_args["blocks_to_swap"] - 1 ,
+ block_swap_args["offload_txt_emb"],
+ block_swap_args["offload_img_emb"],
+ vace_blocks_to_swap = block_swap_args.get("vace_blocks_to_swap", None),
+ )
+ elif model["auto_cpu_offload"]:
+ for module in transformer.modules():
+ if hasattr(module, "offload"):
+ module.offload()
+ if hasattr(module, "onload"):
+ module.onload()
+ for block in transformer.blocks:
+ block.modulation = torch.nn.Parameter(block.modulation.to(device))
+ transformer.head.modulation = torch.nn.Parameter(transformer.head.modulation.to(device))
+ else:
+ transformer.to(device)
+
def check_device_same(first_device, second_device):
if first_device.type != second_device.type:
return False
@@ -140,7 +222,7 @@ def patch_weight_to_device(self, key, device_to=None, inplace_update=False, back
self.backup[key] = collections.namedtuple('Dimension', ['weight', 'inplace_update'])(weight.to(device=self.offload_device, copy=inplace_update), inplace_update)
if device_to is not None:
- temp_weight = cast_to_device(weight, device_to, torch.float32, copy=True)
+ temp_weight = mm.cast_to_device(weight, device_to, torch.float32, copy=True)
else:
temp_weight = weight.to(torch.float32, copy=True)
if convert_func is not None:
diff --git a/wanvideo/schedulers/__init__.py b/wanvideo/schedulers/__init__.py
index abb450f..b5d6c62 100644
--- a/wanvideo/schedulers/__init__.py
+++ b/wanvideo/schedulers/__init__.py
@@ -42,7 +42,7 @@ def _apply_custom_sigmas(sample_scheduler, sigmas, device):
sample_scheduler.timesteps = (sample_scheduler.sigmas[:-1] * 1000).to(torch.int64).to(device)
sample_scheduler.num_inference_steps = len(sample_scheduler.timesteps)
-def get_scheduler(scheduler, steps, start_step, end_step, shift, device, transformer_dim=5120, flowedit_args=None, denoise_strength=1.0, sigmas=None, log_timesteps=False, enhance_hf=False, **kwargs):
+def get_scheduler(scheduler, steps, start_step, end_step, shift, device, transformer_dim=5120, denoise_strength=1.0, sigmas=None, log_timesteps=False, enhance_hf=False, **kwargs):
timesteps = None
if sigmas is not None:
steps = len(sigmas) - 1
From b2c520ca448606180d0c802829b7d60aa0b2b802 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 12:55:13 +0200
Subject: [PATCH 08/22] Fix s2v
---
wanvideo/modules/model.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/wanvideo/modules/model.py b/wanvideo/modules/model.py
index 89f180f..2a0b794 100644
--- a/wanvideo/modules/model.py
+++ b/wanvideo/modules/model.py
@@ -2187,7 +2187,7 @@ class WanModel(torch.nn.Module):
def rope_encode_comfy(self, t, h, w, freq_offset=0, t_start=0, ref_frame_shape=None, pose_frame_shape=None,
steps_t=None, steps_h=None, steps_w=None, ntk_alphas=[1,1,1], device=None, dtype=None,
- ref_frame_index=10, longcat_num_ref_latents=None):
+ ref_frame_index=10, longcat_num_ref_latents=0):
patch_size = self.patch_size
t_len = ((t + (patch_size[0] // 2)) // patch_size[0])
From 027bed8c3d91b7b97f5b5ee069ce233fab9154e7 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 13:51:05 +0200
Subject: [PATCH 09/22] Cleanup
---
nodes_sampler.py | 28 ++++++++++++----------------
wanvideo/modules/model.py | 2 +-
2 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/nodes_sampler.py b/nodes_sampler.py
index e1216a9..42fd8cf 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -599,12 +599,10 @@ class WanVideoSampler:
portrait_cfg = [portrait_cfg] * (steps + 1)
# MiniMax Remover
- minimax_latents = minimax_mask_latents = None
minimax_latents = image_embeds.get("minimax_latents", None)
minimax_mask_latents = image_embeds.get("minimax_mask_latents", None)
if minimax_latents is not None:
- log.info(f"minimax_latents: {minimax_latents.shape}")
- log.info(f"minimax_mask_latents: {minimax_mask_latents.shape}")
+ log.info(f"minimax_latents: {minimax_latents.shape}, minimax_mask_latents: {minimax_mask_latents.shape}")
minimax_latents = minimax_latents.to(device, dtype)
minimax_mask_latents = minimax_mask_latents.to(device, dtype)
@@ -691,7 +689,7 @@ class WanVideoSampler:
framepack = False
s2v_audio_embeds = image_embeds.get("audio_embeds", None)
if s2v_audio_embeds is not None:
- log.info(f"Using S2V audio embeddings")
+ log.info("Using S2V audio embeddings")
framepack = s2v_audio_embeds.get("enable_framepack", False)
if framepack and context_options is not None:
raise ValueError("S2V framepack and context windows cannot be used at the same time")
@@ -1685,7 +1683,6 @@ class WanVideoSampler:
log.info(f"Input sequence length: {seq_len}")
log.info(f"Sampling {(latent_video_length-1) * 4 + 1} frames at {latent.shape[3]*vae_upscale_factor}x{latent.shape[2]*vae_upscale_factor} with {steps-ttm_start_step} steps")
- intermediate_device = device
# Differential diffusion prep
masks = None
@@ -1826,8 +1823,8 @@ class WanVideoSampler:
enhance_enabled = True
#region context windowing
elif context_options is not None:
- counter = torch.zeros_like(latent_model_input, device=intermediate_device)
- noise_pred = torch.zeros_like(latent_model_input, device=intermediate_device)
+ counter = torch.zeros_like(latent_model_input, device=device)
+ noise_pred = torch.zeros_like(latent_model_input, device=device)
context_queue = list(context(idx, steps, latent_video_length, context_frames, context_stride, context_overlap))
fraction_per_context = 1.0 / len(context_queue)
context_pbar = ProgressBar(steps)
@@ -1857,13 +1854,12 @@ class WanVideoSampler:
else:
positive = text_embeds["prompt_embeds"]
- partial_img_emb = None
- partial_control_latents = None
+ partial_img_emb = partial_control_latents = None
if image_cond is not None:
- partial_img_emb = image_cond[:, c]
+ partial_img_emb = image_cond[:, c].to(device)
if c[0] != 0 and context_reference_latent is not None:
if context_reference_latent.shape[0] == 1: #only single extra init latent
- new_init_image = context_reference_latent[0, :, 0].to(intermediate_device)
+ new_init_image = context_reference_latent[0, :, 0].to(device)
# Concatenate the first 4 channels of partial_img_emb with new_init_image to match the required shape
partial_img_emb[:, 0] = torch.cat([image_cond[:4, 0], new_init_image], dim=0)
elif context_reference_latent.shape[0] > 1:
@@ -1872,10 +1868,10 @@ class WanVideoSampler:
extra_init_index = min(int(max(c) / section_size), num_extra_inits - 1)
if context_options["verbose"]:
log.info(f"extra init image index: {extra_init_index}")
- new_init_image = context_reference_latent[extra_init_index, :, 0].to(intermediate_device)
+ new_init_image = context_reference_latent[extra_init_index, :, 0].to(device)
partial_img_emb[:, 0] = torch.cat([image_cond[:4, 0], new_init_image], dim=0)
else:
- new_init_image = image_cond[:, 0].to(intermediate_device)
+ new_init_image = image_cond[:, 0].to(device)
partial_img_emb[:, 0] = new_init_image
if control_latents is not None:
@@ -1893,14 +1889,14 @@ class WanVideoSampler:
if has_ref:
if c[0] != 0 and context_reference_latent is not None:
if context_reference_latent.shape[0] == 1: #only single extra init latent
- partial_context[16:32, :1] = context_reference_latent[0, :, :1].to(intermediate_device)
+ partial_context[16:32, :1] = context_reference_latent[0, :, :1].to(device)
elif context_reference_latent.shape[0] > 1:
num_extra_inits = context_reference_latent.shape[0]
section_size = (latent_video_length / num_extra_inits)
extra_init_index = min(int(max(c) / section_size), num_extra_inits - 1)
if context_options["verbose"]:
log.info(f"extra init image index: {extra_init_index}")
- partial_context[16:32, :1] = context_reference_latent[extra_init_index, :, :1].to(intermediate_device)
+ partial_context[16:32, :1] = context_reference_latent[extra_init_index, :, :1].to(device)
else:
partial_context[:, 0] = vace_entry["context"][0][:, 0]
@@ -2479,7 +2475,7 @@ class WanVideoSampler:
noise_pred = torch.cat([noise_pred[:, latent_video_length - shift_idx:]] + [noise_pred[:, :latent_video_length - shift_idx]], dim=1)
shift_idx = (shift_idx + latent_skip) % latent_video_length
- latent = latent.to(intermediate_device)
+ latent = latent.to(device)
if self.noise_front_pad_num > 0:
noise_pred = noise_pred[:, self.noise_front_pad_num:]
diff --git a/wanvideo/modules/model.py b/wanvideo/modules/model.py
index 2a0b794..96df41c 100644
--- a/wanvideo/modules/model.py
+++ b/wanvideo/modules/model.py
@@ -2648,7 +2648,7 @@ class WanModel(torch.nn.Module):
device=x.device,
dtype=x.dtype
)
- log.info("Generated new RoPE frequencies")
+ tqdm.write("Generated new RoPE frequencies")
if s2v_ref_latent is not None:
freqs_ref = self.rope_encode_comfy(
From 220aac277155d286092ec79f5cf426b9fa4e7f29 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 13:52:27 +0200
Subject: [PATCH 10/22] Update
LongCatAvatar_audio_image_to_video_example_01.json
---
...vatar_audio_image_to_video_example_01.json | 1209 ++++++++---------
1 file changed, 554 insertions(+), 655 deletions(-)
diff --git a/example_workflows/LongCatAvatar_audio_image_to_video_example_01.json b/example_workflows/LongCatAvatar_audio_image_to_video_example_01.json
index cfd6784..f982637 100644
--- a/example_workflows/LongCatAvatar_audio_image_to_video_example_01.json
+++ b/example_workflows/LongCatAvatar_audio_image_to_video_example_01.json
@@ -18,7 +18,7 @@
"flags": {
"collapsed": true
},
- "order": 69,
+ "order": 66,
"mode": 0,
"inputs": [
{
@@ -42,44 +42,6 @@
"wanmodel"
]
},
- {
- "id": 264,
- "type": "SetNode",
- "pos": [
- 1774.0058566239184,
- -2289.9456989986097
- ],
- "size": [
- 210,
- 60
- ],
- "flags": {
- "collapsed": true
- },
- "order": 63,
- "mode": 0,
- "inputs": [
- {
- "name": "CLIP_VISION",
- "type": "CLIP_VISION",
- "link": 466
- }
- ],
- "outputs": [
- {
- "name": "*",
- "type": "*",
- "links": null
- }
- ],
- "title": "Set_clip_vision_model",
- "properties": {
- "previousName": "clip_vision_model"
- },
- "widgets_values": [
- "clip_vision_model"
- ]
- },
{
"id": 247,
"type": "SetNode",
@@ -94,7 +56,7 @@
"flags": {
"collapsed": true
},
- "order": 55,
+ "order": 53,
"mode": 0,
"inputs": [
{
@@ -134,7 +96,7 @@
"flags": {
"collapsed": true
},
- "order": 56,
+ "order": 54,
"mode": 0,
"inputs": [
{
@@ -206,7 +168,7 @@
112
],
"flags": {},
- "order": 76,
+ "order": 73,
"mode": 0,
"inputs": [
{
@@ -217,9 +179,9 @@
],
"outputs": [],
"properties": {
- "Node name for S&R": "PreviewAny",
"cnr_id": "comfy-core",
- "ver": "0.3.50"
+ "ver": "0.3.50",
+ "Node name for S&R": "PreviewAny"
},
"widgets_values": [
null,
@@ -261,29 +223,6 @@
"color": "#1b4669",
"bgcolor": "#29699c"
},
- {
- "id": 299,
- "type": "Note",
- "pos": [
- 1486.8775607254809,
- -2203.5067341548597
- ],
- "size": [
- 290.9361267089844,
- 88
- ],
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "Clip vision is not strictly necessary\n\nAny I2V model should work, MAGREF can be interesting to play with as well."
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
{
"id": 240,
"type": "SetNode",
@@ -298,7 +237,7 @@
"flags": {
"collapsed": true
},
- "order": 58,
+ "order": 56,
"mode": 0,
"inputs": [
{
@@ -336,7 +275,7 @@
314
],
"flags": {},
- "order": 3,
+ "order": 2,
"mode": 0,
"inputs": [],
"outputs": [
@@ -354,9 +293,9 @@
}
],
"properties": {
- "Node name for S&R": "LoadImage",
"cnr_id": "comfy-core",
- "ver": "0.3.50"
+ "ver": "0.3.50",
+ "Node name for S&R": "LoadImage"
},
"widgets_values": [
"man.png",
@@ -375,7 +314,7 @@
58
],
"flags": {},
- "order": 4,
+ "order": 3,
"mode": 0,
"inputs": [],
"outputs": [
@@ -389,9 +328,9 @@
],
"title": "Width",
"properties": {
- "Node name for S&R": "INTConstant",
"cnr_id": "comfyui-kjnodes",
- "ver": "e435e999e4b1a828a6b5f6d8f037e66f4a798324"
+ "ver": "e435e999e4b1a828a6b5f6d8f037e66f4a798324",
+ "Node name for S&R": "INTConstant"
},
"widgets_values": [
832
@@ -411,7 +350,7 @@
58
],
"flags": {},
- "order": 5,
+ "order": 4,
"mode": 0,
"inputs": [],
"outputs": [
@@ -425,9 +364,9 @@
],
"title": "Height",
"properties": {
- "Node name for S&R": "INTConstant",
"cnr_id": "comfyui-kjnodes",
- "ver": "e435e999e4b1a828a6b5f6d8f037e66f4a798324"
+ "ver": "e435e999e4b1a828a6b5f6d8f037e66f4a798324",
+ "Node name for S&R": "INTConstant"
},
"widgets_values": [
480
@@ -447,7 +386,7 @@
46
],
"flags": {},
- "order": 67,
+ "order": 64,
"mode": 0,
"inputs": [
{
@@ -476,9 +415,9 @@
}
],
"properties": {
- "Node name for S&R": "MelBandRoFormerSampler",
"cnr_id": "ComfyUI-MelBandRoFormer",
- "ver": "b68d9077815387b64d596f8c39607052b95b6eba"
+ "ver": "b68d9077815387b64d596f8c39607052b95b6eba",
+ "Node name for S&R": "MelBandRoFormerSampler"
},
"widgets_values": []
},
@@ -494,7 +433,7 @@
336
],
"flags": {},
- "order": 54,
+ "order": 52,
"mode": 0,
"inputs": [
{
@@ -550,9 +489,9 @@
}
],
"properties": {
- "Node name for S&R": "ImageResizeKJv2",
"cnr_id": "comfyui-kjnodes",
- "ver": "f7eb33abc80a2aded1b46dff0dd14d07856a7d50"
+ "ver": "f7eb33abc80a2aded1b46dff0dd14d07856a7d50",
+ "Node name for S&R": "ImageResizeKJv2"
},
"widgets_values": [
832,
@@ -562,8 +501,7 @@
"0, 0, 0",
"center",
16,
- "cpu",
- "
| Output: | 1 x 832 x 480 | 4.57MB |
"
+ "cpu"
]
},
{
@@ -580,7 +518,7 @@
"flags": {
"collapsed": true
},
- "order": 65,
+ "order": 61,
"mode": 0,
"inputs": [
{
@@ -616,7 +554,7 @@
136
],
"flags": {},
- "order": 6,
+ "order": 5,
"mode": 0,
"inputs": [],
"outputs": [
@@ -629,9 +567,9 @@
}
],
"properties": {
- "Node name for S&R": "LoadAudio",
"cnr_id": "comfy-core",
- "ver": "0.3.41"
+ "ver": "0.3.41",
+ "Node name for S&R": "LoadAudio"
},
"widgets_values": [
"man.mp3",
@@ -651,7 +589,7 @@
106
],
"flags": {},
- "order": 7,
+ "order": 6,
"mode": 0,
"inputs": [
{
@@ -672,9 +610,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoVAELoader",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "c3ee35f3ece76e38099dc516182d69b406e16772"
+ "ver": "c3ee35f3ece76e38099dc516182d69b406e16772",
+ "Node name for S&R": "WanVideoVAELoader"
},
"widgets_values": [
"Wan2_1_VAE_bf16.safetensors",
@@ -696,7 +634,7 @@
82
],
"flags": {},
- "order": 57,
+ "order": 55,
"mode": 0,
"inputs": [
{
@@ -716,9 +654,9 @@
}
],
"properties": {
- "Node name for S&R": "TrimAudioDuration",
"cnr_id": "comfy-core",
- "ver": "0.5.0"
+ "ver": "0.5.0",
+ "Node name for S&R": "TrimAudioDuration"
},
"widgets_values": [
0,
@@ -737,7 +675,7 @@
386.354248046875
],
"flags": {},
- "order": 8,
+ "order": 7,
"mode": 0,
"inputs": [
{
@@ -768,9 +706,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoTextEncodeCached",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "ff779c91714d8ee3484cd4119b082c72a1734b72"
+ "ver": "ff779c91714d8ee3484cd4119b082c72a1734b72",
+ "Node name for S&R": "WanVideoTextEncodeCached"
},
"widgets_values": [
"umt5-xxl-enc-bf16.safetensors",
@@ -798,7 +736,7 @@
"flags": {
"collapsed": true
},
- "order": 59,
+ "order": 57,
"mode": 0,
"inputs": [
{
@@ -834,7 +772,7 @@
58
],
"flags": {},
- "order": 9,
+ "order": 8,
"mode": 0,
"inputs": [],
"outputs": [
@@ -848,6 +786,8 @@
],
"title": "cfg",
"properties": {
+ "cnr_id": "comfyui-kjnodes",
+ "ver": "79f529a84a8c20fe5dcdfa984c6be7a94102c014",
"Node name for S&R": "FloatConstant"
},
"widgets_values": [
@@ -870,7 +810,7 @@
"flags": {
"collapsed": true
},
- "order": 10,
+ "order": 9,
"mode": 0,
"inputs": [],
"outputs": [
@@ -904,7 +844,7 @@
"flags": {
"collapsed": true
},
- "order": 11,
+ "order": 10,
"mode": 0,
"inputs": [],
"outputs": [
@@ -938,7 +878,7 @@
"flags": {
"collapsed": true
},
- "order": 85,
+ "order": 82,
"mode": 0,
"inputs": [
{
@@ -968,9 +908,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoEncode",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490"
+ "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490",
+ "Node name for S&R": "WanVideoEncode"
},
"widgets_values": [
false,
@@ -998,7 +938,7 @@
"flags": {
"collapsed": true
},
- "order": 12,
+ "order": 11,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1033,7 +973,7 @@
"flags": {
"collapsed": true
},
- "order": 87,
+ "order": 84,
"mode": 0,
"inputs": [
{
@@ -1058,9 +998,9 @@
}
],
"properties": {
- "Node name for S&R": "ReplaceVideoLatentFrames",
"cnr_id": "comfy-core",
- "ver": "0.5.0"
+ "ver": "0.5.0",
+ "Node name for S&R": "ReplaceVideoLatentFrames"
},
"widgets_values": [
0
@@ -1080,7 +1020,7 @@
"flags": {
"collapsed": true
},
- "order": 13,
+ "order": 12,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1114,7 +1054,7 @@
"flags": {
"collapsed": true
},
- "order": 14,
+ "order": 13,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1146,7 +1086,7 @@
"flags": {
"collapsed": true
},
- "order": 15,
+ "order": 14,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1180,7 +1120,7 @@
"flags": {
"collapsed": true
},
- "order": 16,
+ "order": 15,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1210,7 +1150,7 @@
426.8679387019231
],
"flags": {},
- "order": 75,
+ "order": 72,
"mode": 0,
"inputs": [
{
@@ -1270,9 +1210,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoSamplerv2",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd"
+ "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd",
+ "Node name for S&R": "WanVideoSamplerv2"
},
"widgets_values": [
1,
@@ -1294,7 +1234,7 @@
26
],
"flags": {},
- "order": 77,
+ "order": 74,
"mode": 0,
"inputs": [
{
@@ -1332,7 +1272,7 @@
"flags": {
"collapsed": true
},
- "order": 17,
+ "order": 16,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1365,7 +1305,7 @@
26
],
"flags": {},
- "order": 81,
+ "order": 78,
"mode": 0,
"inputs": [
{
@@ -1403,7 +1343,7 @@
"flags": {
"collapsed": true
},
- "order": 18,
+ "order": 17,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1437,7 +1377,7 @@
"flags": {
"collapsed": true
},
- "order": 19,
+ "order": 18,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1469,7 +1409,7 @@
58
],
"flags": {},
- "order": 20,
+ "order": 19,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1483,6 +1423,8 @@
],
"title": "frames_per_window",
"properties": {
+ "cnr_id": "comfyui-kjnodes",
+ "ver": "79f529a84a8c20fe5dcdfa984c6be7a94102c014",
"Node name for S&R": "INTConstant"
},
"widgets_values": [
@@ -1505,7 +1447,7 @@
"flags": {
"collapsed": true
},
- "order": 61,
+ "order": 59,
"mode": 0,
"inputs": [
{
@@ -1545,7 +1487,7 @@
"flags": {
"collapsed": true
},
- "order": 62,
+ "order": 60,
"mode": 0,
"inputs": [
{
@@ -1585,7 +1527,7 @@
"flags": {
"collapsed": true
},
- "order": 60,
+ "order": 58,
"mode": 0,
"inputs": [
{
@@ -1625,7 +1567,7 @@
"flags": {
"collapsed": true
},
- "order": 21,
+ "order": 20,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1645,40 +1587,6 @@
"color": "#1b4669",
"bgcolor": "#29699c"
},
- {
- "id": 413,
- "type": "GetNode",
- "pos": [
- 5071.410986510317,
- -1685.578721396226
- ],
- "size": [
- 210,
- 60
- ],
- "flags": {
- "collapsed": true
- },
- "order": 22,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 775
- ]
- }
- ],
- "title": "Get_ref_latent",
- "properties": {},
- "widgets_values": [
- "ref_latent"
- ],
- "color": "#323",
- "bgcolor": "#535"
- },
{
"id": 443,
"type": "GetNode",
@@ -1693,7 +1601,7 @@
"flags": {
"collapsed": true
},
- "order": 23,
+ "order": 21,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1727,7 +1635,7 @@
"flags": {
"collapsed": true
},
- "order": 70,
+ "order": 67,
"mode": 0,
"inputs": [
{
@@ -1767,7 +1675,7 @@
"flags": {
"collapsed": true
},
- "order": 24,
+ "order": 22,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1801,7 +1709,7 @@
"flags": {
"collapsed": true
},
- "order": 25,
+ "order": 23,
"mode": 0,
"inputs": [],
"outputs": [
@@ -1833,7 +1741,7 @@
242
],
"flags": {},
- "order": 66,
+ "order": 63,
"mode": 0,
"inputs": [
{
@@ -1863,9 +1771,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoEncode",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490"
+ "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490",
+ "Node name for S&R": "WanVideoEncode"
},
"widgets_values": [
false,
@@ -1891,7 +1799,7 @@
198
],
"flags": {},
- "order": 78,
+ "order": 75,
"mode": 0,
"inputs": [
{
@@ -1916,9 +1824,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoDecode",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490"
+ "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490",
+ "Node name for S&R": "WanVideoDecode"
},
"widgets_values": [
false,
@@ -1943,7 +1851,7 @@
238
],
"flags": {},
- "order": 72,
+ "order": 69,
"mode": 0,
"inputs": [
{
@@ -1992,9 +1900,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoLongCatAvatarExtendEmbeds",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd"
+ "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd",
+ "Node name for S&R": "WanVideoLongCatAvatarExtendEmbeds"
},
"widgets_values": [
93,
@@ -2019,7 +1927,7 @@
146
],
"flags": {},
- "order": 89,
+ "order": 86,
"mode": 0,
"inputs": [
{
@@ -2063,9 +1971,9 @@
}
],
"properties": {
- "Node name for S&R": "ImageBatchExtendWithOverlap",
"cnr_id": "comfyui-kjnodes",
- "ver": "16cbf238a74cac17082d6888bc8934899c850645"
+ "ver": "16cbf238a74cac17082d6888bc8934899c850645",
+ "Node name for S&R": "ImageBatchExtendWithOverlap"
},
"widgets_values": [
13,
@@ -2075,40 +1983,6 @@
"color": "#2a363b",
"bgcolor": "#3f5159"
},
- {
- "id": 418,
- "type": "GetNode",
- "pos": [
- 5063.620609727339,
- -1950.8726913782168
- ],
- "size": [
- 210,
- 60
- ],
- "flags": {
- "collapsed": true
- },
- "order": 26,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "MULTITALK_EMBEDS",
- "type": "MULTITALK_EMBEDS",
- "links": [
- 783
- ]
- }
- ],
- "title": "Get_audio_embeds",
- "properties": {},
- "widgets_values": [
- "audio_embeds"
- ],
- "color": "#323",
- "bgcolor": "#535"
- },
{
"id": 344,
"type": "GetImageSizeAndCount",
@@ -2121,7 +1995,7 @@
86
],
"flags": {},
- "order": 80,
+ "order": 77,
"mode": 0,
"inputs": [
{
@@ -2160,9 +2034,9 @@
}
],
"properties": {
- "Node name for S&R": "GetImageSizeAndCount",
"cnr_id": "comfyui-kjnodes",
- "ver": "16cbf238a74cac17082d6888bc8934899c850645"
+ "ver": "16cbf238a74cac17082d6888bc8934899c850645",
+ "Node name for S&R": "GetImageSizeAndCount"
},
"widgets_values": [],
"color": "#2a363b",
@@ -2182,7 +2056,7 @@
"flags": {
"collapsed": true
},
- "order": 83,
+ "order": 80,
"mode": 0,
"inputs": [
{
@@ -2221,9 +2095,9 @@
}
],
"properties": {
- "Node name for S&R": "GetImageRangeFromBatch",
"cnr_id": "comfyui-kjnodes",
- "ver": "16cbf238a74cac17082d6888bc8934899c850645"
+ "ver": "16cbf238a74cac17082d6888bc8934899c850645",
+ "Node name for S&R": "GetImageRangeFromBatch"
},
"widgets_values": [
-1,
@@ -2246,7 +2120,7 @@
"flags": {
"collapsed": true
},
- "order": 88,
+ "order": 85,
"mode": 0,
"inputs": [
{
@@ -2270,9 +2144,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoDecode",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490"
+ "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490",
+ "Node name for S&R": "WanVideoDecode"
},
"widgets_values": [
false,
@@ -2299,7 +2173,7 @@
"flags": {
"collapsed": true
},
- "order": 27,
+ "order": 24,
"mode": 0,
"inputs": [],
"outputs": [
@@ -2333,7 +2207,7 @@
"flags": {
"collapsed": true
},
- "order": 28,
+ "order": 25,
"mode": 0,
"inputs": [],
"outputs": [
@@ -2367,7 +2241,7 @@
"flags": {
"collapsed": true
},
- "order": 97,
+ "order": 94,
"mode": 0,
"inputs": [
{
@@ -2397,9 +2271,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoEncode",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490"
+ "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490",
+ "Node name for S&R": "WanVideoEncode"
},
"widgets_values": [
false,
@@ -2427,7 +2301,7 @@
"flags": {
"collapsed": true
},
- "order": 29,
+ "order": 26,
"mode": 0,
"inputs": [],
"outputs": [
@@ -2462,7 +2336,7 @@
"flags": {
"collapsed": true
},
- "order": 98,
+ "order": 95,
"mode": 0,
"inputs": [
{
@@ -2487,9 +2361,9 @@
}
],
"properties": {
- "Node name for S&R": "ReplaceVideoLatentFrames",
"cnr_id": "comfy-core",
- "ver": "0.5.0"
+ "ver": "0.5.0",
+ "Node name for S&R": "ReplaceVideoLatentFrames"
},
"widgets_values": [
0
@@ -2509,7 +2383,7 @@
"flags": {
"collapsed": true
},
- "order": 30,
+ "order": 27,
"mode": 0,
"inputs": [],
"outputs": [
@@ -2543,7 +2417,7 @@
"flags": {
"collapsed": true
},
- "order": 31,
+ "order": 28,
"mode": 0,
"inputs": [],
"outputs": [
@@ -2575,7 +2449,7 @@
"flags": {
"collapsed": true
},
- "order": 32,
+ "order": 29,
"mode": 0,
"inputs": [],
"outputs": [
@@ -2609,7 +2483,7 @@
"flags": {
"collapsed": true
},
- "order": 33,
+ "order": 30,
"mode": 0,
"inputs": [],
"outputs": [
@@ -2642,7 +2516,7 @@
26
],
"flags": {},
- "order": 93,
+ "order": 90,
"mode": 0,
"inputs": [
{
@@ -2680,7 +2554,7 @@
"flags": {
"collapsed": true
},
- "order": 34,
+ "order": 31,
"mode": 0,
"inputs": [],
"outputs": [
@@ -2712,7 +2586,7 @@
26
],
"flags": {},
- "order": 102,
+ "order": 99,
"mode": 0,
"inputs": [
{
@@ -2733,40 +2607,6 @@
"horizontal": false
}
},
- {
- "id": 459,
- "type": "GetNode",
- "pos": [
- 7859.880789998097,
- -1675.4559507379802
- ],
- "size": [
- 210,
- 34
- ],
- "flags": {
- "collapsed": true
- },
- "order": 35,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 835
- ]
- }
- ],
- "title": "Get_ref_latent",
- "properties": {},
- "widgets_values": [
- "ref_latent"
- ],
- "color": "#323",
- "bgcolor": "#535"
- },
{
"id": 460,
"type": "ImageBatchExtendWithOverlap",
@@ -2779,7 +2619,7 @@
146
],
"flags": {},
- "order": 100,
+ "order": 97,
"mode": 0,
"inputs": [
{
@@ -2823,9 +2663,9 @@
}
],
"properties": {
- "Node name for S&R": "ImageBatchExtendWithOverlap",
"cnr_id": "comfyui-kjnodes",
- "ver": "16cbf238a74cac17082d6888bc8934899c850645"
+ "ver": "16cbf238a74cac17082d6888bc8934899c850645",
+ "Node name for S&R": "ImageBatchExtendWithOverlap"
},
"widgets_values": [
13,
@@ -2835,132 +2675,6 @@
"color": "#2a363b",
"bgcolor": "#3f5159"
},
- {
- "id": 461,
- "type": "WanVideoLongCatAvatarExtendEmbeds",
- "pos": [
- 7854.07317149529,
- -1892.6690512715838
- ],
- "size": [
- 379.476171875,
- 238
- ],
- "flags": {},
- "order": 94,
- "mode": 0,
- "inputs": [
- {
- "name": "prev_latents",
- "type": "LATENT",
- "link": 845
- },
- {
- "name": "audio_embeds",
- "type": "MULTITALK_EMBEDS",
- "link": 834
- },
- {
- "name": "ref_latent",
- "shape": 7,
- "type": "LATENT",
- "link": 835
- },
- {
- "name": "samples",
- "shape": 7,
- "type": "LATENT",
- "link": null
- },
- {
- "name": "num_frames",
- "type": "INT",
- "widget": {
- "name": "num_frames"
- },
- "link": 836
- },
- {
- "name": "overlap",
- "type": "INT",
- "widget": {
- "name": "overlap"
- },
- "link": 837
- },
- {
- "name": "frames_processed",
- "type": "INT",
- "widget": {
- "name": "frames_processed"
- },
- "link": 838
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "links": [
- 826
- ]
- },
- {
- "name": "samples_slice",
- "type": "LATENT",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoLongCatAvatarExtendEmbeds",
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd"
- },
- "widgets_values": [
- 93,
- 13,
- 93,
- "pad_with_start",
- 10,
- 3
- ],
- "color": "#323",
- "bgcolor": "#535"
- },
- {
- "id": 462,
- "type": "GetNode",
- "pos": [
- 7852.090413215118,
- -1940.749920719971
- ],
- "size": [
- 210,
- 34
- ],
- "flags": {
- "collapsed": true
- },
- "order": 36,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "MULTITALK_EMBEDS",
- "type": "MULTITALK_EMBEDS",
- "links": [
- 834
- ]
- }
- ],
- "title": "Get_audio_embeds",
- "properties": {},
- "widgets_values": [
- "audio_embeds"
- ],
- "color": "#323",
- "bgcolor": "#535"
- },
{
"id": 463,
"type": "GetImageSizeAndCount",
@@ -2973,7 +2687,7 @@
86
],
"flags": {},
- "order": 92,
+ "order": 89,
"mode": 0,
"inputs": [
{
@@ -3012,9 +2726,9 @@
}
],
"properties": {
- "Node name for S&R": "GetImageSizeAndCount",
"cnr_id": "comfyui-kjnodes",
- "ver": "16cbf238a74cac17082d6888bc8934899c850645"
+ "ver": "16cbf238a74cac17082d6888bc8934899c850645",
+ "Node name for S&R": "GetImageSizeAndCount"
},
"widgets_values": [],
"color": "#2a363b",
@@ -3034,7 +2748,7 @@
"flags": {
"collapsed": true
},
- "order": 95,
+ "order": 92,
"mode": 0,
"inputs": [
{
@@ -3073,9 +2787,9 @@
}
],
"properties": {
- "Node name for S&R": "GetImageRangeFromBatch",
"cnr_id": "comfyui-kjnodes",
- "ver": "16cbf238a74cac17082d6888bc8934899c850645"
+ "ver": "16cbf238a74cac17082d6888bc8934899c850645",
+ "Node name for S&R": "GetImageRangeFromBatch"
},
"widgets_values": [
-1,
@@ -3098,7 +2812,7 @@
"flags": {
"collapsed": true
},
- "order": 99,
+ "order": 96,
"mode": 0,
"inputs": [
{
@@ -3122,9 +2836,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoDecode",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490"
+ "ver": "ae6fe0853e2d1ba0f1f47e086befdb089dc07490",
+ "Node name for S&R": "WanVideoDecode"
},
"widgets_values": [
false,
@@ -3151,7 +2865,7 @@
"flags": {
"collapsed": true
},
- "order": 37,
+ "order": 32,
"mode": 0,
"inputs": [],
"outputs": [
@@ -3183,7 +2897,7 @@
26
],
"flags": {},
- "order": 91,
+ "order": 88,
"mode": 0,
"inputs": [
{
@@ -3218,7 +2932,7 @@
26
],
"flags": {},
- "order": 86,
+ "order": 83,
"mode": 0,
"inputs": [
{
@@ -3253,7 +2967,7 @@
106
],
"flags": {},
- "order": 38,
+ "order": 33,
"mode": 0,
"inputs": [],
"outputs": [
@@ -3264,9 +2978,9 @@
}
],
"properties": {
- "Node name for S&R": "Wav2VecModelLoader",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "6fce0e2d3bb976b0006bc6d8e37e1f23460938ee"
+ "ver": "6fce0e2d3bb976b0006bc6d8e37e1f23460938ee",
+ "Node name for S&R": "Wav2VecModelLoader"
},
"widgets_values": [
"wav2vec2-chinese-base_fp16.safetensors",
@@ -3286,7 +3000,7 @@
106
],
"flags": {},
- "order": 39,
+ "order": 34,
"mode": 0,
"inputs": [],
"outputs": [
@@ -3299,9 +3013,9 @@
}
],
"properties": {
- "Node name for S&R": "DownloadAndLoadWav2VecModel",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0"
+ "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
+ "Node name for S&R": "DownloadAndLoadWav2VecModel"
},
"widgets_values": [
"TencentGameMate/chinese-wav2vec2-base",
@@ -3321,7 +3035,7 @@
125.51774597167969
],
"flags": {},
- "order": 40,
+ "order": 35,
"mode": 0,
"inputs": [],
"outputs": [],
@@ -3345,7 +3059,7 @@
58
],
"flags": {},
- "order": 41,
+ "order": 36,
"mode": 0,
"inputs": [],
"outputs": [
@@ -3358,9 +3072,9 @@
}
],
"properties": {
- "Node name for S&R": "MelBandRoFormerModelLoader",
"cnr_id": "ComfyUI-MelBandRoFormer",
- "ver": "b68d9077815387b64d596f8c39607052b95b6eba"
+ "ver": "b68d9077815387b64d596f8c39607052b95b6eba",
+ "Node name for S&R": "MelBandRoFormerModelLoader"
},
"widgets_values": [
"MelBandRoformer_fp32.safetensors"
@@ -3378,7 +3092,7 @@
91.6759033203125
],
"flags": {},
- "order": 42,
+ "order": 37,
"mode": 0,
"inputs": [],
"outputs": [],
@@ -3404,7 +3118,7 @@
"flags": {
"collapsed": true
},
- "order": 68,
+ "order": 65,
"mode": 0,
"inputs": [
{
@@ -3440,7 +3154,7 @@
212.22914465030635
],
"flags": {},
- "order": 43,
+ "order": 38,
"mode": 0,
"inputs": [],
"outputs": [],
@@ -3463,7 +3177,7 @@
58
],
"flags": {},
- "order": 44,
+ "order": 39,
"mode": 0,
"inputs": [],
"outputs": [
@@ -3477,6 +3191,8 @@
],
"title": "Overlap",
"properties": {
+ "cnr_id": "comfyui-kjnodes",
+ "ver": "79f529a84a8c20fe5dcdfa984c6be7a94102c014",
"Node name for S&R": "INTConstant"
},
"widgets_values": [
@@ -3499,7 +3215,7 @@
"flags": {
"collapsed": true
},
- "order": 74,
+ "order": 71,
"mode": 0,
"inputs": [
{
@@ -3541,7 +3257,7 @@
"flags": {
"collapsed": true
},
- "order": 73,
+ "order": 70,
"mode": 0,
"inputs": [
{
@@ -3577,7 +3293,7 @@
560.3785864245906
],
"flags": {},
- "order": 84,
+ "order": 81,
"mode": 0,
"inputs": [
{
@@ -3638,9 +3354,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoSamplerv2",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd"
+ "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd",
+ "Node name for S&R": "WanVideoSamplerv2"
},
"widgets_values": [
1,
@@ -3650,98 +3366,6 @@
false
]
},
- {
- "id": 346,
- "type": "WanVideoLongCatAvatarExtendEmbeds",
- "pos": [
- 5065.603368007511,
- -1902.7918219298297
- ],
- "size": [
- 379.476171875,
- 238
- ],
- "flags": {},
- "order": 82,
- "mode": 0,
- "inputs": [
- {
- "name": "prev_latents",
- "type": "LATENT",
- "link": 806
- },
- {
- "name": "audio_embeds",
- "type": "MULTITALK_EMBEDS",
- "link": 783
- },
- {
- "name": "ref_latent",
- "shape": 7,
- "type": "LATENT",
- "link": 775
- },
- {
- "name": "samples",
- "shape": 7,
- "type": "LATENT",
- "link": null
- },
- {
- "name": "num_frames",
- "type": "INT",
- "widget": {
- "name": "num_frames"
- },
- "link": 814
- },
- {
- "name": "overlap",
- "type": "INT",
- "widget": {
- "name": "overlap"
- },
- "link": 799
- },
- {
- "name": "frames_processed",
- "type": "INT",
- "widget": {
- "name": "frames_processed"
- },
- "link": 727
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "links": [
- 635
- ]
- },
- {
- "name": "samples_slice",
- "type": "LATENT",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoLongCatAvatarExtendEmbeds",
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd"
- },
- "widgets_values": [
- 93,
- 13,
- 93,
- "pad_with_start",
- 10,
- 3
- ],
- "color": "#323",
- "bgcolor": "#535"
- },
{
"id": 468,
"type": "GetNode",
@@ -3756,7 +3380,7 @@
"flags": {
"collapsed": true
},
- "order": 45,
+ "order": 40,
"mode": 0,
"inputs": [],
"outputs": [
@@ -3788,7 +3412,7 @@
"flags": {
"collapsed": true
},
- "order": 46,
+ "order": 41,
"mode": 0,
"inputs": [],
"outputs": [
@@ -3818,7 +3442,7 @@
560.3785864245906
],
"flags": {},
- "order": 96,
+ "order": 93,
"mode": 0,
"inputs": [
{
@@ -3878,9 +3502,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoSamplerv2",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd"
+ "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd",
+ "Node name for S&R": "WanVideoSamplerv2"
},
"widgets_values": [
1,
@@ -3890,58 +3514,6 @@
false
]
},
- {
- "id": 138,
- "type": "WanVideoLoraSelect",
- "pos": [
- 564.2077204363451,
- -2675.4893783617654
- ],
- "size": [
- 503.4073486328125,
- 200
- ],
- "flags": {},
- "order": 47,
- "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": [
- 848
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoLoraSelect",
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0"
- },
- "widgets_values": [
- "LongCat_distill_lora_rank128_bf16.safetensors",
- 1,
- false,
- false,
- "Metadata
| Metadata |
| format | pt |
| model_type | LongCat_distill_lora |
"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
{
"id": 453,
"type": "VHS_VideoCombine",
@@ -3954,7 +3526,7 @@
334
],
"flags": {},
- "order": 101,
+ "order": 98,
"mode": 0,
"inputs": [
{
@@ -3989,9 +3561,9 @@
}
],
"properties": {
- "Node name for S&R": "VHS_VideoCombine",
"cnr_id": "comfyui-videohelpersuite",
- "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
+ "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8",
+ "Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 16,
@@ -4028,10 +3600,10 @@
],
"size": [
991.5499877929688,
- 908.5096083420973
+ 334
],
"flags": {},
- "order": 90,
+ "order": 87,
"mode": 0,
"inputs": [
{
@@ -4066,9 +3638,9 @@
}
],
"properties": {
- "Node name for S&R": "VHS_VideoCombine",
"cnr_id": "comfyui-videohelpersuite",
- "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
+ "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8",
+ "Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 16,
@@ -4108,7 +3680,7 @@
326
],
"flags": {},
- "order": 71,
+ "order": 68,
"mode": 0,
"inputs": [
{
@@ -4169,9 +3741,9 @@
}
],
"properties": {
- "Node name for S&R": "MultiTalkWav2VecEmbeds",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "3d7801cee4c8e3106078dd9b9f146caee95069ba"
+ "ver": "3d7801cee4c8e3106078dd9b9f146caee95069ba",
+ "Node name for S&R": "MultiTalkWav2VecEmbeds"
},
"widgets_values": [
true,
@@ -4198,7 +3770,7 @@
142.90990081361315
],
"flags": {},
- "order": 48,
+ "order": 42,
"mode": 0,
"inputs": [],
"outputs": [],
@@ -4222,7 +3794,7 @@
250
],
"flags": {},
- "order": 49,
+ "order": 43,
"mode": 0,
"inputs": [],
"outputs": [
@@ -4233,9 +3805,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoTorchCompileSettings",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "f3614e6720744247f3211d60f7b9333f43572384"
+ "ver": "f3614e6720744247f3211d60f7b9333f43572384",
+ "Node name for S&R": "WanVideoTorchCompileSettings"
},
"widgets_values": [
"inductor",
@@ -4251,41 +3823,6 @@
"color": "#223",
"bgcolor": "#335"
},
- {
- "id": 238,
- "type": "CLIPVisionLoader",
- "pos": [
- 1468.7586642411059,
- -2311.9486286861097
- ],
- "size": [
- 270,
- 58
- ],
- "flags": {},
- "order": 50,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "CLIP_VISION",
- "type": "CLIP_VISION",
- "links": [
- 466
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPVisionLoader",
- "cnr_id": "comfy-core",
- "ver": "0.3.50"
- },
- "widgets_values": [
- "clip_vision_h.safetensors"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
{
"id": 134,
"type": "WanVideoBlockSwap",
@@ -4298,7 +3835,7 @@
202
],
"flags": {},
- "order": 51,
+ "order": 44,
"mode": 0,
"inputs": [],
"outputs": [
@@ -4311,9 +3848,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoBlockSwap",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0"
+ "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
+ "Node name for S&R": "WanVideoBlockSwap"
},
"widgets_values": [
25,
@@ -4339,7 +3876,7 @@
178.89092796458362
],
"flags": {},
- "order": 52,
+ "order": 45,
"mode": 0,
"inputs": [],
"outputs": [],
@@ -4363,7 +3900,7 @@
338
],
"flags": {},
- "order": 64,
+ "order": 62,
"mode": 0,
"inputs": [
{
@@ -4431,9 +3968,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoModelLoader",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0"
+ "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
+ "Node name for S&R": "WanVideoModelLoader"
},
"widgets_values": [
"LongCat/LongCat-Avatar_bf16.safetensors",
@@ -4458,7 +3995,7 @@
353.33726502245645
],
"flags": {},
- "order": 53,
+ "order": 46,
"mode": 0,
"inputs": [
{
@@ -4479,9 +4016,9 @@
}
],
"properties": {
- "Node name for S&R": "WanVideoSchedulerv2",
"cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd"
+ "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd",
+ "Node name for S&R": "WanVideoSchedulerv2"
},
"widgets_values": [
"longcat_distill_euler",
@@ -4489,8 +4026,7 @@
12,
0,
-1,
- false,
- "
"
+ false
]
},
{
@@ -4502,10 +4038,10 @@
],
"size": [
991.5499877929688,
- 908.5096083420973
+ 334
],
"flags": {},
- "order": 79,
+ "order": 76,
"mode": 0,
"inputs": [
{
@@ -4540,9 +4076,9 @@
}
],
"properties": {
- "Node name for S&R": "VHS_VideoCombine",
"cnr_id": "comfyui-videohelpersuite",
- "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
+ "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8",
+ "Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 16,
@@ -4569,6 +4105,377 @@
}
}
}
+ },
+ {
+ "id": 346,
+ "type": "WanVideoLongCatAvatarExtendEmbeds",
+ "pos": [
+ 5071.598514635023,
+ -1893.1993348384901
+ ],
+ "size": [
+ 379.476171875,
+ 238
+ ],
+ "flags": {},
+ "order": 79,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "prev_latents",
+ "type": "LATENT",
+ "link": 806
+ },
+ {
+ "name": "audio_embeds",
+ "type": "MULTITALK_EMBEDS",
+ "link": 783
+ },
+ {
+ "name": "ref_latent",
+ "shape": 7,
+ "type": "LATENT",
+ "link": 775
+ },
+ {
+ "name": "samples",
+ "shape": 7,
+ "type": "LATENT",
+ "link": null
+ },
+ {
+ "name": "num_frames",
+ "type": "INT",
+ "widget": {
+ "name": "num_frames"
+ },
+ "link": 814
+ },
+ {
+ "name": "overlap",
+ "type": "INT",
+ "widget": {
+ "name": "overlap"
+ },
+ "link": 799
+ },
+ {
+ "name": "frames_processed",
+ "type": "INT",
+ "widget": {
+ "name": "frames_processed"
+ },
+ "link": 727
+ }
+ ],
+ "outputs": [
+ {
+ "name": "image_embeds",
+ "type": "WANVIDIMAGE_EMBEDS",
+ "links": [
+ 635
+ ]
+ },
+ {
+ "name": "samples_slice",
+ "type": "LATENT",
+ "links": null
+ }
+ ],
+ "properties": {
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd",
+ "Node name for S&R": "WanVideoLongCatAvatarExtendEmbeds"
+ },
+ "widgets_values": [
+ 93,
+ 13,
+ 93,
+ "pad_with_start",
+ 10,
+ 3
+ ],
+ "color": "#323",
+ "bgcolor": "#535"
+ },
+ {
+ "id": 461,
+ "type": "WanVideoLongCatAvatarExtendEmbeds",
+ "pos": [
+ 7854.073171495291,
+ -1890.2709706651597
+ ],
+ "size": [
+ 379.476171875,
+ 238
+ ],
+ "flags": {},
+ "order": 91,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "prev_latents",
+ "type": "LATENT",
+ "link": 845
+ },
+ {
+ "name": "audio_embeds",
+ "type": "MULTITALK_EMBEDS",
+ "link": 834
+ },
+ {
+ "name": "ref_latent",
+ "shape": 7,
+ "type": "LATENT",
+ "link": 835
+ },
+ {
+ "name": "samples",
+ "shape": 7,
+ "type": "LATENT",
+ "link": null
+ },
+ {
+ "name": "num_frames",
+ "type": "INT",
+ "widget": {
+ "name": "num_frames"
+ },
+ "link": 836
+ },
+ {
+ "name": "overlap",
+ "type": "INT",
+ "widget": {
+ "name": "overlap"
+ },
+ "link": 837
+ },
+ {
+ "name": "frames_processed",
+ "type": "INT",
+ "widget": {
+ "name": "frames_processed"
+ },
+ "link": 838
+ }
+ ],
+ "outputs": [
+ {
+ "name": "image_embeds",
+ "type": "WANVIDIMAGE_EMBEDS",
+ "links": [
+ 826
+ ]
+ },
+ {
+ "name": "samples_slice",
+ "type": "LATENT",
+ "links": null
+ }
+ ],
+ "properties": {
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "93f7af6dc8559e2f6815caa67fd0982e4d8940dd",
+ "Node name for S&R": "WanVideoLongCatAvatarExtendEmbeds"
+ },
+ "widgets_values": [
+ 93,
+ 13,
+ 93,
+ "pad_with_start",
+ 10,
+ 3
+ ],
+ "color": "#323",
+ "bgcolor": "#535"
+ },
+ {
+ "id": 462,
+ "type": "GetNode",
+ "pos": [
+ 7854.4886035986365,
+ -1994.7075576927305
+ ],
+ "size": [
+ 210,
+ 34
+ ],
+ "flags": {
+ "collapsed": true
+ },
+ "order": 47,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "MULTITALK_EMBEDS",
+ "type": "MULTITALK_EMBEDS",
+ "links": [
+ 834
+ ]
+ }
+ ],
+ "title": "Get_audio_embeds",
+ "properties": {},
+ "widgets_values": [
+ "audio_embeds"
+ ],
+ "color": "#323",
+ "bgcolor": "#535"
+ },
+ {
+ "id": 459,
+ "type": "GetNode",
+ "pos": [
+ 7856.283614199908,
+ -1940.447919500377
+ ],
+ "size": [
+ 210,
+ 34
+ ],
+ "flags": {
+ "collapsed": true
+ },
+ "order": 48,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "LATENT",
+ "type": "LATENT",
+ "links": [
+ 835
+ ]
+ }
+ ],
+ "title": "Get_ref_latent",
+ "properties": {},
+ "widgets_values": [
+ "ref_latent"
+ ],
+ "color": "#323",
+ "bgcolor": "#535"
+ },
+ {
+ "id": 418,
+ "type": "GetNode",
+ "pos": [
+ 5071.548239647001,
+ -1978.6194414594738
+ ],
+ "size": [
+ 210,
+ 60
+ ],
+ "flags": {
+ "collapsed": true
+ },
+ "order": 49,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "MULTITALK_EMBEDS",
+ "type": "MULTITALK_EMBEDS",
+ "links": [
+ 783
+ ]
+ }
+ ],
+ "title": "Get_audio_embeds",
+ "properties": {},
+ "widgets_values": [
+ "audio_embeds"
+ ],
+ "color": "#323",
+ "bgcolor": "#535"
+ },
+ {
+ "id": 413,
+ "type": "GetNode",
+ "pos": [
+ 5072.818279856921,
+ -1936.9548335806312
+ ],
+ "size": [
+ 210,
+ 60
+ ],
+ "flags": {
+ "collapsed": true
+ },
+ "order": 50,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [
+ {
+ "name": "LATENT",
+ "type": "LATENT",
+ "links": [
+ 775
+ ]
+ }
+ ],
+ "title": "Get_ref_latent",
+ "properties": {},
+ "widgets_values": [
+ "ref_latent"
+ ],
+ "color": "#323",
+ "bgcolor": "#535"
+ },
+ {
+ "id": 138,
+ "type": "WanVideoLoraSelect",
+ "pos": [
+ 564.2077204363451,
+ -2675.4893783617654
+ ],
+ "size": [
+ 503.4073486328125,
+ 200
+ ],
+ "flags": {},
+ "order": 51,
+ "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": [
+ 848
+ ]
+ }
+ ],
+ "properties": {
+ "cnr_id": "ComfyUI-WanVideoWrapper",
+ "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
+ "Node name for S&R": "WanVideoLoraSelect"
+ },
+ "widgets_values": [
+ "LongCat_distill_lora_rank128_bf16.safetensors",
+ 0.9,
+ false,
+ false
+ ],
+ "color": "#223",
+ "bgcolor": "#335"
}
],
"links": [
@@ -4620,14 +4527,6 @@
0,
"*"
],
- [
- 466,
- 238,
- 0,
- 264,
- 0,
- "*"
- ],
[
494,
283,
@@ -5403,13 +5302,13 @@
"config": {},
"extra": {
"ds": {
- "scale": 0.3138428376721308,
+ "scale": 0.5054470284993439,
"offset": [
- -367.5989031130344,
- 3444.003601779404
+ -329.7995482986256,
+ 2961.065863628347
]
},
- "frontendVersion": "1.36.2",
+ "frontendVersion": "1.36.7",
"workflowRendererVersion": "LG",
"node_versions": {
"comfy-core": "0.5.1",
From 4b709a7a04e67b2332dad017b5eee18514c68182 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 15:44:08 +0200
Subject: [PATCH 11/22] Cleanup example_workflows folder some
---
...nvideo_2_1_14B_FLF2V_720P_example_02.json} | 0
..._1_14B_Fun_control_camera_example_01.json} | 0
...video_2_1_14B_Fun_control_example_01.json} | 0
... => wanvideo_2_1_14B_HuMo_example_01.json} | 0
...deo_2_1_14B_I2V_ATI_track_testing_01.json} | 0
...1_14B_I2V_FantasyPortrait_example_01.json} | 0
..._1_14B_I2V_FantasyTalking_example_01.json} | 0
..._2_1_14B_I2V_InfiniteTalk_example_03.json} | 0
...n => wanvideo_2_1_14B_I2V_example_03.json} | 0
...ideo_2_1_14B_MTV_Crafter_example_WIP.json} | 0
..._2_1_14B_MoCha_replace_subject_KJ_02.json} | 0
...AllAnimation_pose_control_example_01.json} | 0
..._1_14B_SCAIL_pose_control_example_01.json} | 0
..._1_14B_Stand-In_reference_example_01.json} | 0
...SteadyDancer_pose_control_example_01.json} | 0
...ideo_2_1_14B_T2V_14B_lynx_example_01.json} | 0
...n => wanvideo_2_1_14B_T2V_example_03.json} | 0
..._2_1_14B_V2V_InfiniteTalk_example_02.json} | 0
...video_2_1_14B_WanMove_I2V_example_01.json} | 0
...1_14B_phantom_subject2vid_example_02.json} | 0
...wanvideo_2_1_14B_pusa_I2V_example_01.json} | 0
...video_2_1_14B_skyreels_a2_example_01.json} | 0
...ffusion_forcing_extension_example_01.json} | 0
...eo_2_2_Fun_control_camera_example_01.json} | 0
... wanvideo_2_2_Fun_control_example_03.json} | 0
...ideo_2_2_I2V_A14B_TimeToMove_example.json} | 0
...=> wanvideo_2_2_I2V_A14B_example_WIP.json} | 0
.../wanvideo_flowedit_I2V_example_01.json | 1965 ---------------
.../wanvideo_long_T2V_example_01.json | 780 ------
...anvideo_mocha_replacement_original_01.json | 2138 -----------------
.../wanvideo_multitalk_test_02.json | 1389 -----------
...deo_multitalk_test_context_windows_01.json | 1891 ---------------
.../wanvideo_vid2vid_example_01.json | 1044 --------
33 files changed, 9207 deletions(-)
rename example_workflows/{wanvideo_FLF2V_720P_example_02.json => wanvideo_2_1_14B_FLF2V_720P_example_02.json} (100%)
rename example_workflows/{wanvideo_Fun_control_camera_example_01.json => wanvideo_2_1_14B_Fun_control_camera_example_01.json} (100%)
rename example_workflows/{wanvideo_Fun_control_example_01.json => wanvideo_2_1_14B_Fun_control_example_01.json} (100%)
rename example_workflows/{wanvideo_HuMo_example_01.json => wanvideo_2_1_14B_HuMo_example_01.json} (100%)
rename example_workflows/{wanvideo_ATI_testing_01.json => wanvideo_2_1_14B_I2V_ATI_track_testing_01.json} (100%)
rename example_workflows/{wanvideo_2_1_I2V_FantasyPortrait_example_01.json => wanvideo_2_1_14B_I2V_FantasyPortrait_example_01.json} (100%)
rename example_workflows/{wanvideo_I2V_FantasyTalking_example_01.json => wanvideo_2_1_14B_I2V_FantasyTalking_example_01.json} (100%)
rename example_workflows/{wanvideo_I2V_InfiniteTalk_example_03.json => wanvideo_2_1_14B_I2V_InfiniteTalk_example_03.json} (100%)
rename example_workflows/{wanvideo_480p_I2V_example_03.json => wanvideo_2_1_14B_I2V_example_03.json} (100%)
rename example_workflows/{wanvideo_MTV_Crafter_example_WIP.json => wanvideo_2_1_14B_MTV_Crafter_example_WIP.json} (100%)
rename example_workflows/{wanvideo_MoCha_replace_subject_KJ_02.json => wanvideo_2_1_14B_MoCha_replace_subject_KJ_02.json} (100%)
rename example_workflows/{Wan21_OneToAllAnimation_example_01.json => wanvideo_2_1_14B_OneToAllAnimation_pose_control_example_01.json} (100%)
rename example_workflows/{wanvideo_SCAIL_pose_control_example_01.json => wanvideo_2_1_14B_SCAIL_pose_control_example_01.json} (100%)
rename example_workflows/{wanvideo_Stand-In_reference_example_01.json => wanvideo_2_1_14B_Stand-In_reference_example_01.json} (100%)
rename example_workflows/{wanvideo_SteadyDancer_example_01.json => wanvideo_2_1_14B_SteadyDancer_pose_control_example_01.json} (100%)
rename example_workflows/{wanvideo_T2V_14B_lynx_example_01.json => wanvideo_2_1_14B_T2V_14B_lynx_example_01.json} (100%)
rename example_workflows/{wanvideo_T2V_example_03.json => wanvideo_2_1_14B_T2V_example_03.json} (100%)
rename example_workflows/{wanvideo_InfiniteTalk_V2V_example_02.json => wanvideo_2_1_14B_V2V_InfiniteTalk_example_02.json} (100%)
rename example_workflows/{wanvideo_WanMove_I2V_example_01.json => wanvideo_2_1_14B_WanMove_I2V_example_01.json} (100%)
rename example_workflows/{wanvideo_phantom_subject2vid_example_02.json => wanvideo_2_1_14B_phantom_subject2vid_example_02.json} (100%)
rename example_workflows/{wanvideo_14B_pusa_I2V_example_01.json => wanvideo_2_1_14B_pusa_I2V_example_01.json} (100%)
rename example_workflows/{wanvideo_skyreels_a2_example_01.json => wanvideo_2_1_14B_skyreels_a2_example_01.json} (100%)
rename example_workflows/{wanvideo_skyreels_diffusion_forcing_extension_example_01.json => wanvideo_2_1_14B_skyreels_diffusion_forcing_extension_example_01.json} (100%)
rename example_workflows/{wanvideo_Fun2_2_control_camera_example_01.json => wanvideo_2_2_Fun_control_camera_example_01.json} (100%)
rename example_workflows/{wanvideo_Fun_2_2_control_example_03.json => wanvideo_2_2_Fun_control_example_03.json} (100%)
rename example_workflows/{wanvideo2_2_I2V_A14B_TimeToMove_example.json => wanvideo_2_2_I2V_A14B_TimeToMove_example.json} (100%)
rename example_workflows/{wanvideo2_2_I2V_A14B_example_WIP.json => wanvideo_2_2_I2V_A14B_example_WIP.json} (100%)
delete mode 100644 example_workflows/wanvideo_flowedit_I2V_example_01.json
delete mode 100644 example_workflows/wanvideo_long_T2V_example_01.json
delete mode 100644 example_workflows/wanvideo_mocha_replacement_original_01.json
delete mode 100644 example_workflows/wanvideo_multitalk_test_02.json
delete mode 100644 example_workflows/wanvideo_multitalk_test_context_windows_01.json
delete mode 100644 example_workflows/wanvideo_vid2vid_example_01.json
diff --git a/example_workflows/wanvideo_FLF2V_720P_example_02.json b/example_workflows/wanvideo_2_1_14B_FLF2V_720P_example_02.json
similarity index 100%
rename from example_workflows/wanvideo_FLF2V_720P_example_02.json
rename to example_workflows/wanvideo_2_1_14B_FLF2V_720P_example_02.json
diff --git a/example_workflows/wanvideo_Fun_control_camera_example_01.json b/example_workflows/wanvideo_2_1_14B_Fun_control_camera_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_Fun_control_camera_example_01.json
rename to example_workflows/wanvideo_2_1_14B_Fun_control_camera_example_01.json
diff --git a/example_workflows/wanvideo_Fun_control_example_01.json b/example_workflows/wanvideo_2_1_14B_Fun_control_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_Fun_control_example_01.json
rename to example_workflows/wanvideo_2_1_14B_Fun_control_example_01.json
diff --git a/example_workflows/wanvideo_HuMo_example_01.json b/example_workflows/wanvideo_2_1_14B_HuMo_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_HuMo_example_01.json
rename to example_workflows/wanvideo_2_1_14B_HuMo_example_01.json
diff --git a/example_workflows/wanvideo_ATI_testing_01.json b/example_workflows/wanvideo_2_1_14B_I2V_ATI_track_testing_01.json
similarity index 100%
rename from example_workflows/wanvideo_ATI_testing_01.json
rename to example_workflows/wanvideo_2_1_14B_I2V_ATI_track_testing_01.json
diff --git a/example_workflows/wanvideo_2_1_I2V_FantasyPortrait_example_01.json b/example_workflows/wanvideo_2_1_14B_I2V_FantasyPortrait_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_2_1_I2V_FantasyPortrait_example_01.json
rename to example_workflows/wanvideo_2_1_14B_I2V_FantasyPortrait_example_01.json
diff --git a/example_workflows/wanvideo_I2V_FantasyTalking_example_01.json b/example_workflows/wanvideo_2_1_14B_I2V_FantasyTalking_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_I2V_FantasyTalking_example_01.json
rename to example_workflows/wanvideo_2_1_14B_I2V_FantasyTalking_example_01.json
diff --git a/example_workflows/wanvideo_I2V_InfiniteTalk_example_03.json b/example_workflows/wanvideo_2_1_14B_I2V_InfiniteTalk_example_03.json
similarity index 100%
rename from example_workflows/wanvideo_I2V_InfiniteTalk_example_03.json
rename to example_workflows/wanvideo_2_1_14B_I2V_InfiniteTalk_example_03.json
diff --git a/example_workflows/wanvideo_480p_I2V_example_03.json b/example_workflows/wanvideo_2_1_14B_I2V_example_03.json
similarity index 100%
rename from example_workflows/wanvideo_480p_I2V_example_03.json
rename to example_workflows/wanvideo_2_1_14B_I2V_example_03.json
diff --git a/example_workflows/wanvideo_MTV_Crafter_example_WIP.json b/example_workflows/wanvideo_2_1_14B_MTV_Crafter_example_WIP.json
similarity index 100%
rename from example_workflows/wanvideo_MTV_Crafter_example_WIP.json
rename to example_workflows/wanvideo_2_1_14B_MTV_Crafter_example_WIP.json
diff --git a/example_workflows/wanvideo_MoCha_replace_subject_KJ_02.json b/example_workflows/wanvideo_2_1_14B_MoCha_replace_subject_KJ_02.json
similarity index 100%
rename from example_workflows/wanvideo_MoCha_replace_subject_KJ_02.json
rename to example_workflows/wanvideo_2_1_14B_MoCha_replace_subject_KJ_02.json
diff --git a/example_workflows/Wan21_OneToAllAnimation_example_01.json b/example_workflows/wanvideo_2_1_14B_OneToAllAnimation_pose_control_example_01.json
similarity index 100%
rename from example_workflows/Wan21_OneToAllAnimation_example_01.json
rename to example_workflows/wanvideo_2_1_14B_OneToAllAnimation_pose_control_example_01.json
diff --git a/example_workflows/wanvideo_SCAIL_pose_control_example_01.json b/example_workflows/wanvideo_2_1_14B_SCAIL_pose_control_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_SCAIL_pose_control_example_01.json
rename to example_workflows/wanvideo_2_1_14B_SCAIL_pose_control_example_01.json
diff --git a/example_workflows/wanvideo_Stand-In_reference_example_01.json b/example_workflows/wanvideo_2_1_14B_Stand-In_reference_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_Stand-In_reference_example_01.json
rename to example_workflows/wanvideo_2_1_14B_Stand-In_reference_example_01.json
diff --git a/example_workflows/wanvideo_SteadyDancer_example_01.json b/example_workflows/wanvideo_2_1_14B_SteadyDancer_pose_control_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_SteadyDancer_example_01.json
rename to example_workflows/wanvideo_2_1_14B_SteadyDancer_pose_control_example_01.json
diff --git a/example_workflows/wanvideo_T2V_14B_lynx_example_01.json b/example_workflows/wanvideo_2_1_14B_T2V_14B_lynx_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_T2V_14B_lynx_example_01.json
rename to example_workflows/wanvideo_2_1_14B_T2V_14B_lynx_example_01.json
diff --git a/example_workflows/wanvideo_T2V_example_03.json b/example_workflows/wanvideo_2_1_14B_T2V_example_03.json
similarity index 100%
rename from example_workflows/wanvideo_T2V_example_03.json
rename to example_workflows/wanvideo_2_1_14B_T2V_example_03.json
diff --git a/example_workflows/wanvideo_InfiniteTalk_V2V_example_02.json b/example_workflows/wanvideo_2_1_14B_V2V_InfiniteTalk_example_02.json
similarity index 100%
rename from example_workflows/wanvideo_InfiniteTalk_V2V_example_02.json
rename to example_workflows/wanvideo_2_1_14B_V2V_InfiniteTalk_example_02.json
diff --git a/example_workflows/wanvideo_WanMove_I2V_example_01.json b/example_workflows/wanvideo_2_1_14B_WanMove_I2V_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_WanMove_I2V_example_01.json
rename to example_workflows/wanvideo_2_1_14B_WanMove_I2V_example_01.json
diff --git a/example_workflows/wanvideo_phantom_subject2vid_example_02.json b/example_workflows/wanvideo_2_1_14B_phantom_subject2vid_example_02.json
similarity index 100%
rename from example_workflows/wanvideo_phantom_subject2vid_example_02.json
rename to example_workflows/wanvideo_2_1_14B_phantom_subject2vid_example_02.json
diff --git a/example_workflows/wanvideo_14B_pusa_I2V_example_01.json b/example_workflows/wanvideo_2_1_14B_pusa_I2V_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_14B_pusa_I2V_example_01.json
rename to example_workflows/wanvideo_2_1_14B_pusa_I2V_example_01.json
diff --git a/example_workflows/wanvideo_skyreels_a2_example_01.json b/example_workflows/wanvideo_2_1_14B_skyreels_a2_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_skyreels_a2_example_01.json
rename to example_workflows/wanvideo_2_1_14B_skyreels_a2_example_01.json
diff --git a/example_workflows/wanvideo_skyreels_diffusion_forcing_extension_example_01.json b/example_workflows/wanvideo_2_1_14B_skyreels_diffusion_forcing_extension_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_skyreels_diffusion_forcing_extension_example_01.json
rename to example_workflows/wanvideo_2_1_14B_skyreels_diffusion_forcing_extension_example_01.json
diff --git a/example_workflows/wanvideo_Fun2_2_control_camera_example_01.json b/example_workflows/wanvideo_2_2_Fun_control_camera_example_01.json
similarity index 100%
rename from example_workflows/wanvideo_Fun2_2_control_camera_example_01.json
rename to example_workflows/wanvideo_2_2_Fun_control_camera_example_01.json
diff --git a/example_workflows/wanvideo_Fun_2_2_control_example_03.json b/example_workflows/wanvideo_2_2_Fun_control_example_03.json
similarity index 100%
rename from example_workflows/wanvideo_Fun_2_2_control_example_03.json
rename to example_workflows/wanvideo_2_2_Fun_control_example_03.json
diff --git a/example_workflows/wanvideo2_2_I2V_A14B_TimeToMove_example.json b/example_workflows/wanvideo_2_2_I2V_A14B_TimeToMove_example.json
similarity index 100%
rename from example_workflows/wanvideo2_2_I2V_A14B_TimeToMove_example.json
rename to example_workflows/wanvideo_2_2_I2V_A14B_TimeToMove_example.json
diff --git a/example_workflows/wanvideo2_2_I2V_A14B_example_WIP.json b/example_workflows/wanvideo_2_2_I2V_A14B_example_WIP.json
similarity index 100%
rename from example_workflows/wanvideo2_2_I2V_A14B_example_WIP.json
rename to example_workflows/wanvideo_2_2_I2V_A14B_example_WIP.json
diff --git a/example_workflows/wanvideo_flowedit_I2V_example_01.json b/example_workflows/wanvideo_flowedit_I2V_example_01.json
deleted file mode 100644
index 18f16af..0000000
--- a/example_workflows/wanvideo_flowedit_I2V_example_01.json
+++ /dev/null
@@ -1,1965 +0,0 @@
-{
- "last_node_id": 73,
- "last_link_id": 92,
- "nodes": [
- {
- "id": 46,
- "type": "WanVideoTextEmbedBridge",
- "pos": [
- -947.5358276367188,
- -63.66567611694336
- ],
- "size": [
- 315,
- 46
- ],
- "flags": {},
- "order": 25,
- "mode": 2,
- "inputs": [
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 54
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 55
- }
- ],
- "outputs": [
- {
- "name": "text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoTextEmbedBridge"
- },
- "widgets_values": []
- },
- {
- "id": 50,
- "type": "CLIPTextEncode",
- "pos": [
- -1397.5355224609375,
- 196.33407592773438
- ],
- "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"
- },
- "widgets_values": [
- "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走"
- ]
- },
- {
- "id": 48,
- "type": "CLIPLoader",
- "pos": [
- -1757.53515625,
- -53.66567611694336
- ],
- "size": [
- 315,
- 98.00003051757812
- ],
- "flags": {},
- "order": 0,
- "mode": 2,
- "inputs": [],
- "outputs": [
- {
- "name": "CLIP",
- "type": "CLIP",
- "slot_index": 0,
- "links": [
- 52,
- 53
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPLoader"
- },
- "widgets_values": [
- "umt5_xxl_fp16.safetensors",
- "wan",
- "default"
- ]
- },
- {
- "id": 49,
- "type": "CLIPTextEncode",
- "pos": [
- -1397.5355224609375,
- -53.66567611694336
- ],
- "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"
- },
- "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"
- ]
- },
- {
- "id": 42,
- "type": "Note",
- "pos": [
- -580,
- -760
- ],
- "size": [
- 314.96246337890625,
- 152.77333068847656
- ],
- "flags": {},
- "order": 1,
- "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.\n\nAlternatively there's option to use VRAM management introduced in DiffSynt-Studios. This is usually slower, but saves even more VRAM compared to BlockSwap"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 45,
- "type": "WanVideoVRAMManagement",
- "pos": [
- -210,
- -580
- ],
- "size": [
- 315,
- 58
- ],
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "vram_management_args",
- "type": "VRAM_MANAGEMENTARGS",
- "links": []
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoVRAMManagement"
- },
- "widgets_values": [
- 1
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 36,
- "type": "Note",
- "pos": [
- 160,
- -1010
- ],
- "size": [
- 374.3061828613281,
- 171.9547576904297
- ],
- "flags": {},
- "order": 3,
- "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": 33,
- "type": "Note",
- "pos": [
- 170,
- -1150
- ],
- "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": 51,
- "type": "Note",
- "pos": [
- -1727.53515625,
- -223.66603088378906
- ],
- "size": [
- 253.16725158691406,
- 88
- ],
- "flags": {},
- "order": 5,
- "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": 60,
- "type": "Note",
- "pos": [
- -432.5627136230469,
- -224.5513458251953
- ],
- "size": [
- 253.16725158691406,
- 88
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "You can use either the original clip vision or the normal comfyui clip vision loader, they are the same model in the end."
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 59,
- "type": "CLIPVisionLoader",
- "pos": [
- -158.17127990722656,
- -210.2847442626953
- ],
- "size": [
- 315,
- 58
- ],
- "flags": {},
- "order": 7,
- "mode": 2,
- "inputs": [],
- "outputs": [
- {
- "name": "CLIP_VISION",
- "type": "CLIP_VISION",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPVisionLoader"
- },
- "widgets_values": [
- "clip_vision_h.safetensors"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 11,
- "type": "LoadWanVideoT5TextEncoder",
- "pos": [
- 161.7229461669922,
- -501.2225036621094
- ],
- "size": [
- 377.1661376953125,
- 130
- ],
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "wan_t5_model",
- "type": "WANTEXTENCODER",
- "slot_index": 0,
- "links": [
- 15,
- 69
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "LoadWanVideoT5TextEncoder"
- },
- "widgets_values": [
- "umt5-xxl-enc-bf16.safetensors",
- "bf16",
- "offload_device",
- "disabled"
- ],
- "color": "#332922",
- "bgcolor": "#593930"
- },
- {
- "id": 44,
- "type": "Note",
- "pos": [
- -620.9041137695312,
- -1049.732421875
- ],
- "size": [
- 303.0501403808594,
- 88
- ],
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "If you have Triton installed, connect this for ~30% speed increase"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 39,
- "type": "WanVideoBlockSwap",
- "pos": [
- -210,
- -760
- ],
- "size": [
- 315,
- 130
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "block_swap_args",
- "type": "BLOCKSWAPARGS",
- "slot_index": 0,
- "links": []
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoBlockSwap"
- },
- "widgets_values": [
- 20,
- false,
- false,
- true
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 56,
- "type": "LoadWanVideoClipTextEncoder",
- "pos": [
- -357.8293762207031,
- -83.7756118774414
- ],
- "size": [
- 510.6601257324219,
- 106
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "wan_clip_vision",
- "type": "CLIP_VISION",
- "slot_index": 0,
- "links": [
- 58,
- 82
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "LoadWanVideoClipTextEncoder"
- },
- "widgets_values": [
- "open-clip-xlm-roberta-large-vit-huge-14_visual_fp32.safetensors",
- "fp16",
- "offload_device"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 35,
- "type": "WanVideoTorchCompileSettings",
- "pos": [
- -276.8500671386719,
- -1050.6326904296875
- ],
- "size": [
- 390.5999755859375,
- 178
- ],
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "torch_compile_args",
- "type": "WANCOMPILEARGS",
- "slot_index": 0,
- "links": [
- 75
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoTorchCompileSettings"
- },
- "widgets_values": [
- "inductor",
- false,
- "default",
- false,
- 64,
- true
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 66,
- "type": "WanVideoTextEncode",
- "pos": [
- 153.09332275390625,
- 872.6924438476562
- ],
- "size": [
- 420.30511474609375,
- 261.5306701660156
- ],
- "flags": {},
- "order": 21,
- "mode": 0,
- "inputs": [
- {
- "name": "t5",
- "type": "WANTEXTENCODER",
- "link": 69
- },
- {
- "name": "model_to_offload",
- "shape": 7,
- "type": "WANVIDEOMODEL",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "slot_index": 0,
- "links": [
- 70
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoTextEncode"
- },
- "widgets_values": [
- "video of a wolf",
- "bad quality, cartoon, painting",
- true
- ],
- "color": "#332922",
- "bgcolor": "#593930"
- },
- {
- "id": 16,
- "type": "WanVideoTextEncode",
- "pos": [
- 157.61514282226562,
- 245.40008544921875
- ],
- "size": [
- 420.30511474609375,
- 261.5306701660156
- ],
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "t5",
- "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"
- },
- "widgets_values": [
- "cybernetic wolf is turning it's head",
- "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
- true
- ],
- "color": "#332922",
- "bgcolor": "#593930"
- },
- {
- "id": 65,
- "type": "VHS_LoadVideo",
- "pos": [
- -336.5810241699219,
- 681.5027465820312
- ],
- "size": [
- 392.0638732910156,
- 696.0638427734375
- ],
- "flags": {},
- "order": 13,
- "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": [
- 66,
- 71
- ]
- },
- {
- "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": 58,
- "type": "LoadImage",
- "pos": [
- -347.4864501953125,
- 119.20101928710938
- ],
- "size": [
- 413.10479736328125,
- 498.3180847167969
- ],
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 59,
- 77
- ]
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "LoadImage"
- },
- "widgets_values": [
- "hunhyuanwolf.png",
- "image",
- ""
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 30,
- "type": "VHS_VideoCombine",
- "pos": [
- 1684.1597900390625,
- -394.2595520019531
- ],
- "size": [
- 904.313232421875,
- 1232.313232421875
- ],
- "flags": {},
- "order": 32,
- "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"
- },
- "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_00432.mp4",
- "subfolder": "",
- "type": "output",
- "format": "video/h264-mp4",
- "frame_rate": 16,
- "workflow": "WanVideoWrapper_I2V_00432.png",
- "fullpath": "N:\\AI\\ComfyUI\\output\\WanVideoWrapper_I2V_00432.mp4"
- }
- }
- }
- },
- {
- "id": 68,
- "type": "ImageConcatMulti",
- "pos": [
- 2073.08251953125,
- -643.741455078125
- ],
- "size": [
- 315,
- 170
- ],
- "flags": {},
- "order": 33,
- "mode": 0,
- "inputs": [
- {
- "name": "image_1",
- "type": "IMAGE",
- "link": 78
- },
- {
- "name": "image_2",
- "type": "IMAGE",
- "link": 77
- },
- {
- "name": "image_3",
- "type": "IMAGE",
- "link": 79
- }
- ],
- "outputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 80
- ]
- }
- ],
- "properties": {},
- "widgets_values": [
- 3,
- "right",
- true,
- null
- ]
- },
- {
- "id": 67,
- "type": "GetImageSizeAndCount",
- "pos": [
- 136.5249786376953,
- 714.924072265625
- ],
- "size": [
- 277.20001220703125,
- 86
- ],
- "flags": {},
- "order": 23,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 71
- }
- ],
- "outputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 78,
- 81
- ]
- },
- {
- "label": "512 width",
- "name": "width",
- "type": "INT",
- "slot_index": 1,
- "links": [
- 72,
- 85
- ]
- },
- {
- "label": "512 height",
- "name": "height",
- "type": "INT",
- "slot_index": 2,
- "links": [
- 73,
- 86
- ]
- },
- {
- "label": "53 count",
- "name": "count",
- "type": "INT",
- "slot_index": 3,
- "links": [
- 74,
- 87
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "GetImageSizeAndCount"
- },
- "widgets_values": []
- },
- {
- "id": 57,
- "type": "WanVideoImageClipEncode",
- "pos": [
- 287.3013000488281,
- -147.04237365722656
- ],
- "size": [
- 310.4956359863281,
- 326
- ],
- "flags": {},
- "order": 28,
- "mode": 0,
- "inputs": [
- {
- "name": "clip_vision",
- "type": "CLIP_VISION",
- "link": 58
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 59
- },
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 63
- },
- {
- "name": "generation_width",
- "type": "INT",
- "widget": {
- "name": "generation_width"
- },
- "link": 72
- },
- {
- "name": "generation_height",
- "type": "INT",
- "widget": {
- "name": "generation_height"
- },
- "link": 73
- },
- {
- "name": "num_frames",
- "type": "INT",
- "widget": {
- "name": "num_frames"
- },
- "link": 74
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "slot_index": 0,
- "links": [
- 64
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoImageClipEncode"
- },
- "widgets_values": [
- 832,
- 480,
- 81,
- true,
- 0.030000000000000006,
- 1,
- 1,
- false
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 70,
- "type": "GetImageRangeFromBatch",
- "pos": [
- 546.9578247070312,
- 766.3284912109375
- ],
- "size": [
- 428.4000244140625,
- 102
- ],
- "flags": {
- "collapsed": true
- },
- "order": 27,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "shape": 7,
- "type": "IMAGE",
- "link": 81
- },
- {
- "name": "masks",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 88
- ]
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "GetImageRangeFromBatch"
- },
- "widgets_values": [
- 0,
- 1
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 71,
- "type": "WanVideoImageClipEncode",
- "pos": [
- 855.04638671875,
- 844.81201171875
- ],
- "size": [
- 310.4956359863281,
- 326
- ],
- "flags": {},
- "order": 29,
- "mode": 0,
- "inputs": [
- {
- "name": "clip_vision",
- "type": "CLIP_VISION",
- "link": 82
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 88
- },
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 84
- },
- {
- "name": "generation_width",
- "type": "INT",
- "widget": {
- "name": "generation_width"
- },
- "link": 85
- },
- {
- "name": "generation_height",
- "type": "INT",
- "widget": {
- "name": "generation_height"
- },
- "link": 86
- },
- {
- "name": "num_frames",
- "type": "INT",
- "widget": {
- "name": "num_frames"
- },
- "link": 87
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "slot_index": 0,
- "links": []
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoImageClipEncode"
- },
- "widgets_values": [
- 832,
- 480,
- 81,
- true,
- 0.030000000000000006,
- 1,
- 1,
- false
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 38,
- "type": "WanVideoVAELoader",
- "pos": [
- 169.25408935546875,
- -322.9471740722656
- ],
- "size": [
- 372.7727966308594,
- 82
- ],
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "slot_index": 0,
- "links": [
- 43,
- 63,
- 67,
- 84
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoVAELoader"
- },
- "widgets_values": [
- "wanvideo\\Wan2_1_VAE_bf16.safetensors",
- "bf16"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 22,
- "type": "WanVideoModelLoader",
- "pos": [
- 150,
- -780
- ],
- "size": [
- 477.4410095214844,
- 226.43276977539062
- ],
- "flags": {},
- "order": 22,
- "mode": 0,
- "inputs": [
- {
- "name": "compile_args",
- "shape": 7,
- "type": "WANCOMPILEARGS",
- "link": 75
- },
- {
- "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
- }
- ],
- "outputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "slot_index": 0,
- "links": [
- 29
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoModelLoader"
- },
- "widgets_values": [
- "WanVideo\\Wan2_1-I2V-14B-480P_fp8_e4m3fn.safetensors",
- "fp16_fast",
- "fp8_e4m3fn",
- "offload_device",
- "sageattn"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 52,
- "type": "WanVideoTeaCache",
- "pos": [
- 1323.885986328125,
- -630.6788940429688
- ],
- "size": [
- 315,
- 154
- ],
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "cache_args",
- "type": "CACHEARGS",
- "links": [
- 91
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoTeaCache"
- },
- "widgets_values": [
- 0.20000000000000004,
- 2,
- -1,
- "offload_device",
- true
- ]
- },
- {
- "id": 27,
- "type": "WanVideoSampler",
- "pos": [
- 1315.2401123046875,
- -401.48028564453125
- ],
- "size": [
- 315,
- 767
- ],
- "flags": {},
- "order": 30,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "link": 29
- },
- {
- "name": "text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "link": 30
- },
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "link": 64
- },
- {
- "name": "samples",
- "shape": 7,
- "type": "LATENT",
- "link": 68
- },
- {
- "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": 91
- },
- {
- "name": "flowedit_args",
- "shape": 7,
- "type": "FLOWEDITARGS",
- "link": 65
- },
- {
- "name": "slg_args",
- "shape": 7,
- "type": "SLGARGS",
- "link": 92
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "slot_index": 0,
- "links": [
- 33
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoSampler"
- },
- "widgets_values": [
- 25,
- 4.000000000000001,
- 5.000000000000001,
- 123,
- "fixed",
- true,
- "euler",
- 0,
- 0.9500000000000002,
- false,
- "comfy",
- ""
- ]
- },
- {
- "id": 73,
- "type": "WanVideoSLG",
- "pos": [
- 927.0363159179688,
- -366.92950439453125
- ],
- "size": [
- 315,
- 106
- ],
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "slg_args",
- "type": "SLGARGS",
- "links": [
- 92
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoSLG"
- },
- "widgets_values": [
- "9",
- 0.20000000000000004,
- 0.9000000000000001
- ]
- },
- {
- "id": 63,
- "type": "WanVideoFlowEdit",
- "pos": [
- 879.3870849609375,
- 407.6827697753906
- ],
- "size": [
- 310.8893737792969,
- 174
- ],
- "flags": {},
- "order": 26,
- "mode": 0,
- "inputs": [
- {
- "name": "source_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "link": 70
- },
- {
- "name": "source_image_embeds",
- "shape": 7,
- "type": "WANVIDIMAGE_EMBEDS",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "flowedit_args",
- "type": "FLOWEDITARGS",
- "links": [
- 65
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoFlowEdit"
- },
- "widgets_values": [
- 2,
- 8,
- 7.000000000000002,
- 6,
- 6
- ]
- },
- {
- "id": 64,
- "type": "WanVideoEncode",
- "pos": [
- 874.3060302734375,
- 117.539794921875
- ],
- "size": [
- 315,
- 242
- ],
- "flags": {},
- "order": 24,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 67
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 66
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "slot_index": 0,
- "links": [
- 68
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoEncode"
- },
- "widgets_values": [
- false,
- 272,
- 272,
- 144,
- 128,
- 0,
- 1
- ]
- },
- {
- "id": 28,
- "type": "WanVideoDecode",
- "pos": [
- 1688.0194091796875,
- -647.6461791992188
- ],
- "size": [
- 315,
- 174
- ],
- "flags": {},
- "order": 31,
- "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,
- 79
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoDecode"
- },
- "widgets_values": [
- false,
- 272,
- 272,
- 144,
- 128
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 69,
- "type": "VHS_VideoCombine",
- "pos": [
- 2655.1708984375,
- -395.2093811035156
- ],
- "size": [
- 1507.1126708984375,
- 844.3505249023438
- ],
- "flags": {},
- "order": 34,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 80
- },
- {
- "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_00433.mp4",
- "subfolder": "",
- "type": "output",
- "format": "video/h264-mp4",
- "frame_rate": 16,
- "workflow": "WanVideoWrapper_I2V_00433.png",
- "fullpath": "N:\\AI\\ComfyUI\\output\\WanVideoWrapper_I2V_00433.mp4"
- }
- }
- }
- }
- ],
- "links": [
- [
- 15,
- 11,
- 0,
- 16,
- 0,
- "WANTEXTENCODER"
- ],
- [
- 29,
- 22,
- 0,
- 27,
- 0,
- "WANVIDEOMODEL"
- ],
- [
- 30,
- 16,
- 0,
- 27,
- 1,
- "WANVIDEOTEXTEMBEDS"
- ],
- [
- 33,
- 27,
- 0,
- 28,
- 1,
- "LATENT"
- ],
- [
- 36,
- 28,
- 0,
- 30,
- 0,
- "IMAGE"
- ],
- [
- 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"
- ],
- [
- 58,
- 56,
- 0,
- 57,
- 0,
- "CLIP_VISION"
- ],
- [
- 59,
- 58,
- 0,
- 57,
- 1,
- "IMAGE"
- ],
- [
- 63,
- 38,
- 0,
- 57,
- 2,
- "WANVAE"
- ],
- [
- 64,
- 57,
- 0,
- 27,
- 2,
- "WANVIDIMAGE_EMBEDS"
- ],
- [
- 65,
- 63,
- 0,
- 27,
- 7,
- "FLOWEDITARGS"
- ],
- [
- 66,
- 65,
- 0,
- 64,
- 1,
- "IMAGE"
- ],
- [
- 67,
- 38,
- 0,
- 64,
- 0,
- "WANVAE"
- ],
- [
- 68,
- 64,
- 0,
- 27,
- 3,
- "LATENT"
- ],
- [
- 69,
- 11,
- 0,
- 66,
- 0,
- "WANTEXTENCODER"
- ],
- [
- 70,
- 66,
- 0,
- 63,
- 0,
- "WANVIDEOTEXTEMBEDS"
- ],
- [
- 71,
- 65,
- 0,
- 67,
- 0,
- "IMAGE"
- ],
- [
- 72,
- 67,
- 1,
- 57,
- 3,
- "INT"
- ],
- [
- 73,
- 67,
- 2,
- 57,
- 4,
- "INT"
- ],
- [
- 74,
- 67,
- 3,
- 57,
- 5,
- "INT"
- ],
- [
- 75,
- 35,
- 0,
- 22,
- 0,
- "WANCOMPILEARGS"
- ],
- [
- 77,
- 58,
- 0,
- 68,
- 1,
- "IMAGE"
- ],
- [
- 78,
- 67,
- 0,
- 68,
- 0,
- "IMAGE"
- ],
- [
- 79,
- 28,
- 0,
- 68,
- 2,
- "IMAGE"
- ],
- [
- 80,
- 68,
- 0,
- 69,
- 0,
- "IMAGE"
- ],
- [
- 81,
- 67,
- 0,
- 70,
- 0,
- "IMAGE"
- ],
- [
- 82,
- 56,
- 0,
- 71,
- 0,
- "CLIP_VISION"
- ],
- [
- 84,
- 38,
- 0,
- 71,
- 2,
- "WANVAE"
- ],
- [
- 85,
- 67,
- 1,
- 71,
- 3,
- "INT"
- ],
- [
- 86,
- 67,
- 2,
- 71,
- 4,
- "INT"
- ],
- [
- 87,
- 67,
- 3,
- 71,
- 5,
- "INT"
- ],
- [
- 88,
- 70,
- 0,
- 71,
- 1,
- "IMAGE"
- ],
- [
- 91,
- 52,
- 0,
- 27,
- 6,
- "TEACACHEARGS"
- ],
- [
- 92,
- 73,
- 0,
- 27,
- 8,
- "SLGARGS"
- ]
- ],
- "groups": [
- {
- "id": 1,
- "title": "ComfyUI text encoding alternative",
- "bounding": [
- -1820.35107421875,
- -367.5990905761719,
- 1210.621337890625,
- 805.9080810546875
- ],
- "color": "#3f789e",
- "font_size": 24,
- "flags": {}
- }
- ],
- "config": {},
- "extra": {
- "ds": {
- "scale": 0.6115909044841833,
- "offset": [
- 973.5038468672901,
- 1390.6616196111634
- ]
- },
- "node_versions": {
- "ComfyUI-WanVideoWrapper": "173aff236710272df37b3165c79297cd9b924e5a",
- "comfy-core": "0.3.26",
- "ComfyUI-VideoHelperSuite": "0a75c7958fe320efcb052f1d9f8451fd20c730a8",
- "ComfyUI-KJNodes": "7c488a16ef420acf0276a4f8e31fc024a969d24b"
- },
- "VHS_latentpreview": true,
- "VHS_latentpreviewrate": 0,
- "VHS_MetadataImage": true,
- "VHS_KeepIntermediate": true
- },
- "version": 0.4
-}
\ No newline at end of file
diff --git a/example_workflows/wanvideo_long_T2V_example_01.json b/example_workflows/wanvideo_long_T2V_example_01.json
deleted file mode 100644
index 6f07fa6..0000000
--- a/example_workflows/wanvideo_long_T2V_example_01.json
+++ /dev/null
@@ -1,780 +0,0 @@
-{
- "id": "8b7a9a57-2303-4ef5-9fc2-bf41713bd1fc",
- "revision": 0,
- "last_node_id": 46,
- "last_link_id": 58,
- "nodes": [
- {
- "id": 33,
- "type": "Note",
- "pos": [
- 227.3764190673828,
- -205.28524780273438
- ],
- "size": [
- 351.70458984375,
- 88
- ],
- "flags": {},
- "order": 0,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "Models:\nhttps://huggingface.co/Kijai/WanVideo_comfy/tree/main"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 11,
- "type": "LoadWanVideoT5TextEncoder",
- "pos": [
- 224.15325927734375,
- -34.481563568115234
- ],
- "size": [
- 377.1661376953125,
- 130
- ],
- "flags": {},
- "order": 1,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "wan_t5_model",
- "type": "WANTEXTENCODER",
- "slot_index": 0,
- "links": [
- 15
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "LoadWanVideoT5TextEncoder"
- },
- "widgets_values": [
- "umt5-xxl-enc-bf16.safetensors",
- "bf16",
- "offload_device",
- "disabled"
- ]
- },
- {
- "id": 28,
- "type": "WanVideoDecode",
- "pos": [
- 1692.973876953125,
- -404.8614501953125
- ],
- "size": [
- 315,
- 174
- ],
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 43
- },
- {
- "name": "samples",
- "type": "LATENT",
- "link": 33
- }
- ],
- "outputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 48
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoDecode"
- },
- "widgets_values": [
- true,
- 272,
- 272,
- 144,
- 128
- ]
- },
- {
- "id": 38,
- "type": "WanVideoVAELoader",
- "pos": [
- 1687.4093017578125,
- -582.2750854492188
- ],
- "size": [
- 416.25482177734375,
- 82
- ],
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "slot_index": 0,
- "links": [
- 43
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoVAELoader"
- },
- "widgets_values": [
- "wanvideo\\Wan2_1_VAE_bf16.safetensors",
- "bf16"
- ]
- },
- {
- "id": 42,
- "type": "GetImageSizeAndCount",
- "pos": [
- 1708.7301025390625,
- -140.99705505371094
- ],
- "size": [
- 277.20001220703125,
- 86
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 48
- }
- ],
- "outputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 56
- ]
- },
- {
- "label": "832 width",
- "name": "width",
- "type": "INT",
- "links": null
- },
- {
- "label": "480 height",
- "name": "height",
- "type": "INT",
- "links": null
- },
- {
- "label": "257 count",
- "name": "count",
- "type": "INT",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "GetImageSizeAndCount"
- },
- "widgets_values": []
- },
- {
- "id": 16,
- "type": "WanVideoTextEncode",
- "pos": [
- 675.8850708007812,
- -36.032100677490234
- ],
- "size": [
- 420.30511474609375,
- 261.5306701660156
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "t5",
- "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"
- },
- "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
- ]
- },
- {
- "id": 30,
- "type": "VHS_VideoCombine",
- "pos": [
- 2127.120849609375,
- -511.9014587402344
- ],
- "size": [
- 873.2135620117188,
- 840.2385864257812
- ],
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 56
- },
- {
- "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": "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_00412.mp4",
- "subfolder": "",
- "type": "output",
- "format": "video/h264-mp4",
- "frame_rate": 16,
- "workflow": "WanVideo2_1_T2V_00412.png",
- "fullpath": "N:\\AI\\ComfyUI\\output\\WanVideo2_1_T2V_00412.mp4"
- }
- }
- }
- },
- {
- "id": 37,
- "type": "WanVideoEmptyEmbeds",
- "pos": [
- 1305.26708984375,
- -571.7843627929688
- ],
- "size": [
- 315,
- 106
- ],
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "links": [
- 42
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoEmptyEmbeds"
- },
- "widgets_values": [
- 832,
- 480,
- 257
- ]
- },
- {
- "id": 35,
- "type": "WanVideoTorchCompileSettings",
- "pos": [
- 193.47103881835938,
- -614.6900024414062
- ],
- "size": [
- 390.5999755859375,
- 178
- ],
- "flags": {},
- "order": 4,
- "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
- ]
- },
- {
- "id": 45,
- "type": "WanVideoTeaCache",
- "pos": [
- 931.4036865234375,
- -792.5159912109375
- ],
- "size": [
- 315,
- 154
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "cache_args",
- "type": "CACHEARGS",
- "links": [
- 58
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoTeaCache"
- },
- "widgets_values": [
- 0.10000000000000002,
- 1,
- -1,
- "offload_device",
- true
- ]
- },
- {
- "id": 36,
- "type": "Note",
- "pos": [
- 796.0189208984375,
- -521.5020751953125
- ],
- "size": [
- 298.2554016113281,
- 108.62744140625
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "sdpa should work too, haven't tested flaash\n\nfp8_fast seems to cause huge quality degradation"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 46,
- "type": "Note",
- "pos": [
- 937.9556274414062,
- -940.750244140625
- ],
- "size": [
- 297.4364013671875,
- 88
- ],
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "TeaCache with context windows is VERY experimental and lower values than normal should be used."
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 27,
- "type": "WanVideoSampler",
- "pos": [
- 1315.2401123046875,
- -401.48028564453125
- ],
- "size": [
- 315,
- 574.1923217773438
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "link": 29
- },
- {
- "name": "text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "link": 30
- },
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "link": 42
- },
- {
- "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": 57
- },
- {
- "name": "cache_args",
- "shape": 7,
- "type": "CACHEARGS",
- "link": 58
- },
- {
- "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
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "slot_index": 0,
- "links": [
- 33
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoSampler"
- },
- "widgets_values": [
- 30,
- 6,
- 5,
- 1057359483639288,
- "fixed",
- true,
- "unipc",
- 0,
- 1,
- "",
- "comfy"
- ]
- },
- {
- "id": 43,
- "type": "WanVideoContextOptions",
- "pos": [
- 1307.9542236328125,
- -855.8865356445312
- ],
- "size": [
- 315,
- 226
- ],
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "shape": 7,
- "type": "WANVAE",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "context_options",
- "type": "WANVIDCONTEXT",
- "slot_index": 0,
- "links": [
- 57
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoContextOptions"
- },
- "widgets_values": [
- "uniform_standard",
- 81,
- 4,
- 16,
- true,
- false,
- 6,
- 2
- ]
- },
- {
- "id": 22,
- "type": "WanVideoModelLoader",
- "pos": [
- 620.3950805664062,
- -357.8426818847656
- ],
- "size": [
- 477.4410095214844,
- 226.43276977539062
- ],
- "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
- }
- ],
- "outputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "slot_index": 0,
- "links": [
- 29
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoModelLoader"
- },
- "widgets_values": [
- "WanVideo\\wan2.1_t2v_1.3B_fp16.safetensors",
- "fp16",
- "disabled",
- "offload_device",
- "sdpa"
- ]
- }
- ],
- "links": [
- [
- 15,
- 11,
- 0,
- 16,
- 0,
- "WANTEXTENCODER"
- ],
- [
- 29,
- 22,
- 0,
- 27,
- 0,
- "WANVIDEOMODEL"
- ],
- [
- 30,
- 16,
- 0,
- 27,
- 1,
- "WANVIDEOTEXTEMBEDS"
- ],
- [
- 33,
- 27,
- 0,
- 28,
- 1,
- "LATENT"
- ],
- [
- 42,
- 37,
- 0,
- 27,
- 2,
- "WANVIDIMAGE_EMBEDS"
- ],
- [
- 43,
- 38,
- 0,
- 28,
- 0,
- "VAE"
- ],
- [
- 48,
- 28,
- 0,
- 42,
- 0,
- "IMAGE"
- ],
- [
- 56,
- 42,
- 0,
- 30,
- 0,
- "IMAGE"
- ],
- [
- 57,
- 43,
- 0,
- 27,
- 5,
- "WANVIDCONTEXT"
- ],
- [
- 58,
- 45,
- 0,
- 27,
- 6,
- "TEACACHEARGS"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {
- "ds": {
- "scale": 0.8140274938684471,
- "offset": [
- -122.25834160503663,
- 993.5739491626379
- ]
- },
- "node_versions": {
- "ComfyUI-WanVideoWrapper": "5a2383621a05825d0d0437781afcb8552d9590fd",
- "ComfyUI-KJNodes": "a5bd3c86c8ed6b83c55c2d0e7a59515b15a0137f",
- "ComfyUI-VideoHelperSuite": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
- },
- "VHS_latentpreview": true,
- "VHS_latentpreviewrate": 0,
- "VHS_MetadataImage": true,
- "VHS_KeepIntermediate": true
- },
- "version": 0.4
-}
\ No newline at end of file
diff --git a/example_workflows/wanvideo_mocha_replacement_original_01.json b/example_workflows/wanvideo_mocha_replacement_original_01.json
deleted file mode 100644
index 13c181a..0000000
--- a/example_workflows/wanvideo_mocha_replacement_original_01.json
+++ /dev/null
@@ -1,2138 +0,0 @@
-{
- "id": "c6e410bc-5e2c-460b-ae81-c91b6094fbb1",
- "revision": 0,
- "last_node_id": 342,
- "last_link_id": 616,
- "nodes": [
- {
- "id": 243,
- "type": "SetNode",
- "pos": [
- -4658.337890625,
- 111.99787139892578
- ],
- "size": [
- 210,
- 60
- ],
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "link": 391
- }
- ],
- "outputs": [
- {
- "name": "*",
- "type": "*",
- "links": null
- }
- ],
- "title": "Set_input_video",
- "properties": {
- "previousName": "input_video"
- },
- "widgets_values": [
- "input_video"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 249,
- "type": "PreviewImage",
- "pos": [
- -4242.11767578125,
- 42.481197357177734
- ],
- "size": [
- 261.0582580566406,
- 258
- ],
- "flags": {},
- "order": 21,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 398
- }
- ],
- "outputs": [],
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "widgets_values": []
- },
- {
- "id": 300,
- "type": "LoadImage",
- "pos": [
- -4988.6552734375,
- 1341.486328125
- ],
- "size": [
- 274.080078125,
- 314.000244140625
- ],
- "flags": {},
- "order": 0,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 494
- ]
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "title": "Load Reference Image",
- "properties": {
- "Node name for S&R": "LoadImage"
- },
- "widgets_values": [
- "character-3-2 (1).png",
- "image"
- ]
- },
- {
- "id": 246,
- "type": "ImageResizeKJv2",
- "pos": [
- -4653.63427734375,
- 500.123291015625
- ],
- "size": [
- 270,
- 336.0001220703125
- ],
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 395
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- },
- {
- "name": "width",
- "type": "INT",
- "widget": {
- "name": "width"
- },
- "link": 595
- },
- {
- "name": "height",
- "type": "INT",
- "widget": {
- "name": "height"
- },
- "link": 598
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 396,
- 600
- ]
- },
- {
- "name": "width",
- "type": "INT",
- "links": [
- 501
- ]
- },
- {
- "name": "height",
- "type": "INT",
- "links": [
- 502
- ]
- },
- {
- "name": "mask",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "ImageResizeKJv2"
- },
- "widgets_values": [
- 832,
- 480,
- "lanczos",
- "pad",
- "127,127,127",
- "center",
- 16,
- "cpu"
- ]
- },
- {
- "id": 298,
- "type": "PreviewImage",
- "pos": [
- -4980.3505859375,
- 1790.142578125
- ],
- "size": [
- 452.59210205078125,
- 258
- ],
- "flags": {},
- "order": 28,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 495
- }
- ],
- "outputs": [],
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "widgets_values": []
- },
- {
- "id": 296,
- "type": "ImageResizeKJv2",
- "pos": [
- -4652.1630859375,
- 1343.4151611328125
- ],
- "size": [
- 270,
- 336.0001220703125
- ],
- "flags": {},
- "order": 25,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 494
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- },
- {
- "name": "width",
- "type": "INT",
- "widget": {
- "name": "width"
- },
- "link": 501
- },
- {
- "name": "height",
- "type": "INT",
- "widget": {
- "name": "height"
- },
- "link": 502
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 495,
- 601
- ]
- },
- {
- "name": "width",
- "type": "INT",
- "links": []
- },
- {
- "name": "height",
- "type": "INT",
- "links": []
- },
- {
- "name": "mask",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "ImageResizeKJv2"
- },
- "widgets_values": [
- 983,
- 480,
- "lanczos",
- "pad",
- "127,127,127",
- "center",
- 16,
- "cpu"
- ]
- },
- {
- "id": 332,
- "type": "SetNode",
- "pos": [
- -4295.95556640625,
- 1368.134033203125
- ],
- "size": [
- 210,
- 60
- ],
- "flags": {},
- "order": 29,
- "mode": 0,
- "inputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "link": 601
- }
- ],
- "outputs": [
- {
- "name": "*",
- "type": "*",
- "links": null
- }
- ],
- "title": "Set_ref2",
- "properties": {
- "previousName": "ref2"
- },
- "widgets_values": [
- "ref2"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 331,
- "type": "SetNode",
- "pos": [
- -4293.26025390625,
- 497.8930358886719
- ],
- "size": [
- 210,
- 60
- ],
- "flags": {},
- "order": 24,
- "mode": 0,
- "inputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "link": 600
- }
- ],
- "outputs": [
- {
- "name": "*",
- "type": "*",
- "links": null
- }
- ],
- "title": "Set_ref1",
- "properties": {
- "previousName": "ref1"
- },
- "widgets_values": [
- "ref1"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 336,
- "type": "GetNode",
- "pos": [
- -2132.648681640625,
- 1672.94140625
- ],
- "size": [
- 210,
- 58
- ],
- "flags": {},
- "order": 1,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 606
- ]
- }
- ],
- "title": "Get_ref1",
- "properties": {},
- "widgets_values": [
- "ref1"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 308,
- "type": "WanVideoVAELoader",
- "pos": [
- -2121.183349609375,
- 732.5975341796875
- ],
- "size": [
- 397.5917663574219,
- 92.40150451660156
- ],
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [
- {
- "name": "compile_args",
- "shape": 7,
- "type": "WANCOMPILEARGS",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "links": [
- 602,
- 603
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoVAELoader"
- },
- "widgets_values": [
- "Wan2_1_VAE_bf16.safetensors",
- "bf16"
- ]
- },
- {
- "id": 312,
- "type": "WanVideoLoraSelectMulti",
- "pos": [
- -3116.08837890625,
- 837.6162109375
- ],
- "size": [
- 715.7383422851562,
- 365.4935302734375
- ],
- "flags": {},
- "order": 3,
- "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": [
- 558
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoLoraSelectMulti"
- },
- "widgets_values": [
- "lightx2v/lightx2v_T2V_14B_cfg_step_distill_v2_lora_rank64_bf16.safetensors",
- 1,
- "none",
- 1,
- "none",
- 1,
- "none",
- 1,
- "none",
- 1,
- false,
- true
- ]
- },
- {
- "id": 335,
- "type": "GetNode",
- "pos": [
- -2138.790771484375,
- 1564.837890625
- ],
- "size": [
- 210,
- 58
- ],
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 605
- ]
- }
- ],
- "title": "Get_mask",
- "properties": {},
- "widgets_values": [
- "mask"
- ],
- "color": "#1c5715",
- "bgcolor": "#1f401b"
- },
- {
- "id": 304,
- "type": "WanVideoDecode",
- "pos": [
- -806.5786743164062,
- 779.7594604492188
- ],
- "size": [
- 270,
- 198
- ],
- "flags": {},
- "order": 26,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 602
- },
- {
- "name": "samples",
- "type": "LATENT",
- "link": 563
- }
- ],
- "outputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "links": [
- 611
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoDecode"
- },
- "widgets_values": [
- false,
- 272,
- 272,
- 144,
- 128,
- "default"
- ]
- },
- {
- "id": 339,
- "type": "GetNode",
- "pos": [
- -711.1921997070312,
- 1158.8116455078125
- ],
- "size": [
- 210,
- 58
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 612
- ]
- }
- ],
- "title": "Get_input_video",
- "properties": {},
- "widgets_values": [
- "input_video"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 338,
- "type": "ImageConcanate",
- "pos": [
- -400.39190673828125,
- 1184.6094970703125
- ],
- "size": [
- 270,
- 102
- ],
- "flags": {},
- "order": 30,
- "mode": 0,
- "inputs": [
- {
- "name": "image1",
- "type": "IMAGE",
- "link": 612
- },
- {
- "name": "image2",
- "type": "IMAGE",
- "link": 611
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 613
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "ImageConcanate"
- },
- "widgets_values": [
- "right",
- true
- ]
- },
- {
- "id": 318,
- "type": "VHS_VideoCombine",
- "pos": [
- -57.351234436035156,
- 1083.17822265625
- ],
- "size": [
- 523.336669921875,
- 334
- ],
- "flags": {},
- "order": 32,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 613
- },
- {
- "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": 24,
- "loop_count": 0,
- "filename_prefix": "AnimateDiff",
- "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": "AnimateDiff_00981.mp4",
- "subfolder": "",
- "type": "output",
- "format": "video/h264-mp4",
- "frame_rate": 24,
- "workflow": "AnimateDiff_00981.png",
- "fullpath": "/home/deepspeed/workdir/ComfyUI/output/AnimateDiff_00981.mp4"
- }
- }
- }
- },
- {
- "id": 245,
- "type": "ImageResizeKJv2",
- "pos": [
- -4685.974609375,
- -395.6787109375
- ],
- "size": [
- 270,
- 336.0001220703125
- ],
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 390
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 391,
- 397
- ]
- },
- {
- "name": "width",
- "type": "INT",
- "links": [
- 595
- ]
- },
- {
- "name": "height",
- "type": "INT",
- "links": [
- 598
- ]
- },
- {
- "name": "mask",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "ImageResizeKJv2"
- },
- "widgets_values": [
- 832,
- 480,
- "lanczos",
- "resize",
- "0, 0, 0",
- "center",
- 16,
- "cpu"
- ]
- },
- {
- "id": 248,
- "type": "GetImageRangeFromBatch",
- "pos": [
- -4244.3369140625,
- -117.3695297241211
- ],
- "size": [
- 340.3267517089844,
- 102
- ],
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "shape": 7,
- "type": "IMAGE",
- "link": 397
- },
- {
- "name": "masks",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 398,
- 597,
- 614
- ]
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "GetImageRangeFromBatch"
- },
- "widgets_values": [
- 0,
- 1
- ]
- },
- {
- "id": 328,
- "type": "MaskPreview",
- "pos": [
- -2074.385498046875,
- -147.24452209472656
- ],
- "size": [
- 354.98046875,
- 276.60577392578125
- ],
- "flags": {},
- "order": 33,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 592
- }
- ],
- "outputs": [],
- "properties": {
- "Node name for S&R": "MaskPreview"
- },
- "widgets_values": []
- },
- {
- "id": 325,
- "type": "DownloadAndLoadSAM2Model",
- "pos": [
- -2080.1123046875,
- -334.4346008300781
- ],
- "size": [
- 270,
- 130
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "sam2_model",
- "type": "SAM2MODEL",
- "links": [
- 587
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "DownloadAndLoadSAM2Model",
- "cnr_id": "ComfyUI-segment-anything-2",
- "ver": "c59676b008a76237002926f684d0ca3a9b29ac54"
- },
- "widgets_values": [
- "sam2_hiera_base_plus.safetensors",
- "video",
- "cuda",
- "fp16"
- ]
- },
- {
- "id": 326,
- "type": "Sam2Segmentation",
- "pos": [
- -1742.36962890625,
- -537.3062133789062
- ],
- "size": [
- 272.087890625,
- 182
- ],
- "flags": {},
- "order": 27,
- "mode": 0,
- "inputs": [
- {
- "name": "sam2_model",
- "type": "SAM2MODEL",
- "link": 587
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 614
- },
- {
- "name": "coordinates_positive",
- "shape": 7,
- "type": "STRING",
- "link": 588
- },
- {
- "name": "coordinates_negative",
- "shape": 7,
- "type": "STRING",
- "link": 589
- },
- {
- "name": "bboxes",
- "shape": 7,
- "type": "BBOX",
- "link": null
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "mask",
- "type": "MASK",
- "links": [
- 590
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "Sam2Segmentation",
- "cnr_id": "ComfyUI-segment-anything-2",
- "ver": "c59676b008a76237002926f684d0ca3a9b29ac54"
- },
- "widgets_values": [
- false,
- false
- ]
- },
- {
- "id": 330,
- "type": "SetNode",
- "pos": [
- -1393.6978759765625,
- -505.46051025390625
- ],
- "size": [
- 210,
- 60
- ],
- "flags": {},
- "order": 34,
- "mode": 0,
- "inputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "link": 599
- }
- ],
- "outputs": [
- {
- "name": "*",
- "type": "*",
- "links": null
- }
- ],
- "title": "Set_mask",
- "properties": {
- "previousName": "mask"
- },
- "widgets_values": [
- "mask"
- ],
- "color": "#1c5715",
- "bgcolor": "#1f401b"
- },
- {
- "id": 327,
- "type": "GrowMask",
- "pos": [
- -1743.5830078125,
- -304.02972412109375
- ],
- "size": [
- 270,
- 82
- ],
- "flags": {
- "collapsed": false
- },
- "order": 31,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 590
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 592,
- 599
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "GrowMask",
- "cnr_id": "comfy-core",
- "ver": "0.3.59"
- },
- "widgets_values": [
- 5,
- true
- ]
- },
- {
- "id": 333,
- "type": "GetNode",
- "pos": [
- -2141.247802734375,
- 1465.3330078125
- ],
- "size": [
- 210,
- 60
- ],
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 604
- ]
- }
- ],
- "title": "Get_input_video",
- "properties": {},
- "widgets_values": [
- "input_video"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 311,
- "type": "WanVideoModelLoader",
- "pos": [
- -3117.3388671875,
- 1273.5108642578125
- ],
- "size": [
- 608.3448486328125,
- 329.97747802734375
- ],
- "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": 558
- },
- {
- "name": "vram_management_args",
- "shape": 7,
- "type": "VRAM_MANAGEMENTARGS",
- "link": null
- },
- {
- "name": "extra_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
- },
- {
- "name": "fantasyportrait_model",
- "shape": 7,
- "type": "FANTASYPORTRAITMODEL",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "links": [
- 615
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoModelLoader"
- },
- "widgets_values": [
- "character_render/v14-long-step15000.ckpt",
- "bf16",
- "disabled",
- "offload_device",
- "sdpa",
- "default"
- ]
- },
- {
- "id": 313,
- "type": "WanVideoTextEncodeCached",
- "pos": [
- -2113.37060546875,
- 943.2658081054688
- ],
- "size": [
- 400,
- 302
- ],
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "extender_args",
- "shape": 7,
- "type": "WANVIDEOPROMPTEXTENDER_ARGS",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "links": [
- 559
- ]
- },
- {
- "name": "negative_text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "links": null
- },
- {
- "name": "positive_prompt",
- "type": "STRING",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoTextEncodeCached"
- },
- "widgets_values": [
- "umt5-xxl-enc-fp8_e4m3fn.safetensors",
- "bf16",
- "",
- "",
- "disabled",
- true,
- "gpu"
- ]
- },
- {
- "id": 247,
- "type": "PreviewImage",
- "pos": [
- -4993.5771484375,
- 894.2095947265625
- ],
- "size": [
- 385.585205078125,
- 258
- ],
- "flags": {},
- "order": 23,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 396
- }
- ],
- "outputs": [],
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "widgets_values": []
- },
- {
- "id": 314,
- "type": "WanVideoSampler",
- "pos": [
- -1281.765380859375,
- 1061.5728759765625
- ],
- "size": [
- 327.80859375,
- 734
- ],
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "link": 615
- },
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "link": 581
- },
- {
- "name": "text_embeds",
- "shape": 7,
- "type": "WANVIDEOTEXTEMBEDS",
- "link": 559
- },
- {
- "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": "character_render_latent",
- "shape": 7,
- "type": "LATENT",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "links": [
- 563
- ]
- },
- {
- "name": "denoised_samples",
- "type": "LATENT",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoSampler"
- },
- "widgets_values": [
- 6,
- 1.0000000000000002,
- 5,
- 42,
- "fixed",
- true,
- "dpm++_sde",
- 0,
- 1,
- false,
- "comfy",
- 0,
- -1,
- false
- ]
- },
- {
- "id": 128,
- "type": "VHS_LoadVideo",
- "pos": [
- -4986.1728515625,
- -396.7111511230469
- ],
- "size": [
- 247.455078125,
- 310
- ],
- "flags": {},
- "order": 9,
- "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",
- "links": [
- 390
- ]
- },
- {
- "name": "frame_count",
- "type": "INT",
- "links": []
- },
- {
- "name": "audio",
- "type": "AUDIO",
- "links": null
- },
- {
- "name": "video_info",
- "type": "VHS_VIDEOINFO",
- "links": null
- }
- ],
- "title": "Load Reference Video",
- "properties": {
- "Node name for S&R": "VHS_LoadVideo",
- "cnr_id": "comfyui-videohelpersuite",
- "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
- },
- "widgets_values": {
- "video": "10月15日 (5)(1).mp4",
- "force_rate": 0,
- "custom_width": 0,
- "custom_height": 0,
- "frame_load_cap": 81,
- "skip_first_frames": 0,
- "select_every_nth": 1,
- "format": "AnimateDiff",
- "choose video to upload": "image",
- "videopreview": {
- "hidden": false,
- "paused": false,
- "params": {
- "filename": "10月15日 (5)(1).mp4",
- "type": "input",
- "format": "video/mp4",
- "force_rate": 0,
- "custom_width": 0,
- "custom_height": 0,
- "frame_load_cap": 81,
- "skip_first_frames": 0,
- "select_every_nth": 1
- }
- }
- }
- },
- {
- "id": 212,
- "type": "LoadImage",
- "pos": [
- -4993.25927734375,
- 483.2601013183594
- ],
- "size": [
- 274.080078125,
- 314.0001220703125
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 395
- ]
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "title": "Load Reference Image",
- "properties": {
- "Node name for S&R": "LoadImage"
- },
- "widgets_values": [
- "character-3.png",
- "image"
- ]
- },
- {
- "id": 323,
- "type": "PointsEditor",
- "pos": [
- -2991.7236328125,
- -528.9296875
- ],
- "size": [
- 877,
- 748
- ],
- "flags": {},
- "order": 22,
- "mode": 0,
- "inputs": [
- {
- "name": "bg_image",
- "shape": 7,
- "type": "IMAGE",
- "link": 597
- }
- ],
- "outputs": [
- {
- "name": "positive_coords",
- "type": "STRING",
- "links": [
- 588
- ]
- },
- {
- "name": "negative_coords",
- "type": "STRING",
- "links": [
- 589
- ]
- },
- {
- "name": "bbox",
- "type": "BBOX",
- "links": null
- },
- {
- "name": "bbox_mask",
- "type": "MASK",
- "links": null
- },
- {
- "name": "cropped_image",
- "type": "IMAGE",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "PointsEditor",
- "imgData": {
- "name": "bg_image",
- "base64": [
- "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAHAA0ADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwCxfwSQyjfyW6GoLSYI53kKRWpqE4eyMq4LJzXHtdSzSs5wATWU1bUafQ2rrWzENoIPNS6XPFPctLKcKR3rnXAZ9zc1L5jJHkcD2pc7YuRLVHWxaiY7l4oCFQ9DW/pLlmYu2WPevP8ATrpZDgnkGultdQNsu4GuyCl1MW1sdnTZANo+tc7FrsjuFA61ea9lwuR1NW2kQotmxj5cVUnsVkYtkipVmkwPl4p4Zm7VPMmXyNHG6m8tteGJWOMZqhYOzapk9SprZ1OMNqrBhztrGtPk1cAe9ZzWprHYrXkt2LxkXoW45rLu767iuPLUZ9627xW+3Zz3rHvUJvQetHLoTzaiu94lm8snBxxWWNQuiYiW4ZgDXRX4zpR+lcsRhIv98U3GwoyuXryadblVVyFIq3pxeS3uA7EkDiq90ublD7Vb07hJx6ihLUG9DAMkoYjzG/OnxSTGQDeala3Uy5z+FJEoEwHvS5S1JWIZriZJSPMI/GhLickfOetOuolMxyOc05YwrDFLl1FzHQBP3Kn2qN9qLuZgB6mpgP3CfSqGqf8AHg9dCiuW5jz62J0lidtqyKT6ZqXDDvXLac5/tOMZ611ZNKCUhybiNwT1NN2Rn+IGnScRMfasi2nUgITyDWdacafQcLyNFrdBLnaKk+zRH+BfyqtLOquNzAcUn27BA7HvUKpAu0rE01vCAOF61Yjso3K7Y1P4VlSK3zNuPPSu40PTlXTopX5YqDzVRcZapAlLuUZ9KgjsfmjUNj0rlru32W0jKMFQcV1uvzNFJEobCtkYrnbvBs5f900pQXQfNY5XQ7mW8uJFlIO01tajFs02QjrisHwsP9NuPrXS6mp/s2X6VEYjcjnYHkNxHHn5SpJqDSwx1SQMej/1qzbA/a4WHTac1o2FjEJXlUDcWyaUtEAuuofMGP8AnnWJqUI+z2rHqa3deIWRcnqlYmpTx/YLY7h1ptCTLF/GDpKY9qngjVrGQEfwGq97LF/YYYMM8UwzkW6bTwy0WGzS8Lpm0+hro5kxF07Vz3hVgbVv96ukn/1dVGOhLZwOojGsL/vV6Pbf8guP/drzfWW2awhJ/ir0ezYNpcRz/DVU92KTOF1BW/4SVOCR612mmLhqxVhSTU5iw5B4Nb1iAGwKIx964X0KGtKWPFZmm5GoEEfw1taiAZOfWq0KIshYAbsdaqS1Fc1Y0K2RJ71jIv7xvrW4f+PBfpWOD85+tFgGxo32pDjjNdBcf8e+PasmI/vF+ta05/cfhTSC5gCJ2RsetaWjW7xzMzelQQjIY5xirtnIQ24HI71Enyq40LrcH2iyeI9G4rMSwAVFBxtGK2b9gYgexrNF5F5mzPNHPG3Mw8jV0qHyISM55qe8jEhjz0zTNPbfGa1buwB01Lkdc81Saa0Gkc9LZws+ckUi2UQ/iNSsCZDSNwKLCIFsYhJnea0rYBcAdqohuauW7fMKYGrCeRWgkLYFULcfMPrW0i8CpbLSKH2T5ianjQKMGpX4zVacs0DmM/OBkVDeg0WYlUNwKvrJtUDIrnNI1E3AkEh+ZGwRVLU/EC2915e79aydaKVx2OyL5Gaa1yq968/bxmyMUBz6VHa6zeaneLBETlup9BR7eLA797Zbw+YADioDaqoYGP2rS0yHyLJEJywHJqVotzc9Ku5Rl21nF5HyxhQOwqhe6Xb3EoMkIYg8V0axBQQKhaD591AGP/Z6BAPK4HSo0sYBMW8obsdTW8VYjBAqtLGA2cUAQJpqsm7aBXO6gotrqTPQc12kBBhC1xfiIf6TMB2FC3C2hhtNPduTHgKKt2jTeSyyjBHSs+2d1tD5WA2ec1NYXMszOJCPlqiDq7Q/6Mtc94ymMGks49a37Pm2X6Vzfjz/AJATEdiKiexSOPtrgGMSHjilWaV5SU4BrKsZxNiMZ4rprXRri4sHnicZTquOorj5bO5na7IE1Oaz4Dc133hRLqaJbmdSMjgGsvRPCK7Yr2+ZWfgqnYf/AF67m2RYkAUAACumlfdl8pYSQkkADipQzY6VVibLtVrPy1vzMXIhu45pk7YiY1HO5AJBrPknkIILE1XNoLlHw3awA7hmobvW4RC4UcgGqcz8Guc1d51gk8hC7HgAVhKVkaWM/VPE6XBwyEMvFJZ2upazDG02Y4R0B6tS6F4YdnF3fgF85VOw/wDr12UcQjUKgAFEKV9ZESZhjw6m0cLn6VoWdhNapiKYp9K0VXFL071vZLYhIqmO6P3rp/wqrJpnmtukndj7mtPANIVouOyMz+x4CSWLH8akXSbUKBszj3q9ilxincVkYmoWMMLW5SPkyCtD7LF3iXP0qLVPvWw/6airp6VKHbU80g1GdoGiZsq1VnDRDA6VDay5HPerk+HjXBrjcm9zSxHbRmR+c1fEBxgjiqtvcYcIq81dkvFT93/Fiqja+oncj8iOFg6nDegrQS4RoxlsCs5CzAtJwD0qOSRSnlhe+c1ftZLroTyJnR20sEJBMi+vWtZNRSV0AI68VwDbS6BQc5rstItxcBWYAFeatVE1dgou9kdMuoCMAMBThqiDtSLDazQZdfnWm/ZIymQgxRGSZclYyLmRbnVGbIHy1iKAmsDBzzU/iBxbXCsmV4wazrOTfdwtnOT1p1HqRETUJCmpOM96qXDfvST1qzqK51lt33eDUc6xmXdkYq4S5kyJKzFnMj6exYfLiubb7i+zCunlmSSzMYNZH2GIjBc9c1drolNILh8Sx/StPQrc3Us6Drtqo8MLMpYkkDitbQJIba7cj+IYpPTUFZ6HPXCNBePEeqkioYwfOH1rsruys57hpDGMk5zUA060DBhHgg5qblW6HPTaPfSy70gYqe9Sf2PejH7hq9Ft0UWgIUZxT4QJMhkAqOZmnIjl00m5a0RthzjpVHUtIuP7PmyvRc128kyQx4PSs2/nikgdCfvKRWyqaWMnTV7nmun6dIdQhb3rrDplyeiZrAubiK2ucRyZK1ai8W3MThQFKr1z3rCnX5W0ypQuT3lldoCrIQp4zWXFphVt27vWnd+KY7y3wMA96z1v1C/eFYV580roqCsrGfeQyC8+Ykinp93bnkVoxlZxvIBp5t0HzYHNZc2mpYyFN0HzNzXXWut29rpSgtyi4rjLi33qArFfpV9VRtP8gjnHWtqddRsmQ0+hQ13xULm7hAjIVCTmki1CK9gZAwGRzVS60xMZYfd71hWcqrqjKpIUnAFbU6ym7EOOhv6TpcFjcyOkjMW5Oa1buNZrdkPIIrLnWVXTy+B3rRVlMQwcnHNFSryStYajdFSG0ijwFHAq5BbxxAle5qhI0iOSv3c1ZgmbYd3WsZVOY0jHuO1VInCF03dqy3t7HYFa3UgdjV66nLocr0HFUEgmmUvwBXRTleNmRJWY4QWJj2+QNvpUiwWrLtEQwOAKjFpKRwRU0MTqOavQi5PZJFaAiJAoPpWqzbohisjawrUiOYVpiZzeoaBLe3olLYWuwtI/J0+OPOdoxVUVcQ/6OKIKzCTMdYWW9kk7NWrYn95VM/fNbOiae91cDPCdzTbUdWCTk7IzNQ+/+NVo+Grb8SaTJpzq33o26GsiKJmXNHMpK6Bxa0ZpjmwX6VjE4Y/Wtlf+PBfpWV5e+Q8gc0AOgbMgz61szcwfhWbHahWDbxWm/wDqvwp2Aw23GKRVODik0nUEtLWdZ2zJnAHrVgImWAYZrmDdm21M+YMqr7hXPX01RpA7ITiSwAl+VveuXiSSLU5NxJGcip7jWJL+dXCbEHQCmG7Tz1yvJ71we/y8rG0dbp0qw2ZkY4HrXRWt6l/owjiBIziuSiikv7JYYuE7mu40+K30vw0rMAqp94120pPlSXQqKMSXS5wxYJWfcQSx9UIrfbXtNI/4+F/Osq81mzeTCOGHrWykS4ozNj5+6atWu7eMgigananjNWYpY5cFRTuLlNCBwrAk4rXW5iC/fFYOeKge9VGK46VMmikmdBcXMZjO1ua55NcVLxreVthOcbu9NOoL6GszxFDBd6O7iMmYcoV6is5d0x2ZZkulsJ2uVlBjn9OxrldTvBcXDSqT1qjG062qwvIxCjuaruxMZ65rmcbgxFZ3n3Ak+lei+DoYLK2NxM4Mj/pXnNncCOXbIp9q6bTNbSKE4QuQelGiYkewWdyskW4NwatpIv8AfFef6ZrclxGC8LRJ2561rJ4hgj+UoTXSpxZodaJE5+YU1pIwM7hWF/ayfZzN5fyiqZ8RRN1jNU3EVjpFmjY8GmyKr87hXODxDCvSI1attZiuchYjkUXT2CxqgbOQwrlNVxJfShiDnirF74ntrVmV0IIOK56fU4tTlkeFwM9MGlp0E9CF9P2O3lybQe1TWtsluGO/cx61lyPMJCjMc1bhBij5JLmmK519pxap9K53xwM6Iwz1IFKmo3EaBd3ArD8SXd5fWohAymck1E3oNHHRu9k+6Mbs961bTXb3Y8CSGPfxxT9L0Wa6gmllX5F4H1qa30iREI2fvAcqaxaFynQ+GNZv/ta2t6dyj7pPFekwbCgO8V5vZxySKjSxYkXuK6jT9TjhUQufnx0rSnLox6nRosaMWL1Ks8TZG6udbVpi+1bVyM4Bq2k8xX5kVT6VroBozFGQ4asuQ4Boa9lAceWMgVSjuvtK52kZoC4k2WUhetQW1myZaVtxJq2iBTUgFNQ7kyl2GhAOlPAxSgCkzVkimkxmkzS0AAHNLiikLUAFIaMmopZkhQs7ACkMoaqwEtqTwPMqG+1qKBMRkM/YVm6jqIu7lEX7i55rGkbLGtKdO+5lOpbYwoI2Cc5qxG0iDG0mrUca4JA4qRSSMFcV51zpIbOPaSxGCTSXSATCQvzU7bsfKOagFo9w58wmhMHqJ57ycDJAqzEilBvrX0m0t4oz5qgis28eNLlhGPlB4qkuYVrCxQrvztwPWr9lq66RcmSc/uWGD7Vk+fMzgYwvrSXkQngKP0o0Hex2dp4js79cW8owx61py6pHZQAu2U9a8msXS2hO0kFWPSugk1CW80hkPHHUmrggcrljxnqCXEMTwMOfSqWhs2LcscndXMCeSJzHMWZT0JOa6LRJd4jx2YUOV2QjU1cBb8sSBlRWZck+XuHStDxAmb5Gz/B0qigVoyHYD2qXNwk7D5U9yOJswk0+GPzU44NNUrGdvarEMip0qVVkuo+RCNbnFS2Ntm5Xe+0Z60GapsbUV60dZyjYlU0nc6X+z7by1PnDJ96lXSoGXiWuTFxI0oO47R71rR63HDGA6MT6iiM+jKsdCq+RDsX5sUiSPnBXFVre6eWESInB5qTz5v7lWtSblG/laS4+z4wD3rG1SKaxkCl9ylcg1d1O+W2u181SA46+lc/rOpfaZUEbZQDms5XuUldGNNpazTmQOQWNUZrGWKUqOcd62rZwH3N0zVu6aEqHAAJqbCscTFbXAmYFWAq0kUuCGyD710iLGwycCq99GNgMYyaGFivBceTaqG61a+2B4Cx4Aqi88MdttnGGHNZU2u26o8S5IIxWajcDYF+rnAYHFaNpOsqda5XT9NuJ4lmjl+Vu1b0VnJZRlw+446VE0tg3Ls7KwK461yktoLfXVkBAUDIHvWv/AG1EPleMh6w9XuRLKpIK9+tXRTUhM0zeySXm1iAgq99sRVwvIrkPOPRXP1zVuO88mDls1tKN3cFoak9zdi4DLjy/Sp1uS+Cx24rLt9R3nD9+lUr+4m35TIHtS5R3OjecPjkVoxPbrAN7AZrhY724BGQTitl7mS8t40tkIcdc0/hBq50ivAUJQg1Gsse8jGcVQtFkihxMPm70Ow3GRD25FPnY+RGp5sGOasgjYNvSsGJgTl3AHvWs2t6fHZJEkbtMB95jha0hU/mIlTvsWc8VcjbNsBXNf2ndSZKtCBn+Fc1Yh1KcNg7WX0AwaqNWKYOhJo09uXJrpPD99FFC8cjBSDxmufsbi0Yf6R5q57hcir17ZWstg0lrPnjscEVM5KWg4QlB3L/iq+W6hhhVs85rmRvTgMcVdIjE0S3DnZjljVmePSxC2ycF8cAGmvcXKJvndwX/AJB6n2rkL+W4F2/luQPauvjBbT1CismbR9Qd9y2jFT3q57ExWph2k90bqMNKxG4ZFdu//HuPpXLNZTWt4gmiaM57iuokYfZxz2p0r63FPc469llhuZGDsBmsoxTXDmQAmruqTl55lXnaar6MJ5r9YnJVD0rCSuzRbEYaVJFUkqK3dKSJ7uMOA+eDUHiaIW6QBF75YirOg3MEDGVkyGACn0NYzjysEdDDN/ZVwiOMRSHANddd/v8AwfcgHOUOK5K4EWo6esbZ3hsqRWdqvifULCy/sxFATu/cinTnypplmZJtgbaxAb0qxaIZ+R0FV4raK/xczKdxxxmtiJ412pFGEA9KqN5MTYR2mDyRWvartQAVyU93ONXWISEJu6V11v8AdFbqJLZbzVN4g8xyauCosZkNKSuOLIBbof4q07K1RrWbcAfl71zU2h3L3RmW/lVd2do6V1WmfLayKxzhaSiO5xk2iLNOX6AnpUeq6TEBbJCApJwfek1bWhFvityNwJyfSs+y1qe5mhW4AAU/eFZOOgN6l+88PtPCqwKA/rVyy8Li3VGkY7x94etaI1WC0VXccepqzNr1rNEJIyCQOgNDjHqA0wpHhQ+3A6U0xIBuMgwKyn1UXE2FVmc9h1qtdXrKShRx6g1MXBDudvGQ2kSEHIxWB5sayBHcKT6mptN1mOfTGhEbAgY5FcZ4rkdLqAoxU57VppJ6AnZHcCKMqPnFXtK2LOwVs+tcbZSv9njLSEnA710vh0kzyknvVKKTJ5zP12CGWabzegJ5NU9H0e0SEzxOdx7g1Y8VEi3uiPeqng8k6MuT3NTGOtxykXd0TMWYfOvFKXGc55pk6D7dEo6NnNSLaAiVs8q2BVkoRWWSTYDk1PJAvklcDpSafYrDI05JLN1zU+qjbp0sqEh1UkEVL2K6mNoV8otZbN1bzBI2T+NXNQlEEDPERvA4FUPCmJ7aWRkYyM+WcjrV/V4SIpTGuSFzila8bjejsZmn6pcq5eeZOecAVcTxRANRBmiBA/iFcTcTtO+ACjjqKr263RlKrGXx2rDXcm56ynjGz3qPL+XPLelbltqFvfp5kEisPY15JblkjPmxEKRzmuj8O289pdDyJCYXGcdqunV1swuztpJVSQ5I5FQq8Ma4UqB9ai+wi5n3SM3ToDVHWrJLXT3ljZgw6c108yWoWbNQTx93X86cbmED76/nXnbXVx/z0P5037VOeC5/Ol7WIezZ6Gb2DvIv50w39sP+Wq/nXn7JO3ImOPrTDBN3m/Wq5kTY9AOp2g6zL+dIdYsx/wAtlrzC7NzDNGEmyrHBqYGXHLn86l1EgUWeit4gsFH+tFQHxHYg8yV5/hz3NKfITHnSBSemTihVEwcWd1L4ns1U7Gyewrnr3W2u3JZ8L2ANYwlsApYzrgd81FK9jcwyJBOC+0kYNWp8upLjzaGvbzrI5wc4FUZLxPm5GaZoaFLY5JJweTVNoRuJpOvJaoFRi9DSSQHgVJLMd8YIwO9Z0UpGcHkCpmkeeNWPUVxNG6L2zgsG4oimycCooGby+ajkuDEdqgZqbMDQMzKcA4FVvLLtuY1XWZmOSatRqZF64o1GSABRTWXeu3PJqCaQq20GnW5VbxSzZ445rRIlkUGjXG1vlGCcjNU7u1v42MGSqe3euhku2jdMHjPNWp2jmh3MBkCtJQa2JTTOAeG6U/OproNAV44xvGPmpryL5xDAYq7alTgr0zWavfUpIt+JZhHdQE/xLiucnuysnH4VteMW2/ZH9VNczEwmyHNVNe8Si4L8MAAfmrQtiSuSc1jxWUURLAkk1ct5zGwVulQ0UjWFTyTH7LtqrGwYZp7klcUloMfaozbjninSDAO7tUNs7h8A4FTzYMZycfWmxF6x8RCBFgwDjgHNT3viZ7OPe8JINcATKusxBWzGX9a6zWbfzrKBeOuauEmKxBd6yNWVJNm3Bxg1Vmtdy71qqsZi+UcVeimIiIIobvqVZFPlFOTinQyB12vzg1QminknLFiEpIp1UlM85oFY13MYx6VCyvguvPsapSSOGXAJHetOymR0IcgHHegDj/EExmdR0PTFYqWzMMnpXZ6nbWhdpMqT2FZ2p2S21qjHALDIAq4sVh+mXiWtoqeZg+lWrjX4oY8Md59q5jzE2YJ5FVz86tmo9km7sRonUI7u7Lt+7B6VDfussgKtkAdazdhFSxkgc1pypbCZIMqKbuJ6mp0kXow4qGTG4lelMRIDtUHdz6VMLjzWTnGOtQKqlcmopPvArxRuM2lcKflQNWnax3ckW5FRRXNw3xiGAM10On30i2xdwEj/AL2etZyTGjRUOIyZSB7ms65vorZCI1Zs96bPcvdID92P1NUG1CKP5YwxPt3osaJFSXU52fAYAdsg1JHqBSYR3HAx94cipP7Sy2GiH41dhWC4xuRQT0702y0h9qgkb5HIB7g1u2dlK+1c4c/dYD5X9vY1kWtslpLhyFRjwwPFdZos9vI3kSOFY9CD3FZSNIlvT7FwSCnI++h/pWjNokoAltzlf4k/wq0J0IDjHnoOf9qp4NRXcvPDdAf5VClZmjjdHP6jp7GJG5weM+9YKwlbweg4r0SY208ZHGGHIrmb6zWCcbYzz/H/AHq6VUvuckqNtjoPDdpHPaKzgHHrWve2cuVaHG0dRWNoF4kdqQu7Z646V0MTCQDBJBrbdGa00Oe1K1F1A0bICw5B9K5m6sp2BHnkKO1ejTW6AMcZJFcVc8bx7mnGNyJs4W600/a5I0l525qTw7C092A7YKdMUtwGOqSMpOa1tBt1imLAcmuez57GmnKJ4qs3awLqeRXPaHFO7qrMfL7iup8Vz+Xpje9YOk3UZhUJjNXUgnKxMfhudppEShCM5FGu6HHdacbsDBQ8n2pmisTExPrW5qVxFH4UvNzAHYcVTppQsEXqckII4YlVcdKIf9YKqwuWiRieqirMJwwpwhyomTuY1xxry/7wrtbf7i/SuYGn3l3qoaG2Z13Z344FdzFoV7FbqxTt0FNOw7MgFR/xmp5InhOHBBqqT85qrXBGFM9x9qfE5C56ZrZjuJP7LmIl8oqh+Y/SsCUr9sbLd66JdN/tHS2iBIBXnHes5bDR5bG8jyPvyQ7E5Peuhit0XyVVQOR1rSbRF2oqxn5PasnVNTjt75IHXZt4zWEk0Uldmj4liYWEJTPXBxXN2Xn2d4rvnZnkGvRbKyhvrKLeAwxnJput+GotkZijOT6VU4PcRzsShrqO8tDhlPK9jWld3CX3zNDsdRgn1qnNBNpzhIoJGBHZaar3TxOWt5V57qawhB3syjr7KwhTSiwUZ25rz3xdzeQD3r06zVm0Y4BztrzvxNpd9c30JgtZZADyVXpXU4qL0Fe6J7eJRbR5J4Arp/DPLy/WsWLTbv7PGDA+cDPFb3hqGSKV1kQqc9DVEWMrxX/x7XP41S8H5/sdfqa1vE+n3VzDcJDCzsx4ArD0HT9XsrXyXtJF570oFST0NSQ51OEfWrUf+rm/3zVZbS6W/heWJgoByTV2CB5EnCDJ3Gq6C1E88RwkVha9r62diY9pbzBtz2pmp6m1pdfZZFIYd6xdUkafTnUKCCeCaxlPoUtzpPBk+/R9g+8HOeK6NVjZ5FkGSRXPfD15Liwe1CACN+W+tdnPp5FxlACMc1ovhHLVnn+r+HlSUzxcBjWjonheQTpITnHJre1fTJprFkiA3deTWvoURW3w4+YLzWappgyq2g2gjbcikMOc1yF/cPot55VoAwHTNdxeRSu52tx9a5bVNBuZ7zzkkT6GhQSd0BsaXdTXFks0gAcrk1xlzrOpXk8kFwyCEE4CjrXZafG0GnlWxuVTnFecWl0bq7uGPIVyB+dXPVgti4aZjmnMaZnFRYLnP61cXMd9tildV29AaqXOoXKQxr5jgkcnNXtUkiW+3MpJ21UuGgdF3J24rRLQgtac7yW8Jdix3dTW2OlY9gU+zQ7Bhc8Vrg8VMkNBXOeKZCr24Hoa6Mmuf8QSIJYVeIPwetJA2YyMf7Mc/wC2KuaIc3EnshqzYW8c9sR5KhSfu1pQ2VvbxSOiqH2kcVfUk09J/wBS3+7VMnk1c0r/AI9m/wB2o7Sze+ulhRgpY4yaUhrUiaJUVmA7VZQKbVNo5IyahuWEauh4K8GkE5KAYwAOBWBqtifzcAKKhmikZgyjNWra3LxhyOtXIoRgjvQxGdFBkc8GrY/cxEsaJrWbBZTiuZ1TULwSeTE33epNLluFy5m43TMeQT8v0qvbNNNqsG2TBztK1Qi1lki/0g8jjiiMyT3AnjDKOqsKpabk7ncahatEFG4GnW4MsLKW/hrnLCa6luNs8zuvbdWlpW+PULhWckY4Bro54taGajJFC4R3DKpw1XtHEixMJMnms+e5RLh1JAbJ4rS0qbzAwOKx6mqLXjUZsrNwecEfpXHWUm+TZnmuv8bBzo9iyLk7wP0rkTp14jL5aj5h1FObVyUas7LBCGzmoobgSnpVOEXCny5xuOasI6LNt24NRYo3rd0MYHfFWFZMYNYpuWjX5EJrpdC0mG7sxPeO2ScgKcYFLlvsMrfKPu9ahuYPPjKM5APpXUJpGmgHy1kcj61HL4f+0MPLUxD60/ZTE2jz86XJaahBIjllDjOTXUa1N5FhC/uK2V8KKAGeUkjmnzaBBq1t5MzsAh/hOKqNOS3E2jhReb2+Zau28yyqVNdM/ga1+zssU8gYdCeay4/Cuowv/wAsyP8Aep+zkPmRQ4Y7cVi3luqXGEU5zXXw6Hd+fgpk1XvdGuYGMj252juOalxkugXTMF1aKEMBn2qheXKLCUZjG7Dgg81sXtvK8H7oYNc9daHczyb3ZmPakmhsxY5XjuCN5k5+8TWt4kmZrOzb1H9KzZdLu4HbKEAd60tbRJNHs2Y4YD+laqxBzRcmpYgWXHeoljcnhSfoKsQ2123MdvKfohqgGsm080xuTgVbbTtQZciyuT/2zNVntb6L79ncL9YjU3Cw90CRgjrUW8VC0ku7YQ270xThG/8AEpB9KYizHKNu3AqO4Xa4K9DTo4WyoxyelSz206lIxE7OGzhVJo2CxpwaMkNuLq6OIsZAPeljY3twN52W0fIT1qXUruS6EUCn93EoUY9e5qlBcpA7t1VF49zU7miViXVbo7zDG21QPmI7e1ZBn28RKT7mnTl5rgx9/vOfepQApCRrub+VNaIplMvdFsvGZE9On5Grcdy9oI5EZjA3Xd95T6GknjZceZIQx96aLSTygzOSrn5Vxk49aLoVma8N8SzRE5SQblz2Pelg1CSGdRvwynFZxhkBTg5FPaKVpQ2054qGkWpM7m211mNvLuxu6irc+osyO8XYiVOeh7iuNtFmKKADw1dLY2U8i7RyfSsmkjeLbNeLVy8YYHr71ImtJnypsNGT37H1p0Hh5xFubgVl6jbNBIUEYKD0HWiLQ3F2N6017TrKZ4zIpj64XnmtzTvEmnSEIs6g9t3Ga81iNs7gOoRs9GBrTisLZj0liPZkYMPyNaqbSMHC7PUnuIp0DRyK2R2NcTdnDSD3NR6c01mV8u6Df7LcH8v8K0LyBZ4DNEuGP3lrWnWWzMqlF2ujgHf/AIms/wBK2NGlzPtrM1OzmsbppJoynmcg+tWdAk33VbxSZzSbRN4y/wCQYR61z+hWjJAJSflJrf8AGODp4y3OelUtC06a4tE8nc56kelYzdqhvBXpnT6If3LfWneIif7GnAPG2maOjIrqwwQcEVNrEay6fJG/3SMGtnqYrQ5+xUyxQoOpArTitwH652mqWnFI7mJAeBwK1CfKkYsCATxUvTQaR0Nq5jjQKAOK6iCR2gXJ7Vylv9xK6i3wLdSTjismboyddXAVqwMZY10+r2z3CKE5xzXMEFXII5FXDYzmtSuLOFpclBnPWul0aNVLrjjbWEituzjvXRaOOXJ/u0MEQzgIr/IOp6CvEvFMzT6/PgfcOAK9xuOjfjXiHiAhvEF1jvJWMjSJ6h4bm83TLbgD5BXWXSDZHkdq5DwwCLCAEY+UcV2l0MRx/StXsTszMZAD0qtdDEZwKtO6hsZFVrr/AFdSMvaav+hvj0qCRGLZyKt6aP8AQn+lQsOabBIhwQtR6cD9sJ9TU7Dg1Hpg3XmPegCxdqfNPNQBSBVu7H79h71ARSGZ91nzBzUWnHak7f7Rqe5H70fSqMEohtblycAE0E9TzvxPeK2uSAnJFQxzeZCEJyKy9XuBd6xNKp4LYFXLIdAea5pdxPc7v4cRyNJeEMBHvHHfOK9IC7R93JNeZeCrr+y2uHnwqO2Rk12L+KbeOHzdhZP7w6V0wTcUNyS3NK5i3RNxijTBhX+lZD+JYpYdyxPtYcHFW9I1O2nWQCQBsdCeavkklexPtIN2uTTnLEVyc+pTv4hezzthVMj3NbesXktlp091GhcopIFcpo8jSB9RuyJJpfT+EegrK5qjqFkWKxkLHA2nk15zZWsNoJcS7pWYsR6c12N/fRT2DJEQzd1zXBwsTq9z2AAGKUn72grWRoE801jSM2KjLUEmHq9tcyXJaKF2BXqBUDWV2UiIgbgYNdL57gYBqN55PUflWlkRqZtrE8EcSOu056GtMNVZsySB2PIqQNUuzGiUtWRq+n3N3LFJCm5VBB5rRLVGZnHAYgUK3UHcz4bHUIIAI02uD61JHBdxLLJcDGR2PFWvPl/vmmyu8q7WYkVV4i1NLSf+PVj/ALNRW8xiclTyD2qWw/d2MpHZDWXppledZT/HJgCpauVTdpXL2qQyyv5sanYTkmjdGs6/MOV6VfvNPu4mMIYvEDxisC+03Ujdq8Vu5jX9awcZp2aBTVtzdtrgKwXPFWy3z/Ka5wtqAx/oUoPrinxXV3C7NPHIABx8pqbNdClJHQ3ExROe9cFqMOoT38iogCDnI6kV1VvqcMqDzjhh0BokltUZpJGwSKFOwnqZVtpsEtiI9gaTGcGr9uIrS3WNlGR2xUAuYY7kSW5z6itzwtbRazfTySxZSPjcw4FTrJ2QkVrR4ZTkR7WFTRGMXjOq4OMGuw+x+H4CfNngRh1y4FZd3qHg6Bzuuoi3+y2f5VsqFRbCbRwupaXI96LhG+Qt8w9q09MthBO219ykdK1ZvEPg3BTzFPtg1Fb6loV45j07lwOcA9KHSqJ3YKWpq6vEkugwl1BHHWuccCEKVORjpXR6gUPh9Gm3+WCM7BkiuV/tHQs/NcP+Zq5UZT1RLkkydI4i29gNxqB4EluNwUA1dtItIujvt7h2/wCBVd/smGUgRSuCal0KiQe1iVoYra1tjdXzKkA9aux+OfD9ogRJ1IAxwK57x5/otjbWIc8nLD1xXACMDoK2pR5FtqJ+8ewj4kaKv3C5+iGj/hZmljpHMf8AgFeRIhBqwpA61rzsnkXc9WX4l6dIwQQz5JwPkrRuPEsGlWRu5Y3ZGP8ACMmvH7YhrmLB/jH869A8Rx58OgD2rNzfMi0lZl9fiZpp/wCWM/8A3xUyfEnSP4knH1SvMY4G3fcOKsssSKOm70rTmZNkep2nj/Q5JFHmFCx/iUiuj1K5SS0RY1BEq5Vq8QtrX7VkJt4r1DQbp9R8IlSc3VplfqR0/MUOXccVfYwGYrI8Tr86kginBQeCBmtXSILa81mGWf7kw6HufStHxta2Gn2kLwAJclgFC+neuGpC12bJnO/ZYpU+dAfqKytW0OC/SNPuhDkAVPLfSLGGzSJqClAW5rOM2tguc9LpbWEyxoq49cVt6JeSwO67Ec9uKvma3vE2bQWxWO8qWV55RVkZuhI4NdtKrCSs9zGcZJ3R0q3945wsCfgKmEl65w1sMfSse31a4tXQxjzTn7uK7ez1VXhVnjCnGcGq5lexSg7XbOSufD0d9dJcPagSR9DtrE1Twj9puzLteMYwcDivSh4jto5SrogFR6h4l02W2ZFeIMfeq5X2Fpfc83sfDVtBdxyztuVDnFa+sXljbaLdLZQp5j4TzAOefemXFxC5cpOhzngGsO6dpbJlUEDeGOayrrkRrh/fbfY569dbS3yfvP0rJt908i5GEB3H3rS1OA3WoAMcRRKPxqKTakiRIMAis4vQ1ktSuUaNSeryEn8K1tJs1FvJcyr90E1WWPzbqT/YAAro7K136HMccg0nIajc52O0NxJvkGTWvFZKwGV6cVJFDjHFaEMeMcUjRKxBHpyMwyo/Kr8OlRvj93Vm3i3OBXQWFrEOXINSzSMUULDw/ESD5ddfpmiRIoPlgY7U+zWJQNuK3bQFvugD1NQlfc0ei0If7LV4+gHtXNeINH2xFtmGAr0BEAGKy9YgWS3IIz1H4VTjoZxlqeQRxRXUjRNGPN7Z7n+lEMbxzFVkKSKeY5OD/wDXqXUla3vi6Ah4ycj+8KuNDBrVkLiI5nhHPvUg9GXbGSKYBJ4x9QK05VVICY2DAVz2m3irIYbh9yZwkh6g+hrTuZR5e5SDjuO496SDcdFaWevn7LeD54jleeua0LPwhYWbbolIPrXI/bHtNRjmQnBODWvF49MbrHcWU8aZwZGXiuyjdqxx1kovUo/ECxtrXSN2T5gYbaZ8OZIpm8oj58YNHj+4F9osUi4IZxUnw5s1LCdG6cMPes535tRwty6Hcf2DbRyO6rgscnmmS6JbSqVdcg9jWy9Qk1vdkcqOQvNFsbZwYowrKc5p1vFbXEqxzoNo6Zq7qA3SOPeoLCwe5kDchAeteXiqtZV4qJ1UYQcHclKKkm1Pug8VvxRCW1QEkfSsCQLHOyA9DXTWaMbZDtPSvQfmYaX0DZ8wB9MVWk022yT5YyavFCJASKZL3poTMe7t4YIiQgp2kYLOD0IpdUP7kVFpjYDn2oJZZ1C2VLd2U7uDxXg2o7P+EhnypB87ofrXtmoarbi2lRpShwRXhV0CdWmcSbt0hOT1PNRIqJ7foGnQmygl3kjaDiulmjhmQDpgYrhvCWpSJpsccxPAwOK6eXUVhUF1YZ6cVS2F1HJplt5jEljj3p8um28iYyR+NUf7WjTJw3NIdajx0ai1huRsWkEVtAY+ufWkNvD/AHaz4r9pYjIkbbR61C2rgHG0/nTFc1Dbw/3KSC2ht5TIiAGsk6x/sH86dbai9zMY0T8c0hmldRxSShyvJ60OtvDGWZVAFYd/qksM/lbMkckg1wvibxZJdTmyt5vLC/fcHp7U1G4nO2h1OpeMNGiuDbxxtLPnGFXOPxrC1y8ZNAu5kyobtXKaf9l+0D9+C5P4mt7xGdnhK4x7fzokrRM73Z5yJv3pNa9hcDzELfiK55Ml63bWIbFbPNYS2Geu2Gp+GI9NhF4sauVGQy1b/t7wqYvJUoYz/CEOK87s2S5tvKkxvA+WoVl8uXyyMEcGumnyuNyJNnpI1vwyqeWhG0dAFNUrubQpl3QO0bjoVyK4mNJZJf3cbtz2Fa0NjfMB/oz4+lbRiu5lJvsX7/X5YtLngYedHsIDY5rlPC+s4YWl1kRsflY106abd7PmtXK9+KqNpca7jGgBJ5THBqalJPWA6da2ky/r8GlWmki/R9k2OGVvvH0PrXP2MK6paPfQR4kUfvK0rO1ji06Q3a+cVbIibkL6VLcajFbaTKbW3jtt/BHHNc3KzrumjAZqiL1EZt3NMLk07GRPvprNUW6kZ6LAO3Uoaod4o3iiwEzNUWaYZKTfRYB5NG4VGXpVVn6CnYLmkJBDpczHutU/D1ys99aRf7ZNW/MtWszDcZIIwQveo7O70nTpA9vZ4deQ3etlSkzP2qi7EY1LU2fBmBqz9q1ZRnzAc+1VNPt45btUmchDxnNdNc2UaMkVu4fI9elWpy7mclFdDEXU9TXqqt+FTLrl2BiW2B/Ct6z0VOTcOB9DVHUra2hl2wMGI681alJ9TNtLoZF0kGspuQeVOnTHFcbPeTNO0MzE7GK812clv5MiXQU4U5YDuKj8Q6FYXksd/aqQSo3lO/pXNWp3lojoptcpzFubvBEA2qernsK6+y1S9g0b7Bpls4L/AHp8fmfrXPm3unZVACQr27mt6PxW+n2qW62iHbxuzUxjCL8ypc1tjNl8PS+S7ypLJIeSTnmodP0XZch3gbanJyK6uz8eacgK3ET59VTrVTWPHFpPayRWNqQzjG5hjFaWM7y7Hnmplb7W5Rbx4SPg4FdL4RdFuWjCAHHWs3Rp4NNkuJJYzI0vOcVcstXtrO4MqW5GfSplG6vcuDtK1j1qykEWkB2i8xQDkV4zcRx6hrtxHaR7UaVsKeO9dta/EO2g05rdrdyxyMiuVuNRtDcNPbReVITnO3vTjdIGryuU2t7vSrstC5Xby6Z4r0Xwc011ph1G7AVRnaPYd681eSSe4aWW4LBuoxXQN4luItFGnWhVFxjcaTbHbQzPFmqjU9YkYfcQ7VrCDCpv7IvbhiVnQk881o6f4N1m+XdE8JH1qrgo2MsUNmuqT4d653MP5mpf+Fc623/PH86Vx8pylqds8Z/2h/OvSPELEeGwynnArEX4a61uBMsK4Oe9dZf+H7zUdHNgjKkoUDcelQ/iQ0vdZ5wj3QwODUgtZpG3EZJrqE+HWsAAfbIvyNaFv4C1VQA91Ef+AmtLkcjOLjSW2cHkZ9K7f4f3xh1We0fO24TIz/eH/wBatK08BTrPHJNcI20527eK6y28OqbmGRtimI7gVGDScr6FRg1qclLixv7iD7hik3xk+nWpfFV9HrGm2stqDKyYL7eccVF8StE1W/uII9KiJHWRlbaRWd4N8Pa/bCSC5eKKE84b5mrOajJWZSTOfkmLxt2x2NRREylQCcV6PdeDYZQWlnjB9hiqEHhGyiY/6UuQfauWVO2xXJI5qGEwFXTO49Kq+JdQWHTD5qATdjXTX2lmGdY4cyIO6jpUp8KaVfASXqF2x0dulEINPUtI8usvFy2zDekhI9Bmuqttdn1C03RlkUjqRiurfwR4cit2f7PEABnNc1p9jFPcSWdtgKSdv0rpi9bkTVkY8mx5AHupXJ64NOltbZo8Rli59TTvEenPo9xGmR84yCKi8PI91qILZKoMn61q56XMVC7saFpoRRlaTj2rQudN/wBGnK5P7s4H0FbIhMjqo4Jq5f6e1ppd04cGTyWxj6VzyfMdVOPJseSX7EJn1AzVdomfUYgBxgU45c7HbPf6Vq2UCy3MRxzwDUrRFtXZWgiKXtwG9Qa63w/GJ4rmDj5lyKxdStjDdrOgypG18VY0u7ezvElTkA8j1FJlxRZktjBIVYcg1JGOa1NVWG4VLqHo4yay0pp3RbRZjbaeK0rO4fcBurJjy2OOK27C0YEMw4IpMuLOg0yYHHrXS21zgAVzVlAEIKnituAEipRZvQzBlqC/OYCw6jmq8TkDFSyPmMg+lU5aEcutzzLxSmy5ldflH3lYevpWFpF3JYX7yRAGGUYZc/d/+tXReJSodkfhcYz6ehrgROy3fBIaN/X3qETPc2tTn2XRdcCKQAjHY/8A1qht9VlhmSJ2JVjtYZ/Kq090LmzXdjdk4NQJEXnjZuxGapIzZqy3CSHg5wcCtka3pt2hs5EAdht5HU1z8Vq0t/DbwLvaRs4FWW8Ga+0hkFm2c5BDCtqLs2YYiPMkX7WBNU0i702Rt0sBIQn8wad4KvFsJpTcr5To2wjscUuieHdd0/VvMls5PLkX52JHWuiGlooklaIDnLcVrKCbvcyi3FWZ1I1C3kQMsgwR61E15AW2+aufTNebaxqK210I7afgDkA8CqaauLSUXBkZwwwST0rJzs7F9DuLy4j+0ONwOK2tPngXS1IZQcV5cPFFuwcZ5J6mpYtb3QbI5SPxpcyDU62SdWumO7+Kuwsrr/Q4+nSvHY9Vw53y9TXQ2fiRodg37o8YpuaEtz0Z7gEZYgAVTku4c/fFcY/ipXEiA8E4zmsybV2E5Bl4xnrS50Vc7PUZUliwhzUWny7FkB64rlLfWCBgy8e9WJNWVj8kvzYo9oLQn12GUW0si7MYJ5ryNfJkv/3jkcnp616DrMv9qWn2YytlupBrl18M/ZWWaOfMiNkA9KXNceh3XhzdJbRMwKFQMAjtXS3DfaVCk4ArkLeWW3tllZs8dakk8QMoUJ1I5oUhmnqjfY7YyqCwXqBXPvrrNkJBJke1R3utytE4Y5WstNYDyZVRtA5obYnY2IPGF5Gn2ZLfGe7VCut38l4sckQVWONwNZ0moQzQEquHHtVuxuIXWPzpFXBB5pJu5J18R2oMqGNWI7tocmNFBrLXU7PAAnT86rah4g0/TrdpprhAo9+tdfumepeu/MnST5vncEZriJPA5nkfF4WYnJrX0/xrpWpzCKOXa56BgRmt22tLaGRpoz80nJOc0aC1OIg8FvZXCTecTsYGtXxN/wAijP8AUfzrqpFjKHkHiuV8SkN4VuQOzf1rOp8JUVqeYRna2a0Le4k3rjp6VnoVD/N0rWs4EchkrGWwG5bQ3ctvvtoy0g5Fba6JLfCGdx5UvHmKe9X/AA5CEtQSo571ukAVrRilAl7lXzItNtwzYRR1NPj1qEqGF1GB9RTLy3ivLcwyjKmucuPDZJIhlGPQiquM9C0LWLa+uPsizRySEZwOeKuDwlHJdSTSTHDHIUDGK4nwl4dvrHU1vUuIxjhlx1FeiJ4htUmMExwy8EihPW6Y7XWpRuPB8ed1tNtdhhiwBrH1H4fy3MCRLIjbTnJ4zXbR6pZvHvEw2+tTR31pL92ZPzocb6lJpKx5BefDrVYs+RGrgdAGrn7vw/qtkT59jMoHfbkfpX0KJoD0lT8xSmKGRDnaw71LTQWTPmZtyNtKkH0IqMkk+9e96voWjXaHzoYg/ZlAzXlVxpMMGoSqoG1G4JqOdrcHGxy7ZU4YEGm7iegNdRd2MbbHZRmoBp6QzCTaCh9apSRPKzncsT0NKoZ22qCT7V1uyxkhYBV3jjFUC9vasfKjG41cFzESdinDpcm3fLwB2qNsIxUCrMs08w5fA9BVUxsSec1urR2MndjjGvkE4rMkZVbFWp7vy4tg61lSPuOc80OYlE6dL3TO+0VMuraZCCUk59jWKdMgPWm/2Xaqew/Gs7SNfdLk+qzzzlortlTsu6oknufM3CUMT1z3qEafbj7rD86uWulNJINmaPeWoJR2Lpj1SW1IECbG7lqsW1ldJbra4OO7Gt+wsxawKbiQsQPlXNTodsvmFR7CueVWUnaJtGnGOrMNrSCBQsmF+tR3XhvT5YxJJc9RnANW9Vgj1WGUoCLgHAA7VnR6Jept3yZUds0KPIvM0g41Je87I4/UbJLW8aJGLKOhNVxGK39T0uf7bl1Ij/vUkdhYqB5jsTWikramMo+8+XYwvKpEhJcYXd7V1EOj6feOsUVwyOxwM1ZTw9Lo+o7ZTvVlypx1o50xcrWo3RdEstR0a4M1qVmTPz4wR9K5N7TDsoJ4OK7pNei06CaIwud3oK5JGzIzlepJwapbErcdpeh/bWO9yqitweCYnXKzsKz7bUJo5AoAWPPOBW9BqMRABmerXL1JfPfQy5/Cc9lE0qT7lUZxmtHwdcSNPgOQu7GKfqN3EdOmxK+dp61R8KrGlmJZSVDdwafu3uhe9bU9QWVAMbhTxKmfvCuWjaBxlPOb6E1UbXdEimaKW5mjkU4ZWDAio54dzXlmt0dv5i46iq0Dr9sk5GK5VfEHh88DUiPqxpbTUtLuLthb37EdsNSlJDSZ3AI9amj7c1zSG2wP+JkyE+riuf1PXtb07WIbaxQXdvIQDMTjYfempIHc9PjUmtK3h2ruNcZZ6pq1ssctxbpNGfveW3I/Cuzhv7ea3RkcfMOh60m0VFMq3YXzWzjpXN6rE9xC6QMUY9CpxW3rE6QhFyN8mcD1xWVaXMf2xRLjaTjmplsOLakjIh0ieWDypGJY8ZJNZ8fhC40fVY5FneWOUEFWOcHrXoLT2cfQL+BqvNf27ddpx0rmSOiUuZ3OR1JhpVq1xNkRqMsQM4rh9R8WaXrKi0g1CSF2OAwJX9a9Sv7y3kt3UhSCCOa8rvPCllJuKoASc8fWuiE3axhUiua5m3ei6rZFfI1WeaOTqjOTT7NNXsZxcROquF28jitXVTPp1nbi3gkkCjBIGccVz7eJG5Dxsp9xXRGEGveZzSnK+iH6mur6xcB7qVTtGBgYFbnhnT3s7aVmOXY1zL+Icc8j6ir+meNYrNWjmTejdwaipTjy+6y6Umpe8dxau0sZfcMA44NSyzSSqUZyQRj8K5nQNehvpZo4yFVjkA9TW4Z40bDOAfrXFsd7S0see6ratZ6rJCRgA5HuO1aWgp5t5If4YwPzqbxpd2wgtZo9rSo5V8ddp6VP4ajWOyupW/v9fwphazLN2oOc1UijUHiqOparJJIywKcZ6is7+1LqD7wz6DFVYnmOsjmfy/LzlfT0qxFGoikYjnacVy1nq807YKhfTArpbOZmgYN1IpPQ0g7k0Kn7OMVtWc5ESoTyOlZSq62DbR8wGRVZdQeNQSpX2NQa2O1tZGVtp71t2coyMmvKZPE86OAoY46H0q3a+K7pWGWb6YoC9z2OOMOm4VFKMCuU0nxkhCpMOvU106XUd3HvQ5zSuFmjgfGEZV3/ALuc/nXm24/2kQeuOa9l8Q6b9ogd8ZAXmvJpbbytQLEfdyDREmotCnHKzrCDwuGP41fgdjMobuuax7mcI8aLxtatm2YNFHIDyBtqmYo7PwBai68R72GRCjPz2PQfzr1KaVbfbuXg968m8HaodIvrmYRGTcgX+tb+q+OwVWBrKYc5LKuQK1p2SMql7nbfbIvaqF4kdwsio4QSDB4/Wue0zWLbUgfIZiy/eUqQRV8yjtmquRYwj4A09iS13KSfemP8O9KkGHuJSPTdW/5jeppNzepqORFXMIfDjQ16SSfi1Sr8P9FXpJIP+BVsbmHc0Bm9TRyILmSPAOhg5LSsfdjVn/hEdIVNnz4/3qvbm9aQs3rRyILnFeJNFt9Nubc2wYxMcNzWTIkVzKvldV6103isT3FssFqN055APTFcbb2eraVL9ongDxA5cKecVDVmSxkl23m+Q4Csp4p6yOTx2rQ1nQLmeZJ40VSwzgGqQ0jUtowgGB1zU37itcrtqAi3DkN6GnrqqGAAsAwrLudH1MTvNNjb6CnpDZpEFaFy+eSQarQNTcbVnmsfKBARR1qlp8kd1Nmd22AdjTNSubW4sUito2jcDB4pmhwxLkT+ZwOMDrST0G7iai0aqwDtjJxmseK5Rm8tXHXkitW90q/uJWMcTtEemaNJ0eKwvvMvoX2Y9M0+ZJCIJFaOLKFiBVa4la4hVdxBFdfqV/pq6bKkMeCRgfLXD2yXBlfbbSuD0wtKE7gQtHKOjN+dUvsk99frASxHoTW4LW8YjNnKo9SKNPR7TWlaeNkU8AsK2U09BWsVr/w9LpsCXSfeTnI7V3Ohuup6ZFM07hiOcNWfrt5AukyKzDJHFcr4e8QXFhvhjgeZM5ATnFVsLc9MNhgEi5kOPes7XYPM8LzRknlh0+tUrHWW1CEsFeNhwVbrW3IwOiAkZ+b+tD1QI8zXQruaQCGJmHqa6fR/Cd+WXzFCj61tW7gdABWlbzTAjYxFLkuguKuh6jaQjZPtUe1VJ5LyzjaWW5UqvUYqzrnicaPbpHcs7SSDgAZrh9Y8VJe2ZijSUFmAyVIHWmnbQLHbpcPJCr5+8M0gkbPWoLU/6FF/uinZ561SJZ1WgOdp5rzfxL4gvtM8TXkcJUpu6GvQ/D/3TXknxAHl+Lbw/Q/pUT+JGkPhZq2HifVLk7Vjd/Zelaq+NItNmRNRglQnsR1rzG11u9sXJgn2+xGah1PUbnV3V7ucsV6YGKfMxNI970TxtoOq30VnbqxnkzgFT2rtPtENvE2IxjHNfKvh3UJ9D16C+tojNJHn92c8g8V7DZ+KfEOrxZTSY4Iz0aWQ/wAsUmnLYd0tWbVz400qW7mtYY5DNEcOAvQ1yGsarC12ZUBQfxA1JaeEorbUbjULm8ZZZ2LOsZ4J/GtA2GixtvaLzm9ZDmrWHqSWxlPEU11OPbVJ9RwsAdsHACgmrt0mrmxWNLSYkeg61066ha2qbLaCONfRQBUb6wSOCK1jgmtWzB4xdEcgI9dEWyLTHUdySKmW21JYxvsG3Y5y1dA2qE9xUTalnuK39j3Zl9Y/umHK2oiIKNObd3O4VVL6sJNw0/A9M10LagPXNN+1lqn2Ee4/bvschcWepzSFmtGX2FRfYLxcb4HH4V2omLGp4raef/VxM30FHsF3D6z5HJfaEP8AEKcYoinmSvhfrWaLCaXaIlYn2FbkOiz3FuiTxOu0dTXDztneoRW5VsrOG/uMQbmVTy2eK7NVt9E08zzFdwHArNg0meGONLORIFHUkZNR3/hp9RZTd6lM4H8I4FV7OpJbaEudOOzNTTLsXSm5llXc/Rc9BWhI6onmO429ua5ePwlZpgG7nAHo5FXRoFgFVXurlgvQGU1KhOMr2G5QlG1y/bTRRzPISMNUz6rbKDk9KzDpdnGPknl/76qlc6VbzAq0kpU+jYrblcnexjdRVrlXWfEttcqYo8AA/ezXPHVIM/6xfzrVk8G6W/UTf9/DUDeCNLxwZh/wOl7KXYpVIohs9QSSdfKkG4HIOa7XUdQkNpbSSgN2JB6VxL+CbROY7iZf+BVINAmCCL+07koOilql0pJmiqRaNyfUYmOFhDD1rOuJUm4SBU96fa6DdTERxXTM3vUc2m30DshcMV6in7Nk86GxOImyyBgKvW9yzv8AJak/hVO3sbydC20Lg4w1bEVzewQqggjOO4NNQT30FKo0tFcytavy1hIhjCHpitDSrYPoqxnjdHWRqtleXsnmMqqu4EqO9ddpVvGtuRLII1VO/anFJJkybbRzGia02laqonuP3WSrKxrZm1RbnV/PsrKO5DkZ+YZNcdfaXBfajcPaq85Dkb1PFWdK03WtPvEnt1Ee0/xHP6Vzqj1R0yr9GdHruh6fezxvADBcEfvEC4/P3pmk6P8A2ZKJDKD9RV/z5H/eXLL5pHzEVEZQx4VmP0rqhhtPeOWeI10H3drZ3dys8oLsvQZwKtrcqqhFUBR0FUQsncBR9aCnfcK3hTjHZGEqspbs3INRmjwEkIHpXU6FJJfMrMAuw8+9cDBdwocEjNa2ia5dLfzQ2ig8dW6VniYxlA1w0pRmdF4huV/4Sa23SYijhK49yf8A61YXiC6dLZ5IsoF6HuTTnZp9Qa4vPmdSenSuQuvETar4xh0rG23VvmHrXGde7L8Oq67LGMQMRjg5ro4NP1CazimNwA5wWStRNJhdF2kgY7U46GrDH2iYD2bFSWlY57xPaz2Gl/bbVyWj5kQnqO9ccviy3lVdhBkPQZr09/DVvMhSeWWRD1VnJBqifAOgqd62MQYcggdKpSsS4NhperabFpKtfPEj7ed2K4q51Dw/JfzO0sOC5Iqprk8dhfz6dP8AOqH5c+lc5JY2zSGRFwDzirUk3sJwsr3OujvfCtwzxymALjqR1rzLV7dF1W4WwJa1Dnyz7VbnubJHKjqPaoTfWvbP5VokjFnRaJ4dvTpH9oLOI2QZArGm1XUfNMr3DnJxntXU2mqeb4LmWDgBSvFZmj6YL7TAGXqeuK5+XVnpU6iUVJl7SNFn1PTLm8mLSAooGR905zWvokf/ABLrmJv+euD+VdFotutl4fnhXoFxn8awLD9zZ3D84e4fH0HFS00EpqbuQXgtdPhMjJkjoB1NYGrandwQRSw20ISRS2SM4Fb86i5k+fkelUrjS1ljVPMZUU5UDtQl3JlrsZOn3N/cWj3JaJdmGwF4IOfy6VsadqLyNtbhu4qAWot4ZIkdyJDlz3NP0yyWLBCkAcLk5pNIUbrc6q3mZoecVUvXWNThcnHAx1q3bxEQiobmBmyR1qWjo6HLXtzcwQyzxSgyBggAA2g/1xTNA1DUdTuYo5Hjw5ZRuj5BAz+VaLaPE4eNgQjdQDV6w0ZIWDJI47ZzzinpYzcZt3TLVneKLh7eaNFljOCUORXa6HcyggDJT19KztK0CzmTDo4z3HFdHp+jrZ8JI7j0NZ210N7q1majoJ4mVhkMK808SaMIZ5DEPvc/jXqaphcVymsW7S6qItpbOAOKNibXPPLLwbLqS+Y+Y1PT3966oafpWgaQYjbG4lk+Us3QV0Fz5dlcJbKAqoBuPoKdq1rZX+kzwWswkdx5kX+8KLmlKEVJcy0KOgDTdPinMtvu3yBkyM4XAxWjdeI9GjiaIQAMeB8leQ+KfEep6XqMNvaybU+zRsylc84qXwl4ie7vJjqksYAA2lhit4/CcGIjy1ZI9AmvhpGrWcluse28/dPn6ZBroVEUvKkfhXnF7c6Vf+ItLje53W4clgG4HHFdGZ7K316GHTZj5TjDgNkZppmR03kil8oVm608tno1zcxSsJI4yyn3xWfp9jqV5Ywzy6rMGkUMQqgCnzIdjoTEvrSiNRXH6/bajplmlxHqtw37xVKnHIJArqILdGgQsWJI65pcwuVloIntTZEXYdu3PbmoxbR+/wCdOFtH6frRcOUyrHSXS9nuruVXZzhVB4UVZudPgnieP5cMCOau/Z4/7v61FdRILaT5cYU0iloZOlaQ1pbCKaUzspOGJzx2FaH2JP7grP8ACTM2iqzsWJduSc9zW9RYL2KH2CFh80Sn8KadMtcf8e6flWkMUYFA7mV/Zlr/AM+8f/fNH2K2TgQJ+C1qcCjco7ClYNDGeO2iGTDx7LVGe900cNCx/wC2ZrpWdD1XP4VC5iAz5Ofwp8qE2cdNf6QeTZu2P+mRqD+3NMQ7UsZc+girsmMZB222fwrJutLknuPNSEJxT5YibfQxP7XgcfLpd0f+2VZeuRNqli0dtpVyJuqEpjBrqTp2pg/I8YHutJ/Zern/AJeox9I6FCG5N5Hk03hbxPcqFe0bA9XFdF4Z0K90i1ZLjTN0rHJbcDXdJo2psfnvsfRBUw0a4Xlrxz+FW+V7isznGtnMbf8AEv8AKJ6tkcU69XytD+XJwR0+tdI2mSmMgyluO9FhYO9mVKgEMfvCpVlsDicPbPKTxG5/4Ca6LSraWWVS0bAe4roks54xgLH+VSj7ZHyqx/lVc4ciMLUPDst5qHnvbh1VcLk9Kry+FVmiMb2Kla6j7VqH91KeLq+7xKfxrJxTdyziZofsp8nbt28YqONC54rev9Nu7q6aXyOTTIdEugeIsfjW0WYuLLOgAgle+ai1XwzBf38k8tmshb+IitfStPltZC0i+9bG6TPyoMVNSKmXC6PPm8EaewIbTV59hWZqPhPQILdkktkif16GvTrq4eCEsANwrg9V0O51p2uGYKvUDdURpQWsmOXM1aK1MOzg0uwIaJItw4DYGatSa3EBtSZVH1rgNfvpNNvGtA/K+lYp1CdlLGQ12xqxXwnHKlJv3j0i51ZcE/aAx+tZ76vn+KuAOpSA8vUsd5NIflOatV2Q6COzbVOfvVH/AGkSfvVk6NpeoaxciKMhF7s3aupl+H19ap5jzs69yOKzlibOzLhhW1dGcL0k9akFyD1NW4PDC7gZJW+ma1o/D1hGoYuc/Wr532F7FdzEhMkrAIhOa2bTS3kAaVgg9KZcfZ9OI8qRWz2zUA1GSYgKT9KqMrnJVjNOyOjtYdNtSC+HYevNS6lr9ta2L7NqYHGBiuXlmmjjL7HOPY1wWueIJbyQxI52jg+9KdSyJpYaU3qz1wRwWcWViRB2GKpPetI3A4pbu4t3w0sg+gNU5NasbcYQBiK5vrDT92J6n1dP4mXkM8o+VcCnG2uTnkViSeKG58qMAVUfxLdtkBgKr29di9hRRrzzSQttfgiq/wBt/wBqsSTVJZjmRs1H9rPrWyqu2pi6SvobpvPekN371iC596eJ/en7QPZmwLo+tKbg96yVnx3p4nHc01MOQ0vP3cUoGRmqKzgD2pHvG6JSbuK1jYjvGhYPGoRgMZFQyzmRy7EZPWstGuJ2AUMa0IdPnIzJ8opx1CTSWo4St0Bpyhm6k1J5EcXqTTC53gYCj1q+VLcyU7/CSLEvUn86LiZIkeJWEm9cY9KY1zFGQGy1ULmUJKWiXANZVJRtZG1OEr3ZNaW5tgBEqqPerTyov+tm/AVjPcTOMFj+FRCKSQ4zS9rZaFOld3Zrtf2sZ+Vdx9zSw6h9olEa4Uk4ArGMDKfmp8eYmDqcMO9R7aRXsY2NPW5J7FVRjhiM8d6x1upZcbnbn3qa5le5JeaQu2MZJpbK3EmMAHnrUSm29ylCKWxAX2NlpdvuxrX02e4tGaa3YO5XIx3rmvF2hahsFzEQ0CDlF6/WtD4fXks8DwsNxT5QTUNlqPY7IX90fB93qCxg3ESs5yOMivMvBN5NfeO7e4uG3yysWY165dO1j4P1OGSD5XicggeorxPwwb3Stdtb8WkjJG3PHao6Mvqj6ijQbBwOlOC1wS/EAhRizbp601vH1wfuWePq1KxpzI9AxSMPlNedSeO70ji1H/fVNTxjqkzBREi596EhORwvxDKr4vucyFTgfyrAs917cJbxXB3PwNxrsdc8NS69qL3txc7ZHAGFHArPg8AxxyB/tcm4Hgg4rRGT1ZzV/oNzBfGDy3lfGcxqSKhbQNRGP9Auuf8Apma9RtNLubKMCO5Un1ZcmrJh1J/+XuP/AL90XYWRxvhzTL63tpbW6tJo4JehdcCumsbKOzRIIRwO1WpIdQx+9vQUHYIBWj4fsvtV5luVXqaI73Y3LTlH6qy6X4d3ZwZHA/rWEi7tLiOPv5f8zW/8QrSSbSbSO2A+R2JPYcVg2sgm0u3YdNgH5cVnN6nVSj7hSKENTiGx93FTkc0xxhTUl2KpQNWtoVskmoRh1BUc4NZ0UTTSkjovWtO3UxyKynBHehl04XZ6NcaFbXtgDGqxygfKwH6GuOurR7eZopVwy1u6b4j8mNYpzkDjNaWoRWeoWX2pcO0Y3HB5I7ile6KScXqcK1qWJKKSe+BVqyhZHDMqgZ71be5WKQ+Uo8s9sUsHky9QR7jqKhlWN2ynQKoJxW5b3EYXBIPvXIwxMhysmRWpbOwApBynQ+aCeKcoRmBKgt64qlE2VGakSbYSxOAATU3G0ZniC3iks5rqMfvVIR/pmuTs7h4r2GOMndvGPzrfumuJ9JkZBlZ5dufQZpbXw1FZ3EN087SvkEKBgZo32OiDUFaTOT8U+AZ9b8Qy3iXMcUeFUJj0FSW3gCziVRLHE2BzjPNegNp8FxKZXJ3N1waX+yrX3/M10JaHl1JXk2eRar4SFhrdmLWdES4baox9010+leF2sbmK4mvd5Rt3TGa7J9G092V3gRmX7pPOKlFnaqfuCizMjnfEl3E3h68QBixiIAAzninaPq1mmkWqljkRjI2njiuj8m2xgomPpSCOzUcRp+VHKO5xfivUEu9MSK2illk81CFRCejCtqG/YQoPIkBx6Vt5th0Vfyo+0Ww7rRYLmR9vftBJ+VH9oSf8+0n5VrfabfsVpjXluvdRTsIzft05+7ayH8KiuLq7eB1WykJYYFah1C3H8a0w6nbg/wCsAosI57w9b6jYaasE1o28MT19TmtgG+PS2x+NTnVoR0cGk/tiH1/SiwxiJqBPMQA9zUywXjdVQU0azEegP5Uf20gP3W/KiwEv2S677alW1kxztzVU62v/ADzb8qT+2ifuxN+VCsBc+yP6ikNm394VRbVpe0Rph1W5PRP1oHZmh9kPc0fZB3NZp1K6PYCmm/uj/EKAszU+zIOpo8mL1rJa8uj/ABr+VMM90f8AlqtArM2xDCO9L5cHtWCXuW4M4H0FN2zn/l5NFxpM6ApbgdqAbZem0VzxglY83TU5bM97hvzouh2Z0HmWw6sPzppntR/Ev51h/YV7yt+dH2GP++T+NO6Fys2ftVsP41/Omm+tl/jWsn7HGOhpTap6CldBymk2owY+8KjbVYVGRn8qpC3UdqcIR6Ci4WJzrcf91vypj66qqSEfj2pvkdeBUc1uWiYYxxRcOU5LXvGNxI7QW8bL2JNc0fEuoQWzIXkA7CqfjFrvTtRYRRsdx6iuRl1y7VtsvX0NaJqSsYvmi7plfU/tF9qDzOrEk96ZLbSRw4KmrsWuxggvCDVk+ILYjm3B+op2sQ22c9FZTSvgI35VsW1pNBGAsLMfYVKfESIfktlFKPFcqD5YVoTB3Z0Gka9caXEFFk24d8VsXPj/AFSeExGFgmMfcrh/+EwmPWFPyqeLxSz8NGoz7Umk90WpSSsmbsfiO6z80LZ9xVhdSubxgrFlX2FY8Wpy3C7lC4+lPF7cKeHA/CtVUMHTudNDFawr5kkbO3q1W4tUSFT5dtGFHc1x5u7uUYaVgKzNV1SW3i8kSHJ681MqsvskrDwfxs0PFXi+5uEa0hbyk6Ns71xAG7J9abNK0rZJzmtPQNFudd1aGxthyxyzHoo9altvVm0IKCtE0ZNc8w/NKT+NRnVIz1cfnXPzW0kEhVlIxURBoGdKNTjPRhR/aSf3hWx4X1bw4NP+z39miyIPvOoO73zWR4i1TRp5pY9MslVTwJMYH4CpUnexXKrXFGpR/wB4Uv8AaUf98VzADnoDWto2g3+sXi29nbSTzEbtiDJxVNk2NdNQjxkuMVIl80zbYUZz7DNXNF8KPcXTx3qGHy2KtE3DZHXNel2Gi2VnCsccUUagdeKLsLI83jstSlXK2z4960LLQNSuJ1R4SB1612+sS2VoiCCZXbuBT9Guomuo/wB4uW7ZocmlcqMU3Y5lfCGryHIhG3PTdXV6D8PjNG0l6uAvpXXxxCIBi4INJNqU1sjJFIArdRXJHFTcXLodLw8L2RyV9psGnDEcO1ezEdaxLm5jXJYius8QXSPosisQ0nVQOua80u4rqTliEHua7cBjniKTk42seZi8CqVSyldMmudVRSRGu5vQVxur+IdW84+XBJDGP4ih5rqtHhRbzcxDmumlsmuoGEdqJF7nFOrVbdjSjSUVocF4a11tQJhugpcdG9a6W4SIwMScMOlcde6WdJ8TwzQqY4pHwV9DXXyQllDn8qyT1NmiiI81OihO3NPXaDjFSmLjIqiSsYt5NAsw3WpgwWnJJk8Ciw7mTrUJg09/KBDHgY9a0vD9i8FtbQtzJxyfWtayihLK92itGDnB5q/aizufEEa2xPk45x6+1JrlV2CfM7ImvtKtpLUokpM2OR2rkfCWnGx1+8iC4VnyPY969vGkwQ6TLFbwK8jKcbu5Nef2WmpBrEszjAzz9ayu7am1rPQ6+PSUudONtPh0cYIqqvgzTgMCFQPSrMepxxIAG6VINZTHU0Kw3cq/8IhpwHMK/lSjwrpijHkL+VWG1kdgT+FMOrntGT+FVoIgbwvpm7Pkr+VH/CP6Wn/LAce1PbVm/wCeR/Kom1eXoITRoKw86Rpi/wDLH9KT7Bpq/wDLsfyqA6pcHpDR/aN3/wA8xT0CxP8AZ9PB/wCPQ/8AfNBSxHAsif8AgNVzqF1/cApjX14f4QKV0FhupC2FjLtsip2nnFVfDWyLTpHC/MM80zVL65Fm+/GCMYpvhpydOkB6HimmJofcyLeaFcb/AJpI2y30zXIxJHDahIxhQzcV1VvbtBqJjbmKcFWHtWXr+iNolwsO/ekmXQ+1RLe50UmkrGT1qGfpUmQBVWdi2QKSRdyNbsR74xwD3FLpSvZxujTSTBnLgsc7c9qr+VzV22jKxkmm4ouFR7D722a+CkXE0RU5BjbFdX4civzp8m9mKMhQM3G73rE0nymuAZ13IOdvY128F9CwUJgADgdKzcTZ1NLJHOXFpPbzeXIhHoexqWCNwRgHNdQzRTqFbB9M0rWMewNiiwufuY9urg8g1p2oBOKesKLnDU6NQkuRUsLmhGMIBVDWLkW1k4B+ZxtFX4zkVzOrNLqGqx2sPRTjPv3NSxx1ZXj1WcW4tiR5YOcYrft9R/4l5ONzj7ornRpxF5NE0nyxNt3Ada1IgIUCIOPerhEK1SK0W5P9uu8cRAfjTftd83dRTfNNJ5prU4WS+feEffWmF7wnmUCmmQ0nmGmKw8faD96Y49qCjn/lu1M3n1pMmkFhxhYjmZvzqI2ak8yMfxqTNNLUAMFog/iJ/Gj7LH3yfrTtxoyaVgAW8Q/hFKIY/wC6KTcaMmmA7y0HQCnBF9BTOaORQBIFA6AUuKi3GlBNAEwXNO2VErEGpPMagBDGabtp/mGoySe9AC7fekKikyaTNAAVFKBikzS5oAeFX1o2r/epmKKAHbR60YX1pmDSFSaAJCcdDTdx9aQRn0o8pqLiDefWlEjetJ5TUCJqBtC729aUOfWl8pqPJagVhRIfWgyE96QxkdSKb8vdqAsc54k0R9RiZ4QDL2zXld/4T1lpmLWbfUDIr3jC46ilAhPUCmm0JxTPnC58P39mubiLYB61SEfrivoLXfDunatbssrhTjgg4rxTxFpcekai0MMnmJ6+lXGV9DOULamT5Qx2pjRfSgyAetOiIlcL0ycVdzMjEP0qeEIrqXA4NaUmjKsKsLgFiOR6VXbTSOsi0gOoi1PTfsQRI1D7celVFIdsjpVLToLKDd9qG8npzxTJfLSVmjmZYz0UHOKVh30L93dJaxZJ59K5m7ZrqQyHnPSp7ktK/wAzEjtmhYwke4n6UCMxoXHavS/htZGzZ7grmVyFGPSuCTaX+Y13vgXWIbXUFinP7tjwfQ0nsXDcwCI7oGOWJQe1ZdxpW1iVHFah5bOKRySKLisYX2VozgpQYSDzH+lbIX2pWUNjIFUpCsYhBXov6Vt+GfFN/wCFdSa9soo3dkKMsgyCDUckS+gH4VF5A9qG0xWaJbzxPqN7qE99K7iaZy7FTgZpp8Sai4w0834vTPsw9qUW646CndBZjTrVy33mkP1aprfW54nDhpAR0IaojEvoKPLA7UNoFdHUaf4rvJ5EjkuplT3evT7jxZo//CNQ20a7rjAyx7H1zXhMfDjFbduSyAZNQlFNOxTcmrXOovNe8xisfNYlyZrhy8jkj0piKQc4NPZuOT0rSVWUtDONKMddx+mTr/aCwL1HJr2C2tooNGhjCASEZJrxXw29vLqTtnM5l7+ma+gbO3judDQFcPt4PoawlfmOiPw3PJfiDpqpHHdRrghgTj1quJA1vEc/wiuo8a2THRp0bBZRkGuQtgfsURkwDtFVEiQ54wwyOtRguOMnFStKoGACfpTAzMeENaXIsRnPJxmk89kHCYqbyZW56Uot1BzJIBT94V0VZLuZ1xyBWr4Iv0XXzuXcF6g1Xa90u3j/AHkqcU3wleafN4sP2bhHHJPc1FW/LqXSa5kez6hqMkNizwgZIwPauctlUliygk8nNb8ESXEDxk5I7VllYI5XiVh5inBX0rJtWNorUiKp/cH5UgYDjaKewqMikUxxYegFMaQCjNRtQA4y1GZKa1NoAcZSKTzzTDTcDNMCXzqPNzUfFKhQyornAY4zQBU1OGS6hEUY5Y1esNMews1hPU8muktdHgjUS79xxmsO9mJunw3AOKfQm12V5I3jBk4yvNUvF8xu4NNuD/zzZD9c1PcSMYWGT0qPUoBc+Fo2DDzIX3bc8kd6T2LW5xrd6gVd2SelTv3qlcHcmznB9KEaIbPe2luDvmQEe9RxazZMuBcRH/gdRDRbaUltoBPqM1Kvh+2PXb/3yKRrAswa5aW/SaEjuC2a0rbxNp87KguI0cdCHrMg8P2QkBkBK9woArTbQ9HEQ8q3cP6tgg0rI1Na31N1YFJg6+xzXYaZqC3dsCevQivNxYwQkCCIIfVeK3NJupIJlBPB61ImjsJgqtuFIGzioJZg8IPemQS8cmpbJRovMLe1klPRVJqhodofmupR88h+XPpViSMXMSxMfkLAsPXHatCFQq8DAA4FSXsjDdVM0r45aRj+tJkVIY2JPFHlGt1scctWMHNLgU8RGneV7imSQ7RRtFTeV7il2IOrc0XAg2CjAFTGNPWm7FHai4EWKTbmpsClAHcUXAg2mjbU5AowPQUXAg2+1LtqfA9KMD0ouBDtPpSFDU+RRuFFwsQeWaUIan3CgEUXHYiEbU7y2qTNGaLhYZ5ZpPLqTNFAWGCMdzThHH3NKQKTAouKweXHS7I6bgUEYpBYfiP0o+T+7UdJk0XHYkJUdFpNw9KjJNGTQFiTI9KN1R5zRQFh5aqVxftACRBI2PQVaoPPFAHPzeJpYif+JfcYHfbWdL4zulzt0+X6kV1xjQ9VFRtbwnqi/lTuJpnCXPjTUmBVbXYffNY83iPWZGJWRl9gtenmytm6wofwpn9nWgPECflVKSXQhwfc8u/4SXWgMec//fNVptd1lutzMP0r13+zbTH+oT8hSHSrM9beP8qfOuwuR9zxiTU9TkyDcT8/7RrKuYLi4fdJuY+pr3r+x7H/AJ94/wDvmlGi2J620f8A3yKXOHs33Pnw6a56oaT+z5EOVVvyr6FGiaf3tYv++RTv7G04HP2WLP8AuijnF7I+exa3jHhZD9Aad/ZmoPjEMx/4Ca+h102zX7tug/4CKlFpbqP9Ugx7U1UH7JHz2nh/VZCAbWcD1K1FPa/Z9yn7y8HmvTPH/iuLTYP7Pstv2mUYyP4B615ewd1CAkkn5iacW3uZyiloiOJDI2TworVsfD+pasSLO0d0/vHgVreFvDbardIXU/Z1PJ9a9jtLSKygWKFAqqMcDFTKRcKd1qeIj4a+InckRxj6vWhZfDvxBC4bfCpB/vGvZSaAeanmZfJE+X/t10Od1H9pXQ61IbtP+eS063V7yQxxQgt1+lanPqQ/2pde1H9qXXt+VaP9iXhGRCv5006PeDrAPzouh2Zn/wBp3J9Pyo/tK4Hp+VTy2k0H+st2H4VAJIlOGj/SnoKzJ4b+4kYAgflVi4unhTIIJ96qC4hHRRSmaF/vLn60WQF6wuopgTcOqmrlxNYpGdku5vQVkRta55hFXopLID/UgGpa1GmOt/nYMeK2reRUWsY3EQ+6uBThfBe360BY6SO+CwSR+Vkt0b0qA8IzHsKxBqjjhStRy6hPMChfC+1Fw5UX/ChI8Q7v7zf1r6atImh06FHIGVFfL+gzfZdWhkI/iFfUemzRapptvMv3So4/Cob980S9w5HxRaqlhOWkLRnkk9q5F7SySNT56suPUV3HxBjSy8K3kvQbcCvl2a/uySguJNvoGNaRZnJHrsl5pqNsEyA/WrMCae/L3sQz23CvElaaRvvOT9a2bPw5qN6qmLzDn/ZNU5CjHurnrLWOny8DUQv+64rL1Tw5YS2U3l6lIZNpK4fPNc1Y/DjVboZluTCPfmup0zwHfWA+S9iLYxuaPJrFyfc2UV2PJN7xzNHMW3qSCGroPDl59j1SGVWxzXaXPwqW/vHubjUX3uctsQAVatvhXY25B+2Ttj1NDkmgUGnc3pvHH9n+V5J8xnA+UdSa0rTUYz+/l4lk+Z+O9ZUHg61guUuDI7uowNxzWubBSMFv0paFWaLra1YomSMms+58RWWMn5QKa2lQvjczVFJoNnLw4bH1pqwalWTxXp6/cYufQCov+Eohf7sMh/Cpm8K6bnIRh9GoHhmwXoJP++jT0F7xENfZhlbZyPwpRrTMwBtmUHuSKl/4R607GTH+8aT/AIR2yzyHP/AjRoHvDjqKkdVH41GdQQDJkTH1p6+G9OBz5RP1Jqwug6eBj7MmKWgalI6pCB/rV/A05dQjccMD9a0F0Wx6C2jH4VOmi2o6W6/lQ2h6jLPV5EjKNOQp9TUTz27PkuSfatSLRIT/AMsFFXI9NtogMon5UhnOGe3wfvEfQ003dukew7ghGOQa6vZbRjhFP4VXuRDOmxol2/SiwHmd3EI5mCnKHlT7VnOMGvQtbsbT+yZ2EQDRruUjqDXAyruziixaY1JAg5pftJJwqZqHyyTViKDFFkWmyzbefK4CRlj6LzWgkM7cCJ8+mKZpty9lKHQc5rsIdVhngDMAD0NSzRNo56KwlbllxVuPTCrg5OK1HmjP3SKpy38cR5YZ9BUsfMyz8yLhnJ4xilhkzJtXnHX2rM+2y3T7Y168ZrVjVba3CA5Y8sfU1DGjRgOWFaWcW0hHUKayLV8kVqk/6HIf9mhDexmGQ9M0m6hu9NrVHOx26k3GkooJF3Gmk5pelJQAUtNozQAtFJRQA4UlJRgmgBwNLmm80nNADs0U3mloADRRijFMAzS5pKSgB240u6mUtAD91GaQUpFABmjNJSZ5oEO4pKTNGaACkoJqKSdI2VWPLHAoAmopKKACkpaQ0AJSEZqjqFzcwRf6PCZHJwBU9j5/kA3BBc88UgJ9tKBing4I4qcXAUf6oUwIMGl2k9qmN23aJaPtbjoF/KgCPY/900ohkJ4U043Unt+VH2mQ/wAVAB9mmJ+7S/ZZO5H503znP8Rpd7EdTQFyRbVscuo/GuZ8aeI7bw7pTN5oaduEQdSa0dY1WHSdPluZnCqi55NeAa7rNx4g1V7qcnywSIk9BVJXInKxTluZ7+/e6uXLyyHJJrc0TSpdSvUgiBP95vQVl2dlLPcxwwoWlkOFUV7X4T8NR6RYKXXM7csfeqk7GUI3dzV0fTIdMsI4Y1AwOa0SaMcUmDWZuLSUmDS8+lAHyy0co/gb8q6PQUitLV3mYB5PXsKjGq6e3XH5VMt5YSDh1rocL9TkU7dCxHqiW6lGkDAHg1FLr8Y6Ypvl2E38SH8aDpNlIOAPwNT7Ir2hWk14OMbQazbi7WVifLX8q1n8PRMfkYiopPDcv8D5+tPkaD2iZhs6n+EUwt6DFbSeGruSUIGQZ7k8VI/hO9Xq8R+jUBuc/vPagTOO5rb/AOEXvT0Cn6ZNWoPAus3AHlWrt/wE0roOVnNGaT+8aaZXPVjXbR/DDX3AJgCf7xqUfCvWj1aIfjRzIfJI4aOVlcZY1ow3C55rrl+E2rMBm4hX8DU6fCPUR96/jH0WlzIahI5eCcLKjDsc17x4B8VQjSUtZmwR90n0rz23+FMqkGXUW/BBXT6X4LTT1Cm8ldR2rOTTdzSMZJWZteOZJvFNn/ZllKFh/jk65PtXFWPwt0+IhruaSY+nQV6Db20dtGEQcVIQD2pOTKUUjn7Lwlo9iB5VnHkdyMmtiK1hiGI41UewqfFL0pDGgAdBS5oop2AcDxS5ptFAhc03NHNGKADNNzk0v4UAe1AxuKXbVmG0muM+WhOKlGnTA4YbT70CKQTNOEJPatBbSOP7z80/zIkHygZpgUFtJGI+U1aSwOMuwFPN0/QYFRPO56mgLFgQQR9TmlMqIPlAqpuJ70A0Byk5uWPQ4qFnY9c0nekc4ouOwbsUMc1i6t4m0vR/lurgeb2iT5m/LtXJaj8SX8l2srURoOBJIcsT7DpTFdHSeJ9csrC2+wyyA3V18iRg8j3PoK4vOG+tcjp8txrnjC1aeRmklm3MScnjJ/pXXEYYg9QaT0Kg7kiYzVqPAFU1qYE+tK5qi4hAqXziBwcVQBY96XLA1JdzSW7kC43GmpmRuTkmqqZq/Zx5kFIDVs4vLUNjGKnaXLdaMgQ8VTEnz/jUsqJtWr8itpxI2m3HlY8wRllz6jmsGy+bBrq7GIi0llbptxzQlqOTsc5FcrcQrKnRhnHpTs1RtW2SzQ8/u5CMdsZq6DWid0YTVpNDqM0ZpKCBc0lFFABRRS0wCgUUUgHZFAI9KTtSigApMUtFMBcUYAozQTmgBDRRRQISk/CloxQAlLQBT1QsQAMmgBopTWxaaWpQNMOfSq+oJbRfJGvzetFhXRmmiijFBQYpKdSUCEIzURt1ZgzDJHSpsUYoATFFLiigBKKWkxQAmB6UoFLijGKAACilpCaAAmkzTSaaWFAD89qM81GWoDZoAmWkuLiO2gaWRgFAzk0gYKpJOAK8s+Ifi1ppG0izkwP+WzKeg9KaVxSaSMLxp4qk16/a3gYiziOOD98+v0rBt4gib2GSfuj1qukY69hXf+BPCr6jOmo3a4hQ/ukI6+9aPRHOrzZu+A/CrWsf9oXqf6RJyAf4R6V6DwBgU1EWNAqjAFLWW+50JWVkFFJRQA6kpKM8UwPk7NGaNpoxW+pyChyOhNSLdTp92Vh+NQ4oxRdgaEOs3sJ+WYn61pW3jC+gI3RQSD/aTNc7RRzMVkd9a/EREx5+k2j+vyV0Fj8RtCfAm0yGM98CvIaKTd9xrTY+iNO8b+HZcbIIFP4V0Vt4psZFHlLEB7V8rq7KcgkGrdvqt7asDFcSL+NLliWps+pW1SK46FR9KbvU9CDXzzYeO9Vs2AeTzF9663TPiYjlRcKUPel7O+xSq9z1jIpCa5nT/F9heKMSrk+prehvYJgCrjn3qXBo0VRMm3UhenfKenNNKiosVcTdmgnFFHagAzRmlApcCgBtGMU7FSLCzdjQBEKXFW47Mk/NxVj7PAg5waYGcqM3QVOlo7dRgVa8yNPugVG9y2cA8UgsILBR956UJDH0GTUTSluppoNAWLUd60DZjwKZPeSStuLc+1VSeaYTQOxN5meSabvGaipjME5ZgPqaQ7E5fJpGJNZtzqlraoWeUYAJ/Kuc1Tx1BBxZgzkA/dGADjjk+/8AKgTsjszIEXLEAe9UL3XbGyHzzru443AdfevJ9T8Ua1qMpKuYU7Kh9sf41gvBdz43zFm6ZZs4FWokOa6Hqd/8Q9PhU+TJvbAwEXPf1PtXI6t8QtTvoTDazG3XkFl+8eeOe3Fc21kAMGUH15ojtI84Mq1SiQ5tkcO+ZmeZyT1LE8k0lzMtwNir8qnC1dFtCBlpVPbg1atdD+0pvglC7TgMVzzTJG+D7dYPEsc78mFdx/2QSF/rXX6xB9h1IgjEUxJRvQ9xWb4c0aO1vrqMuzvNDtZjXXi2h1vSBHcDLY2MR1VxwT+fNNwvEqE7M5gc1KtNngk0ucW10SQf9XLjh/8A69TIAeRWDVjqTvqhyVKFyKao5qdRxUmqEVa0LX5eaqquKsRNikOxdeX5cA1DGCz5ppYBcsQB71t6RoU16ySS5hgPPPDMPYdqN3oF1FamloOnvdsMDCD7zeldTKFMsNjF04aT2Uf40zfBpVokUMY3H5Y4l6sf896ax/svS7q8uGzMEaSRvfHAHtWqhZGMql/e+48/gl36peEMCDM+B7Z61fLY71g6SZPM3swKtkgfz/Gtdn4rNBLcnWYEU4OD3rOMpVsdqbJcGORcN+FNMVjXHSlxWbHe5BzT/tyg4Jpk2L9JUMdwkgyGBqUMD0NMB1FFLQACloFLxQACijNGaBBRTsCjAoAbRS4paAExRinYpaAGYNWrS5S3OWTJ9ar0EUAac2rF4ysa4J71lOSxyTk07NNIzQ3cErDaWmmlpAJRmlxSYoAXNGaTFBpgKDRTc0E0DHZpM0wmigB+6l3U3igUCFzTSaWmODSAazDFR7qcRxSbaYADSg4NIBWL4j12HRdPeVz8+MKPU0CZl+OPFyaRZm2t3BuZBhQO3vXkEQa5leRyWLHLMe5p+oXU+rag887bnc/kPSrmnabPqF1HY2gJZvvNjhR61olZGEnzPQ1PC/h9td1IJtP2WI/Of73tXt9jaxWdqkMShVUYwKzfDui22i6bFBEACF5Pcn1rXDJ/eH51Dd3c2jFRVh2aXNNBGTyKMikUKTxRu4pCaO1ACg5FIOppM4pCcUCPljaDSFKYHNLvNdFzkHeXSGOgSU4SCgBhjNIUPpVgEGnbQaLAU8GkxVvyh6VG0RHaiwEFFSGOkKYpWAZSg0YpKAJ4rqaFgY5GBHoa3dO8ZalYkYlLAdia5uinzBY9Z0n4kpIQtxlD6122n+JbS+QFZVOfevnEMR0q5aanc2jhopWXHoaPdY1KSPpqOZJRlSKmEZboM14rofxBmt2Rbv519a9P0Pxpp96i7HXd6E1Eqb6GiqrqdClpK5+7gVaWwVR87c02PU45V+UgUNOWGc1m1Y0TuTCKCMdMmlMwAwoqkZCT1pDIcUiid5mz14qJpCepqHeTTGY460XGkS7hTC/NMzxVa9vobGAyzNgdAO5NIZaMmOppjzoi5ZgK4zUPFPlsA7bWYErGvYeprNPiFpRmRmCY59eaLMV0d1JqcMZ5J/Kqra2pcoiZO3d7AYz/AIfnXDy6xAJmSeaRURGGRyM9AP5/nWRf+JZZDi2ygycsep5/lwKaVwckj0K+1wW8e+e68kYxgdz0+vX+VcjqXjhv3kdn5jnBHmP9cA/l/OuMmmmnkLSSMxPUk1HhgmfaqUTJ1Oxoz63dXHzTSFicnBPHJrPku5WYEtxnketNA+T5hkDpURUufYdfarsiLtkjSzu+QxCnpUbvJx8x/OpSP3Y2jI/xpmwgH/PvQSRKHcgbiKsJvGCOWA/z/KmIRHICT2/z/OpVZmGEGM8ZP+fUUDSHxqssoVjk9Rjv6V6FYaetvp0Ea5DKgz9e9cTptuk99CEzkkZB7YPNejD5VUnpThqN6Iy9IbGv3MZbJVF/XNbcUzabqm5v+PS7YBj2STt+dc1pk3l+ML3JyJHWMf8AfOR/I12YtorqKW3lTfG45BrXeOgvglrs0W7vTbbUbZoZ0Dqw/I1x2oafdaFJlw0tn2lxyvs3+NddpUrwBrO4ctLEPlY9XTsfr2NXpZIpEKOm9SMEEdazlDmV0aRnyOxwkM6SqGRgatxuDSeINCtNNsptRsZPsyxfM8bN8hHt6GubtNSur25itrZFaSU4U7uDXO4tHXGomrnVhlA5IqxYwy6g2LRN6jgyHhB+Pf8ACrWm+FYQFk1Gd7mTrsHyxj8O/wCNdVBFHFGqRIqqowABgCqjSb3IliIrYpadosNswkmPnSjoSOF+grVuNUi0uAyuDJM3yxRL1dqztT1ZNORURDNdy8RQr1Y+vsKNN0+VZPtd+4mvZPT7sY/urWigo6RIu5Lnqbfmbvh+0uJGbUdRbfdPwij7sQ9BWb8QdUFtpS2obHmOu/Hp6V0fmpYWAdv4R09TXivjHxINT8RpZxPvSIlpXHTd2H4UpLlViOdzldmvpYwgBTaeCBn1/lWk5xxWbpBVrVCMYHAq5NLjOCOKwZsipMzrIfnznoKimdngJOQ68j6Uy4lDNzxx1AqpFOUlYSk7TwfQ/wCf60CbJ4r4MVUjBPf3qys43YIrAnE8F3ImwsuN2fUetPFy3QHGRVCudB5qx8jjvxVqO6IjDbq5eO/c4DHP1q1BeyMhQ4Hcc9qVgudRHeAqOanW5HtWBBKPvFverK3GeR607jNxZQaeDmsdLjAGTVhLjHei4jQpRVRbjJqdZc0wJs0Cot1PBzQIfSigVYt7Vp29qAIKQmtb+zYwuScYrNuFjRyIzkCgE7kW6jdmm0maAHbqQtTM0ZpALRTc0uaBjqKbmlzQAtFJmimAUmKWkpANI5paRgex5qCeSaGMuqh8dqALFJ0rkr7xdPbSFBabT7msyXxnqDqVVUU+oq1CTM3USPQMgd6aXUDJYfnXmUviTVHOftTL7AVTl1K9myZLmVv+BVXspE+2ieoy3ltH96ZAPrUD61p6cNcx5+teXh5H+87H6mmvtQZYjjmmqZLrHfah4x0yxgd/MLsBwFFeP+IvEdxrt+zsSIwfkTPAqDWNRNzMYos7Qe3es1sQJk8uaOVIlzbLcR8sBV5c12GgSz6TAWjAWSTksRk1haBppbFzMMk9BXRtwAPSrUb7k3a2L0mt38nW6f8AA1CNTvM5+0y/99VTop2QuZ9y+Na1FPu3cn51KPEWpgYFy1ZOeaU0cqDmfc1h4l1Rf+Xk/lT18U6qD/rwfwrFHNOAyaOVBzvubf8Awleq/wDPVf8AvmoLnxbqkcZdrhVGPSs1sKpY9q5PWdRM8hhjb5R1pcqHzy7nP0Vd/snUB/y5T/8AfBqOTT7yIZe1mUe6GpuFmVs0uaCrKcEEfWkoEPDEU8Smoc0oOKYFkSmnBwarBqeCDTuBMQCOKQpTASOlPDn0ouFhrR+1RtGRVkMD1pGANOwFQim1ZMeajMZFLlAiopxXFNpAKGIq3a6jPauGjdlx6GqdFO4HoWhePbm3KpO+5R3r0rSPFNvfxjbIMntmvnUMVIINaVhrNxZSBkcjFOyluCk47H0rFcLJyDUrPxXlXh3xwH2xztz6mu6j1qCSENvHT1rGULHRComa5nVASTVOXUYlPLD865HW/FCQho4m3N6CuMutYvbhi3nFc9hUqLZbkkeuHVoFGTIvHvXE6jqy6trJmZ2W3iBWMA9vX6muMe8u2G1p3IPUZqS3upEIBPFVGPciUuxtXCmeaSUgBn6/TtVGaGVI2CN97qO1TRXG4dac0gI5Na+6Ze9c565MvmHexIzTc1fvkBORjNUCMHGKgB20Bc5pjkAYPSnEnHSo5PmHpigCN3JARRnPFTeRshwWBZuw9/8A9VLa225S8mefukdqdLEVI9MZz/KgaIACuQemOP500FsH0z0/z9alOSdw9eBnr3qVIQHw5IXPOO3alcLFTYWbaRxjGf0q0iDy9rE7T2Xrz/8AXqSYQE7YkKlR8wJz9elNjTd7MOcjtQNHQ+FrdHvppDGFEacZ9T2rt4UWeEjuK4vw1E0TzY4DKOK6/TXIkKk9qqApnJxWc9xrerNDuV1ceUR2deR/L9a7PQ9UTUIUlxslU7JU7q1ZWlAvdaoY1y32o4/Kpr+0k025XWLRG2ni6hHcd2HuKqN0rmk0pPke+ljf1W1nkSO5syBcwnKZ6MO6n2NJp2s216JI3Rre5iGZYZOqj1HqPep1u1lsFmiIdWAIPqKxtVhjuozI6bJFU4kQ4ZePUfyok7O6IVmrSOJ17VR4tu3jjmcWyMRFEhI/EjuayLez1PRL5RGruAwwewP9DV/T9AlsrpblWYtnKbeq/Wuxt4FvbVlnQIR94Hg/WuSdbXQ7Iwilqdn4fvl1XR4bpgBLjbIo7MOtGoa0ltKLOzUXF+/CxL0X3Y9hXK+HXuIpLmyiaaCNwHPyAuRnGRzxn1rqtOs7SybEFs6M5+Z2XJb6k1tCo2kmY8kU3J6j9M0oWrtdXD+deycyTH+Q9BW1ZJ5k6luFHJqmWDHaOlZerazMpGk6Xhr6YfMw6RL3JrXSKI96pIi8Y+Iprmc6XpjASbT5kvaFe7H3rzEW8MN+yI3ygcFjyeeSfc10viVf7E0ZobZsu7gTzH70rnnH071ylyy6dfwOJDJK215Q57jt9KylfqW7Kyjt+Z2NlJ5aA7lAPJU+/wDnpVmeXKDHIqhG4YBlQIpOVA56+nrSPLI3ChWHT5WrJlJjZZGVtxLDI7nHHrVZrnaOGIbHYf0pzN82HypA7DtVSWSONjnnrkDP5UJA2Xdont0mG4sM5Pt/+vNUioK+YoIKn7vTirVpcC43QR9GX8P/AK1ZctyonZCSMHBB7UyWTNMFTgrknIFSwTqpDkhj6Csqa5BTbjJJ7VHJcKyh1JQ7QCCaZNzrbe4DKUzlSM/SriO44xkY7VylhekjgcDjrW1DdEDB6jtUtFKRrKzEduR0NSJPkgZGay/tKgcHBPNRW8ztM5U/KGHB7/Sgq50STjd1qWS7EMW8nGTgVkQSBnI3c/Wq+p3ZOoWloDxgyN/IUDOntpS68nOavJzWNZHCrhiQRnmtON8UXFY1LW1M7An7orWREgTjgCsOO7kjXCnAp7XsjrtLVaaJabLN5fFwUTgetZrGnFwDzTCc0mykrDc0UYoxSGIaSlxRigQlFLtoIxQAUUmaKAFoooFAC4oxSGlzxQAhpHAIwaWgigRj3+gWuoHMi8+orN/4Qq07SyfnXU4oxTTaBxT3OQk8ER7hsuWx7ion8Dvg7Lr81rtQOaWnzsXJE4YeCLtVz56flXD+K86XMbITo8uMtt7V6d4y8TR6DpbbXH2hxhF714TcXEl1cSXly5Z2OSTVxlJ7mM4xWxHxEDI3U9BWp4e8O32u3PnJbu8KnOccGmeHNBuPE+rLCisIEOZGHYen1NfQmlaXb6VYx20CKqooGAKJSsEIXPNv7B1G3UJ9jcAegqKTTL5fvW0g/wCA16ycbulNZVP8I/KhVWinRR5GbG5HWCT/AL5NRm3mB/1T/wDfJr1/Yn90flTDBEWP7tfyo9q+wvYrueQNFIv3kYfUUwqw6qfyr2B7SB1O6JD+FRHTbRxzBH/3zT9r5B7FdzyNck0/pXqE3h7T5GybdOR2FedeOI7fQ0/ctgtwFzzTVS5EqbRzOt6r5cZgiPzHriuZyWOT3pGkeaQu5yTVuws3vLhUUcZ5pshH0EllaH+FalGl2kg+6uK4Kw8Z287BROMnsa6mw1eKUAtOn51nymvMi3c+EdMvFIktomz6qK56++FmlzgmKIxH/YOK7W2vIWAw+6tOK7hAHK0uVlXTPC9R+FN9Dk2kxcdg6/1Fc5deCdftSd1g7gd0Oa+nhdROOQMfSoZo7aQHKLn3p3aFyxZ8py6RqMBxJY3Cn3jNVXR4zh1ZT6EYr6ok0+3k6oo+grIv/Cun3iESQRtn1UGjnYeyR82h2FSrKMc169qfwvsZwzQAwt22HH6VxGq/D/VbAs0IE6D04NNTTE6ckc4pVuhoINRTW89rIUmieNh2YYoSYjg81dyCdT2p5UEU1GVulSY96aYrEDxcVCyEVcNRuOabEUyMUlTOmKiI5qbAJU0UDOeBUltbNIwOK1UgWJenNA7ENrCYMHPNbUWqzpGI1lIH1rIdjmmoxDUXKSNVpHkYsxJJpUGaihJZBmrC8UihfKGKYU2mpwRUUxwCaQ0LHNt71J55NZRnwx5qZJCykilcZPcOTzVQgnB6VNvyemfrSLluoFBLI1Rxzjj605xhe3HNWPMVFyMHAqFlJycYHUetFwJIpQ6nI2t/KmOSylQTt9vzqCRXKmRecH1psN4Nyo/J9PWkhE0cJyPmwc5HNPm2q23IIyBkDg1K7jd8pIA71WlO7Az7CmMnhs2PQ5z1ppIjHK59c96SKd0VsE4wOtSonnR4JHfJ/nQwR0vhZRKsxHtz+ddPbL5d4B6iud8L+XCrAn5nwT6cV0sGJNQGOgFVTJmV/Cq7ob+U9WumrfwCGBwQe1Y3hVcWF173LVpzMY24q4bF1/jZhPenw5ctBKGOmytmNxz5LHqp9qbql+g02R0mTbL8quG4OfStK/EFzausyoYiPnDdBXFabosV6DNBJK+neYXjVz97tke1RUfJF9gjao13Ox8Lm3lYGQgkDluu76VbtbdbuSW9I+SVj5Sf3VHr7/yrBiSDTjLJBaxSMF29D+6J78Uzwl4tjudVk0iaNo2JPlsx6sOo/HrXNQ5XK6OitGUYp3OktQLXxhboB/rLRlb88j+VdBcXMdvEZZpFjjHVmOBWHD+98TXjqw3xWihM9iTmmweH5b2UXOsXBuJDyIlOEWulX1sQ4xduZ20Qsms3mqsbbRYmC5w13IMKv0q/bWMOi2jCImS5l5eV+WY+v09qtTXFrpcMSHahdhHFGoxuPsKguJVYlicmqS1uyZ1Pd5YKy/M5Xxpbh9Gik5zHOpPvXG+IGMd6XQEMqggj1x3/ADrtvFs4GhSqRy7qq/XNcDqr+fqch4CjA59hj8aie7EvgXzN/SdVS4szF8isg27U6gfQ9fwq5aTkZMnzYP5/XvgVydvEJmDCRRJGMfN3A9a1rG5DqxmVztGAM5x/UCsrFKRqXDR/aC275f0rM1GR4kA2gA8Z7itCORSpIAP+0WyR+P8AjVDUisUSqHTb/cHT/P0pWG2Q6ffGKaNw2455xkml13bBeCYkBZhu65ye/wBKz4izyBQMAHICjBJ/xrW121+0eHFlXcXtJBkZ6Bv164o6k9DBExk601yWDcVUinVSB1749f8AJqUykgAjk8AetWkRcnt5ZI/uuQTwa3ob8hvMaXJAxjH61zSEqQV/HNWoJVWUCQkqOCeuBQxo6T7YHiViSD24qRbh43LOCCRggjpXP/aDl+rIOhBq2rSzKhZyM9STk/WpsUmbcV+sM6s2RxjnjpVCK/8A7T8QXE8JzEmyNSfbr+tY2p3ZWLy1bkZyQaPDN0ls53j77Z/IU7WHfU9L0+RhAoPUVrRvnFYulyLKgIGOBxnpWyg5FZmiLiHIp2BUacCnZqhC0tNpe1ACZpQaKKAFBoNIKWgApDRRigBMUuKMUtACUUUtAhKMUtFMAxRiiigAxRijNLSAAorP1vVbfRdPkurhwqoueauzzpbQtJIwVVGSTXhXjXxPJ4i1Rre3Yizibjnhj600rilKxma1rFx4h1OS6nYhB9xSegrMtbS41fUIrG1Xcztge3uaikdmYW8IJJOMDqTXtXw68FrpFit7doPtcoyc/wAI9K0bsjGMeZm54S8M2/h3SY4UXMpGXY9SfWuh708gcDFNxWZuIVFIVGKcOaD0oAZtprD5qkpCPnFArjcUirxUoHtVa6uY7K2eWRgqqMkk0AU9c1i20bT3uJ3CBQSc189eIten8Q6rJdSkiPOI0/uj/GtTxt4sl8Rag0UTEWcTfKP759a5mGFpXWONSzscADua0jG2rMZyu7IWCGSeURxqWY+ldzo2mLZwKzD5yOa6vwP4EhtLZbi+jDzSDJB7e1d02iaeY9htkwPQUcyD2bsfLfKnIJFWrXVb20YGG4dce9VzzTCK1ZkdZp/ja/iwJmMgHvXWab4yilA3uVPoTXlCnB4q5BKRjmjcL2PcbXxEJANrjHua1oNT8zBJz+NeG22oTQkFXPFdDp/iho2AkYipcS4zPYI7sN3qwsm6uF03Xo5wMOPwrprW8V1BBrJpm8ZJmqTmoJLeOQHcKckocU4nFTYs53VvCtlqMZWWBHHuK8/1b4ZOhZ7KQr6I3Ir2HOaHRWHIoTa2BxT3Pmy+8O6rpjEzWz7R/EnIrPWdlOD+tfSl1pUFyCGj61x+tfD+yvQzJGUfsyjGKpT7mTpdjyATBulBatXWvCWo6O7Hy2liH8SjkViI/O1q0TTMWmtGPPNTQWhkbJHFTQWu8g9q0o4TEvSqFYWC3WJOlJLikaRs8U3JY80mMiK5pVj56VOseamSIUi7iwrgVPikWIgU8oQM0WC4wtiq90xMRI5xTLuRlB206yYzR/NRYL2KEa72yauqoCcipxaKr5FTBFx0pcouYo7fanEeg571fWNOvekaNQKfKFyjH8uTz09P84qNpGClTgYPBH+FXiq9McVBNbeYOKXKFzOnly2EJJ9aWCzGUkY7mxux6f41Y+yGL5hycck0udqEKMe+KWwC724HvTX6nH5U6PBQ5xgHp61GcK+QDz/n/GgB68Jg9T/n/wCvVqDdtwABxn/CqoVnI2jJz0q3Ek0c6qylcjqetDGjc08lYhgEAf0rpdIugtz+8b7w4JrlYdQsoo9rXMYOcEbvSrI1qwjfatwhxgcc/jUxbTKkro6jwzMv9m3HI/4+XrQuJlZCQelc1YXUPkH7NIoDncQp71NJLdLyBuB9K1g1azJq3lJyRka1cXNxdXViJCLaSNDIo6nk8Z7A96s6Fr1qB/ZMbqJ4xhcdCPQe4rI1T7VM100AKyYUHPBIwc4rM0nRisiXkylSpyidDn1NZVJJtps2hSfIpI9P0S1NpqAuZV3W7feRh1rF8U+EIdO1eHWdImYxGXc6f3D1yD3FU4fHUKTfYLljkcfaVHAPof8AGuuZ3udKSNiMfe3eorilCdOSlE3jNSVmVPCl219f6pdyYDZVCPwzXTR3yx2/zHLL8u3ucVwXh+8Fnrd5EAFjuPmK+jDofxFb09y7PlFr0aUk4XOSt8ZUDTa34kN8X/cWWY0A6F++PYV0kVqWALmub0hJtMa7DshSWdpUAPQHHX8atXWqvsO+bA9AcChTSCom2rbIyfGNyJriC1hXMUB8yR+xboB+HWuAuC5um5+Y85/z0rrtVuUltCyupOM/KcjFcezEyKVJJzz3/Ks73dw6JF+yGGDO2NvKEDv7VaukKwfaoVZZMFXy3D/j3rPjV2ww3bAecn/Oa0VvdqKgUcZJPf6egpARWN5tB3HI7knkfiKt3rboAcg9+OfwzWZcRr5wnjQIG6qOM46kf41bMmbXdw4Ixwcj8x6UDuVrOUxzq7Pxnrj1rpzd28umXcEjAAwtkjGR+H9a4uS5EBPQMec+3rURmuJQ3zkJjG0HjHei1xXsRBsMzBThjxu/T9KnV2+UBcMfXsP/ANVNCgRgtzgc8f5+lPKuBubv1AH4n/CrJJEIJ+bA4wKcik528jsfftUSozYyAvJyasRymIoc8buQRxUjLFtwpBYDJ4pJLlY1dckuvQ56/wD6zUckwWTCjaGPGew//VUWwTnduwc9Mfl/jQFyresVj3nJ4+b/AD9auaQrF1fb2GcD1NVr4bbXaM4JH/1qvaUzAblwON39BTewLc9A0a6BtEY7Q5zkfjxW7bXO5RkiuDspHjxJjcqdMdeP/wBddDa3m8/IDtxkE96yaN4nUCQbc5p6SA96y4bg7Bu4zU8Mm6Tg8UFWNDNLSDkUopki0UUme1AC0tNpN1AD6SkzRmgB2aCabmigLBS0lB4FAC0tIORS44piE70uKSjNIBRRIQgyeAOtNeVYI2kfhVGSTXnfi/4gwxWclrpxLTt8u7sKFqJuxm/ETxi08raRYPx0lcH9K83kkEEWxT856093MStPKS0rknJPet3wT4Wl8SaoJZlP2OJsuSPvn0rWyijF3kzofhv4MN1Iur30Z2f8sVYf+PV7KuI1CqMAcCoLWCO0gSGNQqqO1SluazvfU3UUlZDi2TRmoyfmpc0AKp4pSeDUYJHSnckUCY6j+IU0E0rNtAJ4oAc0gjQs3QV4t8R/GjXc8mk2Un7sHEzKf/Ha6L4i+NRptsdPsn/0qUYyP4B6/WvE2ZnYsxJYnJJ71cV1Mpy6IM16n8N/B3nsmqXie8akdB61zngPwnJruorcTJ/okTd/4z/hXvdlax2duIY1CqvAxROXRDpw+0yyqLHGqqOBSk01jkEU0NkCoRofKVIwp1BFdDOQi71LG2DUR60oNCYGij08tVNJOKm38daoRZttTuLGQNG5x3Ga77w94oiukCtIQ/cGvMZWptvdSWswkjYgioepSdj6NsbtXQEMCK1Fk3LmvKvC/idbmNUdwrjgivQLG981Rhs1k0dMJXNgAUuajRty0uM1JZIM0jAN1FA6daZJIEU5pAUr6xgljJYA5HevIfFugWsFy08ACNnkDoa9B1/X47KJiDz2FeZajqVxqUxaQ4XPAqoRdzOpJWsUrbCACrqYbrVRUx1qUSBK6DnuWGhQ9qryIqelNe7xVGa4LGkwRObgKcVJFdjdg1l5JNPUmpKsdJBKjAVM+NvFYNvOyVpxz7161V9BFa4AJqKOXyjxVmVC1VWiINIe5Kbsmk+0MelVipzT1WlcpInEzetOEpPeoaM0rjSLAf3qaNuKphqmjei4+UnkXIyPrVRwDvPcnkfzq6p3riqkwMb7lA9KRNiJRkcLggZ59c1FtAZanCtLJ5at82OMVCSUIGOQfyoAsI5DEgYNOTc0m75mPYk1XjYjJxnt/n8KuQqGKrnmkxohW3ldmJ0mNm3Hkt37f/XqzFHqG4iLT7eEY4JxnpjOT6cn8avw+G4CD/pFwMns/r1qdfDkAxm4uGHu/wDntxRcu/kVI2ljZWl0/aTz5lu3Qf55rQt9TmiOBJu/2ZRgj8akj0C3RfklnU9Rh6SbSbhBhZhKAeBIKTC6ZoJq0LbhcQgjAxlakaTR5V/eRRgkZODj8K5+S0uYcgRt83Uqck9Kg8uVSGJdFUcArkDg/n1qbFJ26m8mn+GElWQWsW4jcDk8frV+PUNKgh2R7Qh/h3EiuUYybo13Z2tuBKe/+eKYkcrIoO/BfIwvf/I/SnYLI6saxpqBmhijG04yE96iuPEQVT5acgZyxAFc7HbzOHJjk+dsMMYBPp+ZNXE0qVipW3jBB4Mhz2oFoR3OuzyT481uVyqwrk/SoGld/mm0q6nHykl2PfrxWtHpFzkf6WIgDkCFAMe2ajk0aeNcpqU4OMc/XIoBNI5O6ks1lTyRcwMQuYyeDUkXL+YTjP5AVY1O2vIpN0t0JUBwQy881HAjkISjAE4BPH/6qZDL5YCIKN24fePf/wCsMVnOxCsSPl7Ad/8AGrkwKKWcYXse35VVdUJ+YZUdR/iaQh8U6MV3hfQ55H4+tXIbC5vsw2s0cTZ/d7vlAz6+lZvClQv1yR/L0q/FeGLnIx146D/E0x3RkXNnc2F29rexGOYc4bjI9R9aSE5PH3R1+v8A+uure+tdeiEOp5V0U+XL/Ep7Anv/ALtc1fWFxpbBZUIU8q3ZvShPTUTt0E3MOoye+e5//XU6S7o13vwOuP8APrVNW3opdieOFWlh3FCowQMde3pVWEXUYEBlORkgDPP+c05w3l4G0Y7qOT61D5mVUBcAYA4/L/GrCMMc8rgYz/n1qRjCq+YPN53cHHb1pw4ZyQFOf8/pTd0ZYh8nac+xx1/WrTnzcnvjnA/Oi4FC+csiDAIyOPr0q5px2yEBgVHI9OOBVC5YoVB2ls/rV7T3MYBJOeCB/Km9gOhiiEakg/MRjH+feta0RgiAMT+NUI2EkhZ8Eg844HT/ABqa3BiDoGJUNkewxjis2axdjbWUtEEJwQOPer1kdpHcGscyBcbj/CAK19PfdErdOOKRpe5soeBT6hjkBGKlzxTQhc02g0dqBAaQUcUGgAPWlzikzQeaAE5JpelGMUdaAAcUuaWk4oAUEUZpMDFIBQA8YPU0oGDntSBePeor+7isbGSedgqIpJJNAHnnxG8X+QjaTZSfvGGJGB+6PSvMY5htLSDOO5p2r3kepa7dXMIISRyRms+4lydingVrFWRzTd2WrK3bWNVhtgwQO2AT2FfRHh7R7bRtLhtrdAqqv515b8NvBr3t3Hq14hEKfNCp7+5r2gIFUAdBUTd2a0lZXEY84NLgU0jk0UjQAPmOafgYqNGxnI70rNxxQAmaeG4NRJkKBTwCQRQJokReBzXMeNvE8Hh/SGcsGnf5Y0zyTWlrus2+h6VLdXEgUIv+cV87+INeufEGpvd3DHb0jTPCLVRVyJy5Sje3k9/eS3Nw5eWRsk1o+G9AuNf1SO3jUiIMPMf0H+NUNOsLjU76O1tkLSOccdh619B+EfC0Hh/S40CgyHl27k1UnbRGUIczuzW0PRrbR9Pjt4EChVA4FaDcSHB4IpxNRt1U1mdDFzzTUGCR706mk4cH1GKBI+VVpTyKYpqQV0HIRMKZUzDioiKQD0NTZ4quKeDxTuAOcmoqkNRmkBYs7uSzuFljPI7eteq+FvEMdzCvz89x6V5FV3TNRl025EqHjuKTVyouzPoy1vFdRWgmCuRXnPh7xEl5Ch3jPpXc2l2roKzkjojK5eOVGaxNV1AQRMSegrUuZwkJOe1ec+KdULMYEbr1qbXZTdlc57WL9r66Yk/KDwKyulSyMDUDHFbpW0OWTuxS1Ru5xSF6Y7U2JEUjZqLBqU80m2kUR4pwpcUYpDuSI2MVaikwBzVLpThJtFAjXSRSOTSkKe4rI+0EHrUiXbFsVQF5oQTUTJtqaCbfwanMIcUrDTM4timGSrcloc1Vktm9Kmxakholp6zehquYnFNMbj1osO6Zq284zT7lPMjODjHOayonZW5zWpC4kjxSBorSMEYFeMAdOKiLZJLcg85qS5QgjA+tRiNMHBJx0zQQTRYIOcYxk/1/oKvWyFp04I55471QiG1hkY9QPb/69alkQLmBc8ZOTnr/AJNJjR00A+Uf57VI33B+FRxMuRj2qU4KD3x/OoGSJwtKx6e5xSD/ABpxxlf94UxEa/f/AM/57U4BX28Z/wAgU5QAfxP86SIYC/T/AApFCLEpEZC8jJGPf/8AXQI1ABC8biwH1z/jTlfaAfRc/wCfypc8EA4wo/OgYwKu4YHBJY/5/GpU479B+pppALED2XP6mngDlv8AaJ/ACgLDlweR3qK4+7+lSJ8qgZ6ACoLljtJGD1NAjldYfB57tmobC5mJWIHK54BAOAfr0+tN1qQmTHocU7TYRKQNueyjryf51RIl6nBJkD4+9zwPx71WSU52MMH2HOKv3sEsTtlRuJOQTyP8KpkgLnjB/WhAxg2sTwMeh/zzTsBt3b1Oen1qNmHOOCKVd2Ny4I6YFMQ1y8aExg8c/T3H+NbWmagtzCun3kQkjdSvzc49MDt9awmZt/HTPQc5P9a1dIQm5BZAFJ2s7NwuehJ70Ma3KeqWcelai9vF+8R1zGxPQH/CqYXa+1G3ZPJ6f5wKkvb37ZfzSD7inansopI0LMoYgYOCf50+gE5BIBH6/wCfSpowMjHTHT+VQtgYAcZBwSff/wCtUittJdiCSAR7Z/8ArVIC7VViRjnGPoOn61J5gI24JxxzUSbny2Dg8r/IU8LjAH4c9P8APNAFS7wJYx2Pf2qdW6NyR6dOaq3X/H0i4JGOfanruxgnAHX29adwOgsL1d8e1iM8c/p9a3FmBwQFPQcDgr/j3rj7IBmGBg7s5966yyV2WMkqUztJ/D+dQy4lwI7PGAflYjBHf/P9K3bf5BtXoOKziq+SBxjkjmrto4aPI9Tx6VDNYmpE+cc1cVsrWWCV+lXLd9wwetNDaLWKbS0oFMkTFJTj1oAFMBOgpMU4jnpxRikA3PagClI+bNAU0AITilGDRtyacseMmiwDTwcU4YoAzzS7e/agBrSrHlm4AHWvIPiH4ubUZjp1o/7hThiv8Zrd8eeLhZo2mWbZncZkYH7i/wCNeTI/mSvO/RemaqKMqk7aIZNi3iCD/WN1r0zwJ8PYZ7L7dq9uHMoysb/wj/GsX4f+E313Uv7TvI/9Eib5Aw4dv8BXuKIsMQVQAAOgpyl0FTh1ZXtbeK1hWKBAiKMADsBU3NNAwMZpc4qDYVTkZozxSDpQQQM0CAdKWheRSlTsOOtAxEHyikurqKytJJ5SFVVzkmjeI0LtwAK8c+I/jU3zvpNlJ+6U4mdT1/2aaVxSkkjA8b+LJfEWoGOJyLKI/IP7x9a5WNGkkVEUszHAA7mk616f8OfBZmYapfR44/dKw6D1+taNqKOdJzkdH8PPBi6VZi8ukBuZQCc/wj0r0E8JwOBTYx5cSoowoGBSn7jfSszp0SsgOKbJwhPpzSqdyg0EfKcUCEBBocApx1BzQoBUH1pdoNAHycDzUymoBUimtzjHkZFRsKlpjCmBFT1NNNKDzSAfTSKdSGgCOilIpKQF/S9Ul024V0Py55Feq6J4nintlbzAOPWvG6mhuZYPuOR9DRa5UXY9l1LxLGsRCyAntzXEXl4bmZpGOSa51L53+8xNTi4JHWmo2G5tlqSYCq7zVE7k96jzQKxL5h9aN/vUOaQmgLFgEU7NV1bFSBqBklBpuaXNFgAimMDUg5oK0AQ7aVV5p5GKTNAFqCTZjmtKG5BGCaxN1OErA8GgLHRqysOcUNCrdqxIr1k4J4rQgv1fAJpisLLAAelRCNSeRV84kXIqtJGVNIY0WqN0qSO0KdKjSQq1XYZgRzRa47so3MLEdKpBSuMdjj61vuFdelZtzHtPy0rBcqnAfKj8PfoP61bZlaLbKxi28bl6mqib1kxjr0yf89qvItxIyi2VS+ON3Qe9QyokSvaoVxqVyOnIHTjg/h0pReAKAupXAGF4I9DwPw61oJZ6s2D5Frx2IHPt+PWg2OrkAbLXj2HJ/wDr9KWhrqVo7kOCTqlx0II29Rnkfj2qcTATZGqzHDg5I6nsfwq1DYauuflte/8ACO/+HaiWx1MnIt7b6Af5609A1IftMnHl6i3c/MPc9f8APehtQuYkwL0HKE8L9OPrTUttTWQZtoT8x7df/wBVTJY37JnyIc7Ov9frS0DUrtfz7D/xMDxgYA9aRrmUv/yFTy2M4OOO/wBKtvY6jkgW1vy2MY9ulV/sN+zY+z244JzjsP8A9dGgWY5ZZS6n+1WxktkL+FBlCjadYm2nCn5e3+etPisdYUbUWAcYyR0/+vVj7FrXBxZgcnG326UtB6lFpww3/wBsXG7JONv4H/61U550VHU6xcY4X7h5A6fhW0bPWQMZtAcDovp+HeqdzZ6sYzl7UDn/AJZ/56dqegnc5+EiUnE0kmWzlhzmt2ycQjKMwYDBIP44J/wrIZZFcrM48zPOwYFadsrCEsvVOc8Zz6egoZmWtTZ3Ik2KA3bH9P6mspy27DZGf89amndtwLEnsTk8n+ZqrnLk5bPbjp/hQhMXy+MZwPpQpKhiODnGTTmk9+Bx9f8AGo/MPclcdM/54piJIk4ySOTjb3x71Y1FhZ6eTtAkcYXPUfQdqhjj2lVAJfrkf54qrfSGebbnKx8DnuaAI7KPzADtJA56df8AJq3HE44xhVPzY788/rU9nCscCuMDcCQTx06fTJqdmRYuuWPI4/Lr70NjKpjjVyPvZOMj82P8hVmNSpwFy2ck+mev6cVXEe7kjI9+4H9SakWQ85P3uDnj6/rSAsfM7nCAnP05/wDrCo5FYgZbjGBUoyDtaXBPJx+tI4ABI5J5JNAGZKQLrLHPy1NECYyoIYHr7+mPqapyPu1Db0G3Gf61fgi5yB24+p/+tRYZLCfKQsDkZ/P/ACa37bUCISqxglQM8dQfX/GudBEafMuCDwP0FWE1M/u/lAwOB7dB/jSY9jr47kzP94jOOCeCPStSyJUjjqea5qzlDeaqgSSRtuX14GOncc1u2smQrbhwcZ/SoZqjcUbhjvmpolZTycVXtiG5J5q1sG7IJx3qSy3HytP6VDGcGputWQKBk05hgCkFLnNMApG6U7ApnfrQACncbcdzSAgUmSWzQIcBil56etJmnL8zbu1AChK5Xxr4ph8OaY21g11KCI09a29a1a30bTpbu4kCIi55r561nWp/EetyX1ySIwfkTPCr2FNK5MpcpTuria5maWdi88zbnY9ya1vD/h+fX9RjtIlIgUgzOO3t9TVXR7CbVtSVYkLMxwor3Xwv4dg0CwSJVBlb5nbuTVSdjOEeZ3Zq6Xp1vpVhFawIFSNQoAq2xAFITTGIyKg2HDApGxtNLxSMeABQABaDnHNPB4pWGR75pANVcCnHCISelKAa5bxv4qh8PaQ7Aq078Rpnlj/hTBuxg/Ebxqmm2radZSZu5Bglf4B614mxLMWJyTyTUt5eT393Lc3Dl5ZG3MxrU8M+HrnxDqSwRKfKXmR/Qen1rVLlRzybm7I2fAXhN9c1Bbm4Q/ZIz3H3jXvVtbx21sIo12gDAqroelW+k6dFbwoqhVAwBWjwcjNZt3dzeKUVYjQsEGRzil3E8EURkGMGnA0hjI+EAp2cU1cjIPrTutADUbIIxjBxinCm4w7fWlFAkfJtOBptArc5CdTxSnpTFNOzTAiYU2pGFR0gHA0+oxTs0AI1NpxptJgFFFFADlbBqxHJ71Vpytg0wL4ORS1DG4NS5oKQhptOJptAxM4p6tTacBQBKDmnZqMHFO3UAPzRuqMmgHmmMeTSYopcUrjEpD0pcUmKQCDNSISGBFNApy0AbFlcbgAavugZKw7d9pFa8M4ZMGncTKsg2vSpJipZ0zzVMnBqHoUi8s1NkfcOaqK9SBsmi4NEcigscnBI4P8AOtbRcvLnHb0rNKZOcDFbGhxsJZC3XApMEdAgwMUAc09V+XNIo5qSrkqDFOalA4pCMmgRGsfP4k04Dag+lPXj8jSNxxSGNIyQf9rP6Uzaen+zipD0+gNP2YJ+oouA0J/OkKmpgKDjI4oAiYYB/Gs29+VCK1ZPu4wOlZGpNiM/Q0xM5CQbrhzjocc+9XgoSGNQWBxkgdB+H+NZzPvmYqe/H+f61LBISCHHA9D1/wAaYhz7g+5nODxkHp+NPGCSBgkj7uP6VG0hckgkY5x3H+FMNyqsDkDPUjof8aYhdhySRwo5Gf5ntTQuTkqxx6cYqbzRsIIAPXOMH/61NhCk4APJ6Hv/AJ96AHt+6t2lUBSOgJ4/+vWfEhd9zEZbrird7KwZYmKhc7jjk/jUMH7zcCMbgTn09f0pjLUUqqXUDAPAyfy/IZNPRlRcIM4Gfm/T/GqseELmQYByOR+f6cVZbBB3nBP3h2HqPywKTAjErMdqYznI9/Qf1p64EwZnUEYxnv6CmFP3jdvp0X/I4p/kKIg24ZzjA7f5FIdi154RkYqrDIGD/EPT8TTHlDM68ZB7f59aWJMBdoBwM59PT8h/OlGwSO2BgdPWgDHUD+02LdOn4VpmbOOO3J+v/wBassqxvmQEYcjr2zV9I3cKM5ViBtHr/wDqpgiRm8w8cZGfoTwBQIAcMDzjt6DgUqSDp5fJ5A75PApXJACgADgD37D9aQFiG6W2dSgDbRgk98fy5rXttYhigc7jknBBPoP15rn5GWIDYASoAOO//wCs1EXAJHXHYd/8mlYpSaPQNN163ePe8gUK2wgnoQB1rfj1GMx+YWAQdfpXkVvI8MzCNdwJ6+p//X/Kt+3vjtCs5ZAMY9T/AI1DiWpnpiXCMeCD7iraSA1w1tqzgArhSRjOOv8A9euisbtmRTJwPXNC03K3NrdkYoxUaHIp+TTuKwE4PWjNIRk0bM0ADNhaVSKTbnrTwmaADI2mmvMsEDSOQFUZJNOIAPJwK8p+JfjIKG0awk+YjEzqeg9KaVxN2VzmvH3i5/EOom3gc/YoDhQP4z61ywVliWJBl3PQVFCm+TnoOa6zwHop1nxHHI6ZggO48cZ7Vr8KOZXnI9J8AeFV0rTkup0H2iQAnI6Cu3zk7qFQRw7FGMDApoDBetZHSlZWEYE1GpIYgnpUue9REck+tAyTr3pDxIPTFIoNLyWOe1ICVWGaHyWQj1pqgg1Hd3UdmjSyuFRVySaAKuu65b6Jpkt3cOFVBn6185+IdeufEGqSXc7EL0jTPCrWx468XSeI9SMULn7FCcIP759a5NEaR1RFLMxwAO5rWKtqc853dkWdO0+41S+jtLZC0khx9PevoTwf4ag8PaSse0GQrl2xyT3rC+Hng5dJtFvLtAbmQZPH3favQSRsIA7YqJSuzWEOVa7iDpkdKXmoxkKBTgxzSLBDletG5c4zzUaY+YDnk0bOelAWHA4kdT9RTsjtTCDvGRyRS4PpQTYVjiQH1HNLupj/ACqGPY804YoA+T6KKK2OQcvWpBUQqRTmqQCsKiIxVjHFROKAI6cDTaXNIBTTadSGkAlFFFABRRRQBIjYNWUORVMdaswnimNE2KQil7UUFDaUGikouA/NGaZS0gQ7NOHWmA04HmgZIKdTAaeKBhSYqQLmnbaAIcGnouakEftUqx0BcjUEGrcMhBpojpyrtNAF5W3DBqCeDPK0qNipwQwoFdoy2ypwRTo2yetW7iENyBWbK5hBPpU21LvoaSqWwO/8h/8ArrSsLqKy3GQ4HQYHWuObV51Pymga1dd2H5VTimZ8x6RHrliR99hg/wB00xNdtN4G2Xtk7K87GuXY6MPypw8QXoOQ4/KlyIfOelLrdof+evf+ClbW7P8AvP8A98GvNv8AhI7/AP56j8qa3iC/b/lr+lHIhc56R/btmM8yfdP8Pf0pf7csy4GZcZHITtXmn9u3x/5a/pQddvugmNHIh856S2u2YjwBMW29NnfP+FDeILbedsU7DceQnUYrzT+3L7/nuaBrl+P+W5o5EHOelJr8RwTbzjpn5fzobxAmTttJzwccd+1ebf27f/8APdqUa9fD/lu1HIg5z0OfxCQ2I7GdlyeTxnjj9azbzVJLhNq2sikgckj8f1rjTrl6esxpp1m6PWQmjlDnN5LZj99BnOc571KICASBg+uf61zn9rXH96mnV7o/x0couc6RYcDHHHr0/KkaFQ27KFj79Px7VzB1K6Jz5hpn264/56Giwcx1Mirt2rjA7+v0qxbhI48ZG7HzHP8AM1x322fP3zS/brg/x07IOY3pV82Ys2OvbjHr/hXong3w14f1jRJIdQuDDf7srPG2cA4+UjoR0rx1b2YfxVctfEGo2R/0edkx6UnFApHdeJ/BeoeGpwZSs9pIT5VxGcq3OcH0Psax44eQFOXK4yf89zWRceM9burVrWe9d4GIJQ9Mis/+1rn+9Qoj5jqRaeWzAEEjjk9fX9akEYI+c5P1rkv7Wuf71L/bFz/ep8qFznXhSeM4J6mh4CY22gEnHPc1yP8AbV1/fpDrV5/z0pcqDnZvNayG83DC4AxV0ogCKrYIJ5z0zx/KuQbVLpmz5lNOoXJ/5aGjlQc7OxMignYqqe2Py/lUTA+ZnOQeQPTsP05rkvt9z/z1NH9oXP8Az0NPlQc51oRRHzx3BzznoP8AGpoIIjMoRgAFyoP8RxgVxn9oXP8Az0NA1G6UgiUgjvS5UHOek2WnQiAkSIsm4klj0UYHPt1rbt7K1VlZlXLNgdxj+vGK8fGsX4GBcvjGMe1SDX9TCgC7kwOnPSk4le0PY1t4gzRbgMAhSf8AP61egZUQBpRhRyM14efEGqFsm8kz9aD4g1Q/8vkn51PIUqtj6QtLmJoFJYDAx1qZriHGA6/nXzanijWo12pqEwHpmn/8JZrv/QRm/MUcg/bI+jfPj/vr+dOFzCB/rF/OvnH/AIS7Xf8AoIS/pSHxZrhOTqEv6Ucge1R9HiaL/nov51J58QHEi/nXzb/wl+u/9BCT8hTv+Ew13GPt7/kKfIL2qPZPHHif+x9NKWpDXcowgz0968Klt7qeZpZMvI5yzE8k0+51m+vJTLcTtI57tUQ1CYdx+VVGKRnObkWFsJljAGAze9e3/DrRINK0NJHK+dL8zGvCv7SuD/EPyrUg8Z63bQrFFdBUUYA2iiSuEJ8r1PpKWSNSBvFM82P++K+dP+E78QHref8Ajopf+E71/wD5+x/3yKjkNfao+jA8flsQwqNnUAfMK+dx4818HIux/wB807/hPvEH/P2P++aOQXtUfQqzIp5IxR5sZJO4c189f8J/4gwQbpTn1Wnr8QtfUACePA/2KOQPao+gxNGBksPzryX4keK5ruR9LsWOwHbKy9/auXk+IevyRNGZoxkYyF5rAOozMxZsMxOST3pqHcUqt1oQ/ZpT/wAs2r0j4c+DRNKmq3qjAbEaN29689GoyD+Fa6Gx+IGqafaJbxRxbV7nOTVSV1oRBpO7PoZUjRQqlQAOKGAKN8w6V4IPijrA6wwn86lX4q6so5toT/wI1HIa+1R7nGVKDnPFPG3NeHx/FjUF+9Zp+DmrSfF2cffsOP8AZejlYe1R7GqbZHx0JzUmPSvH4vi1GJSWtZgp7bgcVpwfFnTn++ZU/wB5c0uVj9oj0mUEshz0zQQR3rjIPiLo9wo/0uPcCOG4rpLTWbK7QNHKpB9DSaKUky4/MZByRQDkAjoaehjfoRUcasqYPbikM+U6KKK3OMKetMpRTQE+eKa3SkQ089KoRAaSnkUypYxRSkZpBThQAw0U8rTSMUgEooooABU0TY4qGlU4pgXwcig1FG2RUlBaEoxRRQOwUZxS5phpAOzSg1FmnBqBMnBqRTVcNUimgCypqQdagU81IpoHYsKKmUCoEOanSgY/FJTqSgBpJFPjlINMNMzg0h2LwIYYrK1VdsZxV9HqrqMfmwn6UAcxRTnUqxBptMxCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAClpKKAFpKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKt2ep3tg4e2uZIyOwbj8qqUUAekeHPiVNHKkOpDg8eYOn416xpmpwX6/JIGyMjnqK+X66vwh4qm0e/iilkJtydoyfu5/pUSj2NoT6M5SiiirMQooooAkQ1J1FQqalWrQARxUTCp6iZaTAjpy9aTFKvFICZQCKGjzQhqdQCKoRSZSDTavPED0qq8ZXtSaGR0UUVIEsbYqypyKpL1q3GDimUmOzRQVOaSkUIOtDdaXFIRQAw0ClxRimA9akXrUaipFByKGMmWpFqNRUyrSGTRjirSLmq6CrUfFAD9tNIqSo3PFICNqjJGajnnC96rC43NSGaKNT2wyEGq0LbhVjtSA57UYws2QKpVf1Igy1QqzF7hRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACgUUUAFFFFABRRRQAoqRTUVSKaaAkpp6UuaQ9KoQwikp9JikMVetWENV161MppiLA5pHj3CmqalU0AZ8ke2oqvzrwaokYNJoY6P71Xo1BAqghwauwyDApoTJHWoWGDVgkEVE4ptDTGZpaZUi1DVjVahtpMc1Ljim45pDsCipFWhB7VKFzQAiDmrCLmmItTqKQDlHNTKeKjzijdgUATbqp3V0I1ODzTbm6EaHnmsSaZpGyTRYTdiSa4aRqWFjmqoqaLNAlK5sQScCrTyBYiazoCaLy42xlR1pWLZn3cnmTE1XpScmkqjF7hRRRQIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnrTKeDTQD80hpM0ZqrgLRjNJmlBGetAhQKkHSmAj1FLuHqKAJVapFaqwYeoqRXX+8PzoAll+YVRcYNXDIhH3h+dVZcZ4I/OhgiKpY2xUVKDSTGXlfIpxqpG+O9WFkXuw/OquIRxilSgshH3l/OkV1B+8PzqWXFlgDikxzSLJHj76/nT98f8Az0X86g1uhyipRUYkiH/LRPzp3nRf89E/OgNCdAKlFVVuIv8Anqn/AH1Thcxf89U/76FAronY8VXmn2KaGuIz0kT/AL6FVLlkdDiRPzoQm0U55jIx54qClPWkFMzbuOUZNWoozUMeBjJq7E0Y6uo/Gg0ikSj5EzWfcS+Y9WbqdQmFYH6Gs80IJvsJRRRQZBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//2Q=="
- ]
- }
- },
- "widgets_values": [
- "{\"positive\":[{\"x\":362.3956220422853,\"y\":221.12275243258088},{\"x\":429.96090750779615,\"y\":319.3995312915057}],\"negative\":[{\"x\":72.97050830275268,\"y\":59.45745120965033}]}",
- "[{\"x\":362.3956220422853,\"y\":221.12275243258088},{\"x\":429.96090750779615,\"y\":319.3995312915057}]",
- "[{\"x\":72.97050830275268,\"y\":59.45745120965033}]",
- "[{}]",
- "[{}]",
- "xyxy",
- 832,
- 448,
- false,
- "",
- null
- ]
- },
- {
- "id": 302,
- "type": "MochaEmbeds",
- "pos": [
- -1842.8629150390625,
- 1508.8265380859375
- ],
- "size": [
- 270,
- 234
- ],
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 603
- },
- {
- "name": "input_video",
- "type": "IMAGE",
- "link": 604
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 605
- },
- {
- "name": "ref1",
- "type": "IMAGE",
- "link": 606
- },
- {
- "name": "ref2",
- "shape": 7,
- "type": "IMAGE",
- "link": 616
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "links": [
- 581
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "MochaEmbeds"
- },
- "widgets_values": [
- 832,
- false
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 337,
- "type": "GetNode",
- "pos": [
- -2132.64892578125,
- 1783.503173828125
- ],
- "size": [
- 210,
- 58
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 616
- ]
- }
- ],
- "title": "Get_ref2",
- "properties": {},
- "widgets_values": [
- "ref2"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 341,
- "type": "MarkdownNote",
- "pos": [
- -5599.3466796875,
- -465.1884765625
- ],
- "size": [
- 537.5685424804688,
- 332.75048828125
- ],
- "flags": {
- "collapsed": false
- },
- "order": 12,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "# Github\nhttps://github.com/Orange-3DV-Team/MoCha\n\n# Project Page\nhttps://orange-3dv-team.github.io/MoCha/\n\n# Huggingface Checkpoint\n\nhttps://huggingface.co/Orange-3DV-Team/MoCha\n\nhttps://huggingface.co/Kijai/WanVideo_comfy"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 342,
- "type": "MarkdownNote",
- "pos": [
- -5621.03955078125,
- 471.94781494140625
- ],
- "size": [
- 517.5745239257812,
- 247.94821166992188
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "1. We recommend using a reference image with a clean background.\n2. Ref2 is optional. You can use a face image as ref2 to enhance face fiedlity.\n3. The model will achieve the best results when the pose of the character in the reference image is close to the pose of the character in the first frame of the video."
- ],
- "color": "#432",
- "bgcolor": "#653"
- }
- ],
- "links": [
- [
- 390,
- 128,
- 0,
- 245,
- 0,
- "IMAGE"
- ],
- [
- 391,
- 245,
- 0,
- 243,
- 0,
- "IMAGE"
- ],
- [
- 395,
- 212,
- 0,
- 246,
- 0,
- "IMAGE"
- ],
- [
- 396,
- 246,
- 0,
- 247,
- 0,
- "IMAGE"
- ],
- [
- 397,
- 245,
- 0,
- 248,
- 0,
- "IMAGE"
- ],
- [
- 398,
- 248,
- 0,
- 249,
- 0,
- "IMAGE"
- ],
- [
- 494,
- 300,
- 0,
- 296,
- 0,
- "IMAGE"
- ],
- [
- 495,
- 296,
- 0,
- 298,
- 0,
- "IMAGE"
- ],
- [
- 501,
- 246,
- 1,
- 296,
- 2,
- "INT"
- ],
- [
- 502,
- 246,
- 2,
- 296,
- 3,
- "INT"
- ],
- [
- 558,
- 312,
- 0,
- 311,
- 2,
- "WANVIDLORA"
- ],
- [
- 559,
- 313,
- 0,
- 314,
- 2,
- "WANVIDEOTEXTEMBEDS"
- ],
- [
- 563,
- 314,
- 0,
- 304,
- 1,
- "LATENT"
- ],
- [
- 581,
- 302,
- 0,
- 314,
- 1,
- "WANVIDIMAGE_EMBEDS"
- ],
- [
- 587,
- 325,
- 0,
- 326,
- 0,
- "SAM2MODEL"
- ],
- [
- 588,
- 323,
- 0,
- 326,
- 2,
- "STRING"
- ],
- [
- 589,
- 323,
- 1,
- 326,
- 3,
- "STRING"
- ],
- [
- 590,
- 326,
- 0,
- 327,
- 0,
- "MASK"
- ],
- [
- 592,
- 327,
- 0,
- 328,
- 0,
- "MASK"
- ],
- [
- 595,
- 245,
- 1,
- 246,
- 2,
- "INT"
- ],
- [
- 597,
- 248,
- 0,
- 323,
- 0,
- "IMAGE"
- ],
- [
- 598,
- 245,
- 2,
- 246,
- 3,
- "INT"
- ],
- [
- 599,
- 327,
- 0,
- 330,
- 0,
- "*"
- ],
- [
- 600,
- 246,
- 0,
- 331,
- 0,
- "*"
- ],
- [
- 601,
- 296,
- 0,
- 332,
- 0,
- "*"
- ],
- [
- 602,
- 308,
- 0,
- 304,
- 0,
- "WANVAE"
- ],
- [
- 603,
- 308,
- 0,
- 302,
- 0,
- "WANVAE"
- ],
- [
- 604,
- 333,
- 0,
- 302,
- 1,
- "IMAGE"
- ],
- [
- 605,
- 335,
- 0,
- 302,
- 2,
- "MASK"
- ],
- [
- 606,
- 336,
- 0,
- 302,
- 3,
- "IMAGE"
- ],
- [
- 611,
- 304,
- 0,
- 338,
- 1,
- "IMAGE"
- ],
- [
- 612,
- 339,
- 0,
- 338,
- 0,
- "IMAGE"
- ],
- [
- 613,
- 338,
- 0,
- 318,
- 0,
- "IMAGE"
- ],
- [
- 614,
- 248,
- 0,
- 326,
- 1,
- "IMAGE"
- ],
- [
- 615,
- 311,
- 0,
- 314,
- 0,
- "WANVIDEOMODEL"
- ],
- [
- 616,
- 337,
- 0,
- 302,
- 4,
- "IMAGE"
- ]
- ],
- "groups": [
- {
- "id": 7,
- "title": "Input Video",
- "bounding": [
- -5017.30029296875,
- -499.0201110839844,
- 1719.6763916015625,
- 869.1625366210938
- ],
- "color": "#3f789e",
- "font_size": 24,
- "flags": {
- "pinned": true
- }
- },
- {
- "id": 9,
- "title": "ref1",
- "bounding": [
- -5009.6689453125,
- 406.9666442871094,
- 965.9547729492188,
- 822.7760009765625
- ],
- "color": "#3f789e",
- "font_size": 24,
- "flags": {
- "pinned": true
- }
- },
- {
- "id": 10,
- "title": "ref2 (Optional)",
- "bounding": [
- -5006.66064453125,
- 1265.4342041015625,
- 971.7285766601562,
- 796.7326049804688
- ],
- "color": "#3f789e",
- "font_size": 24,
- "flags": {
- "pinned": true
- }
- },
- {
- "id": 11,
- "title": "First Frame Mask",
- "bounding": [
- -3017.013916015625,
- -623.8658447265625,
- 1884.53564453125,
- 1125.91064453125
- ],
- "color": "#3f789e",
- "font_size": 24,
- "flags": {}
- }
- ],
- "config": {},
- "extra": {
- "ds": {
- "scale": 0.895430243255371,
- "offset": [
- 3416.8035155009957,
- -580.9858195581344
- ]
- },
- "frontendVersion": "1.27.10",
- "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/example_workflows/wanvideo_multitalk_test_02.json b/example_workflows/wanvideo_multitalk_test_02.json
deleted file mode 100644
index a3113c3..0000000
--- a/example_workflows/wanvideo_multitalk_test_02.json
+++ /dev/null
@@ -1,1389 +0,0 @@
-{
- "id": "8b7a9a57-2303-4ef5-9fc2-bf41713bd1fc",
- "revision": 0,
- "last_node_id": 194,
- "last_link_id": 336,
- "nodes": [
- {
- "id": 130,
- "type": "WanVideoDecode",
- "pos": [
- 3391.91015625,
- -2268.65966796875
- ],
- "size": [
- 315,
- 198
- ],
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 193
- },
- {
- "name": "samples",
- "type": "LATENT",
- "link": 194
- }
- ],
- "outputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 196
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "c3ee35f3ece76e38099dc516182d69b406e16772",
- "Node name for S&R": "WanVideoDecode"
- },
- "widgets_values": [
- false,
- 272,
- 272,
- 144,
- 128,
- "default"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 192,
- "type": "WanVideoImageToVideoMultiTalk",
- "pos": [
- 3007.274169921875,
- -1897.335693359375
- ],
- "size": [
- 315.2046813964844,
- 242
- ],
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 325
- },
- {
- "name": "start_image",
- "shape": 7,
- "type": "IMAGE",
- "link": 326
- },
- {
- "name": "clip_embeds",
- "shape": 7,
- "type": "WANVIDIMAGE_CLIPEMBEDS",
- "link": 329
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "links": [
- 328
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "49430f900bf812a1e281560bafafd04c43dfdf13",
- "Node name for S&R": "WanVideoImageToVideoMultiTalk"
- },
- "widgets_values": [
- 832,
- 480,
- 81,
- 25,
- false,
- "mkl",
- false
- ]
- },
- {
- "id": 133,
- "type": "LoadImage",
- "pos": [
- 1011.3872680664062,
- -1517.9957275390625
- ],
- "size": [
- 341.23583984375,
- 424.5613708496094
- ],
- "flags": {},
- "order": 0,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 283
- ]
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "cnr_id": "comfy-core",
- "ver": "0.3.41",
- "Node name for S&R": "LoadImage"
- },
- "widgets_values": [
- "Mona-Lisa-oil-wood-panel-Leonardo-da.webp",
- "image"
- ]
- },
- {
- "id": 173,
- "type": "CLIPVisionLoader",
- "pos": [
- 1659.6119384765625,
- -1829.4974365234375
- ],
- "size": [
- 270,
- 58
- ],
- "flags": {},
- "order": 1,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "CLIP_VISION",
- "type": "CLIP_VISION",
- "links": [
- 330
- ]
- }
- ],
- "properties": {
- "cnr_id": "comfy-core",
- "ver": "0.3.41",
- "Node name for S&R": "CLIPVisionLoader"
- },
- "widgets_values": [
- "clip_vision_h.safetensors"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 159,
- "type": "AudioCrop",
- "pos": [
- 1936.6385498046875,
- -1060.82666015625
- ],
- "size": [
- 270,
- 82
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "audio",
- "type": "AUDIO",
- "link": 257
- }
- ],
- "outputs": [
- {
- "name": "AUDIO",
- "type": "AUDIO",
- "links": [
- 296,
- 301
- ]
- }
- ],
- "properties": {
- "cnr_id": "audio-separation-nodes-comfyui",
- "ver": "31a4567726e035097cc2d1f767767908a6fda2ea",
- "Node name for S&R": "AudioCrop"
- },
- "widgets_values": [
- "0:00",
- "2:00"
- ]
- },
- {
- "id": 171,
- "type": "ImageResizeKJv2",
- "pos": [
- 1434.24169921875,
- -1517.93603515625
- ],
- "size": [
- 270,
- 286
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 283
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 326,
- 331
- ]
- },
- {
- "name": "width",
- "type": "INT",
- "links": []
- },
- {
- "name": "height",
- "type": "INT",
- "links": []
- },
- {
- "name": "mask",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "cnr_id": "comfyui-kjnodes",
- "ver": "f7eb33abc80a2aded1b46dff0dd14d07856a7d50",
- "Node name for S&R": "ImageResizeKJv2"
- },
- "widgets_values": [
- 832,
- 480,
- "lanczos",
- "crop",
- "0, 0, 0",
- "center",
- 2,
- "cpu"
- ]
- },
- {
- "id": 193,
- "type": "WanVideoClipVisionEncode",
- "pos": [
- 2196.71337890625,
- -1549.066162109375
- ],
- "size": [
- 280.9771423339844,
- 262
- ],
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "clip_vision",
- "type": "CLIP_VISION",
- "link": 330
- },
- {
- "name": "image_1",
- "type": "IMAGE",
- "link": 331
- },
- {
- "name": "image_2",
- "shape": 7,
- "type": "IMAGE",
- "link": null
- },
- {
- "name": "negative_image",
- "shape": 7,
- "type": "IMAGE",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_CLIPEMBEDS",
- "links": [
- 329
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "49430f900bf812a1e281560bafafd04c43dfdf13",
- "Node name for S&R": "WanVideoClipVisionEncode"
- },
- "widgets_values": [
- 1,
- 1,
- "center",
- "average",
- true,
- 0,
- 0.5000000000000001
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 177,
- "type": "WanVideoTorchCompileSettings",
- "pos": [
- 1641.0926513671875,
- -2447.249267578125
- ],
- "size": [
- 342.74609375,
- 202
- ],
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "torch_compile_args",
- "type": "WANCOMPILEARGS",
- "links": [
- 299
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "f3614e6720744247f3211d60f7b9333f43572384",
- "Node name for S&R": "WanVideoTorchCompileSettings"
- },
- "widgets_values": [
- "inductor",
- false,
- "default",
- false,
- 64,
- true,
- 128
- ]
- },
- {
- "id": 134,
- "type": "WanVideoBlockSwap",
- "pos": [
- 1209.63037109375,
- -2396.775146484375
- ],
- "size": [
- 281.404296875,
- 154
- ],
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "block_swap_args",
- "type": "BLOCKSWAPARGS",
- "links": [
- 332
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoBlockSwap"
- },
- "widgets_values": [
- 15,
- false,
- false,
- true,
- 0
- ]
- },
- {
- "id": 135,
- "type": "WanVideoTextEncode",
- "pos": [
- 2834.335693359375,
- -2292.33642578125
- ],
- "size": [
- 469.3669128417969,
- 323.4193115234375
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "t5",
- "shape": 7,
- "type": "WANTEXTENCODER",
- "link": 202
- },
- {
- "name": "model_to_offload",
- "shape": 7,
- "type": "WANVIDEOMODEL",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "links": [
- 306
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoTextEncode"
- },
- "widgets_values": [
- "A woman passionately singing. A close-up shot captures her expressive performance.",
- "bright tones, overexposed, static, blurred details, subtitles, style, works, paintings, images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, three legs, many people in the background, walking backwards",
- true,
- false,
- "gpu"
- ]
- },
- {
- "id": 136,
- "type": "LoadWanVideoT5TextEncoder",
- "pos": [
- 2236.692626953125,
- -2039.4443359375
- ],
- "size": [
- 370.9598693847656,
- 130
- ],
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "wan_t5_model",
- "type": "WANTEXTENCODER",
- "links": [
- 202
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "LoadWanVideoT5TextEncoder"
- },
- "widgets_values": [
- "umt5-xxl-enc-bf16.safetensors",
- "bf16",
- "offload_device",
- "disabled"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 137,
- "type": "DownloadAndLoadWav2VecModel",
- "pos": [
- 2229.880859375,
- -1822.4462890625
- ],
- "size": [
- 330.96728515625,
- 106
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "wav2vec_model",
- "type": "WAV2VECMODEL",
- "links": [
- 334
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "DownloadAndLoadWav2VecModel"
- },
- "widgets_values": [
- "TencentGameMate/chinese-wav2vec2-base",
- "fp16",
- "main_device"
- ]
- },
- {
- "id": 131,
- "type": "VHS_VideoCombine",
- "pos": [
- 3906.588134765625,
- -2240.1123046875
- ],
- "size": [
- 1386.326416015625,
- 334
- ],
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 196
- },
- {
- "name": "audio",
- "shape": 7,
- "type": "AUDIO",
- "link": 296
- },
- {
- "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": {
- "cnr_id": "comfyui-videohelpersuite",
- "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8",
- "Node name for S&R": "VHS_VideoCombine"
- },
- "widgets_values": {
- "frame_rate": 25,
- "loop_count": 0,
- "filename_prefix": "WanVideo2_1_multitalk",
- "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_1_multitalk_00002-audio.mp4",
- "subfolder": "",
- "type": "temp",
- "format": "video/h264-mp4",
- "frame_rate": 25,
- "workflow": "WanVideo2_1_multitalk_00002.png",
- "fullpath": "N:\\AI\\ComfyUI\\temp\\WanVideo2_1_multitalk_00002-audio.mp4"
- }
- }
- }
- },
- {
- "id": 170,
- "type": "AudioSeparation",
- "pos": [
- 2274.1318359375,
- -988.1599731445312
- ],
- "size": [
- 270,
- 166
- ],
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "audio",
- "type": "AUDIO",
- "link": 301
- }
- ],
- "outputs": [
- {
- "name": "Bass",
- "type": "AUDIO",
- "links": null
- },
- {
- "name": "Drums",
- "type": "AUDIO",
- "links": null
- },
- {
- "name": "Other",
- "type": "AUDIO",
- "links": null
- },
- {
- "name": "Vocals",
- "type": "AUDIO",
- "links": [
- 335
- ]
- }
- ],
- "properties": {
- "cnr_id": "audio-separation-nodes-comfyui",
- "ver": "31a4567726e035097cc2d1f767767908a6fda2ea",
- "Node name for S&R": "AudioSeparation"
- },
- "widgets_values": [
- "linear",
- 10,
- 0.1
- ]
- },
- {
- "id": 194,
- "type": "MultiTalkWav2VecEmbeds",
- "pos": [
- 3032.306640625,
- -1562.1412353515625
- ],
- "size": [
- 291.08203125,
- 278
- ],
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "wav2vec_model",
- "type": "WAV2VECMODEL",
- "link": 334
- },
- {
- "name": "audio_1",
- "type": "AUDIO",
- "link": 335
- },
- {
- "name": "audio_2",
- "shape": 7,
- "type": "AUDIO",
- "link": null
- },
- {
- "name": "audio_3",
- "shape": 7,
- "type": "AUDIO",
- "link": null
- },
- {
- "name": "audio_4",
- "shape": 7,
- "type": "AUDIO",
- "link": null
- },
- {
- "name": "ref_target_masks",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "multitalk_embeds",
- "type": "MULTITALK_EMBEDS",
- "links": [
- 336
- ]
- },
- {
- "name": "audio",
- "type": "AUDIO",
- "links": null
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "3d7801cee4c8e3106078dd9b9f146caee95069ba",
- "Node name for S&R": "MultiTalkWav2VecEmbeds"
- },
- "widgets_values": [
- true,
- 250,
- 25,
- 1,
- 1,
- "para"
- ]
- },
- {
- "id": 138,
- "type": "WanVideoLoraSelect",
- "pos": [
- 1009.5531005859375,
- -2124.957763671875
- ],
- "size": [
- 503.4073486328125,
- 150
- ],
- "flags": {},
- "order": 6,
- "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": [
- 256
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoLoraSelect"
- },
- "widgets_values": [
- "Wan21_T2V_14B_lightx2v_cfg_step_distill_lora_rank32.safetensors",
- 0.8000000000000002,
- false,
- true
- ]
- },
- {
- "id": 120,
- "type": "MultiTalkModelLoader",
- "pos": [
- 1067.93701171875,
- -1936.950439453125
- ],
- "size": [
- 447.0210266113281,
- 82
- ],
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "model",
- "type": "MULTITALKMODEL",
- "links": [
- 270
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "MultiTalkModelLoader"
- },
- "widgets_values": [
- "WanVideo\\WanVideo_2_1_Multitalk_14B_fp8_e4m3fn.safetensors",
- "fp16"
- ]
- },
- {
- "id": 122,
- "type": "WanVideoModelLoader",
- "pos": [
- 1610.768798828125,
- -2170.692138671875
- ],
- "size": [
- 595.2891235351562,
- 274
- ],
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "compile_args",
- "shape": 7,
- "type": "WANCOMPILEARGS",
- "link": 299
- },
- {
- "name": "block_swap_args",
- "shape": 7,
- "type": "BLOCKSWAPARGS",
- "link": 332
- },
- {
- "name": "lora",
- "shape": 7,
- "type": "WANVIDLORA",
- "link": 256
- },
- {
- "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": 270
- }
- ],
- "outputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "links": [
- 197
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoModelLoader"
- },
- "widgets_values": [
- "WanVideo\\Wan2_1-I2V-14B-480P_fp8_e4m3fn.safetensors",
- "fp16_fast",
- "fp8_e4m3fn",
- "offload_device",
- "sageattn"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 129,
- "type": "WanVideoVAELoader",
- "pos": [
- 2043.939697265625,
- -2401.840576171875
- ],
- "size": [
- 315,
- 82
- ],
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "slot_index": 0,
- "links": [
- 193,
- 325
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "c3ee35f3ece76e38099dc516182d69b406e16772",
- "Node name for S&R": "WanVideoVAELoader"
- },
- "widgets_values": [
- "wanvideo\\Wan2_1_VAE_bf16.safetensors",
- "bf16"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 125,
- "type": "LoadAudio",
- "pos": [
- 1451.6412353515625,
- -1061.2105712890625
- ],
- "size": [
- 357.32049560546875,
- 136
- ],
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "AUDIO",
- "type": "AUDIO",
- "links": [
- 257
- ]
- }
- ],
- "properties": {
- "cnr_id": "comfy-core",
- "ver": "0.3.41",
- "Node name for S&R": "LoadAudio"
- },
- "widgets_values": [
- "test_song.mp3",
- null,
- null
- ]
- },
- {
- "id": 128,
- "type": "WanVideoSampler",
- "pos": [
- 3461.539306640625,
- -1928.31787109375
- ],
- "size": [
- 315,
- 781.39453125
- ],
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "link": 197
- },
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "link": 328
- },
- {
- "name": "text_embeds",
- "shape": 7,
- "type": "WANVIDEOTEXTEMBEDS",
- "link": 306
- },
- {
- "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": 336
- },
- {
- "name": "freeinit_args",
- "shape": 7,
- "type": "FREEINITARGS",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "slot_index": 0,
- "links": [
- 194
- ]
- },
- {
- "name": "denoised_samples",
- "type": "LATENT",
- "links": null
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "c3ee35f3ece76e38099dc516182d69b406e16772",
- "Node name for S&R": "WanVideoSampler"
- },
- "widgets_values": [
- 4,
- 1.0000000000000002,
- 11.000000000000002,
- 1,
- "fixed",
- true,
- "flowmatch_distill",
- 0,
- 1,
- false,
- "comfy",
- 0,
- -1,
- false
- ]
- }
- ],
- "links": [
- [
- 193,
- 129,
- 0,
- 130,
- 0,
- "WANVAE"
- ],
- [
- 194,
- 128,
- 0,
- 130,
- 1,
- "LATENT"
- ],
- [
- 196,
- 130,
- 0,
- 131,
- 0,
- "IMAGE"
- ],
- [
- 197,
- 122,
- 0,
- 128,
- 0,
- "WANVIDEOMODEL"
- ],
- [
- 202,
- 136,
- 0,
- 135,
- 0,
- "WANTEXTENCODER"
- ],
- [
- 256,
- 138,
- 0,
- 122,
- 2,
- "WANVIDLORA"
- ],
- [
- 257,
- 125,
- 0,
- 159,
- 0,
- "AUDIO"
- ],
- [
- 270,
- 120,
- 0,
- 122,
- 6,
- "MULTITALKMODEL"
- ],
- [
- 283,
- 133,
- 0,
- 171,
- 0,
- "IMAGE"
- ],
- [
- 296,
- 159,
- 0,
- 131,
- 1,
- "AUDIO"
- ],
- [
- 299,
- 177,
- 0,
- 122,
- 0,
- "WANCOMPILEARGS"
- ],
- [
- 301,
- 159,
- 0,
- 170,
- 0,
- "AUDIO"
- ],
- [
- 306,
- 135,
- 0,
- 128,
- 2,
- "WANVIDEOTEXTEMBEDS"
- ],
- [
- 325,
- 129,
- 0,
- 192,
- 0,
- "WANVAE"
- ],
- [
- 326,
- 171,
- 0,
- 192,
- 1,
- "IMAGE"
- ],
- [
- 328,
- 192,
- 0,
- 128,
- 1,
- "WANVIDIMAGE_EMBEDS"
- ],
- [
- 329,
- 193,
- 0,
- 192,
- 2,
- "WANVIDIMAGE_CLIPEMBEDS"
- ],
- [
- 330,
- 173,
- 0,
- 193,
- 0,
- "CLIP_VISION"
- ],
- [
- 331,
- 171,
- 0,
- 193,
- 1,
- "IMAGE"
- ],
- [
- 332,
- 134,
- 0,
- 122,
- 1,
- "BLOCKSWAPARGS"
- ],
- [
- 334,
- 137,
- 0,
- 194,
- 0,
- "WAV2VECMODEL"
- ],
- [
- 335,
- 170,
- 3,
- 194,
- 1,
- "AUDIO"
- ],
- [
- 336,
- 194,
- 0,
- 128,
- 15,
- "MULTITALK_EMBEDS"
- ]
- ],
- "groups": [
- {
- "id": 1,
- "title": "Models",
- "bounding": [
- 969.4049072265625,
- -2553.697509765625,
- 1772.8997802734375,
- 888.819580078125
- ],
- "color": "#3f789e",
- "font_size": 24,
- "flags": {}
- }
- ],
- "config": {},
- "extra": {
- "ds": {
- "scale": 0.6115909044841903,
- "offset": [
- -732.1708708005202,
- 2451.37832568256
- ]
- },
- "frontendVersion": "1.25.1",
- "node_versions": {
- "ComfyUI-WanVideoWrapper": "0a11c67a0c0062b534178920a0d6dcaa75e7b5fe",
- "comfy-core": "0.3.43",
- "audio-separation-nodes-comfyui": "31a4567726e035097cc2d1f767767908a6fda2ea",
- "ComfyUI-KJNodes": "f7eb33abc80a2aded1b46dff0dd14d07856a7d50",
- "comfyui-videohelpersuite": "a7ce59e381934733bfae03b1be029756d6ce936d"
- },
- "VHS_latentpreview": true,
- "VHS_latentpreviewrate": 0,
- "VHS_MetadataImage": true,
- "VHS_KeepIntermediate": true
- },
- "version": 0.4
-}
\ No newline at end of file
diff --git a/example_workflows/wanvideo_multitalk_test_context_windows_01.json b/example_workflows/wanvideo_multitalk_test_context_windows_01.json
deleted file mode 100644
index 15a6ac4..0000000
--- a/example_workflows/wanvideo_multitalk_test_context_windows_01.json
+++ /dev/null
@@ -1,1891 +0,0 @@
-{
- "id": "8b7a9a57-2303-4ef5-9fc2-bf41713bd1fc",
- "revision": 0,
- "last_node_id": 190,
- "last_link_id": 325,
- "nodes": [
- {
- "id": 133,
- "type": "LoadImage",
- "pos": [
- 1011.3872680664062,
- -1517.9957275390625
- ],
- "size": [
- 341.23583984375,
- 424.5613708496094
- ],
- "flags": {},
- "order": 0,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 283
- ]
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "cnr_id": "comfy-core",
- "ver": "0.3.41",
- "Node name for S&R": "LoadImage"
- },
- "widgets_values": [
- "multitalk_single_example.png",
- "image"
- ]
- },
- {
- "id": 170,
- "type": "AudioSeparation",
- "pos": [
- 1926.405517578125,
- -886.7852783203125
- ],
- "size": [
- 270,
- 166
- ],
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "audio",
- "type": "AUDIO",
- "link": 301
- }
- ],
- "outputs": [
- {
- "name": "Bass",
- "type": "AUDIO",
- "links": null
- },
- {
- "name": "Drums",
- "type": "AUDIO",
- "links": null
- },
- {
- "name": "Other",
- "type": "AUDIO",
- "links": null
- },
- {
- "name": "Vocals",
- "type": "AUDIO",
- "links": [
- 318
- ]
- }
- ],
- "properties": {
- "cnr_id": "audio-separation-nodes-comfyui",
- "ver": "31a4567726e035097cc2d1f767767908a6fda2ea",
- "Node name for S&R": "AudioSeparation"
- },
- "widgets_values": [
- "linear",
- 10,
- 0.1
- ]
- },
- {
- "id": 137,
- "type": "DownloadAndLoadWav2VecModel",
- "pos": [
- 2955.85693359375,
- -1515.0516357421875
- ],
- "size": [
- 330.96728515625,
- 106
- ],
- "flags": {},
- "order": 1,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "wav2vec_model",
- "type": "WAV2VECMODEL",
- "links": [
- 317
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "DownloadAndLoadWav2VecModel"
- },
- "widgets_values": [
- "TencentGameMate/chinese-wav2vec2-base",
- "fp16",
- "main_device"
- ]
- },
- {
- "id": 135,
- "type": "WanVideoTextEncode",
- "pos": [
- 2871.396728515625,
- -955.9310302734375
- ],
- "size": [
- 469.3669128417969,
- 323.4193115234375
- ],
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "t5",
- "type": "WANTEXTENCODER",
- "link": 202
- },
- {
- "name": "model_to_offload",
- "shape": 7,
- "type": "WANVIDEOMODEL",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "links": [
- 306
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoTextEncode"
- },
- "widgets_values": [
- "Stationary camera view of A woman passionately singing into a professional microphone in a recording studio. She wears large black headphones and a dark cardigan over a gray top. Her long, wavy brown hair frames her face as she looks slightly upwards, her mouth open mid-song. The studio is equipped with various audio equipment, including a mixing console and a keyboard, with soundproofing panels on the walls. The lighting is warm and focused on her, creating a professional and intimate atmosphere. A close-up shot captures her expressive performance.",
- "bright tones, overexposed, static, blurred details, subtitles, style, works, paintings, images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, three legs, many people in the background, walking backwards",
- true
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 128,
- "type": "WanVideoSampler",
- "pos": [
- 3461.539306640625,
- -1928.31787109375
- ],
- "size": [
- 315,
- 781.39453125
- ],
- "flags": {},
- "order": 26,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "link": 197
- },
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "link": 198
- },
- {
- "name": "text_embeds",
- "shape": 7,
- "type": "WANVIDEOTEXTEMBEDS",
- "link": 306
- },
- {
- "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": 321
- },
- {
- "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": 308
- },
- {
- "name": "multitalk_embeds",
- "shape": 7,
- "type": "MULTITALK_EMBEDS",
- "link": 320
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "slot_index": 0,
- "links": [
- 194
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "c3ee35f3ece76e38099dc516182d69b406e16772",
- "Node name for S&R": "WanVideoSampler"
- },
- "widgets_values": [
- 5,
- 1.0000000000000002,
- 5.000000000000001,
- 6,
- "fixed",
- true,
- "dpm++_sde",
- 0,
- 1,
- false,
- "comfy",
- ""
- ]
- },
- {
- "id": 186,
- "type": "VHS_DuplicateImages",
- "pos": [
- 3737.267822265625,
- -462.8251037597656
- ],
- "size": [
- 214.232421875,
- 78
- ],
- "flags": {},
- "order": 21,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 325
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 314
- ]
- },
- {
- "name": "count",
- "type": "INT",
- "links": null
- }
- ],
- "properties": {
- "cnr_id": "comfyui-videohelpersuite",
- "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8",
- "Node name for S&R": "VHS_DuplicateImages"
- },
- "widgets_values": {
- "multiply_by": 81
- }
- },
- {
- "id": 131,
- "type": "VHS_VideoCombine",
- "pos": [
- 3944.93896484375,
- -2433.943115234375
- ],
- "size": [
- 1266.4205322265625,
- 1067.0887451171875
- ],
- "flags": {},
- "order": 28,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 196
- },
- {
- "name": "audio",
- "shape": 7,
- "type": "AUDIO",
- "link": 296
- },
- {
- "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": {
- "cnr_id": "comfyui-videohelpersuite",
- "ver": "0a75c7958fe320efcb052f1d9f8451fd20c730a8",
- "Node name for S&R": "VHS_VideoCombine"
- },
- "widgets_values": {
- "frame_rate": 25,
- "loop_count": 0,
- "filename_prefix": "WanVideo2_1_multitalk",
- "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_1_multitalk_00001-audio.mp4",
- "subfolder": "",
- "type": "temp",
- "format": "video/h264-mp4",
- "frame_rate": 25,
- "workflow": "WanVideo2_1_multitalk_00001.png",
- "fullpath": "N:\\AI\\ComfyUI\\temp\\WanVideo2_1_multitalk_00001-audio.mp4"
- }
- }
- }
- },
- {
- "id": 182,
- "type": "WanVideoUni3C_embeds",
- "pos": [
- 4198.1904296875,
- -858.3336791992188
- ],
- "size": [
- 270,
- 146
- ],
- "flags": {},
- "order": 25,
- "mode": 0,
- "inputs": [
- {
- "name": "controlnet",
- "type": "WANVIDEOCONTROLNET",
- "link": 309
- },
- {
- "name": "render_latent",
- "type": "LATENT",
- "link": 310
- },
- {
- "name": "render_mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "uni3c_embeds",
- "type": "UNI3C_EMBEDS",
- "links": [
- 308
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "f3614e6720744247f3211d60f7b9333f43572384",
- "Node name for S&R": "WanVideoUni3C_embeds"
- },
- "widgets_values": [
- 1,
- 0,
- 0.10000000000000002
- ]
- },
- {
- "id": 125,
- "type": "LoadAudio",
- "pos": [
- 1451.6412353515625,
- -1061.2105712890625
- ],
- "size": [
- 357.32049560546875,
- 136
- ],
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "AUDIO",
- "type": "AUDIO",
- "links": [
- 257
- ]
- }
- ],
- "properties": {
- "cnr_id": "comfy-core",
- "ver": "0.3.41",
- "Node name for S&R": "LoadAudio"
- },
- "widgets_values": [
- "Lumière · Lorien Testard · Alice Duport-Percier.mp3",
- null,
- null
- ]
- },
- {
- "id": 177,
- "type": "WanVideoTorchCompileSettings",
- "pos": [
- 1076.12060546875,
- -2674.260009765625
- ],
- "size": [
- 342.74609375,
- 202
- ],
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "torch_compile_args",
- "type": "WANCOMPILEARGS",
- "links": [
- 299
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "f3614e6720744247f3211d60f7b9333f43572384",
- "Node name for S&R": "WanVideoTorchCompileSettings"
- },
- "widgets_values": [
- "inductor",
- false,
- "default",
- false,
- 64,
- true,
- 128
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 159,
- "type": "AudioCrop",
- "pos": [
- 1927.918212890625,
- -1068.45703125
- ],
- "size": [
- 270,
- 82
- ],
- "flags": {},
- "order": 15,
- "mode": 4,
- "inputs": [
- {
- "name": "audio",
- "type": "AUDIO",
- "link": 257
- }
- ],
- "outputs": [
- {
- "name": "AUDIO",
- "type": "AUDIO",
- "links": [
- 296,
- 301
- ]
- }
- ],
- "properties": {
- "cnr_id": "audio-separation-nodes-comfyui",
- "ver": "31a4567726e035097cc2d1f767767908a6fda2ea",
- "Node name for S&R": "AudioCrop"
- },
- "widgets_values": [
- "0:01",
- "2:00"
- ]
- },
- {
- "id": 187,
- "type": "MultiTalkWav2VecEmbeds",
- "pos": [
- 2956.00244140625,
- -1333.2303466796875
- ],
- "size": [
- 291.08203125,
- 278
- ],
- "flags": {},
- "order": 22,
- "mode": 0,
- "inputs": [
- {
- "name": "wav2vec_model",
- "type": "WAV2VECMODEL",
- "link": 317
- },
- {
- "name": "audio_1",
- "type": "AUDIO",
- "link": 318
- },
- {
- "name": "audio_2",
- "shape": 7,
- "type": "AUDIO",
- "link": null
- },
- {
- "name": "audio_3",
- "shape": 7,
- "type": "AUDIO",
- "link": null
- },
- {
- "name": "audio_4",
- "shape": 7,
- "type": "AUDIO",
- "link": null
- },
- {
- "name": "ref_target_masks",
- "shape": 7,
- "type": "MASK",
- "link": null
- },
- {
- "name": "num_frames",
- "type": "INT",
- "widget": {
- "name": "num_frames"
- },
- "link": 319
- }
- ],
- "outputs": [
- {
- "name": "multitalk_embeds",
- "type": "MULTITALK_EMBEDS",
- "links": [
- 320
- ]
- },
- {
- "name": "audio",
- "type": "AUDIO",
- "links": null
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "3d7801cee4c8e3106078dd9b9f146caee95069ba",
- "Node name for S&R": "MultiTalkWav2VecEmbeds"
- },
- "widgets_values": [
- true,
- 81,
- 25,
- 1,
- 1,
- "para"
- ]
- },
- {
- "id": 188,
- "type": "Note",
- "pos": [
- 3985.1123046875,
- -638.2463989257812
- ],
- "size": [
- 239.9966278076172,
- 88
- ],
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "Uni3C control is used here only to lock the camera, which improves results when using context windows"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 134,
- "type": "WanVideoBlockSwap",
- "pos": [
- 1133.5965576171875,
- -2395.964599609375
- ],
- "size": [
- 281.404296875,
- 154
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "block_swap_args",
- "type": "BLOCKSWAPARGS",
- "links": [
- 201
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoBlockSwap"
- },
- "widgets_values": [
- 10,
- false,
- false,
- true,
- 0
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 138,
- "type": "WanVideoLoraSelect",
- "pos": [
- 945.2125854492188,
- -2169.73095703125
- ],
- "size": [
- 503.4073486328125,
- 126
- ],
- "flags": {},
- "order": 6,
- "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": [
- 256
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoLoraSelect"
- },
- "widgets_values": [
- "Wan21_T2V_14B_lightx2v_cfg_step_distill_lora_rank32.safetensors",
- 1.2000000000000002,
- false
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 120,
- "type": "MultiTalkModelLoader",
- "pos": [
- 1137.2589111328125,
- -1927.4013671875
- ],
- "size": [
- 314.59307861328125,
- 83.98193359375
- ],
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "model",
- "type": "MULTITALKMODEL",
- "links": [
- 270
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "MultiTalkModelLoader"
- },
- "widgets_values": [
- "WanVideo\\multitalk.safetensors",
- "fp16"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 122,
- "type": "WanVideoModelLoader",
- "pos": [
- 1529.2850341796875,
- -2411.081298828125
- ],
- "size": [
- 595.2891235351562,
- 274
- ],
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "compile_args",
- "shape": 7,
- "type": "WANCOMPILEARGS",
- "link": 299
- },
- {
- "name": "block_swap_args",
- "shape": 7,
- "type": "BLOCKSWAPARGS",
- "link": 201
- },
- {
- "name": "lora",
- "shape": 7,
- "type": "WANVIDLORA",
- "link": 256
- },
- {
- "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": 270
- }
- ],
- "outputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "links": [
- 197
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoModelLoader"
- },
- "widgets_values": [
- "WanVideo\\Wan2_1-I2V-14B-480P_fp8_e4m3fn.safetensors",
- "fp16_fast",
- "fp8_e4m3fn",
- "offload_device",
- "sageattn"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 129,
- "type": "WanVideoVAELoader",
- "pos": [
- 1774.7691650390625,
- -2647.38232421875
- ],
- "size": [
- 315,
- 82
- ],
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "slot_index": 0,
- "links": [
- 193,
- 199,
- 311
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "c3ee35f3ece76e38099dc516182d69b406e16772",
- "Node name for S&R": "WanVideoVAELoader"
- },
- "widgets_values": [
- "wanvideo\\Wan2_1_VAE_bf16.safetensors",
- "bf16"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 172,
- "type": "WanVideoClipVisionEncode",
- "pos": [
- 2515.615234375,
- -1964.957275390625
- ],
- "size": [
- 280.9771423339844,
- 262
- ],
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "clip_vision",
- "type": "CLIP_VISION",
- "link": 288
- },
- {
- "name": "image_1",
- "type": "IMAGE",
- "link": 323
- },
- {
- "name": "image_2",
- "shape": 7,
- "type": "IMAGE",
- "link": null
- },
- {
- "name": "negative_image",
- "shape": 7,
- "type": "IMAGE",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_CLIPEMBEDS",
- "links": [
- 287
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "58104b620f6b52de2fc516ade9f31383b0e7eca9",
- "Node name for S&R": "WanVideoClipVisionEncode"
- },
- "widgets_values": [
- 1,
- 1,
- "center",
- "average",
- true,
- 0,
- 0.5
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 183,
- "type": "WanVideoUni3C_ControlnetLoader",
- "pos": [
- 3802.052978515625,
- -848.1785278320312
- ],
- "size": [
- 322.4781188964844,
- 154
- ],
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "compile_args",
- "shape": 7,
- "type": "WANCOMPILEARGS",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "controlnet",
- "type": "WANVIDEOCONTROLNET",
- "links": [
- 309
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "f3614e6720744247f3211d60f7b9333f43572384",
- "Node name for S&R": "WanVideoUni3C_ControlnetLoader"
- },
- "widgets_values": [
- "Wan21_Uni3C_controlnet_fp16.safetensors",
- "fp16",
- "fp8_e4m3fn",
- "main_device",
- "sageattn"
- ]
- },
- {
- "id": 189,
- "type": "WanVideoContextOptions",
- "pos": [
- 2943.619873046875,
- -2259.861572265625
- ],
- "size": [
- 309.2419128417969,
- 178
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "context_options",
- "type": "WANVIDCONTEXT",
- "links": [
- 321
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "3d7801cee4c8e3106078dd9b9f146caee95069ba",
- "Node name for S&R": "WanVideoContextOptions"
- },
- "widgets_values": [
- "static_standard",
- 81,
- 4,
- 32,
- true,
- false
- ]
- },
- {
- "id": 136,
- "type": "LoadWanVideoT5TextEncoder",
- "pos": [
- 2452.524658203125,
- -945.0313720703125
- ],
- "size": [
- 370.9598693847656,
- 130
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "wan_t5_model",
- "type": "WANTEXTENCODER",
- "links": [
- 202
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "LoadWanVideoT5TextEncoder"
- },
- "widgets_values": [
- "umt5-xxl-enc-fp8_e4m3fn.safetensors",
- "bf16",
- "offload_device",
- "fp8_e4m3fn"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 173,
- "type": "CLIPVisionLoader",
- "pos": [
- 1834.0162353515625,
- -2052.537109375
- ],
- "size": [
- 270,
- 58
- ],
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "CLIP_VISION",
- "type": "CLIP_VISION",
- "links": [
- 288
- ]
- }
- ],
- "properties": {
- "cnr_id": "comfy-core",
- "ver": "0.3.41",
- "Node name for S&R": "CLIPVisionLoader"
- },
- "widgets_values": [
- "clip_vision_h.safetensors"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 132,
- "type": "WanVideoImageToVideoEncode",
- "pos": [
- 2959.904052734375,
- -1989.0770263671875
- ],
- "size": [
- 308.2320251464844,
- 390
- ],
- "flags": {},
- "order": 23,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 199
- },
- {
- "name": "clip_embeds",
- "shape": 7,
- "type": "WANVIDIMAGE_CLIPEMBEDS",
- "link": 287
- },
- {
- "name": "start_image",
- "shape": 7,
- "type": "IMAGE",
- "link": 324
- },
- {
- "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": 290
- },
- {
- "name": "height",
- "type": "INT",
- "widget": {
- "name": "height"
- },
- "link": 291
- },
- {
- "name": "num_frames",
- "type": "INT",
- "widget": {
- "name": "num_frames"
- },
- "link": 295
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "links": [
- 198
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "058286fc0f3b0651a2f6b68309df3f06e8332cc0",
- "Node name for S&R": "WanVideoImageToVideoEncode"
- },
- "widgets_values": [
- 512,
- 720,
- 81,
- 0,
- 1,
- 1,
- true,
- false,
- false
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 130,
- "type": "WanVideoDecode",
- "pos": [
- 3548.77880859375,
- -2445.249755859375
- ],
- "size": [
- 315,
- 198
- ],
- "flags": {},
- "order": 27,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 193
- },
- {
- "name": "samples",
- "type": "LATENT",
- "link": 194
- }
- ],
- "outputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 196
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "c3ee35f3ece76e38099dc516182d69b406e16772",
- "Node name for S&R": "WanVideoDecode"
- },
- "widgets_values": [
- false,
- 272,
- 272,
- 144,
- 128,
- "default"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 184,
- "type": "WanVideoEncode",
- "pos": [
- 4008.18798828125,
- -454.33416748046875
- ],
- "size": [
- 270,
- 242
- ],
- "flags": {},
- "order": 24,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 311
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 314
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "links": [
- 310
- ]
- }
- ],
- "properties": {
- "cnr_id": "ComfyUI-WanVideoWrapper",
- "ver": "f3614e6720744247f3211d60f7b9333f43572384",
- "Node name for S&R": "WanVideoEncode"
- },
- "widgets_values": [
- false,
- 272,
- 272,
- 144,
- 128,
- 0,
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 171,
- "type": "ImageResizeKJv2",
- "pos": [
- 1434.2418212890625,
- -1519.026123046875
- ],
- "size": [
- 270,
- 286
- ],
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 283
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 322
- ]
- },
- {
- "name": "width",
- "type": "INT",
- "links": [
- 290
- ]
- },
- {
- "name": "height",
- "type": "INT",
- "links": [
- 291
- ]
- },
- {
- "name": "mask",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "cnr_id": "comfyui-kjnodes",
- "ver": "f7eb33abc80a2aded1b46dff0dd14d07856a7d50",
- "Node name for S&R": "ImageResizeKJv2"
- },
- "widgets_values": [
- 832,
- 480,
- "lanczos",
- "crop",
- "0, 0, 0",
- "center",
- 2,
- "cpu"
- ]
- },
- {
- "id": 175,
- "type": "INTConstant",
- "pos": [
- 2555.978759765625,
- -1559.425537109375
- ],
- "size": [
- 210,
- 58
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "value",
- "type": "INT",
- "links": [
- 295,
- 319
- ]
- }
- ],
- "title": "Frames",
- "properties": {
- "cnr_id": "comfyui-kjnodes",
- "ver": "f7eb33abc80a2aded1b46dff0dd14d07856a7d50",
- "Node name for S&R": "INTConstant"
- },
- "widgets_values": [
- 257
- ],
- "color": "#1b4669",
- "bgcolor": "#29699c"
- },
- {
- "id": 190,
- "type": "Reroute",
- "pos": [
- 2263.9169921875,
- -1514.1737060546875
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 322
- }
- ],
- "outputs": [
- {
- "name": "",
- "type": "IMAGE",
- "links": [
- 323,
- 324,
- 325
- ]
- }
- ],
- "properties": {
- "showOutputText": false,
- "horizontal": false
- }
- }
- ],
- "links": [
- [
- 193,
- 129,
- 0,
- 130,
- 0,
- "WANVAE"
- ],
- [
- 194,
- 128,
- 0,
- 130,
- 1,
- "LATENT"
- ],
- [
- 196,
- 130,
- 0,
- 131,
- 0,
- "IMAGE"
- ],
- [
- 197,
- 122,
- 0,
- 128,
- 0,
- "WANVIDEOMODEL"
- ],
- [
- 198,
- 132,
- 0,
- 128,
- 1,
- "WANVIDIMAGE_EMBEDS"
- ],
- [
- 199,
- 129,
- 0,
- 132,
- 0,
- "WANVAE"
- ],
- [
- 201,
- 134,
- 0,
- 122,
- 1,
- "BLOCKSWAPARGS"
- ],
- [
- 202,
- 136,
- 0,
- 135,
- 0,
- "WANTEXTENCODER"
- ],
- [
- 256,
- 138,
- 0,
- 122,
- 2,
- "WANVIDLORA"
- ],
- [
- 257,
- 125,
- 0,
- 159,
- 0,
- "AUDIO"
- ],
- [
- 270,
- 120,
- 0,
- 122,
- 6,
- "MULTITALKMODEL"
- ],
- [
- 283,
- 133,
- 0,
- 171,
- 0,
- "IMAGE"
- ],
- [
- 287,
- 172,
- 0,
- 132,
- 1,
- "WANVIDIMAGE_CLIPEMBEDS"
- ],
- [
- 288,
- 173,
- 0,
- 172,
- 0,
- "CLIP_VISION"
- ],
- [
- 290,
- 171,
- 1,
- 132,
- 8,
- "INT"
- ],
- [
- 291,
- 171,
- 2,
- 132,
- 9,
- "INT"
- ],
- [
- 295,
- 175,
- 0,
- 132,
- 10,
- "INT"
- ],
- [
- 296,
- 159,
- 0,
- 131,
- 1,
- "AUDIO"
- ],
- [
- 299,
- 177,
- 0,
- 122,
- 0,
- "WANCOMPILEARGS"
- ],
- [
- 301,
- 159,
- 0,
- 170,
- 0,
- "AUDIO"
- ],
- [
- 306,
- 135,
- 0,
- 128,
- 2,
- "WANVIDEOTEXTEMBEDS"
- ],
- [
- 308,
- 182,
- 0,
- 128,
- 14,
- "UNI3C_EMBEDS"
- ],
- [
- 309,
- 183,
- 0,
- 182,
- 0,
- "WANVIDEOCONTROLNET"
- ],
- [
- 310,
- 184,
- 0,
- 182,
- 1,
- "LATENT"
- ],
- [
- 311,
- 129,
- 0,
- 184,
- 0,
- "WANVAE"
- ],
- [
- 314,
- 186,
- 0,
- 184,
- 1,
- "IMAGE"
- ],
- [
- 317,
- 137,
- 0,
- 187,
- 0,
- "WAV2VECMODEL"
- ],
- [
- 318,
- 170,
- 3,
- 187,
- 1,
- "AUDIO"
- ],
- [
- 319,
- 175,
- 0,
- 187,
- 6,
- "INT"
- ],
- [
- 320,
- 187,
- 0,
- 128,
- 15,
- "MULTITALK_EMBEDS"
- ],
- [
- 321,
- 189,
- 0,
- 128,
- 5,
- "WANVIDCONTEXT"
- ],
- [
- 322,
- 171,
- 0,
- 190,
- 0,
- "*"
- ],
- [
- 323,
- 190,
- 0,
- 172,
- 1,
- "IMAGE"
- ],
- [
- 324,
- 190,
- 0,
- 132,
- 2,
- "IMAGE"
- ],
- [
- 325,
- 190,
- 0,
- 186,
- 0,
- "IMAGE"
- ]
- ],
- "groups": [
- {
- "id": 1,
- "title": "Uni3C - camera lock",
- "bounding": [
- 3490.82958984375,
- -1000.6835327148438,
- 1048.014404296875,
- 834.3169555664062
- ],
- "color": "#3f789e",
- "font_size": 24,
- "flags": {}
- },
- {
- "id": 2,
- "title": "Models",
- "bounding": [
- 897.584716796875,
- -2795.149169921875,
- 1293.1141357421875,
- 1007.8966064453125
- ],
- "color": "#88A",
- "font_size": 24,
- "flags": {}
- }
- ],
- "config": {},
- "extra": {
- "ds": {
- "scale": 0.4177248169415945,
- "offset": [
- -568.3731137113364,
- 3021.0071032227147
- ]
- },
- "frontendVersion": "1.23.4",
- "node_versions": {
- "ComfyUI-KJNodes": "f9118e0bbb39347ea7becb84ec03e397dfb4f644",
- "comfyui-videohelpersuite": "a7ce59e381934733bfae03b1be029756d6ce936d"
- },
- "VHS_latentpreview": true,
- "VHS_latentpreviewrate": 0,
- "VHS_MetadataImage": true,
- "VHS_KeepIntermediate": true
- },
- "version": 0.4
-}
\ No newline at end of file
diff --git a/example_workflows/wanvideo_vid2vid_example_01.json b/example_workflows/wanvideo_vid2vid_example_01.json
deleted file mode 100644
index e9e5973..0000000
--- a/example_workflows/wanvideo_vid2vid_example_01.json
+++ /dev/null
@@ -1,1044 +0,0 @@
-{
- "id": "44436dc8-b9e0-461b-aea2-13203712292d",
- "revision": 0,
- "last_node_id": 49,
- "last_link_id": 62,
- "nodes": [
- {
- "id": 36,
- "type": "Note",
- "pos": [
- 796.0189208984375,
- -521.5020751953125
- ],
- "size": [
- 298.2554016113281,
- 108.62744140625
- ],
- "flags": {},
- "order": 0,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "properties": {},
- "widgets_values": [
- "sdpa should work too, haven't tested flaash\n\nfp8_fast seems to cause huge quality degradation"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 35,
- "type": "WanVideoTorchCompileSettings",
- "pos": [
- 124.67726135253906,
- -627.7935180664062
- ],
- "size": [
- 390.5999755859375,
- 178
- ],
- "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
- ]
- },
- {
- "id": 11,
- "type": "LoadWanVideoT5TextEncoder",
- "pos": [
- 224.15325927734375,
- -34.481563568115234
- ],
- "size": [
- 377.1661376953125,
- 130
- ],
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "wan_t5_model",
- "type": "WANTEXTENCODER",
- "slot_index": 0,
- "links": [
- 15
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "LoadWanVideoT5TextEncoder"
- },
- "widgets_values": [
- "umt5-xxl-enc-bf16.safetensors",
- "bf16",
- "offload_device",
- "disabled"
- ]
- },
- {
- "id": 28,
- "type": "WanVideoDecode",
- "pos": [
- 1692.973876953125,
- -404.8614501953125
- ],
- "size": [
- 315,
- 174
- ],
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 43
- },
- {
- "name": "samples",
- "type": "LATENT",
- "link": 33
- }
- ],
- "outputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 54
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoDecode"
- },
- "widgets_values": [
- true,
- 272,
- 272,
- 144,
- 128
- ]
- },
- {
- "id": 45,
- "type": "ImageConcatMulti",
- "pos": [
- 1817.8916015625,
- 102.76653289794922
- ],
- "size": [
- 210,
- 150
- ],
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "image_1",
- "type": "IMAGE",
- "link": 53
- },
- {
- "name": "image_2",
- "type": "IMAGE",
- "link": 54
- }
- ],
- "outputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 55
- ]
- }
- ],
- "properties": {},
- "widgets_values": [
- 2,
- "right",
- false,
- ""
- ]
- },
- {
- "id": 43,
- "type": "VHS_LoadVideo",
- "pos": [
- 304.38446044921875,
- 285.45703125
- ],
- "size": [
- 247.455078125,
- 551.455078125
- ],
- "flags": {},
- "order": 3,
- "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": [
- 51
- ]
- },
- {
- "name": "frame_count",
- "type": "INT",
- "slot_index": 1,
- "links": [
- 56
- ]
- },
- {
- "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": 37,
- "type": "WanVideoEmptyEmbeds",
- "pos": [
- 753.8429565429688,
- 611.1437377929688
- ],
- "size": [
- 315,
- 146
- ],
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "num_frames",
- "type": "INT",
- "widget": {
- "name": "num_frames"
- },
- "link": 56
- },
- {
- "name": "width",
- "type": "INT",
- "widget": {
- "name": "width"
- },
- "link": 57
- },
- {
- "name": "height",
- "type": "INT",
- "widget": {
- "name": "height"
- },
- "link": 58
- }
- ],
- "outputs": [
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "links": [
- 42
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoEmptyEmbeds"
- },
- "widgets_values": [
- 512,
- 512,
- 53
- ]
- },
- {
- "id": 33,
- "type": "Note",
- "pos": [
- 197.6475830078125,
- -179.16000366210938
- ],
- "size": [
- 351.70458984375,
- 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": 38,
- "type": "WanVideoVAELoader",
- "pos": [
- 1687.4093017578125,
- -582.2750854492188
- ],
- "size": [
- 373.55645751953125,
- 82
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "slot_index": 0,
- "links": [
- 43,
- 48
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoVAELoader"
- },
- "widgets_values": [
- "wanvideo\\Wan2_1_VAE_bf16.safetensors",
- "bf16"
- ]
- },
- {
- "id": 30,
- "type": "VHS_VideoCombine",
- "pos": [
- 2117.870849609375,
- -567.7182006835938
- ],
- "size": [
- 942.6622314453125,
- 809.3311157226562
- ],
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 55
- },
- {
- "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": "WanVideoWrapperV2V",
- "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": "WanVideoWrapperV2V_00016.mp4",
- "subfolder": "",
- "type": "output",
- "format": "video/h264-mp4",
- "frame_rate": 16,
- "workflow": "WanVideoWrapperV2V_00016.png",
- "fullpath": "N:\\AI\\ComfyUI\\output\\WanVideoWrapperV2V_00016.mp4"
- }
- }
- }
- },
- {
- "id": 42,
- "type": "WanVideoEncode",
- "pos": [
- 1298.557861328125,
- 306.5940246582031
- ],
- "size": [
- 315,
- 242
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "vae",
- "type": "WANVAE",
- "link": 48
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 52
- },
- {
- "name": "mask",
- "shape": 7,
- "type": "MASK",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "slot_index": 0,
- "links": [
- 50
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoEncode"
- },
- "widgets_values": [
- false,
- 272,
- 272,
- 144,
- 128,
- 0,
- 1
- ]
- },
- {
- "id": 44,
- "type": "ImageResizeKJ",
- "pos": [
- 744.0538940429688,
- 288.3457336425781
- ],
- "size": [
- 315,
- 286
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 51
- },
- {
- "name": "get_image_size",
- "shape": 7,
- "type": "IMAGE",
- "link": null
- },
- {
- "name": "width_input",
- "shape": 7,
- "type": "INT",
- "widget": {
- "name": "width_input"
- },
- "link": null
- },
- {
- "name": "height_input",
- "shape": 7,
- "type": "INT",
- "widget": {
- "name": "height_input"
- },
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "slot_index": 0,
- "links": [
- 52,
- 53
- ]
- },
- {
- "name": "width",
- "type": "INT",
- "slot_index": 1,
- "links": [
- 57
- ]
- },
- {
- "name": "height",
- "type": "INT",
- "slot_index": 2,
- "links": [
- 58
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "ImageResizeKJ"
- },
- "widgets_values": [
- 512,
- 512,
- "lanczos",
- false,
- 16,
- 0,
- 0,
- "disabled"
- ]
- },
- {
- "id": 16,
- "type": "WanVideoTextEncode",
- "pos": [
- 675.8850708007812,
- -36.032100677490234
- ],
- "size": [
- 420.30511474609375,
- 261.5306701660156
- ],
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "t5",
- "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"
- },
- "widgets_values": [
- "high quality video featuring a red panda",
- "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走",
- true
- ]
- },
- {
- "id": 46,
- "type": "WanVideoTeaCache",
- "pos": [
- 1295.5970458984375,
- -682.718017578125
- ],
- "size": [
- 315,
- 154
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "cache_args",
- "type": "CACHEARGS",
- "slot_index": 0,
- "links": [
- 62
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoTeaCache"
- },
- "widgets_values": [
- 0.25,
- 1,
- -1,
- "offload_device",
- "true"
- ]
- },
- {
- "id": 27,
- "type": "WanVideoSampler",
- "pos": [
- 1310.73583984375,
- -457.3343200683594
- ],
- "size": [
- 315,
- 699
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "link": 29
- },
- {
- "name": "text_embeds",
- "type": "WANVIDEOTEXTEMBEDS",
- "link": 30
- },
- {
- "name": "image_embeds",
- "type": "WANVIDIMAGE_EMBEDS",
- "link": 42
- },
- {
- "name": "samples",
- "shape": 7,
- "type": "LATENT",
- "link": 50
- },
- {
- "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": 62
- },
- {
- "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
- }
- ],
- "outputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "slot_index": 0,
- "links": [
- 33
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoSampler"
- },
- "widgets_values": [
- 15,
- 6.000000000000001,
- 5.000000000000001,
- 1057359483639288,
- "fixed",
- true,
- "dpm++",
- 0,
- 0.5000000000000001,
- "",
- "comfy"
- ]
- },
- {
- "id": 39,
- "type": "WanVideoBlockSwap",
- "pos": [
- 194.8857879638672,
- -363.0874938964844
- ],
- "size": [
- 315,
- 130
- ],
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [],
- "outputs": [
- {
- "name": "block_swap_args",
- "type": "BLOCKSWAPARGS",
- "slot_index": 0,
- "links": []
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoBlockSwap"
- },
- "widgets_values": [
- 20,
- false,
- false,
- true
- ]
- },
- {
- "id": 22,
- "type": "WanVideoModelLoader",
- "pos": [
- 620.3950805664062,
- -357.8426818847656
- ],
- "size": [
- 477.4410095214844,
- 226.43276977539062
- ],
- "flags": {},
- "order": 8,
- "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
- }
- ],
- "outputs": [
- {
- "name": "model",
- "type": "WANVIDEOMODEL",
- "slot_index": 0,
- "links": [
- 29
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "WanVideoModelLoader"
- },
- "widgets_values": [
- "WanVideo\\wan2.1_t2v_1.3B_fp16.safetensors",
- "fp16",
- "disabled",
- "offload_device",
- "sdpa"
- ]
- }
- ],
- "links": [
- [
- 15,
- 11,
- 0,
- 16,
- 0,
- "WANTEXTENCODER"
- ],
- [
- 29,
- 22,
- 0,
- 27,
- 0,
- "WANVIDEOMODEL"
- ],
- [
- 30,
- 16,
- 0,
- 27,
- 1,
- "WANVIDEOTEXTEMBEDS"
- ],
- [
- 33,
- 27,
- 0,
- 28,
- 1,
- "LATENT"
- ],
- [
- 42,
- 37,
- 0,
- 27,
- 2,
- "WANVIDIMAGE_EMBEDS"
- ],
- [
- 43,
- 38,
- 0,
- 28,
- 0,
- "VAE"
- ],
- [
- 48,
- 38,
- 0,
- 42,
- 0,
- "WANVAE"
- ],
- [
- 50,
- 42,
- 0,
- 27,
- 3,
- "LATENT"
- ],
- [
- 51,
- 43,
- 0,
- 44,
- 0,
- "IMAGE"
- ],
- [
- 52,
- 44,
- 0,
- 42,
- 1,
- "IMAGE"
- ],
- [
- 53,
- 44,
- 0,
- 45,
- 0,
- "IMAGE"
- ],
- [
- 54,
- 28,
- 0,
- 45,
- 1,
- "IMAGE"
- ],
- [
- 55,
- 45,
- 0,
- 30,
- 0,
- "IMAGE"
- ],
- [
- 56,
- 43,
- 1,
- 37,
- 0,
- "INT"
- ],
- [
- 57,
- 44,
- 1,
- 37,
- 1,
- "INT"
- ],
- [
- 58,
- 44,
- 2,
- 37,
- 2,
- "INT"
- ],
- [
- 62,
- 46,
- 0,
- 27,
- 6,
- "TEACACHEARGS"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {
- "ds": {
- "scale": 0.6727499949326009,
- "offset": [
- 391.99039310194877,
- 810.1005303189878
- ]
- },
- "node_versions": {
- "ComfyUI-WanVideoWrapper": "5a2383621a05825d0d0437781afcb8552d9590fd",
- "ComfyUI-KJNodes": "a5bd3c86c8ed6b83c55c2d0e7a59515b15a0137f",
- "ComfyUI-VideoHelperSuite": "0a75c7958fe320efcb052f1d9f8451fd20c730a8"
- },
- "VHS_latentpreview": true,
- "VHS_latentpreviewrate": 0,
- "VHS_MetadataImage": true,
- "VHS_KeepIntermediate": true
- },
- "version": 0.4
-}
\ No newline at end of file
From b132a82f7a4b86d4e72d15fe7daa952e1fc18c06 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 15:57:30 +0200
Subject: [PATCH 12/22] Fix LongCat-Avatar audio padding when not enough audio
provided for given window
---
LongCat/nodes.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/LongCat/nodes.py b/LongCat/nodes.py
index 941a4fa..19c12e8 100644
--- a/LongCat/nodes.py
+++ b/LongCat/nodes.py
@@ -37,15 +37,16 @@ class WanVideoLongCatAvatarExtendEmbeds(io.ComfyNode):
new_audio_embed = audio_embeds.copy()
audio_features = torch.stack(new_audio_embed["audio_features"])
+ num_audio_features = audio_features.shape[1]
if audio_features.shape[1] < frames_processed + num_frames:
deficit = frames_processed + num_frames - audio_features.shape[1]
if if_not_enough_audio == "pad_with_start":
- pad = audio_features[:, :1].repeat(1, deficit, 1, 1, 1)
+ pad = audio_features[:, :1].repeat(1, deficit, 1, 1)
audio_features = torch.cat([audio_features, pad], dim=1)
elif if_not_enough_audio == "mirror_from_end":
to_add = audio_features[:, -deficit:, :].flip(dims=[1])
audio_features = torch.cat([audio_features, to_add], dim=1)
- log.info(f"Not enough audio features, extended from {new_audio_embed['audio_features'].shape[1]} to {audio_features.shape[1]} frames.")
+ log.warning(f"Not enough audio features, padded with strategy '{if_not_enough_audio}' from {num_audio_features} to {audio_features.shape[1]} frames")
ref_target_masks = new_audio_embed.get("ref_target_masks", None)
if ref_target_masks is not None:
From fd818faa08ce07e5530e71bd0ccc2985cac98105 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 16:09:01 +0200
Subject: [PATCH 13/22] Fix context window ref latent device
---
nodes_sampler.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/nodes_sampler.py b/nodes_sampler.py
index 42fd8cf..2b60f43 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -1861,7 +1861,7 @@ class WanVideoSampler:
if context_reference_latent.shape[0] == 1: #only single extra init latent
new_init_image = context_reference_latent[0, :, 0].to(device)
# Concatenate the first 4 channels of partial_img_emb with new_init_image to match the required shape
- partial_img_emb[:, 0] = torch.cat([image_cond[:4, 0], new_init_image], dim=0)
+ partial_img_emb[:, 0] = torch.cat([image_cond[:4, 0].to(device), new_init_image], dim=0)
elif context_reference_latent.shape[0] > 1:
num_extra_inits = context_reference_latent.shape[0]
section_size = (latent_video_length / num_extra_inits)
@@ -1869,7 +1869,7 @@ class WanVideoSampler:
if context_options["verbose"]:
log.info(f"extra init image index: {extra_init_index}")
new_init_image = context_reference_latent[extra_init_index, :, 0].to(device)
- partial_img_emb[:, 0] = torch.cat([image_cond[:4, 0], new_init_image], dim=0)
+ partial_img_emb[:, 0] = torch.cat([image_cond[:4, 0].to(device), new_init_image], dim=0)
else:
new_init_image = image_cond[:, 0].to(device)
partial_img_emb[:, 0] = new_init_image
From a896101ec879e9b487e2b90dd9f15bca70726b0f Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 22:28:04 +0200
Subject: [PATCH 14/22] I don't know why this suddenly errors
---
nodes_sampler.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/nodes_sampler.py b/nodes_sampler.py
index 2b60f43..5c47564 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -1379,15 +1379,14 @@ class WanVideoSampler:
z = z * c_in
timestep = c_noise
+ self.noise_front_pad_num = 0
if image_cond is not None:
self.noise_front_pad_num = image_cond_input.shape[1] - z.shape[1]
if self.noise_front_pad_num > 0:
pad = torch.zeros((z.shape[0], self.noise_front_pad_num, z.shape[2], z.shape[3]), dtype=z.dtype, device=z.device)
- z = torch.concat([pad, z], dim=1)
+ z = torch.cat([pad, z], dim=1)
nonlocal seq_len
seq_len = math.ceil((z.shape[2] * z.shape[3]) / 4 * z.shape[1])
- else:
- self.noise_front_pad_num = 0
if background_latents is not None or foreground_latents is not None:
z = torch.cat([z, foreground_latents.to(z), background_latents.to(z)], dim=0)
From e855726f10163bcf1fa6e80e85b55ff67eb89d96 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Fri, 26 Dec 2025 23:12:18 +0200
Subject: [PATCH 15/22] Fix enhance-a-video
---
nodes_sampler.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/nodes_sampler.py b/nodes_sampler.py
index 5c47564..57b73e8 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -1379,7 +1379,6 @@ class WanVideoSampler:
z = z * c_in
timestep = c_noise
- self.noise_front_pad_num = 0
if image_cond is not None:
self.noise_front_pad_num = image_cond_input.shape[1] - z.shape[1]
if self.noise_front_pad_num > 0:
@@ -1771,6 +1770,8 @@ class WanVideoSampler:
latent_flipped = torch.flip(latent, dims=[1])
latent_model_input_flipped = latent_flipped.to(device)
+ self.noise_front_pad_num = 0
+
#InfiniteTalk first frame handling
if (extra_latents is not None
and not multitalk_sampling
@@ -1821,7 +1822,7 @@ class WanVideoSampler:
if feta_args is not None and feta_start_percent <= current_step_percentage <= feta_end_percent:
enhance_enabled = True
#region context windowing
- elif context_options is not None:
+ if context_options is not None:
counter = torch.zeros_like(latent_model_input, device=device)
noise_pred = torch.zeros_like(latent_model_input, device=device)
context_queue = list(context(idx, steps, latent_video_length, context_frames, context_stride, context_overlap))
From 7a6efc145618be57d1a4a959205d5de8995427df Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Sun, 28 Dec 2025 00:35:14 +0200
Subject: [PATCH 16/22] Add node for SVI 2.0 Pro
---
nodes.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/nodes.py b/nodes.py
index 67f5142..f7ef927 100644
--- a/nodes.py
+++ b/nodes.py
@@ -909,6 +909,64 @@ class WanVideoAddStoryMemLatents:
updated["story_mem_latents"] = story_mem_latents["samples"].squeeze(2).permute(1, 0, 2, 3) # [C, T, H, W]
return (updated,)
+
+class WanVideoSVIProEmbeds:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "anchor_samples": ("LATENT", {"tooltip": "Initial start image encoded"}),
+ "num_frames": ("INT", {"default": 81, "min": 1, "max": 10000, "step": 4, "tooltip": "Number of frames to encode"}),
+ },
+ "optional": {
+ "prev_samples": ("LATENT", {"tooltip": "Last latent from previous generation"}),
+ "motion_latent_count": ("INT", {"default": 2, "min": 1, "max": 100, "step": 1, "tooltip": "Number of latents used to continue"}),
+ }
+ }
+
+ RETURN_TYPES = ("WANVIDIMAGE_EMBEDS",)
+ RETURN_NAMES = ("image_embeds",)
+ FUNCTION = "add"
+ CATEGORY = "WanVideoWrapper"
+
+ def add(self, anchor_samples, num_frames, prev_samples=None, motion_latent_count=1):
+
+ anchor_latent = anchor_samples["samples"][0].clone()
+
+ C, T, H, W = anchor_latent.shape
+
+ total_latents = (num_frames - 1) // 4 + 1
+ device = anchor_latent.device
+ dtype = anchor_latent.dtype
+
+ if prev_samples is None or motion_latent_count == 0:
+ padding_size = total_latents - anchor_latent.shape[1]
+ padding = torch.zeros(C, padding_size, H, W, dtype=dtype, device=device)
+ y = torch.concat([anchor_latent, padding], dim=1)
+ else:
+ prev_latent = prev_samples["samples"][0].clone()
+ motion_latent = prev_latent[:, -motion_latent_count:]
+ padding_size = total_latents - anchor_latent.shape[1] - motion_latent.shape[1]
+ padding = torch.zeros(C, padding_size, H, W, dtype=dtype, device=device)
+ y = torch.concat([anchor_latent, motion_latent, padding], dim=1)
+
+ msk = torch.ones(1, num_frames, H, W, device=device, dtype=dtype)
+ msk[:, 1:] = 0
+ msk = torch.concat([torch.repeat_interleave(msk[:, 0:1], repeats=4, dim=1), msk[:, 1:]], dim=1)
+ msk = msk.view(1, msk.shape[1] // 4, 4, H, W)
+ msk = msk.transpose(1, 2)[0]
+
+ image_embeds = {
+ "image_embeds": y,
+
+ #"max_seq_len": max_seq_len,
+ "num_frames": num_frames,
+ "lat_h": H,
+ "lat_w": W,
+ "mask": msk
+ }
+
+ return (image_embeds,)
+
#region I2V encode
class WanVideoImageToVideoEncode:
@classmethod
@@ -2250,6 +2308,7 @@ NODE_CLASS_MAPPINGS = {
"WanVideoUniLumosEmbeds": WanVideoUniLumosEmbeds,
"WanVideoAddTTMLatents": WanVideoAddTTMLatents,
"WanVideoAddStoryMemLatents": WanVideoAddStoryMemLatents,
+ "WanVideoSVIProEmbeds": WanVideoSVIProEmbeds,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -2291,4 +2350,5 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"WanVideoUniLumosEmbeds": "WanVideo UniLumos Embeds",
"WanVideoAddTTMLatents": "WanVideo Add TTMLatents",
"WanVideoAddStoryMemLatents": "WanVideo Add StoryMem Latents",
+ "WanVideoSVIProEmbeds": "WanVideo SVIPro Embeds",
}
From 6fd4c6640c4dcdc963fffb53fbe74eafa0e64dcb Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Sun, 28 Dec 2025 01:27:18 +0200
Subject: [PATCH 17/22] Adjust scheduler graph drawing
---
nodes_sampler.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/nodes_sampler.py b/nodes_sampler.py
index 57b73e8..d054b90 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -2777,8 +2777,13 @@ class WanVideoScheduler:
handles, labels = ax.get_legend_handles_labels()
if labels:
ax.legend()
- if start_idx < end_idx and 0 <= start_idx < len(sigmas_np) and 0 < end_idx < len(sigmas_np):
- ax.axvspan(start_idx, end_idx, color='lightblue', alpha=0.1, label='Sampled Range')
+ # Draw shaded range
+ range_start_idx = start_idx if start_idx > 0 else 0
+ range_end_idx = end_idx if end_idx > 0 and end_idx < len(sigmas_np) else len(sigmas_np) - 1
+ if range_start_idx < range_end_idx:
+ ax.axvspan(range_start_idx, range_end_idx, color='lightblue', alpha=0.1, label='Sampled Range')
+
+
plt.tight_layout()
plt.savefig(buf, format='png')
plt.close(fig)
From 1eab022bb0997934041c9b2112e0cb6d379101f4 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Sun, 28 Dec 2025 02:35:42 +0200
Subject: [PATCH 18/22] Update nodes.py
---
nodes.py | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/nodes.py b/nodes.py
index f7ef927..23ff341 100644
--- a/nodes.py
+++ b/nodes.py
@@ -919,7 +919,7 @@ class WanVideoSVIProEmbeds:
},
"optional": {
"prev_samples": ("LATENT", {"tooltip": "Last latent from previous generation"}),
- "motion_latent_count": ("INT", {"default": 2, "min": 1, "max": 100, "step": 1, "tooltip": "Number of latents used to continue"}),
+ "motion_latent_count": ("INT", {"default": 1, "min": 0, "max": 100, "step": 1, "tooltip": "Number of latents used to continue"}),
}
}
@@ -957,8 +957,6 @@ class WanVideoSVIProEmbeds:
image_embeds = {
"image_embeds": y,
-
- #"max_seq_len": max_seq_len,
"num_frames": num_frames,
"lat_h": H,
"lat_w": W,
From 3730ccf603cadf090f4fc8af8ae657b6c2f93d80 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Sun, 28 Dec 2025 10:34:13 +0200
Subject: [PATCH 19/22] Fix s2v
---
nodes_model_loading.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/nodes_model_loading.py b/nodes_model_loading.py
index 1f9a1d8..83abf6f 100644
--- a/nodes_model_loading.py
+++ b/nodes_model_loading.py
@@ -1235,9 +1235,7 @@ class WanVideoModelLoader:
lynx_ip_layers = "lite"
model_type = "t2v"
- if "audio_injector.injector.0.k.weight" in sd:
- model_type = "s2v"
- elif not "text_embedding.0.weight" in sd:
+ if not "text_embedding.0.weight" in sd:
model_type = "no_cross_attn" #minimaxremover
elif "model_type.Wan2_1-FLF2V-14B-720P" in sd or "img_emb.emb_pos" in sd or "flf2v" in model.lower():
model_type = "fl2v"
@@ -1247,6 +1245,8 @@ class WanVideoModelLoader:
model_type = "t2v"
elif "control_adapter.conv.weight" in sd:
model_type = "t2v"
+ if "audio_injector.injector.0.k.weight" in sd:
+ model_type = "s2v"
out_dim = 16
if dim == 5120: #14B
From 486564060ff740754978fdbc43f4665bd4632266 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Mon, 29 Dec 2025 01:35:32 +0200
Subject: [PATCH 20/22] Add node to set attention mode per step and/or blocks
---
nodes_model_loading.py | 54 +++++++++++++++++++++++++++++++--------
nodes_sampler.py | 1 +
wanvideo/modules/model.py | 45 +++++++++++++++++++++-----------
3 files changed, 74 insertions(+), 26 deletions(-)
diff --git a/nodes_model_loading.py b/nodes_model_loading.py
index 83abf6f..01977f4 100644
--- a/nodes_model_loading.py
+++ b/nodes_model_loading.py
@@ -36,6 +36,9 @@ try:
except:
PromptServer = None
+attention_modes = ["sdpa", "flash_attn_2", "flash_attn_3", "sageattn", "sageattn_3", "radial_sage_attention", "sageattn_compiled",
+ "sageattn_ultravico", "comfy"]
+
#from city96's gguf nodes
def update_folder_names_and_paths(key, targets=[]):
# check for existing key
@@ -1006,6 +1009,43 @@ def add_lora_weights(patcher, lora, base_dtype, merge_loras=False):
del lora_sd
return patcher, control_lora, unianimate_sd
+class WanVideoSetAttentionModeOverride:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {
+ "required": {
+ "model": ("WANVIDEOMODEL", ),
+ "attention_mode": (attention_modes, {"default": "sdpa"}),
+ "start_step": ("INT", {"default": 1, "min": 1, "max": 10000, "step": 1, "tooltip": "Step to start applying the attention mode override"}),
+ "end_step": ("INT", {"default": 10000, "min": 1, "max": 10000, "step": 1, "tooltip": "Step to end applying the attention mode override"}),
+ "verbose": ("BOOLEAN", {"default": False, "tooltip": "Print verbose info about attention mode override during generation"}),
+ },
+ "optional": {
+ "blocks":("INT", {"forceInput": True} ),
+ }
+ }
+
+ RETURN_TYPES = ("WANVIDEOMODEL",)
+ RETURN_NAMES = ("model", )
+ FUNCTION = "getmodelpath"
+ CATEGORY = "WanVideoWrapper"
+ DESCRIPTION = "Override the attention mode for the model for specific step and/or block range"
+
+ def getmodelpath(self, model, attention_mode, start_step, end_step, verbose, blocks=None):
+ model_clone = model.clone()
+ attention_mode_override = {
+ "mode": attention_mode,
+ "start_step": start_step,
+ "end_step": end_step,
+ "verbose": verbose,
+ }
+ if blocks is not None:
+ attention_mode_override["blocks"] = blocks
+ model_clone.model_options['transformer_options']["attention_mode_override"] = attention_mode_override
+
+ return (model_clone,)
+
+
#region Model loading
class WanVideoModelLoader:
@classmethod
@@ -1020,17 +1060,7 @@ class WanVideoModelLoader:
"load_device": (["main_device", "offload_device"], {"default": "offload_device", "tooltip": "Initial device to load the model to, NOT recommended with the larger models unless you have 48GB+ VRAM"}),
},
"optional": {
- "attention_mode": ([
- "sdpa",
- "flash_attn_2",
- "flash_attn_3",
- "sageattn",
- "sageattn_3",
- "radial_sage_attention",
- "sageattn_compiled",
- "sageattn_ultravico",
- "comfy"
- ], {"default": "sdpa"}),
+ "attention_mode": (attention_modes, {"default": "sdpa"}),
"compile_args": ("WANCOMPILEARGS", ),
"block_swap_args": ("BLOCKSWAPARGS", ),
"lora": ("WANVIDLORA", {"default": None}),
@@ -2043,6 +2073,7 @@ NODE_CLASS_MAPPINGS = {
"WanVideoTorchCompileSettings": WanVideoTorchCompileSettings,
"LoadWanVideoT5TextEncoder": LoadWanVideoT5TextEncoder,
"LoadWanVideoClipTextEncoder": LoadWanVideoClipTextEncoder,
+ "WanVideoSetAttentionModeOverride": WanVideoSetAttentionModeOverride,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -2061,4 +2092,5 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"WanVideoTorchCompileSettings": "WanVideo Torch Compile Settings",
"LoadWanVideoT5TextEncoder": "WanVideo T5 Text Encoder Loader",
"LoadWanVideoClipTextEncoder": "WanVideo CLIP Text Encoder Loader",
+ "WanVideoSetAttentionModeOverride": "WanVideo Set Attention Mode Override",
}
diff --git a/nodes_sampler.py b/nodes_sampler.py
index d054b90..6072608 100644
--- a/nodes_sampler.py
+++ b/nodes_sampler.py
@@ -1414,6 +1414,7 @@ class WanVideoSampler:
'is_uncond': False, # is unconditional
'current_step': idx, # current step
'current_step_percentage': current_step_percentage, # current step percentage
+ 'attention_mode_override': transformer_options.get("attention_mode_override", None),
'last_step': len(timesteps) - 1 == idx, # is last step
'control_lora_enabled': control_lora_enabled, # control lora toggle for patch embed selection
'enhance_enabled': enhance_enabled, # enhance-a-video toggle
diff --git a/wanvideo/modules/model.py b/wanvideo/modules/model.py
index 96df41c..6a31cb9 100644
--- a/wanvideo/modules/model.py
+++ b/wanvideo/modules/model.py
@@ -497,7 +497,7 @@ class WanSelfAttention(nn.Module):
attention_mode = self.attention_mode
if attention_mode_override is not None:
attention_mode = attention_mode_override
-
+
# Concatenate main and IP keys/values for main attention
full_k = torch.cat([k, k_ip], dim=1)
full_v = torch.cat([v, v_ip], dim=1)
@@ -1006,6 +1006,7 @@ class WanAttentionBlock(nn.Module):
longcat_num_cond_latents=0, longcat_avatar_options=None, #longcat image cond amount
x_onetoall_ref=None, onetoall_freqs=None, onetoall_ref=None, onetoall_ref_scale=1.0, #one-to-all
e_tr=None, tr_num=0, tr_start=0, #token replacement
+ attention_mode_override=None,
):
r"""
Args:
@@ -1150,6 +1151,10 @@ class WanAttentionBlock(nn.Module):
if enhance_enabled:
feta_scores = get_feta_scores(q, k)
+ if self.attention_mode == "sageattn_3" and attention_mode_override is None:
+ if current_step != 0 and not last_step:
+ attention_mode_override = "sageattn"
+
#self-attention
split_attn = (context is not None
and (context.shape[0] > 1 or (clip_embed is not None and clip_embed.shape[0] > 1))
@@ -1161,19 +1166,14 @@ class WanAttentionBlock(nn.Module):
y = self.self_attn.forward_split(q, k, v, seq_lens, grid_sizes, seq_chunks)
elif ref_target_masks is not None: #multi/infinite talk
y, x_ref_attn_map = self.self_attn.forward_multitalk(q, k, v, seq_lens, grid_sizes, ref_target_masks)
- elif self.attention_mode == "radial_sage_attention":
+ elif self.attention_mode == "radial_sage_attention" or attention_mode_override is not None and attention_mode_override == "radial_sage_attention":
if self.dense_block or self.dense_timesteps is not None and current_step < self.dense_timesteps:
if self.dense_attention_mode == "sparse_sage_attn":
y = self.self_attn.forward_radial(q, k, v, dense_step=True)
else:
- y = self.self_attn.forward(q, k, v, seq_lens)
+ y = self.self_attn.forward(q, k, v, seq_lens, attention_mode_override=attention_mode_override)
else:
y = self.self_attn.forward_radial(q, k, v, dense_step=False)
- elif self.attention_mode == "sageattn_3":
- if current_step != 0 and not last_step:
- y = self.self_attn.forward(q, k, v, seq_lens, attention_mode_override="sageattn_3")
- else:
- y = self.self_attn.forward(q, k, v, seq_lens, attention_mode_override="sageattn")
elif x_ip is not None and self.kv_cache is None: #stand-in
# First pass: cache IP keys/values and compute attention
self.kv_cache = {"k_ip": k_ip.detach(), "v_ip": v_ip.detach()}
@@ -1184,18 +1184,18 @@ class WanAttentionBlock(nn.Module):
v_ip = self.kv_cache["v_ip"]
full_k = torch.cat([k, k_ip], dim=1)
full_v = torch.cat([v, v_ip], dim=1)
- y = self.self_attn.forward(q, full_k, full_v, seq_lens)
+ y = self.self_attn.forward(q, full_k, full_v, seq_lens, attention_mode_override=attention_mode_override)
elif is_longcat and longcat_num_cond_latents > 0:
if longcat_num_cond_latents == 1:
num_cond_latents_thw = longcat_num_cond_latents * (N // num_latent_frames)
# process the noise tokens
- x_noise = self.self_attn.forward(q[:, num_cond_latents_thw:].contiguous(), k, v, seq_lens)
+ x_noise = self.self_attn.forward(q[:, num_cond_latents_thw:].contiguous(), k, v, seq_lens, attention_mode_override=attention_mode_override)
# process the condition tokens
x_cond = self.self_attn.forward(
q[:, :num_cond_latents_thw].contiguous(),
k[:, :num_cond_latents_thw].contiguous(),
v[:, :num_cond_latents_thw].contiguous(),
- seq_lens)
+ seq_lens, attention_mode_override=attention_mode_override)
# merge x_cond and x_noise
y = torch.cat([x_cond, x_noise], dim=1).contiguous()
elif longcat_num_cond_latents > 1: # video continuation
@@ -1237,13 +1237,14 @@ class WanAttentionBlock(nn.Module):
q_cond = q[:, num_ref_latents_thw:num_cond_latents_thw].contiguous()
k_cond = k[:, num_ref_latents_thw:num_cond_latents_thw].contiguous()
v_cond = v[:, num_ref_latents_thw:num_cond_latents_thw].contiguous()
- x_ref = self.self_attn.forward(q_ref, k_ref, v_ref, seq_lens)
- x_cond = self.self_attn.forward(q_cond, k_cond, v_cond, seq_lens)
+ x_ref = self.self_attn.forward(q_ref, k_ref, v_ref, seq_lens, attention_mode_override=attention_mode_override)
+ x_cond = self.self_attn.forward(q_cond, k_cond, v_cond, seq_lens, attention_mode_override=attention_mode_override)
# merge x_cond and x_noise
y = torch.cat([x_ref, x_cond, x_noise], dim=1).contiguous()
else:
- y = self.self_attn.forward(q, k, v, seq_lens, lynx_ref_feature=lynx_ref_feature, lynx_ref_scale=lynx_ref_scale, onetoall_ref=onetoall_ref, onetoall_ref_scale=onetoall_ref_scale)
+ y = self.self_attn.forward(q, k, v, seq_lens, lynx_ref_feature=lynx_ref_feature, lynx_ref_scale=lynx_ref_scale,
+ onetoall_ref=onetoall_ref, onetoall_ref_scale=onetoall_ref_scale, attention_mode_override=attention_mode_override)
del q, k, v
@@ -2280,6 +2281,7 @@ class WanModel(torch.nn.Module):
self, x, t, context, seq_len,
is_uncond=False,
current_step_percentage=0.0, current_step=0, last_step=0, total_steps=50,
+ attention_mode_override=None,
clip_fea=None, y=None,
device=torch.device('cuda'),
freqs=None,
@@ -3125,8 +3127,21 @@ class WanModel(torch.nn.Module):
if lynx_ref_buffer is None and lynx_ref_feature_extractor:
lynx_ref_buffer = {}
+ attn_override_blocks = attention_mode = None
+ attention_mode_override_active = False
+ if attention_mode_override is not None:
+ attn_override_blocks = attention_mode_override.get("blocks", range(len(self.blocks)))
+ if attention_mode_override["start_step"] <= current_step < attention_mode_override["end_step"]:
+ attention_mode_override_active = True
+ if attention_mode_override["verbose"]:
+ tqdm.write(f"Applying attention mode override: {attention_mode_override['mode']} at step {current_step} on blocks: {attn_override_blocks if attn_override_blocks is not None else 'all'}")
+
for b, block in enumerate(self.blocks):
mm.throw_exception_if_processing_interrupted()
+ if attention_mode_override_active and b in attn_override_blocks:
+ attention_mode = attention_mode_override['mode']
+ else:
+ attention_mode = None
block_idx = f"{b:02d}"
if lynx_ref_buffer is not None and not lynx_ref_feature_extractor:
lynx_ref_feature = lynx_ref_buffer.get(block_idx, None)
@@ -3170,7 +3185,7 @@ class WanModel(torch.nn.Module):
x_onetoall_ref = onetoall_ref_block_samples[b // interval_ref]
# ---run block----#
- x, x_ip, lynx_ref_feature, x_ovi = block(x, x_ip=x_ip, lynx_ref_feature=lynx_ref_feature, x_ovi=x_ovi, x_onetoall_ref=x_onetoall_ref, onetoall_freqs=onetoall_freqs, **kwargs)
+ x, x_ip, lynx_ref_feature, x_ovi = block(x, x_ip=x_ip, lynx_ref_feature=lynx_ref_feature, x_ovi=x_ovi, x_onetoall_ref=x_onetoall_ref, onetoall_freqs=onetoall_freqs, attention_mode_override=attention_mode, **kwargs)
# ---post block----#
if self.audio_injector is not None and s2v_audio_input is not None:
From 2fe483417849fe14ce422c3d616358c8031b5a89 Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Mon, 29 Dec 2025 02:48:59 +0200
Subject: [PATCH 21/22] Adjust ultravico frame_tokens
---
nodes_model_loading.py | 2 +-
ultravico/sageattn/attn_qk_int8_per_block.py | 4 ++--
wanvideo/modules/attention.py | 8 ++++----
wanvideo/modules/model.py | 10 ++++++----
4 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/nodes_model_loading.py b/nodes_model_loading.py
index 01977f4..9b32b99 100644
--- a/nodes_model_loading.py
+++ b/nodes_model_loading.py
@@ -1016,7 +1016,7 @@ class WanVideoSetAttentionModeOverride:
"required": {
"model": ("WANVIDEOMODEL", ),
"attention_mode": (attention_modes, {"default": "sdpa"}),
- "start_step": ("INT", {"default": 1, "min": 1, "max": 10000, "step": 1, "tooltip": "Step to start applying the attention mode override"}),
+ "start_step": ("INT", {"default": 0, "min": 0, "max": 10000, "step": 1, "tooltip": "Step to start applying the attention mode override"}),
"end_step": ("INT", {"default": 10000, "min": 1, "max": 10000, "step": 1, "tooltip": "Step to end applying the attention mode override"}),
"verbose": ("BOOLEAN", {"default": False, "tooltip": "Print verbose info about attention mode override during generation"}),
},
diff --git a/ultravico/sageattn/attn_qk_int8_per_block.py b/ultravico/sageattn/attn_qk_int8_per_block.py
index 3d85856..645d5a4 100644
--- a/ultravico/sageattn/attn_qk_int8_per_block.py
+++ b/ultravico/sageattn/attn_qk_int8_per_block.py
@@ -38,7 +38,7 @@ def _attn_fwd_inner(acc, l_i, m_i, q, q_scale, kv_len, current_flag,
qk = tl.dot(q, k).to(tl.float32) * q_scale * k_scale
- window_th = 1560 * 21 / 2
+ window_th = frame_tokens * window_width / 2
dist2 = tl.abs(m - n).to(tl.int32)
dist_mask = dist2 <= window_th
@@ -46,7 +46,7 @@ def _attn_fwd_inner(acc, l_i, m_i, q, q_scale, kv_len, current_flag,
qk = tl.where(dist_mask | negative_mask, qk, qk*multi_factor)
- window3 = (m <= frame_tokens) & (n > 21*frame_tokens)
+ window3 = (m <= frame_tokens) & (n > window_width*frame_tokens)
qk = tl.where(window3, -1e4, qk)
diff --git a/wanvideo/modules/attention.py b/wanvideo/modules/attention.py
index 09caac8..3b891d3 100644
--- a/wanvideo/modules/attention.py
+++ b/wanvideo/modules/attention.py
@@ -80,9 +80,9 @@ except:
try:
from ...ultravico.sageattn.core import sage_attention as sageattn_ultravico
@torch.library.custom_op("wanvideo::sageattn_ultravico", mutates_args=())
- def sageattn_func_ultravico(qkv: List[torch.Tensor], attn_mask: torch.Tensor | None = None, dropout_p: float = 0.0, is_causal: bool = False, multi_factor: float = 0.9
+ def sageattn_func_ultravico(qkv: List[torch.Tensor], attn_mask: torch.Tensor | None = None, dropout_p: float = 0.0, is_causal: bool = False, multi_factor: float = 0.9, frame_tokens: int = 1536
) -> torch.Tensor:
- return sageattn_ultravico(qkv, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal, multi_factor=multi_factor)
+ return sageattn_ultravico(qkv, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal, multi_factor=multi_factor, frame_tokens=frame_tokens)
@sageattn_func_ultravico.register_fake
def _(qkv, attn_mask=None, dropout_p=0.0, is_causal=False, multi_factor=0.9):
@@ -94,7 +94,7 @@ except:
def attention(q, k, v, q_lens=None, k_lens=None, max_seqlen_q=None, max_seqlen_k=None, dropout_p=0.,
softmax_scale=None, q_scale=None, causal=False, window_size=(-1, -1), deterministic=False, dtype=torch.bfloat16,
- attention_mode='sdpa', attn_mask=None, multi_factor=0.9, heads=128):
+ attention_mode='sdpa', attn_mask=None, multi_factor=0.9, frame_tokens=1536, heads=128):
if "flash" in attention_mode:
return flash_attention(q, k, v, q_lens=q_lens, k_lens=k_lens, dropout_p=dropout_p, softmax_scale=softmax_scale,
q_scale=q_scale, causal=causal, window_size=window_size, deterministic=deterministic, dtype=dtype, version=2 if attention_mode == 'flash_attn_2' else 3,
@@ -108,7 +108,7 @@ def attention(q, k, v, q_lens=None, k_lens=None, max_seqlen_q=None, max_seqlen_k
elif attention_mode == 'sageattn':
return sageattn_func(q, k, v, tensor_layout="NHD").contiguous()
elif attention_mode == 'sageattn_ultravico':
- return sageattn_func_ultravico([q, k, v], multi_factor=multi_factor).contiguous()
+ return sageattn_func_ultravico([q, k, v], multi_factor=multi_factor, frame_tokens=frame_tokens).contiguous()
elif attention_mode == 'comfy':
return optimized_attention(q.transpose(1,2), k.transpose(1,2), v.transpose(1,2), heads=heads, skip_reshape=True)
else: # sdpa
diff --git a/wanvideo/modules/model.py b/wanvideo/modules/model.py
index 6a31cb9..7db9377 100644
--- a/wanvideo/modules/model.py
+++ b/wanvideo/modules/model.py
@@ -467,7 +467,7 @@ class WanSelfAttention(nn.Module):
v = (self.v(x) + self.v_loras(x)).view(b, s, n, d)
return q, k, v
- def forward(self, q, k, v, seq_lens, lynx_ref_feature=None, lynx_ref_scale=1.0, attention_mode_override=None, onetoall_ref=None, onetoall_ref_scale=1.0):
+ def forward(self, q, k, v, seq_lens, lynx_ref_feature=None, lynx_ref_scale=1.0, attention_mode_override=None, onetoall_ref=None, onetoall_ref_scale=1.0, frame_tokens=1536):
r"""
Args:
x(Tensor): Shape [B, L, num_heads, C / num_heads]
@@ -477,12 +477,13 @@ class WanSelfAttention(nn.Module):
"""
attention_mode = self.attention_mode
if attention_mode_override is not None:
+ print("Overriding attention mode to:", attention_mode_override)
attention_mode = attention_mode_override
if self.ref_adapter is not None and lynx_ref_feature is not None:
ref_x = self.ref_adapter(self, q, lynx_ref_feature)
- x = attention(q, k, v, k_lens=seq_lens, attention_mode=attention_mode, heads=self.num_heads)
+ x = attention(q, k, v, k_lens=seq_lens, attention_mode=attention_mode, heads=self.num_heads, frame_tokens=frame_tokens)
if self.ref_adapter is not None and lynx_ref_feature is not None:
x = x.add(ref_x, alpha=lynx_ref_scale)
@@ -1006,7 +1007,7 @@ class WanAttentionBlock(nn.Module):
longcat_num_cond_latents=0, longcat_avatar_options=None, #longcat image cond amount
x_onetoall_ref=None, onetoall_freqs=None, onetoall_ref=None, onetoall_ref_scale=1.0, #one-to-all
e_tr=None, tr_num=0, tr_start=0, #token replacement
- attention_mode_override=None,
+ attention_mode_override=None, frame_tokens=None,
):
r"""
Args:
@@ -1244,7 +1245,7 @@ class WanAttentionBlock(nn.Module):
y = torch.cat([x_ref, x_cond, x_noise], dim=1).contiguous()
else:
y = self.self_attn.forward(q, k, v, seq_lens, lynx_ref_feature=lynx_ref_feature, lynx_ref_scale=lynx_ref_scale,
- onetoall_ref=onetoall_ref, onetoall_ref_scale=onetoall_ref_scale, attention_mode_override=attention_mode_override)
+ onetoall_ref=onetoall_ref, onetoall_ref_scale=onetoall_ref_scale, attention_mode_override=attention_mode_override, frame_tokens=frame_tokens)
del q, k, v
@@ -3041,6 +3042,7 @@ class WanModel(torch.nn.Module):
camera_embed=camera_embed,
audio_proj=audio_proj,
num_latent_frames = F,
+ frame_tokens=x.shape[1] // F,
original_seq_len=self.original_seq_len,
enhance_enabled=enhance_enabled,
audio_scale=audio_scale,
From 19bcee67ed7408271aadef7921b01b81705e076b Mon Sep 17 00:00:00 2001
From: kijai <40791699+kijai@users.noreply.github.com>
Date: Mon, 29 Dec 2025 02:50:04 +0200
Subject: [PATCH 22/22] remove print
---
wanvideo/modules/model.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/wanvideo/modules/model.py b/wanvideo/modules/model.py
index 7db9377..4a85818 100644
--- a/wanvideo/modules/model.py
+++ b/wanvideo/modules/model.py
@@ -477,7 +477,6 @@ class WanSelfAttention(nn.Module):
"""
attention_mode = self.attention_mode
if attention_mode_override is not None:
- print("Overriding attention mode to:", attention_mode_override)
attention_mode = attention_mode_override
if self.ref_adapter is not None and lynx_ref_feature is not None: