diff --git a/extensions-builtin/sdnext-modernui b/extensions-builtin/sdnext-modernui index bd51e6348..53cd97305 160000 --- a/extensions-builtin/sdnext-modernui +++ b/extensions-builtin/sdnext-modernui @@ -1 +1 @@ -Subproject commit bd51e63483b34841885f67103d8390d4c94aa3c2 +Subproject commit 53cd97305dc12b20571e26fbb046043e88137763 diff --git a/modules/minimax/minimax_ui.py b/modules/minimax/minimax_ui.py index bee0a638a..455901c5b 100644 --- a/modules/minimax/minimax_ui.py +++ b/modules/minimax/minimax_ui.py @@ -27,11 +27,14 @@ def create_ui(prompt, _negative, styles, overrides, script_inputs, mp4_fps, mp4_ with gr.Row(): steps = gr.Slider(minimum=2, maximum=100, step=1, label="MiniMax Steps", elem_id='minimax_steps', value=30) frames = gr.Slider(label='MiniMax Frames', minimum=22, maximum=345, step=17, value=107, elem_id='minimax_frames') + with gr.Row(): + video_shift = gr.Slider(minimum=8.0, maximum=16.0, step=0.1, label="MiniMax Video Shift", elem_id='minimax_video_shift', value=12) + audio_shift = gr.Slider(minimum=1.5, maximum=6.0, step=0.1, label="MiniMax Audio Shift", elem_id='minimax_audio_shift', value=3) with gr.Row(): seed = gr.Number(label='Seed', value=-1, elem_id='minimax_seed', container=True) random_seed = ToolButton(ui_symbols.random, elem_id='minimax_seed_random') random_seed.click(fn=lambda: -1, show_progress='hidden', inputs=[], outputs=[seed]) - audio_enable = gr.Checkbox(label='Save audio', value=True, elem_id="minimax_audio_enable") + audio_enable = gr.Checkbox(label='Audio Enabled', value=True, elem_id="minimax_audio_enable") with gr.Accordion(open=False, label="Input media", elem_id='minimax_input_media_accordion', visible=True) as input_accordion: with gr.Row(): init_image = gr.Image(label='Image', elem_id='minimax_init_image', type='pil', image_mode='RGB', width=256, height=256) @@ -77,6 +80,7 @@ def create_ui(prompt, _negative, styles, overrides, script_inputs, mp4_fps, mp4_ width, height, frames, steps, seed, init_image, last_image, reference_media, + video_shift, audio_shift, mp4_fps, mp4_interpolate, mp4_codec, mp4_ext, mp4_opt, mp4_video, mp4_frames, mp4_sf, mp4_thumb, audio_enable, overrides, diff --git a/modules/minimax/minimax_video.py b/modules/minimax/minimax_video.py index 711b5b369..4c6482fbb 100644 --- a/modules/minimax/minimax_video.py +++ b/modules/minimax/minimax_video.py @@ -82,6 +82,7 @@ def generate(task_id, _ui_state, steps, seed, init_image, last_image, reference_media, + video_shift, audio_shift, mp4_fps, mp4_interpolate, mp4_codec, mp4_ext, mp4_opt, mp4_video, mp4_frames, mp4_sf, mp4_thumb, audio_enable, _overrides, @@ -119,7 +120,8 @@ def generate(task_id, _ui_state, ops=['video'], ) video_minimax.apply_overrides(p, shared.sd_model, still=False, audio=audio_enable) - log.debug(f'Video: engine="{engine}" model="{model}" workflow={workflow} cls={shared.sd_model.__class__.__name__} kwargs={p.task_args}') + video_minimax.set_sampler_shift(shared.sd_model, video_shift=video_shift, audio_shift=audio_shift) + log.debug(f'Video: engine="{engine}" model="{model}" workflow={workflow} cls={shared.sd_model.__class__.__name__} shift={video_shift}:{audio_shift} kwargs={p.task_args}') processing.fix_seed(p) p.ops.append('video') p.scripts = scripts_manager.scripts_video @@ -158,14 +160,12 @@ def generate(task_id, _ui_state, if mp4_interpolate > 0: p.video_interpolate = mp4_interpolate from modules.processing_video import apply_video_interpolation - print('HERE1', pixels.shape, pixels.min(), pixels.max()) # pixels is 5-D (N,C,T,H,W) in [-1,1]; RIFE needs 4-D (T,C,H,W) in [0,1] x = pixels.squeeze(0).permute(1, 0, 2, 3) x = (x.clamp(-1., 1.) + 1.0) * 0.5 x = apply_video_interpolation(p, x, count=mp4_interpolate) # sets p.video_interpolated otherwise main save_video would do it also x = x * 2.0 - 1.0 pixels = x.permute(1, 0, 2, 3).unsqueeze(0) - print('HERE2', pixels.shape, pixels.min(), pixels.max()) save_fps = mp4_fps * processing_video.interpolation_factor(p) num_frames, video_file, _thumb = video_save.save_video( diff --git a/modules/video_models/video_minimax.py b/modules/video_models/video_minimax.py index 17c7b4542..0f69af878 100644 --- a/modules/video_models/video_minimax.py +++ b/modules/video_models/video_minimax.py @@ -82,3 +82,10 @@ def set_audio(pipe, enabled: bool): elif not enabled and 'audio' in sub: pipe.sdnext_audio_decode_block = sub.pop('audio') log.debug(f'Pipeline: cls={pipe.__class__.__name__} audio=disabled') + + +def set_sampler_shift(pipe, video_shift: float = 12.0, audio_shift: float = 3.0): + if getattr(pipe, 'scheduler', None) is not None and getattr(pipe.scheduler, 'config', None) is not None: + pipe.scheduler.config.shift = video_shift + if getattr(pipe, 'audio_scheduler', None) is not None and getattr(pipe.audio_scheduler, 'config', None) is not None: + pipe.audio_scheduler.config.shift = audio_shift diff --git a/ui/locale/locale_en.json b/ui/locale/locale_en.json index b216e8c41..2ab88e37c 100644 --- a/ui/locale/locale_en.json +++ b/ui/locale/locale_en.json @@ -937,7 +937,10 @@ {"id":"","label":"Max tags","localized":"","hint":"Maximum number of tags to include in the output.
Limits the result length when an image has many detected features.
Tags are sorted by confidence, so the most relevant ones are kept.","ui":"caption"}, {"id":"","label":"Memory","localized":"","hint":"","ui":"component-8779"}, {"id":"","label":"Memory optimization","localized":"","hint":"","ui":"component-8779"}, - {"id":"","label":"Model Info","localized":"","hint":"","ui":"component-8779"}, + {"id":"","label":"MiniMax Video Shift","localized":"","hint":"Controls how inference steps are distributed along the flow-matching curve, where higher values prioritize large-scale motion dynamics, camera movement, and global scene composition, while lower values focus steps on refining fine spatial textures and sharp visual details.","ui":"video"}, + {"id":"","label":"MiniMax Audio Shift","localized":"","hint":"Governs the step distribution for latent sound generation, where higher values enforce strong temporal alignment with visual action and macro rhythm, while lower values allocate sampling depth toward high-frequency acoustic fidelity, speech clarity, and crisp sound effects.","ui":"video"}, + {"id":"","label":"MiniMax Frames","localized":"","hint":"MiniMax is optimized to generate 5-15sec videos at 24 FPS","ui":"video"}, + {"id":"","label":"Model Info","localized":"","hint":"","ui":"component-8779"}, {"id":"","label":"Model pipeline","localized":"","hint":"If autodetect does not detect model automatically, select model type before loading a model","ui":"settings_sd"}, {"id":"","label":"Model auto-load on start","localized":"","hint":"","ui":"settings_sd"}, {"id":"","label":"Model load using multiple threads","localized":"","hint":"","ui":"settings_sd"},