mirror of
https://github.com/vladmandic/automatic
synced 2026-08-26 15:16:01 +02:00
Merge branch 'master' of https://github.com/vladmandic/automatic into settings-improvements
This commit is contained in:
+3
-2
@@ -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",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
+28
-5
@@ -1,11 +1,34 @@
|
||||
# Change Log for SD.Next
|
||||
|
||||
## Update for 06/03/2023
|
||||
## 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
|
||||
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 :)
|
||||
- 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
|
||||
- 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 🙂
|
||||
|
||||
- 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
|
||||
|
||||
## Update for 06/02/2023
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -56,3 +57,5 @@ Tech that can be integrated as part of the core workflow...
|
||||
- docker
|
||||
- port `p.all_hr_prompts`
|
||||
- test `lyco_patch_lora`
|
||||
- fix `lyco` logging
|
||||
- git diff index
|
||||
|
||||
Regular → Executable
+2
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import huggingface_hub as hf
|
||||
from rich import print # pylint: disable=redefined-builtin
|
||||
Executable
+106
@@ -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))
|
||||
+11
-6
@@ -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')
|
||||
@@ -95,7 +99,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')
|
||||
@@ -164,9 +168,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)
|
||||
@@ -176,8 +180,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)}')
|
||||
@@ -376,6 +380,7 @@ def process_inputs():
|
||||
if __name__ == '__main__':
|
||||
log.info('SD.Next train script')
|
||||
parse_args()
|
||||
sdapi.sd_url = args.server
|
||||
setup_logging()
|
||||
prepare_server()
|
||||
verify_args()
|
||||
|
||||
Executable
+31
@@ -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}')
|
||||
@@ -14,21 +14,22 @@ 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"<lora:{alias}:") + " + opts.extra_networks_default_multiplier + " + json.dumps(">"),
|
||||
"prompt": (
|
||||
json.dumps(f"<lora:{alias}")
|
||||
+ " + " + json.dumps(f':{shared.opts.extra_networks_default_multiplier}')
|
||||
+ " + " + 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,
|
||||
}
|
||||
|
||||
def allowed_directories_for_previews(self):
|
||||
return [shared.cmd_opts.lora_dir]
|
||||
|
||||
|
||||
@@ -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 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
|
||||
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)
|
||||
@@ -56,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,
|
||||
@@ -69,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
|
||||
|
||||
|
||||
@@ -142,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
|
||||
|
||||
Submodule extensions-builtin/a1111-sd-webui-lycoris updated: 21e9ea0f58...123d1da15d
Submodule extensions-builtin/sd-webui-agent-scheduler updated: b070319583...45dfe5977e
Submodule extensions-builtin/sd-webui-controlnet updated: d8551e447d...2598ca9e78
Submodule extensions-builtin/stable-diffusion-webui-images-browser updated: 5795886bee...b2f6e4cbe5
Executable
+565
@@ -0,0 +1,565 @@
|
||||
{ "icons": [
|
||||
{"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":"","label":"Prompt","localized":"","hint":"Prompt"},
|
||||
{"id":"","label":"Negative prompt","localized":"","hint":"Negative Prompt"}
|
||||
],
|
||||
"tabs": [
|
||||
{"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":"","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":"","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":"","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":"","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":"","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":"","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","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":"","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":"","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":"","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":"","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":"","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":"","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":"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":""},
|
||||
{"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<Format>], [datetime<Format><Time Zone>], [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<Format>], [datetime<Format><Time Zone>], [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 <extra networks:0.9>","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":"","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":"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":""}
|
||||
]
|
||||
}
|
||||
+61
-89
@@ -9,13 +9,9 @@ import subprocess
|
||||
import io
|
||||
import pstats
|
||||
import cProfile
|
||||
import argparse
|
||||
import pkg_resources
|
||||
|
||||
try:
|
||||
from modules.cmd_args import parser
|
||||
except:
|
||||
import argparse
|
||||
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
|
||||
@@ -24,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 = {}
|
||||
@@ -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):
|
||||
@@ -120,7 +117,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:
|
||||
@@ -346,12 +343,24 @@ 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:
|
||||
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')
|
||||
@@ -418,15 +427,21 @@ def run_extension_installer(folder):
|
||||
log.error(f'Exception running extension installer: {e}')
|
||||
|
||||
# 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}')
|
||||
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':
|
||||
if not quiet:
|
||||
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('.')]
|
||||
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('.')]
|
||||
if not quiet:
|
||||
log.info(f'Enabled {name}: {enabled_extensions}')
|
||||
return enabled_extensions
|
||||
|
||||
|
||||
# run installer for each installed and enabled extension and optionally update them
|
||||
@@ -441,10 +456,12 @@ def install_extensions():
|
||||
extensions_duplicates = []
|
||||
extensions_enabled = []
|
||||
extension_folders = [extensions_builtin_dir] if args.safe else [extensions_builtin_dir, extensions_dir]
|
||||
if args.base:
|
||||
extension_folders = []
|
||||
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:
|
||||
@@ -552,6 +569,8 @@ def check_extensions():
|
||||
newest_all = os.path.getmtime('requirements.txt')
|
||||
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 folder in extension_folders:
|
||||
if not os.path.isdir(folder):
|
||||
continue
|
||||
@@ -568,7 +587,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)
|
||||
|
||||
|
||||
@@ -578,14 +597,12 @@ 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:
|
||||
return
|
||||
if args.skip_git:
|
||||
return
|
||||
commit = git('rev-parse HEAD')
|
||||
global git_commit # pylint: disable=global-statement
|
||||
git_commit = commit[:7]
|
||||
@@ -666,7 +683,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")
|
||||
@@ -686,44 +703,39 @@ def add_args():
|
||||
group.add_argument('--version', default = False, action='store_true', help = "Print version information")
|
||||
group.add_argument('--ignore', default = False, action='store_true', help = "Ignore any errors and attempt to continue")
|
||||
group.add_argument('--safe', default = False, action='store_true', help = "Run in safe mode with no user extensions")
|
||||
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]
|
||||
for ext_dir in extension_folders:
|
||||
t0 = time.time()
|
||||
preload_extensions(ext_dir, parser)
|
||||
t1 = time.time()
|
||||
log.debug(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
|
||||
@@ -740,43 +752,3 @@ def read_options():
|
||||
if os.path.isfile(args.config):
|
||||
with open(args.config, "r", encoding="utf8") as file:
|
||||
opts = json.load(file)
|
||||
|
||||
|
||||
# entry method when used as module
|
||||
def run_setup():
|
||||
# setup_logging(args.upgrade)
|
||||
log.info('Starting SD.Next')
|
||||
read_options()
|
||||
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
|
||||
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}')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
add_args()
|
||||
ensure_base_requirements()
|
||||
parse_args()
|
||||
run_setup()
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* global gradioApp, onUiUpdate, get_tab_index */
|
||||
|
||||
let currentWidth = null;
|
||||
let currentHeight = null;
|
||||
let arFrameTimeout = setTimeout(() => {}, 0);
|
||||
@@ -52,7 +50,7 @@ function dimensionChange(e, is_width, is_height) {
|
||||
}
|
||||
}
|
||||
|
||||
onUiUpdate(() => {
|
||||
onAfterUiUpdate(() => {
|
||||
const arPreviewRect = gradioApp().querySelector('#imageARPreview');
|
||||
if (arPreviewRect) arPreviewRect.style.display = 'none';
|
||||
const tabImg2img = gradioApp().querySelector('#tab_img2img');
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* global gradioApp, uiCurrentTab, onUiUpdate, get_uiCurrentTabContent */
|
||||
|
||||
const contextMenuInit = () => {
|
||||
let eventListenerApplied = false;
|
||||
const menuSpecs = new Map();
|
||||
@@ -137,4 +135,4 @@ const addContextMenuEventListener = initResponse[2];
|
||||
}());
|
||||
// End example Context Menu Items
|
||||
|
||||
onUiUpdate(() => addContextMenuEventListener());
|
||||
onAfterUiUpdate(() => addContextMenuEventListener());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global gradioApp, onUiUpdate */
|
||||
// attaches listeners to the txt2img and img2img galleries to update displayed generation param text when the image changes
|
||||
|
||||
function attachGalleryListeners(tab_name) {
|
||||
@@ -22,7 +21,7 @@ let txt2img_gallery;
|
||||
let img2img_gallery;
|
||||
let modal;
|
||||
|
||||
onUiUpdate(() => {
|
||||
onAfterUiUpdate(() => {
|
||||
if (!txt2img_gallery) txt2img_gallery = attachGalleryListeners('txt2img');
|
||||
if (!img2img_gallery) img2img_gallery = attachGalleryListeners('img2img');
|
||||
if (!modal) {
|
||||
|
||||
@@ -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<Format>], [datetime<Format><Time Zone>], [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<Format>], [datetime<Format><Time Zone>], [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.',
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global gradioApp, opts */
|
||||
function onCalcResolutionHires(enable_hr, width, height, hr_scale, hr_resize_x, hr_resize_y) {
|
||||
function setInactive(elem, inactive) {
|
||||
elem.classList.toggle('inactive', !!inactive);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global gradioApp, onUiUpdate */
|
||||
/**
|
||||
* temporary fix for https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/668
|
||||
* @see https://github.com/gradio-app/gradio/issues/1721
|
||||
@@ -41,5 +40,5 @@ function imageMaskResize() {
|
||||
});
|
||||
}
|
||||
|
||||
onUiUpdate(imageMaskResize);
|
||||
onAfterUiUpdate(imageMaskResize);
|
||||
window.addEventListener('resize', imageMaskResize);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global gradioApp, get_tab_index */
|
||||
window.onload = (function () {
|
||||
window.addEventListener('drop', (e) => {
|
||||
const target = e.composedPath()[0];
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global gradioApp, onUiUpdate */
|
||||
// A full size 'lightbox' preview modal shown when left clicking on gallery previews
|
||||
function closeModal() {
|
||||
gradioApp().getElementById('lightboxModal').style.display = 'none';
|
||||
@@ -143,7 +142,7 @@ function galleryImageHandler(e) {
|
||||
e.onclick = showGalleryImage;
|
||||
}
|
||||
|
||||
onUiUpdate(() => {
|
||||
onAfterUiUpdate(() => {
|
||||
fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img');
|
||||
if (fullImg_preview != null) fullImg_preview.forEach(setupImageForLightbox);
|
||||
updateOnBackgroundChange();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
let lastHeadImg = null;
|
||||
let notificationButton = null;
|
||||
|
||||
onUiUpdate(function () {
|
||||
onAfterUiUpdate(function () {
|
||||
if (!notificationButton) {
|
||||
notificationButton = gradioApp().getElementById('request_notifications');
|
||||
if (notificationButton) notificationButton.addEventListener('click', (evt) => Notification.requestPermission(), true);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* global opts */
|
||||
let lastState = {};
|
||||
|
||||
function rememberGallerySelection(id_gallery) {}
|
||||
|
||||
@@ -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');
|
||||
|
||||
+26
-10
@@ -13,33 +13,48 @@ function get_uiCurrentTabContent() {
|
||||
return gradioApp().querySelector('.tabitem[id^=tab_]:not([style*="display: none"])');
|
||||
}
|
||||
|
||||
uiUpdateCallbacks = [];
|
||||
uiLoadedCallbacks = [];
|
||||
uiTabChangeCallbacks = [];
|
||||
optionsChangedCallbacks = [];
|
||||
const uiAfterUpdateCallbacks = [];
|
||||
const uiUpdateCallbacks = [];
|
||||
const uiLoadedCallbacks = [];
|
||||
const uiTabChangeCallbacks = [];
|
||||
const optionsChangedCallbacks = [];
|
||||
let uiCurrentTab = null;
|
||||
let uiAfterUpdateTimeout = null;
|
||||
|
||||
function onAfterUiUpdate(callback) {
|
||||
uiAfterUpdateCallbacks.push(callback);
|
||||
}
|
||||
|
||||
function onUiUpdate(callback) {
|
||||
uiUpdateCallbacks.push(callback);
|
||||
}
|
||||
|
||||
function onUiLoaded(callback) {
|
||||
uiLoadedCallbacks.push(callback);
|
||||
}
|
||||
|
||||
function onUiTabChange(callback) {
|
||||
uiTabChangeCallbacks.push(callback);
|
||||
}
|
||||
|
||||
function onOptionsChanged(callback) {
|
||||
optionsChangedCallbacks.push(callback);
|
||||
}
|
||||
|
||||
function runCallback(x, m) {
|
||||
try {
|
||||
x(m);
|
||||
} catch (e) { (console.error || console.log).call(console, e.message, e); }
|
||||
function executeCallbacks(queue, arg) {
|
||||
// if (!uiLoaded) return
|
||||
for (const callback of queue) {
|
||||
try {
|
||||
callback(arg);
|
||||
} catch (e) {
|
||||
console.error("error running callback", callback, ":", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function executeCallbacks(queue, m) {
|
||||
queue.forEach((x) => { runCallback(x, m); });
|
||||
function scheduleAfterUiUpdateCallbacks() {
|
||||
clearTimeout(uiAfterUpdateTimeout);
|
||||
uiAfterUpdateTimeout = setTimeout(() => executeCallbacks(uiAfterUpdateCallbacks, 500));
|
||||
}
|
||||
|
||||
let executedOnLoaded = false;
|
||||
@@ -51,6 +66,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
executeCallbacks(uiLoadedCallbacks);
|
||||
}
|
||||
executeCallbacks(uiUpdateCallbacks, m);
|
||||
scheduleAfterUiUpdateCallbacks();
|
||||
const newTab = get_uiCurrentTab();
|
||||
if (newTab && (newTab !== uiCurrentTab)) {
|
||||
uiCurrentTab = newTab;
|
||||
|
||||
+28
-18
@@ -1,20 +1,30 @@
|
||||
onUiUpdate(() => {
|
||||
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)
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
@@ -639,3 +639,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; }
|
||||
|
||||
+4
-3
@@ -1,5 +1,3 @@
|
||||
/* global gradioApp, onUiUpdate, opts */
|
||||
|
||||
window.opts = {};
|
||||
window.localization = {};
|
||||
let tabSelected = '';
|
||||
@@ -227,7 +225,7 @@ function showAllSettings() {
|
||||
});
|
||||
}
|
||||
|
||||
onUiUpdate(() => {
|
||||
onAfterUiUpdate(() => {
|
||||
sort_ui_elements();
|
||||
if (Object.keys(opts).length !== 0) return;
|
||||
const json_elem = gradioApp().getElementById('settings_json');
|
||||
@@ -512,6 +510,8 @@ function preview_theme() {
|
||||
}
|
||||
}
|
||||
|
||||
let uiLoaded = false;
|
||||
|
||||
function reconnect_ui() {
|
||||
const api_logo = Array.from(gradioApp().querySelectorAll('img')).filter((el) => el?.src?.endsWith('api-logo.svg'));
|
||||
if (api_logo.length > 0) api_logo[0].remove();
|
||||
@@ -525,6 +525,7 @@ function reconnect_ui() {
|
||||
rememberGallerySelection('txt2img_gallery');
|
||||
requestProgress(task_id, null, gallery, null, null, true);
|
||||
}
|
||||
uiLoaded = true;
|
||||
|
||||
const sd_model = gradioApp().getElementById('setting_sd_model_checkpoint');
|
||||
let loadingStarted = 0;
|
||||
|
||||
@@ -4,22 +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.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
|
||||
@@ -28,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:
|
||||
@@ -133,19 +137,47 @@ 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.run_setup()
|
||||
installer.extensions_preload(force=True)
|
||||
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.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.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()
|
||||
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.log.debug(f"Args: {vars(args)}")
|
||||
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)
|
||||
while True:
|
||||
try:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -91,6 +92,7 @@ def compatibility_args(opts, args):
|
||||
group.add_argument("--lora-dir", help=argparse.SUPPRESS, default=opts.lora_dir)
|
||||
group.add_argument("--lyco-dir", help=argparse.SUPPRESS, default=opts.lyco_dir)
|
||||
group.add_argument("--lyco-patch-lora", help=argparse.SUPPRESS, default=opts.lyco_patch_lora)
|
||||
group.add_argument("--lyco-debug", help=argparse.SUPPRESS, action='store_true', default=False)
|
||||
group.add_argument("--enable-console-prompts", help=argparse.SUPPRESS, action='store_true', default=False)
|
||||
group.add_argument("--safe", help=argparse.SUPPRESS, action='store_true', default=False)
|
||||
|
||||
|
||||
+35
-13
@@ -98,6 +98,18 @@ 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=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
|
||||
|
||||
|
||||
def set_cuda_params():
|
||||
shared.log.debug('Verifying Torch settings')
|
||||
@@ -117,25 +129,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.float16:
|
||||
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 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 +169,10 @@ 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:
|
||||
cpu = torch.device(f"xpu:{args.device_id}")
|
||||
|
||||
@@ -126,6 +126,8 @@ def list_extensions():
|
||||
extension_paths = []
|
||||
extension_names = []
|
||||
extension_folders = [extensions_builtin_dir] if shared.cmd_opts.safe else [extensions_builtin_dir, extensions_dir]
|
||||
if shared.cmd_opts.base:
|
||||
extension_folders = []
|
||||
for dirname in extension_folders:
|
||||
if not os.path.isdir(dirname):
|
||||
return
|
||||
|
||||
@@ -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 = []
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
|
||||
|
||||
+1
-1
Submodule modules/lora updated: 7c38c33ed6...6417f5d7c1
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
import sys
|
||||
import modules.paths_internal
|
||||
|
||||
|
||||
data_path = modules.paths_internal.data_path
|
||||
script_path = modules.paths_internal.script_path
|
||||
models_path = modules.paths_internal.models_path
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+15
-12
@@ -282,18 +282,21 @@ class ScriptRunner:
|
||||
auto_processing_scripts = scripts_auto_postprocessing.create_auto_preprocessing_script_data()
|
||||
|
||||
for script_class, path, _basedir, _script_module in auto_processing_scripts + scripts_data:
|
||||
script = script_class()
|
||||
script.filename = path
|
||||
script.is_txt2img = not is_img2img
|
||||
script.is_img2img = is_img2img
|
||||
visibility = script.show(script.is_img2img)
|
||||
if visibility == AlwaysVisible:
|
||||
self.scripts.append(script)
|
||||
self.alwayson_scripts.append(script)
|
||||
script.alwayson = True
|
||||
elif visibility:
|
||||
self.scripts.append(script)
|
||||
self.selectable_scripts.append(script)
|
||||
try:
|
||||
script = script_class()
|
||||
script.filename = path
|
||||
script.is_txt2img = not is_img2img
|
||||
script.is_img2img = is_img2img
|
||||
visibility = script.show(script.is_img2img)
|
||||
if visibility == AlwaysVisible:
|
||||
self.scripts.append(script)
|
||||
self.alwayson_scripts.append(script)
|
||||
script.alwayson = True
|
||||
elif visibility:
|
||||
self.scripts.append(script)
|
||||
self.selectable_scripts.append(script)
|
||||
except Exception as e:
|
||||
log.error(f'Script initialize: {path} {e}')
|
||||
|
||||
def setup_ui(self):
|
||||
self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts]
|
||||
|
||||
@@ -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()
|
||||
|
||||
+36
-15
@@ -108,7 +108,9 @@ 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)
|
||||
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):
|
||||
checkpoint_info = CheckpointInfo(filename)
|
||||
if checkpoint_info.name is not None:
|
||||
@@ -125,16 +127,23 @@ 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"])
|
||||
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"])
|
||||
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)
|
||||
checkpoint_info.register()
|
||||
if checkpoint_info.name is not None:
|
||||
checkpoint_info.register()
|
||||
|
||||
|
||||
def update_model_hashes():
|
||||
@@ -181,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}')
|
||||
@@ -291,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)
|
||||
@@ -389,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()
|
||||
|
||||
@@ -397,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:
|
||||
@@ -543,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
|
||||
@@ -564,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:
|
||||
@@ -581,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)
|
||||
@@ -606,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
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
+26
-15
@@ -102,6 +102,7 @@ class State:
|
||||
time_start = None
|
||||
need_restart = False
|
||||
server_start = None
|
||||
oom = False
|
||||
|
||||
def skip(self):
|
||||
log.debug('Requested skip')
|
||||
@@ -250,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)
|
||||
@@ -282,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"),
|
||||
@@ -325,6 +335,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)"),
|
||||
@@ -336,9 +349,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"), {
|
||||
@@ -423,7 +433,7 @@ options_templates.update(options_section(('live-preview', "Live previews"), {
|
||||
"notification_audio_enable": OptionInfo(False, "Play a sound when images are finished generating"),
|
||||
"notification_audio_path": OptionInfo("html/notification.mp3","Path to notification sound", component_args=hide_dirs),
|
||||
"show_progress_every_n_steps": OptionInfo(1, "Live preview display period", gr.Slider, {"minimum": -1, "maximum": 32, "step": 1}),
|
||||
"show_progress_type": OptionInfo("TAESD", "Live preview method", gr.Radio, {"choices": ["Full", "Approx NN", "Approx cheap", "TAESD"]}),
|
||||
"show_progress_type": OptionInfo("TAESD", "Live preview method", gr.Radio, {"choices": ["Full VAE", "Approximate NN", "Approximate simple", "TAESD"]}),
|
||||
"live_preview_content": OptionInfo("Combined", "Live preview subject", gr.Radio, {"choices": ["Combined", "Prompt", "Negative prompt"]}),
|
||||
"live_preview_refresh_period": OptionInfo(250, "Progressbar/preview update period, in milliseconds")
|
||||
}))
|
||||
@@ -431,7 +441,7 @@ options_templates.update(options_section(('live-preview', "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']}),
|
||||
@@ -488,16 +498,17 @@ 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"), {
|
||||
# }))
|
||||
options_templates.update(options_section(('lora', "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 }),
|
||||
}))
|
||||
|
||||
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]}),
|
||||
@@ -516,10 +527,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),
|
||||
|
||||
@@ -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
|
||||
@@ -239,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]
|
||||
@@ -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()
|
||||
|
||||
|
||||
+9
-11
@@ -545,9 +545,7 @@ def create_ui():
|
||||
|
||||
def add_copy_image_controls(tab_name, elem):
|
||||
with gr.Row(variant="compact", elem_id=f"img2img_copy_to_{tab_name}"):
|
||||
gr.HTML("Copy image to: ", elem_id=f"img2img_label_copy_to_{tab_name}")
|
||||
|
||||
for title, name in zip(['img2img', 'sketch', 'inpaint', 'inpaint sketch'], ['img2img', 'sketch', 'inpaint', 'inpaint_sketch']):
|
||||
for title, name in zip(['➠ image', '➠ sketch', '➠ inpaint', '➠ inpaint sketch'], ['img2img', 'sketch', 'inpaint', 'inpaint_sketch']):
|
||||
if name == tab_name:
|
||||
gr.Button(title, interactive=False)
|
||||
copy_image_destinations[name] = elem
|
||||
@@ -558,7 +556,7 @@ def create_ui():
|
||||
|
||||
with gr.Tabs(elem_id="mode_img2img"):
|
||||
img2img_selected_tab = gr.State(0) # pylint: disable=abstract-class-instantiated
|
||||
with gr.TabItem('img2img', id='img2img', elem_id="img2img_img2img_tab") as tab_img2img:
|
||||
with gr.TabItem('Image', id='img2img', elem_id="img2img_img2img_tab") as tab_img2img:
|
||||
init_img = gr.Image(label="Image for img2img", elem_id="img2img_image", show_label=False, source="upload", interactive=True, type="pil", tool="editor", image_mode="RGBA").style(height=480)
|
||||
add_copy_image_controls('img2img', init_img)
|
||||
|
||||
@@ -596,9 +594,9 @@ def create_ui():
|
||||
"<br>Add inpaint batch mask directory to enable inpaint batch processing."
|
||||
f"{hidden}</p>"
|
||||
)
|
||||
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":
|
||||
@@ -1462,7 +1460,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)
|
||||
@@ -1679,7 +1677,7 @@ def html_head():
|
||||
head += f'<script type="module" src="{webpath(script.path)}"></script>\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
|
||||
|
||||
|
||||
@@ -1712,7 +1710,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
|
||||
|
||||
|
||||
|
||||
+33
-23
@@ -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,22 +66,28 @@ 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 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.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)
|
||||
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
|
||||
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 = []
|
||||
@@ -88,10 +95,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.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))
|
||||
@@ -106,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)
|
||||
@@ -164,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],
|
||||
)
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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 = """
|
||||
<table id="extensions">
|
||||
<colgroup>
|
||||
@@ -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")
|
||||
|
||||
@@ -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,13 @@ class ExtraNetworksPage:
|
||||
if subdirs:
|
||||
subdirs = {"": 1, **subdirs}
|
||||
subdirs_html = "".join([f"""
|
||||
<button class='lg secondary gradio-button custom-button{" search-all" if subdir=="" else ""}' onclick='extraNetworksSearchButton("{tabname}_extra_tabs", event)'>
|
||||
{html.escape(subdir if subdir!="" else "all")}
|
||||
</button>
|
||||
""" for subdir in subdirs])
|
||||
<button class='lg secondary gradio-button custom-button{" search-all" if subdir=="" else ""}' onclick='extraNetworksSearchButton("{tabname}_extra_tabs", event)'>
|
||||
{html.escape(subdir if subdir!="" else "all")}
|
||||
</button>""" 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
|
||||
@@ -213,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")
|
||||
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:
|
||||
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
|
||||
@@ -271,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(
|
||||
@@ -286,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(
|
||||
|
||||
@@ -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():
|
||||
|
||||
+12
-17
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
+28
-26
@@ -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):
|
||||
@@ -207,35 +207,35 @@ 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("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("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"])
|
||||
]
|
||||
|
||||
|
||||
@@ -352,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.
|
||||
@@ -362,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:
|
||||
@@ -409,7 +411,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")
|
||||
|
||||
@@ -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
|
||||
@@ -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")
|
||||
|
||||
@@ -222,7 +224,22 @@ 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
|
||||
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,
|
||||
@@ -237,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)}')
|
||||
@@ -282,6 +289,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')
|
||||
|
||||
+1
-1
Submodule wiki updated: d420606fc4...801130e4c4
Reference in New Issue
Block a user