Liu Song’s Projects


~/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 */