diff --git a/CHANGELOG.md b/CHANGELOG.md index d281f37c0..85f81982d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,11 +17,14 @@ Service release addressing all zero-day issues reported so far... - fix image name template using model name - fix model path using relative path - fix torch-rocm version detection (thanks @xangelix) +- fix chainner upscalers color clipping - force second requirements check on startup - remove lyco, multiple_tqdm - enhance extension compatibility for exensions directly importing codeformers - enhance extension compatibility for exensions directly accessing processing params - clearly mark external themes in ui +- new option: *settings -> images -> keep incomplete* + can be used to skip vae decode on aborted/skipped/interrupted image generations - update `openvino` (thanks @disty0) - update `typing-extensions` diff --git a/extensions-builtin/sd-extension-chainner b/extensions-builtin/sd-extension-chainner index 656293e7b..f84c381f8 160000 --- a/extensions-builtin/sd-extension-chainner +++ b/extensions-builtin/sd-extension-chainner @@ -1 +1 @@ -Subproject commit 656293e7bf4c2c462f7904dd2b5b03a244989a39 +Subproject commit f84c381f8e0e06fc1c75f0d49f9dccac8a01843e diff --git a/extensions-builtin/sd-webui-agent-scheduler b/extensions-builtin/sd-webui-agent-scheduler index 1d623c62f..2c6d29853 160000 --- a/extensions-builtin/sd-webui-agent-scheduler +++ b/extensions-builtin/sd-webui-agent-scheduler @@ -1 +1 @@ -Subproject commit 1d623c62fd2c1e0f6a9b46994e7735544cd27ff7 +Subproject commit 2c6d29853ee134b9fc6a00a179937ed8714e21e2 diff --git a/modules/extra_networks.py b/modules/extra_networks.py index 550f71279..d3ca87dd2 100644 --- a/modules/extra_networks.py +++ b/modules/extra_networks.py @@ -64,6 +64,8 @@ class ExtraNetwork: def activate(p, extra_network_data): """call activate for extra networks in extra_network_data in specified order, then call activate for all remaining registered networks with an empty argument list""" + if extra_network_data is None: + return for extra_network_name, extra_network_args in extra_network_data.items(): extra_network = extra_network_registry.get(extra_network_name, None) if extra_network is None: @@ -86,6 +88,8 @@ def activate(p, extra_network_data): def deactivate(p, extra_network_data): """call deactivate for extra networks in extra_network_data in specified order, then call deactivate for all remaining registered networks""" + if extra_network_data is None: + return for extra_network_name in extra_network_data: extra_network = extra_network_registry.get(extra_network_name, None) if extra_network is None: diff --git a/modules/img2img.py b/modules/img2img.py index cb88ad4a2..f01031cb8 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -10,7 +10,7 @@ from modules.memstats import memory_stats def process_batch(p, input_files, input_dir, output_dir, inpaint_mask_dir, args): - shared.log.debug(f'batch: {input_dir}|{output_dir}|{inpaint_mask_dir}') + shared.log.debug(f'batch: {input_files}|{input_dir}|{output_dir}|{inpaint_mask_dir}') processing.fix_seed(p) if input_files is not None and len(input_files) > 0: image_files = [f.name for f in input_files] @@ -109,8 +109,11 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s shared.log.debug(f'img2img: id_task={id_task}|mode={mode}|prompt={prompt}|negative_prompt={negative_prompt}|prompt_styles={prompt_styles}|init_img={init_img}|sketch={sketch}|init_img_with_mask={init_img_with_mask}|inpaint_color_sketch={inpaint_color_sketch}|inpaint_color_sketch_orig={inpaint_color_sketch_orig}|init_img_inpaint={init_img_inpaint}|init_mask_inpaint={init_mask_inpaint}|steps={steps}|sampler_index={sampler_index}|latent_index={latent_index}|mask_blur={mask_blur}|mask_alpha={mask_alpha}|inpainting_fill={inpainting_fill}|full_quality={full_quality}|restore_faces={restore_faces}|tiling={tiling}|n_iter={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|image_cfg_scale={image_cfg_scale}|clip_skip={clip_skip}|denoising_strength={denoising_strength}|seed={seed}|subseed{subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}|selected_scale_tab={selected_scale_tab}|height={height}|width={width}|scale_by={scale_by}|resize_mode={resize_mode}|inpaint_full_res={inpaint_full_res}|inpaint_full_res_padding={inpaint_full_res_padding}|inpainting_mask_invert={inpainting_mask_invert}|img2img_batch_files={img2img_batch_files}|img2img_batch_input_dir={img2img_batch_input_dir}|img2img_batch_output_dir={img2img_batch_output_dir}|img2img_batch_inpaint_mask_dir={img2img_batch_inpaint_mask_dir}|override_settings_texts={override_settings_texts}') - if init_img is None: - shared.log.debug('Init image not set') + if mode == 5: + if img2img_batch_files is None or len(img2img_batch_files) == 0: + shared.log.debug('Init bactch images not set') + elif init_img: + shared.log.debug('Init image not set') if sampler_index is None: sampler_index = 0 @@ -202,7 +205,6 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s inpainting_mask_invert=inpainting_mask_invert, override_settings=override_settings, ) - p.is_batch = mode == 5 if selected_scale_tab == 1 and resize_mode != 0: p.scale_by = scale_by p.scripts = modules.scripts.scripts_img2img @@ -210,6 +212,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s p.extra_generation_params['Resize mode'] = resize_mode if mask: p.extra_generation_params["Mask blur"] = mask_blur + p.is_batch = mode == 5 if p.is_batch: process_batch(p, img2img_batch_files, img2img_batch_input_dir, img2img_batch_output_dir, img2img_batch_inpaint_mask_dir, args) processed = processing.Processed(p, [], p.seed, "") diff --git a/modules/processing.py b/modules/processing.py index 0b3e461da..fffb93455 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -441,6 +441,10 @@ def create_random_tensors(shape, seeds, subseeds=None, subseed_strength=0.0, see def decode_first_stage(model, x, full_quality=True): + if not shared.opts.keep_incomplete and (shared.state.skipped or shared.state.interrupted): + shared.log.debug(f'Decode VAE: skipped={shared.state.skipped} interrupted={shared.state.interrupted}') + x_sample = torch.zeros((len(x), 3, x.shape[2] * 8, x.shape[3] * 8), dtype=devices.dtype_vae, device=devices.device) + return x_sample with devices.autocast(disable = x.dtype==devices.dtype_vae): try: if full_quality: diff --git a/modules/shared.py b/modules/shared.py index b2938bb8b..394c2c7c5 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -365,6 +365,7 @@ options_templates.update(options_section(('system-paths', "System Paths"), { })) options_templates.update(options_section(('saving-images', "Image Options"), { + "keep_incomplete": OptionInfo(True, "Keep incomplete images"), "samples_save": OptionInfo(True, "Always save all generated images"), "samples_format": OptionInfo('jpg', 'File format for generated images', gr.Dropdown, {"choices": ["jpg", "png", "webp", "tiff", "jp2"]}), "jpeg_quality": OptionInfo(90, "Quality for saved images", gr.Slider, {"minimum": 1, "maximum": 100, "step": 1}),