diff --git a/CHANGELOG.md b/CHANGELOG.md index 4733ce97a..4d7babf93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Update for 2023-08-31 - diffusers: + - ability to interrupt (stop/skip) model generate - add `diffusers_force_zeros` setting create zero-tensor for prompt if prompt is empty (positive or negative) - add `diffusers_aesthetics_score` setting diff --git a/README.md b/README.md index 4a7e8f5c7..3b4ac2972 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,6 @@ All Individual features are not listed here, instead check [ChangeLog](CHANGELOG This is the default backend and it is fully compatible with all existing functionality and extensions - **Diffusers**: Based on new [Huggingface Diffusers](https://huggingface.co/docs/diffusers/index) implementation It is also the only backend that supports **Stable Diffusion XL** model - Support for legacy workflows and extensions is limited, but it's being expanded See [wiki article](https://github.com/vladmandic/automatic/wiki/Diffusers) for more information ## Model support @@ -57,9 +56,10 @@ Additional models will be added as they become available and there is public int - Stable Diffusion 1.x and 2.x including all variants - Stable Diffusion XL -- Kandinsky 2.1 +- Kandinsky 2.1 and 2.2 - DeepFloyd IF - UniDiffusion +- SD-Distilled (all variants) ## Platform support diff --git a/modules/lora_diffusers.py b/modules/lora_diffusers.py index b2fe8fc00..59bf57b24 100644 --- a/modules/lora_diffusers.py +++ b/modules/lora_diffusers.py @@ -45,7 +45,6 @@ def load_diffusers_lora(name, lora, strength = 1.0): lora_state['multiplier'].append(strength) if shared.opts.diffusers_lora_loader == "diffusers default": pipe.load_lora_weights(lora.filename, cache_dir=shared.opts.diffusers_dir, local_files_only=True, lora_scale=strength) - shared.log.info(f"LoRA loaded: {name} {lora_state['multiplier']}") else: from safetensors.torch import load_file lora_sd = load_file(lora.filename) @@ -61,9 +60,9 @@ def load_diffusers_lora(name, lora, strength = 1.0): lora_network.to(shared.device, dtype=pipe.unet.dtype) lora_network.apply_to(multiplier=strength) lora_state['all_loras'].append(lora_network) - shared.log.info(f"LoRA loaded: {name}:{strength} loader={shared.opts.diffusers_lora_loader}") + shared.log.info(f"LoRA loaded: {name} strength={strength} loader={shared.opts.diffusers_lora_loader}") except Exception as e: - shared.log.error(f"Diffusers LoRA loading failed: {name} {e}") + shared.log.error(f"LoRA loading failed: {name} {e}") # Diffusersで動くLoRA。このファイル単独で完結する。 diff --git a/modules/processing_diffusers.py b/modules/processing_diffusers.py index d021dfff1..87c142cb5 100644 --- a/modules/processing_diffusers.py +++ b/modules/processing_diffusers.py @@ -52,6 +52,8 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro if p.is_hr_pass: shared.state.sampling_steps += p.hr_second_pass_steps shared.state.current_latent = latents + if shared.state.interrupted or shared.state.skipped: + raise AssertionError('Interrupted...') def full_vae_decode(latents, model): 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={model.vae.config.get("force_upcast", None)} images={latents.shape[0]}') @@ -162,8 +164,6 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro args['callback_steps'] = 1 if 'callback' in possible: args['callback'] = diffusers_callback - if 'cross_attention_kwargs' in possible and lora_state['active'] and shared.opts.diffusers_lora_loader == "diffusers default": - args['cross_attention_kwargs'] = { 'scale': lora_state['multiplier'][0]} for arg in kwargs: if arg in possible: args[arg] = kwargs[arg] @@ -284,7 +284,10 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro ) p.extra_generation_params['CFG rescale'] = p.diffusers_guidance_rescale p.extra_generation_params["Eta DDIM"] = shared.opts.eta_ddim if shared.opts.eta_ddim is not None and shared.opts.eta_ddim > 0 else None - output = shared.sd_model(**base_args) # pylint: disable=not-callable + try: + output = shared.sd_model(**base_args) # pylint: disable=not-callable + except AssertionError as e: + shared.log.info(e) if lora_state['active']: p.extra_generation_params['LoRA method'] = shared.opts.diffusers_lora_loader @@ -320,7 +323,10 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro strength=p.denoising_strength, desc='Hires', ) - output = shared.sd_model(**hires_args) # pylint: disable=not-callable + try: + output = shared.sd_model(**hires_args) # pylint: disable=not-callable + except AssertionError as e: + shared.log.info(e) # optional refiner pass or decode if is_refiner_enabled: @@ -361,7 +367,11 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro clip_skip=p.clip_skip, desc='Refiner', ) - refiner_output = shared.sd_refiner(**refiner_args) # pylint: disable=not-callable + try: + refiner_output = shared.sd_refiner(**refiner_args) # pylint: disable=not-callable + except AssertionError as e: + shared.log.info(e) + 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 steps'] = p.refiner_steps p.extra_generation_params['Refiner start'] = p.refiner_start