From 83645811f441292c957312a288fb39197d34070e Mon Sep 17 00:00:00 2001 From: Chris Dumas Date: Fri, 4 Sep 2026 14:52:43 +0000 Subject: [PATCH] Reuse conditioning for refinement tiles --- dumas_h3_longvideos.py | 56 +++++++++++++++++++++++++++---- tests/test_dumas_h3_longvideos.py | 6 ++++ 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/dumas_h3_longvideos.py b/dumas_h3_longvideos.py index c3f1a34..5e03ca4 100644 --- a/dumas_h3_longvideos.py +++ b/dumas_h3_longvideos.py @@ -4076,6 +4076,52 @@ def _retarget_conditioning_spatial(cond, latent_h, latent_w): return out +def _pad_to_h3_patch_size(tensor): + try: + import comfy.ldm.common_dit as common_dit + return common_dit.pad_to_patch_size(tensor, (1, 2, 2)) + except Exception: + return tensor + + +def _crop_conditioning_to_tile(cond, source_h, source_w, row, col, tile_h, tile_w): + """Crop H3 keyframe latents in existing conditioning for a spatial tile.""" + out = [] + for item in cond: + try: + tensor, data = item + except Exception: + out.append(item) + continue + nd = dict(data) + keyframes = nd.get("minimax_keyframes") + if keyframes: + cropped_keyframes = [] + for keyframe in keyframes: + nkf = dict(keyframe) + latent_value = nkf.get("latent") + if latent_value is not None and len(getattr(latent_value, "shape", ())) >= 5: + kh, kw = latent_value.shape[3], latent_value.shape[4] + if kh != source_h or kw != source_w: + b, c, t, h, w = latent_value.shape + latent_value = torch.nn.functional.interpolate( + latent_value.to(torch.float32).reshape(b * t, c, h, w), + size=(source_h, source_w), + mode="bilinear", + align_corners=False, + ).reshape(b, c, t, source_h, source_w).to( + device=latent_value.device, + dtype=latent_value.dtype, + ) + nkf["latent"] = _pad_to_h3_patch_size( + latent_value[:, :, :, row:row + tile_h, col:col + tile_w].contiguous() + ) + cropped_keyframes.append(nkf) + nd["minimax_keyframes"] = cropped_keyframes + out.append([tensor, nd]) + return out + + def _latent_with_replaced_samples(template_latent, sampled_latent): """Reuse the original latent payload, but swap in freshly sampled tensors.""" if not isinstance(template_latent, dict): @@ -6828,12 +6874,10 @@ class H3LongVideos: for col_index, c0 in enumerate(cols): tc = tcols[col_index] ovw = col_ovl[col_index] - tile_target_w = int(tc) * 16 - tile_target_h = int(tr) * 16 - tile_cond, tile_latent = _build_shot_conditioning( - clip, vae, prompt, tile_target_w, tile_target_h, ln, fps, handoff, - ref_images=refs, ref_image_size=ref_image_size, - ref_noise_aug=ref_noise_aug, audio_vae=audio_vae, silent=silent) + tile_cond = _crop_conditioning_to_tile( + upscale_cond, int(up_h), int(up_w), r0, c0, tr, tc + ) + tile_latent = dict(upscale_latent) if isinstance(upscale_latent, dict) else {} tile_video = upscaled_video[:, :, :, r0:r0 + tr, c0:c0 + tc].contiguous() tr_s = tr + (tr % 2) tc_s = tc + (tc % 2) diff --git a/tests/test_dumas_h3_longvideos.py b/tests/test_dumas_h3_longvideos.py index bb9095d..ac2a1ad 100644 --- a/tests/test_dumas_h3_longvideos.py +++ b/tests/test_dumas_h3_longvideos.py @@ -482,6 +482,12 @@ class DumasH3LongVideosHelperTests(unittest.TestCase): else: self.module.comfy.nested_tensor.NestedTensor = original_nested + def test_latent_refine_tiles_do_not_rebuild_conditioning(self): + source = inspect.getsource(self.module.H3LongVideos._render) + tile_branch = source[source.index("for col_index, c0 in enumerate(cols):"):] + self.assertIn("_crop_conditioning_to_tile", tile_branch) + self.assertNotIn("_build_shot_conditioning(", tile_branch) + def test_latent_upscale_off_skips_second_pass(self): calls = [] original_common_ksampler = self.module.nodes.common_ksampler