From 3d914688ccf0d3da734ba725b96c4d4415165636 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Tue, 15 Aug 2023 05:50:00 +0200 Subject: [PATCH] update metadata --- CHANGELOG.md | 13 ++- cli/train.py | 2 +- extensions-builtin/sd-webui-agent-scheduler | 2 +- .../stable-diffusion-webui-images-browser | 2 +- installer.py | 3 + modules/generation_parameters_copypaste.py | 18 ++-- modules/paths.py | 4 +- modules/processing.py | 1 + modules/processing_diffusers.py | 92 ++++++++++++------- modules/prompt_parser_diffusers.py | 2 +- modules/sd_models.py | 8 +- modules/sd_samplers_diffusers.py | 4 +- modules/sd_samplers_kdiffusion.py | 6 +- modules/shared.py | 19 +++- .../textual_inversion/textual_inversion.py | 2 +- modules/ui.py | 26 ++++-- requirements.txt | 1 - wiki | 2 +- 18 files changed, 130 insertions(+), 77 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f493f05b6..f2364c528 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,22 @@ # Change Log for SD.Next -## Update for 2023-08-14 +## Update for 2023-08-17 - general: - update all metadata saved with images see for details - (work-in-progress) - improved **amd** installer with support for **navi 2x & 3x** and **rocm 5.4/5.5/5.6** thanks @evshiron - - fix img2img resizing (applies to original, diffusers, hires) + - fix **img2img** resizing (applies to *original, diffusers, hires*) + - config change: main `config.json` no longer contains entire configuration + but only differences from defaults (simmilar to recent change performed to `ui-config.json`) - diffusers: - - enable batch img2img workflows -- original: + - enable **batch img2img** workflows +- original: - new samplers: **dpm++ 3M sde** (standard and karras variations) enable in *settings -> samplers -> show samplers* + - expose always/never discard penultimage sigma + enable in *settings -> samplers* ## Update for 2023-08-11 diff --git a/cli/train.py b/cli/train.py index 76de6e632..5e3c7f99e 100755 --- a/cli/train.py +++ b/cli/train.py @@ -375,7 +375,7 @@ def check_versions(): log.info('checking accelerate') error = False import accelerate - if accelerate.__version__ != '0.20.3': + if accelerate.__version__ != '0.19.0': log.error(f'invalid accelerate version: accelerate=0.19.0 found={accelerate.__version__}') error = True log.info('checking diffusers') diff --git a/extensions-builtin/sd-webui-agent-scheduler b/extensions-builtin/sd-webui-agent-scheduler index 4af58ffa2..86857553e 160000 --- a/extensions-builtin/sd-webui-agent-scheduler +++ b/extensions-builtin/sd-webui-agent-scheduler @@ -1 +1 @@ -Subproject commit 4af58ffa2c5406db9ef43d119edcd0b5eb305346 +Subproject commit 86857553e715c8aa50f503dc2da320da8964e701 diff --git a/extensions-builtin/stable-diffusion-webui-images-browser b/extensions-builtin/stable-diffusion-webui-images-browser index d31eb3c48..6fe65accb 160000 --- a/extensions-builtin/stable-diffusion-webui-images-browser +++ b/extensions-builtin/stable-diffusion-webui-images-browser @@ -1 +1 @@ -Subproject commit d31eb3c482857055e45074efb879d37f6a21e2d5 +Subproject commit 6fe65accb317776b769177769dc59ed1b1641dda diff --git a/installer.py b/installer.py index 68119560c..576f87018 100644 --- a/installer.py +++ b/installer.py @@ -506,6 +506,7 @@ def install_packages(): install('git+https://github.com/damian0815/compel', 'compel', ignore=True) tensorflow_package = os.environ.get('TENSORFLOW_PACKAGE', 'tensorflow==2.13.0') install(tensorflow_package, 'tensorflow', ignore=True) + install('git+https://github.com/google-research/torchsde', 'torchsde', ignore=True) bitsandbytes_package = os.environ.get('BITSANDBYTES_PACKAGE', None) if bitsandbytes_package is not None: install(bitsandbytes_package, 'bitsandbytes', ignore=True) @@ -898,5 +899,7 @@ def read_options(): with open(args.config, "r", encoding="utf8") as file: try: opts = json.load(file) + if type(opts) is str: + opts = json.loads(opts) except Exception as e: log.error(f'Error reading options file: {file} {e}') diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index fe90daa25..e7dd07aa0 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -170,10 +170,7 @@ def connect_paste_params_buttons(): def send_image_and_dimensions(x): - if isinstance(x, Image.Image): - img = x - else: - img = image_from_url_text(x) + img = x if isinstance(x, Image.Image) else image_from_url_text(x) if shared.opts.send_size and isinstance(img, Image.Image): w = img.width h = img.height @@ -183,13 +180,10 @@ def send_image_and_dimensions(x): return img, w, h - def find_hypernetwork_key(hypernet_name, hypernet_hash=None): """Determines the config parameter name to use for the hypernet based on the parameters in the infotext. - Example: an infotext provides "Hypernet: ke-ta" and "Hypernet hash: 1234abcd". For the "Hypernet" config parameter this means there should be an entry that looks like "ke-ta-10000(1234abcd)" to set it to. - If the infotext has no hash, then a hypernet with the same name will be selected instead. """ hypernet_name = hypernet_name.lower() @@ -302,12 +296,17 @@ settings_map = {} infotext_to_setting_name_mapping = [ + ('VAE', 'sd_vae'), ('Conditional mask weight', 'inpainting_mask_weight'), ('Model hash', 'sd_model_checkpoint'), + ('Backed', 'sd_backend'), + ('Refiner', 'sd_model_refiner'), + ('Parser', 'prompt_attention'), ('ENSD', 'eta_noise_seed_delta'), ('Noise multiplier', 'initial_noise_multiplier'), ('Eta', 'eta_ancestral'), ('Eta DDIM', 'eta_ddim'), + ('Lora method', 'diffusers_lora_loader'), ('Discard penultimate sigma', 'always_discard_next_to_last_sigma'), ('UniPC variant', 'uni_pc_variant'), ('UniPC skip type', 'uni_pc_skip_type'), @@ -383,8 +382,9 @@ def connect_paste(button, local_paste_fields, input_comp, override_settings_comp v = params.get(param_name, None) if v is None: continue - if setting_name == "sd_model_checkpoint" and shared.opts.disable_weights_auto_swap: - continue + if shared.opts.disable_weights_auto_swap: + if setting_name == "sd_model_checkpoint" or setting_name == 'sd_model_refiner' or setting_name == 'sd_backend': + continue v = shared.opts.cast_value(setting_name, v) current_value = getattr(shared.opts, setting_name, None) if v == current_value: diff --git a/modules/paths.py b/modules/paths.py index e12e4a672..7ff14ee3d 100644 --- a/modules/paths.py +++ b/modules/paths.py @@ -65,7 +65,9 @@ def create_paths(opts): return if os.path.isabs(opts.data[folder]) or opts.data[folder].startswith(data_path): return - opts.data[folder] = os.path.join(data_path, opts.data[folder]) + fullpath = os.path.join(data_path, opts.data[folder]) + relpath = os.path.relpath(fullpath, script_path) + opts.data[folder] = relpath return create_path(fix_path('temp_dir')) diff --git a/modules/processing.py b/modules/processing.py index 4bf9b7e72..9c7964ac8 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -484,6 +484,7 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_su "Negative2": p.refiner_negative if p.enable_hr and len(p.refiner_negative) > 0 else None, "Latent sampler": p.latent_sampler if p.enable_hr and p.latent_sampler != p.sampler_name else None, "Denoising strength": p.denoising_strength if p.enable_hr else None, + "Image CFG Scale": p.image_cfg_scale, # sdnext "Backend": 'Diffusers' if shared.backend == shared.Backend.DIFFUSERS else 'Original', "Version": git_commit, diff --git a/modules/processing_diffusers.py b/modules/processing_diffusers.py index ab104b11c..fa14a480e 100644 --- a/modules/processing_diffusers.py +++ b/modules/processing_diffusers.py @@ -1,6 +1,8 @@ import inspect import typing import torch +# import numpy as np +# from PIL import Image import modules.devices as devices import modules.shared as shared import modules.sd_samplers as sd_samplers @@ -27,31 +29,59 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro shared.state.sampling_steps = p.steps shared.state.current_latent = latents - def vae_decode(latents, model, output_type='np'): - if hasattr(model, 'vae') and torch.is_tensor(latents): - if latents.shape[0] == 0: - shared.log.error(f'VAE nothing to decode: {latents.shape}') - return [] - shared.log.debug(f'Diffusers VAE decode: name={sd_vae.loaded_vae_file} dtype={model.vae.dtype} upcast={model.vae.config.get("force_upcast", None)} images={latents.shape[0]}') - if shared.opts.diffusers_move_unet and not model.has_accelerate: - shared.log.debug('Diffusers: Moving UNet to CPU') - unet_device = model.unet.device - model.unet.to(devices.cpu) - devices.torch_gc() - latents.to(model.vae.device) - decoded = model.vae.decode(latents / model.vae.config.scaling_factor, return_dict=False)[0] - imgs = model.image_processor.postprocess(decoded, output_type=output_type) - if shared.opts.diffusers_move_unet and not model.has_accelerate: - model.unet.to(unet_device) - return imgs - else: + def hires_resize(latents): + return latents # TODO finish hires + if p.hr_upscaler == 'None': return latents + scale = shared.latent_upscale_modes.get(p.hr_upscaler, None) + if scale is not None: + p.init_hr() + p.ops.append('hires') + shared.log.info(f'Diffusers Hires: upscaler={p.hr_upscaler} mode={scale["mode"]} antialias={scale["antialias"]} width={p.hr_upscale_to_x} height={p.hr_upscale_to_y} images={latents.shape[0]}') + hires_image = torch.nn.functional.interpolate(latents, size=(p.hr_upscale_to_y // 8, p.hr_upscale_to_x // 8), mode=scale["mode"], antialias=scale["antialias"]) + else: + shared.log.warning(f'Diffusers hires unsupported: upscaler={p.hr_upscaler} supported=latent modes') + hires_image = latents + return hires_image - def taesd_vae_decode(latents, model, output_type='np'): - shared.log.debug('Diffusers VAE decode: name=TAESD') + def full_vae_decode(latents, model): + shared.log.debug(f'Diffusers VAE decode: 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)} images={latents.shape[0]}') + if shared.opts.diffusers_move_unet and not model.has_accelerate: + shared.log.debug('Diffusers: Moving UNet to CPU') + unet_device = model.unet.device + model.unet.to(devices.cpu) + devices.torch_gc() + latents.to(model.vae.device) + 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: + model.unet.to(unet_device) + return decoded + + def taesd_vae_decode(latents): + shared.log.debug(f'Diffusers VAE decode: name=TAESD images={latents.shape[0]}') decoded = torch.zeros((len(latents), 3, p.height, p.width), dtype=devices.dtype_vae, device=devices.device) for i in range(len(output.images)): decoded[i] = (sd_vae_taesd.decode(latents[i]) * 2.0) - 1.0 + return decoded + + def vae_decode(latents, model, output_type='np', full_quality=True): + if shared.state.interrupted or shared.state.skipped: + return [] + if not hasattr(model, 'vae'): + shared.log.error('VAE not found in model') + return [] + if not torch.is_tensor(latents): + shared.log.error(f'VAE input is not latents: {type(latents)}') + return [] + if latents.shape[0] == 0: + shared.log.error(f'VAE nothing to decode: {latents.shape}') + return [] + if p.enable_hr: + latents = hires_resize(latents=latents) + if full_quality: + decoded = full_vae_decode(latents=latents, model=shared.sd_model) + else: + decoded = taesd_vae_decode(latents=latents) imgs = model.image_processor.postprocess(decoded, output_type=output_type) return imgs @@ -86,7 +116,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro negative_embed = None negative_pooled = None prompts, negative_prompts, prompts_2, negative_prompts_2 = fix_prompts(prompts, negative_prompts, prompts_2, negative_prompts_2) - if shared.opts.data['prompt_attention'] in {'Compel parser', 'Full parser'}: + if shared.opts.prompt_attention in {'Compel parser', 'Full parser'}: prompt_embed, pooled, negative_embed, negative_pooled = prompt_parser_diffusers.compel_encode_prompts(model, prompts, negative_prompts, @@ -216,19 +246,18 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro unload_diffusers_lora() return results - if shared.sd_refiner is None or not p.enable_hr: - output.images = vae_decode(output.images, shared.sd_model) if p.full_quality else taesd_vae_decode(output.images, shared.sd_model) - if lora_state['active']: p.extra_generation_params['Lora method'] = shared.opts.diffusers_lora_loader unload_diffusers_lora() - if refiner_enabled: - for i in range(len(output.images)): + if not refiner_enabled: + results = vae_decode(latents=output.images, model=shared.sd_model, full_quality=p.full_quality) + else: + for i in range(len(output.images)): # save images before refiner if shared.opts.save and not p.do_not_save_samples and shared.opts.save_images_before_refiner and hasattr(shared.sd_model, 'vae'): from modules.processing import create_infotext info=create_infotext(p, p.all_prompts, p.all_seeds, p.all_subseeds, [], iteration=p.iteration, position_in_batch=i) - decoded = vae_decode(output.images, shared.sd_model, output_type='pil') + decoded = vae_decode(latents=output.images, model=shared.sd_model, output_type='pil', full_quality=p.full_quality) for i in range(len(decoded)): images.save_image(decoded[i], path=p.outpath_samples, basename="", seed=seeds[i], prompt=prompts[i], extension=shared.opts.samples_format, info=info, p=p, suffix="-before-refiner") @@ -267,22 +296,17 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro clip_skip=p.clip_skip, ) refiner_output = shared.sd_refiner(**pipe_args) # pylint: disable=not-callable - p.extra_generation_params['Refiner CFG scale'] = p.image_cfg_scale if p.image_cfg_scale is not None else None + p.extra_generation_params['Image CFG scale'] = p.image_cfg_scale if p.image_cfg_scale is not None else None p.extra_generation_params['Refiner start'] = p.refiner_start p.extra_generation_params["Hires steps"] = p.hr_second_pass_steps if not shared.state.interrupted and not shared.state.skipped: - refiner_images = vae_decode(refiner_output.images, shared.sd_refiner) + refiner_images = vae_decode(latents=refiner_output.images, model=shared.sd_refiner, full_quality=True) results.append(refiner_images[0]) if shared.opts.diffusers_move_refiner and not shared.sd_refiner.has_accelerate: shared.log.debug('Diffusers: Moving refiner model to CPU') shared.sd_refiner.to(devices.cpu) devices.torch_gc() - else: - results = output.images - - if p.is_hr_pass: - shared.log.warning('Diffusers not implemented: hires fix') return results diff --git a/modules/prompt_parser_diffusers.py b/modules/prompt_parser_diffusers.py index 27dd423de..f8c2afde8 100644 --- a/modules/prompt_parser_diffusers.py +++ b/modules/prompt_parser_diffusers.py @@ -88,7 +88,7 @@ def compel_encode_prompt( if clip_skip not in CLIP_SKIP_MAPPING: shared.log.warning(f"Prompt parser unsupported: clip_skip={clip_skip} expected={set(CLIP_SKIP_MAPPING.keys())}") - if shared.opts.data["prompt_attention"] != "Compel parser": + if shared.opts.prompt_attention != "Compel parser": prompt = convert_to_compel(prompt) negative_prompt = convert_to_compel(negative_prompt) prompt_2 = convert_to_compel(prompt_2) diff --git a/modules/sd_models.py b/modules/sd_models.py index 1cf408a96..03325d4a9 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -2,6 +2,7 @@ import collections import os.path import re import io +import sys import json import threading from os import mkdir @@ -240,7 +241,10 @@ def select_checkpoint(op='model'): return None checkpoint_info = next(iter(checkpoints_list.values())) if model_checkpoint is not None: - shared.log.warning(f"Selected checkpoint not found: {model_checkpoint}") + if model_checkpoint != 'model.ckpt' and model_checkpoint != 'runwayml/stable-diffusion-v1-5': + shared.log.warning(f"Selected checkpoint not found: {model_checkpoint}") + else: + shared.log.info("Selecting first available checkpoint") # shared.log.warning(f"Loading fallback checkpoint: {checkpoint_info.title}") shared.opts.data['sd_checkpoint'] = checkpoint_info.title shared.log.debug(f'Select checkpoint: {checkpoint_info.title if checkpoint_info is not None else None}') @@ -455,7 +459,7 @@ def repair_config(sd_config): if shared.opts.no_half: sd_config.model.params.unet_config.params.use_fp16 = False elif shared.opts.upcast_sampling: - sd_config.model.params.unet_config.params.use_fp16 = True + sd_config.model.params.unet_config.params.use_fp16 = True if sys.platform != 'darwin' else False if getattr(sd_config.model.params.first_stage_config.params.ddconfig, "attn_type", None) == "vanilla-xformers" and not shared.xformers_available: sd_config.model.params.first_stage_config.params.ddconfig.attn_type = "vanilla" # For UnCLIP-L, override the hardcoded karlo directory diff --git a/modules/sd_samplers_diffusers.py b/modules/sd_samplers_diffusers.py index 6dbd5707e..7e34b30ed 100644 --- a/modules/sd_samplers_diffusers.py +++ b/modules/sd_samplers_diffusers.py @@ -22,8 +22,8 @@ except Exception as e: log.error(f'Diffusers import error: version={diffusers.__version__} error: {e}') config = { - # TODO beta_start, beta_end are typically per-scheduler, but we don't want them as they should be taken from the model itself as those are values model was trained on - # TODO prediction_type is ideally set in model as well, but it maybe needed that we do auto-detect of model type in the future + # beta_start, beta_end are typically per-scheduler, but we don't want them as they should be taken from the model itself as those are values model was trained on + # prediction_type is ideally set in model as well, but it maybe needed that we do auto-detect of model type in the future 'All': { 'num_train_timesteps': 1000, 'beta_start': 0.0001, 'beta_end': 0.02, 'beta_schedule': 'linear', 'prediction_type': 'epsilon' }, 'DDIM': { 'clip_sample': True, 'set_alpha_to_one': True, 'steps_offset': 0, 'thresholding': False, 'clip_sample_range': 1.0, 'sample_max_value': 1.0, 'timestep_spacing': 'linspace', 'rescale_betas_zero_snr': False }, 'DDPM': { 'variance_type': "fixed_small", 'clip_sample': True, 'thresholding': False, 'clip_sample_range': 1.0, 'sample_max_value': 1.0, 'timestep_spacing': 'linspace'}, diff --git a/modules/sd_samplers_kdiffusion.py b/modules/sd_samplers_kdiffusion.py index 3a05ab1f1..2134ed0d7 100644 --- a/modules/sd_samplers_kdiffusion.py +++ b/modules/sd_samplers_kdiffusion.py @@ -292,10 +292,12 @@ class KDiffusionSampler: def get_sigmas(self, p, steps): discard_next_to_last_sigma = self.config is not None and self.config.options.get('discard_next_to_last_sigma', False) - if opts.always_discard_next_to_last_sigma and not discard_next_to_last_sigma: + if opts.always_discard_next_to_last_sigma: discard_next_to_last_sigma = True p.extra_generation_params["Discard penultimate sigma"] = True - + if opts.never_discard_next_to_last_sigma: + discard_next_to_last_sigma = False + p.extra_generation_params["Discard penultimate sigma"] = False steps += 1 if discard_next_to_last_sigma else 0 if p.sampler_noise_scheduler_override: diff --git a/modules/shared.py b/modules/shared.py index de66b56c8..b1fcb7de4 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -45,7 +45,7 @@ pipelines = [ 'Stable Diffusion', 'Stable Diffusion XL', 'Kandinsky V1', 'Kandinsky V2', 'DeepFloyd IF', 'Shap-E', 'Stable Diffusion Img2Img', 'Stable Diffusion XL Img2Img', 'Kandinsky V1 Img2Img', 'Kandinsky V2 Img2Img', 'DeepFloyd IF Img2Img', 'Shap-E Img2Img' ] -latent_upscale_default_mode = "Latent" +latent_upscale_default_mode = "None" latent_upscale_modes = { "Latent": {"mode": "bilinear", "antialias": False}, "Latent (antialiased)": {"mode": "bilinear", "antialias": True}, @@ -302,6 +302,8 @@ def readfile(filename, silent=False): with fasteners.InterProcessLock(f"{filename}.lock"): with open(filename, "r", encoding="utf8") as file: data = json.load(file) + if type(data) is str: + data = json.loads(data) if not silent: log.debug(f'Reading: {filename} len={len(data)}') except Exception as e: @@ -558,6 +560,7 @@ options_templates.update(options_section(('sampler-params', "Sampler Settings"), 's_tmin': OptionInfo(0.0, "sigma tmin", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), 's_noise': OptionInfo(1.0, "sigma noise", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.01}), 'always_discard_next_to_last_sigma': OptionInfo(False, "Always discard next-to-last sigma"), + 'never_discard_next_to_last_sigma': OptionInfo(False, "Never discard next-to-last sigma"), "schedulers_sep_compvis": OptionInfo("

CompVis specific config

", "", gr.HTML), "ddim_discretize": OptionInfo('uniform', "DDIM discretize img2img", gr.Radio, {"choices": ['uniform', 'quad']}), @@ -672,6 +675,8 @@ class Options: def set(self, key, value): """sets an option and calls its onchange callback, returning True if the option changed and False otherwise""" oldval = self.data.get(key, None) + if oldval is None: + oldval = self.data_labels[key].default if oldval == value: return False try: @@ -699,10 +704,14 @@ class Options: log.warning(f'Settings saving is disabled: {filename}') return try: - output = json.dumps(self.data, indent=2) - log.debug(f'Saving settings: {filename} len={len(output)}') - with open(filename, "w", encoding="utf8") as file: - file.write(output) + # output = json.dumps(self.data, indent=2) + diff = {} + for k, v in self.data.items(): + if k in self.data_labels: + if self.data_labels[k].default != v: + diff[k] = v + output = json.dumps(diff, indent=2) + writefile(output, filename) except Exception as e: log.error(f'Saving settings failed: {filename} {e}') diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py index 25345a35a..83d559cbd 100644 --- a/modules/textual_inversion/textual_inversion.py +++ b/modules/textual_inversion/textual_inversion.py @@ -141,7 +141,7 @@ class EmbeddingDatabase: name = os.path.basename(fn) embedding = Embedding(vec=None, name=name) try: - pipe.load_textual_inversion(path, cache_dir=shared.opts.data["diffusers_dir"], local_files_only=True) + pipe.load_textual_inversion(path, cache_dir=shared.opts.diffusers_dir, local_files_only=True) self.word_embeddings[name] = embedding except Exception: self.skipped_embeddings[name] = embedding diff --git a/modules/ui.py b/modules/ui.py index 5e87b070b..b9a07566d 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -93,7 +93,7 @@ def calc_resolution_hires(enable, width, height, hr_scale, hr_resize_x, hr_resiz if not enable: return "" if modules.shared.backend == modules.shared.Backend.DIFFUSERS: - return "Hires resize: disabled" + return "Hires resize: disabled" p = processing.StableDiffusionProcessingTxt2Img(width=width, height=height, enable_hr=True, hr_scale=hr_scale, hr_resize_x=hr_resize_x, hr_resize_y=hr_resize_y) p.init_hr() with devices.autocast(): @@ -107,7 +107,7 @@ def resize_from_to_html(width, height, scale_by): if not target_width or not target_height: return "no image selected" if modules.shared.backend == modules.shared.Backend.DIFFUSERS: - return "Hires resize: disabled" + return "Hires resize: disabled" return f"Hires resize: from {width}x{height} to {target_width}x{target_height}" @@ -497,6 +497,12 @@ def create_ui(startup_timer = None): (hr_second_pass_steps, "Secondary steps"), (hr_resize_x, "Hires resize-1"), (hr_resize_y, "Hires resize-2"), + (diffusers_guidance_rescale, "CFG rescale"), + (image_cfg_scale, "Refiner CFG scale"), + (refiner_start, "Refiner start"), + (tiling, "Tiling"), + (refiner_negative, "Negative2"), + (refiner_prompt, "Prompt2"), *modules.scripts.scripts_txt2img.infotext_fields ] parameters_copypaste.add_paste_fields("txt2img", None, txt2img_paste_fields, override_settings) @@ -661,7 +667,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") - refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise start', value=0.0, elem_id="txt2img_refiner_start") + 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: with FormRow(): @@ -822,7 +828,6 @@ def create_ui(startup_timer = None): negative_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[img2img_negative_prompt, steps], outputs=[negative_token_counter]) ui_extra_networks.setup_ui(extra_networks_ui_img2img, img2img_gallery) - img2img_paste_fields = [ (img2img_prompt, "Prompt"), (img2img_negative_prompt, "Negative prompt"), @@ -838,6 +843,7 @@ def create_ui(startup_timer = None): (latent_index, "Latent sampler"), (denoising_strength, "Denoising strength"), (refiner_start, "Refiner start"), + (full_quality, "Full quality"), # TODO (restore_faces, "Face restoration"), (batch_size, "Batch size"), (batch_count, "Batch count"), @@ -849,7 +855,12 @@ def create_ui(startup_timer = None): (hr_second_pass_steps, "Secondary steps"), (hr_resize_x, "Hires resize-1"), (hr_resize_y, "Hires resize-2"), + (diffusers_guidance_rescale, "CFG rescale"), (image_cfg_scale, "Image CFG scale"), + (refiner_start, "Refiner start"), + (tiling, "Tiling"), + (refiner_negative, "Negative2"), + (refiner_prompt, "Prompt2"), (mask_blur, "Mask blur"), *modules.scripts.scripts_img2img.infotext_fields ] @@ -932,12 +943,7 @@ def create_ui(startup_timer = None): return [getattr(opts, _key) for _key in keys_to_reset] elements_to_reset = [component_dict[_key] for _key in keys_to_reset] - indicator = gr.Button( - "", - elem_classes="modification-indicator", - elem_id="modification_indicator_" + key, - **kwargs - ) + indicator = gr.Button("", elem_classes="modification-indicator", elem_id="modification_indicator_" + key, **kwargs) indicator.click(fn=get_opt_values, outputs=elements_to_reset, show_progress=False) return indicator diff --git a/requirements.txt b/requirements.txt index 0f0644c95..373984093 100644 --- a/requirements.txt +++ b/requirements.txt @@ -35,7 +35,6 @@ scipy tb_nightly toml torchdiffeq -torchsde voluptuous yapf scikit-image diff --git a/wiki b/wiki index 7cc5b14e1..625f3d53f 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 7cc5b14e12d61fcdc904989a99eb9b01743575bd +Subproject commit 625f3d53f99babf329166268b4c4c0c4c209801b