From 699bad38873bf8a772fbbcd1aad9234c1ee3286b Mon Sep 17 00:00:00 2001 From: kijai <40791699+kijai@users.noreply.github.com> Date: Sat, 13 Sep 2025 20:10:13 +0300 Subject: [PATCH] InfiniteTalk: Don't stack or return frames when using output path --- HuMo/nodes.py | 2 +- multitalk/nodes.py | 2 +- nodes.py | 18 ++++++++++++------ nodes_utility.py | 7 ++++--- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/HuMo/nodes.py b/HuMo/nodes.py index 507c554..f93e740 100644 --- a/HuMo/nodes.py +++ b/HuMo/nodes.py @@ -212,7 +212,7 @@ class HuMoEmbeds: reference_images_in = common_upscale(reference_images.movedim(-1, 1), width, height, "lanczos", "disabled").movedim(-1, 1) else: reference_images_in = reference_images - samples, = WanVideoEncodeLatentBatch.encode(self, vae, reference_images_in, tiled_vae, 0, 0, 0, 0) + samples, = WanVideoEncodeLatentBatch.encode(self, vae, reference_images_in, tiled_vae, None, None, None, None) samples = samples["samples"].transpose(0, 2).squeeze(0) num_refs = samples.shape[1] diff --git a/multitalk/nodes.py b/multitalk/nodes.py index b305237..4e5690b 100644 --- a/multitalk/nodes.py +++ b/multitalk/nodes.py @@ -391,7 +391,7 @@ class WanVideoImageToVideoMultiTalk: "multitalk", "infinitetalk" ], {"default": "auto", "tooltip": "The sampling strategy to use in the long video generation loop, should match the model used"}), - "output_path": ("STRING", {"default": "", "tooltip": "If set, will save each window's resulting frames to this folder"}), + "output_path": ("STRING", {"default": "", "tooltip": "If set, will save each window's resulting frames to this folder, also DISABLES returning the final video tensor to save memory"}), } } diff --git a/nodes.py b/nodes.py index b7d0c00..4d030d9 100644 --- a/nodes.py +++ b/nodes.py @@ -3796,8 +3796,8 @@ class WanVideoSampler: im = Image.fromarray(video_np[i]) im.save(os.path.join(output_path, f"frame_{img_counter:05d}.png")) img_counter += 1 - - gen_video_list.append(videos if is_first_clip else videos[:, cur_motion_frames_num:]) + else: + gen_video_list.append(videos if is_first_clip else videos[:, cur_motion_frames_num:]) current_condframe_index += 1 iteration_count += 1 @@ -3845,8 +3845,11 @@ class WanVideoSampler: 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) - - gen_video_samples = torch.cat(gen_video_list, dim=1) + + 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"]: @@ -3856,7 +3859,7 @@ class WanVideoSampler: torch.cuda.reset_peak_memory_stats(device) except: pass - return {"video": gen_video_samples.permute(1, 2, 3, 0)}, + return {"video": gen_video_samples.permute(1, 2, 3, 0), "output_path": output_path}, # region framepack loop elif framepack: framepack_out = [] @@ -4283,7 +4286,10 @@ class WanVideoEncodeLatentBatch: latent_list = [] for img in images: - latent = vae.encode(img.unsqueeze(0).unsqueeze(0).permute(0, 4, 1, 2, 3), device=device, tiled=enable_vae_tiling, tile_size=(tile_x//vae.upsampling_factor, tile_y//vae.upsampling_factor), tile_stride=(tile_stride_x//vae.upsampling_factor, tile_stride_y//vae.upsampling_factor)) + if enable_vae_tiling and tile_x is not None: + latent = vae.encode(img.unsqueeze(0).unsqueeze(0).permute(0, 4, 1, 2, 3), device=device, tiled=enable_vae_tiling, tile_size=(tile_x//vae.upsampling_factor, tile_y//vae.upsampling_factor), tile_stride=(tile_stride_x//vae.upsampling_factor, tile_stride_y//vae.upsampling_factor)) + else: + latent = vae.encode(img.unsqueeze(0).unsqueeze(0).permute(0, 4, 1, 2, 3), device=device, tiled=enable_vae_tiling) vae.model.clear_cache() if latent_strength != 1.0: latent *= latent_strength diff --git a/nodes_utility.py b/nodes_utility.py index bbb195d..fa84e28 100644 --- a/nodes_utility.py +++ b/nodes_utility.py @@ -456,8 +456,9 @@ class WanVideoPassImagesFromSamples: } } - RETURN_TYPES = ("IMAGE",) - RETURN_NAMES = ("images",) + RETURN_TYPES = ("IMAGE", "STRING",) + RETURN_NAMES = ("images", "output_path",) + OUTPUT_TOOLTIPS = ("Decoded images from the samples dictionary", "Output path if provided in the samples dictionary",) FUNCTION = "decode" CATEGORY = "WanVideoWrapper" DESCRIPTION = "Gets possible already decoded images from the samples dictionary, used with Multi/InfiniteTalk sampling" @@ -466,7 +467,7 @@ class WanVideoPassImagesFromSamples: video = samples.get("video", None) video.clamp_(-1.0, 1.0) video.add_(1.0).div_(2.0) - return video.cpu().float(), + return video.cpu().float(), samples.get("output_path", "") NODE_CLASS_MAPPINGS = { "WanVideoImageResizeToClosest": WanVideoImageResizeToClosest,