From cf7118be4df0e91565055ad2951ff03b56441cda Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Wed, 21 Feb 2024 17:13:53 -0500 Subject: [PATCH] refactor stable-cascade, fix taesd bf16, add skip-env cmd flag --- CHANGELOG.md | 4 +- TODO.md | 1 + cli/run-benchmark.py | 2 +- html/reference.json | 6 ++ installer.py | 1 + launch.py | 3 +- .../Reference/stabilityai--stable-cascade.jpg | Bin 0 -> 40176 bytes modules/modelloader.py | 2 + modules/processing_diffusers.py | 63 +++++++++++------- modules/sd_hijack_accelerate.py | 6 ++ modules/sd_models.py | 45 +++++++++---- modules/sd_samplers_common.py | 5 +- ...e_previewer.py => sd_vae_stablecascade.py} | 3 +- modules/sd_vae_taesd.py | 6 +- modules/ui_sections.py | 2 +- wiki | 2 +- 16 files changed, 100 insertions(+), 51 deletions(-) create mode 100644 models/Reference/stabilityai--stable-cascade.jpg rename modules/{sd_cascade_previewer.py => sd_vae_stablecascade.py} (98%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f92845ab..1e2579884 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log for SD.Next -## Update for 2024-02-20 +## Update for 2024-02-21 - **Improvements**: - **IP Adapter** major refactor @@ -78,6 +78,7 @@ see *settings -> compute settings* - **Fixes**: - add variation seed to diffusers txt2img, thanks @AI-Casanova + - add cmd param `--skip-env` to skip setting of environment parameters during sdnext load - handle extensions that install conflicting versions of packages `onnxruntime`, `opencv2-python` - installer refresh package cache on any install @@ -100,6 +101,7 @@ - fix controlnet inpaint mask - fix theme list refresh - fix extensions update information in ui + - fix taesd with bfloat16 - fix model merge manual merge settings, thanks @AI-Casanova - fix gradio instant update issues for textboxes in quicksettings - bind controlnet extension to last known working commit, thanks @Aptronymist diff --git a/TODO.md b/TODO.md index a2863e1b2..f27044535 100644 --- a/TODO.md +++ b/TODO.md @@ -11,6 +11,7 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma - diffusers public callbacks - image2video: pia and vgen pipelines - video2video +- async lowvram: ## Control missing features diff --git a/cli/run-benchmark.py b/cli/run-benchmark.py index afa8d5709..2b09966de 100755 --- a/cli/run-benchmark.py +++ b/cli/run-benchmark.py @@ -98,7 +98,7 @@ async def main(): if i == 0: log.info({ 'warmup': round(ts, 2) }) else: - peak = gpu['session']['peak'] if 'session' in gpu else 0 + peak = gpu['system']['used'] # gpu['session']['peak'] if 'session' in gpu else 0 log.info({ 'batch': batch[i], 'its': round(options.steps / (ts / batch[i]), 2), 'img': round(ts / batch[i], 2), 'wall': round(ts, 2), 'peak': gb(peak), 'oom': oom > 0 }) else: await asyncio.sleep(10) diff --git a/html/reference.json b/html/reference.json index 0d48447fd..f05fee1fe 100644 --- a/html/reference.json +++ b/html/reference.json @@ -73,6 +73,12 @@ "desc": "(SVD) Image-to-Video is a latent diffusion model trained to generate short video clips from an image conditioning. This model was trained to generate 25 frames at resolution 576x1024 given a context frame of the same size, finetuned from SVD Image-to-Video [14 frames]. We also finetune the widely used f8-decoder for temporal consistency.", "preview": "stabilityai--stable-video-diffusion-img2vid-xt.jpg" }, + "StabilityAI Stable Cascade": { + "path": "huggingface/stabilityai/stable-cascade", + "skip": true, + "desc": "Stable Cascade is a diffusion model built upon the Würstchen architecture and its main difference to other models like Stable Diffusion is that it is working at a much smaller latent space. Why is this important? The smaller the latent space, the faster you can run inference and the cheaper the training becomes. How small is the latent space? Stable Diffusion uses a compression factor of 8, resulting in a 1024x1024 image being encoded to 128x128. Stable Cascade achieves a compression factor of 42, meaning that it is possible to encode a 1024x1024 image to 24x24, while maintaining crisp reconstructions. The text-conditional model is then trained in the highly compressed latent space. Previous versions of this architecture, achieved a 16x cost reduction over Stable Diffusion 1.5", + "preview": "stabilityai--stable-cascade.jpg" + }, "Segmind Vega": { "path": "segmind/Segmind-Vega", "desc": "The Segmind-Vega Model is a distilled version of the Stable Diffusion XL (SDXL), offering a remarkable 70% reduction in size and an impressive 100% speedup while retaining high-quality text-to-image generation capabilities. Trained on diverse datasets, including Grit and Midjourney scrape data, it excels at creating a wide range of visual content based on textual prompts. Employing a knowledge distillation strategy, Segmind-Vega leverages the teachings of several expert models, including SDXL, ZavyChromaXL, and JuggernautXL, to combine their strengths and produce compelling visual outputs.", diff --git a/installer.py b/installer.py index b61e75466..b8051072b 100644 --- a/installer.py +++ b/installer.py @@ -975,6 +975,7 @@ def add_args(parser): group.add_argument('--skip-git', default = os.environ.get("SD_SKIPGIT",False), action='store_true', help = "Skips running all GIT operations, default: %(default)s") group.add_argument('--skip-torch', default = os.environ.get("SD_SKIPTORCH",False), action='store_true', help = "Skips running Torch checks, default: %(default)s") group.add_argument('--skip-all', default = os.environ.get("SD_SKIPALL",False), action='store_true', help = "Skips running all checks, default: %(default)s") + group.add_argument('--skip-env', default = os.environ.get("SD_SKIPENV",False), action='store_true', help = "Skips setting of env variables during startup, default: %(default)s") group.add_argument('--experimental', default = os.environ.get("SD_EXPERIMENTAL",False), action='store_true', help = "Allow unsupported versions of libraries, default: %(default)s") group.add_argument('--reinstall', default = os.environ.get("SD_REINSTALL",False), action='store_true', help = "Force reinstallation of all requirements, default: %(default)s") group.add_argument('--test', default = os.environ.get("SD_TEST",False), action='store_true', help = "Run test only and exit") diff --git a/launch.py b/launch.py index 52ce0103b..5533ce22f 100755 --- a/launch.py +++ b/launch.py @@ -202,7 +202,8 @@ def main(): installer.log.info('Skipping GIT operations') installer.check_version() installer.log.info(f'Platform: {installer.print_dict(installer.get_platform())}') - installer.set_environment() + if not args.skip_env: + installer.set_environment() installer.check_torch() installer.check_onnx() installer.check_modified_files() diff --git a/models/Reference/stabilityai--stable-cascade.jpg b/models/Reference/stabilityai--stable-cascade.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c0112259678c407b071076924c0762ebd0ddb55f GIT binary patch literal 40176 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 literal 0 HcmV?d00001 diff --git a/modules/modelloader.py b/modules/modelloader.py index 1c696f777..36e7435f8 100644 --- a/modules/modelloader.py +++ b/modules/modelloader.py @@ -302,6 +302,8 @@ def load_reference(name: str): if v.get('path', '') == name: model_opts = v break + if model_opts.get('skip', False): + return True model_dir = download_diffusers_model( hub_id=name, cache_dir=shared.opts.diffusers_dir, diff --git a/modules/processing_diffusers.py b/modules/processing_diffusers.py index 16c86024b..e04513398 100644 --- a/modules/processing_diffusers.py +++ b/modules/processing_diffusers.py @@ -165,7 +165,7 @@ def process_diffusers(p: processing.StableDiffusionProcessing): if hasattr(model, 'pipe'): # recurse model = model.pipe signature = inspect.signature(type(model).__call__, follow_wrapped=True) - possible = signature.parameters.keys() + possible = list(signature.parameters) debug(f'Diffusers pipeline possible: {possible}') if shared.opts.diffusers_generator_device == "Unset": generator_device = None @@ -179,15 +179,16 @@ def process_diffusers(p: processing.StableDiffusionProcessing): prompts, negative_prompts, prompts_2, negative_prompts_2 = fix_prompts(prompts, negative_prompts, prompts_2, negative_prompts_2) parser = 'Fixed attention' clip_skip = kwargs.pop("clip_skip", 1) + steps = kwargs.get("num_inference_steps", 1) if shared.opts.prompt_attention != 'Fixed attention' and 'StableDiffusion' in model.__class__.__name__ and 'Onnx' not in model.__class__.__name__: try: - prompt_parser_diffusers.encode_prompts(model, p, prompts, negative_prompts, steps=kwargs.get("num_inference_steps", 1), clip_skip=clip_skip) + prompt_parser_diffusers.encode_prompts(model, p, prompts, negative_prompts, steps=steps, clip_skip=clip_skip) parser = shared.opts.prompt_attention except Exception as e: shared.log.error(f'Prompt parser encode: {e}') if os.environ.get('SD_PROMPT_DEBUG', None) is not None: errors.display(e, 'Prompt parser encode') - if parser == 'Fixed attention': + if 'clip_skip' in possible and parser == 'Fixed attention': if clip_skip == 1: pass # clip_skip = None else: @@ -211,17 +212,7 @@ def process_diffusers(p: processing.StableDiffusionProcessing): model.scheduler.noise_sampler_seed = p.seeds[0] # some schedulers have internal noise generator and do not use pipeline generator if 'noise_sampler_seed' in possible: args['noise_sampler_seed'] = p.seeds[0] - if hasattr(model, "decoder") and hasattr(model, "prior_prior") and 'prior_num_inference_steps' in possible: - steps = kwargs.pop("num_inference_steps", 20) - args["prior_num_inference_steps"] = steps - args["num_inference_steps"] = max(int(steps / 2), 1) - if hasattr(model, "decoder") and hasattr(model, "prior_prior") and 'prior_guidance_scale' in possible: - cfg_scale = kwargs.pop("guidance_scale", p.cfg_scale) - args["prior_guidance_scale"] = cfg_scale - # Using decoder_guidance_scale causes "Expected all tensors to be on the same device" errors right now - # Enabling model cpu offload fixes the error above - #args["decoder_guidance_scale"] = 0.0 - elif 'guidance_scale' in possible: + if 'guidance_scale' in possible: args['guidance_scale'] = p.cfg_scale if 'generator' in possible and generator is not None: args['generator'] = generator @@ -230,18 +221,40 @@ def process_diffusers(p: processing.StableDiffusionProcessing): if 'output_type' in possible: if hasattr(model, 'vae'): args['output_type'] = 'np' # only set latent if model has vae + + # stable cascade + if 'StableCascade' in model.__class__.__name__: + kwargs.pop("guidance_scale") # remove + kwargs.pop("num_inference_steps") # remove + if 'prior_num_inference_steps' in possible: + args["prior_num_inference_steps"] = p.steps + args["num_inference_steps"] = p.refiner_steps + if 'prior_guidance_scale' in possible: + args["prior_guidance_scale"] = p.cfg_scale + if 'decoder_guidance_scale' in possible: + args["decoder_guidance_scale"] = p.image_cfg_scale + # TODO Stable Cascade callbacks are currently broken in combined pipeline so preview will not get triggered + if 'prior_callback_on_step_end' in possible: + possible.remove('callback_on_step_end') + if 'callback_on_step_end' in possible: + possible.remove('callback_on_step_end') + if 'callback' in possible: + possible.remove('callback') + + # set callbacks if 'callback_steps' in possible: args['callback_steps'] = 1 - if 'callback' in possible: - args['callback'] = diffusers_callback_legacy - elif 'callback_on_step_end_tensor_inputs' in possible: - if hasattr(model, "decoder") and hasattr(model, "prior_prior") and 'prior_guidance_scale' in possible: - args['prior_callback_on_step_end'] = diffusers_callback + if 'callback_on_step_end' in possible: args['callback_on_step_end'] = diffusers_callback - if 'prompt_embeds' in possible and 'negative_prompt_embeds' in possible and hasattr(model, '_callback_tensor_inputs'): - args['callback_on_step_end_tensor_inputs'] = model._callback_tensor_inputs # pylint: disable=protected-access - else: - args['callback_on_step_end_tensor_inputs'] = ['latents'] + if 'callback_on_step_end_tensor_inputs' in possible: + if 'prompt_embeds' in possible and 'negative_prompt_embeds' in possible and hasattr(model, '_callback_tensor_inputs'): + args['callback_on_step_end_tensor_inputs'] = model._callback_tensor_inputs # pylint: disable=protected-access + else: + args['callback_on_step_end_tensor_inputs'] = ['latents'] + elif 'callback' in possible: + args['callback'] = diffusers_callback_legacy + + # handle remaining args for arg in kwargs: if arg in possible: # add kwargs args[arg] = kwargs[arg] @@ -261,6 +274,8 @@ def process_diffusers(p: processing.StableDiffusionProcessing): debug(f'Diffusers unknown task args: {k}={v}') sd_hijack_hypertile.hypertile_set(p, hr=len(getattr(p, 'init_images', [])) > 0) + + # debug info clean = args.copy() clean.pop('callback', None) clean.pop('callback_steps', None) @@ -284,8 +299,6 @@ def process_diffusers(p: processing.StableDiffusionProcessing): txt += f' Clamp threshold={p.hdr_threshold} boundary={p.hdr_boundary}' if p.hdr_clamp else ' Clamp off' txt += f' Maximize boundary={p.hdr_max_boundry} center={p.hdr_max_center}' if p.hdr_maximize else ' Maximize off' shared.log.debug(txt) - # components = [{ k: getattr(v, 'device', None) } for k, v in model.components.items()] - # shared.log.debug(f'Diffuser pipeline components: {components}') if shared.cmd_opts.profile: t1 = time.time() shared.log.debug(f'Profile: pipeline args: {t1-t0:.2f}') diff --git a/modules/sd_hijack_accelerate.py b/modules/sd_hijack_accelerate.py index c1f1b2614..c1d8429b5 100644 --- a/modules/sd_hijack_accelerate.py +++ b/modules/sd_hijack_accelerate.py @@ -58,3 +58,9 @@ def hijack_accelerate(): def restore_accelerate(): accelerate.utils.set_module_tensor_to_device = orig_method + + +def hijack_hfhub(): + import contextlib + import huggingface_hub.file_download + huggingface_hub.file_download.FileLock = contextlib.nullcontext diff --git a/modules/sd_models.py b/modules/sd_models.py index c2d3ecb34..01a847439 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -20,7 +20,7 @@ from omegaconf import OmegaConf import tomesd from transformers import logging as transformers_logging from ldm.util import instantiate_from_config -from modules import paths, shared, shared_items, shared_state, modelloader, devices, script_callbacks, sd_vae, errors, hashes, sd_models_config, sd_models_compile +from modules import paths, shared, shared_items, shared_state, modelloader, devices, script_callbacks, sd_vae, errors, hashes, sd_models_config, sd_models_compile, sd_hijack_accelerate from modules.timer import Timer from modules.memstats import memory_stats from modules.paths import models_path, script_path @@ -123,6 +123,7 @@ class NoWatermark: def setup_model(): list_models() + sd_hijack_accelerate.hijack_hfhub() if shared.backend == shared.Backend.ORIGINAL: enable_midas_autodownload() @@ -189,6 +190,11 @@ def update_model_hashes(): def get_closet_checkpoint_match(search_string): + if search_string.startswith('huggingface/'): + model_name = search_string.replace('huggingface/', '') + checkpoint_info = CheckpointInfo(model_name) # create a virutal model info + checkpoint_info.type = 'huggingface' + return checkpoint_info checkpoint_info = checkpoint_aliases.get(search_string, None) if checkpoint_info is not None: return checkpoint_info @@ -813,23 +819,31 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No shared.log.debug(f'Diffusers loading: path="{checkpoint_info.path}"') pipeline, model_type = detect_pipeline(checkpoint_info.path, op) - if os.path.isdir(checkpoint_info.path): + if os.path.isdir(checkpoint_info.path) or checkpoint_info.type == 'huggingface': files = shared.walk_files(checkpoint_info.path, ['.safetensors', '.bin', '.ckpt']) if 'variant' not in diffusers_load_config and any('diffusion_pytorch_model.fp16' in f for f in files): # deal with diffusers lack of variant fallback when loading diffusers_load_config['variant'] = 'fp16' if model_type in ['Stable Cascade']: # forced pipeline + # TODO experimental stable cascade try: - # TODO: Add decoder and vqgan loader - # vqgan can reuse the vae loader ui - # decoder needs a new loader - vae_file = diffusers_load_config.pop("vae", None) - prior_model = "stabilityai/stable-cascade-prior" if "models--stabilityai--stable-cascade" in checkpoint_info.path and "models--stabilityai--stable-cascade-prior" not in checkpoint_info.path else checkpoint_info.path - decoder_model = "stabilityai/stable-cascade" if vae_file is None else vae_file - prior = diffusers.StableCascadePriorPipeline.from_pretrained(prior_model, cache_dir=shared.opts.diffusers_dir, **diffusers_load_config) # pylint: disable=no-member - decoder = diffusers.StableCascadeDecoderPipeline.from_pretrained(decoder_model, cache_dir=shared.opts.diffusers_dir, **diffusers_load_config) # pylint: disable=no-member - sd_model = diffusers.StableCascadeCombinedPipeline(tokenizer=decoder.tokenizer, text_encoder=decoder.text_encoder, decoder=decoder.decoder, scheduler=decoder.scheduler, vqgan=decoder.vqgan, prior_prior=prior.prior, prior_scheduler=prior.scheduler, feature_extractor=prior.feature_extractor, image_encoder=prior.image_encoder) # pylint: disable=no-member + diffusers_load_config.pop("vae", None) + diffusers_load_config.pop("variant", None) + decoder = diffusers.StableCascadeDecoderPipeline.from_pretrained("stabilityai/stable-cascade", cache_dir=shared.opts.diffusers_dir, revision="refs/pr/17", **diffusers_load_config) + prior = diffusers.StableCascadePriorPipeline.from_pretrained("stabilityai/stable-cascade-prior", cache_dir=shared.opts.diffusers_dir, **diffusers_load_config) + sd_model = diffusers.StableCascadeCombinedPipeline( + tokenizer=decoder.tokenizer, + text_encoder=decoder.text_encoder, + decoder=decoder.decoder, + scheduler=decoder.scheduler, + vqgan=decoder.vqgan, + prior_prior=prior.prior, + prior_scheduler=prior.scheduler, + feature_extractor=prior.feature_extractor, + image_encoder=prior.image_encoder) except Exception as e: shared.log.error(f'Diffusers Failed loading {op}: {checkpoint_info.path} {e}') + if debug_load: + errors.display(e, 'Load') return elif model_type in ['InstaFlow']: # forced pipeline try: @@ -837,6 +851,8 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No sd_model = pipeline.from_pretrained(checkpoint_info.path, cache_dir=shared.opts.diffusers_dir, **diffusers_load_config) except Exception as e: shared.log.error(f'Diffusers Failed loading {op}: {checkpoint_info.path} {e}') + if debug_load: + errors.display(e, 'Load') return elif model_type in ['SegMoE']: # forced pipeline try: @@ -845,6 +861,8 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No sd_model = sd_model.pipe # segmoe pipe does its stuff in __init__ and __call__ is the original pipeline except Exception as e: shared.log.error(f'Diffusers Failed loading {op}: {checkpoint_info.path} {e}') + if debug_load: + errors.display(e, 'Load') return elif 'ONNX' in model_type: # forced pipeline sd_model = pipeline.from_pretrained(checkpoint_info.path) @@ -913,11 +931,10 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No if shared.opts.disable_accelerate: from diffusers.utils import import_utils import_utils._accelerate_available = False # pylint: disable=protected-access - import modules.sd_hijack_accelerate if shared.opts.diffusers_to_gpu: - modules.sd_hijack_accelerate.hijack_accelerate() + sd_hijack_accelerate.hijack_accelerate() else: - modules.sd_hijack_accelerate.restore_accelerate() + sd_hijack_accelerate.restore_accelerate() sd_model = pipeline.from_single_file(checkpoint_info.path, **diffusers_load_config) if sd_model is not None and hasattr(sd_model, 'unet') and hasattr(sd_model.unet, 'config') and 'inpainting' in checkpoint_info.path.lower(): shared.log.debug('Model patch: type=inpaint') diff --git a/modules/sd_samplers_common.py b/modules/sd_samplers_common.py index 6fadfdcfd..a2b79db1e 100644 --- a/modules/sd_samplers_common.py +++ b/modules/sd_samplers_common.py @@ -3,7 +3,7 @@ from collections import namedtuple import torch import torchvision.transforms as T from PIL import Image -from modules import shared, devices, processing, images, sd_vae_approx, sd_vae_taesd, sd_cascade_previewer, sd_samplers +from modules import shared, devices, processing, images, sd_vae_approx, sd_vae_taesd, sd_vae_stablecascade, sd_samplers SamplerData = namedtuple('SamplerData', ['name', 'constructor', 'aliases', 'options']) @@ -48,6 +48,7 @@ def single_sample_to_image(sample, approximation=None): sd_cascade = True if len(sample.shape) == 4 and sample.shape[0]: # likely animatediff latent sample = sample.permute(1, 0, 2, 3)[0] + if shared.backend == shared.Backend.DIFFUSERS: # [-x,x] to [-5,5] sample_max = torch.max(sample) if sample_max > 5: @@ -56,7 +57,7 @@ def single_sample_to_image(sample, approximation=None): if sample_min < -5: sample = sample * (5 / abs(sample_min)) if sd_cascade: - x_sample = sd_cascade_previewer.decode(sample) + x_sample = sd_vae_stablecascade.decode(sample) elif approximation == 0: # Simple x_sample = sd_vae_approx.cheap_approximation(sample) * 0.5 + 0.5 elif approximation == 1: # Approximate diff --git a/modules/sd_cascade_previewer.py b/modules/sd_vae_stablecascade.py similarity index 98% rename from modules/sd_cascade_previewer.py rename to modules/sd_vae_stablecascade.py index 9690eee7e..44f620a0a 100644 --- a/modules/sd_cascade_previewer.py +++ b/modules/sd_vae_stablecascade.py @@ -1,5 +1,4 @@ import os -import torch from torch import nn import safetensors from modules import devices, paths @@ -69,7 +68,7 @@ def load_model(model_path): def decode(latents): from modules import shared - global preview_model + global preview_model # pylint: disable=global-statement if preview_model is None: model_path = os.path.join(paths.models_path, "VAE-approx", "sd_cascade_previewer.safetensors") download_model(model_path) diff --git a/modules/sd_vae_taesd.py b/modules/sd_vae_taesd.py index 895dce544..fc82acb9d 100644 --- a/modules/sd_vae_taesd.py +++ b/modules/sd_vae_taesd.py @@ -77,7 +77,6 @@ def download_model(model_path): model_name = os.path.basename(model_path) model_url = f'https://github.com/madebyollin/taesd/raw/main/{model_name}' if not os.path.exists(model_path): - import torch from modules.shared import log os.makedirs(os.path.dirname(model_path), exist_ok=True) log.info(f'Downloading TAESD decoder: {model_path}') @@ -109,6 +108,7 @@ def decode(latents): model_class = shared.sd_model_type if model_class == 'ldm': model_class = 'sd' + dtype = devices.dtype_vae if devices.dtype_vae != torch.bfloat16 else torch.float16 # taesd does not support bf16 if 'sd' not in model_class: shared.log.warning(f'TAESD unsupported model type: {model_class}') return Image.new('RGB', (8, 8), color = (0, 0, 0)) @@ -120,10 +120,10 @@ def decode(latents): taesd_models[f'{model_class}-decoder'] = TAESD(decoder_path=model_path, encoder_path=None) shared.log.debug(f'VAE load: type=taesd model={model_path}') vae = taesd_models[f'{model_class}-decoder'] - vae.decoder.to(devices.device, devices.dtype_vae) + vae.decoder.to(devices.device, dtype) try: with devices.inference_context(): - latents = latents.detach().clone().to(devices.device, devices.dtype_vae) + latents = latents.detach().clone().to(devices.device, dtype) if len(latents.shape) == 3: latents = latents.unsqueeze(0) image = vae.decoder(latents).clamp(0, 1).detach() diff --git a/modules/ui_sections.py b/modules/ui_sections.py index 7840789f5..f5ccb41de 100644 --- a/modules/ui_sections.py +++ b/modules/ui_sections.py @@ -206,7 +206,7 @@ def create_hires_inputs(tab): with gr.Group(visible=shared.backend == shared.Backend.DIFFUSERS): with gr.Row(elem_id=f"{tab}_refiner_row1", variant="compact"): refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Refiner start', value=0.8, elem_id=f"{tab}_refiner_start") - refiner_steps = gr.Slider(minimum=0, maximum=99, step=1, label="Refiner steps", elem_id=f"{tab}_refiner_steps", value=5) + refiner_steps = gr.Slider(minimum=0, maximum=99, step=1, label="Refiner steps", elem_id=f"{tab}_refiner_steps", value=10) with gr.Row(elem_id=f"{tab}_refiner_row3", variant="compact"): refiner_prompt = gr.Textbox(value='', label='Secondary prompt', elem_id=f"{tab}_refiner_prompt") with gr.Row(elem_id="txt2img_refiner_row4", variant="compact"): diff --git a/wiki b/wiki index 83b5a6083..acb20bf73 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 83b5a60831be6fe70707be9bb7103e4c837e21e9 +Subproject commit acb20bf7379325e9fabb914118b37515ecc76e8f