From 13fd466c181e9d4e29eaa2430749ea35d5265393 Mon Sep 17 00:00:00 2001 From: w-e-w <40751091+w-e-w@users.noreply.github.com> Date: Mon, 12 Feb 2024 04:07:14 +0900 Subject: [PATCH 01/15] fix extra-network-control--enabled color also add forgotten semicolon --- style.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/style.css b/style.css index 988c28c0..a6b287b9 100644 --- a/style.css +++ b/style.css @@ -851,13 +851,13 @@ table.popup-table .link{ #extensions tr:hover td, #config_state_extensions tr:hover td, #available_extensions tr:hover td { - background: rgba(0, 0, 0, 0.15) + background: rgba(0, 0, 0, 0.15); } .dark #extensions tr:hover td , .dark #config_state_extensions tr:hover td , .dark #available_extensions tr:hover td { - background: rgba(255, 255, 255, 0.15) + background: rgba(255, 255, 255, 0.15); } /* replace original footer with ours */ @@ -1513,12 +1513,12 @@ body.resizing .resize-handle { background-color: var(--input-placeholder-color); } -.dark .extra-network-control .extra-network-control--enabled { - background-color: var(--neutral-700); +.extra-network-control .extra-network-control--enabled { + background-color: rgba(0, 0, 0, 0.15); } .dark .extra-network-control .extra-network-control--enabled { - background-color: var(--neutral-300); + background-color: rgba(255, 255, 255, 0.15); } /* ==== REFRESH ICON ACTIONS ==== */ From 69f9564a6db8ced1b5fbfc7f20c644abd54fca11 Mon Sep 17 00:00:00 2001 From: analysisjp Date: Tue, 13 Feb 2024 21:49:23 +0900 Subject: [PATCH 02/15] fixed webui.sh issue that occurred in WSL environment (fix: #14883) --- webui.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/webui.sh b/webui.sh index 794cfb8a..f116376f 100755 --- a/webui.sh +++ b/webui.sh @@ -227,9 +227,7 @@ fi prepare_tcmalloc() { if [[ "${OSTYPE}" == "linux"* ]] && [[ -z "${NO_TCMALLOC}" ]] && [[ -z "${LD_PRELOAD}" ]]; then # check glibc version - LIBC_LIB="$(PATH=/usr/sbin:$PATH ldconfig -p | grep -P "libc.so.6" | head -n 1)" - LIBC_INFO=$(echo ${LIBC_LIB} | awk '{print $NF}') - LIBC_VER=$(echo $(${LIBC_INFO} | awk 'NR==1 {print $NF}') | grep -oP '\d+\.\d+') + LIBC_VER=$(echo $(ldd --version | awk 'NR==1 {print $NF}') | grep -oP '\d+\.\d+') echo "glibc version is $LIBC_VER" libc_vernum=$(expr $LIBC_VER) # Since 2.34 libpthread is integrated into libc.so @@ -244,9 +242,9 @@ prepare_tcmalloc() { TC_INFO=(${TCMALLOC//=>/}) if [[ ! -z "${TC_INFO}" ]]; then echo "Check TCMalloc: ${TC_INFO}" - # Determine if the library is linked to libptthread and resolve undefined symbol: ptthread_key_create + # Determine if the library is linked to libpthread and resolve undefined symbol: pthread_key_create if [ $(echo "$libc_vernum < $libc_v234" | bc) -eq 1 ]; then - # glibc < 2.33 pthread_key_create into libpthead.so. check linking libpthread.so... + # glibc < 2.34 pthread_key_create into libpthread.so. check linking libpthread.so... if ldd ${TC_INFO[2]} | grep -q 'libpthread'; then echo "$TC_INFO is linked with libpthread,execute LD_PRELOAD=${TC_INFO[2]}" # set fullpath LD_PRELOAD (To be on the safe side) @@ -256,7 +254,7 @@ prepare_tcmalloc() { echo "$TC_INFO is not linked with libpthread will trigger undefined symbol: pthread_Key_create error" fi else - # Version 2.34 of libc.so (glibc) includes the pthead library IN GLIBC. (USE ubuntu 22.04 and modern linux system and WSL) + # Version 2.34 of libc.so (glibc) includes the pthread library IN GLIBC. (USE ubuntu 22.04 and modern linux system and WSL) # libc.so(glibc) is linked with a library that works in ALMOST ALL Linux userlands. SO NO CHECK! echo "$TC_INFO is linked with libc.so,execute LD_PRELOAD=${TC_INFO[2]}" # set fullpath LD_PRELOAD (To be on the safe side) @@ -266,7 +264,7 @@ prepare_tcmalloc() { fi done if [[ -z "${LD_PRELOAD}" ]]; then - printf "\e[1m\e[31mCannot locate TCMalloc. Do you have tcmalloc or gperftools installed on your system? (improves CPU memory usage)\e[0m\n" + printf "\e[1m\e[31mCannot locate TCMalloc. Do you have tcmalloc or google-perftool installed on your system? (improves CPU memory usage)\e[0m\n" fi fi } From 1142201a3a1dbfeafc25e2dee2f25eac9a1fb321 Mon Sep 17 00:00:00 2001 From: Andray Date: Wed, 14 Feb 2024 15:26:57 +0400 Subject: [PATCH 03/15] Use original App Title in progress bar --- javascript/progressbar.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/javascript/progressbar.js b/javascript/progressbar.js index 77761495..f068bac6 100644 --- a/javascript/progressbar.js +++ b/javascript/progressbar.js @@ -45,8 +45,15 @@ function formatTime(secs) { } } + +var originalAppTitle = undefined; + +onUiLoaded(function() { + originalAppTitle = document.title; +}); + function setTitle(progress) { - var title = 'Stable Diffusion'; + var title = originalAppTitle; if (opts.show_progress_in_title && progress) { title = '[' + progress.trim() + '] ' + title; From 18ec22bffea77158777c3a3225e632e25eb33138 Mon Sep 17 00:00:00 2001 From: RedDeltas <160131179+RedDeltas@users.noreply.github.com> Date: Thu, 15 Feb 2024 12:26:14 +0000 Subject: [PATCH 04/15] Added core.filemode=false so doesn't track changes in file permissions in more restrictive environments --- modules/launch_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/launch_utils.py b/modules/launch_utils.py index 107c72b0..ad04eb36 100644 --- a/modules/launch_utils.py +++ b/modules/launch_utils.py @@ -188,7 +188,7 @@ def git_clone(url, dir, name, commithash=None): return try: - run(f'"{git}" clone "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}", live=True) + run(f'"{git}" clone --config core.filemode=false "{url}" "{dir}"', f"Cloning {name} into {dir}...", f"Couldn't clone {name}", live=True) except RuntimeError: shutil.rmtree(dir, ignore_errors=True) raise From 46988af63696a232cbf94cdeaca6de32cc56e23c Mon Sep 17 00:00:00 2001 From: catboxanon <122327233+catboxanon@users.noreply.github.com> Date: Thu, 15 Feb 2024 13:05:39 -0500 Subject: [PATCH 05/15] Fix `Esc` interrupt when button not visible --- script.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/script.js b/script.js index be1bc317..25cf0973 100644 --- a/script.js +++ b/script.js @@ -167,8 +167,10 @@ document.addEventListener('keydown', function(e) { const lightboxModal = document.querySelector('#lightboxModal'); if (!globalPopup || globalPopup.style.display === 'none') { if (document.activeElement === lightboxModal) return; - interruptButton.click(); - e.preventDefault(); + if (interruptButton.style.display !== 'none') { + interruptButton.click(); + e.preventDefault(); + } } } }); From 6ee4012c0a4d16fb3a6b2a9ea80a7a4b54073193 Mon Sep 17 00:00:00 2001 From: catboxanon <122327233+catboxanon@users.noreply.github.com> Date: Thu, 15 Feb 2024 13:31:44 -0500 Subject: [PATCH 06/15] Gracefully handle mtime read exception from cache --- modules/hashes.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/hashes.py b/modules/hashes.py index b7a33b42..d22e5fad 100644 --- a/modules/hashes.py +++ b/modules/hashes.py @@ -21,7 +21,10 @@ def calculate_sha256(filename): def sha256_from_cache(filename, title, use_addnet_hash=False): hashes = cache("hashes-addnet") if use_addnet_hash else cache("hashes") - ondisk_mtime = os.path.getmtime(filename) + try: + ondisk_mtime = os.path.getmtime(filename) + except FileNotFoundError: + return None if title not in hashes: return None From 06ab10a1be812036605e1472f054228562ea08d9 Mon Sep 17 00:00:00 2001 From: catboxanon <122327233+catboxanon@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:22:13 -0500 Subject: [PATCH 07/15] Normalize cmd arg paths In particular, this fixes an issue on Windows where some functions will misbehave if forward slashes are provided rather than double backslashes. --- extensions-builtin/Lora/preload.py | 5 ++-- modules/cmd_args.py | 40 +++++++++++++++--------------- modules/paths_internal.py | 4 +++ 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/extensions-builtin/Lora/preload.py b/extensions-builtin/Lora/preload.py index 50961be3..52fab29b 100644 --- a/extensions-builtin/Lora/preload.py +++ b/extensions-builtin/Lora/preload.py @@ -1,7 +1,8 @@ import os from modules import paths +from modules.paths_internal import normalized_filepath def preload(parser): - parser.add_argument("--lora-dir", type=str, help="Path to directory with Lora networks.", default=os.path.join(paths.models_path, 'Lora')) - parser.add_argument("--lyco-dir-backcompat", type=str, help="Path to directory with LyCORIS networks (for backawards compatibility; can also use --lyco-dir).", default=os.path.join(paths.models_path, 'LyCORIS')) + parser.add_argument("--lora-dir", type=normalized_filepath, help="Path to directory with Lora networks.", default=os.path.join(paths.models_path, 'Lora')) + parser.add_argument("--lyco-dir-backcompat", type=normalized_filepath, help="Path to directory with LyCORIS networks (for backawards compatibility; can also use --lyco-dir).", default=os.path.join(paths.models_path, 'LyCORIS')) diff --git a/modules/cmd_args.py b/modules/cmd_args.py index f1251b6c..312dabff 100644 --- a/modules/cmd_args.py +++ b/modules/cmd_args.py @@ -1,7 +1,7 @@ import argparse import json import os -from modules.paths_internal import models_path, script_path, data_path, extensions_dir, extensions_builtin_dir, sd_default_config, sd_model_file # noqa: F401 +from modules.paths_internal import normalized_filepath, models_path, script_path, data_path, extensions_dir, extensions_builtin_dir, sd_default_config, sd_model_file # noqa: F401 parser = argparse.ArgumentParser() @@ -19,21 +19,21 @@ parser.add_argument("--skip-install", action='store_true', help="launch.py argum parser.add_argument("--dump-sysinfo", action='store_true', help="launch.py argument: dump limited sysinfo file (without information about extensions, options) to disk and quit") parser.add_argument("--loglevel", type=str, help="log level; one of: CRITICAL, ERROR, WARNING, INFO, DEBUG", default=None) parser.add_argument("--do-not-download-clip", action='store_true', help="do not download CLIP model even if it's not included in the checkpoint") -parser.add_argument("--data-dir", type=str, default=os.path.dirname(os.path.dirname(os.path.realpath(__file__))), help="base path where all user data is stored") -parser.add_argument("--config", type=str, default=sd_default_config, help="path to config which constructs model",) -parser.add_argument("--ckpt", type=str, default=sd_model_file, help="path to checkpoint of stable diffusion model; if specified, this checkpoint will be added to the list of checkpoints and loaded",) -parser.add_argument("--ckpt-dir", type=str, default=None, help="Path to directory with stable diffusion checkpoints") -parser.add_argument("--vae-dir", type=str, default=None, help="Path to directory with VAE files") -parser.add_argument("--gfpgan-dir", type=str, help="GFPGAN directory", default=('./src/gfpgan' if os.path.exists('./src/gfpgan') else './GFPGAN')) -parser.add_argument("--gfpgan-model", type=str, help="GFPGAN model file name", default=None) +parser.add_argument("--data-dir", type=normalized_filepath, default=os.path.dirname(os.path.dirname(os.path.realpath(__file__))), help="base path where all user data is stored") +parser.add_argument("--config", type=normalized_filepath, default=sd_default_config, help="path to config which constructs model",) +parser.add_argument("--ckpt", type=normalized_filepath, default=sd_model_file, help="path to checkpoint of stable diffusion model; if specified, this checkpoint will be added to the list of checkpoints and loaded",) +parser.add_argument("--ckpt-dir", type=normalized_filepath, default=None, help="Path to directory with stable diffusion checkpoints") +parser.add_argument("--vae-dir", type=normalized_filepath, default=None, help="Path to directory with VAE files") +parser.add_argument("--gfpgan-dir", type=normalized_filepath, help="GFPGAN directory", default=('./src/gfpgan' if os.path.exists('./src/gfpgan') else './GFPGAN')) +parser.add_argument("--gfpgan-model", type=normalized_filepath, help="GFPGAN model file name", default=None) parser.add_argument("--no-half", action='store_true', help="do not switch the model to 16-bit floats") parser.add_argument("--no-half-vae", action='store_true', help="do not switch the VAE model to 16-bit floats") parser.add_argument("--no-progressbar-hiding", action='store_true', help="do not hide progressbar in gradio UI (we hide it because it slows down ML if you have hardware acceleration in browser)") parser.add_argument("--max-batch-count", type=int, default=16, help="maximum batch count value for the UI") -parser.add_argument("--embeddings-dir", type=str, default=os.path.join(data_path, 'embeddings'), help="embeddings directory for textual inversion (default: embeddings)") -parser.add_argument("--textual-inversion-templates-dir", type=str, default=os.path.join(script_path, 'textual_inversion_templates'), help="directory with textual inversion templates") -parser.add_argument("--hypernetwork-dir", type=str, default=os.path.join(models_path, 'hypernetworks'), help="hypernetwork directory") -parser.add_argument("--localizations-dir", type=str, default=os.path.join(script_path, 'localizations'), help="localizations directory") +parser.add_argument("--embeddings-dir", type=normalized_filepath, default=os.path.join(data_path, 'embeddings'), help="embeddings directory for textual inversion (default: embeddings)") +parser.add_argument("--textual-inversion-templates-dir", type=normalized_filepath, default=os.path.join(script_path, 'textual_inversion_templates'), help="directory with textual inversion templates") +parser.add_argument("--hypernetwork-dir", type=normalized_filepath, default=os.path.join(models_path, 'hypernetworks'), help="hypernetwork directory") +parser.add_argument("--localizations-dir", type=normalized_filepath, default=os.path.join(script_path, 'localizations'), help="localizations directory") parser.add_argument("--allow-code", action='store_true', help="allow custom script execution from webui") parser.add_argument("--medvram", action='store_true', help="enable stable diffusion model optimizations for sacrificing a little speed for low VRM usage") parser.add_argument("--medvram-sdxl", action='store_true', help="enable --medvram optimization just for SDXL models") @@ -48,12 +48,12 @@ parser.add_argument("--ngrok", type=str, help="ngrok authtoken, alternative to g parser.add_argument("--ngrok-region", type=str, help="does not do anything.", default="") parser.add_argument("--ngrok-options", type=json.loads, help='The options to pass to ngrok in JSON format, e.g.: \'{"authtoken_from_env":true, "basic_auth":"user:password", "oauth_provider":"google", "oauth_allow_emails":"user@asdf.com"}\'', default=dict()) parser.add_argument("--enable-insecure-extension-access", action='store_true', help="enable extensions tab regardless of other options") -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')) -parser.add_argument("--bsrgan-models-path", type=str, help="Path to directory with BSRGAN model file(s).", default=os.path.join(models_path, 'BSRGAN')) -parser.add_argument("--realesrgan-models-path", type=str, help="Path to directory with RealESRGAN model file(s).", default=os.path.join(models_path, 'RealESRGAN')) -parser.add_argument("--clip-models-path", type=str, help="Path to directory with CLIP model file(s).", default=None) +parser.add_argument("--codeformer-models-path", type=normalized_filepath, help="Path to directory with codeformer model file(s).", default=os.path.join(models_path, 'Codeformer')) +parser.add_argument("--gfpgan-models-path", type=normalized_filepath, help="Path to directory with GFPGAN model file(s).", default=os.path.join(models_path, 'GFPGAN')) +parser.add_argument("--esrgan-models-path", type=normalized_filepath, help="Path to directory with ESRGAN model file(s).", default=os.path.join(models_path, 'ESRGAN')) +parser.add_argument("--bsrgan-models-path", type=normalized_filepath, help="Path to directory with BSRGAN model file(s).", default=os.path.join(models_path, 'BSRGAN')) +parser.add_argument("--realesrgan-models-path", type=normalized_filepath, help="Path to directory with RealESRGAN model file(s).", default=os.path.join(models_path, 'RealESRGAN')) +parser.add_argument("--clip-models-path", type=normalized_filepath, help="Path to directory with CLIP model file(s).", default=None) parser.add_argument("--xformers", action='store_true', help="enable xformers for cross attention layers") parser.add_argument("--force-enable-xformers", action='store_true', help="enable xformers for cross attention layers regardless of whether the checking code thinks you can run it; do not make bug reports if this fails to work") parser.add_argument("--xformers-flash-attention", action='store_true', help="enable xformers with Flash Attention to improve reproducibility (supported for SD2.x or variant only)") @@ -83,7 +83,7 @@ parser.add_argument("--freeze-specific-settings", type=str, help='disable editin parser.add_argument("--ui-settings-file", type=str, help="filename to use for ui settings", default=os.path.join(data_path, 'config.json')) parser.add_argument("--gradio-debug", action='store_true', help="launch gradio with --debug option") parser.add_argument("--gradio-auth", type=str, help='set gradio authentication like "username:password"; or comma-delimit multiple like "u1:p1,u2:p2,u3:p3"', default=None) -parser.add_argument("--gradio-auth-path", type=str, help='set gradio authentication file path ex. "/path/to/auth/file" same auth format as --gradio-auth', default=None) +parser.add_argument("--gradio-auth-path", type=normalized_filepath, help='set gradio authentication file path ex. "/path/to/auth/file" same auth format as --gradio-auth', default=None) parser.add_argument("--gradio-img2img-tool", type=str, help='does not do anything') parser.add_argument("--gradio-inpaint-tool", type=str, help="does not do anything") parser.add_argument("--gradio-allowed-path", action='append', help="add path to gradio's allowed_paths, make it possible to serve files from it", default=[data_path]) @@ -94,7 +94,7 @@ parser.add_argument("--theme", type=str, help="launches the UI with light or dar parser.add_argument("--use-textbox-seed", action='store_true', help="use textbox for seeds in UI (no up/down, but possible to input long seeds)", default=False) parser.add_argument("--disable-console-progressbars", action='store_true', help="do not output progressbars to console", default=False) parser.add_argument("--enable-console-prompts", action='store_true', help="does not do anything", default=False) # Legacy compatibility, use as default value shared.opts.enable_console_prompts -parser.add_argument('--vae-path', type=str, help='Checkpoint to use as VAE; setting this argument disables all settings related to VAE', default=None) +parser.add_argument('--vae-path', type=normalized_filepath, help='Checkpoint to use as VAE; setting this argument disables all settings related to VAE', default=None) parser.add_argument("--disable-safe-unpickle", action='store_true', help="disable checking pytorch models for malicious code", default=False) parser.add_argument("--api", action='store_true', help="use api=True to launch the API together with the webui (use --nowebui instead for only the API)") parser.add_argument("--api-auth", type=str, help='Set authentication for API like "username:password"; or comma-delimit multiple like "u1:p1,u2:p2,u3:p3"', default=None) diff --git a/modules/paths_internal.py b/modules/paths_internal.py index b86ecd7f..2ed1392a 100644 --- a/modules/paths_internal.py +++ b/modules/paths_internal.py @@ -4,6 +4,10 @@ import argparse import os import sys import shlex +from pathlib import Path + + +normalized_filepath = lambda filepath: str(Path(filepath).resolve()) commandline_args = os.environ.get('COMMANDLINE_ARGS', "") sys.argv += shlex.split(commandline_args) From 23f03d4796be944c36470479c41ec682f5793d9a Mon Sep 17 00:00:00 2001 From: Kohaku-Blueleaf <59680068+KohakuBlueleaf@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:43:43 +0800 Subject: [PATCH 08/15] Update extraNetworks.js --- javascript/extraNetworks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 9a3a2392..7ec6a04d 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -625,7 +625,7 @@ function scheduleAfterScriptsCallbacks() { document.addEventListener("DOMContentLoaded", function() { var mutationObserver = new MutationObserver(function(m) { if (!executedAfterScripts && - gradioApp().querySelectorAll("[id$='_extra_search']").length == 8) { + gradioApp().querySelectorAll("[id$='_extra_search']").length >= 6) { executedAfterScripts = true; scheduleAfterScriptsCallbacks(); } From 2e1b61e5903f004d2313943a5fddf13cfeff493f Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 17 Feb 2024 09:45:03 +0300 Subject: [PATCH 09/15] change condition for scheduleAfterScriptsCallbacks() to properly reflect the needed amount of search fields --- javascript/extraNetworks.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 7ec6a04d..195525b0 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -622,10 +622,13 @@ function scheduleAfterScriptsCallbacks() { }, 200); } -document.addEventListener("DOMContentLoaded", function() { +onUiLoaded(function() { var mutationObserver = new MutationObserver(function(m) { - if (!executedAfterScripts && - gradioApp().querySelectorAll("[id$='_extra_search']").length >= 6) { + let existingSearchfields = gradioApp().querySelectorAll("[id$='_extra_search']").length; + let neededSearchfields = gradioApp().querySelectorAll("[id$='_extra_tabs'] > .tab-nav > button").length - 2; + + if (!executedAfterScripts && existingSearchfields >= neededSearchfields) { + mutationObserver.disconnect(); executedAfterScripts = true; scheduleAfterScriptsCallbacks(); } From 7dae6bb3b52a33dd01ef8c11b55d20049c254a23 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 17 Feb 2024 09:45:48 +0300 Subject: [PATCH 10/15] fix search UI invisible in an extra network tab that just loaded --- javascript/extraNetworks.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 195525b0..4fd810d3 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -114,6 +114,10 @@ function setupExtraNetworksForTab(tabname) { var controls = gradioApp().querySelector("#" + tabname_full + "_controls"); controlsDiv.insertBefore(controls, null); + + if (elem.style.display != "none") { + extraNetworksShowControlsForPage(tabname, tabname_full); + } }); registerPrompt(tabname, tabname + "_prompt"); From dd1641ecc4bbbdf2c319fb32a3250a8e16dd8c77 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 17 Feb 2024 09:46:04 +0300 Subject: [PATCH 11/15] fix an exception when filtering extra networks very early --- javascript/extraNetworks.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 4fd810d3..d5855fe9 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -172,7 +172,11 @@ function extraNetworksTabSelected(tabname, id, showPrompt, showNegativePrompt, t function applyExtraNetworkFilter(tabname_full) { var doFilter = function() { - extraNetworksApplyFilter[tabname_full](true); + var applyFunction = extraNetworksApplyFilter[tabname_full]; + + if (applyFunction) { + applyFunction(true); + } }; setTimeout(doFilter, 1); } From 1466daeafc1cc9dcf0319012a6ec6129d51ebd2c Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 17 Feb 2024 10:31:16 +0300 Subject: [PATCH 12/15] Disable prompt token counters option actually disables token counting rather than just hiding results. Disable prompt token counters option does not require reload UI. token counters do not become visible until they are positioned correctly. --- .eslintrc.js | 2 -- javascript/token-counters.js | 34 +++++++++++++++++++++++----------- javascript/ui.js | 2 -- modules/shared_options.py | 2 +- modules/ui_toprow.py | 4 ++-- style.css | 4 ++++ 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index cf839769..9c70eff8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -86,8 +86,6 @@ module.exports = { // imageviewer.js modalPrevImage: "readonly", modalNextImage: "readonly", - // token-counters.js - setupTokenCounters: "readonly", // localStorage.js localSet: "readonly", localGet: "readonly", diff --git a/javascript/token-counters.js b/javascript/token-counters.js index 2ecc7d91..5d53fe47 100644 --- a/javascript/token-counters.js +++ b/javascript/token-counters.js @@ -48,11 +48,6 @@ function setupTokenCounting(id, id_counter, id_button) { var counter = gradioApp().getElementById(id_counter); var textarea = gradioApp().querySelector(`#${id} > label > textarea`); - if (opts.disable_token_counters) { - counter.style.display = "none"; - return; - } - if (counter.parentElement == prompt.parentElement) { return; } @@ -61,15 +56,32 @@ function setupTokenCounting(id, id_counter, id_button) { prompt.parentElement.style.position = "relative"; var func = onEdit(id, textarea, 800, function() { - gradioApp().getElementById(id_button)?.click(); + if(counter.classList.contains("token-counter-visible")){ + gradioApp().getElementById(id_button)?.click(); + } }); promptTokenCountUpdateFunctions[id] = func; promptTokenCountUpdateFunctions[id_button] = func; } -function setupTokenCounters() { - setupTokenCounting('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button'); - setupTokenCounting('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button'); - setupTokenCounting('img2img_prompt', 'img2img_token_counter', 'img2img_token_button'); - setupTokenCounting('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button'); +function toggleTokenCountingVisibility(id, id_counter, id_button) { + var counter = gradioApp().getElementById(id_counter); + + counter.style.display = opts.disable_token_counters ? "none" : "block"; + counter.classList.toggle("token-counter-visible", ! opts.disable_token_counters); } + +function runCodeForTokenCounters(fun){ + fun('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button'); + fun('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button'); + fun('img2img_prompt', 'img2img_token_counter', 'img2img_token_button'); + fun('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button'); +} + +onUiLoaded(function(){ + runCodeForTokenCounters(setupTokenCounting); +}); + +onOptionsChanged(function(){ + runCodeForTokenCounters(toggleTokenCountingVisibility); +}); diff --git a/javascript/ui.js b/javascript/ui.js index 9e66cd24..3d079b3d 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -319,8 +319,6 @@ onAfterUiUpdate(function() { }); json_elem.parentElement.style.display = "none"; - - setupTokenCounters(); }); onOptionsChanged(function() { diff --git a/modules/shared_options.py b/modules/shared_options.py index f1ab5d6e..e1d11c8e 100644 --- a/modules/shared_options.py +++ b/modules/shared_options.py @@ -270,7 +270,7 @@ options_templates.update(options_section(('ui_prompt_editing', "Prompt editing", "keyedit_delimiters": OptionInfo(r".,\/!?%^*;:{}=`~() ", "Word delimiters when editing the prompt with Ctrl+up/down"), "keyedit_delimiters_whitespace": OptionInfo(["Tab", "Carriage Return", "Line Feed"], "Ctrl+up/down whitespace delimiters", gr.CheckboxGroup, lambda: {"choices": ["Tab", "Carriage Return", "Line Feed"]}), "keyedit_move": OptionInfo(True, "Alt+left/right moves prompt elements"), - "disable_token_counters": OptionInfo(False, "Disable prompt token counters").needs_reload_ui(), + "disable_token_counters": OptionInfo(False, "Disable prompt token counters"), "include_styles_into_token_counters": OptionInfo(True, "Count tokens of enabled styles").info("When calculating how many tokens the prompt has, also consider tokens added by enabled styles."), })) diff --git a/modules/ui_toprow.py b/modules/ui_toprow.py index 30cf1b1b..dc3c3aa3 100644 --- a/modules/ui_toprow.py +++ b/modules/ui_toprow.py @@ -127,9 +127,9 @@ class Toprow: self.restore_progress_button = ToolButton(value=restore_progress_symbol, elem_id=f"{self.id_part}_restore_progress", visible=False, tooltip="Restore progress") - self.token_counter = gr.HTML(value="0/75", elem_id=f"{self.id_part}_token_counter", elem_classes=["token-counter"]) + self.token_counter = gr.HTML(value="0/75", elem_id=f"{self.id_part}_token_counter", elem_classes=["token-counter"], visible=False) self.token_button = gr.Button(visible=False, elem_id=f"{self.id_part}_token_button") - self.negative_token_counter = gr.HTML(value="0/75", elem_id=f"{self.id_part}_negative_token_counter", elem_classes=["token-counter"]) + self.negative_token_counter = gr.HTML(value="0/75", elem_id=f"{self.id_part}_negative_token_counter", elem_classes=["token-counter"], visible=False) self.negative_token_button = gr.Button(visible=False, elem_id=f"{self.id_part}_negative_token_button") self.clear_prompt_button.click( diff --git a/style.css b/style.css index a6b287b9..8ce78ff0 100644 --- a/style.css +++ b/style.css @@ -222,6 +222,10 @@ input[type="checkbox"].input-accordion-checkbox{ top: -0.75em; } +.block.token-counter-visible{ + display: block !important; +} + .block.token-counter span{ background: var(--input-background-fill) !important; box-shadow: 0 0 0.0 0.3em rgba(192,192,192,0.15), inset 0 0 0.6em rgba(192,192,192,0.075); From db19c46d6de32878145e051d8f30ff1ef5b2227c Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 17 Feb 2024 10:32:10 +0300 Subject: [PATCH 13/15] lint --- javascript/token-counters.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/token-counters.js b/javascript/token-counters.js index 5d53fe47..eeea7a5d 100644 --- a/javascript/token-counters.js +++ b/javascript/token-counters.js @@ -56,7 +56,7 @@ function setupTokenCounting(id, id_counter, id_button) { prompt.parentElement.style.position = "relative"; var func = onEdit(id, textarea, 800, function() { - if(counter.classList.contains("token-counter-visible")){ + if (counter.classList.contains("token-counter-visible")) { gradioApp().getElementById(id_button)?.click(); } }); @@ -68,20 +68,20 @@ function toggleTokenCountingVisibility(id, id_counter, id_button) { var counter = gradioApp().getElementById(id_counter); counter.style.display = opts.disable_token_counters ? "none" : "block"; - counter.classList.toggle("token-counter-visible", ! opts.disable_token_counters); + counter.classList.toggle("token-counter-visible", !opts.disable_token_counters); } -function runCodeForTokenCounters(fun){ +function runCodeForTokenCounters(fun) { fun('txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button'); fun('txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button'); fun('img2img_prompt', 'img2img_token_counter', 'img2img_token_button'); fun('img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button'); } -onUiLoaded(function(){ +onUiLoaded(function() { runCodeForTokenCounters(setupTokenCounting); }); -onOptionsChanged(function(){ +onOptionsChanged(function() { runCodeForTokenCounters(toggleTokenCountingVisibility); }); From 4573195894fffeae08a94c015a94772c1a54a58d Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 17 Feb 2024 11:40:53 +0300 Subject: [PATCH 14/15] prevent escape button causing an interrupt when no generation has been made yet --- script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script.js b/script.js index 25cf0973..f069b1ef 100644 --- a/script.js +++ b/script.js @@ -167,7 +167,7 @@ document.addEventListener('keydown', function(e) { const lightboxModal = document.querySelector('#lightboxModal'); if (!globalPopup || globalPopup.style.display === 'none') { if (document.activeElement === lightboxModal) return; - if (interruptButton.style.display !== 'none') { + if (interruptButton.style.display === 'block') { interruptButton.click(); e.preventDefault(); } From 4ff1fabc86db927c45642704fda3472d399f3e19 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 17 Feb 2024 13:21:08 +0300 Subject: [PATCH 15/15] Update comment for Pad prompt/negative prompt v0 to add a warning about truncation, make it override the v1 implementation --- modules/sd_samplers_cfg_denoiser.py | 6 +++--- modules/shared_options.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/sd_samplers_cfg_denoiser.py b/modules/sd_samplers_cfg_denoiser.py index 941dff4b..a73d3b03 100644 --- a/modules/sd_samplers_cfg_denoiser.py +++ b/modules/sd_samplers_cfg_denoiser.py @@ -220,10 +220,10 @@ class CFGDenoiser(torch.nn.Module): self.padded_cond_uncond = False self.padded_cond_uncond_v0 = False - if shared.opts.pad_cond_uncond and tensor.shape[1] != uncond.shape[1]: - tensor, uncond = self.pad_cond_uncond(tensor, uncond) - elif shared.opts.pad_cond_uncond_v0 and tensor.shape[1] != uncond.shape[1]: + if shared.opts.pad_cond_uncond_v0 and tensor.shape[1] != uncond.shape[1]: tensor, uncond = self.pad_cond_uncond_v0(tensor, uncond) + elif shared.opts.pad_cond_uncond and tensor.shape[1] != uncond.shape[1]: + tensor, uncond = self.pad_cond_uncond(tensor, uncond) if tensor.shape[1] == uncond.shape[1] or skip_uncond: if is_edit_model: diff --git a/modules/shared_options.py b/modules/shared_options.py index e1d11c8e..25b47aa1 100644 --- a/modules/shared_options.py +++ b/modules/shared_options.py @@ -211,7 +211,7 @@ options_templates.update(options_section(('optimizations', "Optimizations", "sd" "token_merging_ratio_img2img": OptionInfo(0.0, "Token merging ratio for img2img", gr.Slider, {"minimum": 0.0, "maximum": 0.9, "step": 0.1}).info("only applies if non-zero and overrides above"), "token_merging_ratio_hr": OptionInfo(0.0, "Token merging ratio for high-res pass", gr.Slider, {"minimum": 0.0, "maximum": 0.9, "step": 0.1}, infotext='Token merging ratio hr').info("only applies if non-zero and overrides above"), "pad_cond_uncond": OptionInfo(False, "Pad prompt/negative prompt", infotext='Pad conds').info("improves performance when prompt and negative prompt have different lengths; changes seeds"), - "pad_cond_uncond_v0": OptionInfo(False, "Pad prompt/negative prompt (v0)", infotext='Pad conds v0').info("alternative implementation for the above; used prior to 1.6.0 for DDIM sampler; ignored if the above is set; changes seeds"), + "pad_cond_uncond_v0": OptionInfo(False, "Pad prompt/negative prompt (v0)", infotext='Pad conds v0').info("alternative implementation for the above; used prior to 1.6.0 for DDIM sampler; overrides the above if set; WARNING: truncates negative prompt if it's too long; changes seeds"), "persistent_cond_cache": OptionInfo(True, "Persistent cond cache").info("do not recalculate conds from prompts if prompts have not changed since previous calculation"), "batch_cond_uncond": OptionInfo(True, "Batch cond/uncond").info("do both conditional and unconditional denoising in one batch; uses a bit more VRAM during sampling, but improves speed; previously this was controlled by --always-batch-cond-uncond comandline argument"), "fp8_storage": OptionInfo("Disable", "FP8 weight", gr.Radio, {"choices": ["Disable", "Enable for SDXL", "Enable"]}).info("Use FP8 to store Linear/Conv layers' weight. Require pytorch>=2.1.0."),