From 41626d22c3a74a409eea348b34e6bdc873c3ff7b Mon Sep 17 00:00:00 2001 From: DominikDoom Date: Tue, 12 Dec 2023 12:15:58 +0100 Subject: [PATCH 1/3] Fix refresh in SD.Next if no model was loaded --- scripts/tag_autocomplete_helper.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/tag_autocomplete_helper.py b/scripts/tag_autocomplete_helper.py index 029d650..c420075 100644 --- a/scripts/tag_autocomplete_helper.py +++ b/scripts/tag_autocomplete_helper.py @@ -366,9 +366,19 @@ if EMB_PATH.exists(): def refresh_temp_files(*args, **kwargs): global WILDCARD_EXT_PATHS WILDCARD_EXT_PATHS = find_ext_wildcard_paths() - load_textual_inversion_embeddings(force_reload = True) # Instant embedding reload. write_temp_files() - get_embeddings(shared.sd_model) + + try: + # Fix for SD.Next infinite refresh loop due to gradio not updating after model load on demand. + # This will just skip embedding loading if no model is loaded yet (or there really are no embeddings). + # Try catch is just for safety incase sd_hijack access fails for some reason. + loaded = sd_hijack.model_hijack.embedding_db.word_embeddings + skipped = sd_hijack.model_hijack.embedding_db.skipped_embeddings + if len((loaded | skipped)) > 0: + load_textual_inversion_embeddings(force_reload = True) + get_embeddings(None) + except Exception: + pass def write_temp_files(): # Write wildcards to wc.txt if found From 886704e35115ba4907d643c64c179b2ab476bf69 Mon Sep 17 00:00:00 2001 From: DominikDoom Date: Tue, 12 Dec 2023 13:46:51 +0100 Subject: [PATCH 2/3] Fix lora import in a1111 This makes the built-in list method work on the initial load there --- scripts/tag_autocomplete_helper.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/tag_autocomplete_helper.py b/scripts/tag_autocomplete_helper.py index c420075..1e0072d 100644 --- a/scripts/tag_autocomplete_helper.py +++ b/scripts/tag_autocomplete_helper.py @@ -246,20 +246,22 @@ def _get_lyco(): # Attempt to use the build-in Lora.networks Lora/LyCORIS models lists. try: - import importlib - lora_networks = importlib.import_module("extensions-builtin.Lora.networks") + import sys + from modules import extensions + sys.path.append(Path(extensions.extensions_builtin_dir).joinpath("Lora").as_posix()) + import lora # pyright: ignore [reportMissingImports] def _get_lora(): return [ Path(model.filename).absolute() - for model in lora_networks.available_networks.values() + for model in lora.available_loras.values() if Path(model.filename).absolute().is_relative_to(LORA_PATH) ] def _get_lyco(): return [ Path(model.filename).absolute() - for model in lora_networks.available_networks.values() + for model in lora.available_loras.values() if Path(model.filename).absolute().is_relative_to(LYCO_PATH) ] From f840586b6bce9357cf0b52e8edaf98105b7453e7 Mon Sep 17 00:00:00 2001 From: DominikDoom Date: Tue, 12 Dec 2023 14:13:13 +0100 Subject: [PATCH 3/3] Auto-refresh embedding list after model change Uses own API endpoint and doesn't force-reload to skip unneeded work (only works for A1111 as SD.Next model change detection isn't implemented yet) --- javascript/tagAutocomplete.js | 8 ++++++++ scripts/tag_autocomplete_helper.py | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/javascript/tagAutocomplete.js b/javascript/tagAutocomplete.js index 37a20b6..2d0b3fc 100644 --- a/javascript/tagAutocomplete.js +++ b/javascript/tagAutocomplete.js @@ -1269,6 +1269,13 @@ async function refreshTacTempFiles(api = false) { } } +async function refreshEmbeddings() { + await postAPI("tacapi/v1/refresh-embeddings", null); + embeddings = []; + await processQueue(QUEUE_FILE_LOAD, null); + console.log("TAC: Refreshed embeddings"); +} + function addAutocompleteToArea(area) { // Return if autocomplete is disabled for the current area type in config let textAreaId = getTextAreaIdentifier(area); @@ -1373,6 +1380,7 @@ async function setup() { if (mutation.type === "attributes" && mutation.attributeName === "title") { currentModelHash = mutation.target.title; updateModelName(); + refreshEmbeddings(); } } }); diff --git a/scripts/tag_autocomplete_helper.py b/scripts/tag_autocomplete_helper.py index 1e0072d..994ce02 100644 --- a/scripts/tag_autocomplete_helper.py +++ b/scripts/tag_autocomplete_helper.py @@ -365,11 +365,7 @@ if EMB_PATH.exists(): # Get embeddings after the model loaded callback script_callbacks.on_model_loaded(get_embeddings) -def refresh_temp_files(*args, **kwargs): - global WILDCARD_EXT_PATHS - WILDCARD_EXT_PATHS = find_ext_wildcard_paths() - write_temp_files() - +def refresh_embeddings(force: bool, *args, **kwargs): try: # Fix for SD.Next infinite refresh loop due to gradio not updating after model load on demand. # This will just skip embedding loading if no model is loaded yet (or there really are no embeddings). @@ -377,11 +373,17 @@ def refresh_temp_files(*args, **kwargs): loaded = sd_hijack.model_hijack.embedding_db.word_embeddings skipped = sd_hijack.model_hijack.embedding_db.skipped_embeddings if len((loaded | skipped)) > 0: - load_textual_inversion_embeddings(force_reload = True) + load_textual_inversion_embeddings(force_reload=force) get_embeddings(None) except Exception: pass +def refresh_temp_files(*args, **kwargs): + global WILDCARD_EXT_PATHS + WILDCARD_EXT_PATHS = find_ext_wildcard_paths() + write_temp_files() + refresh_embeddings(force=True) + def write_temp_files(): # Write wildcards to wc.txt if found if WILDCARD_PATH.exists(): @@ -580,6 +582,10 @@ def api_tac(_: gr.Blocks, app: FastAPI): async def api_refresh_temp_files(): refresh_temp_files() + @app.post("/tacapi/v1/refresh-embeddings") + async def api_refresh_embeddings(): + refresh_embeddings(force=False) + @app.get("/tacapi/v1/lora-info/{lora_name}") async def get_lora_info(lora_name): return await get_json_info(LORA_PATH, lora_name)