from modules.sd_samplers_kdiffusion import KDiffusionSampler from modules import shared, scripts, script_callbacks import gradio as gr from scripts.cg_xyz import xyz_support VERSION = "v1.1.0" DYNAMIC_RANGE = [3.25, 2.5, 2.5, 2.5] Default_LUTs = {"C": 0.01, "M": 0.5, "Y": -0.13, "K": 0} def normalize_tensor(x, r): X = x.detach().clone() ratio = r / max(abs(float(X.min())), abs(float(X.max()))) X *= max(ratio, 0.99) return X original_callback = KDiffusionSampler.callback_state def center_callback(self, d): if not self.diffcg_enable or getattr(self.p, "_ad_inner", False): return original_callback(self, d) X = d["denoised"].detach().clone() batchSize = X.size(0) channels = len(self.LUTs) for b in range(batchSize): for c in range(channels): if self.diffcg_recenter_strength > 0.0: d["denoised"][b][c] += ( self.LUTs[c] - X[b][c].mean() ) * self.diffcg_recenter_strength if self.diffcg_normalize and (d["i"] + 1) > self.diffcg_last_step // 2: d["denoised"][b][c] = normalize_tensor(X[b][c], DYNAMIC_RANGE[c]) return original_callback(self, d) KDiffusionSampler.callback_state = center_callback # ["None", "txt2img", "img2img", "Both"] ac = getattr(shared.opts, "always_center", "None") an = getattr(shared.opts, "always_normalize", "None") def_sd = getattr(shared.opts, "default_arch", "1.5") adv_opt = getattr(shared.opts, "show_center_opt", False) c_t2i = ac in ("txt2img", "Both") c_i2i = ac in ("img2img", "Both") n_t2i = an in ("txt2img", "Both") n_i2i = an in ("img2img", "Both") class DiffusionCG(scripts.Script): def __init__(self): self.xyzCache = {} xyz_support(self.xyzCache) def title(self): return "DiffusionCG" def show(self, is_img2img): return scripts.AlwaysVisible def ui(self, is_img2img): with gr.Accordion(f"Diffusion CG {VERSION}", open=False): with gr.Row(): enableG = gr.Checkbox( label="Enable (Global)", value=( ((not is_img2img) and (c_t2i or n_t2i)) or (is_img2img and (c_i2i or n_i2i)) ), ) sd_ver = gr.Radio( ["1.5", "XL"], value=def_sd, label="Stable Diffusion Version" ) with gr.Row(): with gr.Group(): gr.Markdown('

Recenter

') if not is_img2img: v = 1.0 if c_t2i else 0.0 else: v = 1.0 if c_i2i else 0.0 rc_str = gr.Slider( label="Effect Strength", minimum=0.0, maximum=1.0, step=0.2, value=v, ) with gr.Group(): gr.Markdown('

Normalization

') enableN = gr.Checkbox( label="Activate", value=(((not is_img2img) and n_t2i) or (is_img2img and n_i2i)), ) with gr.Accordion("Recenter Settings", visible=adv_opt, open=False): with gr.Group(visible=(def_sd == "1.5")) as setting15: C = gr.Slider( label="C", minimum=-1.00, maximum=1.00, step=0.01, value=Default_LUTs["C"], ) M = gr.Slider( label="M", minimum=-1.00, maximum=1.00, step=0.01, value=Default_LUTs["M"], ) Y = gr.Slider( label="Y", minimum=-1.00, maximum=1.00, step=0.01, value=Default_LUTs["Y"], ) K = gr.Slider( label="K", minimum=-1.00, maximum=1.00, step=0.01, value=Default_LUTs["K"], ) with gr.Group(visible=(def_sd == "XL")) as settingXL: L = gr.Slider( label="L", minimum=-1.00, maximum=1.00, step=0.01, value=0.0 ) a = gr.Slider( label="a", minimum=-1.00, maximum=1.00, step=0.01, value=0.0 ) b = gr.Slider( label="b", minimum=-1.00, maximum=1.00, step=0.01, value=0.0 ) def on_radio_change(choice): if choice == "1.5": return [ gr.Group.update(visible=True), gr.Group.update(visible=False), ] else: return [ gr.Group.update(visible=False), gr.Group.update(visible=True), ] sd_ver.change(on_radio_change, sd_ver, [setting15, settingXL]) self.paste_field_names = [ (rc_str, "ReCenter Str"), (enableN, "Normalization"), (sd_ver, "SD_ver"), ] self.infotext_fields = [ (rc_str, "ReCenter Str"), (enableN, "Normalization"), (sd_ver, "SD_ver"), ] if adv_opt: self.paste_field_names += [ ( C, lambda d: ( float(d["LUTs"].strip("[]").split(",")[0]) if len(d.get("LUTs", "").split(",")) == 4 else gr.update() ), ), ( M, lambda d: ( float(d["LUTs"].strip("[]").split(",")[1]) if len(d.get("LUTs", "").split(",")) == 4 else gr.update() ), ), ( Y, lambda d: ( float(d["LUTs"].strip("[]").split(",")[2]) if len(d.get("LUTs", "").split(",")) == 4 else gr.update() ), ), ( K, lambda d: ( float(d["LUTs"].strip("[]").split(",")[3]) if len(d.get("LUTs", "").split(",")) == 4 else gr.update() ), ), ( L, lambda d: ( float(d["LUTs"].strip("[]").split(",")[0]) if len(d.get("LUTs", "").split(",")) == 3 else gr.update() ), ), ( a, lambda d: ( float(d["LUTs"].strip("[]").split(",")[1]) if len(d.get("LUTs", "").split(",")) == 3 else gr.update() ), ), ( b, lambda d: ( float(d["LUTs"].strip("[]").split(",")[2]) if len(d.get("LUTs", "").split(",")) == 3 else gr.update() ), ), ] self.infotext_fields += [ ( C, lambda d: ( float(d["LUTs"].strip("[]").split(",")[0]) if len(d.get("LUTs", "").split(",")) == 4 else gr.update() ), ), ( M, lambda d: ( float(d["LUTs"].strip("[]").split(",")[1]) if len(d.get("LUTs", "").split(",")) == 4 else gr.update() ), ), ( Y, lambda d: ( float(d["LUTs"].strip("[]").split(",")[2]) if len(d.get("LUTs", "").split(",")) == 4 else gr.update() ), ), ( K, lambda d: ( float(d["LUTs"].strip("[]").split(",")[3]) if len(d.get("LUTs", "").split(",")) == 4 else gr.update() ), ), ( L, lambda d: ( float(d["LUTs"].strip("[]").split(",")[0]) if len(d.get("LUTs", "").split(",")) == 3 else gr.update() ), ), ( a, lambda d: ( float(d["LUTs"].strip("[]").split(",")[1]) if len(d.get("LUTs", "").split(",")) == 3 else gr.update() ), ), ( b, lambda d: ( float(d["LUTs"].strip("[]").split(",")[2]) if len(d.get("LUTs", "").split(",")) == 3 else gr.update() ), ), ] for comp in [enableG, sd_ver, rc_str, enableN, C, M, Y, K, L, a, b]: comp.do_not_save_to_config = True return [enableG, sd_ver, rc_str, enableN, C, M, Y, K, L, a, b] def before_hr(self, p, *args): KDiffusionSampler.diffcg_normalize = False def process( self, p, enableG: bool, sd_ver: str, rc_str: float, enableN: bool, C: float, M: float, Y: float, K: float, L: float, a: float, b: float, ): if "enableG" in self.xyzCache.keys(): enableG = self.xyzCache["enableG"].lower().strip() == "true" del self.xyzCache["enableG"] KDiffusionSampler.diffcg_enable = enableG if not enableG: if len(self.xyzCache.keys()) > 0: print("\n[Diff. CG] X [X/Y/Z Plot] Extension is not Enabled!\n") self.xyzCache.clear() return p if "rc_str" in self.xyzCache.keys(): rc_str = float(self.xyzCache["rc_str"]) if "enableN" in self.xyzCache.keys(): enableN = self.xyzCache["enableN"].lower().strip() == "true" if adv_opt: C = self.xyzCache.get("C", C) M = self.xyzCache.get("M", M) Y = self.xyzCache.get("Y", Y) K = self.xyzCache.get("K", K) L = self.xyzCache.get("L", L) a = self.xyzCache.get("a", a) b = self.xyzCache.get("b", b) if sd_ver == "1.5": KDiffusionSampler.LUTs = [-K, -M, C, Y] else: KDiffusionSampler.LUTs = [L, -a, b] KDiffusionSampler.diffcg_recenter_strength = rc_str KDiffusionSampler.diffcg_normalize = enableN if ( not hasattr(p, "enable_hr") and not shared.opts.img2img_fix_steps and getattr(p, "denoising_strength", 1.0) < 1.0 ): KDiffusionSampler.diffcg_last_step = int(p.steps * p.denoising_strength) + 1 else: KDiffusionSampler.diffcg_last_step = p.steps p.extra_generation_params.update( { "ReCenter Str": rc_str, "Normalization": enableN, "SD_ver": sd_ver, } ) if adv_opt: if def_sd == "1.5": p.extra_generation_params["LUTs"] = f"[{C}, {M}, {Y}, {K}]" else: p.extra_generation_params["LUTs"] = f"[{L}, {a}, {b}]" self.xyzCache.clear() def restore_callback(): KDiffusionSampler.callback_state = original_callback script_callbacks.on_script_unloaded(restore_callback)