diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | javascript/contextMenus.js | 3 | ||||
-rw-r--r-- | javascript/ui.js | 3 | ||||
-rw-r--r-- | javascript/ui_settings_hints.js | 41 | ||||
-rw-r--r-- | launch.py | 17 | ||||
-rw-r--r-- | modules/generation_parameters_copypaste.py | 1 | ||||
-rw-r--r-- | modules/mac_specific.py | 9 | ||||
-rw-r--r-- | modules/modelloader.py | 3 | ||||
-rw-r--r-- | modules/processing.py | 11 | ||||
-rw-r--r-- | modules/sd_hijack_optimizations.py | 3 | ||||
-rw-r--r-- | modules/shared.py | 14 | ||||
-rw-r--r-- | modules/ui.py | 26 | ||||
-rw-r--r-- | modules/ui_tempdir.py | 3 | ||||
-rw-r--r-- | style.css | 16 | ||||
-rw-r--r-- | webui.py | 4 |
15 files changed, 137 insertions, 18 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ae81232..c56d3a0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ * make the lightbox fullscreen image function properly
* fix squished thumbnails in extras tab
* keep "search" filter for extra networks when user refreshes the tab (previously it showed everthing after you refreshed)
+ * fix webui showing the same image if you configure the generation to always save results into same file
## 1.1.1
diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js index 42f301ab..b2bdf053 100644 --- a/javascript/contextMenus.js +++ b/javascript/contextMenus.js @@ -92,8 +92,7 @@ contextMenuInit = function(){ return;
}
gradioApp().addEventListener("click", function(e) {
- let source = e.composedPath()[0]
- if(source.id && source.id.indexOf('check_progress')>-1){
+ if(! e.isTrusted){
return
}
diff --git a/javascript/ui.js b/javascript/ui.js index b63b84b2..611b70d1 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -348,6 +348,9 @@ onUiUpdate(function(){ settings_tabs.appendChild(show_all_pages) show_all_pages.onclick = function(){ gradioApp().querySelectorAll('#settings > div').forEach(function(elem){ + if(elem.id == "settings_tab_licenses") + return; + elem.style.display = "block"; }) } diff --git a/javascript/ui_settings_hints.js b/javascript/ui_settings_hints.js new file mode 100644 index 00000000..87a289d3 --- /dev/null +++ b/javascript/ui_settings_hints.js @@ -0,0 +1,41 @@ +// various hints and extra info for the settings tab
+
+onUiLoaded(function(){
+ createLink = function(elem_id, text, href){
+ var a = document.createElement('A')
+ a.textContent = text
+ a.target = '_blank';
+
+ elem = gradioApp().querySelector('#'+elem_id)
+ elem.insertBefore(a, elem.querySelector('label'))
+
+ return a
+ }
+
+ createLink("setting_samples_filename_pattern", "[wiki] ").href = "https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Custom-Images-Filename-Name-and-Subdirectory"
+ createLink("setting_directories_filename_pattern", "[wiki] ").href = "https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Custom-Images-Filename-Name-and-Subdirectory"
+
+ createLink("setting_quicksettings_list", "[info] ").addEventListener("click", function(event){
+ requestGet("./internal/quicksettings-hint", {}, function(data){
+ var table = document.createElement('table')
+ table.className = 'settings-value-table'
+
+ data.forEach(function(obj){
+ var tr = document.createElement('tr')
+ var td = document.createElement('td')
+ td.textContent = obj.name
+ tr.appendChild(td)
+
+ var td = document.createElement('td')
+ td.textContent = obj.label
+ tr.appendChild(td)
+
+ table.appendChild(tr)
+ })
+
+ popup(table);
+ })
+ });
+})
+
+
@@ -19,6 +19,7 @@ python = sys.executable git = os.environ.get('GIT', "git")
index_url = os.environ.get('INDEX_URL', "")
stored_commit_hash = None
+stored_git_tag = None
dir_repos = "repositories"
if 'GRADIO_ANALYTICS_ENABLED' not in os.environ:
@@ -70,6 +71,20 @@ def commit_hash(): return stored_commit_hash
+def git_tag():
+ global stored_git_tag
+
+ if stored_git_tag is not None:
+ return stored_git_tag
+
+ try:
+ stored_git_tag = run(f"{git} describe --tags").strip()
+ except Exception:
+ stored_git_tag = "<none>"
+
+ return stored_git_tag
+
+
def run(command, desc=None, errdesc=None, custom_env=None, live=False):
if desc is not None:
print(desc)
@@ -246,8 +261,10 @@ def prepare_environment(): check_python_version()
commit = commit_hash()
+ tag = git_tag()
print(f"Python {sys.version}")
+ print(f"Version: {tag}")
print(f"Commit hash: {commit}")
if args.reinstall_torch or not is_installed("torch") or not is_installed("torchvision"):
diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index 6cc8d13b..78248ed2 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -59,6 +59,7 @@ def image_from_url_text(filedata): is_in_right_dir = ui_tempdir.check_tmp_file(shared.demo, filename)
assert is_in_right_dir, 'trying to open image file outside of allowed directories'
+ filename = filename.rsplit('?', 1)[0]
return Image.open(filename)
if type(filedata) == list:
diff --git a/modules/mac_specific.py b/modules/mac_specific.py index 6fe8dea0..40ce2101 100644 --- a/modules/mac_specific.py +++ b/modules/mac_specific.py @@ -54,6 +54,11 @@ if has_mps: CondFunc('torch.cumsum', cumsum_fix_func, None) CondFunc('torch.Tensor.cumsum', cumsum_fix_func, None) CondFunc('torch.narrow', lambda orig_func, *args, **kwargs: orig_func(*args, **kwargs).clone(), None) - if version.parse(torch.__version__) == version.parse("2.0"): + # MPS workaround for https://github.com/pytorch/pytorch/issues/96113 - CondFunc('torch.nn.functional.layer_norm', lambda orig_func, x, normalized_shape, weight, bias, eps, **kwargs: orig_func(x.float(), normalized_shape, weight.float() if weight is not None else None, bias.float() if bias is not None else bias, eps).to(x.dtype), lambda *args, **kwargs: len(args) == 6) + CondFunc('torch.nn.functional.layer_norm', lambda orig_func, x, normalized_shape, weight, bias, eps, **kwargs: orig_func(x.float(), normalized_shape, weight.float() if weight is not None else None, bias.float() if bias is not None else bias, eps).to(x.dtype), lambda _, input, *args, **kwargs: len(args) == 4 and input.device.type == 'mps') + + # MPS workaround for https://github.com/pytorch/pytorch/issues/92311 + if platform.processor() == 'i386': + for funcName in ['torch.argmax', 'torch.Tensor.argmax']: + CondFunc(funcName, lambda _, input, *args, **kwargs: torch.max(input.float() if input.dtype == torch.int64 else input, *args, **kwargs)[1], lambda _, input, *args, **kwargs: input.device.type == 'mps')
\ No newline at end of file diff --git a/modules/modelloader.py b/modules/modelloader.py index f2274488..cb85ac4f 100644 --- a/modules/modelloader.py +++ b/modules/modelloader.py @@ -122,12 +122,9 @@ forbidden_upscaler_classes = set() def list_builtin_upscalers(): - load_upscalers() - builtin_upscaler_classes.clear() builtin_upscaler_classes.extend(Upscaler.__subclasses__()) - def forbid_loaded_nonbuiltin_upscalers(): for cls in Upscaler.__subclasses__(): if cls not in builtin_upscaler_classes: diff --git a/modules/processing.py b/modules/processing.py index e8808beb..e786791a 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -458,6 +458,16 @@ def fix_seed(p): p.subseed = get_fixed_seed(p.subseed)
+def program_version():
+ import launch
+
+ res = launch.git_tag()
+ if res == "<none>":
+ res = None
+
+ return res
+
+
def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iteration=0, position_in_batch=0):
index = position_in_batch + iteration * p.batch_size
@@ -483,6 +493,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" else None,
"NGMS": None if p.s_min_uncond == 0 else p.s_min_uncond,
+ "Version": program_version() if opts.add_version_to_infotext else None,
}
generation_params.update(p.extra_generation_params)
diff --git a/modules/sd_hijack_optimizations.py b/modules/sd_hijack_optimizations.py index 372555ff..f10865cd 100644 --- a/modules/sd_hijack_optimizations.py +++ b/modules/sd_hijack_optimizations.py @@ -256,6 +256,9 @@ def sub_quad_attention_forward(self, x, context=None, mask=None): k = k.unflatten(-1, (h, -1)).transpose(1,2).flatten(end_dim=1)
v = v.unflatten(-1, (h, -1)).transpose(1,2).flatten(end_dim=1)
+ if q.device.type == 'mps':
+ q, k, v = q.contiguous(), k.contiguous(), v.contiguous()
+
dtype = q.dtype
if shared.opts.upcast_attn:
q, k = q.float(), k.float()
diff --git a/modules/shared.py b/modules/shared.py index dd374713..a8154580 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -392,9 +392,6 @@ options_templates.update(options_section(('ui', "User interface"), { "return_mask": OptionInfo(False, "For inpainting, include the greyscale mask in results for web"),
"return_mask_composite": OptionInfo(False, "For inpainting, include masked composite in results for web"),
"do_not_show_images": OptionInfo(False, "Do not show any images in results for web"),
- "add_model_hash_to_info": OptionInfo(True, "Add model hash to generation information"),
- "add_model_name_to_info": OptionInfo(True, "Add model name to generation information"),
- "disable_weights_auto_swap": OptionInfo(True, "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint."),
"send_seed": OptionInfo(True, "Send seed when sending prompt or image to other interface"),
"send_size": OptionInfo(True, "Send size when sending prompt or image to another interface"),
"font": OptionInfo("", "Font for image grids that have text"),
@@ -407,8 +404,8 @@ options_templates.update(options_section(('ui', "User interface"), { "dimensions_and_batch_together": OptionInfo(True, "Show Width/Height and Batch sliders in same row"),
"keyedit_precision_attention": OptionInfo(0.1, "Ctrl+up/down precision when editing (attention:1.1)", gr.Slider, {"minimum": 0.01, "maximum": 0.2, "step": 0.001}),
"keyedit_precision_extra": OptionInfo(0.05, "Ctrl+up/down precision when editing <extra networks:0.9>", gr.Slider, {"minimum": 0.01, "maximum": 0.2, "step": 0.001}),
- "keyedit_delimiters": OptionInfo(".,\/!?%^*;:{}=`~()", "Ctrl+up/down word delimiters"),
- "quicksettings": OptionInfo("sd_model_checkpoint", "Quicksettings list"),
+ "keyedit_delimiters": OptionInfo(".,\\/!?%^*;:{}=`~()", "Ctrl+up/down word delimiters"),
+ "quicksettings_list": OptionInfo(["sd_model_checkpoint"], "Quicksettings list", ui_components.DropdownMulti, lambda: {"choices": list(opts.data_labels.keys())}),
"hidden_tabs": OptionInfo([], "Hidden UI tabs (requires restart)", ui_components.DropdownMulti, lambda: {"choices": [x for x in tab_names]}),
"ui_reorder": OptionInfo(", ".join(ui_reorder_categories), "txt2img/img2img UI item order"),
"ui_extra_networks_tab_reorder": OptionInfo("", "Extra networks tab order"),
@@ -416,6 +413,13 @@ options_templates.update(options_section(('ui', "User interface"), { "gradio_theme": OptionInfo("Default", "Gradio theme (requires restart)", ui_components.DropdownEditable, lambda: {"choices": ["Default"] + gradio_hf_hub_themes})
}))
+options_templates.update(options_section(('infotext', "Infotext"), {
+ "add_model_hash_to_info": OptionInfo(True, "Add model hash to generation information"),
+ "add_model_name_to_info": OptionInfo(True, "Add model name to generation information"),
+ "add_version_to_infotext": OptionInfo(True, "Add program version to generation information"),
+ "disable_weights_auto_swap": OptionInfo(True, "When reading generation parameters from text into UI (from PNG info or pasted text), do not change the selected model/checkpoint."),
+}))
+
options_templates.update(options_section(('ui', "Live previews"), {
"show_progressbar": OptionInfo(True, "Show progressbar"),
"live_previews_enable": OptionInfo(True, "Show live previews of the created image"),
diff --git a/modules/ui.py b/modules/ui.py index 16c46515..842c57f7 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1525,7 +1525,7 @@ def create_ui(): result = gr.HTML(elem_id="settings_result")
- quicksettings_names = [x.strip() for x in opts.quicksettings.split(",")]
+ quicksettings_names = opts.quicksettings_list
quicksettings_names = {x: i for i, x in enumerate(quicksettings_names) if x != 'quicksettings'}
quicksettings_list = []
@@ -1566,7 +1566,7 @@ def create_ui(): current_row.__exit__()
current_tab.__exit__()
- with gr.TabItem("Actions", id="actions"):
+ with gr.TabItem("Actions", id="actions", elem_id="settings_tab_actions"):
request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications")
download_localization = gr.Button(value='Download localization template', elem_id="download_localization")
reload_script_bodies = gr.Button(value='Reload custom script bodies (No ui updates, No restart)', variant='secondary', elem_id="settings_reload_script_bodies")
@@ -1574,7 +1574,7 @@ def create_ui(): unload_sd_model = gr.Button(value='Unload SD checkpoint to free VRAM', elem_id="sett_unload_sd_model")
reload_sd_model = gr.Button(value='Reload the last SD checkpoint back into VRAM', elem_id="sett_reload_sd_model")
- with gr.TabItem("Licenses", id="licenses"):
+ with gr.TabItem("Licenses", id="licenses", elem_id="settings_tab_licenses"):
gr.HTML(shared.html("licenses.html"), elem_id="licenses")
gr.Button(value="Show all pages", elem_id="settings_show_all_pages")
@@ -1923,7 +1923,7 @@ def versions_html(): python_version = ".".join([str(x) for x in sys.version_info[0:3]])
commit = launch.commit_hash()
- short_commit = commit[0:8]
+ tag = launch.git_tag()
if shared.xformers_available:
import xformers
@@ -1932,6 +1932,8 @@ def versions_html(): xformers_version = "N/A"
return f"""
+version: <a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/{commit}">{tag}</a>
+ •
python: <span title="{sys.version}">{python_version}</span>
•
torch: {getattr(torch, '__long_version__',torch.__version__)}
@@ -1940,7 +1942,19 @@ xformers: {xformers_version} •
gradio: {gr.__version__}
•
-commit: <a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/{commit}">{short_commit}</a>
- •
checkpoint: <a id="sd_checkpoint_hash">N/A</a>
"""
+
+
+def setup_ui_api(app):
+ from pydantic import BaseModel, Field
+ from typing import List
+
+ class QuicksettingsHint(BaseModel):
+ name: str = Field(title="Name of the quicksettings field")
+ label: str = Field(title="Label of the quicksettings field")
+
+ def quicksettings_hint():
+ return [QuicksettingsHint(name=k, label=v.label) for k, v in opts.data_labels.items()]
+
+ app.add_api_route("/internal/quicksettings-hint", quicksettings_hint, methods=["GET"], response_model=List[QuicksettingsHint])
diff --git a/modules/ui_tempdir.py b/modules/ui_tempdir.py index 21945235..67bfd1ec 100644 --- a/modules/ui_tempdir.py +++ b/modules/ui_tempdir.py @@ -2,6 +2,7 @@ import os import tempfile
from collections import namedtuple
from pathlib import Path
+from time import time
import gradio as gr
@@ -34,6 +35,8 @@ def check_tmp_file(gradio, filename): def save_pil_to_file(pil_image, dir=None):
already_saved_as = getattr(pil_image, 'already_saved_as', None)
if already_saved_as and os.path.isfile(already_saved_as):
+ already_saved_as += f'?{os.path.getmtime(already_saved_as)}'
+
register_tmp_file(shared.demo, already_saved_as)
file_obj = Savedfile(already_saved_as)
@@ -125,6 +125,10 @@ div.gradio-html.min{ text-decoration: none;
}
+a{
+ font-weight: bold;
+ cursor: pointer;
+}
/* general styled components */
@@ -397,6 +401,18 @@ div#extras_scale_to_tab div.form{ margin: 0 1.2em;
}
+table.settings-value-table{
+ background: white;
+ border-collapse: collapse;
+ margin: 1em;
+ border: 4px solid white;
+}
+
+table.settings-value-table td{
+ padding: 0.4em;
+ border: 1px solid #ccc;
+ max-width: 36em;
+}
/* live preview */
.progressDiv{
@@ -187,6 +187,9 @@ def initialize(): modules.scripts.load_scripts()
startup_timer.record("load scripts")
+ modelloader.load_upscalers()
+ #startup_timer.record("load upscalers") #Is this necessary? I don't know.
+
modules.sd_vae.refresh_vae_list()
startup_timer.record("refresh VAE")
@@ -342,6 +345,7 @@ def webui(): setup_middleware(app)
modules.progress.setup_progress_api(app)
+ modules.ui.setup_ui_api(app)
if launch_api:
create_api(app)
|