mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
Merge branch 'dev' into Dev/DirectoryCacheing
This commit is contained in:
@@ -102,6 +102,8 @@ And it also includes fixes for all reported issues so far
|
||||
- faster json parsing
|
||||
- faster lora indexing
|
||||
- lazy load optional imports
|
||||
- batch embedding load, thanks @midcoastal
|
||||
10x+ faster embeddings load for large number of embeddings, now works for 1000+ embeddings
|
||||
- **extra networks**
|
||||
- 4x faster civitai metadata and previews lookup
|
||||
- better display and selection of tags & trigger words
|
||||
|
||||
Submodule extensions-builtin/sd-webui-controlnet updated: 8870e35682...ba05e1ea20
@@ -4,54 +4,40 @@ from typing import Optional
|
||||
|
||||
def patch(key, obj, field, replacement, add_if_not_exists:bool = False):
|
||||
"""Replaces a function in a module or a class.
|
||||
|
||||
Also stores the original function in this module, possible to be retrieved via original(key, obj, field).
|
||||
If the function is already replaced by this caller (key), an exception is raised -- use undo() before that.
|
||||
|
||||
Arguments:
|
||||
key: identifying information for who is doing the replacement. You can use __name__.
|
||||
obj: the module or the class
|
||||
field: name of the function as a string
|
||||
replacement: the new function
|
||||
|
||||
Returns:
|
||||
the original function
|
||||
"""
|
||||
|
||||
patch_key = (obj, field)
|
||||
if patch_key in originals[key]:
|
||||
raise RuntimeError(f"patch for {field} is already applied")
|
||||
|
||||
if not hasattr(obj, field) and not add_if_not_exists:
|
||||
raise AttributeError(f"type {type(obj)} '{type.__name__}' has no attribute '{field}'")
|
||||
|
||||
original_func = getattr(obj, field, None)
|
||||
originals[key][patch_key] = original_func
|
||||
|
||||
setattr(obj, field, replacement)
|
||||
|
||||
return original_func
|
||||
|
||||
|
||||
def undo(key, obj, field):
|
||||
"""Undoes the peplacement by the patch().
|
||||
|
||||
If the function is not replaced, raises an exception.
|
||||
|
||||
Arguments:
|
||||
key: identifying information for who is doing the replacement. You can use __name__.
|
||||
obj: the module or the class
|
||||
field: name of the function as a string
|
||||
|
||||
Returns:
|
||||
Always None
|
||||
"""
|
||||
|
||||
patch_key = (obj, field)
|
||||
|
||||
if patch_key not in originals[key]:
|
||||
raise RuntimeError(f"there is no patch for {field} to undo")
|
||||
|
||||
original_func = originals[key].pop(patch_key)
|
||||
if original_func is None:
|
||||
delattr(obj, field)
|
||||
@@ -62,7 +48,6 @@ def undo(key, obj, field):
|
||||
def original(key, obj, field):
|
||||
"""Returns the original function for the patch created by the patch() function"""
|
||||
patch_key = (obj, field)
|
||||
|
||||
return originals[key].get(patch_key, None)
|
||||
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ def prepare_embedding_providers(pipe, clip_skip):
|
||||
provider = EmbeddingsProvider(tokenizer=pipe.tokenizer, text_encoder=pipe.text_encoder, truncate=False,
|
||||
returned_embeddings_type=embedding_type, device=device)
|
||||
embeddings_providers.append(provider)
|
||||
if hasattr(pipe, "tokenizer_2") and getattr(pipe, "text_encoder_2"):
|
||||
if hasattr(pipe, "tokenizer_2") and hasattr(pipe, "text_encoder_2"):
|
||||
provider = EmbeddingsProvider(tokenizer=pipe.tokenizer_2, text_encoder=pipe.text_encoder_2, truncate=False,
|
||||
returned_embeddings_type=embedding_type, device=device)
|
||||
embeddings_providers.append(provider)
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Union
|
||||
|
||||
import torch
|
||||
from diffusers.loaders.textual_inversion import (
|
||||
TextualInversionLoaderMixin,
|
||||
load_textual_inversion_state_dicts,
|
||||
logger,
|
||||
nn,
|
||||
)
|
||||
|
||||
from torch import nn
|
||||
from diffusers.loaders.textual_inversion import TextualInversionLoaderMixin, load_textual_inversion_state_dicts
|
||||
from modules import shared
|
||||
from modules.patches import patch_method
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from transformers import PreTrainedModel, PreTrainedTokenizer
|
||||
|
||||
try:
|
||||
from accelerate.hooks import AlignDevicesHook, CpuOffload, remove_hook_from_module
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@patch_method(TextualInversionLoaderMixin)
|
||||
def load_textual_inversion(
|
||||
self: TextualInversionLoaderMixin,
|
||||
@@ -28,12 +23,10 @@ def load_textual_inversion(
|
||||
text_encoder: Optional["PreTrainedModel"] = None,
|
||||
**kwargs, # pylint: disable=W0613
|
||||
):
|
||||
|
||||
# 1. Set correct tokenizer and text encoder
|
||||
tokenizer: PreTrainedTokenizer = tokenizer or getattr(self, "tokenizer", None)
|
||||
text_encoder: PreTrainedModel = text_encoder or getattr(self, "text_encoder", None)
|
||||
loaded_model_names_or_paths = {}
|
||||
|
||||
assert tokenizer and text_encoder, 'Can not resolve `tokenizer` or `text_encoder`'
|
||||
|
||||
# 2. Normalize inputs
|
||||
@@ -99,9 +92,7 @@ def load_textual_inversion(
|
||||
if hasattr(component, "_hf_hook"):
|
||||
is_model_cpu_offload = isinstance(getattr(component, "_hf_hook"), CpuOffload) # noqa: B009
|
||||
is_sequential_cpu_offload = isinstance(getattr(component, "_hf_hook"), AlignDevicesHook) # noqa: B009
|
||||
logger.info(
|
||||
"Accelerate hooks detected. Since you have called `load_textual_inversion()`, the previous hooks will be first removed. Then the textual inversion parameters will be loaded and the hooks will be applied again."
|
||||
)
|
||||
shared.log.debug("Accelerate hooks detected. Since you have called `load_textual_inversion()`, the previous hooks will be first removed. Then the textual inversion parameters will be loaded and the hooks will be applied again.")
|
||||
remove_hook_from_module(component, recurse=is_sequential_cpu_offload)
|
||||
|
||||
# 7.2 save expected device and dtype
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from typing import List, Optional, Union
|
||||
import csv
|
||||
import html
|
||||
import os
|
||||
@@ -17,8 +18,8 @@ from modules.textual_inversion.ti_logging import save_settings_to_file
|
||||
from typing import List, Optional, Union
|
||||
from modules.files_cache import directory_files, directory_mtime, extension_filter
|
||||
|
||||
TokenToAdd = namedtuple("TokenToAdd", ["clip_l", "clip_g"])
|
||||
|
||||
TokenToAdd = namedtuple("TokenToAdd", ["clip_l", "clip_g"])
|
||||
TextualInversionTemplate = namedtuple("TextualInversionTemplate", ["name", "path"])
|
||||
textual_inversion_templates = {}
|
||||
|
||||
|
||||
@@ -221,12 +221,14 @@ class PhotoMakerStableDiffusionXLPipeline(StableDiffusionXLPipeline):
|
||||
):
|
||||
device = device or self._execution_device
|
||||
|
||||
"""
|
||||
if prompt is not None and isinstance(prompt, str):
|
||||
batch_size = 1
|
||||
elif prompt is not None and isinstance(prompt, list):
|
||||
batch_size = len(prompt)
|
||||
else:
|
||||
batch_size = prompt_embeds.shape[0]
|
||||
"""
|
||||
|
||||
# Find the token id of the trigger word
|
||||
image_token_id = self.tokenizer_2.convert_tokens_to_ids(self.trigger_word)
|
||||
|
||||
Reference in New Issue
Block a user