Commit 47d9dd02 authored by AUTOMATIC1111's avatar AUTOMATIC1111
Browse files

speedup extra networks listing

parent a1d6ada6
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ import re
import torch
from typing import Union

from modules import shared, devices, sd_models, errors, scripts, sd_hijack, hashes
from modules import shared, devices, sd_models, errors, scripts, sd_hijack, hashes, cache

metadata_tags_order = {"ss_sd_model_name": 1, "ss_resolution": 2, "ss_clip_skip": 3, "ss_num_train_images": 10, "ss_tag_frequency": 20}

@@ -78,9 +78,16 @@ class LoraOnDisk:
        self.metadata = {}
        self.is_safetensors = os.path.splitext(filename)[1].lower() == ".safetensors"

        def read_metadata():
            metadata = sd_models.read_metadata_from_safetensors(filename)
            metadata.pop('ssmd_cover_images', None)  # those are cover images, and they are too big to display in UI as text

            return metadata

        if self.is_safetensors:
            try:
                self.metadata = sd_models.read_metadata_from_safetensors(filename)
                #self.metadata = sd_models.read_metadata_from_safetensors(filename)
                self.metadata = cache.cached_data_for_file('safetensors-metadata', "lora/" + self.name, filename, read_metadata)
            except Exception as e:
                errors.display(e, f"reading lora {filename}")

@@ -91,7 +98,6 @@ class LoraOnDisk:

            self.metadata = m

        self.ssmd_cover_images = self.metadata.pop('ssmd_cover_images', None)  # those are cover images and they are too big to display in UI as text
        self.alias = self.metadata.get('ss_output_name', self.name)

        self.hash = None
+4 −5
Original line number Diff line number Diff line
import html
import json
import random

import gradio as gr
@@ -64,7 +63,7 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
    def get_metadata_table(self, name):
        table = super().get_metadata_table(name)
        item = self.page.items.get(name, {})
        metadata = json.loads(item.get("metadata") or '{}')
        metadata = item.get("metadata") or {}

        keys = [
            ('ss_sd_model_name', "Model:"),
@@ -91,7 +90,7 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
        values = super().put_values_into_components(name)

        item = self.page.items.get(name, {})
        metadata = json.loads(item.get("metadata") or '{}')
        metadata = item.get("metadata") or {}

        tags = build_tags(metadata)
        gradio_tags = [(tag, str(count)) for tag, count in tags[0:24]]
@@ -108,7 +107,7 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)

    def generate_random_prompt(self, name):
        item = self.page.items.get(name, {})
        metadata = json.loads(item.get("metadata") or '{}')
        metadata = item.get("metadata") or {}
        tags = build_tags(metadata)

        return self.generate_random_prompt_from_tags(tags)
@@ -142,7 +141,7 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)

        self.edit_notes = gr.TextArea(label='Notes', lines=4)

        generate_random_prompt.click(fn=self.generate_random_prompt, inputs=[self.edit_name_input], outputs=[random_prompt])
        generate_random_prompt.click(fn=self.generate_random_prompt, inputs=[self.edit_name_input], outputs=[random_prompt], show_progress=False)

        def select_tag(activation_text, evt: gr.SelectData):
            tag = evt.value[0]
+5 −4
Original line number Diff line number Diff line
import json
import os
import lora

from modules import shared, ui_extra_networks
from modules.ui_extra_networks import quote_js
from ui_edit_user_metadata import LoraUserMetadataEditor


@@ -20,6 +20,7 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):

        alias = lora_on_disk.get_alias()

        # in 1.5 filename changes to be full filename instead of path without extension, and metadata is dict instead of json string
        item = {
            "name": name,
            "filename": lora_on_disk.filename,
@@ -27,17 +28,17 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
            "description": self.find_description(path),
            "search_term": self.search_terms_from_path(lora_on_disk.filename),
            "local_preview": f"{path}.{shared.opts.samples_format}",
            "metadata": json.dumps(lora_on_disk.metadata, indent=4) if lora_on_disk.metadata else None,
            "metadata": lora_on_disk.metadata,
            "sort_keys": {'default': index, **self.get_sort_keys(lora_on_disk.filename)},
        }

        self.read_user_metadata(item)
        activation_text = item["user_metadata"].get("activation text")
        preferred_weight = item["user_metadata"].get("preferred weight", 0.0)
        item["prompt"] = json.dumps(f"<lora:{alias}:") + " + " + (str(preferred_weight) if preferred_weight else "opts.extra_networks_default_multiplier") + " + " + json.dumps(">")
        item["prompt"] = quote_js(f"<lora:{alias}:") + " + " + (str(preferred_weight) if preferred_weight else "opts.extra_networks_default_multiplier") + " + " + quote_js(">")

        if activation_text:
            item["prompt"] += " + " + json.dumps(" " + activation_text)
            item["prompt"] += " + " + quote_js(" " + activation_text)

        return item

+14 −13
Original line number Diff line number Diff line
import json
import os.path

import filelock
import threading

from modules.paths import data_path, script_path

cache_filename = os.path.join(data_path, "cache.json")
cache_data = None
cache_lock = threading.Lock()


def dump_cache():
@@ -14,7 +14,7 @@ def dump_cache():
    Saves all cache data to a file.
    """

    with filelock.FileLock(f"{cache_filename}.lock"):
    with cache_lock:
        with open(cache_filename, "w", encoding="utf8") as file:
            json.dump(cache_data, file, indent=4)

@@ -33,7 +33,8 @@ def cache(subsection):
    global cache_data

    if cache_data is None:
        with filelock.FileLock(f"{cache_filename}.lock"):
        with cache_lock:
            if cache_data is None:
                if not os.path.isfile(cache_filename):
                    cache_data = {}
                else:
+13 −7
Original line number Diff line number Diff line
@@ -73,6 +73,12 @@ def add_pages_to_demo(app):
    app.add_api_route("/sd_extra_networks/get-single-card", get_single_card, methods=["GET"])


def quote_js(s):
    s = s.replace('\\', '\\\\')
    s = s.replace('"', '\\"')
    return f'"{s}"'


class ExtraNetworksPage:
    def __init__(self, title):
        self.title = title
@@ -203,7 +209,7 @@ class ExtraNetworksPage:

        onclick = item.get("onclick", None)
        if onclick is None:
            onclick = '"' + html.escape(f"""return cardClicked({json.dumps(tabname)}, {item["prompt"]}, {"true" if self.allow_negative_prompt else "false"})""") + '"'
            onclick = '"' + html.escape(f"""return cardClicked({quote_js(tabname)}, {item["prompt"]}, {"true" if self.allow_negative_prompt else "false"})""") + '"'

        height = f"height: {shared.opts.extra_networks_card_height}px;" if shared.opts.extra_networks_card_height else ''
        width = f"width: {shared.opts.extra_networks_card_width}px;" if shared.opts.extra_networks_card_width else ''
@@ -211,9 +217,9 @@ class ExtraNetworksPage:
        metadata_button = ""
        metadata = item.get("metadata")
        if metadata:
            metadata_button = f"<div class='metadata-button card-button' title='Show internal metadata' onclick='extraNetworksRequestMetadata(event, {json.dumps(self.name)}, {json.dumps(item['name'])})'></div>"
            metadata_button = f"<div class='metadata-button card-button' title='Show internal metadata' onclick='extraNetworksRequestMetadata(event, {quote_js(self.name)}, {quote_js(item['name'])})'></div>"

        edit_button = f"<div class='edit-button card-button' title='Edit metadata' onclick='extraNetworksEditUserMetadata(event, {json.dumps(tabname)}, {json.dumps(self.id_page)}, {json.dumps(item['name'])})'></div>"
        edit_button = f"<div class='edit-button card-button' title='Edit metadata' onclick='extraNetworksEditUserMetadata(event, {quote_js(tabname)}, {quote_js(self.id_page)}, {quote_js(item['name'])})'></div>"

        local_path = ""
        filename = item.get("filename", "")
@@ -239,12 +245,12 @@ class ExtraNetworksPage:
            "background_image": background_image,
            "style": f"'display: none; {height}{width}'",
            "prompt": item.get("prompt", None),
            "tabname": json.dumps(tabname),
            "local_preview": json.dumps(item["local_preview"]),
            "tabname": quote_js(tabname),
            "local_preview": quote_js(item["local_preview"]),
            "name": item["name"],
            "description": (item.get("description") or ""),
            "card_clicked": onclick,
            "save_card_preview": '"' + html.escape(f"""return saveCardPreview(event, {json.dumps(tabname)}, {json.dumps(item["local_preview"])})""") + '"',
            "save_card_preview": '"' + html.escape(f"""return saveCardPreview(event, {quote_js(tabname)}, {quote_js(item["local_preview"])})""") + '"',
            "search_term": item.get("search_term", ""),
            "metadata_button": metadata_button,
            "edit_button": edit_button,
@@ -359,7 +365,7 @@ def create_ui(container, button, tabname):
                page_elem = gr.HTML('Loading...', elem_id=elem_id)
                ui.pages.append(page_elem)

                page_elem.change(fn=lambda: None, _js='function(){applyExtraNetworkFilter(' + json.dumps(tabname) + '); return []}', inputs=[], outputs=[])
                page_elem.change(fn=lambda: None, _js='function(){applyExtraNetworkFilter(' + quote_js(tabname) + '); return []}', inputs=[], outputs=[])

                editor = page.create_user_metadata_editor(ui, tabname)
                editor.create_ui()
Loading