Add console logging to all VFI interpolation nodes
Log mode/params, pass progress, chunk count, and output frame count for BIM-VFI, EMA-VFI, SGM-VFI, and GIMM-VFI interpolation nodes. Segment nodes also log their input frame range and target fps output range. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
81
nodes.py
81
nodes.py
@@ -219,6 +219,7 @@ class BIMVFIInterpolate:
|
|||||||
Interpolated frames as [M, C, H, W] tensor on storage_device
|
Interpolated frames as [M, C, H, W] tensor on storage_device
|
||||||
"""
|
"""
|
||||||
for pass_idx in range(num_passes):
|
for pass_idx in range(num_passes):
|
||||||
|
logger.info(f"BIM-VFI: pass {pass_idx + 1}/{num_passes}, {frames.shape[0]} -> {2 * frames.shape[0] - 1} frames")
|
||||||
new_frames = []
|
new_frames = []
|
||||||
num_pairs = frames.shape[0] - 1
|
num_pairs = frames.shape[0] - 1
|
||||||
pairs_since_clear = 0
|
pairs_since_clear = 0
|
||||||
@@ -290,6 +291,18 @@ class BIMVFIInterpolate:
|
|||||||
num_passes = {2: 1, 4: 2, 8: 3}[multiplier]
|
num_passes = {2: 1, 4: 2, 8: 3}[multiplier]
|
||||||
mult = multiplier
|
mult = multiplier
|
||||||
|
|
||||||
|
N = images.shape[0]
|
||||||
|
expected = mult * (N - 1) + 1
|
||||||
|
if use_target_fps:
|
||||||
|
if num_passes == 0:
|
||||||
|
expected = int(math.floor((N - 1) / source_fps * target_fps)) + 1
|
||||||
|
logger.info(f"BIM-VFI: {N} frames, {source_fps}fps -> {target_fps}fps (downsampling), expected output: {expected} frames")
|
||||||
|
else:
|
||||||
|
expected_target = int(math.floor((N - 1) / source_fps * target_fps)) + 1
|
||||||
|
logger.info(f"BIM-VFI: interpolating {N} frames, {source_fps}fps -> {target_fps}fps (oversample {mult}x, {num_passes} pass(es)), expected output: {expected_target} frames")
|
||||||
|
else:
|
||||||
|
logger.info(f"BIM-VFI: interpolating {N} frames, {mult}x ({num_passes} pass(es)), expected output: {expected} frames")
|
||||||
|
|
||||||
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||||
|
|
||||||
if all_on_gpu:
|
if all_on_gpu:
|
||||||
@@ -314,6 +327,9 @@ class BIMVFIInterpolate:
|
|||||||
if end == total_input:
|
if end == total_input:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if len(chunks) > 1:
|
||||||
|
logger.info(f"BIM-VFI: processing in {len(chunks)} chunk(s)")
|
||||||
|
|
||||||
# Calculate total progress steps across all chunks
|
# Calculate total progress steps across all chunks
|
||||||
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
||||||
pbar = ProgressBar(total_steps)
|
pbar = ProgressBar(total_steps)
|
||||||
@@ -353,6 +369,7 @@ class BIMVFIInterpolate:
|
|||||||
|
|
||||||
# Convert back to ComfyUI [B, H, W, C], on CPU
|
# Convert back to ComfyUI [B, H, W, C], on CPU
|
||||||
result = result.cpu().permute(0, 2, 3, 1)
|
result = result.cpu().permute(0, 2, 3, 1)
|
||||||
|
logger.info(f"BIM-VFI: done, {result.shape[0]} output frames")
|
||||||
return (result, oversampled)
|
return (result, oversampled)
|
||||||
|
|
||||||
|
|
||||||
@@ -401,6 +418,7 @@ class BIMVFISegmentInterpolate(BIMVFIInterpolate):
|
|||||||
return (images[:1], model)
|
return (images[:1], model)
|
||||||
|
|
||||||
segment_images = images[start:end]
|
segment_images = images[start:end]
|
||||||
|
logger.info(f"BIM-VFI segment {segment_index}: input frames [{start}:{end}] of {total_input}")
|
||||||
|
|
||||||
if use_target_fps:
|
if use_target_fps:
|
||||||
num_passes, mult = _compute_target_fps_params(source_fps, target_fps)
|
num_passes, mult = _compute_target_fps_params(source_fps, target_fps)
|
||||||
@@ -420,6 +438,8 @@ class BIMVFISegmentInterpolate(BIMVFIInterpolate):
|
|||||||
if j_start > j_end:
|
if j_start > j_end:
|
||||||
return (images[:1], model)
|
return (images[:1], model)
|
||||||
|
|
||||||
|
logger.info(f"BIM-VFI segment {segment_index}: target fps output j=[{j_start}..{j_end}]")
|
||||||
|
|
||||||
if num_passes == 0:
|
if num_passes == 0:
|
||||||
# Downsampling — select from segment input directly
|
# Downsampling — select from segment input directly
|
||||||
oversampled_fps = source_fps * mult
|
oversampled_fps = source_fps * mult
|
||||||
@@ -750,6 +770,7 @@ class EMAVFIInterpolate:
|
|||||||
clear_cache_after_n_frames, pbar, step_ref):
|
clear_cache_after_n_frames, pbar, step_ref):
|
||||||
"""Run all interpolation passes on a chunk of frames."""
|
"""Run all interpolation passes on a chunk of frames."""
|
||||||
for pass_idx in range(num_passes):
|
for pass_idx in range(num_passes):
|
||||||
|
logger.info(f"EMA-VFI: pass {pass_idx + 1}/{num_passes}, {frames.shape[0]} -> {2 * frames.shape[0] - 1} frames")
|
||||||
new_frames = []
|
new_frames = []
|
||||||
num_pairs = frames.shape[0] - 1
|
num_pairs = frames.shape[0] - 1
|
||||||
pairs_since_clear = 0
|
pairs_since_clear = 0
|
||||||
@@ -820,6 +841,18 @@ class EMAVFIInterpolate:
|
|||||||
num_passes = {2: 1, 4: 2, 8: 3}[multiplier]
|
num_passes = {2: 1, 4: 2, 8: 3}[multiplier]
|
||||||
mult = multiplier
|
mult = multiplier
|
||||||
|
|
||||||
|
N = images.shape[0]
|
||||||
|
expected = mult * (N - 1) + 1
|
||||||
|
if use_target_fps:
|
||||||
|
if num_passes == 0:
|
||||||
|
expected = int(math.floor((N - 1) / source_fps * target_fps)) + 1
|
||||||
|
logger.info(f"EMA-VFI: {N} frames, {source_fps}fps -> {target_fps}fps (downsampling), expected output: {expected} frames")
|
||||||
|
else:
|
||||||
|
expected_target = int(math.floor((N - 1) / source_fps * target_fps)) + 1
|
||||||
|
logger.info(f"EMA-VFI: interpolating {N} frames, {source_fps}fps -> {target_fps}fps (oversample {mult}x, {num_passes} pass(es)), expected output: {expected_target} frames")
|
||||||
|
else:
|
||||||
|
logger.info(f"EMA-VFI: interpolating {N} frames, {mult}x ({num_passes} pass(es)), expected output: {expected} frames")
|
||||||
|
|
||||||
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||||
|
|
||||||
if all_on_gpu:
|
if all_on_gpu:
|
||||||
@@ -844,6 +877,9 @@ class EMAVFIInterpolate:
|
|||||||
if end == total_input:
|
if end == total_input:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if len(chunks) > 1:
|
||||||
|
logger.info(f"EMA-VFI: processing in {len(chunks)} chunk(s)")
|
||||||
|
|
||||||
# Calculate total progress steps across all chunks
|
# Calculate total progress steps across all chunks
|
||||||
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
||||||
pbar = ProgressBar(total_steps)
|
pbar = ProgressBar(total_steps)
|
||||||
@@ -883,6 +919,7 @@ class EMAVFIInterpolate:
|
|||||||
|
|
||||||
# Convert back to ComfyUI [B, H, W, C], on CPU
|
# Convert back to ComfyUI [B, H, W, C], on CPU
|
||||||
result = result.cpu().permute(0, 2, 3, 1)
|
result = result.cpu().permute(0, 2, 3, 1)
|
||||||
|
logger.info(f"EMA-VFI: done, {result.shape[0]} output frames")
|
||||||
return (result, oversampled)
|
return (result, oversampled)
|
||||||
|
|
||||||
|
|
||||||
@@ -930,6 +967,7 @@ class EMAVFISegmentInterpolate(EMAVFIInterpolate):
|
|||||||
return (images[:1], model)
|
return (images[:1], model)
|
||||||
|
|
||||||
segment_images = images[start:end]
|
segment_images = images[start:end]
|
||||||
|
logger.info(f"EMA-VFI segment {segment_index}: input frames [{start}:{end}] of {total_input}")
|
||||||
|
|
||||||
if use_target_fps:
|
if use_target_fps:
|
||||||
num_passes, mult = _compute_target_fps_params(source_fps, target_fps)
|
num_passes, mult = _compute_target_fps_params(source_fps, target_fps)
|
||||||
@@ -948,6 +986,8 @@ class EMAVFISegmentInterpolate(EMAVFIInterpolate):
|
|||||||
if j_start > j_end:
|
if j_start > j_end:
|
||||||
return (images[:1], model)
|
return (images[:1], model)
|
||||||
|
|
||||||
|
logger.info(f"EMA-VFI segment {segment_index}: target fps output j=[{j_start}..{j_end}]")
|
||||||
|
|
||||||
if num_passes == 0:
|
if num_passes == 0:
|
||||||
oversampled_fps = source_fps * mult
|
oversampled_fps = source_fps * mult
|
||||||
all_seg = segment_images.permute(0, 3, 1, 2)
|
all_seg = segment_images.permute(0, 3, 1, 2)
|
||||||
@@ -1144,6 +1184,7 @@ class SGMVFIInterpolate:
|
|||||||
clear_cache_after_n_frames, pbar, step_ref):
|
clear_cache_after_n_frames, pbar, step_ref):
|
||||||
"""Run all interpolation passes on a chunk of frames."""
|
"""Run all interpolation passes on a chunk of frames."""
|
||||||
for pass_idx in range(num_passes):
|
for pass_idx in range(num_passes):
|
||||||
|
logger.info(f"SGM-VFI: pass {pass_idx + 1}/{num_passes}, {frames.shape[0]} -> {2 * frames.shape[0] - 1} frames")
|
||||||
new_frames = []
|
new_frames = []
|
||||||
num_pairs = frames.shape[0] - 1
|
num_pairs = frames.shape[0] - 1
|
||||||
pairs_since_clear = 0
|
pairs_since_clear = 0
|
||||||
@@ -1214,6 +1255,18 @@ class SGMVFIInterpolate:
|
|||||||
num_passes = {2: 1, 4: 2, 8: 3}[multiplier]
|
num_passes = {2: 1, 4: 2, 8: 3}[multiplier]
|
||||||
mult = multiplier
|
mult = multiplier
|
||||||
|
|
||||||
|
N = images.shape[0]
|
||||||
|
expected = mult * (N - 1) + 1
|
||||||
|
if use_target_fps:
|
||||||
|
if num_passes == 0:
|
||||||
|
expected = int(math.floor((N - 1) / source_fps * target_fps)) + 1
|
||||||
|
logger.info(f"SGM-VFI: {N} frames, {source_fps}fps -> {target_fps}fps (downsampling), expected output: {expected} frames")
|
||||||
|
else:
|
||||||
|
expected_target = int(math.floor((N - 1) / source_fps * target_fps)) + 1
|
||||||
|
logger.info(f"SGM-VFI: interpolating {N} frames, {source_fps}fps -> {target_fps}fps (oversample {mult}x, {num_passes} pass(es)), expected output: {expected_target} frames")
|
||||||
|
else:
|
||||||
|
logger.info(f"SGM-VFI: interpolating {N} frames, {mult}x ({num_passes} pass(es)), expected output: {expected} frames")
|
||||||
|
|
||||||
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||||
|
|
||||||
if all_on_gpu:
|
if all_on_gpu:
|
||||||
@@ -1238,6 +1291,9 @@ class SGMVFIInterpolate:
|
|||||||
if end == total_input:
|
if end == total_input:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if len(chunks) > 1:
|
||||||
|
logger.info(f"SGM-VFI: processing in {len(chunks)} chunk(s)")
|
||||||
|
|
||||||
# Calculate total progress steps across all chunks
|
# Calculate total progress steps across all chunks
|
||||||
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
||||||
pbar = ProgressBar(total_steps)
|
pbar = ProgressBar(total_steps)
|
||||||
@@ -1277,6 +1333,7 @@ class SGMVFIInterpolate:
|
|||||||
|
|
||||||
# Convert back to ComfyUI [B, H, W, C], on CPU
|
# Convert back to ComfyUI [B, H, W, C], on CPU
|
||||||
result = result.cpu().permute(0, 2, 3, 1)
|
result = result.cpu().permute(0, 2, 3, 1)
|
||||||
|
logger.info(f"SGM-VFI: done, {result.shape[0]} output frames")
|
||||||
return (result, oversampled)
|
return (result, oversampled)
|
||||||
|
|
||||||
|
|
||||||
@@ -1324,6 +1381,7 @@ class SGMVFISegmentInterpolate(SGMVFIInterpolate):
|
|||||||
return (images[:1], model)
|
return (images[:1], model)
|
||||||
|
|
||||||
segment_images = images[start:end]
|
segment_images = images[start:end]
|
||||||
|
logger.info(f"SGM-VFI segment {segment_index}: input frames [{start}:{end}] of {total_input}")
|
||||||
|
|
||||||
if use_target_fps:
|
if use_target_fps:
|
||||||
num_passes, mult = _compute_target_fps_params(source_fps, target_fps)
|
num_passes, mult = _compute_target_fps_params(source_fps, target_fps)
|
||||||
@@ -1342,6 +1400,8 @@ class SGMVFISegmentInterpolate(SGMVFIInterpolate):
|
|||||||
if j_start > j_end:
|
if j_start > j_end:
|
||||||
return (images[:1], model)
|
return (images[:1], model)
|
||||||
|
|
||||||
|
logger.info(f"SGM-VFI segment {segment_index}: target fps output j=[{j_start}..{j_end}]")
|
||||||
|
|
||||||
if num_passes == 0:
|
if num_passes == 0:
|
||||||
oversampled_fps = source_fps * mult
|
oversampled_fps = source_fps * mult
|
||||||
all_seg = segment_images.permute(0, 3, 1, 2)
|
all_seg = segment_images.permute(0, 3, 1, 2)
|
||||||
@@ -1555,6 +1615,7 @@ class GIMMVFIInterpolate:
|
|||||||
clear_cache_after_n_frames, pbar, step_ref):
|
clear_cache_after_n_frames, pbar, step_ref):
|
||||||
"""Single-pass interpolation using GIMM-VFI's arbitrary timestep capability."""
|
"""Single-pass interpolation using GIMM-VFI's arbitrary timestep capability."""
|
||||||
num_intermediates = multiplier - 1
|
num_intermediates = multiplier - 1
|
||||||
|
logger.info(f"GIMM-VFI: single-pass {multiplier}x, {frames.shape[0]} input frames, {num_intermediates} intermediates/pair")
|
||||||
new_frames = []
|
new_frames = []
|
||||||
num_pairs = frames.shape[0] - 1
|
num_pairs = frames.shape[0] - 1
|
||||||
pairs_since_clear = 0
|
pairs_since_clear = 0
|
||||||
@@ -1599,6 +1660,7 @@ class GIMMVFIInterpolate:
|
|||||||
clear_cache_after_n_frames, pbar, step_ref):
|
clear_cache_after_n_frames, pbar, step_ref):
|
||||||
"""Recursive 2x interpolation (standard approach, same as other models)."""
|
"""Recursive 2x interpolation (standard approach, same as other models)."""
|
||||||
for pass_idx in range(num_passes):
|
for pass_idx in range(num_passes):
|
||||||
|
logger.info(f"GIMM-VFI: pass {pass_idx + 1}/{num_passes}, {frames.shape[0]} -> {2 * frames.shape[0] - 1} frames")
|
||||||
new_frames = []
|
new_frames = []
|
||||||
num_pairs = frames.shape[0] - 1
|
num_pairs = frames.shape[0] - 1
|
||||||
pairs_since_clear = 0
|
pairs_since_clear = 0
|
||||||
@@ -1671,6 +1733,18 @@ class GIMMVFIInterpolate:
|
|||||||
else:
|
else:
|
||||||
mult = multiplier
|
mult = multiplier
|
||||||
|
|
||||||
|
N = images.shape[0]
|
||||||
|
expected = mult * (N - 1) + 1
|
||||||
|
if use_target_fps:
|
||||||
|
if num_passes == 0:
|
||||||
|
expected = int(math.floor((N - 1) / source_fps * target_fps)) + 1
|
||||||
|
logger.info(f"GIMM-VFI: {N} frames, {source_fps}fps -> {target_fps}fps (downsampling), expected output: {expected} frames")
|
||||||
|
else:
|
||||||
|
expected_target = int(math.floor((N - 1) / source_fps * target_fps)) + 1
|
||||||
|
logger.info(f"GIMM-VFI: interpolating {N} frames, {source_fps}fps -> {target_fps}fps (oversample {mult}x, {num_passes} pass(es)), expected output: {expected_target} frames")
|
||||||
|
else:
|
||||||
|
logger.info(f"GIMM-VFI: interpolating {N} frames, {mult}x ({num_passes if not single_pass else 'single-pass'}), expected output: {expected} frames")
|
||||||
|
|
||||||
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||||
|
|
||||||
if not single_pass or use_target_fps:
|
if not single_pass or use_target_fps:
|
||||||
@@ -1701,6 +1775,9 @@ class GIMMVFIInterpolate:
|
|||||||
if end == total_input:
|
if end == total_input:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if len(chunks) > 1:
|
||||||
|
logger.info(f"GIMM-VFI: processing in {len(chunks)} chunk(s)")
|
||||||
|
|
||||||
# Calculate total progress steps across all chunks
|
# Calculate total progress steps across all chunks
|
||||||
if single_pass:
|
if single_pass:
|
||||||
total_steps = sum(ce - cs - 1 for cs, ce in chunks)
|
total_steps = sum(ce - cs - 1 for cs, ce in chunks)
|
||||||
@@ -1750,6 +1827,7 @@ class GIMMVFIInterpolate:
|
|||||||
|
|
||||||
# Convert back to ComfyUI [B, H, W, C], on CPU
|
# Convert back to ComfyUI [B, H, W, C], on CPU
|
||||||
result = result.cpu().permute(0, 2, 3, 1)
|
result = result.cpu().permute(0, 2, 3, 1)
|
||||||
|
logger.info(f"GIMM-VFI: done, {result.shape[0]} output frames")
|
||||||
return (result, oversampled)
|
return (result, oversampled)
|
||||||
|
|
||||||
|
|
||||||
@@ -1797,6 +1875,7 @@ class GIMMVFISegmentInterpolate(GIMMVFIInterpolate):
|
|||||||
return (images[:1], model)
|
return (images[:1], model)
|
||||||
|
|
||||||
segment_images = images[start:end]
|
segment_images = images[start:end]
|
||||||
|
logger.info(f"GIMM-VFI segment {segment_index}: input frames [{start}:{end}] of {total_input}")
|
||||||
|
|
||||||
if use_target_fps:
|
if use_target_fps:
|
||||||
num_passes, mult = _compute_target_fps_params(source_fps, target_fps)
|
num_passes, mult = _compute_target_fps_params(source_fps, target_fps)
|
||||||
@@ -1815,6 +1894,8 @@ class GIMMVFISegmentInterpolate(GIMMVFIInterpolate):
|
|||||||
if j_start > j_end:
|
if j_start > j_end:
|
||||||
return (images[:1], model)
|
return (images[:1], model)
|
||||||
|
|
||||||
|
logger.info(f"GIMM-VFI segment {segment_index}: target fps output j=[{j_start}..{j_end}]")
|
||||||
|
|
||||||
if num_passes == 0:
|
if num_passes == 0:
|
||||||
oversampled_fps = source_fps * mult
|
oversampled_fps = source_fps * mult
|
||||||
all_seg = segment_images.permute(0, 3, 1, 2)
|
all_seg = segment_images.permute(0, 3, 1, 2)
|
||||||
|
|||||||
Reference in New Issue
Block a user