From 0c5fa9a681672508adadbe1e10fc16d7fe0ed6dd Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Sun, 16 Oct 2022 08:51:24 +0300 Subject: [PATCH 01/15] do not reload embeddings from disk when doing textual inversion --- modules/processing.py | 5 +++-- modules/textual_inversion/textual_inversion.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/processing.py b/modules/processing.py index 941ae089..833fed8a 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -53,7 +53,7 @@ def get_correct_sampler(p): return sd_samplers.samplers_for_img2img class StableDiffusionProcessing: - def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt="", styles=None, seed=-1, subseed=-1, subseed_strength=0, seed_resize_from_h=-1, seed_resize_from_w=-1, seed_enable_extras=True, sampler_index=0, batch_size=1, n_iter=1, steps=50, cfg_scale=7.0, width=512, height=512, restore_faces=False, tiling=False, do_not_save_samples=False, do_not_save_grid=False, extra_generation_params=None, overlay_images=None, negative_prompt=None, eta=None): + def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt="", styles=None, seed=-1, subseed=-1, subseed_strength=0, seed_resize_from_h=-1, seed_resize_from_w=-1, seed_enable_extras=True, sampler_index=0, batch_size=1, n_iter=1, steps=50, cfg_scale=7.0, width=512, height=512, restore_faces=False, tiling=False, do_not_save_samples=False, do_not_save_grid=False, extra_generation_params=None, overlay_images=None, negative_prompt=None, eta=None, do_not_reload_embeddings=False): self.sd_model = sd_model self.outpath_samples: str = outpath_samples self.outpath_grids: str = outpath_grids @@ -80,6 +80,7 @@ class StableDiffusionProcessing: self.extra_generation_params: dict = extra_generation_params or {} self.overlay_images = overlay_images self.eta = eta + self.do_not_reload_embeddings = do_not_reload_embeddings self.paste_to = None self.color_corrections = None self.denoising_strength: float = 0 @@ -364,7 +365,7 @@ def process_images(p: StableDiffusionProcessing) -> Processed: def infotext(iteration=0, position_in_batch=0): return create_infotext(p, all_prompts, all_seeds, all_subseeds, comments, iteration, position_in_batch) - if os.path.exists(cmd_opts.embeddings_dir): + if os.path.exists(cmd_opts.embeddings_dir) and not p.do_not_reload_embeddings: model_hijack.embedding_db.load_textual_inversion_embeddings() infotexts = [] diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py index 2ed345b1..7ec75018 100644 --- a/modules/textual_inversion/textual_inversion.py +++ b/modules/textual_inversion/textual_inversion.py @@ -296,6 +296,7 @@ def train_embedding(embedding_name, learn_rate, batch_size, data_root, log_direc sd_model=shared.sd_model, do_not_save_grid=True, do_not_save_samples=True, + do_not_reload_embeddings=True, ) if preview_from_txt2img: From 2ce27728f6433911274efa67856315d22df56629 Mon Sep 17 00:00:00 2001 From: winterspringsummer Date: Sun, 16 Oct 2022 13:50:55 +0900 Subject: [PATCH 02/15] added extras batch work from directory --- modules/extras.py | 23 ++++++++++++++++++----- modules/ui.py | 12 ++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/modules/extras.py b/modules/extras.py index f2f5a7b0..5b52b27d 100644 --- a/modules/extras.py +++ b/modules/extras.py @@ -20,26 +20,38 @@ import gradio as gr cached_images = {} -def run_extras(extras_mode, resize_mode, image, image_folder, gfpgan_visibility, codeformer_visibility, codeformer_weight, upscaling_resize, upscaling_resize_w, upscaling_resize_h, upscaling_crop, extras_upscaler_1, extras_upscaler_2, extras_upscaler_2_visibility): +def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_dir, show_extras_results, gfpgan_visibility, codeformer_visibility, codeformer_weight, upscaling_resize, upscaling_resize_w, upscaling_resize_h, upscaling_crop, extras_upscaler_1, extras_upscaler_2, extras_upscaler_2_visibility): devices.torch_gc() imageArr = [] # Also keep track of original file names imageNameArr = [] - + outputs = [] + if extras_mode == 1: #convert file to pillow image for img in image_folder: image = Image.open(img) imageArr.append(image) imageNameArr.append(os.path.splitext(img.orig_name)[0]) + elif extras_mode == 2: + if input_dir == '': + return outputs, "Please select an input directory.", '' + image_list = [file for file in [os.path.join(input_dir, x) for x in os.listdir(input_dir)] if os.path.isfile(file)] + for img in image_list: + image = Image.open(img) + imageArr.append(image) + imageNameArr.append(img) else: imageArr.append(image) imageNameArr.append(None) - outpath = opts.outdir_samples or opts.outdir_extras_samples + if extras_mode == 2 and output_dir != '': + outpath = output_dir + else: + outpath = opts.outdir_samples or opts.outdir_extras_samples - outputs = [] + for image, image_name in zip(imageArr, imageNameArr): if image is None: return outputs, "Please select an input image.", '' @@ -112,7 +124,8 @@ def run_extras(extras_mode, resize_mode, image, image_folder, gfpgan_visibility, image.info = existing_pnginfo image.info["extras"] = info - outputs.append(image) + if extras_mode != 2 or show_extras_results : + outputs.append(image) devices.torch_gc() diff --git a/modules/ui.py b/modules/ui.py index b867d40f..08fa72c6 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1016,6 +1016,15 @@ def create_ui(wrap_gradio_gpu_call): with gr.TabItem('Batch Process'): image_batch = gr.File(label="Batch Process", file_count="multiple", interactive=True, type="file") + with gr.TabItem('Batch from Directory'): + extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, + placeholder="A directory on the same machine where the server is running." + ) + extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, + placeholder="Leave blank to save images to the default path." + ) + show_extras_results = gr.Checkbox(label='Show result images', value=True) + with gr.Tabs(elem_id="extras_resize_mode"): with gr.TabItem('Scale by'): upscaling_resize = gr.Slider(minimum=1.0, maximum=4.0, step=0.05, label="Resize", value=2) @@ -1060,6 +1069,9 @@ def create_ui(wrap_gradio_gpu_call): dummy_component, extras_image, image_batch, + extras_batch_input_dir, + extras_batch_output_dir, + show_extras_results, gfpgan_visibility, codeformer_visibility, codeformer_weight, From 179e3ca752d0133470fd3ae44153ee0b71450c9f Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Sun, 16 Oct 2022 09:51:01 +0300 Subject: [PATCH 03/15] honor --hide-ui-dir-config option for #2807 --- modules/extras.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/extras.py b/modules/extras.py index 5b52b27d..0819ed37 100644 --- a/modules/extras.py +++ b/modules/extras.py @@ -35,6 +35,8 @@ def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_ imageArr.append(image) imageNameArr.append(os.path.splitext(img.orig_name)[0]) elif extras_mode == 2: + assert not shared.cmd_opts.hide_ui_dir_config, '--hide-ui-dir-config option must be disabled' + if input_dir == '': return outputs, "Please select an input directory.", '' image_list = [file for file in [os.path.join(input_dir, x) for x in os.listdir(input_dir)] if os.path.isfile(file)] From 3395ba493f93214cf037d084d45693a37610bd85 Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Sun, 16 Oct 2022 09:24:01 +0900 Subject: [PATCH 04/15] Allow specifying the region of ngrok. --- modules/ngrok.py | 8 +++++--- modules/shared.py | 1 + modules/ui.py | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/ngrok.py b/modules/ngrok.py index 7d03a6df..5c5f349a 100644 --- a/modules/ngrok.py +++ b/modules/ngrok.py @@ -1,12 +1,14 @@ from pyngrok import ngrok, conf, exception -def connect(token, port): +def connect(token, port, region): if token == None: token = 'None' - conf.get_default().auth_token = token + config = conf.PyngrokConfig( + auth_token=token, region=region + ) try: - public_url = ngrok.connect(port).public_url + public_url = ngrok.connect(port, pyngrok_config=config).public_url except exception.PyngrokNgrokError: print(f'Invalid ngrok authtoken, ngrok connection aborted.\n' f'Your token: {token}, get the right one on https://dashboard.ngrok.com/get-started/your-authtoken') diff --git a/modules/shared.py b/modules/shared.py index fa30bbb0..dcab0af9 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -40,6 +40,7 @@ parser.add_argument("--unload-gfpgan", action='store_true', help="does not do an parser.add_argument("--precision", type=str, help="evaluate at this precision", choices=["full", "autocast"], default="autocast") parser.add_argument("--share", action='store_true', help="use share=True for gradio and make the UI accessible through their site (doesn't work for me but you might have better luck)") parser.add_argument("--ngrok", type=str, help="ngrok authtoken, alternative to gradio --share", default=None) +parser.add_argument("--ngrok-region", type=str, help="The region in which ngrok should start.", default="us") parser.add_argument("--codeformer-models-path", type=str, help="Path to directory with codeformer model file(s).", default=os.path.join(models_path, 'Codeformer')) parser.add_argument("--gfpgan-models-path", type=str, help="Path to directory with GFPGAN model file(s).", default=os.path.join(models_path, 'GFPGAN')) parser.add_argument("--esrgan-models-path", type=str, help="Path to directory with ESRGAN model file(s).", default=os.path.join(models_path, 'ESRGAN')) diff --git a/modules/ui.py b/modules/ui.py index 08fa72c6..5c0eaf73 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -56,7 +56,7 @@ if not cmd_opts.share and not cmd_opts.listen: if cmd_opts.ngrok != None: import modules.ngrok as ngrok print('ngrok authtoken detected, trying to connect...') - ngrok.connect(cmd_opts.ngrok, cmd_opts.port if cmd_opts.port != None else 7860) + ngrok.connect(cmd_opts.ngrok, cmd_opts.port if cmd_opts.port != None else 7860, cmd_opts.ngrok_region) def gr_show(visible=True): From 20bf99052a9d50b5f99d199f4c449ef1ddd6e3cb Mon Sep 17 00:00:00 2001 From: CookieHCl Date: Sun, 16 Oct 2022 04:47:03 +0900 Subject: [PATCH 05/15] Make style configurable in ui-config.json --- modules/ui.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/ui.py b/modules/ui.py index 5c0eaf73..78096f27 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -508,9 +508,11 @@ def create_toprow(is_img2img): with gr.Row(): with gr.Column(scale=1, elem_id="style_pos_col"): prompt_style = gr.Dropdown(label="Style 1", elem_id=f"{id_part}_style_index", choices=[k for k, v in shared.prompt_styles.styles.items()], value=next(iter(shared.prompt_styles.styles.keys()))) + prompt_style.save_to_config = True with gr.Column(scale=1, elem_id="style_neg_col"): prompt_style2 = gr.Dropdown(label="Style 2", elem_id=f"{id_part}_style2_index", choices=[k for k, v in shared.prompt_styles.styles.items()], value=next(iter(shared.prompt_styles.styles.keys()))) + prompt_style2.save_to_config = True return prompt, roll, prompt_style, negative_prompt, prompt_style2, submit, button_interrogate, button_deepbooru, prompt_style_apply, save_style, paste, token_counter, token_button @@ -1739,6 +1741,11 @@ Requested path was: {f} if type(x) == gr.Number: apply_field(x, 'value') + # Since there are many dropdowns that shouldn't be saved, + # we only mark dropdowns that should be saved. + if type(x) == gr.Dropdown and getattr(x, 'save_to_config', False): + apply_field(x, 'value') + visit(txt2img_interface, loadsave, "txt2img") visit(img2img_interface, loadsave, "img2img") visit(extras_interface, loadsave, "extras") From b65a3101ce82b42b4ccc525044548e66cc44ae4a Mon Sep 17 00:00:00 2001 From: CookieHCl Date: Sun, 16 Oct 2022 04:54:53 +0900 Subject: [PATCH 06/15] Use default value when dropdown ui setting is bad Default value is the first value of selectables. Particually, None in styles. --- modules/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui.py b/modules/ui.py index 78096f27..c8e68bd6 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1744,7 +1744,7 @@ Requested path was: {f} # Since there are many dropdowns that shouldn't be saved, # we only mark dropdowns that should be saved. if type(x) == gr.Dropdown and getattr(x, 'save_to_config', False): - apply_field(x, 'value') + apply_field(x, 'value', lambda val: val in x.choices) visit(txt2img_interface, loadsave, "txt2img") visit(img2img_interface, loadsave, "img2img") From 9258a33e3755c76922cd47a03cd59419b6426304 Mon Sep 17 00:00:00 2001 From: CookieHCl Date: Sun, 16 Oct 2022 05:09:11 +0900 Subject: [PATCH 07/15] Warn when user uses bad ui setting --- modules/ui.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/ui.py b/modules/ui.py index c8e68bd6..10bdf121 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1717,7 +1717,9 @@ Requested path was: {f} saved_value = ui_settings.get(key, None) if saved_value is None: ui_settings[key] = getattr(obj, field) - elif condition is None or condition(saved_value): + elif condition and not condition(saved_value): + print(f'Warning: Bad ui setting value: {key}: {saved_value}; Default value "{getattr(obj, field)}" will be used instead.') + else: setattr(obj, field, saved_value) if type(x) in [gr.Slider, gr.Radio, gr.Checkbox, gr.Textbox, gr.Number] and x.visible: From 863e9efc19d2811f1db5055be8e346781df3f7ce Mon Sep 17 00:00:00 2001 From: Zeithrold <41533799+zeithrold@users.noreply.github.com> Date: Sun, 16 Oct 2022 15:13:18 +0800 Subject: [PATCH 08/15] Pull out some of URL to Env Variable (#2578) * moved repository url to changeable environment variable * move stable diffusion repo itself to env * added missing env * Remove default URL Co-authored-by: AUTOMATIC1111 <16777216c@gmail.com> --- launch.py | 23 ++++++++++++++++------- webui-user.sh | 20 +++++++++++++++++++- webui.sh | 7 ++++++- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/launch.py b/launch.py index 2e6b3369..7520cfee 100644 --- a/launch.py +++ b/launch.py @@ -94,6 +94,15 @@ def prepare_enviroment(): gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379") clip_package = os.environ.get('CLIP_PACKAGE', "git+https://github.com/openai/CLIP.git@d50d76daa670286dd6cacf3bcd80b5e4823fc8e1") + deepdanbooru_package = os.environ.get('DEEPDANBOORU_PACKAGE', "git+https://github.com/KichangKim/DeepDanbooru.git@edf73df4cdaeea2cf00e9ac08bd8a9026b7a7b26") + + xformers_windows_package = os.environ.get('XFORMERS_WINDOWS_PACKAGE', 'https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/f/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl') + + stable_diffusion_repo = os.environ.get('STABLE_DIFFUSION_REPO', "https://github.com/CompVis/stable-diffusion.git") + taming_transformers_repo = os.environ.get('TAMING_REANSFORMERS_REPO', "https://github.com/CompVis/taming-transformers.git") + k_diffusion_repo = os.environ.get('K_DIFFUSION_REPO', 'https://github.com/crowsonkb/k-diffusion.git') + codeformer_repo = os.environ.get('CODEFORMET_REPO', 'https://github.com/sczhou/CodeFormer.git') + blip_repo = os.environ.get('BLIP_REPO', 'https://github.com/salesforce/BLIP.git') stable_diffusion_commit_hash = os.environ.get('STABLE_DIFFUSION_COMMIT_HASH', "69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc") taming_transformers_commit_hash = os.environ.get('TAMING_TRANSFORMERS_COMMIT_HASH', "24268930bf1dce879235a7fddd0b2355b84d7ea6") @@ -131,23 +140,23 @@ def prepare_enviroment(): if (not is_installed("xformers") or reinstall_xformers) and xformers and platform.python_version().startswith("3.10"): if platform.system() == "Windows": - run_pip("install -U -I --no-deps https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/f/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl", "xformers") + run_pip(f"install -U -I --no-deps {xformers_windows_package}", "xformers") elif platform.system() == "Linux": run_pip("install xformers", "xformers") if not is_installed("deepdanbooru") and deepdanbooru: - run_pip("install git+https://github.com/KichangKim/DeepDanbooru.git@edf73df4cdaeea2cf00e9ac08bd8a9026b7a7b26#egg=deepdanbooru[tensorflow] tensorflow==2.10.0 tensorflow-io==0.27.0", "deepdanbooru") + run_pip(f"install {deepdanbooru_package}#egg=deepdanbooru[tensorflow] tensorflow==2.10.0 tensorflow-io==0.27.0", "deepdanbooru") if not is_installed("pyngrok") and ngrok: run_pip("install pyngrok", "ngrok") os.makedirs(dir_repos, exist_ok=True) - git_clone("https://github.com/CompVis/stable-diffusion.git", repo_dir('stable-diffusion'), "Stable Diffusion", stable_diffusion_commit_hash) - git_clone("https://github.com/CompVis/taming-transformers.git", repo_dir('taming-transformers'), "Taming Transformers", taming_transformers_commit_hash) - git_clone("https://github.com/crowsonkb/k-diffusion.git", repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash) - git_clone("https://github.com/sczhou/CodeFormer.git", repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash) - git_clone("https://github.com/salesforce/BLIP.git", repo_dir('BLIP'), "BLIP", blip_commit_hash) + git_clone(stable_diffusion_repo, repo_dir('stable-diffusion'), "Stable Diffusion", stable_diffusion_commit_hash) + git_clone(taming_transformers_repo, repo_dir('taming-transformers'), "Taming Transformers", taming_transformers_commit_hash) + git_clone(k_diffusion_repo, repo_dir('k-diffusion'), "K-diffusion", k_diffusion_commit_hash) + git_clone(codeformer_repo, repo_dir('CodeFormer'), "CodeFormer", codeformer_commit_hash) + git_clone(blip_repo, repo_dir('BLIP'), "BLIP", blip_commit_hash) if not is_installed("lpips"): run_pip(f"install -r {os.path.join(repo_dir('CodeFormer'), 'requirements.txt')}", "requirements for CodeFormer") diff --git a/webui-user.sh b/webui-user.sh index 30646f5c..96293d43 100644 --- a/webui-user.sh +++ b/webui-user.sh @@ -12,6 +12,8 @@ # Commandline arguments for webui.py, for example: export COMMANDLINE_ARGS="--medvram --opt-split-attention" export COMMANDLINE_ARGS="" +#export STABLE_DIFFUSION_WEBUI_REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git" + # python3 executable #python_cmd="python3" @@ -30,13 +32,29 @@ export COMMANDLINE_ARGS="" # Requirements file to use for stable-diffusion-webui #export REQS_FILE="requirements_versions.txt" -# Fixed git repos +# Fixed git-based pip packages +# Example: "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379" #export K_DIFFUSION_PACKAGE="" + #export GFPGAN_PACKAGE="" +#export DEEPDANBOORU_PACKAGE="" +#export CLIP_PACKAGE="" + +#export XFORMERS_WINDOWS_PACKAGE="" + +# Fixed git repos +# Example: "https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/c/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl" +#export STABLE_DIFFUSION_REPO="" +#export TAMING_REANSFORMERS_REPO="" +#export K_DIFFUSION_REPO="" +#export CODEFORMET_REPO="" +#export BLIP_REPO="" # Fixed git commits +# Example: "69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc" #export STABLE_DIFFUSION_COMMIT_HASH="" #export TAMING_TRANSFORMERS_COMMIT_HASH="" +#export K_DIFFUSION_COMMIT_HASH="" #export CODEFORMER_COMMIT_HASH="" #export BLIP_COMMIT_HASH="" diff --git a/webui.sh b/webui.sh index 980c0aaf..88a78459 100755 --- a/webui.sh +++ b/webui.sh @@ -41,6 +41,11 @@ then venv_dir="venv" fi +if [[ -z "${STABLE_DIFFUSION_WEBUI_REPO}" ]] +then + STABLE_DIFFUSION_WEBUI_REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git" +fi + if [[ -z "${LAUNCH_SCRIPT}" ]] then LAUNCH_SCRIPT="launch.py" @@ -111,7 +116,7 @@ then cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; } "${GIT}" pull else - "${GIT}" clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git "${clone_dir}" + "${GIT}" clone "${STABLE_DIFFUSION_WEBUI_REPO}" "${clone_dir}" cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; } fi From bd4f0fb9d9df72899c2c3a1c2bc3580bf26bb685 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Sun, 16 Oct 2022 10:14:27 +0300 Subject: [PATCH 09/15] revert changes to two bat files I asked to revert but the author couldn't in 863e9efc19d2811f1db5055be8e346781df3f7ce. --- webui-user.sh | 22 ++-------------------- webui.sh | 7 +------ 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/webui-user.sh b/webui-user.sh index 96293d43..30646f5c 100644 --- a/webui-user.sh +++ b/webui-user.sh @@ -12,8 +12,6 @@ # Commandline arguments for webui.py, for example: export COMMANDLINE_ARGS="--medvram --opt-split-attention" export COMMANDLINE_ARGS="" -#export STABLE_DIFFUSION_WEBUI_REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git" - # python3 executable #python_cmd="python3" @@ -32,29 +30,13 @@ export COMMANDLINE_ARGS="" # Requirements file to use for stable-diffusion-webui #export REQS_FILE="requirements_versions.txt" -# Fixed git-based pip packages -# Example: "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379" -#export K_DIFFUSION_PACKAGE="" - -#export GFPGAN_PACKAGE="" -#export DEEPDANBOORU_PACKAGE="" -#export CLIP_PACKAGE="" - -#export XFORMERS_WINDOWS_PACKAGE="" - # Fixed git repos -# Example: "https://github.com/C43H66N12O12S2/stable-diffusion-webui/releases/download/c/xformers-0.0.14.dev0-cp310-cp310-win_amd64.whl" -#export STABLE_DIFFUSION_REPO="" -#export TAMING_REANSFORMERS_REPO="" -#export K_DIFFUSION_REPO="" -#export CODEFORMET_REPO="" -#export BLIP_REPO="" +#export K_DIFFUSION_PACKAGE="" +#export GFPGAN_PACKAGE="" # Fixed git commits -# Example: "69ae4b35e0a0f6ee1af8bb9a5d0016ccb27e36dc" #export STABLE_DIFFUSION_COMMIT_HASH="" #export TAMING_TRANSFORMERS_COMMIT_HASH="" -#export K_DIFFUSION_COMMIT_HASH="" #export CODEFORMER_COMMIT_HASH="" #export BLIP_COMMIT_HASH="" diff --git a/webui.sh b/webui.sh index 88a78459..980c0aaf 100755 --- a/webui.sh +++ b/webui.sh @@ -41,11 +41,6 @@ then venv_dir="venv" fi -if [[ -z "${STABLE_DIFFUSION_WEBUI_REPO}" ]] -then - STABLE_DIFFUSION_WEBUI_REPO="https://github.com/AUTOMATIC1111/stable-diffusion-webui.git" -fi - if [[ -z "${LAUNCH_SCRIPT}" ]] then LAUNCH_SCRIPT="launch.py" @@ -116,7 +111,7 @@ then cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; } "${GIT}" pull else - "${GIT}" clone "${STABLE_DIFFUSION_WEBUI_REPO}" "${clone_dir}" + "${GIT}" clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git "${clone_dir}" cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; } fi From 36a0ba357ab0742c3c4a28437b68fb29a235afbe Mon Sep 17 00:00:00 2001 From: Junpeng Qiu Date: Sat, 15 Oct 2022 21:42:52 -0700 Subject: [PATCH 10/15] Added Refresh Button to embedding and hypernetwork names in Train Tab Problem everytime I modified pt files in embedding_dir or hypernetwork_dir, I need to restart webui to have the new files shown in the dropdown of Train Tab Solution refactored create_refresh_button out of create_setting_component so we can use this method to create button next to gr.Dropdowns of embedding name and hypernetworks Extra Modification hypernetwork pt are now sorted in alphabetic order --- modules/ui.py | 45 ++++++++++++++++++++++++++------------------- style.css | 2 +- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/modules/ui.py b/modules/ui.py index 10bdf121..ee3d0248 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -568,6 +568,24 @@ def create_ui(wrap_gradio_gpu_call): import modules.img2img import modules.txt2img + def create_refresh_button(refresh_component, refresh_method, refreshed_args, elem_id): + def refresh(): + refresh_method() + args = refreshed_args() if callable(refreshed_args) else refreshed_args + + for k, v in args.items(): + setattr(refresh_component, k, v) + + return gr.update(**(args or {})) + + refresh_button = gr.Button(value=refresh_symbol, elem_id=elem_id) + refresh_button.click( + fn = refresh, + inputs = [], + outputs = [refresh_component] + ) + return refresh_button + with gr.Blocks(analytics_enabled=False) as txt2img_interface: txt2img_prompt, roll, txt2img_prompt_style, txt2img_negative_prompt, txt2img_prompt_style2, submit, _, _, txt2img_prompt_style_apply, txt2img_save_style, txt2img_paste, token_counter, token_button = create_toprow(is_img2img=False) dummy_component = gr.Label(visible=False) @@ -1205,8 +1223,12 @@ def create_ui(wrap_gradio_gpu_call): with gr.Tab(label="Train"): gr.HTML(value="

Train an embedding; must specify a directory with a set of 1:1 ratio images

") - train_embedding_name = gr.Dropdown(label='Embedding', choices=sorted(sd_hijack.model_hijack.embedding_db.word_embeddings.keys())) - train_hypernetwork_name = gr.Dropdown(label='Hypernetwork', choices=[x for x in shared.hypernetworks.keys()]) + with gr.Row(): + train_embedding_name = gr.Dropdown(label='Embedding', choices=sorted(sd_hijack.model_hijack.embedding_db.word_embeddings.keys())) + create_refresh_button(train_embedding_name, sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings, lambda: {"choices": sorted(sd_hijack.model_hijack.embedding_db.word_embeddings.keys())}, "refresh_train_embedding_name") + with gr.Row(): + train_hypernetwork_name = gr.Dropdown(label='Hypernetwork', choices=[x for x in shared.hypernetworks.keys()]) + create_refresh_button(train_hypernetwork_name, shared.reload_hypernetworks, lambda: {"choices": sorted([x for x in shared.hypernetworks.keys()])}, "refresh_train_hypernetwork_name") learn_rate = gr.Textbox(label='Learning rate', placeholder="Learning rate", value="0.005") batch_size = gr.Number(label='Batch size', value=1, precision=0) dataset_directory = gr.Textbox(label='Dataset directory', placeholder="Path to directory with input images") @@ -1357,26 +1379,11 @@ def create_ui(wrap_gradio_gpu_call): if info.refresh is not None: if is_quicksettings: res = comp(label=info.label, value=fun, **(args or {})) - refresh_button = gr.Button(value=refresh_symbol, elem_id="refresh_"+key) + refresh_button = create_refresh_button(res, info.refresh, info.component_args, "refresh_" + key) else: with gr.Row(variant="compact"): res = comp(label=info.label, value=fun, **(args or {})) - refresh_button = gr.Button(value=refresh_symbol, elem_id="refresh_" + key) - - def refresh(): - info.refresh() - refreshed_args = info.component_args() if callable(info.component_args) else info.component_args - - for k, v in refreshed_args.items(): - setattr(res, k, v) - - return gr.update(**(refreshed_args or {})) - - refresh_button.click( - fn=refresh, - inputs=[], - outputs=[res], - ) + refresh_button = create_refresh_button(res, info.refresh, info.component_args, "refresh_" + key) else: res = comp(label=info.label, value=fun, **(args or {})) diff --git a/style.css b/style.css index 33832ebf..71eb4d20 100644 --- a/style.css +++ b/style.css @@ -478,7 +478,7 @@ input[type="range"]{ padding: 0; } -#refresh_sd_model_checkpoint, #refresh_sd_hypernetwork{ +#refresh_sd_model_checkpoint, #refresh_sd_hypernetwork, #refresh_train_hypernetwork_name, #refresh_train_embedding_name{ max-width: 2.5em; min-width: 2.5em; height: 2.4em; From 91235d8008372862b1f232f7bf99da310a5955e4 Mon Sep 17 00:00:00 2001 From: CookieHCl Date: Sun, 16 Oct 2022 20:50:24 +0900 Subject: [PATCH 11/15] Fix FileNotFoundError in history tab Now only traverse images when directory exists --- modules/images_history.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/images_history.py b/modules/images_history.py index 9260df8a..e6284142 100644 --- a/modules/images_history.py +++ b/modules/images_history.py @@ -1,6 +1,6 @@ import os import shutil - +import sys def traverse_all_files(output_dir, image_list, curr_dir=None): curr_path = output_dir if curr_dir is None else os.path.join(output_dir, curr_dir) @@ -24,10 +24,14 @@ def traverse_all_files(output_dir, image_list, curr_dir=None): def get_recent_images(dir_name, page_index, step, image_index, tabname): page_index = int(page_index) - f_list = os.listdir(dir_name) image_list = [] - image_list = traverse_all_files(dir_name, image_list) - image_list = sorted(image_list, key=lambda file: -os.path.getctime(os.path.join(dir_name, file))) + if not os.path.exists(dir_name): + pass + elif os.path.isdir(dir_name): + image_list = traverse_all_files(dir_name, image_list) + image_list = sorted(image_list, key=lambda file: -os.path.getctime(os.path.join(dir_name, file))) + else: + print(f"ERROR: {dir_name} is not a directory. Check the path in the settings.", file=sys.stderr) num = 48 if tabname != "extras" else 12 max_page_index = len(image_list) // num + 1 page_index = max_page_index if page_index == -1 else page_index + step From c9836279f58461e04c1dda0a86e718f8bd3f41e4 Mon Sep 17 00:00:00 2001 From: CookieHCl Date: Sun, 16 Oct 2022 21:59:05 +0900 Subject: [PATCH 12/15] Only make output dir when creating output --- modules/processing.py | 6 ------ modules/ui.py | 5 ++++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/processing.py b/modules/processing.py index 833fed8a..deb6125e 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -334,12 +334,6 @@ def process_images(p: StableDiffusionProcessing) -> Processed: seed = get_fixed_seed(p.seed) subseed = get_fixed_seed(p.subseed) - if p.outpath_samples is not None: - os.makedirs(p.outpath_samples, exist_ok=True) - - if p.outpath_grids is not None: - os.makedirs(p.outpath_grids, exist_ok=True) - modules.sd_hijack.model_hijack.apply_circular(p.tiling) modules.sd_hijack.model_hijack.clear_comments() diff --git a/modules/ui.py b/modules/ui.py index ee3d0248..fa73627a 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1394,7 +1394,10 @@ def create_ui(wrap_gradio_gpu_call): component_dict = {} def open_folder(f): - if not os.path.isdir(f): + if not os.path.exists(f): + print(f"{f} doesn't exist. After you create an image, the folder will be created.") + return + elif not os.path.isdir(f): print(f""" WARNING An open_folder request was made with an argument that is not a folder. From adc0ea74e1ee9791f15c3a74bc6c5ad789e10d17 Mon Sep 17 00:00:00 2001 From: CookieHCl Date: Sun, 16 Oct 2022 22:03:18 +0900 Subject: [PATCH 13/15] Better readablity of logs --- modules/images_history.py | 2 +- modules/ui.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/images_history.py b/modules/images_history.py index e6284142..e06e07bf 100644 --- a/modules/images_history.py +++ b/modules/images_history.py @@ -31,7 +31,7 @@ def get_recent_images(dir_name, page_index, step, image_index, tabname): image_list = traverse_all_files(dir_name, image_list) image_list = sorted(image_list, key=lambda file: -os.path.getctime(os.path.join(dir_name, file))) else: - print(f"ERROR: {dir_name} is not a directory. Check the path in the settings.", file=sys.stderr) + print(f'ERROR: "{dir_name}" is not a directory. Check the path in the settings.', file=sys.stderr) num = 48 if tabname != "extras" else 12 max_page_index = len(image_list) // num + 1 page_index = max_page_index if page_index == -1 else page_index + step diff --git a/modules/ui.py b/modules/ui.py index fa73627a..7b0d5a92 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1395,7 +1395,7 @@ def create_ui(wrap_gradio_gpu_call): def open_folder(f): if not os.path.exists(f): - print(f"{f} doesn't exist. After you create an image, the folder will be created.") + print(f'Folder "{f}" does not exist. After you create an image, the folder will be created.') return elif not os.path.isdir(f): print(f""" From fc220a51cf5bb5bfca83322c16e907a18ec59f6b Mon Sep 17 00:00:00 2001 From: DancingSnow <1121149616@qq.com> Date: Sun, 16 Oct 2022 10:49:21 +0800 Subject: [PATCH 14/15] fix dir_path in some path like `D:/Pic/outputs` --- modules/images_history.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/images_history.py b/modules/images_history.py index e06e07bf..46b23e56 100644 --- a/modules/images_history.py +++ b/modules/images_history.py @@ -109,10 +109,8 @@ def show_images_history(gr, opts, tabname, run_pnginfo, switch_dict): dir_name = opts.outdir_img2img_samples elif tabname == "extras": dir_name = opts.outdir_extras_samples - d = dir_name.split("/") - dir_name = "/" if dir_name.startswith("/") else d[0] - for p in d[1:]: - dir_name = os.path.join(dir_name, p) + else: + return with gr.Row(): renew_page = gr.Button('Renew Page', elem_id=tabname + "_images_history_renew_page") first_page = gr.Button('First Page') From c57919ea2a8e4a23a05d21f28928e08bbf34c59e Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Sun, 16 Oct 2022 17:22:56 +0300 Subject: [PATCH 15/15] keep focus on current element when updating gallery --- javascript/progressbar.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/javascript/progressbar.js b/javascript/progressbar.js index 076f0a97..c7d0343f 100644 --- a/javascript/progressbar.js +++ b/javascript/progressbar.js @@ -34,7 +34,7 @@ function check_progressbar(id_part, id_progressbar, id_progressbar_span, id_skip preview.style.height = gallery.clientHeight + "px" //only watch gallery if there is a generation process going on - check_gallery(id_gallery); + check_gallery(id_gallery); var progressDiv = gradioApp().querySelectorAll('#' + id_progressbar_span).length > 0; if(!progressDiv){ @@ -73,8 +73,10 @@ function check_gallery(id_gallery){ let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2') if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) { //automatically re-open previously selected index (if exists) + activeElement = document.activeElement; galleryButtons[prevSelectedIndex].click(); - showGalleryImage(); + showGalleryImage(); + if(activeElement) activeElement.focus() } }) galleryObservers[id_gallery].observe( gallery, { childList:true, subtree:false })