From 3bca90b249d749ed5429f76e380d2ffa52fc0d41 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sun, 30 Jul 2023 13:48:27 +0300 Subject: hires fix checkpoint selection --- modules/txt2img.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'modules/txt2img.py') diff --git a/modules/txt2img.py b/modules/txt2img.py index 29d94e8c..935ed418 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -9,7 +9,7 @@ from modules.ui import plaintext_to_html import gradio as gr -def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_sampler_index: int, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args): +def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_index: int, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args): override_settings = create_override_settings_dict(override_settings_texts) p = processing.StableDiffusionProcessingTxt2Img( @@ -41,6 +41,7 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step hr_second_pass_steps=hr_second_pass_steps, hr_resize_x=hr_resize_x, hr_resize_y=hr_resize_y, + hr_checkpoint_name=None if hr_checkpoint_name == 'Use same checkpoint' else hr_checkpoint_name, hr_sampler_name=sd_samplers.samplers_for_img2img[hr_sampler_index - 1].name if hr_sampler_index != 0 else None, hr_prompt=hr_prompt, hr_negative_prompt=hr_negative_prompt, -- cgit v1.2.3 From 70c63c1208d33bf02e15c4e310bac83f12ee8625 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Tue, 8 Aug 2023 21:28:34 +0300 Subject: pass samplers from UI by name, make it possible to use a sampler from infotext even if it's hidden in the dropdown --- modules/img2img.py | 6 +++--- modules/sd_samplers.py | 13 +++++++++---- modules/txt2img.py | 8 ++++---- modules/ui.py | 29 ++++++++++++++--------------- 4 files changed, 30 insertions(+), 26 deletions(-) (limited to 'modules/txt2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index d8e1c534..e06ac1d6 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -6,7 +6,7 @@ import numpy as np from PIL import Image, ImageOps, ImageFilter, ImageEnhance, UnidentifiedImageError import gradio as gr -from modules import sd_samplers, images as imgutil +from modules import images as imgutil from modules.generation_parameters_copypaste import create_override_settings_dict, parse_generation_parameters from modules.processing import Processed, StableDiffusionProcessingImg2Img, process_images from modules.shared import opts, state @@ -116,7 +116,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal process_images(p) -def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, img2img_batch_use_png_info: bool, img2img_batch_png_info_props: list, img2img_batch_png_info_dir: str, request: gr.Request, *args): +def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_name: str, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, img2img_batch_use_png_info: bool, img2img_batch_png_info_props: list, img2img_batch_png_info_dir: str, request: gr.Request, *args): override_settings = create_override_settings_dict(override_settings_texts) is_batch = mode == 5 @@ -172,7 +172,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s seed_resize_from_h=seed_resize_from_h, seed_resize_from_w=seed_resize_from_w, seed_enable_extras=seed_enable_extras, - sampler_name=sd_samplers.samplers_for_img2img[sampler_index].name, + sampler_name=sampler_name, batch_size=batch_size, n_iter=n_iter, steps=steps, diff --git a/modules/sd_samplers.py b/modules/sd_samplers.py index 05dbe2b5..45faae62 100644 --- a/modules/sd_samplers.py +++ b/modules/sd_samplers.py @@ -12,6 +12,7 @@ all_samplers_map = {x.name: x for x in all_samplers} samplers = [] samplers_for_img2img = [] samplers_map = {} +samplers_hidden = {} def find_sampler_config(name): @@ -38,11 +39,11 @@ def create_sampler(name, model): def set_samplers(): - global samplers, samplers_for_img2img + global samplers, samplers_for_img2img, samplers_hidden - hidden = set(shared.opts.hide_samplers) - samplers = [x for x in all_samplers if x.name not in hidden] - samplers_for_img2img = [x for x in all_samplers if x.name not in hidden] + samplers_hidden = set(shared.opts.hide_samplers) + samplers = all_samplers + samplers_for_img2img = all_samplers samplers_map.clear() for sampler in all_samplers: @@ -51,4 +52,8 @@ def set_samplers(): samplers_map[alias.lower()] = sampler.name +def visible_sampler_names(): + return [x.name for x in samplers if x.name not in samplers_hidden] + + set_samplers() diff --git a/modules/txt2img.py b/modules/txt2img.py index 935ed418..8fa389b5 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -1,7 +1,7 @@ from contextlib import closing import modules.scripts -from modules import sd_samplers, processing +from modules import processing from modules.generation_parameters_copypaste import create_override_settings_dict from modules.shared import opts, cmd_opts import modules.shared as shared @@ -9,7 +9,7 @@ from modules.ui import plaintext_to_html import gradio as gr -def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_index: int, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args): +def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_name: str, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_name: str, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args): override_settings = create_override_settings_dict(override_settings_texts) p = processing.StableDiffusionProcessingTxt2Img( @@ -25,7 +25,7 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step seed_resize_from_h=seed_resize_from_h, seed_resize_from_w=seed_resize_from_w, seed_enable_extras=seed_enable_extras, - sampler_name=sd_samplers.samplers[sampler_index].name, + sampler_name=sampler_name, batch_size=batch_size, n_iter=n_iter, steps=steps, @@ -42,7 +42,7 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step hr_resize_x=hr_resize_x, hr_resize_y=hr_resize_y, hr_checkpoint_name=None if hr_checkpoint_name == 'Use same checkpoint' else hr_checkpoint_name, - hr_sampler_name=sd_samplers.samplers_for_img2img[hr_sampler_index - 1].name if hr_sampler_index != 0 else None, + hr_sampler_name=hr_sampler_name, hr_prompt=hr_prompt, hr_negative_prompt=hr_negative_prompt, override_settings=override_settings, diff --git a/modules/ui.py b/modules/ui.py index 5150dae4..e3753e97 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -13,7 +13,7 @@ from PIL import Image, PngImagePlugin # noqa: F401 from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call from modules import gradio_extensons # noqa: F401 -from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, errors, shared_items, ui_settings, timer, sysinfo, ui_checkpoint_merger, ui_prompt_styles, scripts +from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, errors, shared_items, ui_settings, timer, sysinfo, ui_checkpoint_merger, ui_prompt_styles, scripts, sd_samplers from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML from modules.paths import script_path from modules.ui_common import create_refresh_button @@ -29,7 +29,6 @@ import modules.shared as shared import modules.images from modules import prompt_parser from modules.sd_hijack import model_hijack -from modules.sd_samplers import samplers, samplers_for_img2img from modules.generation_parameters_copypaste import image_from_url_text create_setting_component = ui_settings.create_setting_component @@ -360,14 +359,14 @@ def create_output_panel(tabname, outdir): def create_sampler_and_steps_selection(choices, tabname): if opts.samplers_in_dropdown: with FormRow(elem_id=f"sampler_selection_{tabname}"): - sampler_index = gr.Dropdown(label='Sampling method', elem_id=f"{tabname}_sampling", choices=[x.name for x in choices], value=choices[0].name, type="index") + sampler_name = gr.Dropdown(label='Sampling method', elem_id=f"{tabname}_sampling", choices=choices, value=choices[0]) steps = gr.Slider(minimum=1, maximum=150, step=1, elem_id=f"{tabname}_steps", label="Sampling steps", value=20) else: with FormGroup(elem_id=f"sampler_selection_{tabname}"): steps = gr.Slider(minimum=1, maximum=150, step=1, elem_id=f"{tabname}_steps", label="Sampling steps", value=20) - sampler_index = gr.Radio(label='Sampling method', elem_id=f"{tabname}_sampling", choices=[x.name for x in choices], value=choices[0].name, type="index") + sampler_name = gr.Radio(label='Sampling method', elem_id=f"{tabname}_sampling", choices=choices, value=choices[0]) - return steps, sampler_index + return steps, sampler_name def ordered_ui_categories(): @@ -414,7 +413,7 @@ def create_ui(): for category in ordered_ui_categories(): if category == "sampler": - steps, sampler_index = create_sampler_and_steps_selection(samplers, "txt2img") + steps, sampler_name = create_sampler_and_steps_selection(sd_samplers.visible_sampler_names(), "txt2img") elif category == "dimensions": with FormRow(): @@ -460,7 +459,7 @@ def create_ui(): hr_checkpoint_name = gr.Dropdown(label='Hires checkpoint', elem_id="hr_checkpoint", choices=["Use same checkpoint"] + modules.sd_models.checkpoint_tiles(use_short=True), value="Use same checkpoint") create_refresh_button(hr_checkpoint_name, modules.sd_models.list_models, lambda: {"choices": ["Use same checkpoint"] + modules.sd_models.checkpoint_tiles(use_short=True)}, "hr_checkpoint_refresh") - hr_sampler_index = gr.Dropdown(label='Hires sampling method', elem_id="hr_sampler", choices=["Use same sampler"] + [x.name for x in samplers_for_img2img], value="Use same sampler", type="index") + hr_sampler_name = gr.Dropdown(label='Hires sampling method', elem_id="hr_sampler", choices=["Use same sampler"] + sd_samplers.visible_sampler_names(), value="Use same sampler") with FormRow(elem_id="txt2img_hires_fix_row4", variant="compact", visible=opts.hires_fix_show_prompts) as hr_prompts_container: with gr.Column(scale=80): @@ -520,7 +519,7 @@ def create_ui(): toprow.negative_prompt, toprow.ui_styles.dropdown, steps, - sampler_index, + sampler_name, restore_faces, tiling, batch_count, @@ -538,7 +537,7 @@ def create_ui(): hr_resize_x, hr_resize_y, hr_checkpoint_name, - hr_sampler_index, + hr_sampler_name, hr_prompt, hr_negative_prompt, override_settings, @@ -583,7 +582,7 @@ def create_ui(): (toprow.prompt, "Prompt"), (toprow.negative_prompt, "Negative prompt"), (steps, "Steps"), - (sampler_index, "Sampler"), + (sampler_name, "Sampler"), (restore_faces, "Face restoration"), (cfg_scale, "CFG scale"), (seed, "Seed"), @@ -605,7 +604,7 @@ def create_ui(): (hr_resize_x, "Hires resize-1"), (hr_resize_y, "Hires resize-2"), (hr_checkpoint_name, "Hires checkpoint"), - (hr_sampler_index, "Hires sampler"), + (hr_sampler_name, "Hires sampler"), (hr_sampler_container, lambda d: gr.update(visible=True) if d.get("Hires sampler", "Use same sampler") != "Use same sampler" or d.get("Hires checkpoint", "Use same checkpoint") != "Use same checkpoint" else gr.update()), (hr_prompt, "Hires prompt"), (hr_negative_prompt, "Hires negative prompt"), @@ -621,7 +620,7 @@ def create_ui(): toprow.prompt, toprow.negative_prompt, steps, - sampler_index, + sampler_name, cfg_scale, seed, width, @@ -744,7 +743,7 @@ def create_ui(): for category in ordered_ui_categories(): if category == "sampler": - steps, sampler_index = create_sampler_and_steps_selection(samplers_for_img2img, "img2img") + steps, sampler_name = create_sampler_and_steps_selection(sd_samplers.visible_sampler_names(), "img2img") elif category == "dimensions": with FormRow(): @@ -876,7 +875,7 @@ def create_ui(): init_img_inpaint, init_mask_inpaint, steps, - sampler_index, + sampler_name, mask_blur, mask_alpha, inpainting_fill, @@ -972,7 +971,7 @@ def create_ui(): (toprow.prompt, "Prompt"), (toprow.negative_prompt, "Negative prompt"), (steps, "Steps"), - (sampler_index, "Sampler"), + (sampler_name, "Sampler"), (restore_faces, "Face restoration"), (cfg_scale, "CFG scale"), (image_cfg_scale, "Image CFG scale"), -- cgit v1.2.3 From bd4b4292ef6c2cb0a452b7105485ec06301b7531 Mon Sep 17 00:00:00 2001 From: catboxanon <122327233+catboxanon@users.noreply.github.com> Date: Tue, 8 Aug 2023 20:55:08 -0400 Subject: Fix hr use same sampler --- modules/txt2img.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/txt2img.py') diff --git a/modules/txt2img.py b/modules/txt2img.py index 8fa389b5..edad8930 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -42,7 +42,7 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step hr_resize_x=hr_resize_x, hr_resize_y=hr_resize_y, hr_checkpoint_name=None if hr_checkpoint_name == 'Use same checkpoint' else hr_checkpoint_name, - hr_sampler_name=hr_sampler_name, + hr_sampler_name=None if hr_sampler_name == 'Use same sampler' else hr_sampler_name, hr_prompt=hr_prompt, hr_negative_prompt=hr_negative_prompt, override_settings=override_settings, -- cgit v1.2.3 From 33446acf47a8c3e0c0964782189562df3c4bcf4f Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Thu, 10 Aug 2023 12:41:41 +0300 Subject: face restoration and tiling moved to settings - use "Options in main UI" setting if you want them back --- modules/generation_parameters_copypaste.py | 2 ++ modules/img2img.py | 4 +--- modules/processing.py | 11 +++++++++-- modules/shared_options.py | 2 ++ modules/txt2img.py | 4 +--- modules/ui.py | 12 ++---------- 6 files changed, 17 insertions(+), 18 deletions(-) (limited to 'modules/txt2img.py') diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index d932c67d..bdff3266 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -343,6 +343,8 @@ infotext_to_setting_name_mapping = [ ('Pad conds', 'pad_cond_uncond'), ('VAE Encoder', 'sd_vae_encode_method'), ('VAE Decoder', 'sd_vae_decode_method'), + ('Tiling', 'tiling'), + ('Face restoration', 'face_restoration'), ] diff --git a/modules/img2img.py b/modules/img2img.py index e06ac1d6..c7bbbac8 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -116,7 +116,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal process_images(p) -def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_name: str, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, img2img_batch_use_png_info: bool, img2img_batch_png_info_props: list, img2img_batch_png_info_dir: str, request: gr.Request, *args): +def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_name: str, mask_blur: int, mask_alpha: float, inpainting_fill: int, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, img2img_batch_use_png_info: bool, img2img_batch_png_info_props: list, img2img_batch_png_info_dir: str, request: gr.Request, *args): override_settings = create_override_settings_dict(override_settings_texts) is_batch = mode == 5 @@ -179,8 +179,6 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s cfg_scale=cfg_scale, width=width, height=height, - restore_faces=restore_faces, - tiling=tiling, init_images=[image], mask=mask, mask_blur=mask_blur, diff --git a/modules/processing.py b/modules/processing.py index 7819644c..68a8f1c6 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -111,7 +111,7 @@ class StableDiffusionProcessing: cached_uc = [None, None] cached_c = [None, None] - def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_name: str = None, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, width: int = 512, height: int = 512, restore_faces: bool = False, tiling: bool = False, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, ddim_discretize: str = None, s_min_uncond: float = 0.0, s_churn: float = 0.0, s_tmax: float = None, s_tmin: float = 0.0, s_noise: float = None, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None, script_args: list = None): + def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_name: str = None, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, width: int = 512, height: int = 512, restore_faces: bool = None, tiling: bool = None, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, ddim_discretize: str = None, s_min_uncond: float = 0.0, s_churn: float = 0.0, s_tmax: float = None, s_tmin: float = 0.0, s_noise: float = None, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None, script_args: list = None): if sampler_index is not None: print("sampler_index argument for StableDiffusionProcessing does not do anything; use sampler_name", file=sys.stderr) @@ -564,7 +564,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter "CFG scale": p.cfg_scale, "Image CFG scale": getattr(p, 'image_cfg_scale', None), "Seed": p.all_seeds[0] if use_main_prompt else all_seeds[index], - "Face restoration": (opts.face_restoration_model if p.restore_faces else None), + "Face restoration": opts.face_restoration_model if p.restore_faces else None, "Size": f"{p.width}x{p.height}", "Model hash": getattr(p, 'sd_model_hash', None if not opts.add_model_hash_to_info or not shared.sd_model.sd_model_hash else shared.sd_model.sd_model_hash), "Model": (None if not opts.add_model_name_to_info else shared.sd_model.sd_checkpoint_info.name_for_extra), @@ -580,6 +580,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter "Init image hash": getattr(p, 'init_img_hash', None), "RNG": opts.randn_source if opts.randn_source != "GPU" and opts.randn_source != "NV" else None, "NGMS": None if p.s_min_uncond == 0 else p.s_min_uncond, + "Tiling": "True" if p.tiling else None, **p.extra_generation_params, "Version": program_version() if opts.add_version_to_infotext else None, "User": p.user if opts.add_user_name_to_info else None, @@ -645,6 +646,12 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: seed = get_fixed_seed(p.seed) subseed = get_fixed_seed(p.subseed) + if p.restore_faces is None: + p.restore_faces = opts.face_restoration + + if p.tiling is None: + p.tiling = opts.tiling + modules.sd_hijack.model_hijack.apply_circular(p.tiling) modules.sd_hijack.model_hijack.clear_comments() diff --git a/modules/shared_options.py b/modules/shared_options.py index 7468bc81..f72859d9 100644 --- a/modules/shared_options.py +++ b/modules/shared_options.py @@ -92,6 +92,7 @@ options_templates.update(options_section(('upscaling', "Upscaling"), { })) options_templates.update(options_section(('face-restoration', "Face restoration"), { + "face_restoration": OptionInfo(False, "Restore faces").info("will use a third-party model on generation result to reconstruct faces"), "face_restoration_model": OptionInfo("CodeFormer", "Face restoration model", gr.Radio, lambda: {"choices": [x.name() for x in shared.face_restorers]}), "code_former_weight": OptionInfo(0.5, "CodeFormer weight", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.01}).info("0 = maximum effect; 1 = minimum effect"), "face_restoration_unload": OptionInfo(False, "Move face restoration model from VRAM into RAM after processing"), @@ -138,6 +139,7 @@ options_templates.update(options_section(('sd', "Stable Diffusion"), { "CLIP_stop_at_last_layers": OptionInfo(1, "Clip skip", gr.Slider, {"minimum": 1, "maximum": 12, "step": 1}).link("wiki", "https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Features#clip-skip").info("ignore last layers of CLIP network; 1 ignores none, 2 ignores one layer"), "upcast_attn": OptionInfo(False, "Upcast cross attention layer to float32"), "randn_source": OptionInfo("GPU", "Random number generator source.", gr.Radio, {"choices": ["GPU", "CPU", "NV"]}).info("changes seeds drastically; use CPU to produce the same picture across different videocard vendors; use NV to produce same picture as on NVidia videocards"), + "tiling": OptionInfo(False, "Tiling").info("produce a tileable picture"), })) options_templates.update(options_section(('sdxl', "Stable Diffusion XL"), { diff --git a/modules/txt2img.py b/modules/txt2img.py index edad8930..5ea96bba 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -9,7 +9,7 @@ from modules.ui import plaintext_to_html import gradio as gr -def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_name: str, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_name: str, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args): +def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_name: str, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_name: str, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args): override_settings = create_override_settings_dict(override_settings_texts) p = processing.StableDiffusionProcessingTxt2Img( @@ -32,8 +32,6 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step cfg_scale=cfg_scale, width=width, height=height, - restore_faces=restore_faces, - tiling=tiling, enable_hr=enable_hr, denoising_strength=denoising_strength if enable_hr else None, hr_scale=hr_scale, diff --git a/modules/ui.py b/modules/ui.py index cbad3afe..09a826fd 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -432,8 +432,7 @@ def create_ui(): elif category == "checkboxes": with FormRow(elem_classes="checkboxes-row", variant="compact"): - restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1, elem_id="txt2img_restore_faces") - tiling = gr.Checkbox(label='Tiling', value=False, elem_id="txt2img_tiling") + pass elif category == "hires_fix": with InputAccordion(False, label="Hires. fix") as enable_hr: @@ -516,8 +515,6 @@ def create_ui(): toprow.ui_styles.dropdown, steps, sampler_name, - restore_faces, - tiling, batch_count, batch_size, cfg_scale, @@ -572,7 +569,6 @@ def create_ui(): (toprow.negative_prompt, "Negative prompt"), (steps, "Steps"), (sampler_name, "Sampler"), - (restore_faces, "Face restoration"), (cfg_scale, "CFG scale"), (seed, "Seed"), (width, "Size-1"), @@ -792,8 +788,7 @@ def create_ui(): elif category == "checkboxes": with FormRow(elem_classes="checkboxes-row", variant="compact"): - restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1, elem_id="img2img_restore_faces") - tiling = gr.Checkbox(label='Tiling', value=False, elem_id="img2img_tiling") + pass elif category == "batch": if not opts.dimensions_and_batch_together: @@ -866,8 +861,6 @@ def create_ui(): mask_blur, mask_alpha, inpainting_fill, - restore_faces, - tiling, batch_count, batch_size, cfg_scale, @@ -959,7 +952,6 @@ def create_ui(): (toprow.negative_prompt, "Negative prompt"), (steps, "Steps"), (sampler_name, "Sampler"), - (restore_faces, "Face restoration"), (cfg_scale, "CFG scale"), (image_cfg_scale, "Image CFG scale"), (seed, "Seed"), -- cgit v1.2.3 From f0b72b81211881e083c84cff585380bb70d17271 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 12 Aug 2023 17:46:13 +0300 Subject: move seed, variation seed and variation seed strength to a single row, dump resize seed from UI add a way for scripts to register a callback for before/after just a single component's creation --- modules/img2img.py | 8 +-- modules/processing_scripts/seed.py | 95 +++++++++++++++++++++++++++++ modules/scripts.py | 77 +++++++++++++++++++++++- modules/shared_items.py | 1 + modules/txt2img.py | 8 +-- modules/ui.py | 119 ++++--------------------------------- style.css | 9 ++- 7 files changed, 191 insertions(+), 126 deletions(-) create mode 100644 modules/processing_scripts/seed.py (limited to 'modules/txt2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index c7bbbac8..ac9fd3f8 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -116,7 +116,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal process_images(p) -def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_name: str, mask_blur: int, mask_alpha: float, inpainting_fill: int, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, img2img_batch_use_png_info: bool, img2img_batch_png_info_props: list, img2img_batch_png_info_dir: str, request: gr.Request, *args): +def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_name: str, mask_blur: int, mask_alpha: float, inpainting_fill: int, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, img2img_batch_use_png_info: bool, img2img_batch_png_info_props: list, img2img_batch_png_info_dir: str, request: gr.Request, *args): override_settings = create_override_settings_dict(override_settings_texts) is_batch = mode == 5 @@ -166,12 +166,6 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s prompt=prompt, negative_prompt=negative_prompt, styles=prompt_styles, - seed=seed, - subseed=subseed, - subseed_strength=subseed_strength, - seed_resize_from_h=seed_resize_from_h, - seed_resize_from_w=seed_resize_from_w, - seed_enable_extras=seed_enable_extras, sampler_name=sampler_name, batch_size=batch_size, n_iter=n_iter, diff --git a/modules/processing_scripts/seed.py b/modules/processing_scripts/seed.py new file mode 100644 index 00000000..e0911bbe --- /dev/null +++ b/modules/processing_scripts/seed.py @@ -0,0 +1,95 @@ +import json + +import gradio as gr + +from modules import scripts, ui, errors +from modules.shared import cmd_opts +from modules.ui_components import ToolButton + + +class ScriptSeed(scripts.ScriptBuiltin): + section = "seed" + create_group = False + + def __init__(self): + self.seed = None + self.reuse_seed = None + self.reuse_subseed = None + + def title(self): + return "Seed" + + def show(self, is_img2img): + return scripts.AlwaysVisible + + def ui(self, is_img2img): + with gr.Row(elem_id=self.elem_id("seed_row")): + if cmd_opts.use_textbox_seed: + self.seed = gr.Textbox(label='Seed', value="", elem_id=self.elem_id("seed")) + else: + self.seed = gr.Number(label='Seed', value=-1, elem_id=self.elem_id("seed"), precision=0) + + random_seed = ToolButton(ui.random_symbol, elem_id=self.elem_id("random_seed"), label='Random seed') + reuse_seed = ToolButton(ui.reuse_symbol, elem_id=self.elem_id("reuse_seed"), label='Reuse seed') + + subseed = gr.Number(label='Variation seed', value=-1, elem_id=self.elem_id("subseed"), precision=0) + + random_subseed = ToolButton(ui.random_symbol, elem_id=self.elem_id("random_subseed")) + reuse_subseed = ToolButton(ui.reuse_symbol, elem_id=self.elem_id("reuse_subseed")) + + subseed_strength = gr.Slider(label='Variation strength', value=0.0, minimum=0, maximum=1, step=0.01, elem_id=self.elem_id("subseed_strength")) + + random_seed.click(fn=None, _js="function(){setRandomSeed('" + self.elem_id("seed") + "')}", show_progress=False, inputs=[], outputs=[]) + random_subseed.click(fn=None, _js="function(){setRandomSeed('" + self.elem_id("subseed") + "')}", show_progress=False, inputs=[], outputs=[]) + + self.infotext_fields = [ + (self.seed, "Seed"), + (subseed, "Variation seed"), + (subseed_strength, "Variation seed strength"), + ] + + self.on_after_component(lambda x: connect_reuse_seed(self.seed, reuse_seed, x.component, False), elem_id=f'generation_info_{self.tabname}') + self.on_after_component(lambda x: connect_reuse_seed(self.seed, reuse_subseed, x.component, True), elem_id=f'generation_info_{self.tabname}') + + return self.seed, subseed, subseed_strength + + def before_process(self, p, seed, subseed, subseed_strength): + p.seed = seed + + if subseed_strength > 0: + p.subseed = subseed + p.subseed_strength = subseed_strength + + +def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info: gr.Textbox, is_subseed): + """ Connects a 'reuse (sub)seed' button's click event so that it copies last used + (sub)seed value from generation info the to the seed field. If copying subseed and subseed strength + was 0, i.e. no variation seed was used, it copies the normal seed value instead.""" + + def copy_seed(gen_info_string: str, index): + res = -1 + + try: + gen_info = json.loads(gen_info_string) + index -= gen_info.get('index_of_first_image', 0) + + if is_subseed and gen_info.get('subseed_strength', 0) > 0: + all_subseeds = gen_info.get('all_subseeds', [-1]) + res = all_subseeds[index if 0 <= index < len(all_subseeds) else 0] + else: + all_seeds = gen_info.get('all_seeds', [-1]) + res = all_seeds[index if 0 <= index < len(all_seeds) else 0] + + except json.decoder.JSONDecodeError: + if gen_info_string: + errors.report(f"Error parsing JSON generation info: {gen_info_string}") + + return [res, gr.update()] + + reuse_seed.click( + fn=copy_seed, + _js="(x, y) => [x, selected_gallery_index()]", + show_progress=False, + inputs=[generation_info, seed], + outputs=[seed, seed] + ) diff --git a/modules/scripts.py b/modules/scripts.py index 51da732a..66fbec0d 100644 --- a/modules/scripts.py +++ b/modules/scripts.py @@ -3,6 +3,7 @@ import re import sys import inspect from collections import namedtuple +from dataclasses import dataclass import gradio as gr @@ -21,6 +22,11 @@ class PostprocessBatchListArgs: self.images = images +@dataclass +class OnComponent: + component: gr.blocks.Block + + class Script: name = None """script's internal name derived from title""" @@ -35,6 +41,7 @@ class Script: is_txt2img = False is_img2img = False + tabname = None group = None """A gr.Group component that has all script's UI inside it.""" @@ -55,6 +62,12 @@ class Script: api_info = None """Generated value of type modules.api.models.ScriptInfo with information about the script for API""" + on_before_component_elem_id = [] + """list of callbacks to be called before a component with an elem_id is created""" + + on_after_component_elem_id = [] + """list of callbacks to be called after a component with an elem_id is created""" + def title(self): """this function should return the title of the script. This is what will be displayed in the dropdown menu.""" @@ -215,6 +228,24 @@ class Script: pass + def on_before_component(self, callback, *, elem_id): + """ + Calls callback before a component is created. The callback function is called with a single argument of type OnComponent. + + This function is an alternative to before_component in that it also cllows to run before a component is created, but + it doesn't require to be called for every created component - just for the one you need. + """ + + self.on_before_component_elem_id.append((elem_id, callback)) + + def on_after_component(self, callback, *, elem_id): + """ + Calls callback after a component is created. The callback function is called with a single argument of type OnComponent. + """ + + self.on_after_component_elem_id.append((elem_id, callback)) + + def describe(self): """unused""" return "" @@ -236,6 +267,17 @@ class Script: pass +class ScriptBuiltin(Script): + + def elem_id(self, item_id): + """helper function to generate id for a HTML element, constructs final id out of tab and user-supplied item_id""" + + need_tabname = self.show(True) == self.show(False) + tabname = ('img2img' if self.is_img2img else 'txt2txt') + "_" if need_tabname else "" + + return f'{tabname}{item_id}' + + current_basedir = paths.script_path @@ -354,10 +396,17 @@ class ScriptRunner: self.selectable_scripts = [] self.alwayson_scripts = [] self.titles = [] + self.title_map = {} self.infotext_fields = [] self.paste_field_names = [] self.inputs = [None] + self.on_before_component_elem_id = {} + """dict of callbacks to be called before an element is created; key=elem_id, value=list of callbacks""" + + self.on_after_component_elem_id = {} + """dict of callbacks to be called after an element is created; key=elem_id, value=list of callbacks""" + def initialize_scripts(self, is_img2img): from modules import scripts_auto_postprocessing @@ -372,6 +421,7 @@ class ScriptRunner: script.filename = script_data.path script.is_txt2img = not is_img2img script.is_img2img = is_img2img + script.tabname = "img2img" if is_img2img else "txt2img" visibility = script.show(script.is_img2img) @@ -446,6 +496,8 @@ class ScriptRunner: self.inputs = [None] def setup_ui(self): + all_titles = [wrap_call(script.title, script.filename, "title") or script.filename for script in self.scripts] + self.title_map = {title.lower(): script for title, script in zip(all_titles, self.scripts)} self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts] self.setup_ui_for_section(None) @@ -492,6 +544,13 @@ class ScriptRunner: self.infotext_fields.append((dropdown, lambda x: gr.update(value=x.get('Script', 'None')))) self.infotext_fields.extend([(script.group, onload_script_visibility) for script in self.selectable_scripts]) + for script in self.scripts: + for elem_id, callback in script.on_before_component_elem_id: + self.on_before_component_elem_id.get(elem_id, []).append((callback, script)) + + for elem_id, callback in script.on_after_component_elem_id: + self.on_after_component_elem_id.get(elem_id, []).append((callback, script)) + return self.inputs def run(self, p, *args): @@ -585,6 +644,13 @@ class ScriptRunner: errors.report(f"Error running postprocess_image: {script.filename}", exc_info=True) def before_component(self, component, **kwargs): + for callbacks in self.on_before_component_elem_id.get(kwargs.get("elem_id"), []): + for callback, script in callbacks: + try: + callback(OnComponent(component=component)) + except Exception: + errors.report(f"Error running on_before_component: {script.filename}", exc_info=True) + for script in self.scripts: try: script.before_component(component, **kwargs) @@ -592,12 +658,22 @@ class ScriptRunner: errors.report(f"Error running before_component: {script.filename}", exc_info=True) def after_component(self, component, **kwargs): + for callbacks in self.on_after_component_elem_id.get(component.elem_id, []): + for callback, script in callbacks: + try: + callback(OnComponent(component=component)) + except Exception: + errors.report(f"Error running on_after_component: {script.filename}", exc_info=True) + for script in self.scripts: try: script.after_component(component, **kwargs) except Exception: errors.report(f"Error running after_component: {script.filename}", exc_info=True) + def script(self, title): + return self.title_map.get(title.lower()) + def reload_sources(self, cache): for si, script in list(enumerate(self.scripts)): args_from = script.args_from @@ -616,7 +692,6 @@ class ScriptRunner: self.scripts[si].args_from = args_from self.scripts[si].args_to = args_to - def before_hr(self, p): for script in self.alwayson_scripts: try: diff --git a/modules/shared_items.py b/modules/shared_items.py index 754166d2..84d69c8d 100644 --- a/modules/shared_items.py +++ b/modules/shared_items.py @@ -73,6 +73,7 @@ ui_reorder_categories_builtin_items = [ "checkboxes", "dimensions", "cfg", + "denoising", "seed", "batch", "override_settings", diff --git a/modules/txt2img.py b/modules/txt2img.py index 5ea96bba..1ee592ad 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -9,7 +9,7 @@ from modules.ui import plaintext_to_html import gradio as gr -def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_name: str, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_name: str, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args): +def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_name: str, n_iter: int, batch_size: int, cfg_scale: float, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_name: str, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args): override_settings = create_override_settings_dict(override_settings_texts) p = processing.StableDiffusionProcessingTxt2Img( @@ -19,12 +19,6 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step prompt=prompt, styles=prompt_styles, negative_prompt=negative_prompt, - seed=seed, - subseed=subseed, - subseed_strength=subseed_strength, - seed_resize_from_h=seed_resize_from_h, - seed_resize_from_w=seed_resize_from_w, - seed_enable_extras=seed_enable_extras, sampler_name=sampler_name, batch_size=batch_size, n_iter=n_iter, diff --git a/modules/ui.py b/modules/ui.py index 3321b94d..a6b1f964 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1,5 +1,4 @@ import datetime -import json import mimetypes import os import sys @@ -13,7 +12,7 @@ from PIL import Image, PngImagePlugin # noqa: F401 from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call from modules import gradio_extensons # noqa: F401 -from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, errors, shared_items, ui_settings, timer, sysinfo, ui_checkpoint_merger, ui_prompt_styles, scripts, sd_samplers, processing, ui_extra_networks +from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, shared_items, ui_settings, timer, sysinfo, ui_checkpoint_merger, ui_prompt_styles, scripts, sd_samplers, processing, ui_extra_networks from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML, InputAccordion from modules.paths import script_path from modules.ui_common import create_refresh_button @@ -142,45 +141,6 @@ def interrogate_deepbooru(image): return gr.update() if prompt is None else prompt -def create_seed_inputs(target_interface): - with FormRow(elem_id=f"{target_interface}_seed_row", variant="compact"): - if cmd_opts.use_textbox_seed: - seed = gr.Textbox(label='Seed', value="", elem_id=f"{target_interface}_seed") - else: - seed = gr.Number(label='Seed', value=-1, elem_id=f"{target_interface}_seed", precision=0) - - random_seed = ToolButton(random_symbol, elem_id=f"{target_interface}_random_seed", label='Random seed') - reuse_seed = ToolButton(reuse_symbol, elem_id=f"{target_interface}_reuse_seed", label='Reuse seed') - - seed_checkbox = gr.Checkbox(label='Extra', elem_id=f"{target_interface}_subseed_show", value=False) - - # Components to show/hide based on the 'Extra' checkbox - seed_extras = [] - - with FormRow(visible=False, elem_id=f"{target_interface}_subseed_row") as seed_extra_row_1: - seed_extras.append(seed_extra_row_1) - subseed = gr.Number(label='Variation seed', value=-1, elem_id=f"{target_interface}_subseed", precision=0) - random_subseed = ToolButton(random_symbol, elem_id=f"{target_interface}_random_subseed") - reuse_subseed = ToolButton(reuse_symbol, elem_id=f"{target_interface}_reuse_subseed") - subseed_strength = gr.Slider(label='Variation strength', value=0.0, minimum=0, maximum=1, step=0.01, elem_id=f"{target_interface}_subseed_strength") - - with FormRow(visible=False) as seed_extra_row_2: - seed_extras.append(seed_extra_row_2) - seed_resize_from_w = gr.Slider(minimum=0, maximum=2048, step=8, label="Resize seed from width", value=0, elem_id=f"{target_interface}_seed_resize_from_w") - seed_resize_from_h = gr.Slider(minimum=0, maximum=2048, step=8, label="Resize seed from height", value=0, elem_id=f"{target_interface}_seed_resize_from_h") - - random_seed.click(fn=None, _js="function(){setRandomSeed('" + target_interface + "_seed')}", show_progress=False, inputs=[], outputs=[]) - random_subseed.click(fn=None, _js="function(){setRandomSeed('" + target_interface + "_subseed')}", show_progress=False, inputs=[], outputs=[]) - - def change_visibility(show): - return {comp: gr_show(show) for comp in seed_extras} - - seed_checkbox.change(change_visibility, show_progress=False, inputs=[seed_checkbox], outputs=seed_extras) - - return seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox - - - def connect_clear_prompt(button): """Given clear button, prompt, and token_counter objects, setup clear prompt button click event""" button.click( @@ -191,39 +151,6 @@ def connect_clear_prompt(button): ) -def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info: gr.Textbox, dummy_component, is_subseed): - """ Connects a 'reuse (sub)seed' button's click event so that it copies last used - (sub)seed value from generation info the to the seed field. If copying subseed and subseed strength - was 0, i.e. no variation seed was used, it copies the normal seed value instead.""" - def copy_seed(gen_info_string: str, index): - res = -1 - - try: - gen_info = json.loads(gen_info_string) - index -= gen_info.get('index_of_first_image', 0) - - if is_subseed and gen_info.get('subseed_strength', 0) > 0: - all_subseeds = gen_info.get('all_subseeds', [-1]) - res = all_subseeds[index if 0 <= index < len(all_subseeds) else 0] - else: - all_seeds = gen_info.get('all_seeds', [-1]) - res = all_seeds[index if 0 <= index < len(all_seeds) else 0] - - except json.decoder.JSONDecodeError: - if gen_info_string: - errors.report(f"Error parsing JSON generation info: {gen_info_string}") - - return [res, gr_show(False)] - - reuse_seed.click( - fn=copy_seed, - _js="(x, y) => [x, selected_gallery_index()]", - show_progress=False, - inputs=[generation_info, dummy_component], - outputs=[seed, dummy_component] - ) - - def update_token_counter(text, steps): try: text, _ = extra_networks.parse_prompt(text) @@ -429,10 +356,8 @@ def create_ui(): batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="txt2img_batch_size") elif category == "cfg": - cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="txt2img_cfg_scale") - - elif category == "seed": - seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('txt2img') + with gr.Row(): + cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="txt2img_cfg_scale") elif category == "checkboxes": with FormRow(elem_classes="checkboxes-row", variant="compact"): @@ -509,9 +434,6 @@ def create_ui(): txt2img_gallery, generation_info, html_info, html_log = create_output_panel("txt2img", opts.outdir_txt2img_samples) - connect_reuse_seed(seed, reuse_seed, generation_info, dummy_component, is_subseed=False) - connect_reuse_seed(subseed, reuse_subseed, generation_info, dummy_component, is_subseed=True) - txt2img_args = dict( fn=wrap_gradio_gpu_call(modules.txt2img.txt2img, extra_outputs=[None, '', '']), _js="submit", @@ -525,8 +447,6 @@ def create_ui(): batch_count, batch_size, cfg_scale, - seed, - subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox, height, width, enable_hr, @@ -577,15 +497,9 @@ def create_ui(): (steps, "Steps"), (sampler_name, "Sampler"), (cfg_scale, "CFG scale"), - (seed, "Seed"), (width, "Size-1"), (height, "Size-2"), (batch_size, "Batch size"), - (seed_checkbox, lambda d: "Variation seed" in d or "Seed resize from-1" in d), - (subseed, "Variation seed"), - (subseed_strength, "Variation seed strength"), - (seed_resize_from_w, "Seed resize from-1"), - (seed_resize_from_h, "Seed resize from-2"), (toprow.ui_styles.dropdown, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()), (denoising_strength, "Denoising strength"), (enable_hr, lambda d: "Denoising strength" in d and ("Hires upscale" in d or "Hires upscaler" in d or "Hires resize-1" in d)), @@ -613,7 +527,7 @@ def create_ui(): steps, sampler_name, cfg_scale, - seed, + scripts.scripts_txt2img.script('Seed').seed, width, height, ] @@ -783,15 +697,13 @@ def create_ui(): batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="img2img_batch_count") batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="img2img_batch_size") - elif category == "cfg": - with FormGroup(): - with FormRow(): - cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="img2img_cfg_scale") - image_cfg_scale = gr.Slider(minimum=0, maximum=3.0, step=0.05, label='Image CFG Scale', value=1.5, elem_id="img2img_image_cfg_scale", visible=False) - denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength") + elif category == "denoising": + denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength") - elif category == "seed": - seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('img2img') + elif category == "cfg": + with gr.Row(): + cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="img2img_cfg_scale") + image_cfg_scale = gr.Slider(minimum=0, maximum=3.0, step=0.05, label='Image CFG Scale', value=1.5, elem_id="img2img_image_cfg_scale", visible=False) elif category == "checkboxes": with FormRow(elem_classes="checkboxes-row", variant="compact"): @@ -849,9 +761,6 @@ def create_ui(): img2img_gallery, generation_info, html_info, html_log = create_output_panel("img2img", opts.outdir_img2img_samples) - connect_reuse_seed(seed, reuse_seed, generation_info, dummy_component, is_subseed=False) - connect_reuse_seed(subseed, reuse_subseed, generation_info, dummy_component, is_subseed=True) - img2img_args = dict( fn=wrap_gradio_gpu_call(modules.img2img.img2img, extra_outputs=[None, '', '']), _js="submit_img2img", @@ -878,8 +787,6 @@ def create_ui(): cfg_scale, image_cfg_scale, denoising_strength, - seed, - subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox, selected_scale_tab, height, width, @@ -966,15 +873,9 @@ def create_ui(): (sampler_name, "Sampler"), (cfg_scale, "CFG scale"), (image_cfg_scale, "Image CFG scale"), - (seed, "Seed"), (width, "Size-1"), (height, "Size-2"), (batch_size, "Batch size"), - (seed_checkbox, lambda d: "Variation seed" in d or "Seed resize from-1" in d), - (subseed, "Variation seed"), - (subseed_strength, "Variation seed strength"), - (seed_resize_from_w, "Seed resize from-1"), - (seed_resize_from_h, "Seed resize from-2"), (toprow.ui_styles.dropdown, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()), (denoising_strength, "Denoising strength"), (mask_blur, "Mask blur"), diff --git a/style.css b/style.css index f936e9a0..92093b89 100644 --- a/style.css +++ b/style.css @@ -222,14 +222,18 @@ div.block.gradio-accordion { padding: 0.1em 0.75em; } +[id$=_seed], [id$=_subseed]{ + max-width: 10em; +} + [id$=_subseed_show]{ min-width: auto !important; flex-grow: 0 !important; display: flex; } -[id$=_subseed_show] label{ - margin-bottom: 0.5em; +[id$=_subseed_show] .label-wrap{ + margin: 0 0 0 0.5em; align-self: end; } @@ -1028,5 +1032,6 @@ div.accordions{ div.accordions > div.input-accordion.input-accordion-open{ flex: 1 auto; + flex-flow: column; } -- cgit v1.2.3