From c0a824d8c6d8d60c24998e0feb5e1a2100c66941 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Mon, 5 Jun 2023 10:32:08 -0400
Subject: [PATCH 01/27] add extra networks to xyz
---
CHANGELOG.md | 2 +
.../Lora/ui_extra_networks_lora.py | 9 ++--
extensions-builtin/sd-webui-agent-scheduler | 2 +-
extensions-builtin/sd-webui-controlnet | 2 +-
.../stable-diffusion-webui-images-browser | 2 +-
javascript/set-hints.js | 8 ++++
modules/devices.py | 44 +++++++++++++------
modules/lora | 2 +-
modules/memstats.py | 4 ++
modules/shared.py | 7 ++-
modules/ui_extra_networks.py | 31 ++++++++++---
scripts/xyz_grid.py | 41 +++++++++--------
webui.py | 2 +-
13 files changed, 104 insertions(+), 52 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fbeb78785..8dd418e4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## Update for 06/03/2023
+- added extra networks to xyz grid options
+ now you can have more fun with all your loras :)
- new vae decode method to help with larger batch sizes, thanks @bigdog
- profiling of scripts/extensions callbacks
- additional exception handling so bad exception does not crash main app
diff --git a/extensions-builtin/Lora/ui_extra_networks_lora.py b/extensions-builtin/Lora/ui_extra_networks_lora.py
index 259e99ac8..dad4500e7 100644
--- a/extensions-builtin/Lora/ui_extra_networks_lora.py
+++ b/extensions-builtin/Lora/ui_extra_networks_lora.py
@@ -14,21 +14,20 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
def list_items(self):
for name, lora_on_disk in lora.available_loras.items():
- path, ext = os.path.splitext(lora_on_disk.filename)
-
+ path, _ext = os.path.splitext(lora_on_disk.filename)
alias = lora_on_disk.get_alias()
-
yield {
"name": name,
"filename": path,
"preview": self.find_preview(path),
"description": self.find_description(path),
"search_term": self.search_terms_from_path(lora_on_disk.filename),
- "prompt": json.dumps(f""),
+ "prompt": json.dumps(f""),
"local_preview": f"{path}.{shared.opts.samples_format}",
"metadata": json.dumps(lora_on_disk.metadata, indent=4) if lora_on_disk.metadata else None,
}
def allowed_directories_for_previews(self):
return [shared.cmd_opts.lora_dir]
-
diff --git a/extensions-builtin/sd-webui-agent-scheduler b/extensions-builtin/sd-webui-agent-scheduler
index b07031958..08cdc1854 160000
--- a/extensions-builtin/sd-webui-agent-scheduler
+++ b/extensions-builtin/sd-webui-agent-scheduler
@@ -1 +1 @@
-Subproject commit b0703195833b8ea055e07b80902cbda1a01363f6
+Subproject commit 08cdc1854f126ec213f8462bdf81cdb0032bee69
diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet
index d8551e447..f36493878 160000
--- a/extensions-builtin/sd-webui-controlnet
+++ b/extensions-builtin/sd-webui-controlnet
@@ -1 +1 @@
-Subproject commit d8551e447d8718e15b8ff5de04036d3fd1b3c5ce
+Subproject commit f36493878b299c367bc51f2935fd7e6d19188569
diff --git a/extensions-builtin/stable-diffusion-webui-images-browser b/extensions-builtin/stable-diffusion-webui-images-browser
index 5795886be..488c5393d 160000
--- a/extensions-builtin/stable-diffusion-webui-images-browser
+++ b/extensions-builtin/stable-diffusion-webui-images-browser
@@ -1 +1 @@
-Subproject commit 5795886bee895c2e69e5c64e67aa643da423511c
+Subproject commit 488c5393db60f0b1ddfb8ab18f3db9119227c962
diff --git a/javascript/set-hints.js b/javascript/set-hints.js
index 64d18b43b..029db6422 100644
--- a/javascript/set-hints.js
+++ b/javascript/set-hints.js
@@ -18,3 +18,11 @@ onUiUpdate(() => {
select.onchange = () => select.title = titles[select.value] || '';
});
});
+
+/*
+// dump elements
+const elements = [
+ ...Array.from(gradioApp().querySelectorAll('button')).map(el => ({id: el.id, text: el.textContent, title: el.title })),
+ ...Array.from(gradioApp().querySelectorAll('label > span')).map(el => ({id: el.id, text: el.textContent, title: el.title })),
+];
+*/
diff --git a/modules/devices.py b/modules/devices.py
index 510e02a03..5a2785974 100644
--- a/modules/devices.py
+++ b/modules/devices.py
@@ -98,6 +98,17 @@ def test_fp16():
shared.opts.no_half_vae = True
return False
+def test_bf16():
+ if shared.cmd_opts.experimental:
+ return True
+ try:
+ import torch.nn.functional as F
+ image = torch.randn(1, 4, 32, 32).to(device="cuda", dtype=torch.bfloat16)
+ _out = F.interpolate(image, size=(64, 64), mode="nearest")
+ except:
+ shared.log.warning('Torch BF16 test failed: Fallback to FP16 operations')
+ return False
+
def set_cuda_params():
shared.log.debug('Verifying Torch settings')
@@ -117,25 +128,32 @@ def set_cuda_params():
except:
pass
global dtype, dtype_vae, dtype_unet, unet_needs_upcast # pylint: disable=global-statement
- ok = test_fp16()
if shared.cmd_opts.use_directml and not shared.cmd_opts.experimental: # TODO DirectML does not have full autocast capabilities
shared.opts.no_half = True
shared.opts.no_half_vae = True
- if ok and shared.opts.cuda_dtype == 'FP32':
- shared.log.info('CUDA FP16 test passed but desired mode is set to FP32')
- if shared.opts.cuda_dtype == 'FP16' and ok:
- dtype = torch.float16
- dtype_vae = torch.float16
- dtype_unet = torch.float16
- if shared.opts.cuda_dtype == 'BF16' and ok:
- dtype = torch.bfloat16
- dtype_vae = torch.bfloat16
- dtype_unet = torch.bfloat16
- if shared.opts.cuda_dtype == 'FP32' or shared.opts.no_half or not ok:
+ if shared.opts.cuda_dtype == 'FP32':
+ dtype = torch.float32
+ dtype_vae = torch.float32
+ dtype_unet = torch.float32
+ if shared.opts.cuda_dtype == 'BF16' or dtype == torch.bfloat16:
+ bf16_ok = test_bf16()
+ dtype = torch.bfloat16 if bf16_ok else torch.float16
+ dtype_vae = torch.bfloat16 if bf16_ok else torch.float16
+ dtype_unet = torch.bfloat16 if bf16_ok else torch.float16
+ if shared.opts.cuda_dtype == 'FP16' or dtype == torch.bfloat16:
+ fp16_ok = test_fp16()
+ dtype = torch.float16 if fp16_ok else torch.float32
+ dtype_vae = torch.float16 if fp16_ok else torch.float32
+ dtype_unet = torch.float16 if fp16_ok else torch.float32
+ else:
+ pass
+ if shared.opts.no_half:
+ shared.log.info('Torch override dtype: no-half set')
dtype = torch.float32
dtype_vae = torch.float32
dtype_unet = torch.float32
if shared.opts.no_half_vae: # set dtype again as no-half-vae options take priority
+ shared.log.info('Torch override VAE dtype: no-half-vae set')
dtype_vae = torch.float32
unet_needs_upcast = shared.opts.upcast_sampling
shared.log.debug(f'Desired Torch parameters: dtype={shared.opts.cuda_dtype} no-half={shared.opts.no_half} no-half-vae={shared.opts.no_half_vae} upscast={shared.opts.upcast_sampling}')
@@ -150,7 +168,7 @@ if args.use_ipex:
CondFunc('torch.nn.modules.GroupNorm.forward',
lambda orig_func, *args, **kwargs: orig_func(args[0], args[1].to(args[0].weight.data.dtype)),
lambda *args, **kwargs: args[2].dtype != args[1].weight.data.dtype)
-
+
#Use XPU instead of CPU. %20 Perf improvement on weak CPUs.
if args.device_id is not None:
cpu = torch.device(f"xpu:{args.device_id}")
diff --git a/modules/lora b/modules/lora
index 7c38c33ed..0fe1afd4e 160000
--- a/modules/lora
+++ b/modules/lora
@@ -1 +1 @@
-Subproject commit 7c38c33ed62fa1becab94f967a52aca18ffaccc0
+Subproject commit 0fe1afd4efda89d3d4c8f25c5193c6859a32bc42
diff --git a/modules/memstats.py b/modules/memstats.py
index 00260bebf..792d1fdc5 100644
--- a/modules/memstats.py
+++ b/modules/memstats.py
@@ -19,6 +19,8 @@ def memory_stats():
s = torch.cuda.mem_get_info()
gpu = { 'used': gb(s[1] - s[0]), 'total': gb(s[1]) }
s = dict(torch.cuda.memory_stats())
+ if s['num_ooms'] > 0:
+ shared.state.oom = True
mem.update({
'gpu': gpu,
'retries': s['num_alloc_retries'],
@@ -35,6 +37,8 @@ def memory_stats():
'retries': s['num_alloc_retries'],
'oom': s['num_ooms']
})
+ if s['num_ooms'] > 0:
+ shared.state.oom = True
return mem
except:
pass
diff --git a/modules/shared.py b/modules/shared.py
index e30532978..88f1ce227 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -102,6 +102,7 @@ class State:
time_start = None
need_restart = False
server_start = None
+ oom = False
def skip(self):
log.debug('Requested skip')
@@ -496,8 +497,10 @@ options_templates.update(options_section(('upscaling', "Upscaling"), {
"lora_functional": OptionInfo(False, "Use Kohya method for handling multiple Loras", gr.Checkbox, { "visible": False }),
}))
-# options_templates.update(options_section(('lora', "Lora"), {
-# }))
+options_templates.update(options_section(('lora', "Lora"), {
+ "lyco_patch_lora": OptionInfo(False, "Use LyCoris handler for all Lora types", gr.Checkbox, { "visible": True }), # TODO: lyco-patch-lora
+ "lora_functional": OptionInfo(False, "Use Kohya method for handling multiple Loras", gr.Checkbox, { "visible": True }),
+}))
options_templates.update(options_section(('face-restoration', "Face restoration"), {
"face_restoration_model": OptionInfo("CodeFormer", "Face restoration model", gr.Radio, lambda: {"choices": [x.name() for x in face_restorers]}),
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index 79e5c5ae1..929f671c5 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -4,7 +4,7 @@ import os.path
import urllib.parse
from pathlib import Path
import gradio as gr
-from modules import shared
+from modules import shared, scripts
from modules.generation_parameters_copypaste import image_from_url_text
from modules.ui_components import ToolButton
@@ -54,10 +54,27 @@ class ExtraNetworksPage:
self.card_short = shared.html("extra-networks-card-short.html")
self.allow_negative_prompt = False
self.metadata = {}
+ self.items = []
def refresh(self):
pass
+ def create_xyz_grid(self):
+ xyz_grid = [x for x in scripts.scripts_data if x.script_class.__module__ == "xyz_grid.py"][0].module
+
+ def add_prompt(p, opt, x):
+ for item in [x for x in self.items if x["name"] == opt]:
+ try:
+ p.prompt = f'{p.prompt} {eval(item["prompt"])}' # pylint: disable=eval-used
+ except Exception as e:
+ shared.log.error(f'Cannot evaluate extra network prompt: {item["prompt"]} {e}')
+
+ if not any(self.title in x.label for x in xyz_grid.axis_options):
+ if self.title == 'Checkpoints':
+ return
+ opt = xyz_grid.AxisOption(f"[Network] {self.title}", str, add_prompt, choices=lambda: [x["name"] for x in self.items])
+ xyz_grid.axis_options.append(opt)
+
def link_preview(self, filename):
quoted_filename = urllib.parse.quote(filename.replace('\\', '/'))
mtime = os.path.getmtime(filename)
@@ -93,12 +110,14 @@ class ExtraNetworksPage:
if subdirs:
subdirs = {"": 1, **subdirs}
subdirs_html = "".join([f"""
-
-""" for subdir in subdirs])
+
+ """ for subdir in subdirs])
try:
- for item in self.list_items():
+ self.items = list(self.list_items())
+ self.create_xyz_grid()
+ for item in self.items:
metadata = item.get("metadata")
if metadata:
self.metadata[item["name"]] = metadata
diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py
index cfa56fa12..43304cb4b 100644
--- a/scripts/xyz_grid.py
+++ b/scripts/xyz_grid.py
@@ -207,35 +207,34 @@ class AxisOptionTxt2Img(AxisOption):
axis_options = [
AxisOption("Nothing", str, do_nothing, fmt=format_nothing),
- AxisOption("Seed", int, apply_field("seed")),
- AxisOption("Var. seed", int, apply_field("subseed")),
- AxisOption("Var. strength", float, apply_field("subseed_strength")),
- AxisOption("Steps", int, apply_field("steps")),
- AxisOptionTxt2Img("Hires steps", int, apply_field("hr_second_pass_steps")),
- AxisOption("CFG Scale", float, apply_field("cfg_scale")),
- AxisOptionImg2Img("Image CFG Scale", float, apply_field("image_cfg_scale")),
+ AxisOption("Checkpoint name", str, apply_checkpoint, fmt=format_value, confirm=confirm_checkpoints, cost=1.0, choices=lambda: list(sd_models.checkpoints_list)),
+ AxisOption("VAE", str, apply_vae, cost=0.7, choices=lambda: ['None'] + list(sd_vae.vae_dict)),
AxisOption("Prompt S/R", str, apply_prompt, fmt=format_value),
- AxisOption("Prompt order", str_permutations, apply_order, fmt=format_value_join_list),
+ AxisOption("Styles", str, apply_styles, choices=lambda: list(shared.prompt_styles.styles)),
AxisOptionTxt2Img("Sampler", str, apply_sampler, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers]),
AxisOptionImg2Img("Sampler", str, apply_sampler, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers_for_img2img]),
- AxisOption("Checkpoint name", str, apply_checkpoint, fmt=format_value, confirm=confirm_checkpoints, cost=1.0, choices=lambda: list(sd_models.checkpoints_list)),
- AxisOption("Sigma Churn", float, apply_field("s_churn")),
- AxisOption("Sigma min", float, apply_field("s_tmin")),
- AxisOption("Sigma max", float, apply_field("s_tmax")),
- AxisOption("Sigma noise", float, apply_field("s_noise")),
- AxisOption("Eta", float, apply_field("eta")),
+ AxisOption("Seed", int, apply_field("seed")),
+ AxisOption("Steps", int, apply_field("steps")),
+ AxisOption("CFG Scale", float, apply_field("cfg_scale")),
+ AxisOption("Var. seed", int, apply_field("subseed")),
+ AxisOption("Var. strength", float, apply_field("subseed_strength")),
AxisOption("Clip skip", int, apply_clip_skip),
AxisOption("Denoising", float, apply_field("denoising_strength")),
+ AxisOptionTxt2Img("Hires steps", int, apply_field("hr_second_pass_steps")),
+ AxisOptionImg2Img("Image CFG Scale", float, apply_field("image_cfg_scale")),
+ AxisOption("Prompt order", str_permutations, apply_order, fmt=format_value_join_list),
+ AxisOption("Sampler Sigma Churn", float, apply_field("s_churn")),
+ AxisOption("Sampler Sigma min", float, apply_field("s_tmin")),
+ AxisOption("Sampler Sigma max", float, apply_field("s_tmax")),
+ AxisOption("Sampler Sigma noise", float, apply_field("s_noise")),
+ AxisOption("Sampler Eta", float, apply_field("eta")),
AxisOptionTxt2Img("Hires upscaler", str, apply_field("hr_upscaler"), choices=lambda: [*shared.latent_upscale_modes, *[x.name for x in shared.sd_upscalers]]),
- AxisOptionTxt2Img("Fallback latent upscaler sampler", str, apply_fallback, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers]),
- AxisOptionImg2Img("Cond. Image Mask Weight", float, apply_field("inpainting_mask_weight")),
- AxisOption("VAE", str, apply_vae, cost=0.7, choices=lambda: ['None'] + list(sd_vae.vae_dict)),
- AxisOption("Styles", str, apply_styles, choices=lambda: list(shared.prompt_styles.styles)),
+ AxisOptionImg2Img("Image Mask Weight", float, apply_field("inpainting_mask_weight")),
AxisOption("UniPC Order", int, apply_uni_pc_order, cost=0.5),
AxisOption("Face restore", str, apply_face_restore, fmt=format_value),
- AxisOption("ToMe ratio",float,apply_token_merging_ratio),
- AxisOption("ToMe ratio for Hires fix",float,apply_token_merging_ratio_hr),
- AxisOption("ToMe random pertubations",str,apply_token_merging_random, choices = lambda: ["Yes","No"])
+ AxisOption("ToMe ratio",float, apply_token_merging_ratio),
+ AxisOption("ToMe ratio for Hires fix",float, apply_token_merging_ratio_hr),
+ AxisOption("ToMe random pertubations",str, apply_token_merging_random, choices = lambda: ["Yes","No"])
]
diff --git a/webui.py b/webui.py
index 13d7faa9f..8f090b415 100644
--- a/webui.py
+++ b/webui.py
@@ -222,7 +222,7 @@ def start_ui():
gradio_auth_creds += [x.strip() for x in line.split(',') if x.strip()]
import installer
- global local_url
+ global local_url # pylint: disable=global-statement
app, local_url, share_url = shared.demo.launch(
share=cmd_opts.share,
server_name=server_name,
From c52fb69dded135b0a53f9116049f85ebc8377578 Mon Sep 17 00:00:00 2001
From: Disty0
Date: Mon, 5 Jun 2023 20:49:18 +0300
Subject: [PATCH 02/27] Fix bf16 test
---
modules/devices.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/modules/devices.py b/modules/devices.py
index 5a2785974..dfdcf57af 100644
--- a/modules/devices.py
+++ b/modules/devices.py
@@ -103,8 +103,9 @@ def test_bf16():
return True
try:
import torch.nn.functional as F
- image = torch.randn(1, 4, 32, 32).to(device="cuda", dtype=torch.bfloat16)
+ image = torch.randn(1, 4, 32, 32).to(device=device, dtype=torch.bfloat16)
_out = F.interpolate(image, size=(64, 64), mode="nearest")
+ return True
except:
shared.log.warning('Torch BF16 test failed: Fallback to FP16 operations')
return False
@@ -140,7 +141,7 @@ def set_cuda_params():
dtype = torch.bfloat16 if bf16_ok else torch.float16
dtype_vae = torch.bfloat16 if bf16_ok else torch.float16
dtype_unet = torch.bfloat16 if bf16_ok else torch.float16
- if shared.opts.cuda_dtype == 'FP16' or dtype == torch.bfloat16:
+ if shared.opts.cuda_dtype == 'FP16' or dtype == torch.float16:
fp16_ok = test_fp16()
dtype = torch.float16 if fp16_ok else torch.float32
dtype_vae = torch.float16 if fp16_ok else torch.float32
From 46d410687ed59fbcb26a35b8e6e3f3f787c4ef8c Mon Sep 17 00:00:00 2001
From: Patrick von Platen
Date: Mon, 5 Jun 2023 18:22:17 +0000
Subject: [PATCH 03/27] Improve when loading from diffusers
---
modules/modelloader.py | 9 ++++++++-
modules/sd_models.py | 24 +++++++++++++++++-------
2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/modules/modelloader.py b/modules/modelloader.py
index 188ee6db2..aa68b5701 100644
--- a/modules/modelloader.py
+++ b/modules/modelloader.py
@@ -9,9 +9,16 @@ from modules.paths import script_path, models_path
diffuser_repos = []
-def load_diffusers(model_path: str, command_path: str = None):
+def load_diffusers(model_path: str, hub_url: str = None, command_path: str = None):
import huggingface_hub as hf
+ from diffusers import DiffusionPipeline
+
places = []
+
+ # download repo
+ if hub_url is not None:
+ DiffusionPipeline.download(hub_url, cache_dir=model_path)
+
places.append(model_path)
if command_path is not None and command_path != model_path and os.path.isdir(command_path):
places.append(command_path)
diff --git a/modules/sd_models.py b/modules/sd_models.py
index f658d35f9..676075ef8 100644
--- a/modules/sd_models.py
+++ b/modules/sd_models.py
@@ -108,7 +108,8 @@ def list_models():
if shared.backend == shared.Backend.ORIGINAL:
model_list = modelloader.load_models(model_path=os.path.join(models_path, 'Stable-diffusion'), model_url=None, command_path=shared.opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], download_name=None, ext_blacklist=[".vae.ckpt", ".vae.safetensors"])
else:
- model_list = modelloader.load_diffusers(model_path=os.path.join(models_path, 'Diffusers'), command_path=shared.opts.diffusers_dir)
+ model_path = os.path.join(models_path, 'Diffusers')
+ model_list = modelloader.load_diffusers(model_path=model_path, command_path=shared.opts.diffusers_dir)
for filename in sorted(model_list, key=str.lower):
checkpoint_info = CheckpointInfo(filename)
if checkpoint_info.name is not None:
@@ -125,16 +126,25 @@ def list_models():
elif shared.cmd_opts.ckpt != shared.default_sd_model_file and shared.cmd_opts.ckpt is not None:
shared.log.warning(f"Checkpoint not found: {shared.cmd_opts.ckpt}")
shared.log.info(f'Available models: {shared.opts.ckpt_dir} {len(checkpoints_list)}')
+
if len(checkpoints_list) == 0:
if not shared.cmd_opts.no_download:
key = input('Download the default model? (y/N) ')
if key.lower().startswith('y'):
- model_url = "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors"
- shared.opts.data['sd_model_checkpoint'] = "v1-5-pruned-emaonly.safetensors"
- model_list = modelloader.load_models(model_path=model_path, model_url=model_url, command_path=shared.opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], download_name="v1-5-pruned-emaonly.safetensors", ext_blacklist=[".vae.ckpt", ".vae.safetensors"])
- for filename in sorted(model_list, key=str.lower):
- checkpoint_info = CheckpointInfo(filename)
- checkpoint_info.register()
+ if shared.backend == shared.Backend.ORIGINAL:
+ model_url = "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors"
+ shared.opts.data['sd_model_checkpoint'] = "v1-5-pruned-emaonly.safetensors"
+ model_list = modelloader.load_models(model_path=model_path, model_url=model_url, command_path=shared.opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], download_name="v1-5-pruned-emaonly.safetensors", ext_blacklist=[".vae.ckpt", ".vae.safetensors"])
+ for filename in sorted(model_list, key=str.lower):
+ checkpoint_info = CheckpointInfo(filename)
+ checkpoint_info.register()
+ else:
+ hub_url = "runwayml/stable-diffusion-v1-5"
+ model_list = modelloader.load_diffusers(model_path=model_path, hub_url=hub_url, command_path=shared.opts.diffusers_dir)
+ for filename in sorted(model_list, key=str.lower):
+ checkpoint_info = CheckpointInfo(filename)
+ if checkpoint_info.name is not None:
+ checkpoint_info.register()
def update_model_hashes():
From 9cf58884790e13c40e945a6a324ad4968e507161 Mon Sep 17 00:00:00 2001
From: Patrick von Platen
Date: Mon, 5 Jun 2023 18:23:35 +0000
Subject: [PATCH 04/27] dedup code
---
modules/sd_models.py | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/modules/sd_models.py b/modules/sd_models.py
index 676075ef8..17dab145d 100644
--- a/modules/sd_models.py
+++ b/modules/sd_models.py
@@ -135,16 +135,14 @@ def list_models():
model_url = "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors"
shared.opts.data['sd_model_checkpoint'] = "v1-5-pruned-emaonly.safetensors"
model_list = modelloader.load_models(model_path=model_path, model_url=model_url, command_path=shared.opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], download_name="v1-5-pruned-emaonly.safetensors", ext_blacklist=[".vae.ckpt", ".vae.safetensors"])
- for filename in sorted(model_list, key=str.lower):
- checkpoint_info = CheckpointInfo(filename)
- checkpoint_info.register()
else:
hub_url = "runwayml/stable-diffusion-v1-5"
model_list = modelloader.load_diffusers(model_path=model_path, hub_url=hub_url, command_path=shared.opts.diffusers_dir)
- for filename in sorted(model_list, key=str.lower):
- checkpoint_info = CheckpointInfo(filename)
- if checkpoint_info.name is not None:
- checkpoint_info.register()
+
+ for filename in sorted(model_list, key=str.lower):
+ checkpoint_info = CheckpointInfo(filename)
+ if checkpoint_info.name is not None:
+ checkpoint_info.register()
def update_model_hashes():
From efbe364f7dc5073d2ad35ce510c7c364c5985941 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Mon, 5 Jun 2023 14:25:57 -0400
Subject: [PATCH 05/27] js optimizations
---
.eslintrc.json | 5 +-
CHANGELOG.md | 16 +-
cli/{hfsearch.py => hf-search.py} | 2 +
cli/validate-locale.py | 31 ++
extensions-builtin/a1111-sd-webui-lycoris | 2 +-
html/locale_en.json | 570 ++++++++++++++++++++++
installer.py | 9 +-
javascript/aspectRatioOverlay.js | 4 +-
javascript/contextMenus.js | 4 +-
javascript/generationParams.js | 3 +-
javascript/hires.js | 1 -
javascript/imageMaskFix.js | 3 +-
javascript/imageParams.js | 1 -
javascript/imageviewer.js | 3 +-
javascript/notification.js | 2 +-
javascript/progressbar.js | 1 -
javascript/script.js | 36 +-
javascript/set-hints.js | 6 +-
javascript/ui.js | 7 +-
modules/cmd_args.py | 1 +
modules/devices.py | 2 +-
modules/extensions.py | 2 +
modules/paths.py | 1 +
modules/scripts.py | 27 +-
modules/shared.py | 2 +-
modules/ui.py | 14 +-
modules/ui_extensions.py | 2 +-
scripts/prompt_matrix.py | 2 +-
scripts/xyz_grid.py | 2 +-
webui.py | 6 +-
30 files changed, 697 insertions(+), 70 deletions(-)
rename cli/{hfsearch.py => hf-search.py} (96%)
mode change 100644 => 100755
create mode 100755 cli/validate-locale.py
create mode 100755 html/locale_en.json
diff --git a/.eslintrc.json b/.eslintrc.json
index 2958fbc79..e34b2792c 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -51,13 +51,14 @@
"globals": {
//script.js
"gradioApp": "readonly",
+ "executeCallbacks": "readonly",
+ "onAfterUiUpdate": "readonly",
+ "onOptionsChanged": "readonly",
"onUiLoaded": "readonly",
"onUiUpdate": "readonly",
- "onOptionsChanged": "readonly",
"uiCurrentTab": "writable",
"uiElementIsVisible": "readonly",
"uiElementInSight": "readonly",
- "executeCallbacks": "readonly",
//ui.js
"opts": "writable",
"all_gallery_buttons": "readonly",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8dd418e4b..5c62d2c26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,12 +2,16 @@
## Update for 06/03/2023
-- added extra networks to xyz grid options
- now you can have more fun with all your loras :)
-- new vae decode method to help with larger batch sizes, thanks @bigdog
-- profiling of scripts/extensions callbacks
-- additional exception handling so bad exception does not crash main app
-- additional background removal models
+- added extra networks to **xyz grid** options
+ now you can have more fun with all your embeddings and loras :)
+- new **vae decode** method to help with larger batch sizes, thanks @bigdog
+- new setting -> lora -> **use lycoris to handle all lora types**
+ this is still experimental, but the goal is to obsolete old built-in lora module
+ as it doesn't understand many new loras and built-in lyco module can handle it all
+- optimize browser page loading
+- profiling of scripts/extensions callbacks
+- additional exception handling so bad exception does not crash main app
+- additional background removal models
## Update for 06/02/2023
diff --git a/cli/hfsearch.py b/cli/hf-search.py
old mode 100644
new mode 100755
similarity index 96%
rename from cli/hfsearch.py
rename to cli/hf-search.py
index b0fc9040c..bbb4a4f0f
--- a/cli/hfsearch.py
+++ b/cli/hf-search.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+
import sys
import huggingface_hub as hf
from rich import print # pylint: disable=redefined-builtin
diff --git a/cli/validate-locale.py b/cli/validate-locale.py
new file mode 100755
index 000000000..45841b7a3
--- /dev/null
+++ b/cli/validate-locale.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+import sys
+import json
+from rich import print # pylint: disable=redefined-builtin
+
+if __name__ == "__main__":
+ sys.argv.pop(0)
+ fn = sys.argv[0] if len(sys.argv) > 0 else 'locale_en.json'
+ with open(fn, 'r') as f:
+ data = json.load(f)
+ keys = []
+ t_names = 0
+ t_hints = 0
+ for k in data.keys():
+ print(f'Section: {k}')
+ names = len(data[k])
+ t_names += names
+ print(f' Names: {names}')
+ hints = len([k for k in data[k] if k["hint"] != ""])
+ t_hints += hints
+ print(f' Hints: {hints}')
+ print(f' Missing: {names - hints}')
+ for v in data[k]:
+ if v['text'] in keys:
+ print(f' Duplicate: {k}.{v["text"]}')
+ else:
+ keys.append(v['text'])
+ print(f'Total entries: {t_names}')
+ print(f'Total hints: {t_hints}')
+ print(f'Total missing: {t_names - t_hints}')
diff --git a/extensions-builtin/a1111-sd-webui-lycoris b/extensions-builtin/a1111-sd-webui-lycoris
index 21e9ea0f5..1e5db3921 160000
--- a/extensions-builtin/a1111-sd-webui-lycoris
+++ b/extensions-builtin/a1111-sd-webui-lycoris
@@ -1 +1 @@
-Subproject commit 21e9ea0f58dfdbee12b08389fd2cd1aa545e058d
+Subproject commit 1e5db39210df4dd3bb6f3667d9e690c447939e71
diff --git a/html/locale_en.json b/html/locale_en.json
new file mode 100755
index 000000000..448bb79a0
--- /dev/null
+++ b/html/locale_en.json
@@ -0,0 +1,570 @@
+{ "icons": [
+ {"id":"","text":"📘","localized":"","hint":"Read generation parameters from prompt or last generation if prompt is empty into user interface"},
+ {"id":"","text":"🚮","localized":"","hint":"Clear prompt"},
+ {"id":"","text":"🌐","localized":"","hint":"Show/hide extra networks"},
+ {"id":"","text":"🧳","localized":"","hint":"Apply selected styles to current prompt"},
+ {"id":"","text":"🛅","localized":"","hint":"Save style"},
+ {"id":"","text":"🔄","localized":"","hint":"Refresh"},
+ {"id":"","text":"❌","localized":"","hint":"Close"},
+ {"id":"","text":"📒","localized":"","hint":"Fill"},
+ {"id":"","text":"🎲️","localized":"","hint":"Use random seed"},
+ {"id":"","text":"♻️","localized":"","hint":"Reuse previous seed"},
+ {"id":"","text":"⇅","localized":"","hint":"Switch values"}
+ ],
+ "prompts": [
+ {"id":"","text":"Prompt","localized":"","hint":"Prompt"},
+ {"id":"","text":"Negative prompt","localized":"","hint":"Negative Prompt"}
+ ],
+ "tabs": [
+ {"id":"","text":"From Text ","localized":"","hint":"Create image from text"},
+ {"id":"","text":"From Image ","localized":"","hint":"Create image from image"},
+ {"id":"","text":"Process Image ","localized":"","hint":"Process existing image"},
+ {"id":"","text":"Train ","localized":"","hint":"Run training or model merging"},
+ {"id":"","text":"Settings ","localized":"","hint":"Application settings"},
+ {"id":"","text":"Extensions ","localized":"","hint":"Application extensions"}
+ ],
+ "action panel": [
+ {"id":"","text":"Generate","localized":"","hint":"Start processing"},
+ {"id":"","text":"Stop","localized":"","hint":"Stop processing"},
+ {"id":"","text":"Skip","localized":"","hint":"Stop processing current job and continue processing"},
+ {"id":"","text":"Pause","localized":"","hint":"Pause processing"},
+ {"id":"","text":"Interrogate\nCLIP","localized":"","hint":"Run interrogate using CLIP model"},
+ {"id":"","text":"Interrogate\nDeepBooru","localized":"","hint":"Run interrogate using DeepBooru model"}
+ ],
+ "extra networks": [
+ {"id":"","text":"Save preview","localized":"","hint":"Save current image as extra network preview"},
+ {"id":"","text":"Save description","localized":"","hint":"Save current text as extra network description"},
+ {"id":"","text":"Read description","localized":"","hint":"Read stored extra network description"}
+ ],
+ "gallery buttons": [
+ {"id":"","text":"show","localized":"","hint":"Show image location"},
+ {"id":"","text":"save","localized":"","hint":"Save image"},
+ {"id":"","text":"zip","localized":"","hint":"Create zip archive from images"},
+ {"id":"","text":"delete","localized":"","hint":"Delete image"},
+ {"id":"","text":"➠ text","localized":"","hint":"Transfer image to text interface"},
+ {"id":"","text":"➠ image","localized":"","hint":"Transfer image to image interface"},
+ {"id":"","text":"➠ inpaint","localized":"","hint":"Transfer image to inpaint interface"},
+ {"id":"","text":"➠ sketch","localized":"","hint":"Transfer image to sketch interface"},
+ {"id":"","text":"➠ inpaint sketch","localized":"","hint":"Transfer image to inpaint sketch interface"},
+ {"id":"","text":"➠ process","localized":"","hint":"Transfer image to process interface"}
+ ],
+ "extensions": [
+ {"id":"","text":"Install","localized":"","hint":""},
+ {"id":"","text":"Search","localized":"","hint":""},
+ {"id":"","text":"Sort by","localized":"","hint":""},
+ {"id":"","text":"Manage Extensions ","localized":"","hint":""},
+ {"id":"","text":"Manual install ","localized":"","hint":""},
+ {"id":"","text":"Extension GIT repository URL","localized":"","hint":""},
+ {"id":"","text":"Specific branch name","localized":"","hint":""},
+ {"id":"","text":"Local directory name","localized":"","hint":""},
+ {"id":"","text":"Refresh extension list","localized":"","hint":""},
+ {"id":"","text":"Update installed extensions","localized":"","hint":""},
+ {"id":"","text":"Apply changes & restart server","localized":"","hint":""}
+ ],
+ "txt2img tab": [
+ {"id":"","text":"Sampling method","localized":"","hint":"Which algorithm to use to produce the image"},
+ {"id":"","text":"Sampling steps","localized":"","hint":"How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results"},
+ {"id":"","text":"Restore faces","localized":"","hint":""},
+ {"id":"","text":"Tiling","localized":"","hint":"Produce an image that can be tiled"},
+ {"id":"","text":"Hires fix","localized":"","hint":""},
+ {"id":"","text":"Denoising strength","localized":"","hint":"Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies"},
+ {"id":"","text":"Hires steps","localized":"","hint":"Number of sampling steps for upscaled picture. If 0, uses same as for original"},
+ {"id":"","text":"Upscaler","localized":"","hint":""},
+ {"id":"","text":"Upscale by","localized":"","hint":"Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero"},
+ {"id":"","text":"Resize width to","localized":"","hint":"Resizes image to this width. If 0, width is inferred from either of two nearby sliders"},
+ {"id":"","text":"Resize height to","localized":"","hint":"Resizes image to this height. If 0, height is inferred from either of two nearby sliders"},
+ {"id":"","text":"Width","localized":"","hint":""},
+ {"id":"","text":"Height","localized":"","hint":""},
+ {"id":"","text":"Batch count","localized":"","hint":"How many batches of images to create (has no impact on generation performance or VRAM usage)"},
+ {"id":"","text":"Batch size","localized":"","hint":"How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)"},
+ {"id":"","text":"CFG Scale","localized":"","hint":"Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results"},
+ {"id":"","text":"CLIP skip","localized":"","hint":""},
+ {"id":"","text":"Seed","localized":"","hint":"A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result"},
+ {"id":"","text":"Extra","localized":"","hint":""},
+ {"id":"","text":"Variation seed","localized":"","hint":"Seed of a different picture to be mixed into the generation"},
+ {"id":"","text":"Variation strength","localized":"","hint":"How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something)"},
+ {"id":"","text":"Resize seed from width","localized":"","hint":"Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution"},
+ {"id":"","text":"Resize seed from height","localized":"","hint":"Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution"},
+ {"id":"","text":"Override settings","localized":"","hint":""}
+ ],
+ "process tab": [
+ {"id":"","text":"Single Image ","localized":"","hint":""},
+ {"id":"","text":"Process Batch ","localized":"","hint":""},
+ {"id":"","text":"Process Folder ","localized":"","hint":""},
+ {"id":"","text":"Scale by ","localized":"","hint":""},
+ {"id":"","text":"Scale to ","localized":"","hint":""},
+ {"id":"","text":"Input directory","localized":"","hint":""},
+ {"id":"","text":"Output directory","localized":"","hint":""},
+ {"id":"","text":"Show result images","localized":"","hint":""},
+ {"id":"","text":"Resize","localized":"","hint":""},
+ {"id":"","text":"Crop to fit","localized":"","hint":""},
+ {"id":"","text":"Secondary Upscaler","localized":"","hint":""},
+ {"id":"","text":"Upscaler 2 visibility","localized":"","hint":""},
+ {"id":"","text":"GFPGAN visibility","localized":"","hint":""},
+ {"id":"","text":"CodeFormer visibility","localized":"","hint":""},
+ {"id":"","text":"CodeFormer weight (0 = max), 1 = min)","localized":"","hint":""}
+ ],
+ "settings menu": [
+ {"id":"settings_submit","text":"Apply settings","localized":"","hint":""},
+ {"id":"restart_submit","text":"Restart server","localized":"","hint":""},
+ {"id":"shutdown_submit","text":"Shutdown server","localized":"","hint":""},
+ {"id":"settings_preview_theme","text":"Preview theme","localized":"","hint":""},
+ {"id":"defaults_submit","text":"Restore defaults","localized":"","hint":""},
+ {"id":"sett_unload_sd_model","text":"Unload checkpoint","localized":"","hint":""},
+ {"id":"sett_reload_sd_model","text":"Reload checkpoint","localized":"","hint":""}
+ ],
+ "settings sections": [
+ {"id":"","text":"Stable Diffusion ","localized":"","hint":""},
+ {"id":"","text":"Compute Settings ","localized":"","hint":""},
+ {"id":"","text":"System Paths ","localized":"","hint":""},
+ {"id":"","text":"Image Options ","localized":"","hint":""},
+ {"id":"","text":"Image Processing ","localized":"","hint":""},
+ {"id":"","text":"Output Paths ","localized":"","hint":""},
+ {"id":"","text":"User interface ","localized":"","hint":""},
+ {"id":"","text":"Live previews ","localized":"","hint":""},
+ {"id":"","text":"Sampler Settings ","localized":"","hint":""},
+ {"id":"","text":"Postprocessing ","localized":"","hint":""},
+ {"id":"","text":"Training ","localized":"","hint":""},
+ {"id":"","text":"Interrogate ","localized":"","hint":""},
+ {"id":"","text":"Upscaling ","localized":"","hint":""},
+ {"id":"","text":"Lora ","localized":"","hint":""},
+ {"id":"","text":"Face restoration ","localized":"","hint":""},
+ {"id":"","text":"Extra Networks ","localized":"","hint":""},
+ {"id":"","text":"Token Merging ","localized":"","hint":""},
+ {"id":"","text":"Licenses ","localized":"","hint":""},
+ {"id":"","text":"Show all pages","localized":"","hint":""},
+ {"id":"","text":"Request browser notifications","localized":"","hint":""}
+ ],
+ "img2img tabs": [
+ {"id":"","text":"Image ","localized":"","hint":""},
+ {"id":"","text":"Sketch ","localized":"","hint":""},
+ {"id":"","text":"Inpaint ","localized":"","hint":""},
+ {"id":"","text":"Inpaint sketch ","localized":"","hint":""},
+ {"id":"","text":"Inpaint upload ","localized":"","hint":""},
+ {"id":"","text":"Batch ","localized":"","hint":""}
+ ],
+ "img2img tab": [
+ {"id":"","text":"Inpaint Batch input directory","localized":"","hint":""},
+ {"id":"","text":"Inpaint Batch output directory","localized":"","hint":""},
+ {"id":"","text":"Inpaint batch mask directory","localized":"","hint":""},
+ {"id":"","text":"Resize fixed","localized":"","hint":"Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio"},
+ {"id":"","text":"Crop and resize","localized":"","hint":"Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out"},
+ {"id":"","text":"Resize and fill","localized":"","hint":"Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors"},
+ {"id":"","text":"Resize using Latent upscale","localized":"","hint":""},
+ {"id":"","text":"Mask blur","localized":"","hint":"How much to blur the mask before processing, in pixels"},
+ {"id":"","text":"Mask transparency","localized":"","hint":""},
+ {"id":"","text":"Inpaint masked","localized":"","hint":""},
+ {"id":"","text":"Inpaint not masked","localized":"","hint":""},
+ {"id":"","text":"fill","localized":"","hint":"fill it with colors of the image"},
+ {"id":"","text":"original","localized":"","hint":"keep whatever was there originally"},
+ {"id":"","text":"latent noise","localized":"","hint":"fill it with latent space noise"},
+ {"id":"","text":"latent nothing","localized":"","hint":"fill it with latent space zeroes"},
+ {"id":"","text":"Whole picture","localized":"","hint":""},
+ {"id":"","text":"Only masked","localized":"","hint":""},
+ {"id":"","text":"Only masked padding, pixels","localized":"","hint":""},
+ {"id":"","text":"Scale","localized":"","hint":""},
+ {"id":"","text":"Unused","localized":"","hint":""},
+ {"id":"","text":"Image CFG Scale","localized":"","hint":""}
+ ],
+ "train tabs": [
+ {"id":"","text":"Merge models ","localized":"","hint":""},
+ {"id":"","text":"Create embedding ","localized":"","hint":""},
+ {"id":"","text":"Create hypernetwork ","localized":"","hint":""},
+ {"id":"","text":"Preprocess images ","localized":"","hint":""},
+ {"id":"","text":"Merge","localized":"","hint":""},
+ {"id":"","text":"Calculate hash for all models (may take a long time)","localized":"","hint":""},
+ {"id":"","text":"Create embedding","localized":"","hint":""},
+ {"id":"","text":"Create hypernetwork","localized":"","hint":""},
+ {"id":"","text":"Preprocess","localized":"","hint":""},
+ {"id":"","text":"Train Embedding","localized":"","hint":""},
+ {"id":"","text":"Train Hypernetwork","localized":"","hint":""}
+ ],
+ "train tab": [
+ {"id":"","text":"Primary model","localized":"","hint":""},
+ {"id":"","text":"Secondary model","localized":"","hint":""},
+ {"id":"","text":"Tertiary model","localized":"","hint":""},
+ {"id":"","text":"New model name","localized":"","hint":""},
+ {"id":"","text":"No interpolation","localized":"","hint":"Result = A"},
+ {"id":"","text":"Weighted sum","localized":"","hint":"Result = A * (1 - M) + B * M"},
+ {"id":"","text":"Add difference","localized":"","hint":"Result = A + (B - C) * M"},
+ {"id":"","text":"Interpolation ratio from Primary to Secondary","localized":"","hint":""},
+ {"id":"","text":"ckpt","localized":"","hint":""},
+ {"id":"","text":"safetensors","localized":"","hint":""},
+ {"id":"","text":"Use FP16","localized":"","hint":""},
+ {"id":"","text":"Save metadata","localized":"","hint":""},
+ {"id":"","text":"Primary","localized":"","hint":""},
+ {"id":"","text":"Secondary","localized":"","hint":""},
+ {"id":"","text":"Tertiary","localized":"","hint":""},
+ {"id":"","text":"Bake in VAE","localized":"","hint":""},
+ {"id":"","text":"Discard weights with matching name","localized":"","hint":"Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights"},
+ {"id":"","text":"Name","localized":"","hint":""},
+ {"id":"","text":"Initialization text","localized":"","hint":"If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors"},
+ {"id":"","text":"Number of vectors per token","localized":"","hint":""},
+ {"id":"","text":"Overwrite Old Embedding","localized":"","hint":""},
+ {"id":"","text":"Enter hypernetwork layer structure","localized":"","hint":""},
+ {"id":"","text":"Select activation function of hypernetwork. Recommended : Swish / Linear(none)","localized":"","hint":""},
+ {"id":"","text":"Select Layer weights initialization. Recommended: Kaiming for relu-like, Xavier for sigmoid-like, Normal otherwise","localized":"","hint":""},
+ {"id":"","text":"Add layer normalization","localized":"","hint":""},
+ {"id":"","text":"Use dropout","localized":"","hint":""},
+ {"id":"","text":"Enter hypernetwork Dropout structure (or empty). Recommended : 0~0.35 incrementing sequence: 0, 0.05, 0.15","localized":"","hint":""},
+ {"id":"","text":"Overwrite Old Hypernetwork","localized":"","hint":""},
+ {"id":"","text":"Source directory","localized":"","hint":""},
+ {"id":"","text":"Destination directory","localized":"","hint":""},
+ {"id":"","text":"Existing Caption txt Action","localized":"","hint":""},
+ {"id":"","text":"Keep original size","localized":"","hint":""},
+ {"id":"","text":"Keep original image channels","localized":"","hint":""},
+ {"id":"","text":"Create flipped copies","localized":"","hint":""},
+ {"id":"","text":"Split oversized images","localized":"","hint":""},
+ {"id":"","text":"Auto focal point crop","localized":"","hint":""},
+ {"id":"","text":"Auto-sized crop","localized":"","hint":""},
+ {"id":"","text":"Create captions only","localized":"","hint":""},
+ {"id":"","text":"Create BLIP captions","localized":"","hint":""},
+ {"id":"","text":"Create Deepbooru captions","localized":"","hint":""},
+ {"id":"","text":"Split image threshold","localized":"","hint":""},
+ {"id":"","text":"Split image overlap ratio","localized":"","hint":""},
+ {"id":"","text":"Focal point face weight","localized":"","hint":""},
+ {"id":"","text":"Focal point entropy weight","localized":"","hint":""},
+ {"id":"","text":"Focal point edges weight","localized":"","hint":""},
+ {"id":"","text":"Create debug image","localized":"","hint":""},
+ {"id":"","text":"Dimension lower bound","localized":"","hint":""},
+ {"id":"","text":"Dimension upper bound","localized":"","hint":""},
+ {"id":"","text":"Area lower bound","localized":"","hint":""},
+ {"id":"","text":"Area upper bound","localized":"","hint":""},
+ {"id":"","text":"Maximize area","localized":"","hint":""},
+ {"id":"","text":"Minimize error","localized":"","hint":""},
+ {"id":"","text":"Error threshold","localized":"","hint":""},
+ {"id":"","text":"Embedding","localized":"","hint":""},
+ {"id":"","text":"Hypernetwork","localized":"","hint":""},
+ {"id":"","text":"Embedding Learning rate","localized":"","hint":""},
+ {"id":"","text":"Hypernetwork Learning rate","localized":"","hint":""},
+ {"id":"","text":"Gradient Clipping","localized":"","hint":""},
+ {"id":"","text":"Gradient accumulation steps","localized":"","hint":""},
+ {"id":"","text":"Dataset directory","localized":"","hint":""},
+ {"id":"","text":"Log directory","localized":"","hint":""},
+ {"id":"","text":"Prompt template","localized":"","hint":""},
+ {"id":"","text":"Do not resize images","localized":"","hint":""},
+ {"id":"","text":"Max steps","localized":"","hint":""},
+ {"id":"","text":"Save an image to log directory every N steps, 0 to disable","localized":"","hint":""},
+ {"id":"","text":"Save a copy of embedding to log directory every N steps, 0 to disable","localized":"","hint":""},
+ {"id":"","text":"Use PNG alpha channel as loss weight","localized":"","hint":""},
+ {"id":"","text":"Save images with embedding in PNG chunks","localized":"","hint":""},
+ {"id":"","text":"Read parameters (prompt, etc...) from txt2img tab when making previews","localized":"","hint":""},
+ {"id":"","text":"Shuffle tags by ',' when creating prompts","localized":"","hint":""},
+ {"id":"","text":"Drop out tags when creating prompts","localized":"","hint":""},
+ {"id":"","text":"once","localized":"","hint":""},
+ {"id":"","text":"deterministic","localized":"","hint":""},
+ {"id":"","text":"random","localized":"","hint":""}
+ ],
+ "settings": [
+ {"id":"","text":"Number of cached model checkpoints","localized":"","hint":""},
+ {"id":"","text":"Number of cached VAE checkpoints","localized":"","hint":""},
+ {"id":"","text":"Select VAE","localized":"","hint":""},
+ {"id":"","text":"Enable splitting of hires batch processing","localized":"","hint":""},
+ {"id":"","text":"When loading models attempt stream loading optimized for slow or network storage","localized":"","hint":""},
+ {"id":"","text":"When loading models attempt to reuse previous model dictionary","localized":"","hint":""},
+ {"id":"","text":"Disable cross-attention layer optimization","localized":"","hint":""},
+ {"id":"","text":"xFormers","localized":"","hint":""},
+ {"id":"","text":"Scaled-Dot-Product","localized":"","hint":""},
+ {"id":"","text":"Doggettx's","localized":"","hint":""},
+ {"id":"","text":"InvokeAI's","localized":"","hint":""},
+ {"id":"","text":"Sub-quadratic","localized":"","hint":""},
+ {"id":"","text":"Split attention","localized":"","hint":""},
+ {"id":"","text":"xFormers enable flash Attention","localized":"","hint":""},
+ {"id":"","text":"SDP disable memory attention","localized":"","hint":""},
+ {"id":"","text":"Sub-quadratic cross-attention query chunk size","localized":"","hint":""},
+ {"id":"","text":"Sub-quadratic cross-attention kv chunk size","localized":"","hint":""},
+ {"id":"","text":"Sub-quadratic cross-attention chunking threshold","localized":"","hint":""},
+ {"id":"","text":"Full parser","localized":"","hint":""},
+ {"id":"","text":"Compel parser","localized":"","hint":""},
+ {"id":"","text":"A1111 parser","localized":"","hint":""},
+ {"id":"","text":"Fixed attention","localized":"","hint":""},
+ {"id":"","text":"Prompt attention mean normalization","localized":"","hint":""},
+ {"id":"","text":"Disable conditional batching enabled on low memory systems","localized":"","hint":""},
+ {"id":"","text":"Enable samplers quantization for sharper and cleaner results","localized":"","hint":""},
+ {"id":"","text":"Increase coherency by padding from the last comma within n tokens when using more than 75 tokens","localized":"","hint":""},
+ {"id":"","text":"Original","localized":"","hint":""},
+ {"id":"","text":"Diffusers","localized":"","hint":""},
+ {"id":"","text":"VRAM usage polls per second during generation","localized":"","hint":""},
+ {"id":"","text":"Autocast","localized":"","hint":""},
+ {"id":"","text":"Full","localized":"","hint":""},
+ {"id":"","text":"FP32","localized":"","hint":""},
+ {"id":"","text":"FP16","localized":"","hint":""},
+ {"id":"","text":"BF16","localized":"","hint":""},
+ {"id":"","text":"Use full precision for model (--no-half)","localized":"","hint":""},
+ {"id":"","text":"Use full precision for VAE (--no-half-vae)","localized":"","hint":""},
+ {"id":"","text":"Enable upcast sampling","localized":"","hint":""},
+ {"id":"","text":"Enable upcast cross attention layer","localized":"","hint":""},
+ {"id":"","text":"Disable NaN check in produced images/latent spaces","localized":"","hint":""},
+ {"id":"","text":"Attempt to roll back VAE when produced NaN values, requires NaN check (experimental)","localized":"","hint":""},
+ {"id":"","text":"Use channels last as torch memory format ","localized":"","hint":""},
+ {"id":"","text":"Enable full-depth cuDNN benchmark feature","localized":"","hint":""},
+ {"id":"","text":"Allow TF32 math ops","localized":"","hint":""},
+ {"id":"","text":"Allow TF16 reduced precision math ops","localized":"","hint":""},
+ {"id":"","text":"Enable model compile (experimental)","localized":"","hint":""},
+ {"id":"","text":"inductor","localized":"","hint":""},
+ {"id":"","text":"cudagraphs","localized":"","hint":""},
+ {"id":"","text":"aot_ts_nvfuser","localized":"","hint":""},
+ {"id":"","text":"hidet","localized":"","hint":""},
+ {"id":"","text":"ipex","localized":"","hint":""},
+ {"id":"","text":"Model compile verbose mode","localized":"","hint":""},
+ {"id":"","text":"Model compile suppress errors","localized":"","hint":""},
+ {"id":"","text":"Disable Torch memory garbage collection (experimental)","localized":"","hint":""},
+ {"id":"","text":"Directory for temporary images; leave empty for default","localized":"","hint":""},
+ {"id":"","text":"Cleanup non-default temporary directory when starting webui","localized":"","hint":""},
+ {"id":"","text":"Path to directory with stable diffusion checkpoints","localized":"","hint":""},
+ {"id":"","text":"Path to directory with stable diffusion diffusers","localized":"","hint":""},
+ {"id":"","text":"Path to directory with VAE files","localized":"","hint":""},
+ {"id":"","text":"Embeddings directory for textual inversion","localized":"","hint":""},
+ {"id":"","text":"Hypernetwork directory","localized":"","hint":""},
+ {"id":"","text":"Path to directory with codeformer model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with GFPGAN model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with ESRGAN model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with BSRGAN model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with RealESRGAN model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with ScuNET model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with SwinIR model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with LDSR model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with CLIP model file(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with Lora network(s)","localized":"","hint":""},
+ {"id":"","text":"Path to directory with LyCORIS network(s)","localized":"","hint":""},
+ {"id":"","text":"Path to user-defined styles file","localized":"","hint":""},
+ {"id":"","text":"Always save all generated images","localized":"","hint":""},
+ {"id":"","text":"File format for generated images","localized":"","hint":""},
+ {"id":"","text":"Images filename pattern","localized":"","hint":"Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime], [datetime
"
)
- img2img_batch_input_dir = gr.Textbox(label="Input directory", **modules.shared.hide_dirs, elem_id="img2img_batch_input_dir")
- img2img_batch_output_dir = gr.Textbox(label="Output directory", **modules.shared.hide_dirs, elem_id="img2img_batch_output_dir")
- img2img_batch_inpaint_mask_dir = gr.Textbox(label="Inpaint batch mask directory (required for inpaint batch processing only)", **modules.shared.hide_dirs, elem_id="img2img_batch_inpaint_mask_dir")
+ img2img_batch_input_dir = gr.Textbox(label="Inpaint batch input directory", **modules.shared.hide_dirs, elem_id="img2img_batch_input_dir")
+ img2img_batch_output_dir = gr.Textbox(label="Inpaint batch output directory", **modules.shared.hide_dirs, elem_id="img2img_batch_output_dir")
+ img2img_batch_inpaint_mask_dir = gr.Textbox(label="Inpaint batch mask directory", **modules.shared.hide_dirs, elem_id="img2img_batch_inpaint_mask_dir")
img2img_tabs = [tab_img2img, tab_sketch, tab_inpaint, tab_inpaint_color, tab_inpaint_upload, tab_batch]
img2img_image_inputs = [init_img, sketch, init_img_with_mask, inpaint_color_sketch] # pylint: disable=unused-variable
@@ -626,7 +624,7 @@ def create_ui():
)
with FormRow():
- resize_mode = gr.Radio(label="Resize mode", elem_id="resize_mode", choices=["Just resize", "Crop and resize", "Resize and fill", "Just resize (latent upscale)"], type="index", value="Just resize")
+ resize_mode = gr.Radio(label="Resize mode", elem_id="resize_mode", choices=["Resize fixed", "Crop and resize", "Resize and fill", "Resize using Latent upscale"], type="index", value="Resize and fill")
for category in ordered_ui_categories():
if category == "sampler":
diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py
index dc3298fe8..296616492 100644
--- a/modules/ui_extensions.py
+++ b/modules/ui_extensions.py
@@ -432,7 +432,7 @@ def create_ui():
outputs=[extensions_table, info],
)
with gr.TabItem("Manual install", id="install_from_url"):
- install_url = gr.Text(label="URL for extension's git repository")
+ install_url = gr.Text(label="Extension GIT repository URL")
install_branch = gr.Text(label="Specific branch name", placeholder="Leave empty for default main branch")
install_dirname = gr.Text(label="Local directory name", placeholder="Leave empty for auto")
install_button = gr.Button(value="Install", variant="primary")
diff --git a/scripts/prompt_matrix.py b/scripts/prompt_matrix.py
index 8614b59d9..3d8d682db 100644
--- a/scripts/prompt_matrix.py
+++ b/scripts/prompt_matrix.py
@@ -51,7 +51,7 @@ class Script(scripts.Script):
prompt_type = gr.Radio(["positive", "negative"], label="Select prompt", elem_id=self.elem_id("prompt_type"), value="positive")
variations_delimiter = gr.Radio(["comma", "space"], label="Select joining char", elem_id=self.elem_id("variations_delimiter"), value="comma")
with gr.Column():
- margin_size = gr.Slider(label="Grid margins (px)", minimum=0, maximum=500, value=0, step=2, elem_id=self.elem_id("margin_size"))
+ margin_size = gr.Slider(label="Grid margins", minimum=0, maximum=500, value=0, step=2, elem_id=self.elem_id("margin_size"))
return [put_at_start, different_seeds, prompt_type, variations_delimiter, margin_size]
diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py
index 43304cb4b..0175d07a0 100644
--- a/scripts/xyz_grid.py
+++ b/scripts/xyz_grid.py
@@ -408,7 +408,7 @@ class Script(scripts.Script):
include_lone_images = gr.Checkbox(label='Include Sub Images', value=False, elem_id=self.elem_id("include_lone_images"))
include_sub_grids = gr.Checkbox(label='Include Sub Grids', value=False, elem_id=self.elem_id("include_sub_grids"))
with gr.Row(variant="compact", elem_id="axis_options"):
- margin_size = gr.Slider(label="Grid margins (px)", minimum=0, maximum=500, value=0, step=2, elem_id=self.elem_id("margin_size"))
+ margin_size = gr.Slider(label="Grid margins", minimum=0, maximum=500, value=0, step=2, elem_id=self.elem_id("margin_size"))
with gr.Row(variant="compact", elem_id="swap_axes"):
swap_xy_axes_button = gr.Button(value="Swap X/Y axes", elem_id="xy_grid_swap_axes_button")
swap_yz_axes_button = gr.Button(value="Swap Y/Z axes", elem_id="yz_grid_swap_axes_button")
diff --git a/webui.py b/webui.py
index 8f090b415..6b2151a17 100644
--- a/webui.py
+++ b/webui.py
@@ -6,7 +6,7 @@ import asyncio
import logging
import warnings
from threading import Thread
-from modules import timer, errors
+from modules import timer, errors, paths # pylint: disable=unused-import
startup_timer = timer.Timer()
local_url = None
@@ -241,8 +241,8 @@ def start_ui():
"version": f'0.0.{installer.git_commit}',
"title": "SD.Next",
"description": "SD.Next",
- "docs_url": "/docs",
- "redocs_url": "/redocs",
+ # "docs_url": "/docs",
+ # "redocs_url": "/redocs",
"swagger_ui_parameters": {
"displayOperationId": True,
"showCommonExtensions": True,
From c49b6c34e1c8d5f5496ba5165a457147454cb0ef Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Mon, 5 Jun 2023 15:14:50 -0400
Subject: [PATCH 06/27] fix extra networks
---
.../Lora/ui_extra_networks_lora.py | 6 ++++--
javascript/prompt-bracket-checker.js | 2 +-
javascript/script.js | 2 +-
modules/ui_extra_networks.py | 21 +++++++++----------
4 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/extensions-builtin/Lora/ui_extra_networks_lora.py b/extensions-builtin/Lora/ui_extra_networks_lora.py
index dad4500e7..8cbcbe9d3 100644
--- a/extensions-builtin/Lora/ui_extra_networks_lora.py
+++ b/extensions-builtin/Lora/ui_extra_networks_lora.py
@@ -22,9 +22,11 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
"preview": self.find_preview(path),
"description": self.find_description(path),
"search_term": self.search_terms_from_path(lora_on_disk.filename),
- "prompt": json.dumps(f""),
+ + " + " + json.dumps(">")
+ ),
"local_preview": f"{path}.{shared.opts.samples_format}",
"metadata": json.dumps(lora_on_disk.metadata, indent=4) if lora_on_disk.metadata else None,
}
diff --git a/javascript/prompt-bracket-checker.js b/javascript/prompt-bracket-checker.js
index 114cf94cc..444c676aa 100644
--- a/javascript/prompt-bracket-checker.js
+++ b/javascript/prompt-bracket-checker.js
@@ -34,7 +34,7 @@ function setupBracketChecking(id_prompt, id_counter) {
}
}
-onUiLoaded(function() {
+onAfterUiUpdate(function() {
setupBracketChecking('txt2img_prompt', 'txt2img_token_counter');
setupBracketChecking('txt2img_neg_prompt', 'txt2img_negative_token_counter');
setupBracketChecking('img2img_prompt', 'img2img_token_counter');
diff --git a/javascript/script.js b/javascript/script.js
index 9b07a40c1..ccf5767bb 100644
--- a/javascript/script.js
+++ b/javascript/script.js
@@ -42,7 +42,7 @@ function onOptionsChanged(callback) {
}
function executeCallbacks(queue, arg) {
- if (!uiLoaded) return
+ // if (!uiLoaded) return
for (const callback of queue) {
try {
callback(arg);
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index 929f671c5..80e7a9e7e 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -112,8 +112,7 @@ class ExtraNetworksPage:
subdirs_html = "".join([f"""
- """ for subdir in subdirs])
+ """ for subdir in subdirs])
try:
self.items = list(self.list_items())
self.create_xyz_grid()
@@ -232,20 +231,20 @@ def create_ui(container, button, tabname):
ui.stored_extra_pages = pages_in_preferred_order(extra_pages.copy())
ui.tabname = tabname
with gr.Tabs(elem_id=tabname+"_extra_tabs"):
+ ui.search = gr.Textbox('', show_label=False, elem_id=tabname+"_extra_search", placeholder="Search...", visible=True)
+ ui.description_input = gr.TextArea('', show_label=False, elem_id=tabname+"_description_input", placeholder="Save/Replace Extra Network Description...", lines=2)
+ button_refresh = ToolButton(refresh_symbol, elem_id=tabname+"_extra_refresh")
+ button_close = ToolButton(close_symbol, elem_id=tabname+"_extra_close")
for page in ui.stored_extra_pages:
+ ui.button_save_preview = gr.Button('Save preview', elem_id=tabname+"_save_preview", visible=False)
+ ui.preview_target_filename = gr.Textbox('Preview save filename', elem_id=tabname+"_preview_filename", visible=False)
+ ui.button_save_description = gr.Button('Save description', elem_id=tabname+"_save_description", visible=False)
+ ui.button_read_description = gr.Button('Read description', elem_id=tabname+"_read_description", visible=False)
+ ui.description_target_filename = gr.Textbox('Description save filename', elem_id=tabname+"_description_filename", visible=False)
with gr.Tab(page.title, id=page.title.lower().replace(" ", "_")):
page_elem = gr.HTML(page.create_html(ui.tabname))
page_elem.change(fn=lambda: None, _js=f'() => refreshExtraNetworks("{tabname}")', inputs=[], outputs=[])
ui.pages.append(page_elem)
- ui.search = gr.Textbox('', show_label=False, elem_id=tabname+"_extra_search", placeholder="Search...", visible=False)
- ui.description_input = gr.TextArea('', show_label=False, elem_id=tabname+"_description_input", placeholder="Save/Replace Extra Network Description...", lines=2)
- button_refresh = ToolButton(refresh_symbol, elem_id=tabname+"_extra_refresh")
- button_close = ToolButton(close_symbol, elem_id=tabname+"_extra_close")
- ui.button_save_preview = gr.Button('Save preview', elem_id=tabname+"_save_preview", visible=False)
- ui.preview_target_filename = gr.Textbox('Preview save filename', elem_id=tabname+"_preview_filename", visible=False)
- ui.button_save_description = gr.Button('Save description', elem_id=tabname+"_save_description", visible=False)
- ui.button_read_description = gr.Button('Read description', elem_id=tabname+"_read_description", visible=False)
- ui.description_target_filename = gr.Textbox('Description save filename', elem_id=tabname+"_description_filename", visible=False)
def toggle_visibility(is_visible):
is_visible = not is_visible
From 45806805381ec90e7d76a4739393d831c8808255 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Mon, 5 Jun 2023 15:39:46 -0400
Subject: [PATCH 07/27] allow access to files in data-dir
---
modules/ui.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/ui.py b/modules/ui.py
index 727fff97e..572f0aaad 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1421,7 +1421,7 @@ def create_ui():
for _interface, label, _ifid in interfaces:
modules.shared.tab_names.append(label)
- with gr.Blocks(theme=modules.shared.gradio_theme, analytics_enabled=False, title="SD.Next") as demo:
+ with gr.Blocks(theme=modules.shared.gradio_theme, analytics_enabled=False, title="SD.Next", allowed_paths=[cmd_opts.data_dir]) as demo:
with gr.Row(elem_id="quicksettings", variant="compact"):
for i, k, item in sorted(quicksettings_list, key=lambda x: quicksettings_names.get(x[1], x[0])):
component = create_setting_component(k, is_quicksettings=True)
From da38d27f88d74590079406fedf31c0023e6c6533 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Mon, 5 Jun 2023 16:07:51 -0400
Subject: [PATCH 08/27] fix train
---
CHANGELOG.md | 11 +++++++++--
cli/train.py | 6 +++---
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5c62d2c26..4b5eadde2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
# Change Log for SD.Next
-## Update for 06/03/2023
+## Update for 06/05/2023
+
+Few new features and extra handling for broken extensions
+that caused my phone to go crazy with notifications over the weekend...
- added extra networks to **xyz grid** options
now you can have more fun with all your embeddings and loras :)
@@ -8,10 +11,14 @@
- new setting -> lora -> **use lycoris to handle all lora types**
this is still experimental, but the goal is to obsolete old built-in lora module
as it doesn't understand many new loras and built-in lyco module can handle it all
-- optimize browser page loading
+- somewhat optimize browser page loading
+ still slower than i'd want, but gradio is pretty bad at this
- profiling of scripts/extensions callbacks
+ you can now see how much or pre/post processing is done, not just how long generate takes
- additional exception handling so bad exception does not crash main app
- additional background removal models
+- some work on bfloat16 which nobody really should be using, but why not 🙂
+
## Update for 06/02/2023
diff --git a/cli/train.py b/cli/train.py
index 8ee5a675e..2f68bbb40 100755
--- a/cli/train.py
+++ b/cli/train.py
@@ -164,9 +164,9 @@ def verify_args():
if not os.path.isfile(args.model):
log.error(f'cannot find loaded model: {args.model}')
exit(1)
- if not os.path.exists(args.ckpt_dir) or not os.path.isdir(args.ckpt_dir):
- log.error(f'cannot find models folder: {args.ckpt_dir}')
- exit(1)
+ # if not os.path.exists(args.ckpt_dir) or not os.path.isdir(args.ckpt_dir):
+ # log.error(f'cannot find models folder: {args.ckpt_dir}')
+ # exit(1)
if not os.path.exists(args.input) or not os.path.isdir(args.input):
log.error(f'cannot find training folder: {args.input}')
exit(1)
From fff3bda6cf0f863bd1ac3320f68a27850c33a249 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Tue, 6 Jun 2023 07:52:59 -0400
Subject: [PATCH 09/27] fix extra network save preview/description
---
extensions-builtin/a1111-sd-webui-lycoris | 2 +-
extensions-builtin/sd-webui-agent-scheduler | 2 +-
extensions-builtin/sd-webui-controlnet | 2 +-
.../stable-diffusion-webui-images-browser | 2 +-
javascript/extraNetworks.js | 1 +
modules/ui_extra_networks.py | 22 +++++++++----------
6 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/extensions-builtin/a1111-sd-webui-lycoris b/extensions-builtin/a1111-sd-webui-lycoris
index 1e5db3921..e47548884 160000
--- a/extensions-builtin/a1111-sd-webui-lycoris
+++ b/extensions-builtin/a1111-sd-webui-lycoris
@@ -1 +1 @@
-Subproject commit 1e5db39210df4dd3bb6f3667d9e690c447939e71
+Subproject commit e47548884864da9cfe30f6f33fbaa8e731d3dd85
diff --git a/extensions-builtin/sd-webui-agent-scheduler b/extensions-builtin/sd-webui-agent-scheduler
index 08cdc1854..340102006 160000
--- a/extensions-builtin/sd-webui-agent-scheduler
+++ b/extensions-builtin/sd-webui-agent-scheduler
@@ -1 +1 @@
-Subproject commit 08cdc1854f126ec213f8462bdf81cdb0032bee69
+Subproject commit 3401020066a20444594ec2902d95217b0cd95e94
diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet
index f36493878..1b2aa4a96 160000
--- a/extensions-builtin/sd-webui-controlnet
+++ b/extensions-builtin/sd-webui-controlnet
@@ -1 +1 @@
-Subproject commit f36493878b299c367bc51f2935fd7e6d19188569
+Subproject commit 1b2aa4a96e9241b96abfbce249284ed17fc98b11
diff --git a/extensions-builtin/stable-diffusion-webui-images-browser b/extensions-builtin/stable-diffusion-webui-images-browser
index 488c5393d..342efe98c 160000
--- a/extensions-builtin/stable-diffusion-webui-images-browser
+++ b/extensions-builtin/stable-diffusion-webui-images-browser
@@ -1 +1 @@
-Subproject commit 488c5393db60f0b1ddfb8ab18f3db9119227c962
+Subproject commit 342efe98c747aecbdde35144d017f9eaf2dd025a
diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js
index a8c54bf7b..d43aa2244 100644
--- a/javascript/extraNetworks.js
+++ b/javascript/extraNetworks.js
@@ -72,6 +72,7 @@ function cardClicked(tabname, textToAdd, allowNegativePrompt) {
}
function saveCardPreview(event, tabname, filename) {
+ console.log('saveCardPreview', event, tabname, filename)
const textarea = gradioApp().querySelector(`#${tabname}_preview_filename > label > textarea`);
const button = gradioApp().getElementById(`${tabname}_save_preview`);
textarea.value = filename;
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index 80e7a9e7e..5119f2301 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -235,12 +235,12 @@ def create_ui(container, button, tabname):
ui.description_input = gr.TextArea('', show_label=False, elem_id=tabname+"_description_input", placeholder="Save/Replace Extra Network Description...", lines=2)
button_refresh = ToolButton(refresh_symbol, elem_id=tabname+"_extra_refresh")
button_close = ToolButton(close_symbol, elem_id=tabname+"_extra_close")
+ ui.button_save_preview = gr.Button('Save preview', elem_id=tabname+"_save_preview", visible=False)
+ ui.preview_target_filename = gr.Textbox('Preview save filename', elem_id=tabname+"_preview_filename", visible=False)
+ ui.button_save_description = gr.Button('Save description', elem_id=tabname+"_save_description", visible=False)
+ ui.button_read_description = gr.Button('Read description', elem_id=tabname+"_read_description", visible=False)
+ ui.description_target_filename = gr.Textbox('Description save filename', elem_id=tabname+"_description_filename", visible=False)
for page in ui.stored_extra_pages:
- ui.button_save_preview = gr.Button('Save preview', elem_id=tabname+"_save_preview", visible=False)
- ui.preview_target_filename = gr.Textbox('Preview save filename', elem_id=tabname+"_preview_filename", visible=False)
- ui.button_save_description = gr.Button('Save description', elem_id=tabname+"_save_description", visible=False)
- ui.button_read_description = gr.Button('Read description', elem_id=tabname+"_read_description", visible=False)
- ui.description_target_filename = gr.Textbox('Description save filename', elem_id=tabname+"_description_filename", visible=False)
with gr.Tab(page.title, id=page.title.lower().replace(" ", "_")):
page_elem = gr.HTML(page.create_html(ui.tabname))
page_elem.change(fn=lambda: None, _js=f'() => refreshExtraNetworks("{tabname}")', inputs=[], outputs=[])
@@ -289,6 +289,7 @@ def setup_ui(ui, gallery):
break
assert is_allowed, f'writing to {filename} is not allowed'
image.save(filename)
+ shared.log.info(f'Extra network save preview: {filename}')
return [page.create_html(ui.tabname) for page in ui.stored_extra_pages]
ui.button_save_preview.click(
@@ -304,12 +305,11 @@ def setup_ui(ui, gallery):
filename = filename[0:lastDotIndex]+".description.txt"
if descrip != "":
try:
- f = open(filename,'w', encoding='utf-8')
- except OSError:
- print ("Could not open file to write: " + filename)
- with f:
- f.write(descrip)
- f.close()
+ with open(filename,'w', encoding='utf-8') as f:
+ f.write(descrip)
+ shared.log.info(f'Extra network save description: {filename}')
+ except Exception as e:
+ shared.log.error(f'Extra network save preview: {filename} {e}')
return [page.create_html(ui.tabname) for page in ui.stored_extra_pages]
ui.button_save_description.click(
From 2c23d88409435de198f543be53e58742a68a00bb Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Tue, 6 Jun 2023 08:23:08 -0400
Subject: [PATCH 10/27] update style
---
javascript/style.css | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/javascript/style.css b/javascript/style.css
index 4c667d584..e1bfd2027 100644
--- a/javascript/style.css
+++ b/javascript/style.css
@@ -93,7 +93,7 @@ footer { display: none !important; }
}
.performance { font-size: 0.85em; color: #444; }
-.performance p { display: inline-block; color: var(--primary-100) !important }
+.performance p { display: inline-block; color: var(--body-text-color-subdued) !important }
.performance .time { margin-right: 0; }
@media screen and (min-width: 2500px) {
@@ -585,3 +585,4 @@ div.controlnet_main_options { display: grid; grid-template-columns: 1fr 1fr; gri
#scripts_alwayson_txt2img, #scripts_alwayson_img2img { display: grid }
#extras_generate, #extras_interrupt, #extras_skip { display: block !important; position: relative; height: 36px; }
#extras_upscale { margin-top: 10px }
+#refresh_tac_refreshTempFiles { display: none; }
From f0ad70c80a742ab83e6d6f1eedaa085450b021ac Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Tue, 6 Jun 2023 08:48:11 -0400
Subject: [PATCH 11/27] fix upscalers
---
TODO.md | 1 +
.../SwinIR/scripts/swinir_model.py | 10 +++----
modules/upscaler.py | 29 ++++++++-----------
3 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/TODO.md b/TODO.md
index e543fe3b6..b27447c36 100644
--- a/TODO.md
+++ b/TODO.md
@@ -56,3 +56,4 @@ Tech that can be integrated as part of the core workflow...
- docker
- port `p.all_hr_prompts`
- test `lyco_patch_lora`
+- fix `lyco` logging
diff --git a/extensions-builtin/SwinIR/scripts/swinir_model.py b/extensions-builtin/SwinIR/scripts/swinir_model.py
index 1c7bf325e..d07c9acb5 100644
--- a/extensions-builtin/SwinIR/scripts/swinir_model.py
+++ b/extensions-builtin/SwinIR/scripts/swinir_model.py
@@ -1,15 +1,13 @@
import os
-
import numpy as np
import torch
from PIL import Image
from basicsr.utils.download_util import load_file_from_url
from tqdm import tqdm
-
-from modules import modelloader, devices, script_callbacks, shared
-from modules.shared import opts, state
from swinir_model_arch import SwinIR as net
from swinir_model_arch_v2 import Swin2SR as net2
+from modules import modelloader, devices, script_callbacks, shared
+from modules.shared import opts, state
from modules.upscaler import Upscaler, UpscalerData
@@ -36,8 +34,8 @@ class UpscalerSwinIR(Upscaler):
scalers.append(model_data)
self.scalers = scalers
- def do_upscale(self, img, model_file):
- model = self.load_model(model_file)
+ def do_upscale(self, img, selected_model):
+ model = self.load_model(selected_model)
if model is None:
return img
model = model.to(device_swinir, dtype=devices.dtype)
diff --git a/modules/upscaler.py b/modules/upscaler.py
index d35edce68..34bb83230 100644
--- a/modules/upscaler.py
+++ b/modules/upscaler.py
@@ -4,7 +4,8 @@ from abc import abstractmethod
import PIL
from PIL import Image
-from modules import modelloader, shared
+import modules.shared
+from modules import modelloader
LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
NEAREST = (Image.Resampling.NEAREST if hasattr(Image, 'Resampling') else Image.NEAREST)
@@ -24,25 +25,26 @@ class Upscaler:
def __init__(self, create_dirs=False):
self.mod_pad_h = None
- self.tile_size = shared.opts.ESRGAN_tile
- self.tile_pad = shared.opts.ESRGAN_tile_overlap
- self.device = shared.device
+ self.tile_size = modules.shared.opts.ESRGAN_tile
+ self.tile_pad = modules.shared.opts.ESRGAN_tile_overlap
+ self.device = modules.shared.device
self.img = None
self.output = None
self.scale = 1
- self.half = not shared.opts.no_half
+ self.half = not modules.shared.cmd_opts.no_half
self.pre_pad = 0
self.mod_scale = None
+ self.model_download_path = None
if self.model_path is None and self.name:
- self.model_path = os.path.join(shared.models_path, self.name)
+ self.model_path = os.path.join(modules.shared.models_path, self.name)
if self.model_path and create_dirs:
os.makedirs(self.model_path, exist_ok=True)
try:
- import cv2 # pylint: disable=unused-import
+ import cv2 # pylint: disable=unused-import
self.can_tile = True
- except:
+ except Exception:
pass
@abstractmethod
@@ -50,25 +52,18 @@ class Upscaler:
return img
def upscale(self, img: PIL.Image, scale, selected_model: str = None):
- shared.log.debug(f'upscale: {img}|{scale}|{selected_model}')
self.scale = scale
dest_w = int(img.width * scale)
dest_h = int(img.height * scale)
-
- for _i in range(3):
+ for _ in range(3):
shape = (img.width, img.height)
-
img = self.do_upscale(img, selected_model)
-
if shape == (img.width, img.height):
break
-
if img.width >= dest_w and img.height >= dest_h:
break
-
if img.width != dest_w or img.height != dest_h:
img = img.resize((int(dest_w), int(dest_h)), resample=LANCZOS)
-
return img
@abstractmethod
@@ -79,7 +74,7 @@ class Upscaler:
return modelloader.load_models(model_path=self.model_path, model_url=self.model_url, command_path=self.user_path)
def update_status(self, prompt):
- print(f"\nextras: {prompt}")
+ print(f"\nextras: {prompt}", file=modules.shared.progress_print_out)
class UpscalerData:
From ac20b37e1ab1323163564ac8997469b4bd136363 Mon Sep 17 00:00:00 2001
From: Alexander Brown
Date: Tue, 6 Jun 2023 08:31:38 -0700
Subject: [PATCH 12/27] Update ui_extensions.py
---
modules/ui_extensions.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py
index 296616492..58342e410 100644
--- a/modules/ui_extensions.py
+++ b/modules/ui_extensions.py
@@ -112,7 +112,7 @@ def check_updates(_id_task, disable_list, search_text, sort_column):
except FileNotFoundError as e:
if 'FETCH_HEAD' not in str(e):
raise
- except Exception:
+ except Exception as e:
errors.display(e, f'extensions check update: {ext.name}')
shared.state.nextjob()
return refresh_extensions_list_from_data(search_text, sort_column), "Extension update complete | Restart required"
From b8f432aff4aa5d7c4fd4ae82f2a122844f830c51 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Tue, 6 Jun 2023 12:01:08 -0400
Subject: [PATCH 13/27] cleanup
---
installer.py | 24 +++++++++++++-----------
launch.py | 1 +
modules/extensions.py | 2 +-
modules/lora | 2 +-
modules/script_loading.py | 2 ++
5 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/installer.py b/installer.py
index 49b2be294..f31c25106 100644
--- a/installer.py
+++ b/installer.py
@@ -120,7 +120,7 @@ def installed(package, friendly: str = None):
ok = ok and spec is not None
if ok:
version = pkg_resources.get_distribution(p[0]).version
- log.debug(f"Package version found: {p[0]} {version}")
+ # log.debug(f"Package version found: {p[0]} {version}")
if len(p) > 1:
ok = ok and version == p[1]
if not ok:
@@ -419,14 +419,17 @@ def run_extension_installer(folder):
# get list of all enabled extensions
def list_extensions(folder):
- disabled_extensions = opts.get('disable_all_extensions', 'none')
- if disabled_extensions != 'none':
- log.debug(f'Disabled extensions: {disabled_extensions}')
+ name = os.path.basename(folder)
+ disabled_extensions_all = opts.get('disable_all_extensions', 'none')
+ if disabled_extensions_all != 'none':
+ log.info(f'Disabled {name}: {disabled_extensions_all}')
return []
- disabled_extensions = set(opts.get('disabled_extensions', []))
+ disabled_extensions = opts.get('disabled_extensions', [])
if len(disabled_extensions) > 0:
- log.debug(f'Disabled extensions: {disabled_extensions}')
- return [x for x in os.listdir(folder) if x not in disabled_extensions and not x.startswith('.')]
+ log.info(f'Disabled {name}: {disabled_extensions}')
+ enabled_extensions = [x for x in os.listdir(folder) if x not in disabled_extensions and not x.startswith('.')]
+ log.info(f'Enabled {name}: {enabled_extensions}')
+ return enabled_extensions
# run installer for each installed and enabled extension and optionally update them
@@ -572,7 +575,7 @@ def check_extensions():
ts = os.path.getmtime(os.path.join(extension_dir, f))
newest = max(newest, ts)
newest_all = max(newest_all, newest)
- log.debug(f'Extension version: {time.ctime(newest)} {folder}{os.pathsep}{ext}')
+ # log.debug(f'Extension version: {time.ctime(newest)} {folder}{os.pathsep}{ext}')
return round(newest_all)
@@ -712,7 +715,7 @@ def extensions_preload(force = False):
if 'Setup complete without errors' in line:
setup_time = int(line.split(' ')[-1])
if setup_time > 0 or force:
- log.info('Running extension preloading')
+ # log.info('Running extension preloading')
if args.safe:
log.info('Running in safe mode without user extensions')
try:
@@ -725,7 +728,7 @@ def extensions_preload(force = False):
t0 = time.time()
preload_extensions(ext_dir, parser)
t1 = time.time()
- log.debug(f'Extension preload: {round(t1 - t0, 1)}s {ext_dir}')
+ log.info(f'Extension preload: {round(t1 - t0, 1)}s {ext_dir}')
except:
log.error('Error running extension preloading')
if args.profile:
@@ -753,7 +756,6 @@ def read_options():
def run_setup():
# setup_logging(args.upgrade)
log.info('Starting SD.Next')
- read_options()
check_python()
if args.reset:
git_reset()
diff --git a/launch.py b/launch.py
index b00035b39..bc00d111c 100644
--- a/launch.py
+++ b/launch.py
@@ -13,6 +13,7 @@ installer.ensure_base_requirements()
installer.add_args()
installer.parse_args()
installer.setup_logging(False)
+installer.read_options()
installer.extensions_preload(force=False)
import modules.cmd_args
diff --git a/modules/extensions.py b/modules/extensions.py
index 65474592b..f5a5f39bf 100644
--- a/modules/extensions.py
+++ b/modules/extensions.py
@@ -139,7 +139,7 @@ def list_extensions():
shared.log.info(f'Skipping conflicting extension: {path}')
continue
extension_names.append(extension_dirname)
- extension_paths.append((extension_dirname, path, dirname == extensions_builtin_dir))
+ extension_paths.append((extension_dirname, path, dirname == dirname))
for dirname, path, is_builtin in extension_paths:
extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin)
extensions.append(extension)
diff --git a/modules/lora b/modules/lora
index 0fe1afd4e..363f1dfab 160000
--- a/modules/lora
+++ b/modules/lora
@@ -1 +1 @@
-Subproject commit 0fe1afd4efda89d3d4c8f25c5193c6859a32bc42
+Subproject commit 363f1dfab94a422765e72165f2648812dda92169
diff --git a/modules/script_loading.py b/modules/script_loading.py
index b28f6b65d..dd8170ff2 100644
--- a/modules/script_loading.py
+++ b/modules/script_loading.py
@@ -21,6 +21,8 @@ def preload_extensions(extensions_dir, parser):
if not os.path.isdir(extensions_dir):
return
for dirname in sorted(os.listdir(extensions_dir)):
+ # if dirname in opts.get('disabled_extensions', []): # TODO: preload happens before opts are parsed
+ # continue
if dirname in preloaded:
continue
preloaded.append(dirname)
From 82095082aff76466234b3e433c06bd5ea5d2422e Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Tue, 6 Jun 2023 15:32:22 -0400
Subject: [PATCH 14/27] fix model path on initial install
---
modules/generation_parameters_copypaste.py | 2 +-
modules/sd_models.py | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py
index 1ea0e24cb..8882502c8 100644
--- a/modules/generation_parameters_copypaste.py
+++ b/modules/generation_parameters_copypaste.py
@@ -352,7 +352,6 @@ def create_override_settings_dict(text_pairs):
def connect_paste(button, local_paste_fields, input_comp, override_settings_component, tabname):
def paste_func(prompt):
- shared.log.debug(f'paste prompt: {prompt}')
if prompt is not None and 'Negative prompt' not in prompt and 'Steps' not in prompt:
prompt = None
if not prompt and not shared.cmd_opts.hide_ui_dir_config:
@@ -362,6 +361,7 @@ def connect_paste(button, local_paste_fields, input_comp, override_settings_comp
prompt = file.read()
else:
prompt = ''
+ shared.log.debug(f'paste prompt: {prompt}')
params = parse_generation_parameters(prompt)
script_callbacks.infotext_pasted_callback(prompt, params)
res = []
diff --git a/modules/sd_models.py b/modules/sd_models.py
index 17dab145d..feebec737 100644
--- a/modules/sd_models.py
+++ b/modules/sd_models.py
@@ -108,6 +108,7 @@ def list_models():
if shared.backend == shared.Backend.ORIGINAL:
model_list = modelloader.load_models(model_path=os.path.join(models_path, 'Stable-diffusion'), model_url=None, command_path=shared.opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], download_name=None, ext_blacklist=[".vae.ckpt", ".vae.safetensors"])
else:
+ global model_path # pylint: disable=global-statement
model_path = os.path.join(models_path, 'Diffusers')
model_list = modelloader.load_diffusers(model_path=model_path, command_path=shared.opts.diffusers_dir)
for filename in sorted(model_list, key=str.lower):
From 2a664b1bdb6dcda2193abef0b9c8dd12f5b22c36 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Tue, 6 Jun 2023 17:32:34 -0400
Subject: [PATCH 15/27] new localization engine
---
html/locale_en.json | 1064 +++++++++++++-------------
javascript/hints.js | 97 ---
javascript/set-hints.js | 54 +-
modules/shared.py | 29 +-
scripts/postprocessing_codeformer.py | 2 +-
5 files changed, 576 insertions(+), 670 deletions(-)
delete mode 100644 javascript/hints.js
diff --git a/html/locale_en.json b/html/locale_en.json
index 448bb79a0..ed034d9eb 100755
--- a/html/locale_en.json
+++ b/html/locale_en.json
@@ -1,570 +1,564 @@
{ "icons": [
- {"id":"","text":"📘","localized":"","hint":"Read generation parameters from prompt or last generation if prompt is empty into user interface"},
- {"id":"","text":"🚮","localized":"","hint":"Clear prompt"},
- {"id":"","text":"🌐","localized":"","hint":"Show/hide extra networks"},
- {"id":"","text":"🧳","localized":"","hint":"Apply selected styles to current prompt"},
- {"id":"","text":"🛅","localized":"","hint":"Save style"},
- {"id":"","text":"🔄","localized":"","hint":"Refresh"},
- {"id":"","text":"❌","localized":"","hint":"Close"},
- {"id":"","text":"📒","localized":"","hint":"Fill"},
- {"id":"","text":"🎲️","localized":"","hint":"Use random seed"},
- {"id":"","text":"♻️","localized":"","hint":"Reuse previous seed"},
- {"id":"","text":"⇅","localized":"","hint":"Switch values"}
+ {"id":"","label":"📘","localized":"","hint":"Read generation parameters from prompt or last generation if prompt is empty into user interface"},
+ {"id":"","label":"🚮","localized":"","hint":"Clear prompt"},
+ {"id":"","label":"🌐","localized":"","hint":"Show/hide extra networks"},
+ {"id":"","label":"🧳","localized":"","hint":"Apply selected styles to current prompt"},
+ {"id":"","label":"🛅","localized":"","hint":"Save style"},
+ {"id":"","label":"🔄","localized":"","hint":"Refresh"},
+ {"id":"","label":"❌","localized":"","hint":"Close"},
+ {"id":"","label":"📒","localized":"","hint":"Fill"},
+ {"id":"","label":"🎲️","localized":"","hint":"Use random seed"},
+ {"id":"","label":"♻️","localized":"","hint":"Reuse previous seed"},
+ {"id":"","label":"⇅","localized":"","hint":"Switch values"}
],
"prompts": [
- {"id":"","text":"Prompt","localized":"","hint":"Prompt"},
- {"id":"","text":"Negative prompt","localized":"","hint":"Negative Prompt"}
+ {"id":"","label":"Prompt","localized":"","hint":"Prompt"},
+ {"id":"","label":"Negative prompt","localized":"","hint":"Negative Prompt"}
],
"tabs": [
- {"id":"","text":"From Text ","localized":"","hint":"Create image from text"},
- {"id":"","text":"From Image ","localized":"","hint":"Create image from image"},
- {"id":"","text":"Process Image ","localized":"","hint":"Process existing image"},
- {"id":"","text":"Train ","localized":"","hint":"Run training or model merging"},
- {"id":"","text":"Settings ","localized":"","hint":"Application settings"},
- {"id":"","text":"Extensions ","localized":"","hint":"Application extensions"}
+ {"id":"","label":"From Text ","localized":"txt2img","hint":"Create image from text"},
+ {"id":"","label":"From Image ","localized":"","hint":"Create image from image"},
+ {"id":"","label":"Process Image ","localized":"","hint":"Process existing image"},
+ {"id":"","label":"Train ","localized":"","hint":"Run training or model merging"},
+ {"id":"","label":"Settings ","localized":"","hint":"Application settings"},
+ {"id":"","label":"Extensions ","localized":"","hint":"Application extensions"}
],
"action panel": [
- {"id":"","text":"Generate","localized":"","hint":"Start processing"},
- {"id":"","text":"Stop","localized":"","hint":"Stop processing"},
- {"id":"","text":"Skip","localized":"","hint":"Stop processing current job and continue processing"},
- {"id":"","text":"Pause","localized":"","hint":"Pause processing"},
- {"id":"","text":"Interrogate\nCLIP","localized":"","hint":"Run interrogate using CLIP model"},
- {"id":"","text":"Interrogate\nDeepBooru","localized":"","hint":"Run interrogate using DeepBooru model"}
+ {"id":"","label":"Generate","localized":"","hint":"Start processing"},
+ {"id":"","label":"Stop","localized":"","hint":"Stop processing"},
+ {"id":"","label":"Skip","localized":"","hint":"Stop processing current job and continue processing"},
+ {"id":"","label":"Pause","localized":"","hint":"Pause processing"},
+ {"id":"","label":"Interrogate\nCLIP","localized":"","hint":"Run interrogate using CLIP model"},
+ {"id":"","label":"Interrogate\nDeepBooru","localized":"","hint":"Run interrogate using DeepBooru model"}
],
"extra networks": [
- {"id":"","text":"Save preview","localized":"","hint":"Save current image as extra network preview"},
- {"id":"","text":"Save description","localized":"","hint":"Save current text as extra network description"},
- {"id":"","text":"Read description","localized":"","hint":"Read stored extra network description"}
+ {"id":"","label":"Save preview","localized":"","hint":"Save current image as extra network preview"},
+ {"id":"","label":"Save description","localized":"","hint":"Save current text as extra network description"},
+ {"id":"","label":"Read description","localized":"","hint":"Read stored extra network description"}
],
"gallery buttons": [
- {"id":"","text":"show","localized":"","hint":"Show image location"},
- {"id":"","text":"save","localized":"","hint":"Save image"},
- {"id":"","text":"zip","localized":"","hint":"Create zip archive from images"},
- {"id":"","text":"delete","localized":"","hint":"Delete image"},
- {"id":"","text":"➠ text","localized":"","hint":"Transfer image to text interface"},
- {"id":"","text":"➠ image","localized":"","hint":"Transfer image to image interface"},
- {"id":"","text":"➠ inpaint","localized":"","hint":"Transfer image to inpaint interface"},
- {"id":"","text":"➠ sketch","localized":"","hint":"Transfer image to sketch interface"},
- {"id":"","text":"➠ inpaint sketch","localized":"","hint":"Transfer image to inpaint sketch interface"},
- {"id":"","text":"➠ process","localized":"","hint":"Transfer image to process interface"}
+ {"id":"","label":"show","localized":"","hint":"Show image location"},
+ {"id":"","label":"save","localized":"","hint":"Save image"},
+ {"id":"","label":"zip","localized":"","hint":"Create zip archive from images"},
+ {"id":"","label":"delete","localized":"","hint":"Delete image"},
+ {"id":"","label":"➠ text","localized":"","hint":"Transfer image to text interface"},
+ {"id":"","label":"➠ image","localized":"","hint":"Transfer image to image interface"},
+ {"id":"","label":"➠ inpaint","localized":"","hint":"Transfer image to inpaint interface"},
+ {"id":"","label":"➠ sketch","localized":"","hint":"Transfer image to sketch interface"},
+ {"id":"","label":"➠ inpaint sketch","localized":"","hint":"Transfer image to inpaint sketch interface"},
+ {"id":"","label":"➠ process","localized":"","hint":"Transfer image to process interface"}
],
"extensions": [
- {"id":"","text":"Install","localized":"","hint":""},
- {"id":"","text":"Search","localized":"","hint":""},
- {"id":"","text":"Sort by","localized":"","hint":""},
- {"id":"","text":"Manage Extensions ","localized":"","hint":""},
- {"id":"","text":"Manual install ","localized":"","hint":""},
- {"id":"","text":"Extension GIT repository URL","localized":"","hint":""},
- {"id":"","text":"Specific branch name","localized":"","hint":""},
- {"id":"","text":"Local directory name","localized":"","hint":""},
- {"id":"","text":"Refresh extension list","localized":"","hint":""},
- {"id":"","text":"Update installed extensions","localized":"","hint":""},
- {"id":"","text":"Apply changes & restart server","localized":"","hint":""}
+ {"id":"","label":"Install","localized":"","hint":""},
+ {"id":"","label":"Search","localized":"","hint":""},
+ {"id":"","label":"Sort by","localized":"","hint":""},
+ {"id":"","label":"Manage Extensions ","localized":"","hint":""},
+ {"id":"","label":"Manual install ","localized":"","hint":""},
+ {"id":"","label":"Extension GIT repository URL","localized":"","hint":""},
+ {"id":"","label":"Specific branch name","localized":"","hint":""},
+ {"id":"","label":"Local directory name","localized":"","hint":""},
+ {"id":"","label":"Refresh extension list","localized":"","hint":""},
+ {"id":"","label":"Update installed extensions","localized":"","hint":""},
+ {"id":"","label":"Apply changes & restart server","localized":"","hint":""}
],
"txt2img tab": [
- {"id":"","text":"Sampling method","localized":"","hint":"Which algorithm to use to produce the image"},
- {"id":"","text":"Sampling steps","localized":"","hint":"How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results"},
- {"id":"","text":"Restore faces","localized":"","hint":""},
- {"id":"","text":"Tiling","localized":"","hint":"Produce an image that can be tiled"},
- {"id":"","text":"Hires fix","localized":"","hint":""},
- {"id":"","text":"Denoising strength","localized":"","hint":"Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies"},
- {"id":"","text":"Hires steps","localized":"","hint":"Number of sampling steps for upscaled picture. If 0, uses same as for original"},
- {"id":"","text":"Upscaler","localized":"","hint":""},
- {"id":"","text":"Upscale by","localized":"","hint":"Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero"},
- {"id":"","text":"Resize width to","localized":"","hint":"Resizes image to this width. If 0, width is inferred from either of two nearby sliders"},
- {"id":"","text":"Resize height to","localized":"","hint":"Resizes image to this height. If 0, height is inferred from either of two nearby sliders"},
- {"id":"","text":"Width","localized":"","hint":""},
- {"id":"","text":"Height","localized":"","hint":""},
- {"id":"","text":"Batch count","localized":"","hint":"How many batches of images to create (has no impact on generation performance or VRAM usage)"},
- {"id":"","text":"Batch size","localized":"","hint":"How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)"},
- {"id":"","text":"CFG Scale","localized":"","hint":"Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results"},
- {"id":"","text":"CLIP skip","localized":"","hint":""},
- {"id":"","text":"Seed","localized":"","hint":"A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result"},
- {"id":"","text":"Extra","localized":"","hint":""},
- {"id":"","text":"Variation seed","localized":"","hint":"Seed of a different picture to be mixed into the generation"},
- {"id":"","text":"Variation strength","localized":"","hint":"How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something)"},
- {"id":"","text":"Resize seed from width","localized":"","hint":"Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution"},
- {"id":"","text":"Resize seed from height","localized":"","hint":"Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution"},
- {"id":"","text":"Override settings","localized":"","hint":""}
+ {"id":"","label":"Sampling method","localized":"","hint":"Which algorithm to use to produce the image"},
+ {"id":"","label":"Sampling steps","localized":"","hint":"How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results"},
+ {"id":"","label":"Restore faces","localized":"","hint":""},
+ {"id":"","label":"Tiling","localized":"","hint":"Produce an image that can be tiled"},
+ {"id":"","label":"Hires fix","localized":"","hint":""},
+ {"id":"","label":"Denoising strength","localized":"","hint":"Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies"},
+ {"id":"","label":"Hires steps","localized":"","hint":"Number of sampling steps for upscaled picture. If 0, uses same as for original"},
+ {"id":"","label":"Upscaler","localized":"","hint":""},
+ {"id":"","label":"Upscale by","localized":"","hint":"Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero"},
+ {"id":"","label":"Resize width to","localized":"","hint":"Resizes image to this width. If 0, width is inferred from either of two nearby sliders"},
+ {"id":"","label":"Resize height to","localized":"","hint":"Resizes image to this height. If 0, height is inferred from either of two nearby sliders"},
+ {"id":"","label":"Width","localized":"","hint":""},
+ {"id":"","label":"Height","localized":"","hint":""},
+ {"id":"","label":"Batch count","localized":"","hint":"How many batches of images to create (has no impact on generation performance or VRAM usage)"},
+ {"id":"","label":"Batch size","localized":"","hint":"How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)"},
+ {"id":"","label":"CFG Scale","localized":"","hint":"Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results"},
+ {"id":"","label":"CLIP skip","localized":"","hint":""},
+ {"id":"","label":"Seed","localized":"","hint":"A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result"},
+ {"id":"","label":"Extra","localized":"","hint":""},
+ {"id":"","label":"Variation seed","localized":"","hint":"Seed of a different picture to be mixed into the generation"},
+ {"id":"","label":"Variation strength","localized":"","hint":"How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something)"},
+ {"id":"","label":"Resize seed from width","localized":"","hint":"Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution"},
+ {"id":"","label":"Resize seed from height","localized":"","hint":"Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution"},
+ {"id":"","label":"Override settings","localized":"","hint":""}
],
"process tab": [
- {"id":"","text":"Single Image ","localized":"","hint":""},
- {"id":"","text":"Process Batch ","localized":"","hint":""},
- {"id":"","text":"Process Folder ","localized":"","hint":""},
- {"id":"","text":"Scale by ","localized":"","hint":""},
- {"id":"","text":"Scale to ","localized":"","hint":""},
- {"id":"","text":"Input directory","localized":"","hint":""},
- {"id":"","text":"Output directory","localized":"","hint":""},
- {"id":"","text":"Show result images","localized":"","hint":""},
- {"id":"","text":"Resize","localized":"","hint":""},
- {"id":"","text":"Crop to fit","localized":"","hint":""},
- {"id":"","text":"Secondary Upscaler","localized":"","hint":""},
- {"id":"","text":"Upscaler 2 visibility","localized":"","hint":""},
- {"id":"","text":"GFPGAN visibility","localized":"","hint":""},
- {"id":"","text":"CodeFormer visibility","localized":"","hint":""},
- {"id":"","text":"CodeFormer weight (0 = max), 1 = min)","localized":"","hint":""}
+ {"id":"","label":"Single Image ","localized":"","hint":""},
+ {"id":"","label":"Process Batch ","localized":"","hint":""},
+ {"id":"","label":"Process Folder ","localized":"","hint":""},
+ {"id":"","label":"Scale by ","localized":"","hint":""},
+ {"id":"","label":"Scale to ","localized":"","hint":""},
+ {"id":"","label":"Input directory","localized":"","hint":""},
+ {"id":"","label":"Output directory","localized":"","hint":""},
+ {"id":"","label":"Show result images","localized":"","hint":""},
+ {"id":"","label":"Resize","localized":"","hint":""},
+ {"id":"","label":"Crop to fit","localized":"","hint":""},
+ {"id":"","label":"Secondary Upscaler","localized":"","hint":""},
+ {"id":"","label":"Upscaler 2 visibility","localized":"","hint":""},
+ {"id":"","label":"GFPGAN visibility","localized":"","hint":""},
+ {"id":"","label":"CodeFormer visibility","localized":"","hint":""},
+ {"id":"","label":"CodeFormer weight (0 = max, 1 = min)","localized":"","hint":""}
],
"settings menu": [
- {"id":"settings_submit","text":"Apply settings","localized":"","hint":""},
- {"id":"restart_submit","text":"Restart server","localized":"","hint":""},
- {"id":"shutdown_submit","text":"Shutdown server","localized":"","hint":""},
- {"id":"settings_preview_theme","text":"Preview theme","localized":"","hint":""},
- {"id":"defaults_submit","text":"Restore defaults","localized":"","hint":""},
- {"id":"sett_unload_sd_model","text":"Unload checkpoint","localized":"","hint":""},
- {"id":"sett_reload_sd_model","text":"Reload checkpoint","localized":"","hint":""}
+ {"id":"settings_submit","label":"Apply settings","localized":"","hint":""},
+ {"id":"restart_submit","label":"Restart server","localized":"","hint":""},
+ {"id":"shutdown_submit","label":"Shutdown server","localized":"","hint":""},
+ {"id":"settings_preview_theme","label":"Preview theme","localized":"","hint":""},
+ {"id":"defaults_submit","label":"Restore defaults","localized":"","hint":""},
+ {"id":"sett_unload_sd_model","label":"Unload checkpoint","localized":"","hint":""},
+ {"id":"sett_reload_sd_model","label":"Reload checkpoint","localized":"","hint":""}
],
"settings sections": [
- {"id":"","text":"Stable Diffusion ","localized":"","hint":""},
- {"id":"","text":"Compute Settings ","localized":"","hint":""},
- {"id":"","text":"System Paths ","localized":"","hint":""},
- {"id":"","text":"Image Options ","localized":"","hint":""},
- {"id":"","text":"Image Processing ","localized":"","hint":""},
- {"id":"","text":"Output Paths ","localized":"","hint":""},
- {"id":"","text":"User interface ","localized":"","hint":""},
- {"id":"","text":"Live previews ","localized":"","hint":""},
- {"id":"","text":"Sampler Settings ","localized":"","hint":""},
- {"id":"","text":"Postprocessing ","localized":"","hint":""},
- {"id":"","text":"Training ","localized":"","hint":""},
- {"id":"","text":"Interrogate ","localized":"","hint":""},
- {"id":"","text":"Upscaling ","localized":"","hint":""},
- {"id":"","text":"Lora ","localized":"","hint":""},
- {"id":"","text":"Face restoration ","localized":"","hint":""},
- {"id":"","text":"Extra Networks ","localized":"","hint":""},
- {"id":"","text":"Token Merging ","localized":"","hint":""},
- {"id":"","text":"Licenses ","localized":"","hint":""},
- {"id":"","text":"Show all pages","localized":"","hint":""},
- {"id":"","text":"Request browser notifications","localized":"","hint":""}
+ {"id":"","label":"Stable Diffusion ","localized":"","hint":""},
+ {"id":"","label":"Compute Settings ","localized":"","hint":""},
+ {"id":"","label":"System Paths ","localized":"","hint":""},
+ {"id":"","label":"Image Options ","localized":"","hint":""},
+ {"id":"","label":"Image Processing ","localized":"","hint":""},
+ {"id":"","label":"Output Paths ","localized":"","hint":""},
+ {"id":"","label":"User interface ","localized":"","hint":""},
+ {"id":"","label":"Live previews ","localized":"","hint":""},
+ {"id":"","label":"Sampler Settings ","localized":"","hint":""},
+ {"id":"","label":"Postprocessing ","localized":"","hint":""},
+ {"id":"","label":"Training ","localized":"","hint":""},
+ {"id":"","label":"Interrogate ","localized":"","hint":""},
+ {"id":"","label":"Upscaling ","localized":"","hint":""},
+ {"id":"","label":"Lora ","localized":"","hint":""},
+ {"id":"","label":"Face restoration ","localized":"","hint":""},
+ {"id":"","label":"Extra Networks ","localized":"","hint":""},
+ {"id":"","label":"Token Merging ","localized":"","hint":""},
+ {"id":"","label":"Licenses ","localized":"","hint":""},
+ {"id":"","label":"Show all pages","localized":"","hint":""},
+ {"id":"","label":"Request browser notifications","localized":"","hint":""}
],
"img2img tabs": [
- {"id":"","text":"Image ","localized":"","hint":""},
- {"id":"","text":"Sketch ","localized":"","hint":""},
- {"id":"","text":"Inpaint ","localized":"","hint":""},
- {"id":"","text":"Inpaint sketch ","localized":"","hint":""},
- {"id":"","text":"Inpaint upload ","localized":"","hint":""},
- {"id":"","text":"Batch ","localized":"","hint":""}
+ {"id":"","label":"Image ","localized":"","hint":""},
+ {"id":"","label":"Sketch ","localized":"","hint":""},
+ {"id":"","label":"Inpaint ","localized":"","hint":""},
+ {"id":"","label":"Inpaint sketch ","localized":"","hint":""},
+ {"id":"","label":"Inpaint upload ","localized":"","hint":""},
+ {"id":"","label":"Batch ","localized":"","hint":""}
],
"img2img tab": [
- {"id":"","text":"Inpaint Batch input directory","localized":"","hint":""},
- {"id":"","text":"Inpaint Batch output directory","localized":"","hint":""},
- {"id":"","text":"Inpaint batch mask directory","localized":"","hint":""},
- {"id":"","text":"Resize fixed","localized":"","hint":"Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio"},
- {"id":"","text":"Crop and resize","localized":"","hint":"Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out"},
- {"id":"","text":"Resize and fill","localized":"","hint":"Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors"},
- {"id":"","text":"Resize using Latent upscale","localized":"","hint":""},
- {"id":"","text":"Mask blur","localized":"","hint":"How much to blur the mask before processing, in pixels"},
- {"id":"","text":"Mask transparency","localized":"","hint":""},
- {"id":"","text":"Inpaint masked","localized":"","hint":""},
- {"id":"","text":"Inpaint not masked","localized":"","hint":""},
- {"id":"","text":"fill","localized":"","hint":"fill it with colors of the image"},
- {"id":"","text":"original","localized":"","hint":"keep whatever was there originally"},
- {"id":"","text":"latent noise","localized":"","hint":"fill it with latent space noise"},
- {"id":"","text":"latent nothing","localized":"","hint":"fill it with latent space zeroes"},
- {"id":"","text":"Whole picture","localized":"","hint":""},
- {"id":"","text":"Only masked","localized":"","hint":""},
- {"id":"","text":"Only masked padding, pixels","localized":"","hint":""},
- {"id":"","text":"Scale","localized":"","hint":""},
- {"id":"","text":"Unused","localized":"","hint":""},
- {"id":"","text":"Image CFG Scale","localized":"","hint":""}
+ {"id":"","label":"Inpaint Batch input directory","localized":"","hint":""},
+ {"id":"","label":"Inpaint Batch output directory","localized":"","hint":""},
+ {"id":"","label":"Inpaint batch mask directory","localized":"","hint":""},
+ {"id":"","label":"Resize fixed","localized":"","hint":"Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio"},
+ {"id":"","label":"Crop and resize","localized":"","hint":"Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out"},
+ {"id":"","label":"Resize and fill","localized":"","hint":"Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors"},
+ {"id":"","label":"Resize using Latent upscale","localized":"","hint":""},
+ {"id":"","label":"Mask blur","localized":"","hint":"How much to blur the mask before processing, in pixels"},
+ {"id":"","label":"Mask transparency","localized":"","hint":""},
+ {"id":"","label":"Inpaint masked","localized":"","hint":""},
+ {"id":"","label":"Inpaint not masked","localized":"","hint":""},
+ {"id":"","label":"fill","localized":"","hint":"fill it with colors of the image"},
+ {"id":"","label":"original","localized":"","hint":"keep whatever was there originally"},
+ {"id":"","label":"latent noise","localized":"","hint":"fill it with latent space noise"},
+ {"id":"","label":"latent nothing","localized":"","hint":"fill it with latent space zeroes"},
+ {"id":"","label":"Whole picture","localized":"","hint":""},
+ {"id":"","label":"Only masked","localized":"","hint":""},
+ {"id":"","label":"Only masked padding, pixels","localized":"","hint":""},
+ {"id":"","label":"Scale","localized":"","hint":""},
+ {"id":"","label":"Unused","localized":"","hint":""},
+ {"id":"","label":"Image CFG Scale","localized":"","hint":""}
],
"train tabs": [
- {"id":"","text":"Merge models ","localized":"","hint":""},
- {"id":"","text":"Create embedding ","localized":"","hint":""},
- {"id":"","text":"Create hypernetwork ","localized":"","hint":""},
- {"id":"","text":"Preprocess images ","localized":"","hint":""},
- {"id":"","text":"Merge","localized":"","hint":""},
- {"id":"","text":"Calculate hash for all models (may take a long time)","localized":"","hint":""},
- {"id":"","text":"Create embedding","localized":"","hint":""},
- {"id":"","text":"Create hypernetwork","localized":"","hint":""},
- {"id":"","text":"Preprocess","localized":"","hint":""},
- {"id":"","text":"Train Embedding","localized":"","hint":""},
- {"id":"","text":"Train Hypernetwork","localized":"","hint":""}
+ {"id":"","label":"Merge models ","localized":"","hint":""},
+ {"id":"","label":"Create embedding ","localized":"","hint":""},
+ {"id":"","label":"Create hypernetwork ","localized":"","hint":""},
+ {"id":"","label":"Preprocess images ","localized":"","hint":""},
+ {"id":"","label":"Merge","localized":"","hint":""},
+ {"id":"","label":"Calculate hash for all models (may take a long time)","localized":"","hint":""},
+ {"id":"","label":"Create embedding","localized":"","hint":""},
+ {"id":"","label":"Create hypernetwork","localized":"","hint":""},
+ {"id":"","label":"Preprocess","localized":"","hint":""},
+ {"id":"","label":"Train Embedding","localized":"","hint":""},
+ {"id":"","label":"Train Hypernetwork","localized":"","hint":""}
],
"train tab": [
- {"id":"","text":"Primary model","localized":"","hint":""},
- {"id":"","text":"Secondary model","localized":"","hint":""},
- {"id":"","text":"Tertiary model","localized":"","hint":""},
- {"id":"","text":"New model name","localized":"","hint":""},
- {"id":"","text":"No interpolation","localized":"","hint":"Result = A"},
- {"id":"","text":"Weighted sum","localized":"","hint":"Result = A * (1 - M) + B * M"},
- {"id":"","text":"Add difference","localized":"","hint":"Result = A + (B - C) * M"},
- {"id":"","text":"Interpolation ratio from Primary to Secondary","localized":"","hint":""},
- {"id":"","text":"ckpt","localized":"","hint":""},
- {"id":"","text":"safetensors","localized":"","hint":""},
- {"id":"","text":"Use FP16","localized":"","hint":""},
- {"id":"","text":"Save metadata","localized":"","hint":""},
- {"id":"","text":"Primary","localized":"","hint":""},
- {"id":"","text":"Secondary","localized":"","hint":""},
- {"id":"","text":"Tertiary","localized":"","hint":""},
- {"id":"","text":"Bake in VAE","localized":"","hint":""},
- {"id":"","text":"Discard weights with matching name","localized":"","hint":"Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights"},
- {"id":"","text":"Name","localized":"","hint":""},
- {"id":"","text":"Initialization text","localized":"","hint":"If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors"},
- {"id":"","text":"Number of vectors per token","localized":"","hint":""},
- {"id":"","text":"Overwrite Old Embedding","localized":"","hint":""},
- {"id":"","text":"Enter hypernetwork layer structure","localized":"","hint":""},
- {"id":"","text":"Select activation function of hypernetwork. Recommended : Swish / Linear(none)","localized":"","hint":""},
- {"id":"","text":"Select Layer weights initialization. Recommended: Kaiming for relu-like, Xavier for sigmoid-like, Normal otherwise","localized":"","hint":""},
- {"id":"","text":"Add layer normalization","localized":"","hint":""},
- {"id":"","text":"Use dropout","localized":"","hint":""},
- {"id":"","text":"Enter hypernetwork Dropout structure (or empty). Recommended : 0~0.35 incrementing sequence: 0, 0.05, 0.15","localized":"","hint":""},
- {"id":"","text":"Overwrite Old Hypernetwork","localized":"","hint":""},
- {"id":"","text":"Source directory","localized":"","hint":""},
- {"id":"","text":"Destination directory","localized":"","hint":""},
- {"id":"","text":"Existing Caption txt Action","localized":"","hint":""},
- {"id":"","text":"Keep original size","localized":"","hint":""},
- {"id":"","text":"Keep original image channels","localized":"","hint":""},
- {"id":"","text":"Create flipped copies","localized":"","hint":""},
- {"id":"","text":"Split oversized images","localized":"","hint":""},
- {"id":"","text":"Auto focal point crop","localized":"","hint":""},
- {"id":"","text":"Auto-sized crop","localized":"","hint":""},
- {"id":"","text":"Create captions only","localized":"","hint":""},
- {"id":"","text":"Create BLIP captions","localized":"","hint":""},
- {"id":"","text":"Create Deepbooru captions","localized":"","hint":""},
- {"id":"","text":"Split image threshold","localized":"","hint":""},
- {"id":"","text":"Split image overlap ratio","localized":"","hint":""},
- {"id":"","text":"Focal point face weight","localized":"","hint":""},
- {"id":"","text":"Focal point entropy weight","localized":"","hint":""},
- {"id":"","text":"Focal point edges weight","localized":"","hint":""},
- {"id":"","text":"Create debug image","localized":"","hint":""},
- {"id":"","text":"Dimension lower bound","localized":"","hint":""},
- {"id":"","text":"Dimension upper bound","localized":"","hint":""},
- {"id":"","text":"Area lower bound","localized":"","hint":""},
- {"id":"","text":"Area upper bound","localized":"","hint":""},
- {"id":"","text":"Maximize area","localized":"","hint":""},
- {"id":"","text":"Minimize error","localized":"","hint":""},
- {"id":"","text":"Error threshold","localized":"","hint":""},
- {"id":"","text":"Embedding","localized":"","hint":""},
- {"id":"","text":"Hypernetwork","localized":"","hint":""},
- {"id":"","text":"Embedding Learning rate","localized":"","hint":""},
- {"id":"","text":"Hypernetwork Learning rate","localized":"","hint":""},
- {"id":"","text":"Gradient Clipping","localized":"","hint":""},
- {"id":"","text":"Gradient accumulation steps","localized":"","hint":""},
- {"id":"","text":"Dataset directory","localized":"","hint":""},
- {"id":"","text":"Log directory","localized":"","hint":""},
- {"id":"","text":"Prompt template","localized":"","hint":""},
- {"id":"","text":"Do not resize images","localized":"","hint":""},
- {"id":"","text":"Max steps","localized":"","hint":""},
- {"id":"","text":"Save an image to log directory every N steps, 0 to disable","localized":"","hint":""},
- {"id":"","text":"Save a copy of embedding to log directory every N steps, 0 to disable","localized":"","hint":""},
- {"id":"","text":"Use PNG alpha channel as loss weight","localized":"","hint":""},
- {"id":"","text":"Save images with embedding in PNG chunks","localized":"","hint":""},
- {"id":"","text":"Read parameters (prompt, etc...) from txt2img tab when making previews","localized":"","hint":""},
- {"id":"","text":"Shuffle tags by ',' when creating prompts","localized":"","hint":""},
- {"id":"","text":"Drop out tags when creating prompts","localized":"","hint":""},
- {"id":"","text":"once","localized":"","hint":""},
- {"id":"","text":"deterministic","localized":"","hint":""},
- {"id":"","text":"random","localized":"","hint":""}
+ {"id":"","label":"Primary model","localized":"","hint":""},
+ {"id":"","label":"Secondary model","localized":"","hint":""},
+ {"id":"","label":"Tertiary model","localized":"","hint":""},
+ {"id":"","label":"New model name","localized":"","hint":""},
+ {"id":"","label":"No interpolation","localized":"","hint":"Result = A"},
+ {"id":"","label":"Weighted sum","localized":"","hint":"Result = A * (1 - M) + B * M"},
+ {"id":"","label":"Add difference","localized":"","hint":"Result = A + (B - C) * M"},
+ {"id":"","label":"Interpolation ratio from Primary to Secondary","localized":"","hint":""},
+ {"id":"","label":"ckpt","localized":"","hint":""},
+ {"id":"","label":"safetensors","localized":"","hint":""},
+ {"id":"","label":"Use FP16","localized":"","hint":""},
+ {"id":"","label":"Save metadata","localized":"","hint":""},
+ {"id":"","label":"Primary","localized":"","hint":""},
+ {"id":"","label":"Secondary","localized":"","hint":""},
+ {"id":"","label":"Tertiary","localized":"","hint":""},
+ {"id":"","label":"Bake in VAE","localized":"","hint":""},
+ {"id":"","label":"Discard weights with matching name","localized":"","hint":"Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights"},
+ {"id":"","label":"Name","localized":"","hint":""},
+ {"id":"","label":"Initialization text","localized":"","hint":"If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors"},
+ {"id":"","label":"Number of vectors per token","localized":"","hint":""},
+ {"id":"","label":"Overwrite Old Embedding","localized":"","hint":""},
+ {"id":"","label":"Enter hypernetwork layer structure","localized":"","hint":""},
+ {"id":"","label":"Select activation function of hypernetwork. Recommended : Swish / Linear(none)","localized":"","hint":""},
+ {"id":"","label":"Select Layer weights initialization. Recommended: Kaiming for relu-like, Xavier for sigmoid-like, Normal otherwise","localized":"","hint":""},
+ {"id":"","label":"Add layer normalization","localized":"","hint":""},
+ {"id":"","label":"Use dropout","localized":"","hint":""},
+ {"id":"","label":"Enter hypernetwork Dropout structure (or empty). Recommended : 0~0.35 incrementing sequence: 0, 0.05, 0.15","localized":"","hint":""},
+ {"id":"","label":"Overwrite Old Hypernetwork","localized":"","hint":""},
+ {"id":"","label":"Source directory","localized":"","hint":""},
+ {"id":"","label":"Destination directory","localized":"","hint":""},
+ {"id":"","label":"Existing Caption txt Action","localized":"","hint":""},
+ {"id":"","label":"Keep original size","localized":"","hint":""},
+ {"id":"","label":"Keep original image channels","localized":"","hint":""},
+ {"id":"","label":"Create flipped copies","localized":"","hint":""},
+ {"id":"","label":"Split oversized images","localized":"","hint":""},
+ {"id":"","label":"Auto focal point crop","localized":"","hint":""},
+ {"id":"","label":"Auto-sized crop","localized":"","hint":""},
+ {"id":"","label":"Create captions only","localized":"","hint":""},
+ {"id":"","label":"Create BLIP captions","localized":"","hint":""},
+ {"id":"","label":"Create Deepbooru captions","localized":"","hint":""},
+ {"id":"","label":"Split image threshold","localized":"","hint":""},
+ {"id":"","label":"Split image overlap ratio","localized":"","hint":""},
+ {"id":"","label":"Focal point face weight","localized":"","hint":""},
+ {"id":"","label":"Focal point entropy weight","localized":"","hint":""},
+ {"id":"","label":"Focal point edges weight","localized":"","hint":""},
+ {"id":"","label":"Create debug image","localized":"","hint":""},
+ {"id":"","label":"Dimension lower bound","localized":"","hint":""},
+ {"id":"","label":"Dimension upper bound","localized":"","hint":""},
+ {"id":"","label":"Area lower bound","localized":"","hint":""},
+ {"id":"","label":"Area upper bound","localized":"","hint":""},
+ {"id":"","label":"Maximize area","localized":"","hint":""},
+ {"id":"","label":"Minimize error","localized":"","hint":""},
+ {"id":"","label":"Error threshold","localized":"","hint":""},
+ {"id":"","label":"Embedding","localized":"","hint":""},
+ {"id":"","label":"Hypernetwork","localized":"","hint":""},
+ {"id":"","label":"Embedding Learning rate","localized":"","hint":""},
+ {"id":"","label":"Hypernetwork Learning rate","localized":"","hint":""},
+ {"id":"","label":"Gradient Clipping","localized":"","hint":""},
+ {"id":"","label":"Gradient accumulation steps","localized":"","hint":""},
+ {"id":"","label":"Dataset directory","localized":"","hint":""},
+ {"id":"","label":"Log directory","localized":"","hint":""},
+ {"id":"","label":"Prompt template","localized":"","hint":""},
+ {"id":"","label":"Do not resize images","localized":"","hint":""},
+ {"id":"","label":"Max steps","localized":"","hint":""},
+ {"id":"","label":"Save an image to log directory every N steps, 0 to disable","localized":"","hint":""},
+ {"id":"","label":"Save a copy of embedding to log directory every N steps, 0 to disable","localized":"","hint":""},
+ {"id":"","label":"Use PNG alpha channel as loss weight","localized":"","hint":""},
+ {"id":"","label":"Save images with embedding in PNG chunks","localized":"","hint":""},
+ {"id":"","label":"Read parameters (prompt, etc...) from txt2img tab when making previews","localized":"","hint":""},
+ {"id":"","label":"Shuffle tags by ',' when creating prompts","localized":"","hint":""},
+ {"id":"","label":"Drop out tags when creating prompts","localized":"","hint":""},
+ {"id":"","label":"once","localized":"","hint":""},
+ {"id":"","label":"deterministic","localized":"","hint":""},
+ {"id":"","label":"random","localized":"","hint":""}
],
"settings": [
- {"id":"","text":"Number of cached model checkpoints","localized":"","hint":""},
- {"id":"","text":"Number of cached VAE checkpoints","localized":"","hint":""},
- {"id":"","text":"Select VAE","localized":"","hint":""},
- {"id":"","text":"Enable splitting of hires batch processing","localized":"","hint":""},
- {"id":"","text":"When loading models attempt stream loading optimized for slow or network storage","localized":"","hint":""},
- {"id":"","text":"When loading models attempt to reuse previous model dictionary","localized":"","hint":""},
- {"id":"","text":"Disable cross-attention layer optimization","localized":"","hint":""},
- {"id":"","text":"xFormers","localized":"","hint":""},
- {"id":"","text":"Scaled-Dot-Product","localized":"","hint":""},
- {"id":"","text":"Doggettx's","localized":"","hint":""},
- {"id":"","text":"InvokeAI's","localized":"","hint":""},
- {"id":"","text":"Sub-quadratic","localized":"","hint":""},
- {"id":"","text":"Split attention","localized":"","hint":""},
- {"id":"","text":"xFormers enable flash Attention","localized":"","hint":""},
- {"id":"","text":"SDP disable memory attention","localized":"","hint":""},
- {"id":"","text":"Sub-quadratic cross-attention query chunk size","localized":"","hint":""},
- {"id":"","text":"Sub-quadratic cross-attention kv chunk size","localized":"","hint":""},
- {"id":"","text":"Sub-quadratic cross-attention chunking threshold","localized":"","hint":""},
- {"id":"","text":"Full parser","localized":"","hint":""},
- {"id":"","text":"Compel parser","localized":"","hint":""},
- {"id":"","text":"A1111 parser","localized":"","hint":""},
- {"id":"","text":"Fixed attention","localized":"","hint":""},
- {"id":"","text":"Prompt attention mean normalization","localized":"","hint":""},
- {"id":"","text":"Disable conditional batching enabled on low memory systems","localized":"","hint":""},
- {"id":"","text":"Enable samplers quantization for sharper and cleaner results","localized":"","hint":""},
- {"id":"","text":"Increase coherency by padding from the last comma within n tokens when using more than 75 tokens","localized":"","hint":""},
- {"id":"","text":"Original","localized":"","hint":""},
- {"id":"","text":"Diffusers","localized":"","hint":""},
- {"id":"","text":"VRAM usage polls per second during generation","localized":"","hint":""},
- {"id":"","text":"Autocast","localized":"","hint":""},
- {"id":"","text":"Full","localized":"","hint":""},
- {"id":"","text":"FP32","localized":"","hint":""},
- {"id":"","text":"FP16","localized":"","hint":""},
- {"id":"","text":"BF16","localized":"","hint":""},
- {"id":"","text":"Use full precision for model (--no-half)","localized":"","hint":""},
- {"id":"","text":"Use full precision for VAE (--no-half-vae)","localized":"","hint":""},
- {"id":"","text":"Enable upcast sampling","localized":"","hint":""},
- {"id":"","text":"Enable upcast cross attention layer","localized":"","hint":""},
- {"id":"","text":"Disable NaN check in produced images/latent spaces","localized":"","hint":""},
- {"id":"","text":"Attempt to roll back VAE when produced NaN values, requires NaN check (experimental)","localized":"","hint":""},
- {"id":"","text":"Use channels last as torch memory format ","localized":"","hint":""},
- {"id":"","text":"Enable full-depth cuDNN benchmark feature","localized":"","hint":""},
- {"id":"","text":"Allow TF32 math ops","localized":"","hint":""},
- {"id":"","text":"Allow TF16 reduced precision math ops","localized":"","hint":""},
- {"id":"","text":"Enable model compile (experimental)","localized":"","hint":""},
- {"id":"","text":"inductor","localized":"","hint":""},
- {"id":"","text":"cudagraphs","localized":"","hint":""},
- {"id":"","text":"aot_ts_nvfuser","localized":"","hint":""},
- {"id":"","text":"hidet","localized":"","hint":""},
- {"id":"","text":"ipex","localized":"","hint":""},
- {"id":"","text":"Model compile verbose mode","localized":"","hint":""},
- {"id":"","text":"Model compile suppress errors","localized":"","hint":""},
- {"id":"","text":"Disable Torch memory garbage collection (experimental)","localized":"","hint":""},
- {"id":"","text":"Directory for temporary images; leave empty for default","localized":"","hint":""},
- {"id":"","text":"Cleanup non-default temporary directory when starting webui","localized":"","hint":""},
- {"id":"","text":"Path to directory with stable diffusion checkpoints","localized":"","hint":""},
- {"id":"","text":"Path to directory with stable diffusion diffusers","localized":"","hint":""},
- {"id":"","text":"Path to directory with VAE files","localized":"","hint":""},
- {"id":"","text":"Embeddings directory for textual inversion","localized":"","hint":""},
- {"id":"","text":"Hypernetwork directory","localized":"","hint":""},
- {"id":"","text":"Path to directory with codeformer model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with GFPGAN model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with ESRGAN model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with BSRGAN model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with RealESRGAN model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with ScuNET model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with SwinIR model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with LDSR model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with CLIP model file(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with Lora network(s)","localized":"","hint":""},
- {"id":"","text":"Path to directory with LyCORIS network(s)","localized":"","hint":""},
- {"id":"","text":"Path to user-defined styles file","localized":"","hint":""},
- {"id":"","text":"Always save all generated images","localized":"","hint":""},
- {"id":"","text":"File format for generated images","localized":"","hint":""},
- {"id":"","text":"Images filename pattern","localized":"","hint":"Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime], [datetime], [job_timestamp]; leave empty for default"},
- {"id":"","text":"Add number to filename when saving","localized":"","hint":""},
- {"id":"","text":"Always save all generated image grids","localized":"","hint":""},
- {"id":"","text":"File format for grids","localized":"","hint":""},
- {"id":"","text":"Add extended info (seed, prompt) to filename when saving grid","localized":"","hint":""},
- {"id":"","text":"Do not save grids consisting of one picture","localized":"","hint":""},
- {"id":"","text":"Prevent empty spots in grid (when set to autodetect)","localized":"","hint":""},
- {"id":"","text":"Grid row count; use -1 for autodetect and 0 for it to be same as batch size","localized":"","hint":""},
- {"id":"","text":"Create a text file next to every image with generation parameters","localized":"","hint":""},
- {"id":"","text":"Create a JSON log file with image information for each saved image","localized":"","hint":""},
- {"id":"","text":"Save a copy of image before doing face restoration","localized":"","hint":""},
- {"id":"","text":"Save a copy of image before applying highres fix","localized":"","hint":""},
- {"id":"","text":"Save a copy of image before applying color correction to img2img results","localized":"","hint":""},
- {"id":"","text":"Save a copy of the inpainting greyscale mask","localized":"","hint":""},
- {"id":"","text":"Save a copy of inpainting masked composite","localized":"","hint":""},
- {"id":"","text":"Save a copy of processing init images","localized":"","hint":""},
- {"id":"","text":"Quality for saved jpeg images","localized":"","hint":""},
- {"id":"","text":"Use lossless compression for webp images","localized":"","hint":""},
- {"id":"","text":"Maximum allowed image size in megapixels","localized":"","hint":""},
- {"id":"","text":"Use original name for output filename during batch process in extras tab","localized":"","hint":""},
- {"id":"","text":"Use upscaler name as filename suffix in the extras tab","localized":"","hint":""},
- {"id":"","text":"When using 'Save' button, only save a single selected image","localized":"","hint":""},
- {"id":"","text":"Save images to a subdirectory","localized":"","hint":""},
- {"id":"","text":"Save grids to a subdirectory","localized":"","hint":""},
- {"id":"","text":"Save images to a subdirectory when using Save button","localized":"","hint":""},
- {"id":"","text":"Directory name pattern","localized":"","hint":"Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg],[prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime], [datetime], [job_timestamp]; leave empty for default"},
- {"id":"","text":"Max prompt words for [prompt_words] pattern","localized":"","hint":""},
- {"id":"","text":"Apply color correction to match original colors","localized":"","hint":""},
- {"id":"","text":"For image processing do exact number of steps as specified","localized":"","hint":""},
- {"id":"","text":"Image transparent color fill","localized":"","hint":""},
- {"id":"","text":"Inpainting conditioning mask strength","localized":"","hint":"Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked (default). 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes"},
- {"id":"","text":"Noise multiplier for image processing","localized":"","hint":""},
- {"id":"","text":"Clip skip","localized":"","hint":"Early stopping parameter for CLIP model; 1 is stop at last layer as usual, 2 is stop at penultimate layer, etc"},
- {"id":"","text":"Output directory for images; if empty, defaults to three directories below","localized":"","hint":""},
- {"id":"","text":"Output directory for txt2img images","localized":"","hint":""},
- {"id":"","text":"Output directory for img2img images","localized":"","hint":""},
- {"id":"","text":"Output directory for images from extras tab","localized":"","hint":""},
- {"id":"","text":"Output directory for grids; if empty, defaults to two directories below","localized":"","hint":""},
- {"id":"","text":"Output directory for txt2img grids","localized":"","hint":""},
- {"id":"","text":"Output directory for img2img grids","localized":"","hint":""},
- {"id":"","text":"Directory for saving images using the Save button","localized":"","hint":""},
- {"id":"","text":"Directory for saving init images when using img2img","localized":"","hint":""},
- {"id":"","text":"UI theme","localized":"","hint":""},
- {"id":"","text":"Auto","localized":"","hint":""},
- {"id":"","text":"Dark","localized":"","hint":""},
- {"id":"","text":"Light","localized":"","hint":""},
- {"id":"","text":"Show grid in results for web","localized":"","hint":""},
- {"id":"","text":"For inpainting, include the greyscale mask in results for web","localized":"","hint":""},
- {"id":"","text":"For inpainting, include masked composite in results for web","localized":"","hint":""},
- {"id":"","text":"Do not change the selected model when reading generation parameters","localized":"","hint":""},
- {"id":"","text":"Send seed when sending prompt or image to other interface","localized":"","hint":""},
- {"id":"","text":"Send size when sending prompt or image to another interface","localized":"","hint":""},
- {"id":"","text":"Font for image grids that have text","localized":"","hint":""},
- {"id":"","text":"Ctrl+up/down precision when editing (attention:1.1)","localized":"","hint":""},
- {"id":"","text":"Ctrl+up/down precision when editing ","localized":"","hint":""},
- {"id":"","text":"Ctrl+up/down word delimiters","localized":"","hint":""},
- {"id":"","text":"Quicksettings list","localized":"","hint":"List of setting names, separated by commas, for settings that should go to the quick access bar at the top instead the setting tab"},
- {"id":"","text":"Hidden UI tabs","localized":"","hint":""},
- {"id":"","text":"UI tabs order","localized":"","hint":""},
- {"id":"","text":"UI scripts order","localized":"","hint":""},
- {"id":"","text":"txt2img/img2img UI item order","localized":"","hint":""},
- {"id":"","text":"Extra networks tab order","localized":"","hint":"Comma-separated list of tab names; tabs listed here will appear in the extra networks UI first and in order lsited"},
- {"id":"","text":"Show progressbar","localized":"","hint":""},
- {"id":"","text":"Show live previews of the created image","localized":"","hint":""},
- {"id":"","text":"Show previews of all images generated in a batch as a grid","localized":"","hint":""},
- {"id":"","text":"Play a sound when images are finished generating","localized":"","hint":""},
- {"id":"","text":"Path to notification sound","localized":"","hint":""},
- {"id":"","text":"Live preview display period","localized":"","hint":""},
- {"id":"","text":"Full VAE","localized":"","hint":""},
- {"id":"","text":"Approximate NN","localized":"","hint":"Cheap neural network approximation. Very fast compared to VAE, but produces pictures with 4 times smaller horizontal/vertical resolution and lower quality"},
- {"id":"","text":"Approximate simple","localized":"","hint":"Very cheap approximation. Very fast compared to VAE, but produces pictures with 8 times smaller horizontal/vertical resolution and extremely low quality"},
- {"id":"","text":"TAESD","localized":"","hint":""},
- {"id":"","text":"Combined","localized":"","hint":""},
- {"id":"","text":"Progressbar/preview update period, in milliseconds","localized":"","hint":""},
- {"id":"","text":"Euler a","localized":"","hint":"Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help"},
- {"id":"","text":"Euler","localized":"","hint":""},
- {"id":"","text":"LMS","localized":"","hint":""},
- {"id":"","text":"Heun","localized":"","hint":""},
- {"id":"","text":"DPM2","localized":"","hint":""},
- {"id":"","text":"DPM2 a","localized":"","hint":""},
- {"id":"","text":"DPM++ 2S a","localized":"","hint":""},
- {"id":"","text":"DPM++ 2M","localized":"","hint":""},
- {"id":"","text":"DPM++ SDE","localized":"","hint":""},
- {"id":"","text":"DPM++ 2M SDE","localized":"","hint":""},
- {"id":"","text":"DPM fast","localized":"","hint":""},
- {"id":"","text":"DPM adaptive","localized":"","hint":"Ignores step count - uses a number of steps determined by the CFG and resolution"},
- {"id":"","text":"LMS Karras","localized":"","hint":""},
- {"id":"","text":"DPM2 Karras","localized":"","hint":""},
- {"id":"","text":"DPM2 a Karras","localized":"","hint":""},
- {"id":"","text":"DPM++ 2S a Karras","localized":"","hint":""},
- {"id":"","text":"DPM++ 2M Karras","localized":"","hint":""},
- {"id":"","text":"DPM++ SDE Karras","localized":"","hint":""},
- {"id":"","text":"DPM++ 2M SDE Karras","localized":"","hint":""},
- {"id":"","text":"DDIM","localized":"","hint":"Denoising Diffusion Implicit Models - best at inpainting"},
- {"id":"","text":"UniPC","localized":"","hint":"Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models"},
- {"id":"","text":"Secondary sampler","localized":"","hint":""},
- {"id":"","text":"Force latent upscaler sampler","localized":"","hint":""},
- {"id":"","text":"Noise multiplier for ancestral samplers (eta)","localized":"","hint":""},
- {"id":"","text":"Noise multiplier for DDIM (eta)","localized":"","hint":""},
- {"id":"","text":"uniform","localized":"","hint":""},
- {"id":"","text":"quad","localized":"","hint":""},
- {"id":"","text":"sigma churn","localized":"","hint":""},
- {"id":"","text":"Negative Guidance minimum sigma","localized":"","hint":""},
- {"id":"","text":"sigma tmin","localized":"","hint":""},
- {"id":"","text":"sigma noise","localized":"","hint":""},
- {"id":"","text":"Noise seed delta (eta)","localized":"","hint":""},
- {"id":"","text":"Always discard next-to-last sigma","localized":"","hint":""},
- {"id":"","text":"bh1","localized":"","hint":""},
- {"id":"","text":"bh2","localized":"","hint":""},
- {"id":"","text":"vary_coeff","localized":"","hint":""},
- {"id":"","text":"time_uniform","localized":"","hint":""},
- {"id":"","text":"time_quadratic","localized":"","hint":""},
- {"id":"","text":"logSNR","localized":"","hint":""},
- {"id":"","text":"UniPC order (must be < sampling steps)","localized":"","hint":""},
- {"id":"","text":"UniPC lower order final","localized":"","hint":""},
- {"id":"","text":"Enable addtional postprocessing operations","localized":"","hint":""},
- {"id":"","text":"Postprocessing operation order","localized":"","hint":""},
- {"id":"","text":"Maximum number of images in upscaling cache","localized":"","hint":""},
- {"id":"","text":"Move VAE and CLIP to RAM when training if possible","localized":"","hint":""},
- {"id":"","text":"Pin training dataset to memory","localized":"","hint":""},
- {"id":"","text":"Saves resumable optimizer state when training embedding or hypernetwork","localized":"","hint":""},
- {"id":"","text":"Save textual inversion and hypernet settings to a text file whenever training starts","localized":"","hint":""},
- {"id":"","text":"Filename word regex","localized":"","hint":"This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is"},
- {"id":"","text":"Filename join string","localized":"","hint":"This string will be used to join split words into a single line if the option above is enabled"},
- {"id":"","text":"Embeddings train templates directory","localized":"","hint":""},
- {"id":"","text":"Number of repeats for a single input image per epoch; used only for displaying epoch number","localized":"","hint":""},
- {"id":"","text":"Save an csv containing the loss to log directory every N steps, 0 to disable","localized":"","hint":""},
- {"id":"","text":"Enable tensorboard logging","localized":"","hint":""},
- {"id":"","text":"Save generated images within tensorboard","localized":"","hint":""},
- {"id":"","text":"How often, in seconds, to flush the pending tensorboard events and summaries to disk","localized":"","hint":""},
- {"id":"","text":"Interrogate: keep models in VRAM","localized":"","hint":""},
- {"id":"","text":"Interrogate: include ranks of model tags matches in results","localized":"","hint":""},
- {"id":"","text":"Interrogate: num_beams for BLIP","localized":"","hint":""},
- {"id":"","text":"Interrogate: minimum description length (excluding artists, etc..)","localized":"","hint":""},
- {"id":"","text":"Interrogate: maximum description length","localized":"","hint":""},
- {"id":"","text":"CLIP: maximum number of lines in text file (0 = No limit)","localized":"","hint":""},
- {"id":"","text":"flavors","localized":"","hint":""},
- {"id":"","text":"artists","localized":"","hint":""},
- {"id":"","text":"mediums","localized":"","hint":""},
- {"id":"","text":"movements","localized":"","hint":""},
- {"id":"","text":"Interrogate: deepbooru score threshold","localized":"","hint":""},
- {"id":"","text":"Interrogate: deepbooru sort alphabetically","localized":"","hint":""},
- {"id":"","text":"use spaces for tags in deepbooru","localized":"","hint":""},
- {"id":"","text":"escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)","localized":"","hint":""},
- {"id":"","text":"filter out those tags from deepbooru output (separated by comma)","localized":"","hint":""},
- {"id":"","text":"Default upscaler for image resize operations","localized":"","hint":""},
- {"id":"","text":"Tile size for ESRGAN upscalers (0 = no tiling)","localized":"","hint":""},
- {"id":"","text":"Tile overlap in pixels for ESRGAN upscalers","localized":"","hint":""},
- {"id":"","text":"Tile size for SCUNET upscalers. 0 = no tiling","localized":"","hint":""},
- {"id":"","text":"Tile overlap, in pixels for SCUNET upscalers. Low values = visible seam","localized":"","hint":""},
- {"id":"","text":"Hires fix uses width & height to set final resolution rather than first pass","localized":"","hint":""},
- {"id":"","text":"Do not fix prompt schedule for second order samplers","localized":"","hint":""},
- {"id":"","text":"Use LyCoris handler for all Lora types","localized":"","hint":""},
- {"id":"","text":"Use Kohya method for handling multiple Loras","localized":"","hint":""},
- {"id":"","text":"CodeFormer","localized":"","hint":""},
- {"id":"","text":"GFPGAN","localized":"","hint":"Restore low quality faces using GFPGAN neural network"},
- {"id":"","text":"CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect","localized":"","hint":""},
- {"id":"","text":"Move face restoration model from VRAM into RAM after processing","localized":"","hint":""},
- {"id":"","text":"Default view for Extra Networks","localized":"","hint":""},
- {"id":"","text":"Multiplier for extra networks","localized":"","hint":"When adding extra network such as Hypernetwork or Lora to prompt, use this multiplier for it"},
- {"id":"","text":"Card width for Extra Networks (px)","localized":"","hint":""},
- {"id":"","text":"Card height for Extra Networks (px)","localized":"","hint":""},
- {"id":"","text":"Extra text to add before <...> when adding extra network to prompt","localized":"","hint":""},
- {"id":"","text":"Add hypernetwork to prompt","localized":"","hint":""},
- {"id":"","text":"Enable redundant token merging via tomesd for speed and memory improvements","localized":"","hint":""},
- {"id":"","text":"Token merging Ratio. Higher merging ratio = faster generation, smaller VRAM usage, lower quality","localized":"","hint":""},
- {"id":"","text":"Apply only to high-res fix pass. Disabling can yield a ~20-35% speedup on contemporary resolutions","localized":"","hint":""},
- {"id":"","text":"Merging Ratio (high-res pass) - If 'Apply only to high-res' is enabled, this will always be the ratio used","localized":"","hint":""},
- {"id":"","text":"Use random perturbations - Can improve outputs for certain samplers. For others, it may cause visual artifacting","localized":"","hint":""},
- {"id":"","text":"Merge attention (Recommend on)","localized":"","hint":""},
- {"id":"","text":"Merge cross attention (Recommend off)","localized":"","hint":""},
- {"id":"","text":"Merge mlp (Strongly recommend off)","localized":"","hint":""},
- {"id":"","text":"1","localized":"","hint":""},
- {"id":"","text":"2","localized":"","hint":""},
- {"id":"","text":"4","localized":"","hint":""},
- {"id":"","text":"8","localized":"","hint":""},
- {"id":"","text":"Stride - X","localized":"","hint":""},
- {"id":"","text":"Stride - Y","localized":"","hint":""},
- {"id":"","text":"user","localized":"","hint":""},
- {"id":"","text":"all","localized":"","hint":""}
+ {"id":"","label":"Number of cached model checkpoints","localized":"","hint":""},
+ {"id":"","label":"Number of cached VAE checkpoints","localized":"","hint":""},
+ {"id":"","label":"Select VAE","localized":"","hint":""},
+ {"id":"","label":"Enable splitting of hires batch processing","localized":"","hint":""},
+ {"id":"","label":"When loading models attempt stream loading optimized for slow or network storage","localized":"","hint":""},
+ {"id":"","label":"When loading models attempt to reuse previous model dictionary","localized":"","hint":""},
+ {"id":"","label":"Disable cross-attention layer optimization","localized":"","hint":""},
+ {"id":"","label":"xFormers","localized":"","hint":""},
+ {"id":"","label":"Scaled-Dot-Product","localized":"","hint":""},
+ {"id":"","label":"Doggettx's","localized":"","hint":""},
+ {"id":"","label":"InvokeAI's","localized":"","hint":""},
+ {"id":"","label":"Sub-quadratic","localized":"","hint":""},
+ {"id":"","label":"Split attention","localized":"","hint":""},
+ {"id":"","label":"xFormers enable flash Attention","localized":"","hint":""},
+ {"id":"","label":"SDP disable memory attention","localized":"","hint":""},
+ {"id":"","label":"Sub-quadratic cross-attention query chunk size","localized":"","hint":""},
+ {"id":"","label":"Sub-quadratic cross-attention kv chunk size","localized":"","hint":""},
+ {"id":"","label":"Sub-quadratic cross-attention chunking threshold","localized":"","hint":""},
+ {"id":"","label":"Full parser","localized":"","hint":""},
+ {"id":"","label":"Compel parser","localized":"","hint":""},
+ {"id":"","label":"A1111 parser","localized":"","hint":""},
+ {"id":"","label":"Fixed attention","localized":"","hint":""},
+ {"id":"","label":"Prompt attention mean normalization","localized":"","hint":""},
+ {"id":"","label":"Disable conditional batching enabled on low memory systems","localized":"","hint":""},
+ {"id":"","label":"Enable samplers quantization for sharper and cleaner results","localized":"","hint":""},
+ {"id":"","label":"Increase coherency by padding from the last comma within n tokens when using more than 75 tokens","localized":"","hint":""},
+ {"id":"","label":"Original","localized":"","hint":""},
+ {"id":"","label":"Diffusers","localized":"","hint":""},
+ {"id":"","label":"VRAM usage polls per second during generation","localized":"","hint":""},
+ {"id":"","label":"Autocast","localized":"","hint":""},
+ {"id":"","label":"Full","localized":"","hint":""},
+ {"id":"","label":"FP32","localized":"","hint":""},
+ {"id":"","label":"FP16","localized":"","hint":""},
+ {"id":"","label":"BF16","localized":"","hint":""},
+ {"id":"","label":"Use full precision for model (--no-half)","localized":"","hint":""},
+ {"id":"","label":"Use full precision for VAE (--no-half-vae)","localized":"","hint":""},
+ {"id":"","label":"Enable upcast sampling","localized":"","hint":""},
+ {"id":"","label":"Enable upcast cross attention layer","localized":"","hint":""},
+ {"id":"","label":"Disable NaN check in produced images/latent spaces","localized":"","hint":""},
+ {"id":"","label":"Attempt to roll back VAE when produced NaN values, requires NaN check (experimental)","localized":"","hint":""},
+ {"id":"","label":"Use channels last as torch memory format ","localized":"","hint":""},
+ {"id":"","label":"Enable full-depth cuDNN benchmark feature","localized":"","hint":""},
+ {"id":"","label":"Allow TF32 math ops","localized":"","hint":""},
+ {"id":"","label":"Allow TF16 reduced precision math ops","localized":"","hint":""},
+ {"id":"","label":"Enable model compile (experimental)","localized":"","hint":""},
+ {"id":"","label":"inductor","localized":"","hint":""},
+ {"id":"","label":"cudagraphs","localized":"","hint":""},
+ {"id":"","label":"aot_ts_nvfuser","localized":"","hint":""},
+ {"id":"","label":"hidet","localized":"","hint":""},
+ {"id":"","label":"ipex","localized":"","hint":""},
+ {"id":"","label":"Model compile verbose mode","localized":"","hint":""},
+ {"id":"","label":"Model compile suppress errors","localized":"","hint":""},
+ {"id":"","label":"Disable Torch memory garbage collection (experimental)","localized":"","hint":""},
+ {"id":"","label":"Directory for temporary images; leave empty for default","localized":"","hint":""},
+ {"id":"","label":"Cleanup non-default temporary directory when starting webui","localized":"","hint":""},
+ {"id":"","label":"Path to directory with stable diffusion checkpoints","localized":"","hint":""},
+ {"id":"","label":"Path to directory with stable diffusion diffusers","localized":"","hint":""},
+ {"id":"","label":"Path to directory with VAE files","localized":"","hint":""},
+ {"id":"","label":"Embeddings directory for textual inversion","localized":"","hint":""},
+ {"id":"","label":"Hypernetwork directory","localized":"","hint":""},
+ {"id":"","label":"Path to directory with codeformer model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with GFPGAN model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with ESRGAN model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with BSRGAN model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with RealESRGAN model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with ScuNET model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with SwinIR model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with LDSR model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with CLIP model file(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with Lora network(s)","localized":"","hint":""},
+ {"id":"","label":"Path to directory with LyCORIS network(s)","localized":"","hint":""},
+ {"id":"","label":"Path to user-defined styles file","localized":"","hint":""},
+ {"id":"","label":"Always save all generated images","localized":"","hint":""},
+ {"id":"","label":"File format for generated images","localized":"","hint":""},
+ {"id":"","label":"Images filename pattern","localized":"","hint":"Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime], [datetime], [job_timestamp]; leave empty for default"},
+ {"id":"","label":"Add number to filename when saving","localized":"","hint":""},
+ {"id":"","label":"Always save all generated image grids","localized":"","hint":""},
+ {"id":"","label":"File format for grids","localized":"","hint":""},
+ {"id":"","label":"Add extended info (seed, prompt) to filename when saving grid","localized":"","hint":""},
+ {"id":"","label":"Do not save grids consisting of one picture","localized":"","hint":""},
+ {"id":"","label":"Prevent empty spots in grid (when set to autodetect)","localized":"","hint":""},
+ {"id":"","label":"Grid row count; use -1 for autodetect and 0 for it to be same as batch size","localized":"","hint":""},
+ {"id":"","label":"Create a text file next to every image with generation parameters","localized":"","hint":""},
+ {"id":"","label":"Create a JSON log file with image information for each saved image","localized":"","hint":""},
+ {"id":"","label":"Save a copy of image before doing face restoration","localized":"","hint":""},
+ {"id":"","label":"Save a copy of image before applying highres fix","localized":"","hint":""},
+ {"id":"","label":"Save a copy of image before applying color correction to img2img results","localized":"","hint":""},
+ {"id":"","label":"Save a copy of the inpainting greyscale mask","localized":"","hint":""},
+ {"id":"","label":"Save a copy of inpainting masked composite","localized":"","hint":""},
+ {"id":"","label":"Save a copy of processing init images","localized":"","hint":""},
+ {"id":"","label":"Quality for saved jpeg images","localized":"","hint":""},
+ {"id":"","label":"Use lossless compression for webp images","localized":"","hint":""},
+ {"id":"","label":"Maximum allowed image size in megapixels","localized":"","hint":""},
+ {"id":"","label":"Use original name for output filename during batch process in extras tab","localized":"","hint":""},
+ {"id":"","label":"Use upscaler name as filename suffix in the extras tab","localized":"","hint":""},
+ {"id":"","label":"When using 'Save' button, only save a single selected image","localized":"","hint":""},
+ {"id":"","label":"Save images to a subdirectory","localized":"","hint":""},
+ {"id":"","label":"Save grids to a subdirectory","localized":"","hint":""},
+ {"id":"","label":"Save images to a subdirectory when using Save button","localized":"","hint":""},
+ {"id":"","label":"Directory name pattern","localized":"","hint":"Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg],[prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime], [datetime], [job_timestamp]; leave empty for default"},
+ {"id":"","label":"Max prompt words for [prompt_words] pattern","localized":"","hint":""},
+ {"id":"","label":"Apply color correction to match original colors","localized":"","hint":""},
+ {"id":"","label":"For image processing do exact number of steps as specified","localized":"","hint":""},
+ {"id":"","label":"Image transparent color fill","localized":"","hint":""},
+ {"id":"","label":"Inpainting conditioning mask strength","localized":"","hint":"Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked (default). 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes"},
+ {"id":"","label":"Noise multiplier for image processing","localized":"","hint":""},
+ {"id":"","label":"Clip skip","localized":"","hint":"Early stopping parameter for CLIP model; 1 is stop at last layer as usual, 2 is stop at penultimate layer, etc"},
+ {"id":"","label":"Output directory for images; if empty, defaults to three directories below","localized":"","hint":""},
+ {"id":"","label":"Output directory for txt2img images","localized":"","hint":""},
+ {"id":"","label":"Output directory for img2img images","localized":"","hint":""},
+ {"id":"","label":"Output directory for images from extras tab","localized":"","hint":""},
+ {"id":"","label":"Output directory for grids; if empty, defaults to two directories below","localized":"","hint":""},
+ {"id":"","label":"Output directory for txt2img grids","localized":"","hint":""},
+ {"id":"","label":"Output directory for img2img grids","localized":"","hint":""},
+ {"id":"","label":"Directory for saving images using the Save button","localized":"","hint":""},
+ {"id":"","label":"Directory for saving init images when using img2img","localized":"","hint":""},
+ {"id":"","label":"UI theme","localized":"","hint":""},
+ {"id":"","label":"Auto","localized":"","hint":""},
+ {"id":"","label":"Dark","localized":"","hint":""},
+ {"id":"","label":"Light","localized":"","hint":""},
+ {"id":"","label":"Show grid in results for web","localized":"","hint":""},
+ {"id":"","label":"For inpainting, include the greyscale mask in results for web","localized":"","hint":""},
+ {"id":"","label":"For inpainting, include masked composite in results for web","localized":"","hint":""},
+ {"id":"","label":"Do not change the selected model when reading generation parameters","localized":"","hint":""},
+ {"id":"","label":"Send seed when sending prompt or image to other interface","localized":"","hint":""},
+ {"id":"","label":"Send size when sending prompt or image to another interface","localized":"","hint":""},
+ {"id":"","label":"Font for image grids that have text","localized":"","hint":""},
+ {"id":"","label":"Ctrl+up/down precision when editing (attention:1.1)","localized":"","hint":""},
+ {"id":"","label":"Ctrl+up/down precision when editing ","localized":"","hint":""},
+ {"id":"","label":"Ctrl+up/down word delimiters","localized":"","hint":""},
+ {"id":"","label":"Quicksettings list","localized":"","hint":"List of setting names, separated by commas, for settings that should go to the quick access bar at the top instead the setting tab"},
+ {"id":"","label":"Hidden UI tabs","localized":"","hint":""},
+ {"id":"","label":"UI tabs order","localized":"","hint":""},
+ {"id":"","label":"UI scripts order","localized":"","hint":""},
+ {"id":"","label":"txt2img/img2img UI item order","localized":"","hint":""},
+ {"id":"","label":"Extra networks tab order","localized":"","hint":"Comma-separated list of tab names; tabs listed here will appear in the extra networks UI first and in order lsited"},
+ {"id":"","label":"Show progressbar","localized":"","hint":""},
+ {"id":"","label":"Show live previews of the created image","localized":"","hint":""},
+ {"id":"","label":"Show previews of all images generated in a batch as a grid","localized":"","hint":""},
+ {"id":"","label":"Play a sound when images are finished generating","localized":"","hint":""},
+ {"id":"","label":"Path to notification sound","localized":"","hint":""},
+ {"id":"","label":"Live preview display period","localized":"","hint":""},
+ {"id":"","label":"Full VAE","localized":"","hint":""},
+ {"id":"","label":"Approximate NN","localized":"","hint":"Cheap neural network approximation. Very fast compared to VAE, but produces pictures with 4 times smaller horizontal/vertical resolution and lower quality"},
+ {"id":"","label":"Approximate simple","localized":"","hint":"Very cheap approximation. Very fast compared to VAE, but produces pictures with 8 times smaller horizontal/vertical resolution and extremely low quality"},
+ {"id":"","label":"TAESD","localized":"","hint":""},
+ {"id":"","label":"Combined","localized":"","hint":""},
+ {"id":"","label":"Progressbar/preview update period, in milliseconds","localized":"","hint":""},
+ {"id":"","label":"Euler a","localized":"","hint":"Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help"},
+ {"id":"","label":"Euler","localized":"","hint":""},
+ {"id":"","label":"LMS","localized":"","hint":""},
+ {"id":"","label":"Heun","localized":"","hint":""},
+ {"id":"","label":"DPM2","localized":"","hint":""},
+ {"id":"","label":"DPM2 a","localized":"","hint":""},
+ {"id":"","label":"DPM++ 2S a","localized":"","hint":""},
+ {"id":"","label":"DPM++ 2M","localized":"","hint":""},
+ {"id":"","label":"DPM++ SDE","localized":"","hint":""},
+ {"id":"","label":"DPM++ 2M SDE","localized":"","hint":""},
+ {"id":"","label":"DPM fast","localized":"","hint":""},
+ {"id":"","label":"DPM adaptive","localized":"","hint":"Ignores step count - uses a number of steps determined by the CFG and resolution"},
+ {"id":"","label":"LMS Karras","localized":"","hint":""},
+ {"id":"","label":"DPM2 Karras","localized":"","hint":""},
+ {"id":"","label":"DPM2 a Karras","localized":"","hint":""},
+ {"id":"","label":"DPM++ 2S a Karras","localized":"","hint":""},
+ {"id":"","label":"DPM++ 2M Karras","localized":"","hint":""},
+ {"id":"","label":"DPM++ SDE Karras","localized":"","hint":""},
+ {"id":"","label":"DPM++ 2M SDE Karras","localized":"","hint":""},
+ {"id":"","label":"DDIM","localized":"","hint":"Denoising Diffusion Implicit Models - best at inpainting"},
+ {"id":"","label":"UniPC","localized":"","hint":"Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models"},
+ {"id":"","label":"Secondary sampler","localized":"","hint":""},
+ {"id":"","label":"Force latent upscaler sampler","localized":"","hint":""},
+ {"id":"","label":"Noise multiplier for ancestral samplers (eta)","localized":"","hint":""},
+ {"id":"","label":"Noise multiplier for DDIM (eta)","localized":"","hint":""},
+ {"id":"","label":"uniform","localized":"","hint":""},
+ {"id":"","label":"quad","localized":"","hint":""},
+ {"id":"","label":"sigma churn","localized":"","hint":""},
+ {"id":"","label":"Negative Guidance minimum sigma","localized":"","hint":""},
+ {"id":"","label":"sigma tmin","localized":"","hint":""},
+ {"id":"","label":"sigma noise","localized":"","hint":""},
+ {"id":"","label":"Noise seed delta (eta)","localized":"","hint":""},
+ {"id":"","label":"Always discard next-to-last sigma","localized":"","hint":""},
+ {"id":"","label":"bh1","localized":"","hint":""},
+ {"id":"","label":"bh2","localized":"","hint":""},
+ {"id":"","label":"vary_coeff","localized":"","hint":""},
+ {"id":"","label":"time_uniform","localized":"","hint":""},
+ {"id":"","label":"time_quadratic","localized":"","hint":""},
+ {"id":"","label":"logSNR","localized":"","hint":""},
+ {"id":"","label":"UniPC order (must be < sampling steps)","localized":"","hint":""},
+ {"id":"","label":"UniPC lower order final","localized":"","hint":""},
+ {"id":"","label":"Enable addtional postprocessing operations","localized":"","hint":""},
+ {"id":"","label":"Postprocessing operation order","localized":"","hint":""},
+ {"id":"","label":"Maximum number of images in upscaling cache","localized":"","hint":""},
+ {"id":"","label":"Move VAE and CLIP to RAM when training if possible","localized":"","hint":""},
+ {"id":"","label":"Pin training dataset to memory","localized":"","hint":""},
+ {"id":"","label":"Saves resumable optimizer state when training embedding or hypernetwork","localized":"","hint":""},
+ {"id":"","label":"Save textual inversion and hypernet settings to a text file whenever training starts","localized":"","hint":""},
+ {"id":"","label":"Filename word regex","localized":"","hint":"This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is"},
+ {"id":"","label":"Filename join string","localized":"","hint":"This string will be used to join split words into a single line if the option above is enabled"},
+ {"id":"","label":"Embeddings train templates directory","localized":"","hint":""},
+ {"id":"","label":"Number of repeats for a single input image per epoch; used only for displaying epoch number","localized":"","hint":""},
+ {"id":"","label":"Save an csv containing the loss to log directory every N steps, 0 to disable","localized":"","hint":""},
+ {"id":"","label":"Enable tensorboard logging","localized":"","hint":""},
+ {"id":"","label":"Save generated images within tensorboard","localized":"","hint":""},
+ {"id":"","label":"How often, in seconds, to flush the pending tensorboard events and summaries to disk","localized":"","hint":""},
+ {"id":"","label":"Interrogate: keep models in VRAM","localized":"","hint":""},
+ {"id":"","label":"Interrogate: include ranks of model tags matches in results","localized":"","hint":""},
+ {"id":"","label":"Interrogate: num_beams for BLIP","localized":"","hint":""},
+ {"id":"","label":"Interrogate: minimum description length (excluding artists, etc..)","localized":"","hint":""},
+ {"id":"","label":"Interrogate: maximum description length","localized":"","hint":""},
+ {"id":"","label":"CLIP: maximum number of lines in text file (0 = No limit)","localized":"","hint":""},
+ {"id":"","label":"flavors","localized":"","hint":""},
+ {"id":"","label":"artists","localized":"","hint":""},
+ {"id":"","label":"mediums","localized":"","hint":""},
+ {"id":"","label":"movements","localized":"","hint":""},
+ {"id":"","label":"Interrogate: deepbooru score threshold","localized":"","hint":""},
+ {"id":"","label":"Interrogate: deepbooru sort alphabetically","localized":"","hint":""},
+ {"id":"","label":"use spaces for tags in deepbooru","localized":"","hint":""},
+ {"id":"","label":"escape (\\) brackets in deepbooru (so they are used as literal brackets and not for emphasis)","localized":"","hint":""},
+ {"id":"","label":"filter out those tags from deepbooru output (separated by comma)","localized":"","hint":""},
+ {"id":"","label":"Default upscaler for image resize operations","localized":"","hint":""},
+ {"id":"","label":"Tile size for ESRGAN upscalers (0 = no tiling)","localized":"","hint":""},
+ {"id":"","label":"Tile overlap in pixels for ESRGAN upscalers","localized":"","hint":""},
+ {"id":"","label":"Tile size for SCUNET upscalers. 0 = no tiling","localized":"","hint":""},
+ {"id":"","label":"Tile overlap, in pixels for SCUNET upscalers. Low values = visible seam","localized":"","hint":""},
+ {"id":"","label":"Hires fix uses width & height to set final resolution rather than first pass","localized":"","hint":""},
+ {"id":"","label":"Do not fix prompt schedule for second order samplers","localized":"","hint":""},
+ {"id":"","label":"Use LyCoris handler for all Lora types","localized":"","hint":""},
+ {"id":"","label":"Use Kohya method for handling multiple Loras","localized":"","hint":""},
+ {"id":"","label":"CodeFormer","localized":"","hint":""},
+ {"id":"","label":"GFPGAN","localized":"","hint":"Restore low quality faces using GFPGAN neural network"},
+ {"id":"","label":"CodeFormer weight parameter; 0 = maximum effect; 1 = minimum effect","localized":"","hint":""},
+ {"id":"","label":"Move face restoration model from VRAM into RAM after processing","localized":"","hint":""},
+ {"id":"","label":"Default view for Extra Networks","localized":"","hint":""},
+ {"id":"","label":"Multiplier for extra networks","localized":"","hint":"When adding extra network such as Hypernetwork or Lora to prompt, use this multiplier for it"},
+ {"id":"","label":"Card width for Extra Networks (px)","localized":"","hint":""},
+ {"id":"","label":"Card height for Extra Networks (px)","localized":"","hint":""},
+ {"id":"","label":"Extra text to add before <...> when adding extra network to prompt","localized":"","hint":""},
+ {"id":"","label":"Add hypernetwork to prompt","localized":"","hint":""},
+ {"id":"","label":"Enable redundant token merging via tomesd for speed and memory improvements","localized":"","hint":""},
+ {"id":"","label":"Token merging Ratio. Higher merging ratio = faster generation, smaller VRAM usage, lower quality","localized":"","hint":""},
+ {"id":"","label":"Apply only to high-res fix pass. Disabling can yield a ~20-35% speedup on contemporary resolutions","localized":"","hint":""},
+ {"id":"","label":"Merging Ratio (high-res pass) - If 'Apply only to high-res' is enabled, this will always be the ratio used","localized":"","hint":""},
+ {"id":"","label":"Use random perturbations - Can improve outputs for certain samplers. For others, it may cause visual artifacting","localized":"","hint":""},
+ {"id":"","label":"Merge attention (Recommend on)","localized":"","hint":""},
+ {"id":"","label":"Merge cross attention (Recommend off)","localized":"","hint":""},
+ {"id":"","label":"Merge mlp (Strongly recommend off)","localized":"","hint":""},
+ {"id":"","label":"Stride - X","localized":"","hint":""},
+ {"id":"","label":"Stride - Y","localized":"","hint":""}
],
"scripts": [
- {"id":"","text":"Script","localized":"","hint":""},
- {"id":"","text":"Swap X/Y axes","localized":"","hint":""},
- {"id":"","text":"Swap Y/Z axes","localized":"","hint":""},
- {"id":"","text":"Swap X/Z axes","localized":"","hint":""},
- {"id":"","text":"Resize to ","localized":"","hint":""},
- {"id":"","text":"Resize by ","localized":"","hint":""},
- {"id":"","text":"Use via API ","localized":"","hint":""},
- {"id":"","text":"Stable Diffusion checkpoint","localized":"","hint":""},
- {"id":"","text":"Styles","localized":"","hint":""},
- {"id":"","text":"Put variable parts at start of prompt","localized":"","hint":""},
- {"id":"","text":"Use different seed for each picture","localized":"","hint":""},
- {"id":"","text":"positive","localized":"","hint":""},
- {"id":"","text":"negative","localized":"","hint":""},
- {"id":"","text":"comma","localized":"","hint":""},
- {"id":"","text":"space","localized":"","hint":""},
- {"id":"","text":"Iterate seed every line","localized":"","hint":""},
- {"id":"","text":"Use same random seed for all lines","localized":"","hint":""},
- {"id":"","text":"List of prompt inputs","localized":"","hint":""},
- {"id":"","text":"X type","localized":"","hint":""},
- {"id":"","text":"X values","localized":"","hint":"Separate values for X axis using commas"},
- {"id":"","text":"Y type","localized":"","hint":""},
- {"id":"","text":"Y values","localized":"","hint":"Separate values for Y axis using commas"},
- {"id":"","text":"Z type","localized":"","hint":""},
- {"id":"","text":"Z values","localized":"","hint":""},
- {"id":"","text":"Draw legend","localized":"","hint":""},
- {"id":"","text":"Keep random for seeds","localized":"","hint":""},
- {"id":"","text":"Do not create grid","localized":"","hint":""},
- {"id":"","text":"Include Sub Images","localized":"","hint":""},
- {"id":"","text":"Include Sub Grids","localized":"","hint":""},
- {"id":"","text":"Override `Sampling method` to Euler?(this method is built for it)","localized":"","hint":""},
- {"id":"","text":"Override `prompt` to the same value as `original prompt`?(and `negative prompt`)","localized":"","hint":""},
- {"id":"","text":"Original prompt","localized":"","hint":""},
- {"id":"","text":"Original negative prompt","localized":"","hint":""},
- {"id":"","text":"Override `Sampling Steps` to the same value as `Decode steps`?","localized":"","hint":""},
- {"id":"","text":"Decode steps","localized":"","hint":""},
- {"id":"","text":"Override `Denoising strength` to 1?","localized":"","hint":""},
- {"id":"","text":"Decode CFG scale","localized":"","hint":""},
- {"id":"","text":"Randomness","localized":"","hint":""},
- {"id":"","text":"Sigma adjustment for finding noise for image","localized":"","hint":""},
- {"id":"","text":"Loops","localized":"","hint":"How many times to process an image. Each output is used as the input of the next loop. If set to 1, behavior will be as if this script were not used"},
- {"id":"","text":"Final denoising strength","localized":"","hint":"The denoising strength for the final loop of each image in the batch"},
- {"id":"","text":"Denoising strength curve","localized":"","hint":"The denoising curve controls the rate of denoising strength change each loop. Aggressive: Most of the change will happen towards the start of the loops. Linear: Change will be constant through all loops. Lazy: Most of the change will happen towards the end of the loops"},
- {"id":"","text":"Append interrogated prompt at each iteration","localized":"","hint":""},
- {"id":"","text":"Pixels to expand","localized":"","hint":""},
- {"id":"","text":"left","localized":"","hint":""},
- {"id":"","text":"right","localized":"","hint":""},
- {"id":"","text":"up","localized":"","hint":""},
- {"id":"","text":"down","localized":"","hint":""},
- {"id":"","text":"Fall-off exponent (lower=higher detail)","localized":"","hint":""},
- {"id":"","text":"Color variation","localized":"","hint":""},
- {"id":"","text":"Tile overlap","localized":"","hint":"For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam"},
- {"id":"","text":"Scale Factor","localized":"","hint":""},
- {"id":"","text":"None","localized":"","hint":"Do not do anything special"},
- {"id":"","text":"Grid margins","localized":"","hint":""}
+ {"id":"","label":"Script","localized":"","hint":""},
+ {"id":"","label":"Swap X/Y axes","localized":"","hint":""},
+ {"id":"","label":"Swap Y/Z axes","localized":"","hint":""},
+ {"id":"","label":"Swap X/Z axes","localized":"","hint":""},
+ {"id":"","label":"Resize to ","localized":"","hint":""},
+ {"id":"","label":"Resize by ","localized":"","hint":""},
+ {"id":"","label":"Use via API ","localized":"","hint":""},
+ {"id":"","label":"Stable Diffusion checkpoint","localized":"","hint":""},
+ {"id":"","label":"Styles","localized":"","hint":""},
+ {"id":"","label":"Put variable parts at start of prompt","localized":"","hint":""},
+ {"id":"","label":"Use different seed for each picture","localized":"","hint":""},
+ {"id":"","label":"positive","localized":"","hint":""},
+ {"id":"","label":"negative","localized":"","hint":""},
+ {"id":"","label":"comma","localized":"","hint":""},
+ {"id":"","label":"space","localized":"","hint":""},
+ {"id":"","label":"Iterate seed every line","localized":"","hint":""},
+ {"id":"","label":"Use same random seed for all lines","localized":"","hint":""},
+ {"id":"","label":"List of prompt inputs","localized":"","hint":""},
+ {"id":"","label":"X type","localized":"","hint":""},
+ {"id":"","label":"X values","localized":"","hint":"Separate values for X axis using commas"},
+ {"id":"","label":"Y type","localized":"","hint":""},
+ {"id":"","label":"Y values","localized":"","hint":"Separate values for Y axis using commas"},
+ {"id":"","label":"Z type","localized":"","hint":""},
+ {"id":"","label":"Z values","localized":"","hint":""},
+ {"id":"","label":"Draw legend","localized":"","hint":""},
+ {"id":"","label":"Keep random for seeds","localized":"","hint":""},
+ {"id":"","label":"Do not create grid","localized":"","hint":""},
+ {"id":"","label":"Include Sub Images","localized":"","hint":""},
+ {"id":"","label":"Include Sub Grids","localized":"","hint":""},
+ {"id":"","label":"Override `Sampling method` to Euler?(this method is built for it)","localized":"","hint":""},
+ {"id":"","label":"Override `prompt` to the same value as `original prompt`?(and `negative prompt`)","localized":"","hint":""},
+ {"id":"","label":"Original prompt","localized":"","hint":""},
+ {"id":"","label":"Original negative prompt","localized":"","hint":""},
+ {"id":"","label":"Override `Sampling Steps` to the same value as `Decode steps`?","localized":"","hint":""},
+ {"id":"","label":"Decode steps","localized":"","hint":""},
+ {"id":"","label":"Override `Denoising strength` to 1?","localized":"","hint":""},
+ {"id":"","label":"Decode CFG scale","localized":"","hint":""},
+ {"id":"","label":"Randomness","localized":"","hint":""},
+ {"id":"","label":"Sigma adjustment for finding noise for image","localized":"","hint":""},
+ {"id":"","label":"Loops","localized":"","hint":"How many times to process an image. Each output is used as the input of the next loop. If set to 1, behavior will be as if this script were not used"},
+ {"id":"","label":"Final denoising strength","localized":"","hint":"The denoising strength for the final loop of each image in the batch"},
+ {"id":"","label":"Denoising strength curve","localized":"","hint":"The denoising curve controls the rate of denoising strength change each loop. Aggressive: Most of the change will happen towards the start of the loops. Linear: Change will be constant through all loops. Lazy: Most of the change will happen towards the end of the loops"},
+ {"id":"","label":"Append interrogated prompt at each iteration","localized":"","hint":""},
+ {"id":"","label":"Pixels to expand","localized":"","hint":""},
+ {"id":"","label":"left","localized":"","hint":""},
+ {"id":"","label":"right","localized":"","hint":""},
+ {"id":"","label":"up","localized":"","hint":""},
+ {"id":"","label":"down","localized":"","hint":""},
+ {"id":"","label":"Fall-off exponent (lower=higher detail)","localized":"","hint":""},
+ {"id":"","label":"Color variation","localized":"","hint":""},
+ {"id":"","label":"Tile overlap","localized":"","hint":"For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam"},
+ {"id":"","label":"Scale Factor","localized":"","hint":""},
+ {"id":"","label":"None","localized":"","hint":"Do not do anything special"},
+ {"id":"","label":"Grid margins","localized":"","hint":""}
]
}
diff --git a/javascript/hints.js b/javascript/hints.js
deleted file mode 100644
index 026836b67..000000000
--- a/javascript/hints.js
+++ /dev/null
@@ -1,97 +0,0 @@
-// HTML tooltips for various UI elements
-
-titles = {
- // unicode icons
- '\u{1f3b2}\ufe0f': 'Set seed to -1, which will cause a new random number to be used every time',
- '\u267b\ufe0f': 'Reuse seed from last generation, mostly useful if it was randomed',
- '\u2199\ufe0f': 'Read generation parameters from prompt or last generation if prompt is empty into user interface.',
- '\u{1f4c2}': 'Open images output directory',
- '\u{1f4be}': 'Save style',
- '\u{1f5d1}\ufe0f': 'Clear prompt',
- '\u{1f4cb}': 'Apply selected styles to current prompt',
- '\u{1f4d2}': 'Paste available values into the field',
- '\u{1f3b4}': 'Show/hide extra networks',
- '\u{1F4D8}': 'Read generation parameters from prompt or last generation if prompt is empty into user interface.',
- '\u{1F6C5}': 'Save style',
- '\u{1F9F3}': 'Apply selected styles to current prompt',
- '\u{1F6AE}': 'Clear prompt',
- '\u{1F310}': 'Show/hide extra networks',
- // strings
- 'Sampling steps': 'How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results',
- 'Sampling method': 'Which algorithm to use to produce the image',
- 'GFPGAN': 'Restore low quality faces using GFPGAN neural network',
- 'Euler a': 'Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help',
- 'DDIM': 'Denoising Diffusion Implicit Models - best at inpainting',
- 'UniPC': 'Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models',
- 'DPM adaptive': 'Ignores step count - uses a number of steps determined by the CFG and resolution',
- 'Batch count': 'How many batches of images to create (has no impact on generation performance or VRAM usage)',
- 'Batch size': 'How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)',
- 'CFG Scale': 'Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results',
- 'Seed': "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result",
- 'Inpaint a part of image': 'Draw a mask over an image, and the script will regenerate the masked area with content according to prompt',
- 'SD upscale': 'Upscale image normally, split result into tiles, improve each tile using img2img, merge whole image back',
- 'Just resize': 'Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.',
- 'Crop and resize': 'Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.',
- 'Resize and fill': "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.",
- 'Mask blur': 'How much to blur the mask before processing, in pixels.',
- 'Masked content': 'What to put inside the masked area before processing it with Stable Diffusion.',
- 'fill': 'fill it with colors of the image',
- 'original': 'keep whatever was there originally',
- 'latent noise': 'fill it with latent space noise',
- 'latent nothing': 'fill it with latent space zeroes',
- 'Inpaint at full resolution': 'Upscale masked region to target resolution, do inpainting, downscale back and paste into original image',
- 'Denoising strength': "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.",
- 'Skip': 'Stop processing current image and continue processing.',
- 'Interrupt': 'Stop processing images and return any results accumulated so far.',
- 'Save': 'Write image to a directory (default - log/images) and generation parameters into csv file.',
- 'X values': 'Separate values for X axis using commas.',
- 'Y values': 'Separate values for Y axis using commas.',
- 'None': 'Do not do anything special',
- 'Prompt matrix': 'Separate prompts into parts using vertical pipe character (|) and the script will create a picture for every combination of them (except for the first part, which will be present in all combinations)',
- 'X/Y/Z plot': 'Create grid(s) where images will have different parameters. Use inputs below to specify which parameters will be shared by columns and rows',
- 'Custom code': 'Run Python code. Advanced user only. Must run program with --allow-code for this to work',
- 'Prompt S/R': 'Separate a list of words with commas, and the first word will be used as a keyword: script will search for this word in the prompt, and replace it with others',
- 'Prompt order': 'Separate a list of words with commas, and the script will make a variation of prompt with those words for their every possible order',
- 'Tiling': 'Produce an image that can be tiled.',
- 'Tile overlap': 'For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.',
- 'Variation seed': 'Seed of a different picture to be mixed into the generation.',
- 'Variation strength': 'How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).',
- 'Resize seed from height': 'Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution',
- 'Resize seed from width': 'Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution',
- 'Interrogate': 'Reconstruct prompt from existing image and put it into the prompt field.',
- 'Images filename pattern': 'Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime], [datetime], [job_timestamp]; leave empty for default.',
- 'Directory name pattern': 'Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg],[prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime], [datetime], [job_timestamp]; leave empty for default.',
- 'Max prompt words': 'Set the maximum number of words to be used in the [prompt_words] option; ATTENTION: If the words are too long, they may exceed the maximum length of the file path that the system can handle',
- 'Loopback': 'Performs img2img processing multiple times. Output images are used as input for the next loop.',
- 'Loops': 'How many times to process an image. Each output is used as the input of the next loop. If set to 1, behavior will be as if this script were not used.',
- 'Final denoising strength': 'The denoising strength for the final loop of each image in the batch.',
- 'Denoising strength curve': 'The denoising curve controls the rate of denoising strength change each loop. Aggressive: Most of the change will happen towards the start of the loops. Linear: Change will be constant through all loops. Lazy: Most of the change will happen towards the end of the loops.',
- 'Style 1': 'Style to apply; styles have components for both positive and negative prompts and apply to both',
- 'Style 2': 'Style to apply; styles have components for both positive and negative prompts and apply to both',
- 'Apply style': 'Insert selected styles into prompt fields',
- 'Create style': 'Save current prompts as a style. If you add the token {prompt} to the text, the style uses that as a placeholder for your prompt when you use the style in the future.',
- 'Checkpoint name': 'Loads weights from checkpoint before making images. You can either use hash or a part of filename (as seen in settings) for checkpoint name. Recommended to use with Y axis for less switching.',
- 'Inpainting conditioning mask strength': 'Only applies to inpainting models. Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked, which is the default behaviour. 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes.',
- 'vram': 'Torch active: Peak amount of VRAM used by Torch during generation, excluding cached data.\nTorch reserved: Peak amount of VRAM allocated by Torch, including all active and cached data.\nSys VRAM: Peak amount of VRAM allocation across all applications / total GPU VRAM (peak utilization%).',
- 'Eta noise seed delta': 'If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.',
- 'Do not add watermark to images': 'If this option is enabled, watermark will not be added to created images. Warning: if you do not add watermark, you may be behaving in an unethical manner.',
- 'Filename word regex': 'This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.',
- 'Filename join string': 'This string will be used to join split words into a single line if the option above is enabled.',
- 'Quicksettings list': 'List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.',
- 'Weighted sum': 'Result = A * (1 - M) + B * M',
- 'Add difference': 'Result = A + (B - C) * M',
- 'No interpolation': 'Result = A',
- 'Initialization text': 'If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors',
- 'Learning rate': 'How fast should training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.',
- 'Clip skip': 'Early stopping parameter for CLIP model; 1 is stop at last layer as usual, 2 is stop at penultimate layer, etc.',
- 'Approx NN': 'Cheap neural network approximation. Very fast compared to VAE, but produces pictures with 4 times smaller horizontal/vertical resolution and lower quality.',
- 'Approx cheap': 'Very cheap approximation. Very fast compared to VAE, but produces pictures with 8 times smaller horizontal/vertical resolution and extremely low quality.',
- 'Hires. fix': 'Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition',
- 'Hires steps': 'Number of sampling steps for upscaled picture. If 0, uses same as for original.',
- 'Upscale by': 'Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero.',
- 'Resize width to': 'Resizes image to this width. If 0, width is inferred from either of two nearby sliders.',
- 'Resize height to': 'Resizes image to this height. If 0, height is inferred from either of two nearby sliders.',
- 'Multiplier for extra networks': 'When adding extra network such as Hypernetwork or Lora to prompt, use this multiplier for it.',
- 'Discard weights with matching name': "Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights.",
- 'Extra networks tab order': 'Comma-separated list of tab names; tabs listed here will appear in the extra networks UI first and in order lsited.',
-};
diff --git a/javascript/set-hints.js b/javascript/set-hints.js
index 9bef3f3d0..47dac1be4 100644
--- a/javascript/set-hints.js
+++ b/javascript/set-hints.js
@@ -1,28 +1,30 @@
-onAfterUiUpdate(() => {
- gradioApp().querySelectorAll('span, button, select, p').forEach((span) => {
- tooltip = titles[span.textContent];
- if (!tooltip) tooltip = titles[span.value];
- if (!tooltip) {
- for (const c of span.classList) {
- if (c in titles) {
- tooltip = titles[c];
- break;
- }
- }
- }
- if (tooltip) span.title = tooltip;
- });
+let locale = {
+ data: [],
+ timeout: null,
+ finished: false,
+}
- gradioApp().querySelectorAll('select').forEach((select) => {
- if (select.onchange != null) return;
- select.onchange = () => select.title = titles[select.value] || '';
- });
+async function setLocale() {
+ if (locale.finished) return;
+ console.log('setLocale');
+ if (locale.data.length === 0) {
+ const res = await fetch('/file=html/locale_en.json');
+ const json = await res.json();
+ locale.data = Object.values(json).flat();
+ }
+ const elements = [
+ ...Array.from(gradioApp().querySelectorAll('button')),
+ ...Array.from(gradioApp().querySelectorAll('label > span')),
+ ];
+ for (el of elements) {
+ const found = locale.data.find(l => l.label === el.textContent);
+ if (found?.localized?.length > 0) el.textContent = found.localized;
+ if (found?.hint?.length > 0) el.title = found.hint;
+ }
+ locale.finished = true;
+}
+
+onAfterUiUpdate(async () => {
+ if (locale.timeout) clearTimeout(locale.timeout);
+ locale.timeout = setTimeout(setLocale, 250)
});
-
-/*
-// dump elements
-const elements = [
- ...Array.from(gradioApp().querySelectorAll('button')).map(el => ({id: el.id, text: el.textContent, localized: '', hint: el.title })),
- ...Array.from(gradioApp().querySelectorAll('label > span')).map(el => ({id: el.id, text: el.textContent, localized: '', hint: el.title })),
-];
-*/
diff --git a/modules/shared.py b/modules/shared.py
index 9ef938a38..ceab41342 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -251,6 +251,14 @@ def list_themes():
return themes
+def lora_disable():
+ if opts.lora_disable:
+ if 'Lora' not in opts.disabled_extensions:
+ opts.data['disabled_extensions'].append('Lora')
+ else:
+ opts.data['disabled_extensions'] = [x for x in opts.disabled_extensions if x != 'Lora']
+
+
def refresh_themes():
try:
req = requests.get('https://huggingface.co/datasets/freddyaboulton/gradio-theme-subdomains/resolve/main/subdomains.json', timeout=5)
@@ -326,6 +334,9 @@ options_templates.update(options_section(('system-paths', "System Paths"), {
"ckpt_dir": OptionInfo(os.path.join(paths.models_path, 'Stable-diffusion'), "Path to directory with stable diffusion checkpoints"),
"diffusers_dir": OptionInfo(os.path.join(paths.models_path, 'Diffusers'), "Path to directory with stable diffusion diffusers"),
"vae_dir": OptionInfo(os.path.join(paths.models_path, 'VAE'), "Path to directory with VAE files"),
+ "lora_dir": OptionInfo(os.path.join(paths.models_path, 'Lora'), "Path to directory with Lora network(s)"),
+ "lyco_dir": OptionInfo(os.path.join(paths.models_path, 'LyCORIS'), "Path to directory with LyCORIS network(s)"),
+ "styles_dir": OptionInfo(os.path.join(paths.data_path, 'styles.csv'), "Path to user-defined styles file"),
"embeddings_dir": OptionInfo(os.path.join(paths.models_path, 'embeddings'), "Embeddings directory for textual inversion"),
"hypernetwork_dir": OptionInfo(os.path.join(paths.models_path, 'hypernetworks'), "Hypernetwork directory"),
"codeformer_models_path": OptionInfo(os.path.join(paths.models_path, 'Codeformer'), "Path to directory with codeformer model file(s)"),
@@ -337,9 +348,6 @@ options_templates.update(options_section(('system-paths', "System Paths"), {
"swinir_models_path": OptionInfo(os.path.join(paths.models_path, 'SwinIR'), "Path to directory with SwinIR model file(s)"),
"ldsr_models_path": OptionInfo(os.path.join(paths.models_path, 'LDSR'), "Path to directory with LDSR model file(s)"),
"clip_models_path": OptionInfo(os.path.join(paths.models_path, 'CLIP'), "Path to directory with CLIP model file(s)"),
- "lora_dir": OptionInfo(os.path.join(paths.models_path, 'Lora'), "Path to directory with Lora network(s)"),
- "lyco_dir": OptionInfo(os.path.join(paths.models_path, 'LyCORIS'), "Path to directory with LyCORIS network(s)"),
- "styles_dir": OptionInfo(os.path.join(paths.data_path, 'styles.csv'), "Path to user-defined styles file"),
}))
options_templates.update(options_section(('saving-images', "Image Options"), {
@@ -489,16 +497,15 @@ options_templates.update(options_section(('upscaling', "Upscaling"), {
"realesrgan_enabled_models": OptionInfo(["R-ESRGAN 4x+", "R-ESRGAN 4x+ Anime6B"], "Real-ESRGAN available models", gr.CheckboxGroup, lambda: {"choices": shared_items.realesrgan_models_names()}),
"ESRGAN_tile": OptionInfo(192, "Tile size for ESRGAN upscalers (0 = no tiling)", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}),
"ESRGAN_tile_overlap": OptionInfo(8, "Tile overlap in pixels for ESRGAN upscalers", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}),
- "SCUNET_tile": OptionInfo(256, "Tile size for SCUNET upscalers. 0 = no tiling.", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}),
- "SCUNET_tile_overlap": OptionInfo(8, "Tile overlap, in pixels for SCUNET upscalers. Low values = visible seam.", gr.Slider, {"minimum": 0, "maximum": 64, "step": 1}),
+ "SCUNET_tile": OptionInfo(256, "Tile size for SCUNET upscalers (0 = no tiling)", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}),
+ "SCUNET_tile_overlap": OptionInfo(8, "Tile overlap, in pixels for SCUNET upscalers (low values = visible seam)", gr.Slider, {"minimum": 0, "maximum": 64, "step": 1}),
"use_old_hires_fix_width_height": OptionInfo(False, "Hires fix uses width & height to set final resolution rather than first pass"),
"dont_fix_second_order_samplers_schedule": OptionInfo(False, "Do not fix prompt schedule for second order samplers"),
- "lyco_patch_lora": OptionInfo(False, "Use LyCoris handler for all Lora types", gr.Checkbox, { "visible": False }), # TODO: lyco-patch-lora
- "lora_functional": OptionInfo(False, "Use Kohya method for handling multiple Loras", gr.Checkbox, { "visible": False }),
}))
options_templates.update(options_section(('lora', "Lora"), {
"lyco_patch_lora": OptionInfo(False, "Use LyCoris handler for all Lora types", gr.Checkbox, { "visible": True }), # TODO: lyco-patch-lora
+ "lora_disable": OptionInfo(False, "Disable built-in Lora handler", gr.Checkbox, { "visible": True }, onchange=lora_disable),
"lora_functional": OptionInfo(False, "Use Kohya method for handling multiple Loras", gr.Checkbox, { "visible": True }),
}))
@@ -519,10 +526,10 @@ options_templates.update(options_section(('extra_networks', "Extra Networks"), {
options_templates.update(options_section(('token_merging', 'Token Merging'), {
"token_merging": OptionInfo(False, "Enable redundant token merging via tomesd for speed and memory improvements", gr.Checkbox),
- "token_merging_ratio": OptionInfo(0.5, "Token merging Ratio. Higher merging ratio = faster generation, smaller VRAM usage, lower quality.", gr.Slider, {"minimum": 0, "maximum": 0.9, "step": 0.1}),
- "token_merging_hr_only": OptionInfo(True, "Apply only to high-res fix pass. Disabling can yield a ~20-35% speedup on contemporary resolutions.", gr.Checkbox),
- "token_merging_ratio_hr": OptionInfo(0.5, "Merging Ratio (high-res pass) - If 'Apply only to high-res' is enabled, this will always be the ratio used.", gr.Slider, {"minimum": 0, "maximum": 0.9, "step": 0.1}),
- "token_merging_random": OptionInfo(False, "Use random perturbations - Can improve outputs for certain samplers. For others, it may cause visual artifacting.", gr.Checkbox),
+ "token_merging_ratio": OptionInfo(0.5, "Token merging Ratio. Higher merging ratio = faster generation, smaller VRAM usage, lower quality", gr.Slider, {"minimum": 0, "maximum": 0.9, "step": 0.1}),
+ "token_merging_hr_only": OptionInfo(True, "Apply only to high-res fix pass. Disabling can yield a ~20-35% speedup on contemporary resolutions", gr.Checkbox),
+ "token_merging_ratio_hr": OptionInfo(0.5, "Merging Ratio for high-res pass", gr.Slider, {"minimum": 0, "maximum": 0.9, "step": 0.1}),
+ "token_merging_random": OptionInfo(False, "Use random perturbations - Can improve outputs for certain samplers. For others, it may cause visual artifacting", gr.Checkbox),
"token_merging_merge_attention": OptionInfo(True, "Merge attention (Recommend on)", gr.Checkbox),
"token_merging_merge_cross_attention": OptionInfo(False, "Merge cross attention (Recommend off)", gr.Checkbox),
"token_merging_merge_mlp": OptionInfo(False, "Merge mlp (Strongly recommend off)", gr.Checkbox),
diff --git a/scripts/postprocessing_codeformer.py b/scripts/postprocessing_codeformer.py
index 822d06cfa..6890642f6 100644
--- a/scripts/postprocessing_codeformer.py
+++ b/scripts/postprocessing_codeformer.py
@@ -12,7 +12,7 @@ class ScriptPostprocessingCodeFormer(scripts_postprocessing.ScriptPostprocessing
def ui(self):
with FormRow():
codeformer_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="CodeFormer visibility", value=0.0, elem_id="extras_codeformer_visibility")
- codeformer_weight = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="CodeFormer weight (0 = max), 1 = min)", value=0.2, elem_id="extras_codeformer_weight")
+ codeformer_weight = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="CodeFormer weight (0 = max, 1 = min)", value=0.2, elem_id="extras_codeformer_weight")
return {
"codeformer_visibility": codeformer_visibility,
From 3bef3e3eee9b380e223608a14de9103c62a09cea Mon Sep 17 00:00:00 2001
From: Disty0
Date: Wed, 7 Jun 2023 17:25:11 +0300
Subject: [PATCH 16/27] Train patches for IPEX
---
modules/devices.py | 3 +++
modules/hypernetworks/hypernetwork.py | 10 ++++------
modules/textual_inversion/textual_inversion.py | 9 ++++++++-
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/modules/devices.py b/modules/devices.py
index b8d363cc5..1b7cb428b 100644
--- a/modules/devices.py
+++ b/modules/devices.py
@@ -169,6 +169,9 @@ if args.use_ipex:
CondFunc('torch.nn.modules.GroupNorm.forward',
lambda orig_func, *args, **kwargs: orig_func(args[0], args[1].to(args[0].weight.data.dtype)),
lambda *args, **kwargs: args[2].dtype != args[1].weight.data.dtype)
+ CondFunc('torch.nn.modules.Linear.forward',
+ lambda orig_func, *args, **kwargs: orig_func(args[0], args[1].to(args[0].weight.data.dtype)),
+ lambda *args, **kwargs: args[2].dtype != args[1].weight.data.dtype)
#Use XPU instead of CPU. %20 Perf improvement on weak CPUs.
if args.device_id is not None:
diff --git a/modules/hypernetworks/hypernetwork.py b/modules/hypernetworks/hypernetwork.py
index 49253c2c3..75d4b07f6 100644
--- a/modules/hypernetworks/hypernetwork.py
+++ b/modules/hypernetworks/hypernetwork.py
@@ -594,12 +594,10 @@ def train_hypernetwork(id_task, hypernetwork_name, learn_rate, batch_size, gradi
print(e)
if shared.cmd_opts.use_ipex:
- scaler = ipex.cpu.autocast._grad_scaler.GradScaler()
- #Remove these after Intel adds support for float16 training:
- if shared.opts.cuda_dtype == 'BF16':
- shared.sd_model = shared.sd_model.bfloat16()
- elif shared.opts.cuda_dtype == 'FP32':
- shared.sd_model = shared.sd_model.float32()
+ scaler = ipex.cpu.autocast._grad_scaler.GradScaler() #scaler.step(optimizer): PI_ERROR_INVALID_ARG_VALUE
+ shared.sd_model = shared.sd_model.to(dtype=torch.float32)
+ shared.sd_model.train()
+ shared.sd_model, optimizer = ipex.optimize(shared.sd_model, optimizer=optimizer, dtype=devices.dtype)
else:
scaler = torch.cuda.amp.GradScaler()
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index 722593525..3025bd864 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -3,6 +3,10 @@ import html
import csv
from collections import namedtuple
import torch
+try:
+ import intel_extension_for_pytorch as ipex # pylint: disable=import-error, unused-import
+except:
+ pass
from tqdm import tqdm
import safetensors.torch
import numpy as np
@@ -433,7 +437,10 @@ def train_embedding(id_task, embedding_name, learn_rate, batch_size, gradient_st
shared.log.info("No saved optimizer exists in checkpoint")
if shared.cmd_opts.use_ipex:
- scaler = torch.xpu.amp.GradScaler()
+ scaler = ipex.cpu.autocast._grad_scaler.GradScaler() #scaler.step(optimizer): PI_ERROR_INVALID_ARG_VALUE
+ shared.sd_model = shared.sd_model.to(dtype=torch.float32)
+ shared.sd_model.train()
+ shared.sd_model, optimizer = ipex.optimize(shared.sd_model, optimizer=optimizer, dtype=devices.dtype)
else:
scaler = torch.cuda.amp.GradScaler()
From 8e3a8fb474da7f1060c4d93bc5098977710e1f69 Mon Sep 17 00:00:00 2001
From: Disty0
Date: Wed, 7 Jun 2023 19:17:55 +0300
Subject: [PATCH 17/27] Fix PI_ERROR_DEVICE_NOT_FOUND with UniPC and IPEX
---
modules/models/diffusion/uni_pc/uni_pc.py | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/modules/models/diffusion/uni_pc/uni_pc.py b/modules/models/diffusion/uni_pc/uni_pc.py
index 4df51e587..3e1fec68a 100644
--- a/modules/models/diffusion/uni_pc/uni_pc.py
+++ b/modules/models/diffusion/uni_pc/uni_pc.py
@@ -3,6 +3,7 @@ import torch.nn.functional as F
import math
import time
from rich.progress import Progress, TextColumn, BarColumn, TaskProgressColumn, TimeRemainingColumn, TimeElapsedColumn
+from modules import shared
class NoiseScheduleVP:
@@ -684,7 +685,12 @@ class UniPC:
if order == 2:
rhos_p = torch.tensor([0.5], device=b.device)
else:
- rhos_p = torch.linalg.solve(R[:-1, :-1], b[:-1])
+ if shared.cmd_opts.use_ipex:
+ #Running torch.linalg.solve on XPU crashes the GPU.
+ rhos_p = torch.linalg.solve(R[:-1, :-1].to("cpu"), b[:-1].to("cpu"))
+ rhos_p = rhos_p.to(b.device)
+ else:
+ rhos_p = torch.linalg.solve(R[:-1, :-1], b[:-1])
else:
D1s = None
@@ -694,7 +700,12 @@ class UniPC:
if order == 1:
rhos_c = torch.tensor([0.5], device=b.device)
else:
- rhos_c = torch.linalg.solve(R, b)
+ if shared.cmd_opts.use_ipex:
+ #Running torch.linalg.solve on XPU crashes the GPU.
+ rhos_c = torch.linalg.solve(R.to("cpu"), b.to("cpu"))
+ rhos_c = rhos_c.to(b.device)
+ else:
+ rhos_c = torch.linalg.solve(R, b)
model_t = None
if self.predict_x0:
From aaa0d462865a8bb7c9d1475f6257598ae1fe148f Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Wed, 7 Jun 2023 13:26:19 -0400
Subject: [PATCH 18/27] update installer and add sd_model_dict
---
extensions-builtin/sd-webui-agent-scheduler | 2 +-
extensions-builtin/sd-webui-controlnet | 2 +-
html/locale_en.json | 5 +-
installer.py | 77 +++++++------------
launch.py | 54 +++++++------
modules/extensions.py | 2 +-
modules/processing.py | 4 +-
modules/sd_models.py | 32 +++++---
modules/shared.py | 5 +-
.../textual_inversion/textual_inversion.py | 2 +-
modules/ui.py | 4 +-
modules/ui_extensions.py | 2 +-
scripts/xyz_grid.py | 11 ++-
webui.py | 9 ++-
wiki | 2 +-
15 files changed, 110 insertions(+), 103 deletions(-)
diff --git a/extensions-builtin/sd-webui-agent-scheduler b/extensions-builtin/sd-webui-agent-scheduler
index 340102006..5c6cbdc5a 160000
--- a/extensions-builtin/sd-webui-agent-scheduler
+++ b/extensions-builtin/sd-webui-agent-scheduler
@@ -1 +1 @@
-Subproject commit 3401020066a20444594ec2902d95217b0cd95e94
+Subproject commit 5c6cbdc5ae78d5162b6753c9f5aad4a850ac3f83
diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet
index 1b2aa4a96..99408b9f4 160000
--- a/extensions-builtin/sd-webui-controlnet
+++ b/extensions-builtin/sd-webui-controlnet
@@ -1 +1 @@
-Subproject commit 1b2aa4a96e9241b96abfbce249284ed17fc98b11
+Subproject commit 99408b9f4e514efdf33b19f3215ab661b989e209
diff --git a/html/locale_en.json b/html/locale_en.json
index ed034d9eb..97572b593 100755
--- a/html/locale_en.json
+++ b/html/locale_en.json
@@ -256,9 +256,11 @@
{"id":"","label":"random","localized":"","hint":""}
],
"settings": [
+ {"id":"","label":"Stable Diffusion checkpoint","localized":"","hint":"Select model checkpoint to use"},
+ {"id":"","label":"Stable Diffusion checkpoint dict","localized":"","hint":"Select model from which to extract dictionary only"},
{"id":"","label":"Number of cached model checkpoints","localized":"","hint":""},
{"id":"","label":"Number of cached VAE checkpoints","localized":"","hint":""},
- {"id":"","label":"Select VAE","localized":"","hint":""},
+ {"id":"","label":"Select VAE","localized":"","hint":"Select variable auto-encoder to work with model when rendering images"},
{"id":"","label":"Enable splitting of hires batch processing","localized":"","hint":""},
{"id":"","label":"When loading models attempt stream loading optimized for slow or network storage","localized":"","hint":""},
{"id":"","label":"When loading models attempt to reuse previous model dictionary","localized":"","hint":""},
@@ -513,7 +515,6 @@
{"id":"","label":"Resize to ","localized":"","hint":""},
{"id":"","label":"Resize by ","localized":"","hint":""},
{"id":"","label":"Use via API ","localized":"","hint":""},
- {"id":"","label":"Stable Diffusion checkpoint","localized":"","hint":""},
{"id":"","label":"Styles","localized":"","hint":""},
{"id":"","label":"Put variable parts at start of prompt","localized":"","hint":""},
{"id":"","label":"Use different seed for each picture","localized":"","hint":""},
diff --git a/installer.py b/installer.py
index f31c25106..2c2bb5da4 100644
--- a/installer.py
+++ b/installer.py
@@ -12,10 +12,6 @@ import cProfile
import argparse
import pkg_resources
-try:
- from modules.cmd_args import parser
-except:
- parser = argparse.ArgumentParser(description="SD.Next", conflict_handler='resolve', formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=55, indent_increment=2, width=200))
class Dot(dict): # dot notation access to dictionary attributes
__getattr__ = dict.get
@@ -69,8 +65,6 @@ def setup_logging(clean=False):
"traceback.border.syntax_error": "black",
"inspect.value.border": "black",
}))
- # logging.getLogger("urllib3").setLevel(logging.ERROR)
- # logging.getLogger("httpx").setLevel(logging.ERROR)
level = logging.DEBUG if args.debug else logging.INFO
logging.basicConfig(level=logging.ERROR, format='%(asctime)s | %(name)s | %(levelname)s | %(module)s | %(message)s', filename=log_file, filemode='a', encoding='utf-8', force=True)
log.setLevel(logging.DEBUG) # log to file is always at level debug for facility `sd`
@@ -81,6 +75,9 @@ def setup_logging(clean=False):
while log.hasHandlers() and len(log.handlers) > 0:
log.removeHandler(log.handlers[0])
log.addHandler(rh)
+ logging.getLogger("urllib3").setLevel(logging.ERROR)
+ logging.getLogger("httpx").setLevel(logging.ERROR)
+ logging.getLogger("ControlNet").handlers = log.handlers
def print_profile(profile: cProfile.Profile, msg: str):
@@ -351,7 +348,7 @@ def install_packages():
if args.profile:
pr = cProfile.Profile()
pr.enable()
- log.info('Installing packages')
+ log.info('Verifying packages')
# gfpgan_package = os.environ.get('GFPGAN_PACKAGE', "git+https://github.com/TencentARC/GFPGAN.git@8d2447a2d918f8eba5a4a01463fd48e45126a379")
# openclip_package = os.environ.get('OPENCLIP_PACKAGE', "git+https://github.com/mlfoundations/open_clip.git@bb6e834e9c70d9c27d0dc3ecedeebeaeb1ffad6b")
# install(gfpgan_package, 'gfpgan')
@@ -593,6 +590,8 @@ def check_version(offline=False, reset=True): # pylint: disable=unused-argument
log.info(f'Version: {ver}')
if args.version:
return
+ if args.skip_git:
+ return
commit = git('rev-parse HEAD')
global git_commit # pylint: disable=global-statement
git_commit = commit[:7]
@@ -673,7 +672,7 @@ def check_timestamp():
return ok
-def add_args():
+def add_args(parser):
group = parser.add_argument_group('Setup options')
group.add_argument('--debug', default = False, action='store_true', help = "Run installer with debug logging, default: %(default)s")
group.add_argument('--reset', default = False, action='store_true', help = "Reset main repository to latest version, default: %(default)s")
@@ -696,44 +695,36 @@ def add_args():
group.add_argument('--base', default = False, action='store_true', help = argparse.SUPPRESS)
-def parse_args():
+def parse_args(parser):
# command line args
global args # pylint: disable=global-statement
args = parser.parse_args()
+ return args
-def extensions_preload(force = False):
+def extensions_preload(parser):
if args.profile:
pr = cProfile.Profile()
pr.enable()
- setup_time = 0
- if not force:
- if os.path.isfile(log_file):
- with open(log_file, 'r', encoding='utf8') as f:
- lines = f.readlines()
- for line in lines:
- if 'Setup complete without errors' in line:
- setup_time = int(line.split(' ')[-1])
- if setup_time > 0 or force:
- # log.info('Running extension preloading')
- if args.safe:
- log.info('Running in safe mode without user extensions')
- try:
- from modules.script_loading import preload_extensions
- from modules.paths_internal import extensions_builtin_dir, extensions_dir
- extension_folders = [extensions_builtin_dir] if args.safe else [extensions_builtin_dir, extensions_dir]
- if args.base:
- extension_folders = []
- for ext_dir in extension_folders:
- t0 = time.time()
- preload_extensions(ext_dir, parser)
- t1 = time.time()
- log.info(f'Extension preload: {round(t1 - t0, 1)}s {ext_dir}')
- except:
- log.error('Error running extension preloading')
+ if args.safe:
+ log.info('Running in safe mode without user extensions')
+ try:
+ from modules.script_loading import preload_extensions
+ from modules.paths_internal import extensions_builtin_dir, extensions_dir
+ extension_folders = [extensions_builtin_dir] if args.safe else [extensions_builtin_dir, extensions_dir]
+ if args.base:
+ extension_folders = []
+ for ext_dir in extension_folders:
+ t0 = time.time()
+ preload_extensions(ext_dir, parser)
+ t1 = time.time()
+ log.info(f'Extension preload: {round(t1 - t0, 1)}s {ext_dir}')
+ except:
+ log.error('Error running extension preloading')
if args.profile:
print_profile(pr, 'Preload')
+
def git_reset():
log.warning('Running GIT reset')
global quick_allowed # pylint: disable=global-statement
@@ -752,22 +743,13 @@ def read_options():
opts = json.load(file)
-# entry method when used as module
def run_setup():
- # setup_logging(args.upgrade)
- log.info('Starting SD.Next')
- check_python()
if args.reset:
git_reset()
if args.skip_git:
log.info('Skipping GIT operations')
- check_version()
- set_environment()
if args.reinstall:
log.info('Forcing reinstall of all packages')
- check_torch()
- install_requirements()
- install_packages()
if check_timestamp():
log.info('No changes detected: Quick launch active')
return
@@ -782,10 +764,3 @@ def run_setup():
else:
log.warning(f'Setup complete with errors: {errors}')
log.warning(f'See log file for more details: {log_file}')
-
-
-if __name__ == "__main__":
- add_args()
- ensure_base_requirements()
- parse_args()
- run_setup()
diff --git a/launch.py b/launch.py
index bc00d111c..56ee77a0e 100644
--- a/launch.py
+++ b/launch.py
@@ -4,23 +4,15 @@ import time
import shlex
import logging
import subprocess
+import installer
+
commandline_args = os.environ.get('COMMANDLINE_ARGS', "")
sys.argv += shlex.split(commandline_args)
-
-import installer
-installer.ensure_base_requirements()
-installer.add_args()
-installer.parse_args()
-installer.setup_logging(False)
-installer.read_options()
-installer.extensions_preload(force=False)
-
-import modules.cmd_args
-args, _ = modules.cmd_args.parser.parse_known_args()
-import modules.paths_internal
-script_path = modules.paths_internal.script_path
-extensions_dir = modules.paths_internal.extensions_dir
+args = None
+parser = None
+script_path = None
+extensions_dir = None
git = os.environ.get('GIT', "git")
index_url = os.environ.get('INDEX_URL', "")
stored_commit_hash = None
@@ -29,6 +21,17 @@ python = sys.executable # used by some extensions to run python
skip_install = False # parsed by some extensions
+def init_modules():
+ global parser, args, script_path, extensions_dir # pylint: disable=global-statement
+ import modules.cmd_args
+ parser = modules.cmd_args.parser
+ installer.add_args(parser)
+ args, _ = parser.parse_known_args()
+ import modules.paths_internal
+ script_path = modules.paths_internal.script_path
+ extensions_dir = modules.paths_internal.extensions_dir
+
+
def commit_hash(): # compatbility function
global stored_commit_hash # pylint: disable=global-statement
if stored_commit_hash is not None:
@@ -134,17 +137,22 @@ def start_server(immediate=True, server=None):
if __name__ == "__main__":
- if args.version:
- installer.add_args()
- installer.log.info('SD.Next version information')
- installer.check_python()
- installer.check_version()
- installer.check_torch()
- exit(0)
+ installer.ensure_base_requirements()
+ init_modules() # setup argparser and default folders
+ installer.args = args
+ installer.setup_logging(False)
+ installer.log.info('Starting SD.Next')
+ installer.check_python()
+ installer.check_version()
+ installer.set_environment()
+ installer.check_torch()
+ installer.install_requirements()
+ installer.install_packages()
+ installer.extensions_preload(parser) # adds additional args from extensions
+ args = installer.parse_args(parser)
+ installer.read_options()
installer.run_setup()
- installer.extensions_preload(force=True)
installer.log.info(f"Server arguments: {sys.argv[1:]}")
- installer.log.debug('Starting WebUI')
logging.disable(logging.NOTSET if args.debug else logging.DEBUG)
instance = start_server(immediate=True, server=None)
diff --git a/modules/extensions.py b/modules/extensions.py
index f5a5f39bf..65474592b 100644
--- a/modules/extensions.py
+++ b/modules/extensions.py
@@ -139,7 +139,7 @@ def list_extensions():
shared.log.info(f'Skipping conflicting extension: {path}')
continue
extension_names.append(extension_dirname)
- extension_paths.append((extension_dirname, path, dirname == dirname))
+ extension_paths.append((extension_dirname, path, dirname == extensions_builtin_dir))
for dirname, path, is_builtin in extension_paths:
extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin)
extensions.append(extension)
diff --git a/modules/processing.py b/modules/processing.py
index 2fa263887..4edef3350 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -933,7 +933,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
image_conditioning = self.img2img_image_conditioning(decoded_samples, samples)
shared.state.nextjob()
img2img_sampler_name = self.sampler_name
- force_latent_upscaler = shared.opts.data.get('xyz_fallback_sampler')
+ force_latent_upscaler = shared.opts.data.get('force_latent_sampler')
if force_latent_upscaler != 'None' and force_latent_upscaler != 'PLMS':
img2img_sampler_name = force_latent_upscaler
if img2img_sampler_name == 'PLMS':
@@ -981,7 +981,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.image_conditioning = None
def init(self, all_prompts, all_seeds, all_subseeds):
- force_latent_upscaler = shared.opts.data.get('xyz_fallback_sampler')
+ force_latent_upscaler = shared.opts.data.get('force_latent_sampler')
if self.sampler_name in ['PLMS']:
self.sampler_name = force_latent_upscaler if force_latent_upscaler != 'None' else shared.opts.fallback_sampler # PLMS does not support img2img, use fallback instead
self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
diff --git a/modules/sd_models.py b/modules/sd_models.py
index feebec737..54359b76d 100644
--- a/modules/sd_models.py
+++ b/modules/sd_models.py
@@ -190,8 +190,8 @@ def model_hash(filename):
return 'NOHASH'
-def select_checkpoint():
- model_checkpoint = shared.opts.sd_model_checkpoint
+def select_checkpoint(model=True):
+ model_checkpoint = shared.opts.sd_model_checkpoint if model else shared.opts.sd_model_dict
checkpoint_info = checkpoint_aliases.get(model_checkpoint, None)
if checkpoint_info is not None:
shared.log.debug(f'Select checkpoint: {checkpoint_info.title if checkpoint_info is not None else None}')
@@ -300,7 +300,8 @@ def load_model_weights(model: torch.nn.Module, checkpoint_info: CheckpointInfo,
shared.log.debug(f'Model weights loading: {memory_stats()}')
sd_model_hash = checkpoint_info.calculate_shorthash()
timer.record("hash")
- shared.opts.data["sd_model_checkpoint"] = checkpoint_info.title
+ if model_data.sd_dict == 'None':
+ shared.opts.data["sd_model_checkpoint"] = checkpoint_info.title
if state_dict is None:
state_dict = get_checkpoint_state_dict(checkpoint_info, timer)
model.load_state_dict(state_dict, strict=False)
@@ -398,6 +399,7 @@ sd2_clip_weight = 'cond_stage_model.model.transformer.resblocks.0.attn.in_proj_w
class SdModelData:
def __init__(self):
self.sd_model = None
+ self.sd_dict = 'None'
self.initial = True
self.lock = threading.Lock()
@@ -406,7 +408,7 @@ class SdModelData:
with self.lock:
try:
if shared.backend == shared.Backend.ORIGINAL:
- load_model()
+ reload_model_weights()
elif shared.backend == shared.Backend.DIFFUSERS:
load_diffuser()
else:
@@ -552,15 +554,21 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None)
shared.log.info(f'Model load finished: {memory_stats()}')
-def reload_model_weights(sd_model=None, info=None):
+def reload_model_weights(sd_model=None, info=None, reuse_dict=False):
+ load_dict = shared.opts.sd_model_dict != model_data.sd_dict
global skip_next_load # pylint: disable=global-statement
if skip_next_load:
shared.log.debug('Reload model weights skip')
skip_next_load = False
return
- shared.log.debug(f'Reload model weights: {sd_model is not None} {info}')
from modules import lowvram, sd_hijack
- checkpoint_info = info or select_checkpoint()
+ checkpoint_info = info or select_checkpoint(model=not load_dict) # are we selecting model or dictionary
+ next_checkpoint_info = info or select_checkpoint(model=load_dict) if load_dict else None
+ if load_dict:
+ shared.log.debug(f'Model dict: existing={sd_model is not None} target={checkpoint_info.filename} info={info}')
+ else:
+ model_data.sd_dict = 'None'
+ shared.log.debug(f'Reload model weights: existing={sd_model is not None} target={checkpoint_info.filename} info={info}')
if not sd_model:
sd_model = model_data.sd_model
if sd_model is None: # previous model load failed
@@ -573,7 +581,7 @@ def reload_model_weights(sd_model=None, info=None):
lowvram.send_everything_to_cpu()
else:
sd_model.to(devices.cpu)
- if shared.opts.model_reuse_dict and sd_model is not None:
+ if reuse_dict or (shared.opts.model_reuse_dict and sd_model is not None):
shared.log.info('Reusing previous model dictionary')
sd_hijack.model_hijack.undo_hijack(sd_model)
else:
@@ -590,6 +598,10 @@ def reload_model_weights(sd_model=None, info=None):
load_model(checkpoint_info, already_loaded_state_dict=state_dict, timer=timer)
else:
load_diffuser(checkpoint_info, already_loaded_state_dict=state_dict, timer=timer)
+ if load_dict and next_checkpoint_info is not None:
+ model_data.sd_dict = shared.opts.sd_model_dict
+ shared.opts.data["sd_model_checkpoint"] = next_checkpoint_info.title
+ reload_model_weights(reuse_dict=True) # ok we loaded dict now lets redo and load model on top of it
return model_data.sd_model
try:
load_model_weights(sd_model, checkpoint_info, state_dict, timer)
@@ -615,8 +627,8 @@ def unload_model_weights(sd_model=None, _info=None):
sd_hijack.model_hijack.undo_hijack(model_data.sd_model)
model_data.sd_model = None
sd_model = None
- devices.torch_gc(force=True)
- shared.log.debug(f'Model weights unloaded: {memory_stats()}')
+ devices.torch_gc(force=True)
+ shared.log.debug(f'Model weights unloaded: {memory_stats()}')
return sd_model
diff --git a/modules/shared.py b/modules/shared.py
index ceab41342..58c7f6ab4 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -291,6 +291,7 @@ options_templates.update(options_section(('sd', "Stable Diffusion"), {
"sd_checkpoint_cache": OptionInfo(0, "Number of cached model checkpoints", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
"sd_vae_checkpoint_cache": OptionInfo(0, "Number of cached VAE checkpoints", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
"sd_vae": OptionInfo("Automatic", "Select VAE", gr.Dropdown, lambda: {"choices": shared_items.sd_vae_items()}, refresh=shared_items.refresh_vae_list),
+ "sd_model_dict": OptionInfo('None', "Stable Diffusion checkpoint dict", gr.Dropdown, lambda: {"choices": ['None'] + list_checkpoint_tiles()}, refresh=refresh_checkpoints),
"sd_vae_sliced_encode": OptionInfo(False, "Enable splitting of hires batch processing"),
"stream_load": OptionInfo(False, "When loading models attempt stream loading optimized for slow or network storage"),
"model_reuse_dict": OptionInfo(False, "When loading models attempt to reuse previous model dictionary"),
@@ -440,7 +441,7 @@ options_templates.update(options_section(('ui', "Live previews"), {
options_templates.update(options_section(('sampler-params', "Sampler Settings"), {
"show_samplers": OptionInfo(["Euler a", "UniPC", "DDIM", "DPM++ 2M SDE", "DPM++ 2M SDE Karras", "DPM2 Karras", "DPM++ 2M Karras"], "Show samplers in user interface", gr.CheckboxGroup, lambda: {"choices": [x.name for x in list_samplers() if x.name != "PLMS"]}),
"fallback_sampler": OptionInfo("Euler a", "Secondary sampler", gr.Dropdown, lambda: {"choices": ["None"] + [x.name for x in list_samplers()]}),
- "xyz_fallback_sampler": OptionInfo("None", "Force latent upscaler sampler", gr.Dropdown, lambda: {"choices": ["None"] + [x.name for x in list_samplers()]}),
+ "force_latent_sampler": OptionInfo("None", "Force latent upscaler sampler", gr.Dropdown, lambda: {"choices": ["None"] + [x.name for x in list_samplers()]}),
"eta_ancestral": OptionInfo(1.0, "Noise multiplier for ancestral samplers (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
"eta_ddim": OptionInfo(0.0, "Noise multiplier for DDIM (eta)", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}),
"ddim_discretize": OptionInfo('uniform', "DDIM discretize img2img", gr.Radio, {"choices": ['uniform', 'quad']}),
@@ -504,7 +505,7 @@ options_templates.update(options_section(('upscaling', "Upscaling"), {
}))
options_templates.update(options_section(('lora', "Lora"), {
- "lyco_patch_lora": OptionInfo(False, "Use LyCoris handler for all Lora types", gr.Checkbox, { "visible": True }), # TODO: lyco-patch-lora
+ "lyco_patch_lora": OptionInfo(False, "Use LyCoris handler for all Lora types", gr.Checkbox, { "visible": True }),
"lora_disable": OptionInfo(False, "Disable built-in Lora handler", gr.Checkbox, { "visible": True }, onchange=lora_disable),
"lora_functional": OptionInfo(False, "Use Kohya method for handling multiple Loras", gr.Checkbox, { "visible": True }),
}))
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index 3025bd864..e09adc184 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -243,7 +243,7 @@ class EmbeddingDatabase:
self.previously_displayed_embeddings = displayed_embeddings
shared.log.info(f"Embeddings loaded: {len(self.word_embeddings)} {[k for k in self.word_embeddings.keys()]}")
if len(self.skipped_embeddings) > 0:
- shared.log.info(f"Textual inversion embeddings skipped({len(self.skipped_embeddings)}): {', '.join(self.skipped_embeddings.keys())}")
+ shared.log.info(f"Embeddings skipped: {len(self.skipped_embeddings)} {[k for k in self.skipped_embeddings.keys()]}")
def find_embedding_at_position(self, tokens, offset):
token = tokens[offset]
diff --git a/modules/ui.py b/modules/ui.py
index 572f0aaad..03423064e 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1638,7 +1638,7 @@ def html_head():
head += f'\n'
added.append(script.path)
added = [a.replace(script_path, '').replace('\\', '/') for a in added]
- modules.shared.log.debug(f'Adding JS scripts: {added}')
+ # modules.shared.log.debug(f'Adding JS scripts: {added}')
return head
@@ -1671,7 +1671,7 @@ def html_css():
if os.path.exists(os.path.join(data_path, "user.css")):
head += stylesheet(os.path.join(data_path, "user.css"))
added = [a.replace(script_path, '').replace('\\', '/') for a in added]
- modules.shared.log.debug(f'Adding CSS stylesheets: {added}')
+ # modules.shared.log.debug(f'Adding CSS stylesheets: {added}')
return head
diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py
index 58342e410..6e6124119 100644
--- a/modules/ui_extensions.py
+++ b/modules/ui_extensions.py
@@ -261,7 +261,7 @@ def search_extensions(search_text, sort_column):
def refresh_extensions_list_from_data(search_text, sort_column):
- shared.log.debug(f'Extensions manager: refresh list search="{search_text}" sort="{sort_column}"')
+ # shared.log.debug(f'Extensions manager: refresh list search="{search_text}" sort="{sort_column}"')
code = """
diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py
index 0175d07a0..c3025d0d6 100644
--- a/scripts/xyz_grid.py
+++ b/scripts/xyz_grid.py
@@ -121,7 +121,7 @@ def apply_fallback(p, x, xs):
if sampler_name is None:
shared.log.warning(f"XYZ grid: unknown sampler: {x}")
else:
- shared.opts.data["xyz_fallback_sampler"] = sampler_name
+ shared.opts.data["force_latent_sampler"] = sampler_name
def apply_uni_pc_order(p, x, xs):
@@ -209,6 +209,7 @@ axis_options = [
AxisOption("Nothing", str, do_nothing, fmt=format_nothing),
AxisOption("Checkpoint name", str, apply_checkpoint, fmt=format_value, confirm=confirm_checkpoints, cost=1.0, choices=lambda: list(sd_models.checkpoints_list)),
AxisOption("VAE", str, apply_vae, cost=0.7, choices=lambda: ['None'] + list(sd_vae.vae_dict)),
+ AxisOption("Dict name", str, apply_checkpoint, fmt=format_value, confirm=confirm_checkpoints, cost=1.0, choices=lambda: ['None'] + list(sd_models.checkpoints_list)),
AxisOption("Prompt S/R", str, apply_prompt, fmt=format_value),
AxisOption("Styles", str, apply_styles, choices=lambda: list(shared.prompt_styles.styles)),
AxisOptionTxt2Img("Sampler", str, apply_sampler, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers]),
@@ -351,8 +352,9 @@ class SharedSettingsStackHelper(object):
self.token_merging_ratio = shared.opts.token_merging_ratio
self.token_merging_random = shared.opts.token_merging_random
self.sd_model_checkpoint = shared.opts.sd_model_checkpoint
+ self.sd_model_dict = shared.opts.sd_model_dict
self.sd_vae_checkpoint = shared.opts.sd_vae
- self.xyz_fallback_sampler = shared.opts.xyz_fallback_sampler
+ self.force_latent_sampler = shared.opts.force_latent_sampler
def __exit__(self, exc_type, exc_value, tb):
#Restore overriden settings after plot generation.
@@ -361,8 +363,9 @@ class SharedSettingsStackHelper(object):
shared.opts.data["token_merging_ratio_hr"] = self.token_merging_ratio_hr
shared.opts.data["token_merging_ratio"] = self.token_merging_ratio
shared.opts.data["token_merging_random"] = self.token_merging_random
- shared.opts.data["xyz_fallback_sampler"] = self.xyz_fallback_sampler
- if self.sd_model_checkpoint != shared.opts.sd_model_checkpoint:
+ shared.opts.data["force_latent_sampler"] = self.force_latent_sampler
+ if (self.sd_model_checkpoint != shared.opts.sd_model_checkpoint) or (self.sd_model_dict != shared.opts.sd_model_dict):
+ shared.opts.data["sd_model_dict"] = self.sd_model_dict
shared.opts.data["sd_model_checkpoint"] = self.sd_model_checkpoint
sd_models.reload_model_weights()
if self.sd_vae_checkpoint != shared.opts.sd_vae:
diff --git a/webui.py b/webui.py
index 6b2151a17..84f4aefc9 100644
--- a/webui.py
+++ b/webui.py
@@ -85,7 +85,7 @@ def check_rollback_vae():
def initialize():
- log.debug('Entering Initialize')
+ log.debug('Entering initialize')
check_rollback_vae()
modules.sd_vae.refresh_vae_list()
@@ -104,6 +104,7 @@ def initialize():
gfpgan.setup_model(opts.gfpgan_models_path)
startup_timer.record("gfpgan")
+ log.debug('Loading scripts')
modules.scripts.load_scripts()
startup_timer.record("scripts")
@@ -157,6 +158,7 @@ def load_model():
else:
shared.opts.data["sd_model_checkpoint"] = shared.sd_model.sd_checkpoint_info.title
shared.opts.onchange("sd_model_checkpoint", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()), call=False)
+ shared.opts.onchange("sd_model_dict", wrap_queued_call(lambda: modules.sd_models.reload_model_weights()), call=False)
shared.state.end()
startup_timer.record("checkpoint")
@@ -282,6 +284,11 @@ def webui():
start_ui()
load_model()
log.info(f"Startup time: {startup_timer.summary()}")
+
+ # override all loggers to use the same handlers as the main logger
+ for logger in [logging.getLogger(name) for name in logging.root.manager.loggerDict]: # pylint: disable=no-member
+ logger.handlers = log.handlers
+
if cmd_opts.autolaunch and local_url is not None:
cmd_opts.autolaunch = False
shared.log.info('Launching browser')
diff --git a/wiki b/wiki
index d420606fc..d54b7fd3b 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit d420606fc4f9735aa0a4d31f6e5ef18429508ab9
+Subproject commit d54b7fd3be2783cec8f17e73b453d1d59820a3a8
From eaeb5453b878cfaad9b46cfd73d9719ef45cfd0d Mon Sep 17 00:00:00 2001
From: Disty0
Date: Wed, 7 Jun 2023 21:16:11 +0300
Subject: [PATCH 19/27] Fix show_progress_type
---
modules/processing.py | 2 +-
modules/sd_samplers_common.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/processing.py b/modules/processing.py
index 4edef3350..386ec9985 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -609,7 +609,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
with torch.no_grad(), ema_scope_context():
with devices.autocast():
p.init(p.all_prompts, p.all_seeds, p.all_subseeds)
- if shared.opts.live_previews_enable and opts.show_progress_type == "Approx NN" and backend == Backend.ORIGINAL:
+ if shared.opts.live_previews_enable and opts.show_progress_type == "Approximate NN" and backend == Backend.ORIGINAL:
sd_vae_approx.model()
if state.job_count == -1:
state.job_count = p.n_iter
diff --git a/modules/sd_samplers_common.py b/modules/sd_samplers_common.py
index 1eacedca1..e76e7d4e8 100644
--- a/modules/sd_samplers_common.py
+++ b/modules/sd_samplers_common.py
@@ -22,7 +22,7 @@ def setup_img2img_steps(p, steps=None):
return steps, t_enc
-approximation_indexes = {"Full": 0, "Approx NN": 1, "Approx cheap": 2, "TAESD": 3}
+approximation_indexes = {"Full VAE": 0, "Approximate NN": 1, "Approximate simple": 2, "TAESD": 3}
def single_sample_to_image(sample, approximation=None):
From 98719c16725339ceb5ad93f895de622ab53d58ce Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Wed, 7 Jun 2023 14:49:44 -0400
Subject: [PATCH 20/27] bugfixes
---
CHANGELOG.md | 10 ++++++++++
cli/train.py | 9 ++++++---
launch.py | 2 +-
modules/cmd_args.py | 1 +
webui.py | 31 ++++++++++++++++++-------------
5 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b5eadde2..afc7a8fcf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
# Change Log for SD.Next
+## Update for 06/07/2023
+
+- reworked **installer** sequence
+ as some extensions are loading packages directly from their preload sequence
+ which was preventing some optimizations to take effect
+ i hope this does not cause regressions, but if it does, please report
+- experimental `sd_model_dict` setting which allows you to load model dictionary
+ from one model and apply weights from another model specified in `sd_model_checkpoint`
+ results? who am i to judge :)
+
## Update for 06/05/2023
Few new features and extra handling for broken extensions
diff --git a/cli/train.py b/cli/train.py
index 2f68bbb40..919295a77 100755
--- a/cli/train.py
+++ b/cli/train.py
@@ -95,7 +95,7 @@ def parse_args():
group_data = parser.add_argument_group('Dataset')
group_data.add_argument('--input', type=str, default=None, required=True, help='input folder with training images')
- group_data.add_argument('--output', type=str, default='', required=False, help='where to store processed images, default is system temp/train')
+ group_data.add_argument('--interim', type=str, default='', required=False, help='where to store processed images, default is system temp/train')
group_data.add_argument('--process', type=str, default='original,interrogate,resize,square', required=False, help=f'list of possible processing steps: {valid_steps}, default: %(default)s')
group_train = parser.add_argument_group('Train')
@@ -176,8 +176,8 @@ def verify_args():
if not os.path.exists(args.lyco_dir) or not os.path.isdir(args.lyco_dir):
log.error(f'cannot find lyco folder: {args.lyco_dir}')
exit(1)
- if args.output != '':
- args.process_dir = args.output
+ if args.interim != '':
+ args.process_dir = args.interim
else:
args.process_dir = os.path.join(tempfile.gettempdir(), 'train', args.name)
log.debug(f'args: {vars(args)}')
@@ -375,6 +375,9 @@ def process_inputs():
if __name__ == '__main__':
log.info('SD.Next train script')
+ server_options = util.Map(sdapi.options())
+ from rich import print
+ print(server_options)
parse_args()
setup_logging()
prepare_server()
diff --git a/launch.py b/launch.py
index 56ee77a0e..4b931e8e5 100644
--- a/launch.py
+++ b/launch.py
@@ -142,6 +142,7 @@ if __name__ == "__main__":
installer.args = args
installer.setup_logging(False)
installer.log.info('Starting SD.Next')
+ installer.read_options()
installer.check_python()
installer.check_version()
installer.set_environment()
@@ -150,7 +151,6 @@ if __name__ == "__main__":
installer.install_packages()
installer.extensions_preload(parser) # adds additional args from extensions
args = installer.parse_args(parser)
- installer.read_options()
installer.run_setup()
installer.log.info(f"Server arguments: {sys.argv[1:]}")
logging.disable(logging.NOTSET if args.debug else logging.DEBUG)
diff --git a/modules/cmd_args.py b/modules/cmd_args.py
index 7d854702c..b385961d7 100644
--- a/modules/cmd_args.py
+++ b/modules/cmd_args.py
@@ -25,6 +25,7 @@ group.add_argument("--freeze", action='store_true', help="Disable editing settin
group.add_argument("--auth", type=str, help='Set access authentication like "user:pwd,user:pwd""', default=None)
group.add_argument("--auth-file", type=str, help='Set access authentication using file, default: %(default)s', default=None)
group.add_argument("--autolaunch", action='store_true', help="Open the UI URL in the system's default browser upon launch", default=False)
+group.add_argument('--docs', default = False, action='store_true', help = "Mount Gradio docs at /docs, default: %(default)s")
group.add_argument('--api-only', default = False, action='store_true', help = "Run in API only mode without starting UI")
group.add_argument("--api-log", default=False, action='store_true', help="Enable logging of all API requests, default: %(default)s")
group.add_argument("--device-id", type=str, help="Select the default CUDA device to use, default: %(default)s", default=None)
diff --git a/webui.py b/webui.py
index 84f4aefc9..4f34b62af 100644
--- a/webui.py
+++ b/webui.py
@@ -225,6 +225,21 @@ def start_ui():
import installer
global local_url # pylint: disable=global-statement
+ gradio_kwargs = {
+ "version": f'0.0.{installer.git_commit}',
+ "title": "SD.Next",
+ "description": "SD.Next",
+ }
+ if cmd_opts.docs:
+ gradio_kwargs.update({
+ "docs_url": "/docs",
+ "redocs_url": "/redocs",
+ "swagger_ui_parameters": {
+ "displayOperationId": True,
+ "showCommonExtensions": True,
+ "deepLinking": False,
+ }
+ })
app, local_url, share_url = shared.demo.launch(
share=cmd_opts.share,
server_name=server_name,
@@ -239,21 +254,11 @@ def start_ui():
max_threads=64,
show_api=True,
favicon_path='html/logo.ico',
- app_kwargs={
- "version": f'0.0.{installer.git_commit}',
- "title": "SD.Next",
- "description": "SD.Next",
- # "docs_url": "/docs",
- # "redocs_url": "/redocs",
- "swagger_ui_parameters": {
- "displayOperationId": True,
- "showCommonExtensions": True,
- "deepLinking": False,
- },
- }
+ app_kwargs=gradio_kwargs,
)
shared.log.info(f'Local URL: {local_url}')
- shared.log.info(f'API Docs: {local_url[:-1]}/docs') # {local_url[:-1]}?view=api
+ if cmd_opts.docs:
+ shared.log.info(f'API Docs: {local_url[:-1]}/docs') # {local_url[:-1]}?view=api
if share_url is not None:
shared.log.info(f'Share URL: {share_url}')
shared.log.debug(f'Gradio registered functions: {len(shared.demo.fns)}')
From 0cca4d452a899068371d69c5fe71704a85ea382b Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Wed, 7 Jun 2023 17:35:27 -0400
Subject: [PATCH 21/27] add saving from process tab
---
.../stable-diffusion-webui-images-browser | 2 +-
modules/api/api.py | 1 -
modules/images.py | 4 ++--
modules/postprocessing.py | 5 +++--
modules/sd_hijack_optimizations.py | 2 +-
modules/ui_common.py | 13 +++++++++----
modules/ui_postprocessing.py | 5 +++--
7 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/extensions-builtin/stable-diffusion-webui-images-browser b/extensions-builtin/stable-diffusion-webui-images-browser
index 342efe98c..40ddbfbe0 160000
--- a/extensions-builtin/stable-diffusion-webui-images-browser
+++ b/extensions-builtin/stable-diffusion-webui-images-browser
@@ -1 +1 @@
-Subproject commit 342efe98c747aecbdde35144d017f9eaf2dd025a
+Subproject commit 40ddbfbe0aeea48896ffd2b1ec7987dab0030b5a
diff --git a/modules/api/api.py b/modules/api/api.py
index 81dfc5d6c..420e774f2 100644
--- a/modules/api/api.py
+++ b/modules/api/api.py
@@ -89,7 +89,6 @@ def save_image(image, fn, ext):
def encode_pil_to_base64(image):
- # TODO jpeg
with io.BytesIO() as output_bytes:
save_image(image, output_bytes, shared.opts.samples_format)
bytes_data = output_bytes.getvalue()
diff --git a/modules/images.py b/modules/images.py
index db812eb38..6e2b60acd 100644
--- a/modules/images.py
+++ b/modules/images.py
@@ -403,8 +403,8 @@ class FilenameGenerator:
elif replacement is not None:
res += text + str(replacement)
continue
- res += f'{text}[{pattern}]'
- res = res.split('?')[0]
+ res += f'{text}'
+ res = res.split('?')[0].strip()
return res
diff --git a/modules/postprocessing.py b/modules/postprocessing.py
index 63d0f359e..29c6bc204 100644
--- a/modules/postprocessing.py
+++ b/modules/postprocessing.py
@@ -62,7 +62,8 @@ def run_postprocessing(extras_mode, image, image_folder: List[tempfile.NamedTemp
basename = os.path.splitext(os.path.basename(name))[0]
else:
basename = ''
- _geninfo, items = images.read_info_from_image(image)
+ geninfo, items = images.read_info_from_image(image)
+ params = generation_parameters_copypaste.parse_generation_parameters(geninfo)
for k, v in items.items():
pp.image.info[k] = v
if 'parameters' in items:
@@ -75,7 +76,7 @@ def run_postprocessing(extras_mode, image, image_folder: List[tempfile.NamedTemp
outputs.append(pp.image)
devices.torch_gc()
- return outputs, ui_common.infotext_to_html(infotext), pp.image.info
+ return outputs, ui_common.infotext_to_html(infotext), params
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, upscale_first: bool, save_output: bool = True): #pylint: disable=unused-argument
diff --git a/modules/sd_hijack_optimizations.py b/modules/sd_hijack_optimizations.py
index cef0d8a6a..49519ea2a 100644
--- a/modules/sd_hijack_optimizations.py
+++ b/modules/sd_hijack_optimizations.py
@@ -511,7 +511,7 @@ def sdp_attnblock_forward(self, x):
q, k, v = map(lambda t: rearrange(t, 'b c h w -> b (h w) c'), (q, k, v))
dtype = q.dtype
if shared.opts.upcast_attn:
- q, k = q.float(), k.float()
+ q, k, v = q.float(), k.float(), v.float()
q = q.contiguous()
k = k.contiguous()
v = v.contiguous()
diff --git a/modules/ui_common.py b/modules/ui_common.py
index 8ce3c409d..f421d3dfc 100644
--- a/modules/ui_common.py
+++ b/modules/ui_common.py
@@ -68,17 +68,22 @@ def delete_files(js_data, images, _do_make_zip, index):
def save_files(js_data, images, do_make_zip, index):
os.makedirs(shared.opts.outdir_save, exist_ok=True)
- class MyObject: #quick dictionary to class object conversion. Its necessary due apply_filename_pattern requiring it
+ class PObject: #quick dictionary to class object conversion. Its necessary due apply_filename_pattern requiring it
def __init__(self, d=None):
if d is not None:
for key, value in d.items():
setattr(self, key, value)
-
+ self.seed = getattr(self, 'seed', None) or getattr(self, 'Seed', None)
+ self.prompt = getattr(self, 'prompt', None) or getattr(self, 'Prompt', None)
+ self.all_seeds = getattr(self, 'all_seeds', [self.seed])
+ self.all_prompts = getattr(self, 'all_prompts', [self.prompt])
+ self.infotexts = getattr(self, 'infotext', [json.dumps(d)])
+ self.index_of_first_image = getattr(self, 'index_of_first_image', 0)
try:
data = json.loads(js_data)
except Exception:
- data = { 'index_of_first_image': 0 }
- p = MyObject(data)
+ data = {}
+ p = PObject(data)
start_index = 0
if index > -1 and shared.opts.save_selected_only and (index >= data['index_of_first_image']): # ensures we are looking at a specific non-grid picture, and we have save_selected_only # pylint: disable=no-member
images = [images[index]]
diff --git a/modules/ui_postprocessing.py b/modules/ui_postprocessing.py
index 990b05e23..208cffe43 100644
--- a/modules/ui_postprocessing.py
+++ b/modules/ui_postprocessing.py
@@ -1,3 +1,4 @@
+import json
import gradio as gr
from modules import scripts_postprocessing, scripts, shared, gfpgan_model, codeformer_model, ui_common, postprocessing, call_queue # pylint: disable=unused-import
import modules.generation_parameters_copypaste as parameters_copypaste
@@ -13,8 +14,8 @@ def wrap_pnginfo(image):
def submit_click(tab_index, extras_image, image_batch, extras_batch_input_dir, extras_batch_output_dir, show_extras_results, *script_inputs):
- result_images, geninfo, _js_info = postprocessing.run_postprocessing(tab_index, extras_image, image_batch, extras_batch_input_dir, extras_batch_output_dir, show_extras_results, *script_inputs)
- return result_images, geninfo, '{}', ''
+ result_images, geninfo, js_info = postprocessing.run_postprocessing(tab_index, extras_image, image_batch, extras_batch_input_dir, extras_batch_output_dir, show_extras_results, *script_inputs)
+ return result_images, geninfo, json.dumps(js_info), ''
def create_ui():
From 276fb6a08aaf869388eda33762dea9e44dbd0b2b Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Wed, 7 Jun 2023 17:45:39 -0400
Subject: [PATCH 22/27] add train server endpoint
---
cli/train.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/cli/train.py b/cli/train.py
index 919295a77..8b2d1287d 100755
--- a/cli/train.py
+++ b/cli/train.py
@@ -87,6 +87,10 @@ def parse_args():
global args # pylint: disable=global-statement
parser = argparse.ArgumentParser(description = 'SD.Next Train')
+
+ group_server = parser.add_argument_group('Server')
+ group_server.add_argument('--server', type=str, default='http://127.0.0.1:7860', required=False, help='server url, default: %(default)s')
+
group_main = parser.add_argument_group('Main')
group_main.add_argument('--type', type=str, choices=['embedding', 'ti', 'lora', 'lyco', 'dreambooth', 'hypernetwork'], default=None, required=True, help='training type')
group_main.add_argument('--model', type=str, default='', required=False, help='base model to use for training, default: current loaded model')
@@ -375,10 +379,8 @@ def process_inputs():
if __name__ == '__main__':
log.info('SD.Next train script')
- server_options = util.Map(sdapi.options())
- from rich import print
- print(server_options)
parse_args()
+ sdapi.sd_url = args.server
setup_logging()
prepare_server()
verify_args()
From 6ef3e964a39501e63b7b89a92b993e0355f52ac7 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Thu, 8 Jun 2023 06:45:28 -0400
Subject: [PATCH 23/27] update images index
---
TODO.md | 1 +
extensions-builtin/a1111-sd-webui-lycoris | 2 +-
extensions-builtin/sd-webui-controlnet | 2 +-
.../stable-diffusion-webui-images-browser | 2 +-
modules/ui_common.py | 10 ++++++----
wiki | 2 +-
6 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/TODO.md b/TODO.md
index b27447c36..10f7d05a3 100644
--- a/TODO.md
+++ b/TODO.md
@@ -42,6 +42,7 @@ Tech that can be integrated as part of the core workflow...
- [Custom diffusion](https://github.com/guaneec/custom-diffusion-webui), [Custom diffusion](https://www.cs.cmu.edu/~custom-diffusion/)
- [Dream artist](https://github.com/7eu7d7/DreamArtist-sd-webui-extension)
- [QuickEmbedding](https://github.com/ethansmith2000/QuickEmbedding)
+- [DataComp CLiP](https://github.com/mlfoundations/open_clip/blob/main/docs/datacomp_models.md)
- `TensorRT`
## Random
diff --git a/extensions-builtin/a1111-sd-webui-lycoris b/extensions-builtin/a1111-sd-webui-lycoris
index e47548884..123d1da15 160000
--- a/extensions-builtin/a1111-sd-webui-lycoris
+++ b/extensions-builtin/a1111-sd-webui-lycoris
@@ -1 +1 @@
-Subproject commit e47548884864da9cfe30f6f33fbaa8e731d3dd85
+Subproject commit 123d1da15d802823480f8020312ce449523f10e2
diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet
index 99408b9f4..2598ca9e7 160000
--- a/extensions-builtin/sd-webui-controlnet
+++ b/extensions-builtin/sd-webui-controlnet
@@ -1 +1 @@
-Subproject commit 99408b9f4e514efdf33b19f3215ab661b989e209
+Subproject commit 2598ca9e78f167014c6556cb89dab792a745749f
diff --git a/extensions-builtin/stable-diffusion-webui-images-browser b/extensions-builtin/stable-diffusion-webui-images-browser
index 40ddbfbe0..b2f6e4cbe 160000
--- a/extensions-builtin/stable-diffusion-webui-images-browser
+++ b/extensions-builtin/stable-diffusion-webui-images-browser
@@ -1 +1 @@
-Subproject commit 40ddbfbe0aeea48896ffd2b1ec7987dab0030b5a
+Subproject commit b2f6e4cbe507078e3bf2b9d5fce6f83e2e233aa8
diff --git a/modules/ui_common.py b/modules/ui_common.py
index f421d3dfc..7d0efe812 100644
--- a/modules/ui_common.py
+++ b/modules/ui_common.py
@@ -93,10 +93,12 @@ def save_files(js_data, images, do_make_zip, index):
for image_index, filedata in enumerate(images, start_index):
is_grid = image_index < p.index_of_first_image # pylint: disable=no-member
i = 0 if is_grid else (image_index - p.index_of_first_image) # pylint: disable=no-member
- if len(p.all_seeds) <= i: # pylint: disable=no-member
- p.all_seeds.append(p.seed) # pylint: disable=no-member
- if len(p.all_prompts) <= i: # pylint: disable=no-member
- p.all_prompts.append(p.prompt) # pylint: disable=no-member
+ while len(p.all_seeds) <= i:
+ p.all_seeds.append(p.seed)
+ while len(p.all_prompts) <= i:
+ p.all_prompts.append(p.prompt)
+ while len(p.infotexts) <= i:
+ p.infotexts.append(p.prompt)
if 'name' in filedata and ('tmp' not in filedata['name']) and os.path.isfile(filedata['name']):
fullfn = filedata['name']
filenames.append(os.path.basename(fullfn))
diff --git a/wiki b/wiki
index d54b7fd3b..e9a86af55 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit d54b7fd3be2783cec8f17e73b453d1d59820a3a8
+Subproject commit e9a86af55bc5b03a5f396527a66a518b1147913a
From 727b41a4bda8005aa481ea9a1ec750ace05c9b4e Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Thu, 8 Jun 2023 08:16:43 -0400
Subject: [PATCH 24/27] update swinir
---
.../SwinIR/scripts/swinir_model.py | 55 ++++++++++---------
1 file changed, 29 insertions(+), 26 deletions(-)
diff --git a/extensions-builtin/SwinIR/scripts/swinir_model.py b/extensions-builtin/SwinIR/scripts/swinir_model.py
index d07c9acb5..085c2ecc3 100644
--- a/extensions-builtin/SwinIR/scripts/swinir_model.py
+++ b/extensions-builtin/SwinIR/scripts/swinir_model.py
@@ -3,7 +3,7 @@ import numpy as np
import torch
from PIL import Image
from basicsr.utils.download_util import load_file_from_url
-from tqdm import tqdm
+from tqdm.rich import tqdm
from swinir_model_arch import SwinIR as net
from swinir_model_arch_v2 import Swin2SR as net2
from modules import modelloader, devices, script_callbacks, shared
@@ -54,8 +54,7 @@ class UpscalerSwinIR(Upscaler):
filename = path
if filename is None or not os.path.exists(filename):
return None
- if filename.endswith(".v2.pth"):
- model = net2(
+ model_v2 = net2(
upscale=scale,
in_chans=3,
img_size=64,
@@ -67,29 +66,33 @@ class UpscalerSwinIR(Upscaler):
mlp_ratio=2,
upsampler="nearest+conv",
resi_connection="1conv",
- )
- params = None
- else:
- model = net(
- upscale=scale,
- in_chans=3,
- img_size=64,
- window_size=8,
- img_range=1.0,
- depths=[6, 6, 6, 6, 6, 6, 6, 6, 6],
- embed_dim=240,
- num_heads=[8, 8, 8, 8, 8, 8, 8, 8, 8],
- mlp_ratio=2,
- upsampler="nearest+conv",
- resi_connection="3conv",
- )
- params = "params_ema"
-
+ )
+ model_v1 = net(
+ upscale=scale,
+ in_chans=3,
+ img_size=64,
+ window_size=8,
+ img_range=1.0,
+ depths=[6, 6, 6, 6, 6, 6, 6, 6, 6],
+ embed_dim=240,
+ num_heads=[8, 8, 8, 8, 8, 8, 8, 8, 8],
+ mlp_ratio=2,
+ upsampler="nearest+conv",
+ resi_connection="3conv",
+ )
pretrained_model = torch.load(filename)
- if params is not None:
- model.load_state_dict(pretrained_model[params], strict=True)
- else:
- model.load_state_dict(pretrained_model, strict=True)
+ for model in [model_v1, model_v2]:
+ for param in ["params_ema", "params", None]:
+ try:
+ if param is not None:
+ model.load_state_dict(pretrained_model[param], strict=True)
+ else:
+ model.load_state_dict(pretrained_model, strict=True)
+ shared.log.info(f'Loaded SwinIR model: {filename} param={param}')
+ return model
+ except Exception:
+ pass
+ shared.log.error(f'Could not determine SwinIR model parameters: {filename}')
return model
@@ -140,7 +143,7 @@ def inference(img, model, tile, tile_overlap, window_size, scale):
E = torch.zeros(b, c, h * sf, w * sf, dtype=devices.dtype, device=device_swinir).type_as(img)
W = torch.zeros_like(E, dtype=devices.dtype, device=device_swinir)
- with tqdm(total=len(h_idx_list) * len(w_idx_list), desc="SwinIR tiles") as pbar:
+ with tqdm(total=len(h_idx_list) * len(w_idx_list), desc="Upscaling SwinIR") as pbar:
for h_idx in h_idx_list:
if state.interrupted or state.skipped:
break
From 0d629f3c2b6a808052890137c23140e2393a0240 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Thu, 8 Jun 2023 09:01:43 -0400
Subject: [PATCH 25/27] fix installer and add image-exif
---
cli/image-exif.py | 106 +++++++++++++++++++++++++++++++++++++++++++
installer.py | 23 ----------
launch.py | 27 +++++++++--
modules/ui_common.py | 2 +-
4 files changed, 131 insertions(+), 27 deletions(-)
create mode 100755 cli/image-exif.py
diff --git a/cli/image-exif.py b/cli/image-exif.py
new file mode 100755
index 000000000..8531ef687
--- /dev/null
+++ b/cli/image-exif.py
@@ -0,0 +1,106 @@
+#!/bin/env python
+
+import os
+import io
+import re
+import sys
+import json
+from PIL import Image, ExifTags, TiffImagePlugin, PngImagePlugin
+from rich import print # pylint: disable=redefined-builtin
+
+# warnings.filterwarnings("ignore", category=UserWarning)
+
+
+class Exif: # pylint: disable=single-string-used-for-slots
+ __slots__ = ('__dict__') # pylint: disable=superfluous-parens
+ def __init__(self, image = None):
+ super(Exif, self).__setattr__('exif', Image.Exif())
+ self.pnginfo = PngImagePlugin.PngInfo()
+ self.tags = {**dict(((k, v) for k, v in ExifTags.TAGS.items())), **dict(((k, v) for k, v in ExifTags.GPSTAGS.items()))}
+ self.ids = {**dict(((v, k) for k, v in ExifTags.TAGS.items())), **dict(((v, k) for k, v in ExifTags.GPSTAGS.items()))}
+ if image is not None:
+ self.load(image)
+
+ def __getattr__(self, attr):
+ if attr in self.__dict__:
+ return self.__dict__[attr]
+ return self.exif.get(attr, None)
+
+ def load(self, img: Image):
+ img.load() # exif may not be ready
+ exif_dict = {}
+ try:
+ exif_dict = dict(img._getexif().items()) # pylint: disable=protected-access
+ except:
+ exif_dict = dict(img.info.items())
+ for key, val in exif_dict.items():
+ if isinstance(val, bytes): # decode bytestring
+ val = self.decode(val)
+ if val is not None:
+ if isinstance(key, str):
+ self.exif[key] = val
+ self.pnginfo.add_text(key, str(val), zip=False)
+ elif isinstance(key, int) and key in ExifTags.TAGS: # add known tags
+ if self.tags[key] in ['ExifOffset']:
+ continue
+ self.exif[self.tags[key]] = val
+ self.pnginfo.add_text(self.tags[key], str(val), zip=False)
+ # if self.tags[key] == 'UserComment': # add geninfo from UserComment
+ # self.geninfo = val
+ else:
+ print('metadata unknown tag:', key, val)
+ for key, val in self.exif.items():
+ if isinstance(val, bytes): # decode bytestring
+ self.exif[key] = self.decode(val)
+
+ def decode(self, s: bytes):
+ remove_prefix = lambda text, prefix: text[len(prefix):] if text.startswith(prefix) else text # pylint: disable=unnecessary-lambda-assignment
+ for encoding in ['utf-8', 'utf-16', 'ascii', 'latin_1', 'cp1252', 'cp437']: # try different encodings
+ try:
+ s = remove_prefix(s, b'UNICODE')
+ s = remove_prefix(s, b'ASCII')
+ s = remove_prefix(s, b'\x00')
+ val = s.decode(encoding, errors="strict")
+ val = re.sub(r'[\x00-\x09]', '', val).strip() # remove remaining special characters
+ if len(val) == 0: # remove empty strings
+ val = None
+ return val
+ except:
+ pass
+ return None
+
+ def get_bytes(self):
+ ifd = TiffImagePlugin.ImageFileDirectory_v2()
+ exif_stream = io.BytesIO()
+ for key, val in self.exif.items():
+ if key in self.ids:
+ ifd[self.ids[key]] = val
+ else:
+ print('metadata unknown exif tag:', key, val)
+ ifd.save(exif_stream)
+ raw = b'Exif\x00\x00' + exif_stream.getvalue()
+ return raw
+
+
+def read_exif(filename: str):
+ try:
+ img = Image.open(filename)
+ exif = Exif(img)
+ print('image:', filename, 'format:', img.format, 'metadata:', json.dumps(vars(exif.exif)['_data'], indent=2))
+ except Exception as e:
+ print('metadata error reading:', filename, e)
+ # exif.exif['Software'] = 'This is a Test'
+ # img.save('input-scored.jpg', exif=exif.bytes())
+
+
+if __name__ == '__main__':
+ sys.argv.pop(0)
+ if len(sys.argv) == 0:
+ print('metadata:', 'no files specified')
+ for fn in sys.argv:
+ if os.path.isfile(fn):
+ read_exif(fn)
+ elif os.path.isdir(fn):
+ for root, dirs, files in os.walk(fn):
+ for file in files:
+ read_exif(os.path.join(root, file))
diff --git a/installer.py b/installer.py
index 2c2bb5da4..0488b3a59 100644
--- a/installer.py
+++ b/installer.py
@@ -741,26 +741,3 @@ def read_options():
if os.path.isfile(args.config):
with open(args.config, "r", encoding="utf8") as file:
opts = json.load(file)
-
-
-def run_setup():
- if args.reset:
- git_reset()
- if args.skip_git:
- log.info('Skipping GIT operations')
- if args.reinstall:
- log.info('Forcing reinstall of all packages')
- if check_timestamp():
- log.info('No changes detected: Quick launch active')
- return
- log.info("Running setup")
- log.debug(f"Args: {vars(args)}")
- install_repositories()
- install_submodules()
- install_extensions()
- update_wiki()
- if errors == 0:
- log.debug(f'Setup complete without errors: {round(time.time())}')
- else:
- log.warning(f'Setup complete with errors: {errors}')
- log.warning(f'See log file for more details: {log_file}')
diff --git a/launch.py b/launch.py
index 4b931e8e5..7fb712fa0 100644
--- a/launch.py
+++ b/launch.py
@@ -144,17 +144,38 @@ if __name__ == "__main__":
installer.log.info('Starting SD.Next')
installer.read_options()
installer.check_python()
+ if args.reset:
+ installer.git_reset()
+ if args.skip_git:
+ installer.log.info('Skipping GIT operations')
installer.check_version()
installer.set_environment()
installer.check_torch()
- installer.install_requirements()
- installer.install_packages()
+ if args.reinstall:
+ installer.log.info('Forcing reinstall of all packages')
+ installer.quick_allowed = False
+ if installer.check_timestamp():
+ installer.log.info('No changes detected: Quick launch active')
+ else:
+ installer.install_requirements()
+ installer.install_packages()
+ installer.install_repositories()
+ installer.install_submodules()
+ installer.install_extensions()
+ installer.update_wiki()
+ if installer.errors == 0:
+ installer.log.debug(f'Setup complete without errors: {round(time.time())}')
+ else:
+ installer.log.warning(f'Setup complete with errors: {installer.errors}')
+ installer.log.warning(f'See log file for more details: {installer.log_file}')
installer.extensions_preload(parser) # adds additional args from extensions
args = installer.parse_args(parser)
- installer.run_setup()
+ # installer.run_setup()
+ installer.log.debug(f"Args: {vars(args)}")
installer.log.info(f"Server arguments: {sys.argv[1:]}")
logging.disable(logging.NOTSET if args.debug else logging.DEBUG)
+
instance = start_server(immediate=True, server=None)
while True:
try:
diff --git a/modules/ui_common.py b/modules/ui_common.py
index 7d0efe812..bba2505ce 100644
--- a/modules/ui_common.py
+++ b/modules/ui_common.py
@@ -85,7 +85,7 @@ def save_files(js_data, images, do_make_zip, index):
data = {}
p = PObject(data)
start_index = 0
- if index > -1 and shared.opts.save_selected_only and (index >= data['index_of_first_image']): # ensures we are looking at a specific non-grid picture, and we have save_selected_only # pylint: disable=no-member
+ if index > -1 and shared.opts.save_selected_only and (index >= p.index_of_first_image): # ensures we are looking at a specific non-grid picture, and we have save_selected_only # pylint: disable=no-member
images = [images[index]]
start_index = index
filenames = []
From c82eaef261b6717599e27068d19a4b5425c66aec Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Thu, 8 Jun 2023 11:17:09 -0400
Subject: [PATCH 26/27] update save function
---
extensions-builtin/sd-webui-agent-scheduler | 2 +-
modules/lora | 2 +-
modules/ui_common.py | 35 +++++++++++----------
wiki | 2 +-
4 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/extensions-builtin/sd-webui-agent-scheduler b/extensions-builtin/sd-webui-agent-scheduler
index 5c6cbdc5a..45dfe5977 160000
--- a/extensions-builtin/sd-webui-agent-scheduler
+++ b/extensions-builtin/sd-webui-agent-scheduler
@@ -1 +1 @@
-Subproject commit 5c6cbdc5ae78d5162b6753c9f5aad4a850ac3f83
+Subproject commit 45dfe5977ea43a14f61f46d572615efe169ca2be
diff --git a/modules/lora b/modules/lora
index 363f1dfab..6417f5d7c 160000
--- a/modules/lora
+++ b/modules/lora
@@ -1 +1 @@
-Subproject commit 363f1dfab94a422765e72165f2648812dda92169
+Subproject commit 6417f5d7c183eccd79422f28804f7d7c507e05b9
diff --git a/modules/ui_common.py b/modules/ui_common.py
index bba2505ce..7b8e38bab 100644
--- a/modules/ui_common.py
+++ b/modules/ui_common.py
@@ -17,12 +17,13 @@ def update_generation_info(generation_info, html_info, img_index):
try:
generation_info = json.loads(generation_info)
if img_index < 0 or img_index >= len(generation_info["infotexts"]):
- return html_info, gr.update()
- html_text = infotext_to_html(generation_info["infotexts"][img_index])
- return html_text, gr.update()
+ return html_info, generation_info
+ infotext = generation_info["infotexts"][img_index]
+ html_text = infotext_to_html(infotext)
+ return html_text, infotext
except Exception:
pass
- return html_info, gr.update()
+ return html_info, generation_info
def plaintext_to_html(text):
@@ -39,7 +40,7 @@ def infotext_to_html(text):
return res
-def delete_files(js_data, images, _do_make_zip, index):
+def delete_files(js_data, images, _html_info, _do_make_zip, index):
try:
data = json.loads(js_data)
except Exception:
@@ -65,7 +66,7 @@ def delete_files(js_data, images, _do_make_zip, index):
return images, plaintext_to_html(f"Deleted: {filenames[0] if len(filenames) > 0 else 'none'}")
-def save_files(js_data, images, do_make_zip, index):
+def save_files(js_data, images, html_info, do_make_zip, index):
os.makedirs(shared.opts.outdir_save, exist_ok=True)
class PObject: #quick dictionary to class object conversion. Its necessary due apply_filename_pattern requiring it
@@ -77,7 +78,8 @@ def save_files(js_data, images, do_make_zip, index):
self.prompt = getattr(self, 'prompt', None) or getattr(self, 'Prompt', None)
self.all_seeds = getattr(self, 'all_seeds', [self.seed])
self.all_prompts = getattr(self, 'all_prompts', [self.prompt])
- self.infotexts = getattr(self, 'infotext', [json.dumps(d)])
+ self.infotext = html_info
+ self.infotexts = getattr(self, 'infotexts', [html_info])
self.index_of_first_image = getattr(self, 'index_of_first_image', 0)
try:
data = json.loads(js_data)
@@ -98,7 +100,7 @@ def save_files(js_data, images, do_make_zip, index):
while len(p.all_prompts) <= i:
p.all_prompts.append(p.prompt)
while len(p.infotexts) <= i:
- p.infotexts.append(p.prompt)
+ p.infotexts.append(p.infotext)
if 'name' in filedata and ('tmp' not in filedata['name']) and os.path.isfile(filedata['name']):
fullfn = filedata['name']
filenames.append(os.path.basename(fullfn))
@@ -113,7 +115,7 @@ def save_files(js_data, images, do_make_zip, index):
shared.log.info(f"Copying image: {fullfn} -> {destination}")
else:
image = image_from_url_text(filedata)
- fullfn, txt_fullfn = modules.images.save_image(image, shared.opts.outdir_save, "", seed=p.all_seeds[i], prompt=p.all_prompts[i], extension=shared.opts.samples_format, info=p.infotexts[image_index], grid=is_grid, p=p, save_to_dirs=shared.opts.use_save_to_dirs_for_ui) # pylint: disable=no-member
+ fullfn, txt_fullfn = modules.images.save_image(image, shared.opts.outdir_save, "", seed=p.all_seeds[i], prompt=p.all_prompts[i], info=p.infotexts[i], extension=shared.opts.samples_format, grid=is_grid, p=p, save_to_dirs=shared.opts.use_save_to_dirs_for_ui)
if fullfn is None:
continue
filename = os.path.relpath(fullfn, shared.opts.outdir_save)
@@ -171,23 +173,24 @@ def create_output_panel(tabname, outdir):
download_files = gr.File(None, file_count="multiple", interactive=False, show_label=False, visible=False, elem_id=f'download_files_{tabname}')
with gr.Group():
html_info = gr.HTML(elem_id=f'html_info_{tabname}', elem_classes="infotext")
+ html_info_raw = gr.Text(elem_id=f'html_info_raw_{tabname}', visible=False)
html_log = gr.HTML(elem_id=f'html_log_{tabname}')
generation_info = gr.Textbox(visible=False, elem_id=f'generation_info_{tabname}')
generation_info_button = gr.Button(visible=False, elem_id=f"{tabname}_generation_info_button")
generation_info_button.click(fn=update_generation_info, _js="(x, y, z) => [x, y, selected_gallery_index()]", show_progress=False,
inputs=[generation_info, html_info, html_info],
- outputs=[html_info, html_info],
+ outputs=[html_info, html_info_raw],
)
- save.click(fn=call_queue.wrap_gradio_call(save_files), _js="(x, y, z, w) => [x, y, false, selected_gallery_index()]", show_progress=False,
- inputs=[generation_info, result_gallery, html_info, html_info],
+ save.click(fn=call_queue.wrap_gradio_call(save_files), _js="(x, y, z, q1, q2) => [x, y, z, false, selected_gallery_index()]", show_progress=False,
+ inputs=[generation_info, result_gallery, html_info, html_info, html_info],
outputs=[download_files, html_log],
)
- save_zip.click(fn=call_queue.wrap_gradio_call(save_files), _js="(x, y, z, w) => [x, y, true, selected_gallery_index()]",
- inputs=[generation_info, result_gallery, html_info, html_info],
+ save_zip.click(fn=call_queue.wrap_gradio_call(save_files), _js="(x, y, z, q1, q2) => [x, y, z, true, selected_gallery_index()]",
+ inputs=[generation_info, result_gallery, html_info, html_info, html_info],
outputs=[download_files, html_log],
)
- delete.click(fn=call_queue.wrap_gradio_call(delete_files), _js="(x, y, z, w) => [x, y, true, selected_gallery_index()]",
- inputs=[generation_info, result_gallery, html_info, html_info],
+ delete.click(fn=call_queue.wrap_gradio_call(delete_files), _js="(x, y, z, q1, q2) => [x, y, z, true, selected_gallery_index()]",
+ inputs=[generation_info, result_gallery, html_info, html_info, html_info],
outputs=[result_gallery, html_log],
)
diff --git a/wiki b/wiki
index e9a86af55..801130e4c 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit e9a86af55bc5b03a5f396527a66a518b1147913a
+Subproject commit 801130e4c45c815c4b2718a70ae88a2653fd780e
From b5f745b4cd6a7b23986e0e182b66bd34f1304704 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Thu, 8 Jun 2023 11:56:29 -0400
Subject: [PATCH 27/27] warn of modified files
---
.github/ISSUE_TEMPLATE/bug_report.yml | 2 +-
.github/ISSUE_TEMPLATE/extension_report.yml | 8 +++++-
README.md | 4 +--
TODO.md | 1 +
installer.py | 31 ++++++++++++++-------
launch.py | 2 ++
6 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index add464bca..9347c4bf6 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -28,7 +28,7 @@ body:
- type: markdown
attributes:
value: |
- If issue is setup, installation or startup related, please check `webui.log` before reporting
+ If issue is setup, installation or startup related, please check `sdnext.log` before reporting
And when posting console logs, please use code blocks ( \`\`\` ) to format them insead of uploading screenshots
- type: markdown
attributes:
diff --git a/.github/ISSUE_TEMPLATE/extension_report.yml b/.github/ISSUE_TEMPLATE/extension_report.yml
index 21e95688a..88c590307 100644
--- a/.github/ISSUE_TEMPLATE/extension_report.yml
+++ b/.github/ISSUE_TEMPLATE/extension_report.yml
@@ -22,6 +22,12 @@ body:
label: URL link of the extension
description: URL link of the extension
value:
+ - type: textarea
+ id: url
+ attributes:
+ label: URL link of the issue reported in the extension repository
+ description: Any extension related issue must also be reported to extension repository as well
+ value:
- type: markdown
attributes:
value: |
@@ -29,5 +35,5 @@ body:
- type: markdown
attributes:
value: |
- If issue is extension installation or startup related, please check `webui.log` before reporting
+ If issue is extension installation or startup related, please check `sdnext.log` before reporting
And when posting console logs, please use code blocks ( \`\`\` ) to format them insead of uploading screenshots
diff --git a/README.md b/README.md
index 6b06f20df..c400a63f3 100644
--- a/README.md
+++ b/README.md
@@ -31,13 +31,13 @@ Individual features are not listed here, instead check [Changelog](CHANGELOG.md)
3. Run launcher
`webui.bat` or `webui.sh`:
- Platform specific wrapper scripts For Windows, Linux and OSX
- - Starts `launch.py` in a Python virtual environment (`venv`)
+ - Starts `sdnext.py` in a Python virtual environment (`venv`)
- Uses `install.py` to handle all actual requirements and dependencies
- *Note*: Server can run without virtual environment, but it is recommended to use it to avoid library version conflicts with other applications
*Note*: **nVidia/CUDA** and **AMD/ROCm** are auto-detected is present and available, but for any other use case specify required parameter explicitly or wrong packages may be installed as installer will assume CPU-only environment
-Full startup sequence is logged in `webui.log`, so if you encounter any issues, please check it first
+Full startup sequence is logged in `sdnext.log`, so if you encounter any issues, please check it first
Below is partial list of all available parameters, run `webui --help` for the full list:
diff --git a/TODO.md b/TODO.md
index 10f7d05a3..8c450f503 100644
--- a/TODO.md
+++ b/TODO.md
@@ -58,3 +58,4 @@ Tech that can be integrated as part of the core workflow...
- port `p.all_hr_prompts`
- test `lyco_patch_lora`
- fix `lyco` logging
+- git diff index
diff --git a/installer.py b/installer.py
index 0488b3a59..dce439f18 100644
--- a/installer.py
+++ b/installer.py
@@ -20,7 +20,7 @@ class Dot(dict): # dot notation access to dictionary attributes
log = logging.getLogger("sd")
-log_file = os.path.join(os.path.dirname(__file__), 'webui.log')
+log_file = os.path.join(os.path.dirname(__file__), 'sdnext.log')
quick_allowed = True
errors = 0
opts = {}
@@ -343,6 +343,18 @@ def check_torch():
print_profile(pr, 'Torch')
+# check modified files
+def check_modified_files():
+ if args.skip_git:
+ return
+ try:
+ res = git('status --porcelain')
+ files = [x[2:].strip() for x in res.split('\n')]
+ log.warning(f'Modified files: {files}')
+ except:
+ pass
+
+
# install required packages
def install_packages():
if args.profile:
@@ -415,17 +427,20 @@ def run_extension_installer(folder):
log.error(f'Exception running extension installer: {e}')
# get list of all enabled extensions
-def list_extensions(folder):
+def list_extensions(folder, quiet=False):
name = os.path.basename(folder)
disabled_extensions_all = opts.get('disable_all_extensions', 'none')
if disabled_extensions_all != 'none':
- log.info(f'Disabled {name}: {disabled_extensions_all}')
+ if not quiet:
+ log.info(f'Disabled {name}: {disabled_extensions_all}')
return []
disabled_extensions = opts.get('disabled_extensions', [])
if len(disabled_extensions) > 0:
- log.info(f'Disabled {name}: {disabled_extensions}')
+ if not quiet:
+ log.info(f'Disabled {name}: {disabled_extensions}')
enabled_extensions = [x for x in os.listdir(folder) if x not in disabled_extensions and not x.startswith('.')]
- log.info(f'Enabled {name}: {enabled_extensions}')
+ if not quiet:
+ log.info(f'Enabled {name}: {enabled_extensions}')
return enabled_extensions
@@ -446,7 +461,7 @@ def install_extensions():
for folder in extension_folders:
if not os.path.isdir(folder):
continue
- extensions = list_extensions(folder)
+ extensions = list_extensions(folder, quiet=True)
log.debug(f'Extensions all: {extensions}')
for ext in extensions:
if ext in extensions_enabled:
@@ -582,10 +597,6 @@ def check_version(offline=False, reset=True): # pylint: disable=unused-argument
log.error('Not a git repository')
if not args.ignore:
sys.exit(1)
- # status = git('status')
- # if 'branch' not in status:
- # log.error('Cannot get git repository status')
- # sys.exit(1)
ver = git('log -1 --pretty=format:"%h %ad"')
log.info(f'Version: {ver}')
if args.version:
diff --git a/launch.py b/launch.py
index 7fb712fa0..76e6e9144 100644
--- a/launch.py
+++ b/launch.py
@@ -151,11 +151,13 @@ if __name__ == "__main__":
installer.check_version()
installer.set_environment()
installer.check_torch()
+ installer.check_modified_files()
if args.reinstall:
installer.log.info('Forcing reinstall of all packages')
installer.quick_allowed = False
if installer.check_timestamp():
installer.log.info('No changes detected: Quick launch active')
+ installer.check_extensions()
else:
installer.install_requirements()
installer.install_packages()