mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
Submodule extensions-builtin/sd-extension-system-info updated: 83dd4d8f65...b73ffdcc8d
+7
-7
@@ -356,7 +356,7 @@
|
||||
{"id":"","label":"Enable splitting of hires batch processing","localized":"","hint":"Reduces VRAM usage when using hires fix on batches of images"},
|
||||
{"id":"","label":"Load models using stream loading method","localized":"","hint":"When loading models attempt stream loading optimized for slow or network storage"},
|
||||
{"id":"","label":"When loading models attempt to reuse previous model dictionary","localized":"","hint":""},
|
||||
{"id":"","label":"Disable cross-attention layer optimization","localized":"","hint":"Disable the all cross-attention optimization. May result in higher VRAM usage and longer generation times"},
|
||||
{"id":"","label":"Disabled","localized":"","hint":""},
|
||||
{"id":"","label":"xFormers","localized":"","hint":"Memory optimization. Non-Deterministic (different results each time)"},
|
||||
{"id":"","label":"Scaled-Dot-Product","localized":"","hint":"Memory optimization. Non-Deterministic unless SDP memory attention is disabled."},
|
||||
{"id":"","label":"Doggettx's","localized":"","hint":""},
|
||||
@@ -365,9 +365,9 @@
|
||||
{"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":"cross-attention query chunk size","localized":"","hint":""},
|
||||
{"id":"","label":"cross-attention kv chunk size","localized":"","hint":""},
|
||||
{"id":"","label":"cross-attention chunking threshold","localized":"","hint":""},
|
||||
{"id":"","label":"Full parser","localized":"","hint":""},
|
||||
{"id":"","label":"Compel parser","localized":"","hint":""},
|
||||
{"id":"","label":"A1111 parser","localized":"","hint":""},
|
||||
@@ -466,9 +466,9 @@
|
||||
{"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":"Show grid in results","localized":"","hint":""},
|
||||
{"id":"","label":"For inpainting, include the greyscale mask in results","localized":"","hint":""},
|
||||
{"id":"","label":"For inpainting, include masked composite in results","localized":"","hint":""},
|
||||
{"id":"","label":"Do not change 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":""},
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
+1
-1
@@ -496,7 +496,7 @@ def check_torch():
|
||||
if opts.get('cuda_compile_backend', '') == 'hidet':
|
||||
install('hidet', 'hidet')
|
||||
if args.use_openvino or opts.get('cuda_compile_backend', '') == 'openvino_fx':
|
||||
install('openvino==2023.1.0.dev20230811', 'openvino')
|
||||
install('openvino==2023.1.0', 'openvino')
|
||||
os.environ.setdefault('PYTORCH_TRACING_MODE', 'TORCHFX')
|
||||
if args.profile:
|
||||
print_profile(pr, 'Torch')
|
||||
|
||||
@@ -34,9 +34,10 @@ async function createSplash() {
|
||||
</div>`;
|
||||
document.body.insertAdjacentHTML('beforeend', splash);
|
||||
await preloadImages();
|
||||
const imgElement = `<div class="splash-img" alt="logo" style="background-image: url(file=html/logo-bg-${dark ? 'dark' : 'light'}.jpg), url(file=html/logo-bg-${num}.jpg); background-blend-mode: ${dark ? 'darken' : 'lighten'}"></div>`;
|
||||
const imgElement = `<div class="splash-img" alt="logo" style="background-image: url(file=html/logo-bg-${dark ? 'dark' : 'light'}.jpg), url(file=html/logo-bg-${num}.jpg); background-blend-mode: ${dark ? 'multiply' : 'lighten'}"></div>`;
|
||||
document.getElementById('splash').insertAdjacentHTML('afterbegin', imgElement);
|
||||
}
|
||||
|
||||
async function removeSplash() {
|
||||
const splash = document.getElementById('splash');
|
||||
if (splash) splash.remove();
|
||||
|
||||
@@ -75,7 +75,7 @@ let executedOnLoaded = false;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const mutationObserver = new MutationObserver((m) => {
|
||||
if (!executedOnLoaded && gradioApp().querySelector('#txt2img_prompt')) {
|
||||
if (!executedOnLoaded && gradioApp().getElementById('txt2img_prompt')) {
|
||||
executedOnLoaded = true;
|
||||
executeCallbacks(uiLoadedCallbacks);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ async function setHints() {
|
||||
if (localeData.data.length === 0) {
|
||||
const res = await fetch('/file=html/locale_en.json');
|
||||
const json = await res.json();
|
||||
localeData.data = Object.values(json).flat();
|
||||
localeData.data = Object.values(json).flat().filter((e) => e.hint.length > 0);
|
||||
for (const e of localeData.data) e.label = e.label.toLowerCase().trim();
|
||||
}
|
||||
const elements = [
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
:root, .dark{ --checkbox-label-gap: 0.25em 0.1em; --section-header-text-size: 12pt; --block-background-fill: transparent;}
|
||||
a { font-weight: bold; cursor: pointer; }
|
||||
h2 { margin-top: 1em !important; font-size: 1.4em !important; }
|
||||
table { overflow-x: auto !important; overflow-y: auto !important; }
|
||||
div.gradio-container{ max-width: unset !important; padding: 8px !important; }
|
||||
div.tabitem { padding: 0 !important; }
|
||||
div.form { border-width: 0; box-shadow: none; background: transparent; overflow: visible; gap: 0.5em 1em; flex-grow: 1 !important; }
|
||||
@@ -230,7 +231,7 @@ table.settings-value-table td { padding: 0.4em; border: 1px solid #ccc; max-widt
|
||||
.extra-networks .description { flex: 3; }
|
||||
.extra-networks .tab-nav > button { margin-right: 0; height: 24px; padding: 2px 4px 2px 4px; }
|
||||
.extra-networks-tab { padding: 0 !important; }
|
||||
.extra-network-subdirs { background: var(--input-background-fill); overflow-x: hidden; overflow-y: auto; min-width: max(20%, 120px); padding-top: 0.5em; }
|
||||
.extra-network-subdirs { background: var(--input-background-fill); overflow-x: hidden; overflow-y: auto; min-width: max(15%, 120px); padding-top: 0.5em; }
|
||||
.extra-networks-page { display: flex }
|
||||
.extra-networks .custom-button { width: 120px; width: 100%; background: none; justify-content: left; text-align: left; padding: 2px 8px 2px 16px; text-indent: -8px; box-shadow: none; line-break: auto; }
|
||||
.extra-networks .custom-button:hover { background: var(--button-primary-background-fill) }
|
||||
@@ -294,8 +295,8 @@ div.controlnet_main_options { display: grid; grid-template-columns: 1fr 1fr; gri
|
||||
/* Workaround for Gradio dropdowns capturing clicks during and after fadeout */
|
||||
.gradio-dropdown > label > div > div:first-child:not(.showOptions) ~ ul.options { pointer-events: none; }
|
||||
|
||||
.splash { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 100; display: block; text-align: center; }
|
||||
.splash-img { margin: 10% auto 0 auto; width: 512px; background-repeat: no-repeat; height: 512px; animation: move 5s infinite alternate; }
|
||||
.splash { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 1000; display: block; text-align: center; }
|
||||
.splash-img { margin: 10% auto 0 auto; width: 512px; background-repeat: no-repeat; height: 512px; animation: color 10s infinite alternate; }
|
||||
.loading { color: white; position: absolute; top: 20%; left: 50%; transform: translateX(-50%); }
|
||||
.loader { width: 300px; height: 300px; border: var(--spacing-md) solid transparent; border-radius: 50%; border-top: var(--spacing-md) solid var(--primary-600); animation: spin 4s linear infinite; position: relative; }
|
||||
.loader::before, .loader::after { content: ""; position: absolute; top: 6px; bottom: 6px; left: 6px; right: 6px; border-radius: 50%; border: var(--spacing-md) solid transparent; }
|
||||
@@ -311,3 +312,8 @@ div.controlnet_main_options { display: grid; grid-template-columns: 1fr 1fr; gri
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes color {
|
||||
from { filter: hue-rotate(0deg) }
|
||||
to { filter: hue-rotate(360deg) }
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ def esrgan_upscale(model, img):
|
||||
|
||||
with Progress(TextColumn('[cyan]{task.description}'), BarColumn(), TaskProgressColumn(), TimeRemainingColumn(), TimeElapsedColumn(), console=console) as progress:
|
||||
total = 0
|
||||
for y, h, row in grid.tiles:
|
||||
for _y, _h, row in grid.tiles:
|
||||
total += len(row)
|
||||
task = progress.add_task(description="Upscaling", total=total)
|
||||
for y, h, row in grid.tiles:
|
||||
|
||||
+22
-10
@@ -291,7 +291,8 @@ def sanitize_filename_part(text, replace_spaces=True):
|
||||
|
||||
class FilenameGenerator:
|
||||
replacements = {
|
||||
'batch_number': lambda self: NOTHING if self.index <= 1 else self.index,
|
||||
'batch_number': lambda self: self.batch_number,
|
||||
'iter_number': lambda self: self.iter_number,
|
||||
'cfg': lambda self: self.p and self.p.cfg_scale,
|
||||
'clip_skip': lambda self: self.p and self.p.clip_skip,
|
||||
'date': lambda self: datetime.datetime.now().strftime('%Y-%m-%d'),
|
||||
@@ -320,12 +321,17 @@ class FilenameGenerator:
|
||||
}
|
||||
default_time_format = '%Y%m%d%H%M%S'
|
||||
|
||||
def __init__(self, p, seed, prompt, image, index = 0):
|
||||
def __init__(self, p, seed, prompt, image, grid=False):
|
||||
self.p = p
|
||||
self.seed = seed
|
||||
self.prompt = prompt
|
||||
self.image = image
|
||||
self.index = index if self.p is None or self.p.batch_size == 1 else self.p.batch_index + 1
|
||||
if not grid:
|
||||
self.batch_number = NOTHING if self.p is None or getattr(self.p, 'batch_size', 1) == 1 else (self.p.batch_index + 1 if hasattr(self.p, 'batch_index') else NOTHING)
|
||||
self.iter_number = NOTHING if self.p is None or getattr(self.p, 'n_iter', 1) == 1 else (self.p.iteration + 1 if hasattr(self.p, 'iteration') else NOTHING)
|
||||
else:
|
||||
self.batch_number = NOTHING
|
||||
self.iter_number = NOTHING
|
||||
|
||||
def hasprompt(self, *args):
|
||||
lower = self.prompt.lower()
|
||||
@@ -449,14 +455,14 @@ def atomically_save_image():
|
||||
image_format = 'JPEG'
|
||||
if shared.opts.image_watermark_enabled:
|
||||
image = set_watermark(image, shared.opts.image_watermark)
|
||||
shared.log.debug(f'Saving: image={fn} type={image_format} size={image.width}x{image.height}')
|
||||
shared.log.debug(f'Saving: image="{fn}" type={image_format} size={image.width}x{image.height}')
|
||||
# actual save
|
||||
exifinfo = (exifinfo or "") if shared.opts.image_metadata else ""
|
||||
if image_format == 'PNG':
|
||||
pnginfo_data = PngImagePlugin.PngInfo()
|
||||
for k, v in params.pnginfo.items():
|
||||
pnginfo_data.add_text(k, str(v))
|
||||
image.save(fn, format=image_format, quality=shared.opts.jpeg_quality, pnginfo=pnginfo_data if shared.opts.image_metadata else None)
|
||||
image.save(fn, format=image_format, optimize=True, compress_level=9, pnginfo=pnginfo_data if shared.opts.image_metadata else None)
|
||||
elif image_format == 'JPEG':
|
||||
if image.mode == 'RGBA':
|
||||
shared.log.warning('Saving RGBA image as JPEG: Alpha channel will be lost')
|
||||
@@ -464,7 +470,7 @@ def atomically_save_image():
|
||||
elif image.mode == 'I;16':
|
||||
image = image.point(lambda p: p * 0.0038910505836576).convert("L")
|
||||
exif_bytes = piexif.dump({ "Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(exifinfo, encoding="unicode") } })
|
||||
image.save(fn, format=image_format, quality=shared.opts.jpeg_quality, exif=exif_bytes)
|
||||
image.save(fn, format=image_format, optimize=True, quality=shared.opts.jpeg_quality, exif=exif_bytes)
|
||||
elif image_format == 'WEBP':
|
||||
if image.mode == 'I;16':
|
||||
image = image.point(lambda p: p * 0.0038910505836576).convert("RGB")
|
||||
@@ -489,8 +495,14 @@ def atomically_save_image():
|
||||
with open(os.path.join(paths.data_path, "params.txt"), "w", encoding="utf8") as file:
|
||||
file.write(exifinfo)
|
||||
if shared.opts.save_log_fn != '' and len(exifinfo) > 0:
|
||||
entry = { 'filename': filename, 'time': datetime.datetime.now().isoformat(), 'info': exifinfo }
|
||||
shared.writefile(entry, os.path.join(paths.data_path, shared.opts.save_log_fn), mode='a+')
|
||||
fn = os.path.join(paths.data_path, shared.opts.save_log_fn)
|
||||
entries = shared.readfile(fn)
|
||||
idx = len(list(entries))
|
||||
if idx == 0:
|
||||
entries = []
|
||||
entry = { 'id': idx, 'filename': filename, 'time': datetime.datetime.now().isoformat(), 'info': exifinfo }
|
||||
entries.append(entry)
|
||||
shared.writefile(entries, fn, mode='w')
|
||||
save_queue.task_done()
|
||||
|
||||
|
||||
@@ -499,7 +511,7 @@ save_thread = threading.Thread(target=atomically_save_image, daemon=True)
|
||||
save_thread.start()
|
||||
|
||||
|
||||
def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', info=None, short_filename=False, no_prompt=False, grid=False, pnginfo_section_name='parameters', p=None, existing_info=None, forced_filename=None, suffix="", save_to_dirs=None, index=0):
|
||||
def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', info=None, short_filename=False, no_prompt=False, grid=False, pnginfo_section_name='parameters', p=None, existing_info=None, forced_filename=None, suffix="", save_to_dirs=None):
|
||||
"""Save an image.
|
||||
Args:
|
||||
image (`PIL.Image`):
|
||||
@@ -537,7 +549,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', i
|
||||
return None, None
|
||||
if path is None or len(path) == 0: # set default path to avoid errors when functions are triggered manually or via api and param is not set
|
||||
path = shared.opts.outdir_save
|
||||
namegen = FilenameGenerator(p, seed, prompt, image, index)
|
||||
namegen = FilenameGenerator(p, seed, prompt, image, grid=grid)
|
||||
if save_to_dirs is None:
|
||||
save_to_dirs = (grid and shared.opts.grid_save_to_dirs) or (not grid and shared.opts.save_to_dirs and not no_prompt)
|
||||
if save_to_dirs:
|
||||
|
||||
+13
-9
@@ -472,6 +472,7 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_su
|
||||
"CFG scale": p.cfg_scale,
|
||||
"Size": f"{p.width}x{p.height}",
|
||||
"Batch": f'{p.n_iter}x{p.batch_size}' if p.n_iter > 1 or p.batch_size > 1 else None,
|
||||
"Index": f'{p.iteration + 1}x{index + 1}' if (p.n_iter > 1 or p.batch_size > 1) and index >= 0 else None,
|
||||
"Parser": shared.opts.prompt_attention,
|
||||
"Model": None if (not shared.opts.add_model_name_to_info) or (not shared.sd_model.sd_checkpoint_info.model_name) else shared.sd_model.sd_checkpoint_info.model_name.replace(',', '').replace(':', ''),
|
||||
"Model hash": getattr(p, 'sd_model_hash', None if (not shared.opts.add_model_hash_to_info) or (not shared.sd_model.sd_model_hash) else shared.sd_model.sd_model_hash),
|
||||
@@ -798,7 +799,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
p.scripts.postprocess_batch_list(p, batch_params, batch_number=n)
|
||||
x_samples_ddim = batch_params.images
|
||||
|
||||
def infotext(index=0): # pylint: disable=function-redefined # noqa: F811
|
||||
def infotext(index): # pylint: disable=function-redefined # noqa: F811
|
||||
return create_infotext(p, p.prompts, p.seeds, p.subseeds, index=index, all_negative_prompts=p.negative_prompts)
|
||||
|
||||
for i, x_sample in enumerate(x_samples_ddim):
|
||||
@@ -816,7 +817,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
p.restore_faces = False
|
||||
info = infotext(i)
|
||||
p.restore_faces = orig
|
||||
images.save_image(Image.fromarray(x_sample), path=p.outpath_samples, basename="", seed=p.seeds[i], prompt=p.prompts[i], extension=shared.opts.samples_format, info=info, p=p, suffix="-before-face-restoration")
|
||||
images.save_image(Image.fromarray(x_sample), path=p.outpath_samples, basename="", seed=p.seeds[i], prompt=p.prompts[i], extension=shared.opts.samples_format, info=info, p=p, suffix="-before-face-restore")
|
||||
p.ops.append('face')
|
||||
x_sample = modules.face_restoration.restore_faces(x_sample)
|
||||
image = Image.fromarray(x_sample)
|
||||
@@ -831,7 +832,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
info = infotext(i)
|
||||
p.color_corrections = orig
|
||||
image_without_cc = apply_overlay(image, p.paste_to, i, p.overlay_images)
|
||||
images.save_image(image_without_cc, path=p.outpath_samples, basename="", seed=p.seeds[i], prompt=p.prompts[i], extension=shared.opts.samples_format, info=info, p=p, suffix="-before-color-correction")
|
||||
images.save_image(image_without_cc, path=p.outpath_samples, basename="", seed=p.seeds[i], prompt=p.prompts[i], extension=shared.opts.samples_format, info=info, p=p, suffix="-before-color-correct")
|
||||
p.ops.append('color')
|
||||
image = apply_color_correction(p.color_corrections[i], image)
|
||||
image = apply_overlay(image, p.paste_to, i, p.overlay_images)
|
||||
@@ -840,7 +841,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
image.info["parameters"] = text
|
||||
output_images.append(image)
|
||||
if shared.opts.samples_save and not p.do_not_save_samples:
|
||||
images.save_image(image, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=text, p=p)
|
||||
images.save_image(image, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=text, p=p) # main save image
|
||||
if hasattr(p, 'mask_for_overlay') and p.mask_for_overlay and any([shared.opts.save_mask, shared.opts.save_mask_composite, shared.opts.return_mask, shared.opts.return_mask_composite]):
|
||||
image_mask = p.mask_for_overlay.convert('RGB')
|
||||
image_mask_composite = Image.composite(image.convert('RGBA').convert('RGBa'), Image.new('RGBa', image.size), images.resize_image(3, p.mask_for_overlay, image.width, image.height).convert('L')).convert('RGBA')
|
||||
@@ -865,13 +866,13 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
if images.check_grid_size(output_images):
|
||||
grid = images.image_grid(output_images, p.batch_size)
|
||||
if shared.opts.return_grid:
|
||||
text = infotext()
|
||||
text = infotext(-1)
|
||||
infotexts.insert(0, text)
|
||||
grid.info["parameters"] = text
|
||||
output_images.insert(0, grid)
|
||||
index_of_first_image = 1
|
||||
if shared.opts.grid_save:
|
||||
images.save_image(grid, p.outpath_grids, "grid", p.all_seeds[0], p.all_prompts[0], shared.opts.grid_format, info=infotext(), short_filename=not shared.opts.grid_extended_filename, p=p, grid=True)
|
||||
images.save_image(grid, p.outpath_grids, "", p.all_seeds[0], p.all_prompts[0], shared.opts.grid_format, info=infotext(-1), short_filename=not shared.opts.grid_extended_filename, p=p, grid=True, suffix="-grid") # main save grid
|
||||
|
||||
if not p.disable_extra_networks and extra_network_data:
|
||||
modules.extra_networks.deactivate(p, extra_network_data)
|
||||
@@ -880,7 +881,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
p,
|
||||
images_list=output_images,
|
||||
seed=p.all_seeds[0],
|
||||
info=infotext(),
|
||||
info=infotext(0),
|
||||
comments="\n".join(comments),
|
||||
subseed=p.all_subseeds[0],
|
||||
index_of_first_image=index_of_first_image,
|
||||
@@ -964,6 +965,9 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
||||
if (self.hr_upscale_to_x == self.width and self.hr_upscale_to_y == self.height) or self.hr_upscaler is None or self.hr_upscaler == 'None':
|
||||
self.is_hr_pass = False
|
||||
return
|
||||
if self.denoising_strength == 0:
|
||||
self.is_hr_pass = False
|
||||
return
|
||||
self.is_hr_pass = True
|
||||
if not shared.state.processing_has_refined_job_count:
|
||||
if shared.state.job_count == -1:
|
||||
@@ -987,7 +991,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
||||
info = create_infotext(self, self.all_prompts, self.all_seeds, self.all_subseeds, [], iteration=self.iteration, position_in_batch=index)
|
||||
self.extra_generation_params = orig1
|
||||
self.restore_faces = orig2
|
||||
images.save_image(image, self.outpath_samples, "", seeds[index], prompts[index], shared.opts.samples_format, info=info, suffix="-before-hires", index=index+1)
|
||||
images.save_image(image, self.outpath_samples, "", seeds[index], prompts[index], shared.opts.samples_format, info=info, suffix="-before-hires")
|
||||
|
||||
if shared.backend == shared.Backend.DIFFUSERS:
|
||||
modules.sd_models.set_diffuser_pipe(self.sd_model, modules.sd_models.DiffusersTaskType.TEXT_2_IMAGE)
|
||||
@@ -1140,7 +1144,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
|
||||
self.init_img_width = img.width # pylint: disable=attribute-defined-outside-init
|
||||
self.init_img_height = img.height # pylint: disable=attribute-defined-outside-init
|
||||
if shared.opts.save_init_img:
|
||||
images.save_image(img, path=shared.opts.outdir_init_images, basename=None, forced_filename=self.init_img_hash, save_to_dirs=False)
|
||||
images.save_image(img, path=shared.opts.outdir_init_images, basename=None, forced_filename=self.init_img_hash, save_to_dirs=False, suffix="-init-image")
|
||||
image = images.flatten(img, shared.opts.img2img_background_color)
|
||||
if crop_region is None and self.resize_mode != 4:
|
||||
image = images.resize_image(self.resize_mode, image, self.width, self.height)
|
||||
|
||||
@@ -65,7 +65,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
|
||||
def full_vae_decode(latents, model):
|
||||
t0 = time.time()
|
||||
if shared.opts.diffusers_move_unet and not model.has_accelerate:
|
||||
if shared.opts.diffusers_move_unet and not getattr(model, 'has_accelerate', False):
|
||||
shared.log.debug('Moving to CPU: model=UNet')
|
||||
unet_device = model.unet.device
|
||||
model.unet.to(devices.cpu)
|
||||
@@ -80,7 +80,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
latents = latents.to(next(iter(model.vae.post_quant_conv.parameters())).dtype)
|
||||
|
||||
decoded = model.vae.decode(latents / model.vae.config.scaling_factor, return_dict=False)[0]
|
||||
if shared.opts.diffusers_move_unet and not model.has_accelerate:
|
||||
if shared.opts.diffusers_move_unet and not getattr(model, 'has_accelerate', False):
|
||||
model.unet.to(unet_device)
|
||||
t1 = time.time()
|
||||
shared.log.debug(f'VAE decode: name={sd_vae.loaded_vae_file if sd_vae.loaded_vae_file is not None else "baked"} dtype={model.vae.dtype} upcast={upcast} images={latents.shape[0]} latents={latents.shape} time={round(t1-t0, 3)}s')
|
||||
@@ -88,7 +88,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
|
||||
def full_vae_encode(image, model):
|
||||
shared.log.debug(f'VAE encode: name={sd_vae.loaded_vae_file if sd_vae.loaded_vae_file is not None else "baked"} dtype={model.vae.dtype} upcast={model.vae.config.get("force_upcast", None)}')
|
||||
if shared.opts.diffusers_move_unet and not model.has_accelerate:
|
||||
if shared.opts.diffusers_move_unet and not getattr(model, 'has_accelerate', False):
|
||||
shared.log.debug('Moving to CPU: model=UNet')
|
||||
unet_device = model.unet.device
|
||||
model.unet.to(devices.cpu)
|
||||
@@ -96,7 +96,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
if not shared.cmd_opts.lowvram and not shared.opts.diffusers_seq_cpu_offload:
|
||||
model.vae.to(devices.device)
|
||||
encoded = model.vae.encode(image.to(model.vae.device, model.vae.dtype))
|
||||
if shared.opts.diffusers_move_unet and not model.has_accelerate:
|
||||
if shared.opts.diffusers_move_unet and not getattr(model, 'has_accelerate', False):
|
||||
model.unet.to(unet_device)
|
||||
return encoded
|
||||
|
||||
@@ -315,10 +315,11 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
task_specific_kwargs = {"image": p.init_images, "mask_image": p.mask, "strength": p.denoising_strength, "height": 8 * math.ceil(p.height / 8), "width": 8 * math.ceil(p.width / 8)}
|
||||
|
||||
if shared.state.interrupted or shared.state.skipped:
|
||||
unload_diffusers_lora()
|
||||
if lora_state['active']:
|
||||
unload_diffusers_lora()
|
||||
return results
|
||||
|
||||
if shared.opts.diffusers_move_base and not shared.sd_model.has_accelerate:
|
||||
if shared.opts.diffusers_move_base and not hasattr(shared.sd_model, 'has_accelerate', False):
|
||||
shared.sd_model.to(devices.device)
|
||||
|
||||
is_img2img = bool(sd_models.get_diffusers_task(shared.sd_model) == sd_models.DiffusersTaskType.IMAGE_2_IMAGE or sd_models.get_diffusers_task(shared.sd_model) == sd_models.DiffusersTaskType.INPAINTING)
|
||||
@@ -357,15 +358,16 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
output = shared.sd_model(**base_args) # pylint: disable=not-callable
|
||||
except AssertionError as e:
|
||||
shared.log.info(e)
|
||||
except ValueError as e:
|
||||
shared.state.interrupted = True
|
||||
shared.log.error(e)
|
||||
|
||||
if hasattr(shared.sd_model, 'embedding_db') and len(shared.sd_model.embedding_db.embeddings_used) > 0:
|
||||
p.extra_generation_params['Embeddings'] = ', '.join(shared.sd_model.embedding_db.embeddings_used)
|
||||
|
||||
if lora_state['active']:
|
||||
p.extra_generation_params['LoRA method'] = shared.opts.diffusers_lora_loader
|
||||
unload_diffusers_lora()
|
||||
|
||||
if shared.state.interrupted or shared.state.skipped:
|
||||
if lora_state['active']:
|
||||
unload_diffusers_lora()
|
||||
return results
|
||||
|
||||
# optional hires pass
|
||||
@@ -407,11 +409,15 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
except AssertionError as e:
|
||||
shared.log.info(e)
|
||||
|
||||
if lora_state['active']:
|
||||
p.extra_generation_params['LoRA method'] = shared.opts.diffusers_lora_loader
|
||||
unload_diffusers_lora()
|
||||
|
||||
# optional refiner pass or decode
|
||||
if is_refiner_enabled:
|
||||
if shared.opts.save and not p.do_not_save_samples and shared.opts.save_images_before_refiner and hasattr(shared.sd_model, 'vae'):
|
||||
save_intermediate(latents=output.images, suffix="-before-refiner")
|
||||
if shared.opts.diffusers_move_base and not shared.sd_model.has_accelerate:
|
||||
if shared.opts.diffusers_move_base and not hasattr(shared.sd_model, 'has_accelerate', False):
|
||||
shared.log.debug('Moving to CPU: model=base')
|
||||
shared.sd_model.to(devices.cpu)
|
||||
devices.torch_gc()
|
||||
@@ -423,9 +429,11 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
sd_samplers.create_sampler(sampler.name, shared.sd_refiner) # TODO(Patrick): For wrapped pipelines this is currently a no-op
|
||||
|
||||
if shared.state.interrupted or shared.state.skipped:
|
||||
if lora_state['active']:
|
||||
unload_diffusers_lora()
|
||||
return results
|
||||
|
||||
if shared.opts.diffusers_move_refiner and not shared.sd_refiner.has_accelerate:
|
||||
if shared.opts.diffusers_move_refiner and not hasattr(shared.sd_refiner, 'has_accelerate', False):
|
||||
shared.sd_refiner.to(devices.device)
|
||||
refiner_is_sdxl = bool("StableDiffusionXL" in shared.sd_refiner.__class__.__name__)
|
||||
p.ops.append('refine')
|
||||
@@ -461,7 +469,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
|
||||
for refiner_image in refiner_images:
|
||||
results.append(refiner_image)
|
||||
|
||||
if shared.opts.diffusers_move_refiner and not shared.sd_refiner.has_accelerate:
|
||||
if shared.opts.diffusers_move_refiner and not hasattr(shared.sd_refiner, 'has_accelerate', False):
|
||||
shared.log.debug('Moving to CPU: model=refiner')
|
||||
shared.sd_refiner.to(devices.cpu)
|
||||
devices.torch_gc()
|
||||
|
||||
@@ -155,7 +155,7 @@ class RealESRGANer():
|
||||
# input tile dimensions
|
||||
input_tile_width = input_end_x - input_start_x
|
||||
input_tile_height = input_end_y - input_start_y
|
||||
tile_idx = y * tiles_x + x + 1
|
||||
tile_idx = y * tiles_x + x + 1 # noqa
|
||||
input_tile = self.img[:, :, input_start_y_pad:input_end_y_pad, input_start_x_pad:input_end_x_pad]
|
||||
|
||||
# upscale tile
|
||||
@@ -315,7 +315,7 @@ class IOConsumer(threading.Thread):
|
||||
|
||||
from basicsr.utils.registry import ARCH_REGISTRY
|
||||
from torch import nn as nn
|
||||
from torch.nn import functional as F
|
||||
from torch.nn import functional as F # noqa
|
||||
|
||||
|
||||
class SRVGGNetCompact(nn.Module):
|
||||
@@ -381,4 +381,3 @@ class SRVGGNetCompact(nn.Module):
|
||||
base = F.interpolate(x, scale_factor=self.upscale, mode='nearest')
|
||||
out += base
|
||||
return out
|
||||
|
||||
+4
-11
@@ -37,45 +37,38 @@ def apply_optimizations():
|
||||
can_use_sdp = hasattr(torch.nn.functional, "scaled_dot_product_attention") and callable(torch.nn.functional.scaled_dot_product_attention)
|
||||
if devices.device == torch.device("cpu"):
|
||||
if opts.cross_attention_optimization == "Scaled-Dot-Product":
|
||||
shared.log.warning("Scaled dot product cross attention is not available on CPU")
|
||||
shared.log.warning("Cross-attention: Scaled dot product is not available on CPU")
|
||||
can_use_sdp = False
|
||||
if opts.cross_attention_optimization == "xFormers":
|
||||
shared.log.warning("xFormers cross attention is not available on CPU")
|
||||
shared.log.warning("Cross-attention: xFormers is not available on CPU")
|
||||
shared.xformers_available = False
|
||||
|
||||
if opts.cross_attention_optimization == "Disable cross-attention layer optimization":
|
||||
shared.log.warning("Cross-attention optimization disabled")
|
||||
shared.log.info(f"Cross-attention: optimization={opts.cross_attention_optimization} options={opts.cross_attention_options}")
|
||||
if opts.cross_attention_optimization == "Disabled":
|
||||
optimization_method = 'none'
|
||||
if can_use_sdp and opts.cross_attention_optimization == "Scaled-Dot-Product" and 'SDP disable memory attention' in opts.cross_attention_options:
|
||||
shared.log.info("Applying scaled dot product cross attention optimization (without memory efficient attention)")
|
||||
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.scaled_dot_product_no_mem_attention_forward
|
||||
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.sdp_no_mem_attnblock_forward
|
||||
optimization_method = 'sdp-no-mem'
|
||||
elif can_use_sdp and opts.cross_attention_optimization == "Scaled-Dot-Product":
|
||||
shared.log.info("Applying scaled dot product cross attention optimization")
|
||||
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.scaled_dot_product_attention_forward
|
||||
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.sdp_attnblock_forward
|
||||
optimization_method = 'sdp'
|
||||
if shared.xformers_available and opts.cross_attention_optimization == "xFormers":
|
||||
shared.log.info("Applying xformers cross attention optimization")
|
||||
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.xformers_attention_forward
|
||||
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.xformers_attnblock_forward
|
||||
optimization_method = 'xformers'
|
||||
if opts.cross_attention_optimization == "Sub-quadratic":
|
||||
shared.log.info("Applying sub-quadratic cross attention optimization")
|
||||
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.sub_quad_attention_forward
|
||||
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.sub_quad_attnblock_forward
|
||||
optimization_method = 'sub-quadratic'
|
||||
if opts.cross_attention_optimization == "Split attention":
|
||||
shared.log.info("Applying split attention optimization")
|
||||
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.split_cross_attention_forward_v1
|
||||
optimization_method = 'v1'
|
||||
if opts.cross_attention_optimization == "InvokeAI's":
|
||||
shared.log.info("Applying InvokeAI cross attention optimization")
|
||||
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.split_cross_attention_forward_invokeAI
|
||||
optimization_method = 'invokeai'
|
||||
if opts.cross_attention_optimization == "Doggettx's":
|
||||
shared.log.info("Applying Doggettx cross attention optimization")
|
||||
ldm.modules.attention.CrossAttention.forward = sd_hijack_optimizations.split_cross_attention_forward
|
||||
ldm.modules.diffusionmodules.model.AttnBlock.forward = sd_hijack_optimizations.cross_attention_attnblock_forward
|
||||
optimization_method = 'doggettx'
|
||||
|
||||
+15
-15
@@ -261,7 +261,7 @@ def select_checkpoint(op='model'):
|
||||
return None
|
||||
checkpoint_info = get_closet_checkpoint_match(model_checkpoint)
|
||||
if checkpoint_info is not None:
|
||||
shared.log.debug(f'Select checkpoint: {op} {checkpoint_info.title if checkpoint_info is not None else None}')
|
||||
shared.log.debug(f'Select checkpoint: {op}="{checkpoint_info.title if checkpoint_info is not None else None}"')
|
||||
return checkpoint_info
|
||||
if len(checkpoints_list) == 0 and not shared.cmd_opts.no_download:
|
||||
shared.log.error("Cannot run without a checkpoint")
|
||||
@@ -275,7 +275,7 @@ def select_checkpoint(op='model'):
|
||||
shared.log.info("Selecting first available checkpoint")
|
||||
# shared.log.warning(f"Loading fallback checkpoint: {checkpoint_info.title}")
|
||||
shared.opts.data['sd_model_checkpoint'] = checkpoint_info.title
|
||||
shared.log.debug(f'Select checkpoint: {checkpoint_info.title if checkpoint_info is not None else None}')
|
||||
shared.log.debug(f'Select checkpoint: {op}="{checkpoint_info.title if checkpoint_info is not None else None}"')
|
||||
return checkpoint_info
|
||||
|
||||
|
||||
@@ -896,7 +896,7 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No
|
||||
|
||||
base_sent_to_cpu=False
|
||||
if (shared.opts.cuda_compile and shared.opts.cuda_compile_backend != 'none') or shared.opts.ipex_optimize:
|
||||
if op == 'refiner' and not sd_model.has_accelerate:
|
||||
if op == 'refiner' and not getattr(sd_model, 'has_accelerate', False):
|
||||
gpu_vram = memory_stats().get('gpu', {})
|
||||
free_vram = gpu_vram.get('total', 0) - gpu_vram.get('used', 0)
|
||||
refiner_enough_vram = free_vram >= 7 if "StableDiffusionXL" in sd_model.__class__.__name__ else 3
|
||||
@@ -917,7 +917,7 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No
|
||||
devices.torch_gc(force=True)
|
||||
sd_model.to(devices.device)
|
||||
base_sent_to_cpu=True
|
||||
elif not sd_model.has_accelerate:
|
||||
elif not getattr(sd_model, 'has_accelerate', False):
|
||||
sd_model.to(devices.device)
|
||||
|
||||
compile_diffusers(sd_model)
|
||||
@@ -931,10 +931,10 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No
|
||||
shared.opts.data["sd_checkpoint_hash"] = checkpoint_info.sha256
|
||||
if hasattr(sd_model, "set_progress_bar_config"):
|
||||
sd_model.set_progress_bar_config(bar_format='Progress {rate_fmt}{postfix} {bar} {percentage:3.0f}% {n_fmt}/{total_fmt} {elapsed} {remaining}', ncols=80, colour='#327fba')
|
||||
if op == 'refiner' and shared.opts.diffusers_move_refiner and not sd_model.has_accelerate:
|
||||
if op == 'refiner' and shared.opts.diffusers_move_refiner and not getattr(sd_model, 'has_accelerate', False):
|
||||
shared.log.debug('Moving refiner model to CPU')
|
||||
sd_model.to(devices.cpu)
|
||||
elif not sd_model.has_accelerate: # In offload modes, accelerate will move models around
|
||||
elif not getattr(sd_model, 'has_accelerate', False): # In offload modes, accelerate will move models around
|
||||
sd_model.to(devices.device)
|
||||
if op == 'refiner' and base_sent_to_cpu:
|
||||
shared.log.debug('Moving base model back to GPU')
|
||||
@@ -965,10 +965,10 @@ class DiffusersTaskType(Enum):
|
||||
INPAINTING = 3
|
||||
|
||||
def set_diffuser_pipe(pipe, new_pipe_type):
|
||||
sd_checkpoint_info = pipe.sd_checkpoint_info if hasattr(pipe, "sd_checkpoint_info") else None
|
||||
sd_model_checkpoint = pipe.sd_model_checkpoint if hasattr(pipe, "sd_model_checkpoint") else None
|
||||
sd_model_hash = pipe.sd_model_hash if hasattr(pipe, "sd_model_hash") else None
|
||||
has_accelerate = pipe.has_accelerate if hasattr(pipe, "has_accelerate") else None
|
||||
sd_checkpoint_info = getattr(pipe, "sd_checkpoint_info", None)
|
||||
sd_model_checkpoint = getattr(pipe, "sd_model_checkpoint", None)
|
||||
sd_model_hash = getattr(pipe, "sd_model_hash", None)
|
||||
has_accelerate = getattr(pipe, "has_accelerate", None)
|
||||
|
||||
if new_pipe_type == DiffusersTaskType.TEXT_2_IMAGE:
|
||||
new_pipe = diffusers.AutoPipelineForText2Image.from_pipe(pipe)
|
||||
@@ -1067,6 +1067,7 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None,
|
||||
shared.log.info(f'LDM: {line.strip()}')
|
||||
shared.log.debug(f"Model created from config: {checkpoint_config}")
|
||||
sd_model.used_config = checkpoint_config
|
||||
sd_model.has_accelerate = False
|
||||
timer.record("create")
|
||||
ok = load_model_weights(sd_model, checkpoint_info, state_dict, timer)
|
||||
if not ok:
|
||||
@@ -1090,7 +1091,6 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None,
|
||||
sd_hijack.model_hijack.hijack(sd_model)
|
||||
timer.record("hijack")
|
||||
sd_model.eval()
|
||||
sd_model.has_accelerate = False
|
||||
if op == 'refiner':
|
||||
model_data.sd_refiner = sd_model
|
||||
else:
|
||||
@@ -1126,12 +1126,12 @@ def reload_model_weights(sd_model=None, info=None, reuse_dict=False, op='model')
|
||||
current_checkpoint_info = getattr(sd_model, 'sd_checkpoint_info', None)
|
||||
if current_checkpoint_info is not None and checkpoint_info is not None and current_checkpoint_info.filename == checkpoint_info.filename:
|
||||
return
|
||||
if not sd_model.has_accelerate:
|
||||
if not getattr(sd_model, 'has_accelerate', False):
|
||||
if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
|
||||
lowvram.send_everything_to_cpu()
|
||||
else:
|
||||
sd_model.to(devices.cpu)
|
||||
if (reuse_dict or shared.opts.model_reuse_dict) and not sd_model.has_accelerate:
|
||||
if (reuse_dict or shared.opts.model_reuse_dict) and not getattr(sd_model, 'has_accelerate', False):
|
||||
shared.log.info('Reusing previous model dictionary')
|
||||
sd_hijack.model_hijack.undo_hijack(sd_model)
|
||||
else:
|
||||
@@ -1164,7 +1164,7 @@ def reload_model_weights(sd_model=None, info=None, reuse_dict=False, op='model')
|
||||
timer.record("hijack")
|
||||
script_callbacks.model_loaded_callback(sd_model)
|
||||
timer.record("callbacks")
|
||||
if sd_model is not None and not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram and not sd_model.has_accelerate:
|
||||
if sd_model is not None and not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram and not getattr(sd_model, 'has_accelerate', False):
|
||||
sd_model.to(devices.device)
|
||||
timer.record("device")
|
||||
shared.log.info(f"Weights loaded in {timer.summary()}")
|
||||
@@ -1172,7 +1172,7 @@ def reload_model_weights(sd_model=None, info=None, reuse_dict=False, op='model')
|
||||
|
||||
def disable_offload(sd_model):
|
||||
from accelerate.hooks import remove_hook_from_module
|
||||
if not sd_model.has_accelerate:
|
||||
if not getattr(sd_model, 'has_accelerate', False):
|
||||
return
|
||||
for _name, model in sd_model.components.items():
|
||||
if not isinstance(model, torch.nn.Module):
|
||||
|
||||
@@ -55,6 +55,29 @@ def samples_to_image_grid(samples, approximation=None):
|
||||
return images.image_grid([single_sample_to_image(sample, approximation) for sample in samples])
|
||||
|
||||
|
||||
def images_tensor_to_samples(image, approximation=None, model=None):
|
||||
'''image[0, 1] -> latent'''
|
||||
if approximation is None:
|
||||
approximation = approximation_indexes.get(shared.opts.show_progress_type, 0)
|
||||
if approximation == 3:
|
||||
image = image.to(devices.device, devices.dtype)
|
||||
x_latent = sd_vae_taesd.encode(image)
|
||||
else:
|
||||
if model is None:
|
||||
model = shared.sd_model
|
||||
model.first_stage_model.to(devices.dtype_vae)
|
||||
image = image.to(shared.device, dtype=devices.dtype_vae)
|
||||
image = image * 2 - 1
|
||||
if len(image) > 1:
|
||||
x_latent = torch.stack([
|
||||
model.get_first_stage_encoding(model.encode_first_stage(torch.unsqueeze(img, 0)))[0]
|
||||
for img in image
|
||||
])
|
||||
else:
|
||||
x_latent = model.get_first_stage_encoding(model.encode_first_stage(image))
|
||||
return x_latent
|
||||
|
||||
|
||||
def store_latent(decoded):
|
||||
shared.state.current_latent = decoded
|
||||
if shared.opts.live_previews_enable and shared.opts.show_progress_every_n_steps > 0 and shared.state.sampling_step % shared.opts.show_progress_every_n_steps == 0:
|
||||
|
||||
+2
-2
@@ -243,7 +243,7 @@ def reload_vae_weights(sd_model=None, vae_file=unspecified):
|
||||
vae_source = "function-argument"
|
||||
if loaded_vae_file == vae_file:
|
||||
return
|
||||
if not sd_model.has_accelerate:
|
||||
if not getattr(sd_model, 'has_accelerate', False):
|
||||
if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
|
||||
lowvram.send_everything_to_cpu()
|
||||
else:
|
||||
@@ -265,6 +265,6 @@ def reload_vae_weights(sd_model=None, vae_file=unspecified):
|
||||
if vae is not None:
|
||||
sd_model.vae = vae
|
||||
|
||||
if not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram and not sd_model.has_accelerate:
|
||||
if not shared.cmd_opts.lowvram and not shared.cmd_opts.medvram and not getattr(sd_model, 'has_accelerate', False):
|
||||
sd_model.to(devices.device)
|
||||
return sd_model
|
||||
|
||||
+24
-21
@@ -340,7 +340,7 @@ def readfile(filename, silent=False):
|
||||
return data
|
||||
|
||||
|
||||
def writefile(data, filename, mode='w'):
|
||||
def writefile(data, filename, mode='w', silent=False):
|
||||
|
||||
def default(obj):
|
||||
log.error(f"Saving: {filename} not a valid object: {obj}")
|
||||
@@ -350,7 +350,8 @@ def writefile(data, filename, mode='w'):
|
||||
with fasteners.InterProcessLock(f"{filename}.lock"):
|
||||
# skipkeys=True, ensure_ascii=True, check_circular=True, allow_nan=True
|
||||
output = json.dumps(data, indent=2, default=default)
|
||||
log.debug(f'Saving: {filename} len={len(output)}')
|
||||
if not silent:
|
||||
log.debug(f'Saving: {filename} len={len(output)}')
|
||||
with open(filename, mode, encoding="utf8") as file:
|
||||
file.write(output)
|
||||
except Exception as e:
|
||||
@@ -376,24 +377,26 @@ options_templates.update(options_section(('sd', "Execution & Models"), {
|
||||
"sd_checkpoint_autoload": OptionInfo(True, "Model autoload on server start"),
|
||||
"sd_model_checkpoint": OptionInfo(default_checkpoint, "Base model", gr.Dropdown, lambda: {"choices": list_checkpoint_tiles()}, refresh=refresh_checkpoints),
|
||||
"sd_model_refiner": OptionInfo('None', "Refiner model", gr.Dropdown, lambda: {"choices": ['None'] + list_checkpoint_tiles()}, refresh=refresh_checkpoints),
|
||||
"sd_checkpoint_cache": OptionInfo(0, "Number of cached models", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
|
||||
"sd_vae_checkpoint_cache": OptionInfo(0, "Number of cached VAEs", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
|
||||
"sd_vae": OptionInfo("Automatic", "VAE model", gr.Dropdown, lambda: {"choices": shared_items.sd_vae_items()}, refresh=shared_items.refresh_vae_list),
|
||||
"sd_model_dict": OptionInfo('None', "Use baseline data from a different model", gr.Dropdown, lambda: {"choices": ['None'] + list_checkpoint_tiles()}, refresh=refresh_checkpoints),
|
||||
"stream_load": OptionInfo(False, "Load models using stream loading method"),
|
||||
"model_reuse_dict": OptionInfo(False, "When loading models attempt to reuse previous model dictionary"),
|
||||
"model_reuse_dict": OptionInfo(False, "When loading models attempt to reuse previous model dictionary", gr.Checkbox, {"visible": False}),
|
||||
"prompt_attention": OptionInfo("Full parser", "Prompt attention parser", gr.Radio, lambda: {"choices": ["Full parser", "Compel parser", "A1111 parser", "Fixed attention"] }),
|
||||
"prompt_mean_norm": OptionInfo(True, "Prompt attention mean normalization"),
|
||||
"comma_padding_backtrack": OptionInfo(20, "Prompt padding for long prompts", gr.Slider, {"minimum": 0, "maximum": 74, "step": 1 }),
|
||||
"sd_checkpoint_cache": OptionInfo(0, "Number of cached models", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
|
||||
"sd_vae_checkpoint_cache": OptionInfo(0, "Number of cached VAEs", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1}),
|
||||
"sd_disable_ckpt": OptionInfo(False, "Disallow usage of models in ckpt format"),
|
||||
}))
|
||||
|
||||
options_templates.update(options_section(('optimizations', "Optimizations"), {
|
||||
"cross_attention_optimization": OptionInfo(cross_attention_optimization_default, "Cross-attention optimization method", gr.Radio, lambda: {"choices": shared_items.list_crossattention() }),
|
||||
"cross_attention_options": OptionInfo([], "Cross-attention advanced options", gr.CheckboxGroup, lambda: {"choices": ['xFormers enable flash Attention', 'SDP disable memory attention']}),
|
||||
"sub_quad_q_chunk_size": OptionInfo(512, "Sub-quadratic cross-attention query chunk size", gr.Slider, {"minimum": 16, "maximum": 8192, "step": 8}),
|
||||
"sub_quad_kv_chunk_size": OptionInfo(512, "Sub-quadratic cross-attention kv chunk size", gr.Slider, {"minimum": 0, "maximum": 8192, "step": 8}),
|
||||
"sub_quad_chunk_threshold": OptionInfo(80, "Sub-quadratic cross-attention chunking threshold", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1}),
|
||||
"sub_quad_sep": OptionInfo("<h2>Sub-quadratic options</h2>", "", gr.HTML),
|
||||
"sub_quad_q_chunk_size": OptionInfo(512, "cross-attention query chunk size", gr.Slider, {"minimum": 16, "maximum": 8192, "step": 8}),
|
||||
"sub_quad_kv_chunk_size": OptionInfo(512, "cross-attention kv chunk size", gr.Slider, {"minimum": 0, "maximum": 8192, "step": 8}),
|
||||
"sub_quad_chunk_threshold": OptionInfo(80, "cross-attention chunking threshold", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1}),
|
||||
"token_merging_sep": OptionInfo("<h2>Token Merging</h2>", "", gr.HTML),
|
||||
"token_merging_ratio": OptionInfo(0.0, "Token merging ratio", gr.Slider, {"minimum": 0.0, "maximum": 0.9, "step": 0.1}),
|
||||
"token_merging_ratio_img2img": OptionInfo(0.0, "Token merging ratio for img2img", gr.Slider, {"minimum": 0.0, "maximum": 0.9, "step": 0.1}),
|
||||
"token_merging_ratio_hr": OptionInfo(0.0, "Token merging ratio for hires pass", gr.Slider, {"minimum": 0.0, "maximum": 0.9, "step": 0.1}),
|
||||
@@ -441,7 +444,7 @@ options_templates.update(options_section(('diffusers', "Diffusers Settings"), {
|
||||
"diffusers_attention_slicing": OptionInfo(True if devices.backend == "ipex" else False, "Enable attention slicing"),
|
||||
"diffusers_model_load_variant": OptionInfo("default", "Diffusers model loading variant", gr.Radio, lambda: {"choices": ['default', 'fp32', 'fp16']}),
|
||||
"diffusers_vae_load_variant": OptionInfo("default", "Diffusers VAE loading variant", gr.Radio, lambda: {"choices": ['default', 'fp32', 'fp16']}),
|
||||
"diffusers_lora_loader": OptionInfo("sequential apply", "Diffusers LoRA loading variant", gr.Radio, lambda: {"choices": ['diffusers', 'sequential apply', 'merge and apply']}),
|
||||
"diffusers_lora_loader": OptionInfo("diffusers" if cmd_opts.use_openvino else "sequential apply", "Diffusers LoRA loading variant", gr.Radio, lambda: {"choices": ['diffusers', 'sequential apply', 'merge and apply']}),
|
||||
"diffusers_force_zeros": OptionInfo(True, "Force zeros for prompts when empty"),
|
||||
"diffusers_aesthetics_score": OptionInfo(False, "Require aesthetics score"),
|
||||
}))
|
||||
@@ -529,19 +532,19 @@ options_templates.update(options_section(('saving-paths', "Image Naming & Paths"
|
||||
options_templates.update(options_section(('ui', "User Interface"), {
|
||||
"gradio_theme": OptionInfo("black-teal", "UI theme", gr.Dropdown, lambda: {"choices": list_themes()}, refresh=refresh_themes),
|
||||
"theme_style": OptionInfo("Auto", "Theme mode", gr.Radio, {"choices": ["Auto", "Dark", "Light"]}),
|
||||
"tooltips": OptionInfo("UI Tooltips", "UI tooltips", gr.Radio, {"choices": ["None", "Browser default", "UI tooltips"]}),
|
||||
"return_grid": OptionInfo(True, "Show grid in results for web"),
|
||||
"return_mask": OptionInfo(False, "For inpainting, include the greyscale mask in results for web"),
|
||||
"return_mask_composite": OptionInfo(False, "For inpainting, include masked composite in results for web"),
|
||||
"tooltips": OptionInfo("UI Tooltips", "UI tooltips", gr.Radio, {"choices": ["None", "Browser default", "UI tooltips"], "visible": False}),
|
||||
"return_grid": OptionInfo(True, "Show grid in results"),
|
||||
"return_mask": OptionInfo(False, "For inpainting, include the greyscale mask in results"),
|
||||
"return_mask_composite": OptionInfo(False, "For inpainting, include masked composite in results"),
|
||||
"disable_weights_auto_swap": OptionInfo(True, "Do not change selected model when reading generation parameters"),
|
||||
"send_seed": OptionInfo(True, "Send seed when sending prompt or image to other interface"),
|
||||
"send_size": OptionInfo(True, "Send size when sending prompt or image to another interface"),
|
||||
"font": OptionInfo("", "Font for image grids that have text"),
|
||||
"keyedit_precision_attention": OptionInfo(0.1, "Ctrl+up/down precision when editing (attention:1.1)", gr.Slider, {"minimum": 0.01, "maximum": 0.2, "step": 0.001}),
|
||||
"keyedit_precision_extra": OptionInfo(0.05, "Ctrl+up/down precision when editing <extra networks:0.9>", gr.Slider, {"minimum": 0.01, "maximum": 0.2, "step": 0.001}),
|
||||
"keyedit_delimiters": OptionInfo(".,\/!?%^*;:{}=`~()", "Ctrl+up/down word delimiters"), # pylint: disable=anomalous-backslash-in-string
|
||||
"keyedit_precision_attention": OptionInfo(0.1, "Ctrl+up/down precision when editing (attention:1.1)", gr.Slider, {"minimum": 0.01, "maximum": 0.2, "step": 0.001, "visible": False}),
|
||||
"keyedit_precision_extra": OptionInfo(0.05, "Ctrl+up/down precision when editing <extra networks:0.9>", gr.Slider, {"minimum": 0.01, "maximum": 0.2, "step": 0.001, "visible": False}),
|
||||
"keyedit_delimiters": OptionInfo(".,\/!?%^*;:{}=`~()", "Ctrl+up/down word delimiters", gr.Textbox, { "visible": False }), # pylint: disable=anomalous-backslash-in-string
|
||||
"quicksettings_list": OptionInfo(["sd_model_checkpoint"] if backend == Backend.ORIGINAL else ["sd_model_checkpoint", "sd_model_refiner"], "Quicksettings list", ui_components.DropdownMulti, lambda: {"choices": list(opts.data_labels.keys())}),
|
||||
"ui_scripts_reorder": OptionInfo("", "UI scripts order"),
|
||||
"ui_scripts_reorder": OptionInfo("", "UI scripts order", gr.Textbox, { "visible": False }),
|
||||
}))
|
||||
|
||||
options_templates.update(options_section(('live-preview', "Live Previews"), {
|
||||
@@ -552,7 +555,7 @@ options_templates.update(options_section(('live-preview', "Live Previews"), {
|
||||
"notification_audio_path": OptionInfo("html/notification.mp3","Path to notification sound", component_args=hide_dirs, folder=True),
|
||||
"show_progress_every_n_steps": OptionInfo(1, "Live preview display period", gr.Slider, {"minimum": -1, "maximum": 32, "step": 1}),
|
||||
"show_progress_type": OptionInfo("Approximate NN", "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_content": OptionInfo("Combined", "Live preview subject", gr.Radio, {"choices": ["Combined", "Prompt", "Negative prompt"], "visible": False}),
|
||||
"live_preview_refresh_period": OptionInfo(500, "Progress update period", gr.Slider, {"minimum": 0, "maximum": 5000, "step": 25}),
|
||||
"logmonitor_show": OptionInfo(True, "Show log view"),
|
||||
"logmonitor_refresh_period": OptionInfo(5000, "Log view update period", gr.Slider, {"minimum": 0, "maximum": 30000, "step": 25}),
|
||||
@@ -638,7 +641,7 @@ options_templates.update(options_section(('interrogate', "Interrogate"), {
|
||||
"interrogate_clip_num_beams": OptionInfo(1, "Interrogate: num_beams for BLIP", gr.Slider, {"minimum": 1, "maximum": 16, "step": 1}),
|
||||
"interrogate_clip_min_length": OptionInfo(32, "Interrogate: minimum description length", gr.Slider, {"minimum": 1, "maximum": 128, "step": 1}),
|
||||
"interrogate_clip_max_length": OptionInfo(192, "Interrogate: maximum description length", gr.Slider, {"minimum": 1, "maximum": 256, "step": 1}),
|
||||
"interrogate_clip_dict_limit": OptionInfo(2048, "CLIP: maximum number of lines in text file"),
|
||||
"interrogate_clip_dict_limit": OptionInfo(2048, "CLIP: maximum number of lines in text file", gr.Slider, { "visible": False }),
|
||||
"interrogate_clip_skip_categories": OptionInfo(["artists", "movements", "flavors"], "Interrogate: skip categories", gr.CheckboxGroup, lambda: {"choices": modules.interrogate.category_types()}, refresh=modules.interrogate.category_types),
|
||||
"interrogate_deepbooru_score_threshold": OptionInfo(0.65, "Interrogate: deepbooru score threshold", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.01}),
|
||||
"deepbooru_sort_alpha": OptionInfo(False, "Interrogate: deepbooru sort alphabetically"),
|
||||
@@ -652,10 +655,10 @@ options_templates.update(options_section(('extra_networks', "Extra Networks"), {
|
||||
"extra_networks_card_cover": OptionInfo("sidebar", "UI position", gr.Radio, lambda: {"choices": ["cover", "inline", "sidebar"]}),
|
||||
"extra_networks_height": OptionInfo(53, "UI height (%)", gr.Slider, {"minimum": 10, "maximum": 100, "step": 1}),
|
||||
"extra_networks_sidebar_width": OptionInfo(35, "UI sidebar width (%)", gr.Slider, {"minimum": 10, "maximum": 80, "step": 1}),
|
||||
"extra_networks_card_lazy": OptionInfo(True, "UI card preview lazy loading"),
|
||||
"extra_networks_card_lazy": OptionInfo(True, "UI card preview lazy loading", gr.Checkbox, { "visible": False }),
|
||||
"extra_networks_card_size": OptionInfo(160, "UI card size (px)", gr.Slider, {"minimum": 20, "maximum": 2000, "step": 1}),
|
||||
"extra_networks_card_square": OptionInfo(True, "UI disable variable aspect ratio"),
|
||||
"extra_networks_card_fit": OptionInfo("cover", "UI image contain method", gr.Radio, lambda: {"choices": ["contain", "cover", "fill"]}),
|
||||
"extra_networks_card_fit": OptionInfo("cover", "UI image contain method", gr.Radio, lambda: {"choices": ["contain", "cover", "fill"], "visible": False}),
|
||||
"extra_network_skip_indexing": OptionInfo(False, "Do not automatically build extra network pages", gr.Checkbox),
|
||||
"lyco_patch_lora": OptionInfo(False, "Use LyCoris handler for all LoRA types", gr.Checkbox),
|
||||
"lora_functional": OptionInfo(False, "Use Kohya method for handling multiple LoRA", gr.Checkbox, { "visible": False }),
|
||||
|
||||
@@ -20,7 +20,7 @@ def refresh_vae_list():
|
||||
|
||||
def list_crossattention():
|
||||
return [
|
||||
"Disable cross-attention layer optimization",
|
||||
"Disabled",
|
||||
"xFormers",
|
||||
"Scaled-Dot-Product",
|
||||
"Doggettx's",
|
||||
|
||||
+2
-2
@@ -392,7 +392,7 @@ def create_ui(startup_timer = None):
|
||||
with FormGroup():
|
||||
with FormRow(elem_id="sampler_selection_txt2img_alt_row1"):
|
||||
latent_index = gr.Dropdown(label='Secondary sampler', elem_id="txt2img_sampling_alt", choices=[x.name for x in modules.sd_samplers.samplers], value='Default', type="index")
|
||||
denoising_strength = gr.Slider(minimum=0.05, maximum=1.0, step=0.01, label='Denoising strength', value=0.5, elem_id="txt2img_denoising_strength")
|
||||
denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoising strength', value=0.5, elem_id="txt2img_denoising_strength")
|
||||
with FormRow(elem_id="txt2img_hires_finalres", variant="compact"):
|
||||
hr_final_resolution = FormHTML(value="", elem_id="txtimg_hr_finalres", label="Upscaled resolution", interactive=False)
|
||||
with FormRow(elem_id="txt2img_hires_fix_row1", variant="compact"):
|
||||
@@ -678,7 +678,7 @@ def create_ui(startup_timer = None):
|
||||
|
||||
with FormGroup(visible=show_denoise.value, elem_id=f"{tab}_denoise_group") as denoise_group:
|
||||
with FormRow():
|
||||
denoising_strength = gr.Slider(minimum=0.05, maximum=1.0, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength")
|
||||
denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength")
|
||||
refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise start', value=0.0, elem_id="img2img_refiner_start")
|
||||
|
||||
with FormGroup(visible=show_advanced.value, elem_id=f"{tab}_advanced_group") as advanced_group:
|
||||
|
||||
+13
-7
@@ -75,15 +75,21 @@ def save_files(js_data, images, html_info, index):
|
||||
class PObject: # pylint: disable=too-few-public-methods
|
||||
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)
|
||||
for k, v in d.items():
|
||||
setattr(self, k, v)
|
||||
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.negative_prompt = getattr(self, 'negative_prompt', None)
|
||||
self.all_negative_prompt = getattr(self, 'all_negative_prompts', [self.negative_prompt])
|
||||
self.seed = getattr(self, 'seed', None) or getattr(self, 'Seed', None)
|
||||
self.all_seeds = getattr(self, 'all_seeds', [self.seed])
|
||||
self.subseed = getattr(self, 'subseed', None)
|
||||
self.all_subseeds = getattr(self, 'all_subseeds', [self.subseed])
|
||||
self.width = getattr(self, 'width', None)
|
||||
self.height = getattr(self, 'height', None)
|
||||
self.index_of_first_image = getattr(self, 'index_of_first_image', 0)
|
||||
self.infotexts = getattr(self, 'infotexts', [html_info])
|
||||
self.infotext = self.infotexts[0] if len(self.infotexts) > 0 else html_info
|
||||
self.index_of_first_image = getattr(self, 'index_of_first_image', 0)
|
||||
try:
|
||||
data = json.loads(js_data)
|
||||
except Exception:
|
||||
@@ -110,12 +116,12 @@ def save_files(js_data, images, html_info, index):
|
||||
fullfns.append(fullfn)
|
||||
destination = shared.opts.outdir_save
|
||||
if shared.opts.use_save_to_dirs_for_ui:
|
||||
namegen = modules.images.FilenameGenerator(p, seed=p.all_seeds[i], prompt=p.all_prompts[i], image=None, index=image_index) # pylint: disable=no-member
|
||||
namegen = modules.images.FilenameGenerator(p, seed=p.all_seeds[i], prompt=p.all_prompts[i], image=None) # pylint: disable=no-member
|
||||
dirname = namegen.apply(shared.opts.directories_filename_pattern or "[prompt_words]").lstrip(' ').rstrip('\\ /')
|
||||
destination = os.path.join(destination, dirname)
|
||||
os.makedirs(destination, exist_ok = True)
|
||||
shutil.copy(fullfn, destination)
|
||||
shared.log.info(f"Copying image: {fullfn} -> {destination}")
|
||||
shared.log.info(f'Copying image: file="{fullfn}" folder="{destination}"')
|
||||
tgt_filename = os.path.join(destination, os.path.basename(fullfn))
|
||||
modules.script_callbacks.image_save_btn_callback(tgt_filename)
|
||||
else:
|
||||
|
||||
@@ -61,7 +61,7 @@ def pil_to_temp_file(self, img, dir: str, format="png") -> str: # pylint: disabl
|
||||
file_obj = tempfile.NamedTemporaryFile(delete=False, suffix=".png", dir=dir)
|
||||
img.save(file_obj, pnginfo=(metadata if use_metadata else None))
|
||||
name = file_obj.name
|
||||
shared.log.debug(f'Saving temp image: {name}')
|
||||
shared.log.debug(f'Saving temp: image="{name}"')
|
||||
return name
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user