import gradio as gr import torch from modules import scripts, sd_models from modules.infotext_utils import PasteField from modules.shared import opts from modules.ui_common import create_refresh_button from modules.ui_components import InputAccordion class ScriptRefiner(scripts.ScriptBuiltinUI): section = "accordions" create_group = False ckpts = [] def title(self): return "Refiner" def show(self, is_img2img): return scripts.AlwaysVisible if opts.show_refiner else None @classmethod def refresh_checkpoints(cls): from modules_forge.main_entry import refresh_models ckpt_list, _ = refresh_models() cls.ckpts = ["None"] + ckpt_list def ui(self, is_img2img): self.refresh_checkpoints() with InputAccordion(False, label="Refiner", elem_id=self.elem_id("enable")) as enable_refiner: with gr.Row(): refiner_checkpoint = gr.Dropdown(value="None", label="Checkpoint", info="(use model of same architecture and quantization)", elem_id=self.elem_id("checkpoint"), choices=self.ckpts) create_refresh_button(refiner_checkpoint, self.refresh_checkpoints, lambda: {"choices": self.ckpts}, self.elem_id("checkpoint_refresh")) refiner_switch_at = gr.Slider( value=0.875, label="Switch at", minimum=0.0, maximum=1.0, step=0.025, elem_id=self.elem_id("switch_at"), **({"info": "(in steps)", "tooltip": "based on percentage of steps"} if opts.refiner_use_steps else {"info": "(in sigmas)", "tooltip": "Wan 2.2 T2V: 0.875 ; Wan 2.2 I2V: 0.9"}), ) def lookup_checkpoint(title): info = sd_models.get_closet_checkpoint_match(title) return None if info is None else info.short_title self.infotext_fields = [ PasteField(enable_refiner, lambda d: "Refiner" in d), PasteField(refiner_checkpoint, lambda d: lookup_checkpoint(d.get("Refiner")), api="refiner_checkpoint"), PasteField(refiner_switch_at, "Refiner switch at", api="refiner_switch_at"), ] return enable_refiner, refiner_checkpoint, refiner_switch_at def setup(self, p, enable_refiner, refiner_checkpoint, refiner_switch_at): # the actual implementation is in sd_samplers_common.py apply_refiner() if not enable_refiner or refiner_checkpoint in (None, "", "None"): p.refiner_checkpoint = None p.refiner_switch_at = None else: p.refiner_checkpoint = refiner_checkpoint p.refiner_switch_at = refiner_switch_at @torch.inference_mode() def postprocess(self, *args, **kwargs): from modules import sd_samplers_common, shared if sd_samplers_common.ORIGINAL_CHECKPOINT is None: return sd_model = shared.sd_model import huggingface_guess from backend.loader import preprocess_state_dict from backend.state_dict import load_state_dict, try_filter_state_dict from backend.utils import load_torch_file from modules_forge.main_entry import logger model = sd_model.forge_objects.unet.model.diffusion_model sd = load_torch_file(sd_samplers_common.ORIGINAL_CHECKPOINT) sd = preprocess_state_dict(sd) guess = huggingface_guess.guess(sd) sd = try_filter_state_dict(sd, guess.unet_key_prefix) logger.info("Restoring state_dict...") load_state_dict(model, sd) if sd_samplers_common.ORIGINAL_CHECKPOINT.lower().endswith(".gguf"): from backend.memory_management import bake_gguf_model sd_model.forge_objects.unet.model.gguf_baked = False sd_model.forge_objects.unet.model = bake_gguf_model(sd_model.forge_objects.unet.model) sd_samplers_common.ORIGINAL_CHECKPOINT = None