Always Visible UI Overhaul

UI Changes:
 - Made extension always visible on the img2img tab. This will allow for other scripts to be run alongside extension. 
    - Added triggers to determine if the script should run. Triggers are if a model is selected or if an image is present.
    - Removed "Deepbooru (Native)" from being the default model, so that script is not active by default. 
 - Set `clip_api_mode` to "best" to better align with 'clip-interrogator-ext' defaults

Optimizations:
 - Library declarations needed to be organized and cleaned of repetition.
 - Script will no longer run if there is no image to interrogate, (I think that img2img probably should not run if there is no images anyways...)
pull/10/head
Smirking Kitsune 2024-06-27 17:44:48 -07:00 committed by GitHub
parent fa3234ecbf
commit 6b1b47f392
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 133 additions and 126 deletions

View File

@ -1,13 +1,14 @@
import gradio as gr import gradio as gr
import re import re
from modules import scripts, deepbooru
from modules.processing import process_images
import modules.shared as shared
import os import os
import requests import requests
from io import BytesIO from io import BytesIO
import base64 import base64
from modules import script_callbacks from modules import scripts, deepbooru, script_callbacks
from modules.processing import process_images
import modules.shared as shared
NAME = "Img2img batch interrogator"
""" """
@ -30,8 +31,9 @@ class Script(scripts.Script):
return cls.server_address return cls.server_address
# Fallback to the brute force method if server_address is not set # Fallback to the brute force method if server_address is not set
# Initial testing indicates that fallback method might not be needed... # Initial testing indicates that fallback method will never be used...
print("Server address not set. Falling back to brute force method.") print("Server address not set. Falling back to brute force method.")
# Fallback is highly inefficient and in some cases slow (especially if expected port is far from default)
ports = range(7860, 7960) # Gradio will increment port 100 times if default and subsequent desired ports are unavailable. ports = range(7860, 7960) # Gradio will increment port 100 times if default and subsequent desired ports are unavailable.
for port in ports: for port in ports:
url = f"http://127.0.0.1:{port}/" url = f"http://127.0.0.1:{port}/"
@ -42,14 +44,14 @@ class Script(scripts.Script):
except requests.RequestException as error: except requests.RequestException as error:
print(f"API not available on port {port}: {error}") print(f"API not available on port {port}: {error}")
print("API not found on any port") print("API not found")
return None return None
def title(self): def title(self):
return "Img2img batch interrogator" return NAME
def show(self, is_img2img): def show(self, is_img2img):
return is_img2img return scripts.AlwaysVisible if is_img2img else False
def b_clicked(o): def b_clicked(o):
return gr.Button.update(interactive=True) return gr.Button.update(interactive=True)
@ -97,8 +99,10 @@ class Script(scripts.Script):
return gr.Dropdown.update(choices=models if models else None) return gr.Dropdown.update(choices=models if models else None)
def ui(self, is_img2img): def ui(self, is_img2img):
with gr.Group():
with gr.Accordion(NAME, open=False):
model_options = ["CLIP (API)", "CLIP (Native)", "Deepbooru (Native)", "WD (API)"] model_options = ["CLIP (API)", "CLIP (Native)", "Deepbooru (Native)", "WD (API)"]
model_selection = gr.Dropdown(choices=model_options, label="Select Interrogation Model(s)", multiselect=True, value="Deepbooru (Native)") model_selection = gr.Dropdown(choices=model_options, label="Select Interrogation Model(s)", multiselect=True, value=None)
in_front = gr.Radio( in_front = gr.Radio(
choices=["Prepend to prompt", "Append to prompt"], choices=["Prepend to prompt", "Append to prompt"],
@ -124,7 +128,7 @@ class Script(scripts.Script):
clip_api_accordion = gr.Accordion("CLIP API Options:", open=False, visible=False) clip_api_accordion = gr.Accordion("CLIP API Options:", open=False, visible=False)
with clip_api_accordion: with clip_api_accordion:
clip_api_model = gr.Dropdown(choices=[], value='ViT-L-14/openai', label="CLIP API Model") clip_api_model = gr.Dropdown(choices=[], value='ViT-L-14/openai', label="CLIP API Model")
clip_api_mode = gr.Radio(choices=["fast", "best", "classic", "negative"], label="CLIP API Mode", value="fast") clip_api_mode = gr.Radio(choices=["best", "fast", "classic", "negative"], label="CLIP API Mode", value="best")
# WD API Options # WD API Options
def update_wd_api_visibility(model_selection): def update_wd_api_visibility(model_selection):
@ -138,8 +142,8 @@ class Script(scripts.Script):
wd_api_accordion = gr.Accordion("WD API Options:", open=False, visible=False) wd_api_accordion = gr.Accordion("WD API Options:", open=False, visible=False)
with wd_api_accordion: with wd_api_accordion:
wd_api_model = gr.Dropdown(choices=[], value='wd-v1-4-moat-tagger.v2', label="WD API Model") wd_api_model = gr.Dropdown(choices=[], value='wd-v1-4-moat-tagger.v2', label="WD API Model")
wd_underscore_fix = gr.Checkbox(label="Remove Underscores from Tags", value=True)
wd_threshold = gr.Slider(0.0, 1.0, value=0.35, step=0.01, label="Threshold") wd_threshold = gr.Slider(0.0, 1.0, value=0.35, step=0.01, label="Threshold")
wd_underscore_fix = gr.Checkbox(label="Remove Underscores from Tags", value=True)
unload_wd_models_afterwords = gr.Checkbox(label="Unload WD Model After Use", value=True) unload_wd_models_afterwords = gr.Checkbox(label="Unload WD Model After Use", value=True)
unload_wd_models_button = gr.Button(value="Unload WD Models") unload_wd_models_button = gr.Button(value="Unload WD Models")
@ -215,6 +219,8 @@ class Script(scripts.Script):
raw_prompt = p.prompt raw_prompt = p.prompt
interrogator = "" interrogator = ""
# If no model selected or no image, interrogation should not run
if model_selection and not p.init_images[0]:
# fix alpha channel # fix alpha channel
p.init_images[0] = p.init_images[0].convert("RGB") p.init_images[0] = p.init_images[0].convert("RGB")
@ -357,8 +363,9 @@ class Script(scripts.Script):
"name_in_queue": "" "name_in_queue": ""
} }
api_address = f"{self.get_server_address()}tagger/v1/interrogate" api_address = f"{self.get_server_address()}tagger/v1/interrogate"
# WARNING: Removing `timeout` could result in a frozen client if the queue_lock is locked. If you need more time add more time, do not remove or risk DEADLOCK. # WARNING: Removing `timeout` could result in a frozen client if the queue_lock is locked. If you need more time add more time, do not remove timeout or risk DEADLOCK.
# Note: If WD Tagger did not load a model, it is likely that WD Tagger specifically queue_lock (FIFOLock) is concerned with your system's threading and thinks running could cause process starvation... # Note: If WD Tagger did not load a model, it is likely that WD Tagger specifically queue_lock (FIFOLock) is concerned with your system's threading and thinks running could cause processes starvation...
# Note: It would be advisable to download models in the WD tab due to the timeout
response = requests.post(api_address, json=payload, timeout=120) response = requests.post(api_address, json=payload, timeout=120)
response.raise_for_status() response.raise_for_status()
result = response.json() result = response.json()