From 52078069d29364a1053126829a7917a7378fc56d Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Fri, 20 Oct 2023 07:30:13 -0400 Subject: [PATCH 1/6] mark external themes clearly --- CHANGELOG.md | 2 +- beautiful girl sitting on an edge of a.jpg | Bin 23511 -> 0 bytes modules/theme.py | 6 ++++-- 3 files changed, 5 insertions(+), 3 deletions(-) delete mode 100644 beautiful girl sitting on an edge of a.jpg diff --git a/CHANGELOG.md b/CHANGELOG.md index 47ffc4781..b39895d09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log for SD.Next -## Update for 2023-10-18 +## Update for 2023-10-19 Service release addressing all zero-day issues reported so far... diff --git a/beautiful girl sitting on an edge of a.jpg b/beautiful girl sitting on an edge of a.jpg deleted file mode 100644 index 1c5e7382fe5e0f7176a74970746a909864ea9014..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23511 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 Date: Fri, 20 Oct 2023 08:19:37 -0400 Subject: [PATCH 2/6] add a1111 compatibility items --- modules/scripts.py | 18 +++++- modules/sd_samplers.py | 7 ++- modules/shared.py | 1 + modules/ui.py | 11 +++- modules/ui_common.py | 5 +- modules/ui_components.py | 57 +++++++++++++++++++ modules/ui_prompt_styles.py | 106 ++++++++++++++++++++++++++++++++++++ 7 files changed, 201 insertions(+), 4 deletions(-) create mode 100644 modules/ui_prompt_styles.py diff --git a/modules/scripts.py b/modules/scripts.py index dca8b3f64..f378744ee 100644 --- a/modules/scripts.py +++ b/modules/scripts.py @@ -35,6 +35,7 @@ class Script: group = None infotext_fields = None paste_field_names = None + section = None def title(self): """this function should return the title of the script. This is what will be displayed in the dropdown menu.""" @@ -332,7 +333,6 @@ class ScriptRunner: self.paste_field_names.clear() self.script_load_ctr = 0 self.is_img2img = is_img2img - self.scripts.clear() self.alwayson_scripts.clear() self.selectable_scripts.clear() @@ -355,6 +355,22 @@ class ScriptRunner: except Exception as e: log.error(f'Script initialize: {path} {e}') + def setup_ui_for_section(self, section, scriptlist=None): + if scriptlist is None: + scriptlist = self.alwayson_scripts + for script in scriptlist: + if script.alwayson and script.section != section: + continue + if script.create_group: + with gr.Group(visible=script.alwayson) as group: + self.create_script_ui(script) + script.group = group + else: + self.create_script_ui(script) + + def prepare_ui(self): + self.inputs = [None] + def setup_ui(self): import modules.api.models as api_models self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts] diff --git a/modules/sd_samplers.py b/modules/sd_samplers.py index 103d7a93c..d538a0da9 100644 --- a/modules/sd_samplers.py +++ b/modules/sd_samplers.py @@ -34,6 +34,11 @@ def find_sampler_config(name): return config +def visible_sampler_names(): + samplers = [x for x in all_samplers if x.name in shared.opts.show_samplers] if len(shared.opts.show_samplers) > 0 else all_samplers + return samplers + + def create_sampler(name, model): if name == 'Default' and hasattr(model, 'scheduler'): config = {k: v for k, v in model.scheduler.config.items() if not k.startswith('_')} @@ -64,7 +69,7 @@ def create_sampler(name, model): def set_samplers(): global samplers # pylint: disable=global-statement global samplers_for_img2img # pylint: disable=global-statement - samplers = [x for x in all_samplers if x.name in shared.opts.show_samplers] if len(shared.opts.show_samplers) > 0 else all_samplers + samplers = visible_sampler_names() samplers_for_img2img = [x for x in samplers if x.name != "PLMS"] samplers_map.clear() for sampler in all_samplers: diff --git a/modules/shared.py b/modules/shared.py index 9c0b8058e..f4ebea262 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -425,6 +425,7 @@ options_templates.update(options_section(('ui', "User Interface"), { "gradio_theme": OptionInfo("black-teal", "UI theme", gr.Dropdown, lambda: {"choices": theme.list_themes()}, refresh=theme.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"], "visible": False}), + "gallery_height": OptionInfo("", "Gallery height", gr.Textbox), "compact_view": OptionInfo(False, "Compact view"), "return_grid": OptionInfo(True, "Show grid in results"), "return_mask": OptionInfo(False, "For inpainting, include the greyscale mask in results"), diff --git a/modules/ui.py b/modules/ui.py index b7edcdaac..3477a2802 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -35,6 +35,15 @@ mimetypes.init() mimetypes.add_type('application/javascript', '.js') log = modules.shared.log ui_system_tabs = None +switch_values_symbol = symbols.switch +detect_image_size_symbol = symbols.detect +paste_symbol = symbols.paste +clear_prompt_symbol = symbols.clear +restore_progress_symbol = symbols.apply +folder_symbol = symbols.folder +extra_networks_symbol = symbols.networks +apply_style_symbol = symbols.apply +save_style_symbol = symbols.save if not cmd_opts.share and not cmd_opts.listen: @@ -353,7 +362,7 @@ def get_value_for_setting(key): def ordered_ui_categories(): - return [] # dummy + return ['dimensions', 'sampler', 'seed', 'denoising', 'cfg', 'checkboxes', 'accordions', 'override_settings', 'scripts'] # TODO: a1111 compatibility item, not implemented def create_override_settings_dropdown(tabname, row): # pylint: disable=unused-argument diff --git a/modules/ui_common.py b/modules/ui_common.py index eee96b085..ad00dcb63 100644 --- a/modules/ui_common.py +++ b/modules/ui_common.py @@ -12,6 +12,9 @@ import modules.images import modules.script_callbacks +folder_symbol = symbols.folder + + def update_generation_info(generation_info, html_info, img_index): try: generation_info = json.loads(generation_info) @@ -178,7 +181,7 @@ def create_output_panel(tabname): with gr.Column(variant='panel', elem_id=f"{tabname}_results"): with gr.Group(elem_id=f"{tabname}_gallery_container"): # columns are for <576px, <768px, <992px, <1200px, <1400px, >1400px - result_gallery = gr.Gallery(value=[], label='Output', show_label=False, show_download_button=True, allow_preview=True, elem_id=f"{tabname}_gallery", container=False, preview=True, columns=5, object_fit='scale-down') + result_gallery = gr.Gallery(value=[], label='Output', show_label=False, show_download_button=True, allow_preview=True, elem_id=f"{tabname}_gallery", container=False, preview=True, columns=5, object_fit='scale-down', height=shared.opts.gallery_height or None) with gr.Column(elem_id=f"{tabname}_footer", elem_classes="gallery_footer"): dummy_component = gr.Label(visible=False) diff --git a/modules/ui_components.py b/modules/ui_components.py index 6d2186b92..0e5862765 100644 --- a/modules/ui_components.py +++ b/modules/ui_components.py @@ -71,3 +71,60 @@ class DropdownEditable(FormComponent, gr.Dropdown): def get_block_name(self): return "dropdown" + + +class InputAccordion(gr.Checkbox): + """A gr.Accordion that can be used as an input - returns True if open, False if closed. + Actaully just a hidden checkbox, but creates an accordion that follows and is followed by the state of the checkbox. + """ + global_index = 0 + + def __init__(self, value, **kwargs): + self.accordion_id = kwargs.get('elem_id') + if self.accordion_id is None: + self.accordion_id = f"input-accordion-{InputAccordion.global_index}" + InputAccordion.global_index += 1 + kwargs_checkbox = {**kwargs, "elem_id": f"{self.accordion_id}-checkbox", "visible": False} + super().__init__(value, **kwargs_checkbox) + self.change(fn=None, _js='function(checked){ inputAccordionChecked("' + self.accordion_id + '", checked); }', inputs=[self]) + kwargs_accordion = { + **kwargs, + "elem_id": self.accordion_id, + "label": kwargs.get('label', 'Accordion'), + "elem_classes": ['input-accordion'], + "open": value, + } + self.accordion = gr.Accordion(**kwargs_accordion) + + def extra(self): + """Allows you to put something into the label of the accordion. + Use it like this: + ``` + with InputAccordion(False, label="Accordion") as acc: + with acc.extra(): + FormHTML(value="hello", min_width=0) + ... + ``` + """ + return gr.Column(elem_id=self.accordion_id + '-extra', elem_classes='input-accordion-extra', min_width=0) + + def __enter__(self): + self.accordion.__enter__() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.accordion.__exit__(exc_type, exc_val, exc_tb) + + def get_block_name(self): + return "checkbox" + + +class ResizeHandleRow(gr.Row): + """Same as gr.Row but fits inside gradio forms""" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.elem_classes.append("resize-handle-row") + + def get_block_name(self): + return "row" diff --git a/modules/ui_prompt_styles.py b/modules/ui_prompt_styles.py new file mode 100644 index 000000000..9f8a43c7c --- /dev/null +++ b/modules/ui_prompt_styles.py @@ -0,0 +1,106 @@ +# TODO: a1111 compatibility item, not used + +import gradio as gr + +from modules import shared, ui_common, ui_components, styles + +styles_edit_symbol = '\U0001f58c\uFE0F' # 🖌️ +styles_materialize_symbol = '\U0001f4cb' # 📋 + + +def select_style(name): + style = shared.prompt_styles.styles.get(name) + existing = style is not None + empty = not name + prompt = style.prompt if style else gr.update() + negative_prompt = style.negative_prompt if style else gr.update() + return prompt, negative_prompt, gr.update(visible=existing), gr.update(visible=not empty) + + +def save_style(name, prompt, negative_prompt): + if not name: + return gr.update(visible=False) + style = styles.PromptStyle(name, prompt, negative_prompt) + shared.prompt_styles.styles[style.name] = style + shared.prompt_styles.save_styles(shared.styles_filename) + return gr.update(visible=True) + + +def delete_style(name): + if name == "": + return + shared.prompt_styles.styles.pop(name, None) + shared.prompt_styles.save_styles(shared.styles_filename) + return '', '', '' + + +def materialize_styles(prompt, negative_prompt, styles): + prompt = shared.prompt_styles.apply_styles_to_prompt(prompt, styles) + negative_prompt = shared.prompt_styles.apply_negative_styles_to_prompt(negative_prompt, styles) + return [gr.Textbox.update(value=prompt), gr.Textbox.update(value=negative_prompt), gr.Dropdown.update(value=[])] + + +def refresh_styles(): + return gr.update(choices=list(shared.prompt_styles.styles)), gr.update(choices=list(shared.prompt_styles.styles)) + + +class UiPromptStyles: + def __init__(self, tabname, main_ui_prompt, main_ui_negative_prompt): + self.dropdown = gr.Dropdown(label="Styles", elem_id=f"{tabname}_styles", choices=[style.name for style in shared.prompt_styles.styles.values()], value=[], multiselect=True) + + """ + def __init__(self, tabname, main_ui_prompt, main_ui_negative_prompt): + self.tabname = tabname + + with gr.Row(elem_id=f"{tabname}_styles_row"): + self.dropdown = gr.Dropdown(label="Styles", show_label=False, elem_id=f"{tabname}_styles", choices=list(shared.prompt_styles.styles), value=[], multiselect=True, tooltip="Styles") + edit_button = ui_components.ToolButton(value=styles_edit_symbol, elem_id=f"{tabname}_styles_edit_button", tooltip="Edit styles") + + with gr.Box(elem_id=f"{tabname}_styles_dialog", elem_classes="popup-dialog") as styles_dialog: + with gr.Row(): + self.selection = gr.Dropdown(label="Styles", elem_id=f"{tabname}_styles_edit_select", choices=list(shared.prompt_styles.styles), value=[], allow_custom_value=True, info="Styles allow you to add custom text to prompt. Use the {prompt} token in style text, and it will be replaced with user's prompt when applying style. Otherwise, style's text will be added to the end of the prompt.") + ui_common.create_refresh_button([self.dropdown, self.selection], shared.prompt_styles.reload, lambda: {"choices": list(shared.prompt_styles.styles)}, f"refresh_{tabname}_styles") + self.materialize = ui_components.ToolButton(value=styles_materialize_symbol, elem_id=f"{tabname}_style_apply", tooltip="Apply all selected styles from the style selction dropdown in main UI to the prompt.") + + with gr.Row(): + self.prompt = gr.Textbox(label="Prompt", show_label=True, elem_id=f"{tabname}_edit_style_prompt", lines=3) + + with gr.Row(): + self.neg_prompt = gr.Textbox(label="Negative prompt", show_label=True, elem_id=f"{tabname}_edit_style_neg_prompt", lines=3) + + with gr.Row(): + self.save = gr.Button('Save', variant='primary', elem_id=f'{tabname}_edit_style_save', visible=False) + self.delete = gr.Button('Delete', variant='primary', elem_id=f'{tabname}_edit_style_delete', visible=False) + self.close = gr.Button('Close', variant='secondary', elem_id=f'{tabname}_edit_style_close') + + self.selection.change( + fn=select_style, + inputs=[self.selection], + outputs=[self.prompt, self.neg_prompt, self.delete, self.save], + show_progress=False, + ) + + self.save.click( + fn=save_style, + inputs=[self.selection, self.prompt, self.neg_prompt], + outputs=[self.delete], + show_progress=False, + ).then(refresh_styles, outputs=[self.dropdown, self.selection], show_progress=False) + + self.delete.click( + fn=delete_style, + _js='function(name){ if(name == "") return ""; return confirm("Delete style " + name + "?") ? name : ""; }', + inputs=[self.selection], + outputs=[self.selection, self.prompt, self.neg_prompt], + show_progress=False, + ).then(refresh_styles, outputs=[self.dropdown, self.selection], show_progress=False) + + self.materialize.click( + fn=materialize_styles, + inputs=[main_ui_prompt, main_ui_negative_prompt, self.dropdown], + outputs=[main_ui_prompt, main_ui_negative_prompt, self.dropdown], + show_progress=False, + ).then(fn=None, _js="function(){update_"+tabname+"_tokens(); closePopup();}", show_progress=False) + + ui_common.setup_dialog(button_show=edit_button, dialog=styles_dialog, button_close=self.close) + """ From d8bb3496df2785ecab26ba1e3d26b6ea2e449b99 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Fri, 20 Oct 2023 09:31:51 -0400 Subject: [PATCH 3/6] force update deis settings --- CHANGELOG.md | 3 ++- javascript/settings.js | 1 + modules/sd_samplers_diffusers.py | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b39895d09..d281f37c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ Service release addressing all zero-day issues reported so far... - fix handling of relative path for models - fix simple live preview device mismatch - fix batch img2img -- fix diffusers dpm++ 2m and 1s samplers +- fix diffusers dpm++ 2m, dpm++ 1s, deis samplers - fix new style filename template - fix image name template using model name - fix model path using relative path @@ -21,6 +21,7 @@ Service release addressing all zero-day issues reported so far... - 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 - update `openvino` (thanks @disty0) - update `typing-extensions` diff --git a/javascript/settings.js b/javascript/settings.js index ff91ec995..c9fe3010a 100644 --- a/javascript/settings.js +++ b/javascript/settings.js @@ -77,6 +77,7 @@ function markIfModified(setting_name, value) { tab_nav_indicator.classList.toggle('saved', saved.size > 0); if (changed_items.size > 0) tab_nav_indicator.title += `click to reset ${changed_items.size} unapplied changes in this tab\n`; if (saved.size > 0) tab_nav_indicator.title += `${saved.size} custom values\n${unsaved.size} default values}`; + elem.scrollIntoView({ behavior: 'smooth', block: 'center' }); } onAfterUiUpdate(async () => { diff --git a/modules/sd_samplers_diffusers.py b/modules/sd_samplers_diffusers.py index e7067c1fd..b613fca99 100644 --- a/modules/sd_samplers_diffusers.py +++ b/modules/sd_samplers_diffusers.py @@ -97,11 +97,13 @@ class DiffusionSampler: self.config['solver_order'] = shared.opts.schedulers_solver_order if 'predict_x0' in self.config: self.config['predict_x0'] = shared.opts.uni_pc_variant - if name == 'DPM++ 2M': - self.config['algorithm_type'] = shared.opts.schedulers_dpm_solver if 'beta_start' in self.config and shared.opts.schedulers_beta_start > 0: self.config['beta_start'] = shared.opts.schedulers_beta_start if 'beta_end' in self.config and shared.opts.schedulers_beta_end > 0: self.config['beta_end'] = shared.opts.schedulers_beta_end + if name == 'DPM++ 2M': + self.config['algorithm_type'] = shared.opts.schedulers_dpm_solver + if name == 'DEIS': + self.config['algorithm_type'] = 'deis' self.sampler = constructor(**self.config) self.sampler.name = name From 7b63e4c911760c135b632ed10e49afe3a01d2691 Mon Sep 17 00:00:00 2001 From: Disty0 Date: Fri, 20 Oct 2023 18:28:13 +0300 Subject: [PATCH 4/6] OpenVINO replace MULTI device with HETERO --- modules/intel/openvino/__init__.py | 8 +++++--- modules/shared.py | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/intel/openvino/__init__.py b/modules/intel/openvino/__init__.py index b4294f9ee..5e62dbbc0 100644 --- a/modules/intel/openvino/__init__.py +++ b/modules/intel/openvino/__init__.py @@ -71,15 +71,17 @@ def get_device(): core = Core() if os.getenv("OPENVINO_TORCH_BACKEND_DEVICE") is not None: device = os.getenv("OPENVINO_TORCH_BACKEND_DEVICE") - elif shared.opts.openvino_multi_gpu: + elif shared.opts.openvino_hetero_gpu: device = "" available_devices = core.available_devices available_devices.remove("CPU") - if shared.opts.openvino_remove_igpu_from_multi and "GPU.0" in available_devices: + if shared.opts.openvino_remove_igpu_from_hetero and "GPU.0" in available_devices: available_devices.remove("GPU.0") for gpu in available_devices: device = f"{device},{gpu}" - device = f"MULTI:{device[1:]}" + if not shared.opts.openvino_remove_cpu_from_hetero: + device = f"{device},CPU" + device = f"HETERO:{device[1:]}" elif any(openvino_cpu in cpu_module.lower() for cpu_module in shared.cmd_opts.use_cpu for openvino_cpu in ["openvino", "all"]): device = "CPU" elif shared.cmd_opts.device_id is not None: diff --git a/modules/shared.py b/modules/shared.py index f4ebea262..b2938bb8b 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -289,8 +289,9 @@ options_templates.update(options_section(('cuda', "Compute Settings"), { "ipex_optimize": OptionInfo(True if devices.backend == "ipex" else False, "Enable IPEX Optimize for Intel GPUs"), "directml_memory_provider": OptionInfo(default_memory_provider, 'DirectML memory stats provider', gr.Radio, {"choices": memory_providers}), "openvino_disable_model_caching": OptionInfo(False, "OpenVINO disable model caching"), - "openvino_multi_gpu": OptionInfo(False, "OpenVINO use Multi GPU"), - "openvino_remove_igpu_from_multi": OptionInfo(False, "OpenVINO remove iGPU from Multi GPU"), + "openvino_hetero_gpu": OptionInfo(False, "OpenVINO use Hetero Device for single inference with multiple devices"), + "openvino_remove_cpu_from_hetero": OptionInfo(False, "OpenVINO remove CPU from Hetero Device"), + "openvino_remove_igpu_from_hetero": OptionInfo(False, "OpenVINO remove iGPU from Hetero Device"), })) options_templates.update(options_section(('advanced', "Inference Settings"), { From df7c04ab2714d2db9941986455af1554aa6408e9 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Fri, 20 Oct 2023 11:51:44 -0400 Subject: [PATCH 5/6] add keep-interrupted option --- CHANGELOG.md | 3 +++ extensions-builtin/sd-extension-chainner | 2 +- extensions-builtin/sd-webui-agent-scheduler | 2 +- modules/extra_networks.py | 4 ++++ modules/img2img.py | 11 +++++++---- modules/processing.py | 4 ++++ modules/shared.py | 1 + 7 files changed, 21 insertions(+), 6 deletions(-) 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}), From c82f9748f5a60039f3a65910ccb41242a506335b Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Fri, 20 Oct 2023 12:06:35 -0400 Subject: [PATCH 6/6] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85f81982d..7110eb3f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log for SD.Next -## Update for 2023-10-19 +## Update for 2023-10-20 Service release addressing all zero-day issues reported so far...