diff --git a/.gitignore b/.gitignore index d507e4c31..0d241f33e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,7 @@ __pycache__ .ruff_cache /cache.json -/metadata.json -/config.json -/ui-config.json +/*.json /params.txt /styles.csv /user.css @@ -38,6 +36,7 @@ venv /*.lnk !webui.bat !webui.sh +!package.json # all dynamic stuff /repositories/**/* diff --git a/javascript/style.css b/javascript/style.css index 453572d34..a7e18efba 100644 --- a/javascript/style.css +++ b/javascript/style.css @@ -1,5 +1,6 @@ :root, .dark{ --checkbox-label-gap: 0.25em 0.1em; --section-header-text-size: 12pt; --block-background-fill: transparent;} a { font-weight: bold; cursor: pointer; } +h2 { margin-top: 1em !important; font-size: 1.4em !important; } div.gradio-container{ max-width: unset !important; padding: 8px !important; } div.tabitem { padding: 0 !important; } div.form{ border-width: 0; box-shadow: none; background: transparent; overflow: visible; gap: 0.5em; } diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index bccc7c0fe..a475afab3 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -308,8 +308,8 @@ def parse_generation_parameters(x: str): ('Discard penultimate sigma', 'always_discard_next_to_last_sigma'), ('UniPC variant', 'uni_pc_variant'), ('UniPC skip type', 'uni_pc_skip_type'), - ('UniPC order', 'uni_pc_order'), - ('UniPC lower order final', 'uni_pc_lower_order_final'), + ('UniPC order', 'schedulers_solver_order'), + ('UniPC lower order final', 'schedulers_use_loworder'), ('Token merging ratio', 'token_merging_ratio'), ('Token merging ratio hr', 'token_merging_ratio_hr'), ] diff --git a/modules/models/diffusion/uni_pc/sampler.py b/modules/models/diffusion/uni_pc/sampler.py index 41455c94d..21991d2b9 100644 --- a/modules/models/diffusion/uni_pc/sampler.py +++ b/modules/models/diffusion/uni_pc/sampler.py @@ -30,7 +30,7 @@ def stochastic_encode(self, x0, t, use_original_steps=False, noise=None): # value from the hires steps slider: num_inference_steps = t[0] + 1 num_inference_steps / self.inflated_steps - self.denoise_steps = max(num_inference_steps, shared.opts.uni_pc_order) + self.denoise_steps = max(num_inference_steps, shared.opts.schedulers_solver_order) max(self.inflated_steps - self.denoise_steps, 0) @@ -102,8 +102,8 @@ def decode(self, x_latent, conditioning, t_start, unconditional_guidance_scale=1 steps=self.denoise_steps, skip_type=shared.opts.uni_pc_skip_type, method="multistep", - order=shared.opts.uni_pc_order, - lower_order_final=shared.opts.uni_pc_lower_order_final, + order=shared.opts.schedulers_solver_order, + lower_order_final=shared.opts.schedulers_use_loworder, denoise_to_zero=True, timesteps=self.timesteps, ) @@ -187,6 +187,6 @@ def sample(self, ) uni_pc = UniPC(model_fn, self.noise_schedule, predict_x0=True, thresholding=False, variant=shared.opts.uni_pc_variant, condition=conditioning, unconditional_condition=unconditional_conditioning, before_sample=self.before_sample, after_sample=self.after_sample, after_update=self.after_update) - x = uni_pc.sample(img, steps=S, skip_type=shared.opts.uni_pc_skip_type, method="multistep", order=shared.opts.uni_pc_order, lower_order_final=shared.opts.uni_pc_lower_order_final) + x = uni_pc.sample(img, steps=S, skip_type=shared.opts.uni_pc_skip_type, method="multistep", order=shared.opts.schedulers_solver_order, lower_order_final=shared.opts.schedulers_use_loworder) return x.to(device), None diff --git a/modules/sd_samplers_compvis.py b/modules/sd_samplers_compvis.py index 562705e1c..2f6e81f4c 100644 --- a/modules/sd_samplers_compvis.py +++ b/modules/sd_samplers_compvis.py @@ -149,8 +149,8 @@ def initialize(self, p): keys = [ ('UniPC variant', 'uni_pc_variant'), ('UniPC skip type', 'uni_pc_skip_type'), - ('UniPC order', 'uni_pc_order'), - ('UniPC lower order final', 'uni_pc_lower_order_final'), + ('UniPC order', 'schedulers_solver_order'), + ('UniPC lower order final', 'schedulers_use_loworder'), ] for name, key in keys: @@ -170,8 +170,8 @@ def initialize(self, p): def adjust_steps_if_invalid(self, p, num_steps): if ((self.config.name == 'DDIM') and p.ddim_discretize == 'uniform') or (self.config.name == 'PLMS') or (self.config.name == 'UniPC'): - if self.config.name == 'UniPC' and num_steps < shared.opts.uni_pc_order: - num_steps = shared.opts.uni_pc_order + if self.config.name == 'UniPC' and num_steps < shared.opts.schedulers_solver_order: + num_steps = shared.opts.schedulers_solver_order valid_step = 999 / (1000 // num_steps) if valid_step == math.floor(valid_step): return min(int(valid_step) + 1, num_steps) diff --git a/modules/shared.py b/modules/shared.py index 6e51d6ebb..c392575c4 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -485,55 +485,38 @@ def refresh_themes(): "logmonitor_refresh_period": OptionInfo(5000, "Log view update period, in milliseconds", gr.Slider, {"minimum": 0, "maximum": 30000, "step": 25}), })) - options_templates.update(options_section(('sampler-params', "Sampler Settings"), { "show_samplers": OptionInfo(["Euler a", "UniPC", "DEIS", "DDIM", "DPM 1S", "DPM 2M", "DPM++ 2M SDE", "DPM++ 2M SDE Karras", "DPM2 Karras", "DPM++ 2M Karras"], "Show samplers in user interface", gr.CheckboxGroup, lambda: {"choices": [x.name for x in list_samplers() if x.name != "PLMS"]}), "fallback_sampler": OptionInfo("Euler a", "Secondary sampler", gr.Dropdown, lambda: {"choices": ["None"] + [x.name for x in list_samplers()]}), "force_latent_sampler": OptionInfo("None", "Force latent upscaler sampler", gr.Dropdown, lambda: {"choices": ["None"] + [x.name for x in list_samplers()]}), 'uni_pc_variant': OptionInfo("bh1", "UniPC variant", gr.Radio, {"choices": ["bh1", "bh2", "vary_coeff"]}), 'uni_pc_skip_type': OptionInfo("time_uniform", "UniPC skip type", gr.Radio, {"choices": ["time_uniform", "time_quadratic", "logSNR"]}), - 'uni_pc_order': OptionInfo(3, "UniPC order (must be < sampling steps)", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1}), - 'uni_pc_lower_order_final': OptionInfo(True, "UniPC lower order final"), + 'eta_noise_seed_delta': OptionInfo(0, "Noise seed delta (eta)", gr.Number, {"precision": 0}), + + "schedulers_sep_diffusers": OptionInfo("

Diffusers specific config

", "", gr.HTML), + "schedulers_prediction_type": OptionInfo("default", "Samplers override model prediction type", gr.Radio, lambda: {"choices": ['default', 'epsilon', 'sample', 'v-prediction']}), + "schedulers_beta_schedule": OptionInfo("default", "Samplers override beta schedule", gr.Radio, lambda: {"choices": ['default', 'linear', 'scaled_linear', 'squaredcos_cap_v2']}), + "schedulers_solver_order": OptionInfo(2, "Samplers solver order where applicable", gr.Slider, {"minimum": 1, "maximum": 5, "step": 1}), + "schedulers_use_karras": OptionInfo(True, "Samplers should use Karras sigmas where applicable"), + "schedulers_use_loworder": OptionInfo(True, "Samplers should use use lower-order solvers in the final steps where applicable"), + "schedulers_use_thresholding": OptionInfo(False, "Samplers should use dynamic thresholding where applicable"), + "schedulers_dpm_solver": OptionInfo("sde-dpmsolver++", "Samplers DPM solver algorithm", gr.Radio, lambda: {"choices": ['dpmsolver', 'dpmsolver++', 'sde-dpmsolver++']}), + + "schedulers_sep_kdiffusers": OptionInfo("

K-Diffusion specific config

", "", gr.HTML), + "always_batch_cond_uncond": OptionInfo(False, "Disable conditional batching enabled on low memory systems"), + "enable_quantization": OptionInfo(True, "Enable samplers quantization for sharper and cleaner results"), + "eta_ancestral": OptionInfo(1.0, "Noise multiplier for ancestral samplers (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), + 's_churn': OptionInfo(0.0, "sigma churn", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), + 's_min_uncond': OptionInfo(0, "sigma negative guidance minimum ", gr.Slider, {"minimum": 0.0, "maximum": 4.0, "step": 0.01}), + 's_tmin': OptionInfo(0.0, "sigma tmin", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), + 's_noise': OptionInfo(1.0, "sigma noise", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), + 'always_discard_next_to_last_sigma': OptionInfo(False, "Always discard next-to-last sigma"), + + "schedulers_sep_compvis": OptionInfo("

CompVis specific config

", "", gr.HTML), + "ddim_discretize": OptionInfo('uniform', "DDIM discretize img2img", gr.Radio, {"choices": ['uniform', 'quad']}), + "eta_ddim": OptionInfo(0.0, "Noise multiplier for DDIM (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), })) -if backend == Backend.ORIGINAL: - options_templates.update(options_section(('sampler-params', "Sampler Settings"), { - "always_batch_cond_uncond": OptionInfo(False, "Disable conditional batching enabled on low memory systems"), - "enable_quantization": OptionInfo(True, "Enable samplers quantization for sharper and cleaner results"), - "eta_ancestral": OptionInfo(1.0, "Noise multiplier for ancestral samplers (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), - "eta_ddim": OptionInfo(0.0, "Noise multiplier for DDIM (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), - "ddim_discretize": OptionInfo('uniform', "DDIM discretize img2img", gr.Radio, {"choices": ['uniform', 'quad']}), - 's_churn': OptionInfo(0.0, "sigma churn", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), - 's_min_uncond': OptionInfo(0, "sigma negative guidance minimum ", gr.Slider, {"minimum": 0.0, "maximum": 4.0, "step": 0.01}), - 's_tmin': OptionInfo(0.0, "sigma tmin", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), - 's_noise': OptionInfo(1.0, "sigma noise", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), - 'eta_noise_seed_delta': OptionInfo(0, "Noise seed delta (eta)", gr.Number, {"precision": 0}), - 'always_discard_next_to_last_sigma': OptionInfo(False, "Always discard next-to-last sigma"), - })) -elif backend == Backend.DIFFUSERS: - options_templates.update(options_section(('sampler-params', "Sampler Settings"), { - # hidden - included for compatibility only - "always_batch_cond_uncond": OptionInfo(False, "Disable conditional batching enabled on low memory systems", gr.Checkbox, { "visible": False}), - "enable_quantization": OptionInfo(True, "Enable samplers quantization for sharper and cleaner results", gr.Checkbox, { "visible": False}), - "eta_ancestral": OptionInfo(1.0, "Noise multiplier for ancestral samplers (eta)", gr.Number, { "visible": False}), - "eta_ddim": OptionInfo(0.0, "Noise multiplier for DDIM (eta)", gr.Number, { "visible": False}), - "ddim_discretize": OptionInfo('uniform', "", gr.Text, { "visible": False}), - 's_churn': OptionInfo(0.0, "sigma churn", gr.Number, { "visible": False}), - 's_min_uncond': OptionInfo(0, "sigma negative guidance minimum ", gr.Number, { "visible": False}), - 's_tmin': OptionInfo(0.0, "sigma tmin", gr.Number, { "visible": False}), - 's_noise': OptionInfo(1.0, "sigma noise", gr.Number, { "visible": False}), - 'eta_noise_seed_delta': OptionInfo(0, "Noise seed delta (eta)", gr.Number, {"precision": 0}, { "visible": False}), - 'always_discard_next_to_last_sigma': OptionInfo(False, "Always discard next-to-last sigma", gr.Checkbox, { "visible": False}), - # diffuser specific - "schedulers_prediction_type": OptionInfo("default", "Samplers override model prediction type", gr.Radio, lambda: {"choices": ['default', 'epsilon', 'sample', 'v-prediction']}), - "schedulers_beta_schedule": OptionInfo("default", "Samplers override beta schedule", gr.Radio, lambda: {"choices": ['default', 'linear', 'scaled_linear', 'squaredcos_cap_v2']}), - "schedulers_solver_order": OptionInfo(2, "Samplers solver order where applicable", gr.Slider, {"minimum": 1, "maximum": 5, "step": 1}), - "schedulers_use_karras": OptionInfo(True, "Samplers should use Karras sigmas where applicable"), - "schedulers_use_loworder": OptionInfo(True, "Samplers should use use lower-order solvers in the final steps where applicable"), - "schedulers_use_thresholding": OptionInfo(False, "Samplers should use dynamic thresholding where applicable"), - "schedulers_dpm_solver": OptionInfo("sde-dpmsolver++", "Samplers DPM solver algorithm", gr.Radio, lambda: {"choices": ['dpmsolver', 'dpmsolver++', 'sde-dpmsolver++']}), - })) - options_templates.update(options_section(('postprocessing', "Postprocessing"), { 'postprocessing_enable_in_main_ui': OptionInfo([], "Enable addtional postprocessing operations", ui_components.DropdownMulti, lambda: {"choices": [x.name for x in shared_items.postprocessing_scripts()]}), 'postprocessing_operation_order': OptionInfo([], "Postprocessing operation order", ui_components.DropdownMulti, lambda: {"choices": [x.name for x in shared_items.postprocessing_scripts()]}), diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py index 11f716d00..866eae913 100644 --- a/scripts/xyz_grid.py +++ b/scripts/xyz_grid.py @@ -131,8 +131,8 @@ def apply_fallback(p, x, xs): shared.opts.data["force_latent_sampler"] = sampler_name -def apply_uni_pc_order(p, x, xs): - shared.opts.data["uni_pc_order"] = min(x, p.steps - 1) +def apply_schedulers_solver_order(p, x, xs): + shared.opts.data["schedulers_solver_order"] = min(x, p.steps - 1) def apply_face_restore(p, opt, x): @@ -231,7 +231,7 @@ def __init__(self, *args, **kwargs): AxisOption("Sampler Eta", float, apply_field("eta")), AxisOptionTxt2Img("Hires upscaler", str, apply_field("hr_upscaler"), choices=lambda: [*shared.latent_upscale_modes, *[x.name for x in shared.sd_upscalers]]), AxisOptionImg2Img("Image Mask Weight", float, apply_field("inpainting_mask_weight")), - AxisOption("UniPC Order", int, apply_uni_pc_order, cost=0.5), + AxisOption("Sampler Solver Order", int, apply_schedulers_solver_order, cost=0.5), AxisOption("Face restore", str, apply_face_restore, fmt=format_value), AxisOption("Token merging ratio", float, apply_override('token_merging_ratio')), AxisOption("Token merging ratio high-res", float, apply_override('token_merging_ratio_hr')), @@ -345,7 +345,7 @@ class SharedSettingsStackHelper(object): def __enter__(self): #Save overridden settings so they can be restored later. self.vae = shared.opts.sd_vae - self.uni_pc_order = shared.opts.uni_pc_order + self.schedulers_solver_order = shared.opts.schedulers_solver_order self.token_merging_ratio_hr = shared.opts.token_merging_ratio_hr self.token_merging_ratio = shared.opts.token_merging_ratio self.sd_model_checkpoint = shared.opts.sd_model_checkpoint @@ -356,7 +356,7 @@ def __enter__(self): def __exit__(self, exc_type, exc_value, tb): #Restore overriden settings after plot generation. shared.opts.data["sd_vae"] = self.vae - shared.opts.data["uni_pc_order"] = self.uni_pc_order + shared.opts.data["schedulers_solver_order"] = self.schedulers_solver_order shared.opts.data["token_merging_ratio_hr"] = self.token_merging_ratio_hr shared.opts.data["token_merging_ratio"] = self.token_merging_ratio shared.opts.data["force_latent_sampler"] = self.force_latent_sampler