replace script with AlwaysVisible to allow combining with scripts

pull/9/head
Alex "mcmonkey" Goodwin 2023-01-27 00:31:35 -08:00
parent 1cb63313cd
commit 2d3e5da9d4
2 changed files with 40 additions and 34 deletions

View File

@ -42,7 +42,7 @@ The core functionality of this PR was mainly developed by [Birch-san](https://gi
- Install the extension and restart. - Install the extension and restart.
- Go to txt2img or img2img - Go to txt2img or img2img
- Select `Script` at the bottom and select `Dynamic Thresholding (CFG Scale Fix)` - Check the `Enable Dynamic Thresholding (CFG Scale Fix)` box
- Read the info on-page and set the sliders where you want em. - Read the info on-page and set the sliders where you want em.
- Click generate. - Click generate.

View File

@ -26,44 +26,50 @@ class Script(scripts.Script):
return "Dynamic Thresholding (CFG Scale Fix)" return "Dynamic Thresholding (CFG Scale Fix)"
def show(self, is_img2img): def show(self, is_img2img):
return True return scripts.AlwaysVisible
def ui(self, is_img2img): def ui(self, is_img2img):
gr.Markdown("Thresholds high CFG scales to make them work better. \nSet your actual **CFG Scale** to the high value you want above (eg: 20). \nThen set '**Mimic CFG Scale**' below to a (lower) CFG scale to mimic the effects of (eg: 10). Make sure it's not *too* different from your actual scale, it can only compensate so far. \nSet '**Top percentile**' to how much clamping you want. 90% is good is normal, 100% clamps so hard it's like the mimic scale is the real scale. This scales as it approaches 100%, (eg 90% and 95% are much more similar than 98% and 99%). \n... \n") enabled = gr.Checkbox(value=False, label="Enable Dynamic Thresholding (CFG Scale Fix)")
mimic_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='Mimic CFG Scale', value=7.0) # "Dynamic Thresholding (CFG Scale Fix)"
threshold_percentile = gr.Slider(minimum=90.0, value=90.0, maximum=100.0, step=0.05, label='Top percentile of latents to clamp') accordion = gr.Group(visible=False)
with gr.Accordion("Advanced Options", open=False): with accordion:
gr.Markdown("You can configure the **scale scheduler** for either the CFG Scale or the Mimic Scale here. \n'**Constant**' is normal. \nSetting **Mimic** to '**Cosine Down**' seems to produce better results. Needs more testing. \nSetting **CFG** to '**Linear Down**' produces results that are just like the raw high scale CFG but with better quality fine details. \nOther setting combos produce interesting results as well. \n... \n") gr.Markdown("Thresholds high CFG scales to make them work better. \nSet your actual **CFG Scale** to the high value you want above (eg: 20). \nThen set '**Mimic CFG Scale**' below to a (lower) CFG scale to mimic the effects of (eg: 10). Make sure it's not *too* different from your actual scale, it can only compensate so far. \nSet '**Top percentile**' to how much clamping you want. 90% is good is normal, 100% clamps so hard it's like the mimic scale is the real scale. This scales as it approaches 100%, (eg 90% and 95% are much more similar than 98% and 99%). \n... \n")
mimic_mode = gr.Dropdown(["Constant", "Linear Down", "Cosine Down", "Linear Up", "Cosine Up"], value="Constant", label="Mimic Scale Scheduler") mimic_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='Mimic CFG Scale', value=7.0)
cfg_mode = gr.Dropdown(["Constant", "Linear Down", "Cosine Down", "Linear Up", "Cosine Up"], value="Constant", label="CFG Scale Scheduler") threshold_percentile = gr.Slider(minimum=90.0, value=90.0, maximum=100.0, step=0.05, label='Top percentile of latents to clamp')
return [mimic_scale, threshold_percentile, mimic_mode, cfg_mode] with gr.Accordion("Dynamic Thresholding Advanced Options", open=False):
gr.Markdown("You can configure the **scale scheduler** for either the CFG Scale or the Mimic Scale here. \n'**Constant**' is normal. \nSetting **Mimic** to '**Cosine Down**' seems to produce better results. Needs more testing. \nSetting **CFG** to '**Linear Down**' produces results that are just like the raw high scale CFG but with better quality fine details. \nOther setting combos produce interesting results as well. \n... \n")
mimic_mode = gr.Dropdown(["Constant", "Linear Down", "Cosine Down", "Linear Up", "Cosine Up"], value="Constant", label="Mimic Scale Scheduler")
cfg_mode = gr.Dropdown(["Constant", "Linear Down", "Cosine Down", "Linear Up", "Cosine Up"], value="Constant", label="CFG Scale Scheduler")
enabled.change(
fn=lambda x: {"visible": x, "__type__": "update"},
inputs=[enabled],
outputs=[accordion],
show_progress = False)
return [enabled, mimic_scale, threshold_percentile, mimic_mode, cfg_mode]
def run(self, p, mimic_scale, threshold_percentile, mimic_mode, cfg_mode): def process(self, p, enabled, mimic_scale, threshold_percentile, mimic_mode, cfg_mode):
if not enabled:
return
# Note: the random number is to protect the edge case of multiple simultaneous runs with different settings # Note: the random number is to protect the edge case of multiple simultaneous runs with different settings
fixed_sampler_name = f"{p.sampler_name}_dynthres{random.randrange(100)}" fixed_sampler_name = f"{p.sampler_name}_dynthres{random.randrange(100)}"
try: p.fixed_sampler_name = fixed_sampler_name
# Percentage to portion # Percentage to portion
threshold_percentile *= 0.01 threshold_percentile *= 0.01
# Make a placeholder sampler # Make a placeholder sampler
sampler = sd_samplers.all_samplers_map[p.sampler_name] sampler = sd_samplers.all_samplers_map[p.sampler_name]
def newConstructor(model): def newConstructor(model):
result = sampler.constructor(model) result = sampler.constructor(model)
cfg = CustomCFGDenoiser(result.model_wrap_cfg.inner_model, mimic_scale, threshold_percentile, mimic_mode, cfg_mode, p.steps) cfg = CustomCFGDenoiser(result.model_wrap_cfg.inner_model, mimic_scale, threshold_percentile, mimic_mode, cfg_mode, p.steps)
result.model_wrap_cfg = cfg result.model_wrap_cfg = cfg
return result return result
newSampler = sd_samplers.SamplerData(fixed_sampler_name, newConstructor, sampler.aliases, sampler.options) newSampler = sd_samplers.SamplerData(fixed_sampler_name, newConstructor, sampler.aliases, sampler.options)
sd_samplers.all_samplers_map[fixed_sampler_name] = newSampler p.sampler_name = fixed_sampler_name
# Prep data sd_samplers.all_samplers_map[fixed_sampler_name] = newSampler
p = copy(p)
p.sampler_name = fixed_sampler_name def postprocess(self, p, enabled, mimic_scale, threshold_percentile, mimic_mode, cfg_mode):
# Run if not enabled:
proc = process_images(p) return
# Cleanup del sd_samplers.all_samplers_map[p.fixed_sampler_name]
del sd_samplers.all_samplers_map[fixed_sampler_name]
return proc
except Exception as e:
del sd_samplers.all_samplers_map[fixed_sampler_name]
raise e
######################### Implementation logic ######################### ######################### Implementation logic #########################