From cb7bc0facaf53276a2f6137b5b6ce7d6482fea37 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Mon, 14 Sep 2026 11:34:34 +0200 Subject: [PATCH] fix grid with lora, add dlss framgen logging, add 8bit minimax variants Signed-off-by: Vladimir Mandic --- CHANGELOG.md | 2 +- data/reference-quantized.json | 34 ++++++++++++++++++++++++++++++++++ modules/image/grid.py | 4 ++-- modules/lora/lora_load.py | 2 ++ modules/sd_hijack_modular.py | 4 ++++ scripts/dlss/framegen.py | 7 +++++-- scripts/dlss_ext.py | 16 +++++++++------- scripts/xyz_grid.py | 1 + scripts/xyz_grid_on.py | 1 + 9 files changed, 59 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9256755a1..0c0bca81e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ Plus inevitable bug-fixes... with support for text-to-image, vq-conditioned text-to-image and image-editing workflows *note* model is extremely quantization sensitive so minimum allowed quant type is `uint8` - [MiniMax-H3](https://huggingface.co/MiniMaxAI/MiniMax-H3) updates - new [SDNQ-uint8](https://huggingface.co/OzzyGT/MiniMax_H3_sdnq_8bit_pruned) pre-quantized *pruned* variants + new [SDNQ-uint8](https://huggingface.co/OzzyGT/MiniMax_H3_sdnq_8bit_pruned) pre-quantized *base* and *pruned* variants new [Nunchaku-Lite](https://huggingface.co/rootonchair/MiniMax-H3-nunchaku-lite-int4) variant new [VDN](https://huggingface.co/OpenVDN/vdn-minimax-h3) *video-delta-net* variant - **LoRA** diff --git a/data/reference-quantized.json b/data/reference-quantized.json index ee0cbbd09..310a6c0af 100644 --- a/data/reference-quantized.json +++ b/data/reference-quantized.json @@ -275,5 +275,39 @@ "extras": "sampler: Default", "size": 23.70, "date": "2026 August" + }, + "MiniMaxAI MiniMax-H3 sdnq-uint8": { + "path": "OzzyGT/MiniMax_H3_sdnq_dynamic_8bit", + "preview": "MiniMaxAI--MiniMax-H3.jpg", + "desc": "Quantization of MiniMaxAI/MiniMax-H3 using SDNQ: dynamic 8-bit uint. Video with synchronized audio; in image tabs the model runs in experimental still mode.", + "extras": "sampler: Default", + "size": 32.29, + "date": "2026 August" + }, + "MiniMaxAI MiniMax-H3 sdnq-uint8 Ref2VA": { + "path": "OzzyGT/MiniMax_H3_sdnq_dynamic_8bit", + "preview": "MiniMaxAI--MiniMax-H3.jpg", + "subfolder": "ref2va", + "desc": "Quantization of MiniMaxAI/MiniMax-H3 using SDNQ: dynamic 8-bit uint. Video with synchronized audio; in image tabs the model runs in experimental still mode.", + "extras": "sampler: Default", + "size": 32.29, + "date": "2026 August" + }, + "MiniMaxAI MiniMax-H3 Pruned sdnq-uint8": { + "path": "OzzyGT/MiniMax_H3_sdnq_8bit_pruned", + "preview": "MiniMaxAI--MiniMax-H3.jpg", + "desc": "Quantization of MiniMaxAI/MiniMax-H3 using SDNQ: dynamic 8-bit uint. Video with synchronized audio; in image tabs the model runs in experimental still mode.", + "extras": "sampler: Default", + "size": 32.29, + "date": "2026 August" + }, + "MiniMaxAI MiniMax-H3 Pruned sdnq-uint8 Ref2VA": { + "path": "OzzyGT/MiniMax_H3_sdnq_8bit_pruned", + "preview": "MiniMaxAI--MiniMax-H3.jpg", + "subfolder": "ref2va", + "desc": "Quantization of MiniMaxAI/MiniMax-H3 using SDNQ: dynamic 8-bit uint. Video with synchronized audio; in image tabs the model runs in experimental still mode.", + "extras": "sampler: Default", + "size": 32.29, + "date": "2026 August" } } diff --git a/modules/image/grid.py b/modules/image/grid.py index e387270a0..dbd4bbda6 100644 --- a/modules/image/grid.py +++ b/modules/image/grid.py @@ -154,7 +154,7 @@ def get_font(fontsize: float): def draw_grid_annotations(im: Image.Image, width: int, height: int, x_texts: list[list[GridAnnotation]], y_texts: list[list[GridAnnotation]], margin=0, title: list[GridAnnotation] | None = None): def wrap(drawing: ImageDraw.ImageDraw, text, font, line_length): lines = [''] - for word in text.split(): + for word in text.split('/\\'): line = f'{lines[-1]} {word}'.strip() if drawing.textlength(line, font=font) <= line_length: lines[-1] = line @@ -162,7 +162,7 @@ def draw_grid_annotations(im: Image.Image, width: int, height: int, x_texts: lis lines.append(word) return lines - def draw_texts(drawing: ImageDraw.ImageDraw, draw_x: float, draw_y: float, lines, initial_fnt: ImageFont.FreeTypeFont, initial_fontsize: int): + def draw_texts(drawing: ImageDraw.ImageDraw, draw_x: float, draw_y: float, lines: list[GridAnnotation], initial_fnt: ImageFont.FreeTypeFont, initial_fontsize: int): for line in lines: font = initial_fnt fontsize = initial_fontsize diff --git a/modules/lora/lora_load.py b/modules/lora/lora_load.py index ffcf053a1..0fcc2dc34 100644 --- a/modules/lora/lora_load.py +++ b/modules/lora/lora_load.py @@ -322,6 +322,8 @@ def network_load(names, te_multipliers=None, unet_multipliers=None, dyn_dims=Non if net is None: failed_to_load_networks.append(name) lora_ver = network_on_disk.sd_version if network_on_disk is not None else None + if lora_ver is None or len(lora_ver) == 0: + lora_ver = "unknown" log.error(f'Network load: type=LoRA name="{name}" detected={lora_ver} not loaded') continue if hasattr(sd_model, 'embedding_db'): diff --git a/modules/sd_hijack_modular.py b/modules/sd_hijack_modular.py index 50f3965de..59651deab 100644 --- a/modules/sd_hijack_modular.py +++ b/modules/sd_hijack_modular.py @@ -39,6 +39,8 @@ def modular_step(components: diffusers.modular_pipelines.ModularPipeline, state: def modular_intercept(self, components, state: diffusers.modular_pipelines.modular_pipeline.BlockState, *args, **kwargs): + if shared.state.interrupted or shared.state.skipped: + raise AssertionError('Interrupted...') t0 = time.time() block = type(self).__name__ # run code before block call @@ -117,6 +119,8 @@ def install_state_hook(pipe): def set_phase(phase: str, module: torch.nn.Module | None = None): # every stage runs inside one pipeline call, so the forward hooks are the only place the current stage is visible + if shared.state.interrupted or shared.state.skipped: + raise AssertionError('Interrupted...') if getattr(pipe, 'sdnext_phase', None) != phase: pipe.sdnext_phase = phase jobid = getattr(pipe, 'sdnext_phaseid', None) # previous jobid if any diff --git a/scripts/dlss/framegen.py b/scripts/dlss/framegen.py index dfb07ac4d..4df99f04c 100644 --- a/scripts/dlss/framegen.py +++ b/scripts/dlss/framegen.py @@ -93,8 +93,7 @@ class DLSSFrameGen: capabilities = probe_frame_interpolation_capabilities(options.ai_gpu_uuid) log.debug(f'DLSSFrameGen: capabilities={capabilities}') if not capabilities.available: - raise StandaloneError("feature_unavailable", "FrameGen: unavailable. " + capabilities.detail, - ) + raise StandaloneError("feature_unavailable", "FrameGen: unavailable. " + capabilities.detail) plan = choose_interpolation_plan( source_rate, target_rate, @@ -102,6 +101,7 @@ class DLSSFrameGen: capabilities.native_multiplier, cfr=True, ) + log.debug(f'DLSSFrameGen: plan={plan}') source_frames = [ _TimedFrame(rgb_to_rgba(nchw_image_to_hwc(frames, index, name="frames")), Fraction(index, 1) / source_rate) for index in range(batch) @@ -146,6 +146,7 @@ class DLSSFrameGen: ideal = Fraction(index, 1) / target_rate selected = min(frames, key=lambda frame, target=ideal: abs(frame.timestamp - target)) result.append(_TimedFrame(selected.rgba.copy(), ideal)) + log.debug(f'DLSSFrameGen: input={len(frames)} resampled={len(result)}') return result @staticmethod @@ -155,6 +156,7 @@ class DLSSFrameGen: try: stage_count = plan.cascade_stages or 1 for stage_index in range(stage_count): + log.debug(f'DirectDLSSGSession: index={stage_index + 1} count={stage_count} stage create') generated_count = ( plan.generated_per_interval if plan.path == "Native DLSSG" @@ -195,6 +197,7 @@ class DLSSFrameGen: return result finally: for session in reversed(sessions): + log.debug(f'DirectDLSSGSession: session={session} close') try: session.close() except (OSError, RuntimeError, ValueError): diff --git a/scripts/dlss_ext.py b/scripts/dlss_ext.py index 00a42670b..bc042d6b1 100644 --- a/scripts/dlss_ext.py +++ b/scripts/dlss_ext.py @@ -62,10 +62,10 @@ def create_ui(parent): with gr.Row(): fg_enabled = gr.Checkbox(label='FG enable', value=False, elem_id='dlss_fg_enabled') with gr.Row(): - fg_source_fps = gr.Dropdown(label='Source FPS', choices=FPS_CHOICES, value='23.976', elem_id='dlss_fg_source_fps') - fg_target_fps = gr.Dropdown(label='Target FPS', choices=FPS_CHOICES, value='60', elem_id='dlss_fg_target_fps') + fg_source_fps = gr.Dropdown(label='FG source FPS', choices=FPS_CHOICES, value='23.976', elem_id='dlss_fg_source_fps') + fg_target_fps = gr.Dropdown(label='FG target FPS', choices=FPS_CHOICES, value='60', elem_id='dlss_fg_target_fps') with gr.Row(): - fg_engine = gr.Dropdown(label='Engine', choices=['Auto', 'Native DLSSG', 'Cascade'], value='Auto', elem_id='dlss_fg_engine') + fg_engine = gr.Dropdown(label='FG engine', choices=['Auto', 'Native DLSSG', 'Cascade'], value='Auto', elem_id='dlss_fg_engine') with gr.Accordion('DLSS Status', open=True, elem_id='dlss_status'): ss_status = gr.JSON({ 'Status': 'unknown' if len(shared.opts.dlss_pkg_path) < 4 else 'stored'}) @@ -231,9 +231,10 @@ def framegen(pkg_path, images, fg_source_fps, fg_target_fps, fg_engine): if debug: log.trace(f'DLSS: method=FrameGen input={frames.shape} options={options}') response = c.controller.call( - pkg_path, 'framegen', + pkg_path, + 'framegen', { 'frames': frames, 'source_fps': fg_source_fps, 'target_fps': fg_target_fps, 'options': options }, - timeout=300.0, + timeout=600.0, ) if response.get('status') != 'ok': error = response.get('error') or {} @@ -333,10 +334,11 @@ def dlss(p: processing.StableDiffusionProcessing | None, pp: processing.Processe t0 = time.time() if p: p.extra_generation_params["DLSSFrameGen"] = True - log.info(f'DLSS: method=FrameGen source={fg_source_fps} target={fg_target_fps} engine={fg_engine}') + log.info(f'DLSS: method=FrameGen source={fg_source_fps} target={fg_target_fps} engine="{fg_engine}"') output = framegen(pkg_path, current_images, fg_source_fps, fg_target_fps, fg_engine) if debug: - log.trace(f'DLSS: method=FrameGen images={len(output) if output else 0} time={time.time() - t0:.3f}') + t1 = time.time() + log.trace(f'DLSS: method=FrameGen frames={len(output) if output else 0} time={t1 - t0:.3f}') if output: images = output current_images = output diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py index 66d697f5d..1a79b5ec8 100644 --- a/scripts/xyz_grid.py +++ b/scripts/xyz_grid.py @@ -330,6 +330,7 @@ class XYZGridScript(scripts_manager.Script): return processing.Processed(p, [], p.seed, ""), 0 p.xyz = True pc = copy(p) + pc.network_data = None pc.override_settings_restore_afterwards = False pc.styles = pc.styles[:] x_opt.apply(pc, x, xs) diff --git a/scripts/xyz_grid_on.py b/scripts/xyz_grid_on.py index b6e09ff30..c45271e23 100644 --- a/scripts/xyz_grid_on.py +++ b/scripts/xyz_grid_on.py @@ -352,6 +352,7 @@ class XYZGridScript(scripts_manager.Script): return processing.Processed(p, [], p.seed, ""), 0 p.xyz = True pc = copy(p) + pc.network_data = None pc.override_settings_restore_afterwards = False pc.styles = pc.styles[:] if no_fixed_seeds: