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
|
||||
"""
|
||||
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 = []
|
||||
num_pairs = frames.shape[0] - 1
|
||||
pairs_since_clear = 0
|
||||
@@ -290,6 +291,18 @@ class BIMVFIInterpolate:
|
||||
num_passes = {2: 1, 4: 2, 8: 3}[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")
|
||||
|
||||
if all_on_gpu:
|
||||
@@ -314,6 +327,9 @@ class BIMVFIInterpolate:
|
||||
if end == total_input:
|
||||
break
|
||||
|
||||
if len(chunks) > 1:
|
||||
logger.info(f"BIM-VFI: processing in {len(chunks)} chunk(s)")
|
||||
|
||||
# Calculate total progress steps across all chunks
|
||||
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
||||
pbar = ProgressBar(total_steps)
|
||||
@@ -353,6 +369,7 @@ class BIMVFIInterpolate:
|
||||
|
||||
# Convert back to ComfyUI [B, H, W, C], on CPU
|
||||
result = result.cpu().permute(0, 2, 3, 1)
|
||||
logger.info(f"BIM-VFI: done, {result.shape[0]} output frames")
|
||||
return (result, oversampled)
|
||||
|
||||
|
||||
@@ -401,6 +418,7 @@ class BIMVFISegmentInterpolate(BIMVFIInterpolate):
|
||||
return (images[:1], model)
|
||||
|
||||
segment_images = images[start:end]
|
||||
logger.info(f"BIM-VFI segment {segment_index}: input frames [{start}:{end}] of {total_input}")
|
||||
|
||||
if use_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:
|
||||
return (images[:1], model)
|
||||
|
||||
logger.info(f"BIM-VFI segment {segment_index}: target fps output j=[{j_start}..{j_end}]")
|
||||
|
||||
if num_passes == 0:
|
||||
# Downsampling — select from segment input directly
|
||||
oversampled_fps = source_fps * mult
|
||||
@@ -750,6 +770,7 @@ class EMAVFIInterpolate:
|
||||
clear_cache_after_n_frames, pbar, step_ref):
|
||||
"""Run all interpolation passes on a chunk of frames."""
|
||||
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 = []
|
||||
num_pairs = frames.shape[0] - 1
|
||||
pairs_since_clear = 0
|
||||
@@ -820,6 +841,18 @@ class EMAVFIInterpolate:
|
||||
num_passes = {2: 1, 4: 2, 8: 3}[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")
|
||||
|
||||
if all_on_gpu:
|
||||
@@ -844,6 +877,9 @@ class EMAVFIInterpolate:
|
||||
if end == total_input:
|
||||
break
|
||||
|
||||
if len(chunks) > 1:
|
||||
logger.info(f"EMA-VFI: processing in {len(chunks)} chunk(s)")
|
||||
|
||||
# Calculate total progress steps across all chunks
|
||||
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
||||
pbar = ProgressBar(total_steps)
|
||||
@@ -883,6 +919,7 @@ class EMAVFIInterpolate:
|
||||
|
||||
# Convert back to ComfyUI [B, H, W, C], on CPU
|
||||
result = result.cpu().permute(0, 2, 3, 1)
|
||||
logger.info(f"EMA-VFI: done, {result.shape[0]} output frames")
|
||||
return (result, oversampled)
|
||||
|
||||
|
||||
@@ -930,6 +967,7 @@ class EMAVFISegmentInterpolate(EMAVFIInterpolate):
|
||||
return (images[:1], model)
|
||||
|
||||
segment_images = images[start:end]
|
||||
logger.info(f"EMA-VFI segment {segment_index}: input frames [{start}:{end}] of {total_input}")
|
||||
|
||||
if use_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:
|
||||
return (images[:1], model)
|
||||
|
||||
logger.info(f"EMA-VFI segment {segment_index}: target fps output j=[{j_start}..{j_end}]")
|
||||
|
||||
if num_passes == 0:
|
||||
oversampled_fps = source_fps * mult
|
||||
all_seg = segment_images.permute(0, 3, 1, 2)
|
||||
@@ -1144,6 +1184,7 @@ class SGMVFIInterpolate:
|
||||
clear_cache_after_n_frames, pbar, step_ref):
|
||||
"""Run all interpolation passes on a chunk of frames."""
|
||||
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 = []
|
||||
num_pairs = frames.shape[0] - 1
|
||||
pairs_since_clear = 0
|
||||
@@ -1214,6 +1255,18 @@ class SGMVFIInterpolate:
|
||||
num_passes = {2: 1, 4: 2, 8: 3}[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")
|
||||
|
||||
if all_on_gpu:
|
||||
@@ -1238,6 +1291,9 @@ class SGMVFIInterpolate:
|
||||
if end == total_input:
|
||||
break
|
||||
|
||||
if len(chunks) > 1:
|
||||
logger.info(f"SGM-VFI: processing in {len(chunks)} chunk(s)")
|
||||
|
||||
# Calculate total progress steps across all chunks
|
||||
total_steps = sum(self._count_steps(ce - cs, num_passes) for cs, ce in chunks)
|
||||
pbar = ProgressBar(total_steps)
|
||||
@@ -1277,6 +1333,7 @@ class SGMVFIInterpolate:
|
||||
|
||||
# Convert back to ComfyUI [B, H, W, C], on CPU
|
||||
result = result.cpu().permute(0, 2, 3, 1)
|
||||
logger.info(f"SGM-VFI: done, {result.shape[0]} output frames")
|
||||
return (result, oversampled)
|
||||
|
||||
|
||||
@@ -1324,6 +1381,7 @@ class SGMVFISegmentInterpolate(SGMVFIInterpolate):
|
||||
return (images[:1], model)
|
||||
|
||||
segment_images = images[start:end]
|
||||
logger.info(f"SGM-VFI segment {segment_index}: input frames [{start}:{end}] of {total_input}")
|
||||
|
||||
if use_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:
|
||||
return (images[:1], model)
|
||||
|
||||
logger.info(f"SGM-VFI segment {segment_index}: target fps output j=[{j_start}..{j_end}]")
|
||||
|
||||
if num_passes == 0:
|
||||
oversampled_fps = source_fps * mult
|
||||
all_seg = segment_images.permute(0, 3, 1, 2)
|
||||
@@ -1555,6 +1615,7 @@ class GIMMVFIInterpolate:
|
||||
clear_cache_after_n_frames, pbar, step_ref):
|
||||
"""Single-pass interpolation using GIMM-VFI's arbitrary timestep capability."""
|
||||
num_intermediates = multiplier - 1
|
||||
logger.info(f"GIMM-VFI: single-pass {multiplier}x, {frames.shape[0]} input frames, {num_intermediates} intermediates/pair")
|
||||
new_frames = []
|
||||
num_pairs = frames.shape[0] - 1
|
||||
pairs_since_clear = 0
|
||||
@@ -1599,6 +1660,7 @@ class GIMMVFIInterpolate:
|
||||
clear_cache_after_n_frames, pbar, step_ref):
|
||||
"""Recursive 2x interpolation (standard approach, same as other models)."""
|
||||
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 = []
|
||||
num_pairs = frames.shape[0] - 1
|
||||
pairs_since_clear = 0
|
||||
@@ -1671,6 +1733,18 @@ class GIMMVFIInterpolate:
|
||||
else:
|
||||
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")
|
||||
|
||||
if not single_pass or use_target_fps:
|
||||
@@ -1701,6 +1775,9 @@ class GIMMVFIInterpolate:
|
||||
if end == total_input:
|
||||
break
|
||||
|
||||
if len(chunks) > 1:
|
||||
logger.info(f"GIMM-VFI: processing in {len(chunks)} chunk(s)")
|
||||
|
||||
# Calculate total progress steps across all chunks
|
||||
if single_pass:
|
||||
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
|
||||
result = result.cpu().permute(0, 2, 3, 1)
|
||||
logger.info(f"GIMM-VFI: done, {result.shape[0]} output frames")
|
||||
return (result, oversampled)
|
||||
|
||||
|
||||
@@ -1797,6 +1875,7 @@ class GIMMVFISegmentInterpolate(GIMMVFIInterpolate):
|
||||
return (images[:1], model)
|
||||
|
||||
segment_images = images[start:end]
|
||||
logger.info(f"GIMM-VFI segment {segment_index}: input frames [{start}:{end}] of {total_input}")
|
||||
|
||||
if use_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:
|
||||
return (images[:1], model)
|
||||
|
||||
logger.info(f"GIMM-VFI segment {segment_index}: target fps output j=[{j_start}..{j_end}]")
|
||||
|
||||
if num_passes == 0:
|
||||
oversampled_fps = source_fps * mult
|
||||
all_seg = segment_images.permute(0, 3, 1, 2)
|
||||
|
||||
Reference in New Issue
Block a user