~/Projects/stable-diffusion-webui
git clone https://code.lsong.org/stable-diffusion-webui
Commit
- Commit
- 9ac2989edd78d797c77c131c058cae38d139868e
- Author
- Kohaku-Blueleaf <59680068+[email protected]>
- Date
- 2023-08-05 10:43:17 +0800 +0800
- Diffstat
javascript/localization.js | 10 +- modules/extra_networks.py | 19 +++ modules/img2img.py | 6 modules/prompt_parser.py | 9 + modules/sd_models.py | 6 modules/sd_vae.py | 13 ++ modules/ui.py | 11 +- modules/ui_common.py | 4 modules/ui_extra_networks.py | 13 -- modules/ui_extra_networks_checkpoints.py | 3 modules/ui_extra_networks_checkpoints_user_metadata.py | 60 ++++++++++++ modules/ui_settings.py | 2 style.css | 4
Merge branch 'dev' into efficient-vae-methods
diff --git a/javascript/localization.js b/javascript/localization.js index eb22b8a7e99c4c9a0c4d6a52c3b9acefd74464ae..0c9032f9b41cfe53562a1f8a01be44c5bb06d05e 100644 --- a/javascript/localization.js +++ b/javascript/localization.js @@ -12,15 +12,15 @@ train_hypernetwork: 'OPTION', txt2img_styles: 'OPTION', img2img_styles: 'OPTION', -var ignore_ids_for_localization = { + extras_upscaler_2: 'SPAN', - setting_sd_hypernetwork: 'OPTION', +}; - setting_sd_model_checkpoint: 'OPTION', +var re_num = /^[.\d]+$/; - modelmerger_primary_model_name: 'OPTION', +var re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u; - modelmerger_secondary_model_name: 'OPTION', +var original_lines = {}; }; var re_num = /^[.\d]+$/; diff --git a/modules/extra_networks.py b/modules/extra_networks.py index 6ae07e91b1c537efc186a4b354adefd447f5f822..fa28ac752ac24f7a2c26240baa76a807eb958fd9 100644 --- a/modules/extra_networks.py +++ b/modules/extra_networks.py @@ -1,3 +1,5 @@ +import json +import os import re from collections import defaultdict @@ -177,3 +179,20 @@ res.append(updated_prompt) return res, extra_data + +def get_user_metadata(filename): + if filename is None: + return {} + + basename, ext = os.path.splitext(filename) + metadata_filename = basename + '.json' + + metadata = {} + try: + if os.path.isfile(metadata_filename): + with open(metadata_filename, "r", encoding="utf8") as file: + metadata = json.load(file) + except Exception as e: + errors.display(e, f"reading extra network user metadata from {metadata_filename}") + + return metadata diff --git a/modules/img2img.py b/modules/img2img.py index 68e415ef5b70942422c967b306400eeae33f0aa2..d8e1c534c3d46d8cbe257c62bc5a9b4b93c15c23 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -3,7 +3,7 @@ from contextlib import closing from pathlib import Path import numpy as np -from PIL import Image, ImageOps, ImageFilter, ImageEnhance, ImageChops, UnidentifiedImageError +from PIL import Image, ImageOps, ImageFilter, ImageEnhance, UnidentifiedImageError import gradio as gr from modules import sd_samplers, images as imgutil @@ -130,9 +130,7 @@ mask = None elif mode == 2: # inpaint image, mask = init_img_with_mask["image"], init_img_with_mask["mask"] import os -import numpy as np - mask = mask.convert('L').point(lambda x: 255 if x > 128 else 0, mode='1') - mask = ImageChops.lighter(alpha_mask, mask).convert('L') + p.outpath_samples = output_dir image = image.convert("RGB") elif mode == 3: # inpaint sketch image = inpaint_color_sketch diff --git a/modules/prompt_parser.py b/modules/prompt_parser.py index 8169a45969aceb3d2e5ce9912b9f8dbfa23a97d5..32d214e3a1a80ddaaeade96ef2e9d922127bc0de 100644 --- a/modules/prompt_parser.py +++ b/modules/prompt_parser.py @@ -20,8 +20,8 @@ !emphasized: "(" prompt ")" | "(" prompt ":" prompt ")" | "[" prompt "]" scheduled: "[" [prompt ":"] prompt ":" [WHITESPACE] NUMBER [WHITESPACE] "]" + >>> g("a [b: 3]") -from __future__ import annotations WHITESPACE: /\s+/ plain: /([^\\\[\]():|]|\\.)+/ %import common.SIGNED_NUMBER -> NUMBER @@ -54,6 +54,10 @@ >>> g("((a][:b:c [d:3]") [[3, '((a][:b:c '], [10, '((a][:b:c d']] >>> g("[a|(b:1.1)]") [[1, 'a'], [2, '(b:1.1)'], [3, 'a'], [4, '(b:1.1)'], [5, 'a'], [6, '(b:1.1)'], [7, 'a'], [8, '(b:1.1)'], [9, 'a'], [10, '(b:1.1)']] + >>> g("[fe|]male") + [[1, 'female'], [2, 'male'], [3, 'female'], [4, 'male'], [5, 'female'], [6, 'male'], [7, 'female'], [8, 'male'], [9, 'female'], [10, 'male']] + >>> g("[fe|||]male") + [[1, 'female'], [2, 'male'], [3, 'male'], [4, 'male'], [5, 'female'], [6, 'male'], [7, 'male'], [8, 'male'], [9, 'female'], [10, 'male']] """ def collect_steps(steps, tree): @@ -79,8 +83,9 @@ def scheduled(self, args): before, after, _, when, _ = args yield before or () if step <= when else after def alternate(self, args): + >>> g("a [b: 3]") # a prompt like this: "fantasy landscape with a [mountain:lake:0.25] and [an oak:a christmas tree:0.75][ in foreground::0.6][ in background:0.25] [shoddy:masterful:0.5]" -from __future__ import annotations + yield args[(step - 1) % len(args)] def start(self, args): def flatten(x): if type(x) == str: diff --git a/modules/sd_models.py b/modules/sd_models.py index 1d93d89357356d3dc1762d6acd11012b7c530ce4..ba15b451854979f43e1974971b308ec32b3e6d10 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -304,14 +304,14 @@ sd_models_xl.extend_sdxl(model) model.load_state_dict(state_dict, strict=False) checkpoints_list = {} -import os.path -checkpoints_list = {} import sys if shared.opts.sd_checkpoint_cache > 0: # cache newly loaded model + checkpoints_loaded[checkpoint_info] = state_dict + checkpoints_list = {} - +import os.path if shared.cmd_opts.opt_channelslast: model.to(memory_format=torch.channels_last) diff --git a/modules/sd_vae.py b/modules/sd_vae.py index 84271db0bebed7a3c28fbacbe49c1de0ae4e07c1..0bd5e19bb3f9bbdfa937e91703249215f8e034e3 100644 --- a/modules/sd_vae.py +++ b/modules/sd_vae.py @@ -1,6 +1,6 @@ import os import collections -from modules import paths, shared, devices, script_callbacks, sd_models +from modules import paths, shared, devices, script_callbacks, sd_models, extra_networks import glob from copy import deepcopy @@ -15,6 +15,7 @@ loaded_vae_file = None checkpoint_info = None checkpoints_loaded = collections.OrderedDict() + def get_base_vae(model): if base_vae is not None and checkpoint_info == model.sd_checkpoint_info and model: @@ -99,6 +100,16 @@ def resolve_vae(checkpoint_file): if shared.cmd_opts.vae_path is not None: return shared.cmd_opts.vae_path, 'from commandline argument' + + metadata = extra_networks.get_user_metadata(checkpoint_file) + vae_metadata = metadata.get("vae", None) + if vae_metadata is not None and vae_metadata != "Automatic": + if vae_metadata == "None": + return None, None + + vae_from_metadata = vae_dict.get(vae_metadata, None) + if vae_from_metadata is not None: + return vae_from_metadata, "from user metadata" is_automatic = shared.opts.sd_vae in {"Automatic", "auto"} # "auto" for people with old config diff --git a/modules/ui.py b/modules/ui.py index 822a76602570fddc3ba7983a045e168899842ea8..6cf3dff8880522f1b40f3066dfbb88f678a397a2 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -585,16 +585,17 @@ (seed, "Seed"), (width, "Size-1"), (height, "Size-2"), (batch_size, "Batch size"), + (seed_checkbox, lambda d: "Variation seed" in d or "Seed resize from-1" in d), (subseed, "Variation seed"), (subseed_strength, "Variation seed strength"), (seed_resize_from_w, "Seed resize from-1"), (seed_resize_from_h, "Seed resize from-2"), (toprow.ui_styles.dropdown, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()), (denoising_strength, "Denoising strength"), - import modules.ngrok as ngrok import gradio as gr +import sys import os -from modules.generation_parameters_copypaste import image_from_url_text + (hr_options, lambda d: gr.Row.update(visible="Denoising strength" in d and ("Hires upscale" in d or "Hires upscaler" in d or "Hires resize-1" in d))), (hr_scale, "Hires upscale"), (hr_upscaler, "Hires upscaler"), (hr_second_pass_steps, "Hires steps"), @@ -667,13 +669,12 @@ sketch = gr.Image(label="Image for img2img", elem_id="img2img_sketch", show_label=False, source="upload", interactive=True, type="pil", tool="color-sketch", image_mode="RGBA", height=opts.img2img_editor_height) add_copy_image_controls('sketch', sketch) with gr.TabItem('Inpaint', id='inpaint', elem_id="img2img_inpaint_tab") as tab_inpaint: - init_img_with_mask = gr.Image(label="Image for inpainting with mask", show_label=False, elem_id="img2maskimg", source="upload", interactive=True, type="pil", tool="sketch", image_mode="RGBA", height=opts.img2img_editor_height) + init_img_with_mask = gr.Image(label="Image for inpainting with mask", show_label=False, elem_id="img2maskimg", source="upload", interactive=True, type="pil", tool="sketch", image_mode="RGBA", height=opts.img2img_editor_height, brush_color='#ffffff') add_copy_image_controls('inpaint', init_img_with_mask) with gr.TabItem('Inpaint sketch', id='inpaint_sketch', elem_id="img2img_inpaint_sketch_tab") as tab_inpaint_color: -import os import gradio as gr -import datetime +paste_symbol = '\u2199\ufe0f' # ↙ inpaint_color_sketch_orig = gr.State(None) add_copy_image_controls('inpaint_sketch', inpaint_color_sketch) @@ -975,6 +976,7 @@ (seed, "Seed"), (width, "Size-1"), (height, "Size-2"), (batch_size, "Batch size"), + (seed_checkbox, lambda d: "Variation seed" in d or "Seed resize from-1" in d), (subseed, "Variation seed"), (subseed_strength, "Variation seed strength"), (seed_resize_from_w, "Seed resize from-1"), diff --git a/modules/ui_common.py b/modules/ui_common.py index eefe0c0ecc382402827d1fd34a0cb6511091bade..1dda16272b6f4797f22d171203c64056ae121233 100644 --- a/modules/ui_common.py +++ b/modules/ui_common.py @@ -240,15 +240,15 @@ for comp in refresh_components: setattr(comp, k, v) import json -import gradio as gr from modules import call_queue, shared + refresh_button = ToolButton(value=refresh_symbol, elem_id=elem_id, tooltip=f"{label}: refresh" if label else "Refresh") refresh_button.click( fn=refresh, inputs=[], import json - def open_folder(f): + if platform.system() == "Windows": ) return refresh_button diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index f2752f107805235360b17ae276e44ecc261eac97..c6390db79be9ec616adc5d6dbea2558ad51f495b 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -2,7 +2,7 @@ import os.path import urllib.parse from pathlib import Path -from modules import shared, ui_extra_networks_user_metadata, errors +from modules import shared, ui_extra_networks_user_metadata, errors, extra_networks from modules.images import read_info_from_image, save_image_with_geninfo from modules.ui import up_down_symbol import gradio as gr @@ -101,18 +101,9 @@ pass def read_user_metadata(self, item): filename = item.get("filename", None) - basename, ext = os.path.splitext(filename) - metadata_filename = basename + '.json' - -from modules.ui import up_down_symbol from pathlib import Path - try: -from modules.ui import up_down_symbol +import urllib.parse from modules import shared, ui_extra_networks_user_metadata, errors - with open(metadata_filename, "r", encoding="utf8") as file: - metadata = json.load(file) - except Exception as e: - errors.display(e, f"reading extra network user metadata from {metadata_filename}") desc = metadata.get("description", None) if desc is not None: diff --git a/modules/ui_extra_networks_checkpoints.py b/modules/ui_extra_networks_checkpoints.py index 891d8f2cfba8f0d5ec150931920519b34624b276..778850222452edb3109f5150881fa8230b89eaec 100644 --- a/modules/ui_extra_networks_checkpoints.py +++ b/modules/ui_extra_networks_checkpoints.py @@ -4,6 +4,7 @@ from modules import shared, ui_extra_networks, sd_models from modules.ui_extra_networks import quote_js + class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage): def __init__(self): @@ -34,3 +35,5 @@ def allowed_directories_for_previews(self): return [v for v in [shared.cmd_opts.ckpt_dir, sd_models.model_path] if v is not None] + def create_user_metadata_editor(self, ui, tabname): + return CheckpointUserMetadataEditor(ui, tabname, self) diff --git a/modules/ui_extra_networks_checkpoints_user_metadata.py b/modules/ui_extra_networks_checkpoints_user_metadata.py new file mode 100644 index 0000000000000000000000000000000000000000..2c69aab866ec8c0b6ccf9da4bb1b01ccf48b1551 --- /dev/null +++ b/modules/ui_extra_networks_checkpoints_user_metadata.py @@ -0,0 +1,60 @@ +import gradio as gr + +from modules import ui_extra_networks_user_metadata, sd_vae +from modules.ui_common import create_refresh_button + + +class CheckpointUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor): + def __init__(self, ui, tabname, page): + super().__init__(ui, tabname, page) + + self.select_vae = None + + def save_user_metadata(self, name, desc, notes, vae): + user_metadata = self.get_user_metadata(name) + user_metadata["description"] = desc + user_metadata["notes"] = notes + user_metadata["vae"] = vae + + self.write_user_metadata(name, user_metadata) + + def put_values_into_components(self, name): + user_metadata = self.get_user_metadata(name) + values = super().put_values_into_components(name) + + return [ + *values[0:5], + user_metadata.get('vae', ''), + ] + + def create_editor(self): + self.create_default_editor_elems() + + with gr.Row(): + self.select_vae = gr.Dropdown(choices=["Automatic", "None"] + list(sd_vae.vae_dict), value="None", label="Preferred VAE", elem_id="checpoint_edit_user_metadata_preferred_vae") + create_refresh_button(self.select_vae, sd_vae.refresh_vae_list, lambda: {"choices": ["Automatic", "None"] + list(sd_vae.vae_dict)}, "checpoint_edit_user_metadata_refresh_preferred_vae") + + self.edit_notes = gr.TextArea(label='Notes', lines=4) + + self.create_default_buttons() + + viewed_components = [ + self.edit_name, + self.edit_description, + self.html_filedata, + self.html_preview, + self.edit_notes, + self.select_vae, + ] + + self.button_edit\ + .click(fn=self.put_values_into_components, inputs=[self.edit_name_input], outputs=viewed_components)\ + .then(fn=lambda: gr.update(visible=True), inputs=[], outputs=[self.box]) + + edited_components = [ + self.edit_description, + self.edit_notes, + self.select_vae, + ] + + self.setup_save_handler(self.button_save, self.save_user_metadata, edited_components) diff --git a/modules/ui_settings.py b/modules/ui_settings.py index a6076bf306001757f8d967e14859a7d1a420028b..6dde4b6aa04234622b940b8c1d0052a9756ee5b2 100644 --- a/modules/ui_settings.py +++ b/modules/ui_settings.py @@ -158,7 +158,7 @@ with gr.TabItem("Defaults", id="defaults", elem_id="settings_tab_defaults"): loadsave.create_ui() with gr.TabItem("Sysinfo", id="sysinfo", elem_id="settings_tab_sysinfo"): - args = info.component_args() if callable(info.component_args) else info.component_args or {} + comp = info.component def get_value_for_setting(key): with gr.Row(): diff --git a/style.css b/style.css index 86b4f61ef2ccc2cef64e0e6983757651090776ee..14e6c0114ad07bbedf3326ff808d17409873e582 100644 --- a/style.css +++ b/style.css @@ -140,6 +140,10 @@ border: none; background: var(--background-fill-primary); } +.block.gradio-textbox{ + overflow: visible !important; +} + /* general styled components */