fix(video): count minimax steps as transformer evaluations

MiniMaxH3Scheduler counts the terminal sigma in num_inference_steps, so
Steps N ran N-1 evaluations while every other model runs N. The shim
hands the scheduler p.steps + 1, the slider starts at 1, and the PDD
pin records the evaluation count while passing the scheduler its grid
argument. Metadata written before this change counted grid points.
This commit is contained in:
CalamitousFelicitousness
2026-09-16 00:47:46 +01:00
parent 29fe895c0b
commit 726907dd5b
6 changed files with 12 additions and 10 deletions
+4 -4
View File
@@ -285,7 +285,7 @@ def reconcile(pipe, loaded, components):
def pin(p, model):
"""Hold a generation on the distilled step count and shipped schedule while heads are installed; returns the pinned step count or None."""
"""Hold a generation on the distilled evaluation count and shipped schedule while heads are installed; returns the scheduler step argument or None."""
state = getattr(model, 'sdnext_pdd', None)
if state is None:
return None
@@ -297,13 +297,13 @@ def pin(p, model):
scheduler.set_shift(scheduler.config['shift'])
shifts[name] = scheduler.config['shift']
requested = p.steps
p.steps = state.steps
p.steps = state.heads.nfe # what the user-facing step count means: transformer evaluations
if getattr(p, 'task_args', None) is not None:
p.task_args['num_inference_steps'] = state.steps
p.task_args['num_inference_steps'] = state.steps # the scheduler argument that yields that many grid intervals
if getattr(model, 'num_timesteps', None) is not None:
model.num_timesteps = state.heads.nfe # the progress total counts transformer evaluations
extra = getattr(p, 'extra_generation_params', None)
if extra is not None:
extra.update({state.spec.shift_keys[name]: shift for name, shift in shifts.items() if name in state.spec.shift_keys})
log.info(f'Network: type=PDD name="{state.name}" steps={state.steps} requested={requested} nfe={state.heads.nfe} shift={shifts}')
log.info(f'Network: type=PDD name="{state.name}" steps={state.heads.nfe} requested={requested} grid_steps={state.steps} shift={shifts}')
return state.steps
+1 -1
View File
@@ -26,7 +26,7 @@ def create_ui(prompt, _negative, styles, overrides, script_inputs, mp4_fps, mp4_
width, height = ui_sections.create_resolution_inputs('minimax', default_width=1024, default_height=576, step=32)
btn_detect_image_size = ToolButton(value=ui_symbols.detect, elem_id="minimax_resize_detect_size")
with gr.Row():
steps = gr.Slider(minimum=2, maximum=100, step=1, label="MiniMax steps", elem_id='minimax_steps', value=30)
steps = gr.Slider(minimum=1, maximum=100, step=1, label="MiniMax steps", elem_id='minimax_steps', value=30)
frames = gr.Slider(label='MiniMax frames', minimum=22, maximum=362, step=17, value=124, elem_id='minimax_frames')
with gr.Row():
video_shift = gr.Slider(minimum=0.5, maximum=20.0, step=0.1, value=12.0, label="MiniMax video shift", elem_id='minimax_video_shift')
+3 -3
View File
@@ -29,9 +29,9 @@ def apply_overrides(p, pipe, still: bool = False, audio: bool = True, preview: b
log.debug(f'Pipeline: cls={pipe.__class__.__name__} frames requested={getattr(p, "frames", None)} aligned={frames}')
p.frames = frames
p.task_args['num_frames'] = frames
p.steps = max(2, p.steps)
p.task_args['num_inference_steps'] = p.steps
pipe.num_timesteps = p.steps - 1 # sigma grid includes the terminal point; feeds the progress total
p.steps = max(1, p.steps) # transformer evaluations, as on every other model
p.task_args['num_inference_steps'] = p.steps + 1 # the scheduler counts the terminal sigma as a grid point
pipe.num_timesteps = p.steps # feeds the progress total
if p.sampler_name not in ('None', 'Default'):
log.warning(f'Pipeline: cls={pipe.__class__.__name__} sampler={p.sampler_name} unsupported: using model default')
p.sampler_name = 'Default' # the model default is the bespoke scheduler pair, which discrete samplers must not replace