mirror of
https://github.com/lllyasviel/Fooocus.git
synced 2026-08-16 13:13:16 +02:00
Merge branch 'main_upstream'
# Conflicts: # css/style.css # fooocus_colab.ipynb # fooocus_version.py # launch.py # modules/async_worker.py # modules/config.py # modules/flags.py # modules/meta_parser.py # webui.py
This commit is contained in:
+13
-19
@@ -1,5 +1,6 @@
|
||||
import threading
|
||||
import os
|
||||
import re
|
||||
from modules.patch import PatchSettings, patch_settings, patch_all
|
||||
|
||||
patch_all()
|
||||
@@ -49,8 +50,8 @@ def worker():
|
||||
from modules.sdxl_styles import apply_style, apply_wildcards, fooocus_expansion, apply_arrays
|
||||
from modules.private_logger import log
|
||||
from extras.expansion import safe_str
|
||||
from modules.util import remove_empty_str, HWC3, resize_image, \
|
||||
get_image_shape_ceil, set_image_shape_ceil, get_shape_ceil, resample_image, erode_or_dilate
|
||||
from modules.util import remove_empty_str, HWC3, resize_image, get_image_shape_ceil, set_image_shape_ceil, \
|
||||
get_shape_ceil, resample_image, erode_or_dilate, get_enabled_loras
|
||||
from modules.upscaler import perform_upscale
|
||||
from modules.flags import Performance
|
||||
from modules.meta_parser import get_metadata_parser, MetadataScheme
|
||||
@@ -131,14 +132,6 @@ def worker():
|
||||
async_task.results = async_task.results + [wall]
|
||||
return
|
||||
|
||||
def apply_enabled_loras(loras):
|
||||
enabled_loras = []
|
||||
for lora_enabled, lora_model, lora_weight in loras:
|
||||
if lora_enabled:
|
||||
enabled_loras.append([lora_model, lora_weight])
|
||||
|
||||
return enabled_loras
|
||||
|
||||
@torch.no_grad()
|
||||
@torch.inference_mode()
|
||||
def handler(async_task):
|
||||
@@ -157,12 +150,13 @@ def worker():
|
||||
image_number = args.pop()
|
||||
output_format = args.pop()
|
||||
image_seed = args.pop()
|
||||
read_wildcards_in_order = args.pop()
|
||||
sharpness = args.pop()
|
||||
guidance_scale = args.pop()
|
||||
base_model_name = args.pop()
|
||||
refiner_model_name = args.pop()
|
||||
refiner_switch = args.pop()
|
||||
loras = apply_enabled_loras([[bool(args.pop()), str(args.pop()), float(args.pop()), ] for _ in range(modules.config.default_max_lora_number)])
|
||||
loras = get_enabled_loras([[bool(args.pop()), str(args.pop()), float(args.pop())] for _ in range(modules.config.default_max_lora_number)])
|
||||
input_image_checkbox = args.pop()
|
||||
current_tab = args.pop()
|
||||
uov_method = args.pop()
|
||||
@@ -385,7 +379,7 @@ def worker():
|
||||
print(f'[Inpaint] Current inpaint model is {inpaint_patch_model_path}')
|
||||
if refiner_model_name == 'None':
|
||||
use_synthetic_refiner = True
|
||||
refiner_switch = 0.5
|
||||
refiner_switch = 0.8
|
||||
else:
|
||||
inpaint_head_model_path, inpaint_patch_model_path = None, None
|
||||
print(f'[Inpaint] Parameterized inpaint is disabled.')
|
||||
@@ -460,16 +454,16 @@ def worker():
|
||||
|
||||
for i in range(image_number):
|
||||
if disable_seed_increment:
|
||||
task_seed = seed
|
||||
task_seed = seed % (constants.MAX_SEED + 1)
|
||||
else:
|
||||
task_seed = (seed + i) % (constants.MAX_SEED + 1) # randint is inclusive, % is not
|
||||
|
||||
task_rng = random.Random(task_seed) # may bind to inpaint noise in the future
|
||||
task_prompt = apply_wildcards(prompt, task_rng)
|
||||
task_prompt = apply_wildcards(prompt, task_rng, i, read_wildcards_in_order)
|
||||
task_prompt = apply_arrays(task_prompt, i)
|
||||
task_negative_prompt = apply_wildcards(negative_prompt, task_rng)
|
||||
task_extra_positive_prompts = [apply_wildcards(pmt, task_rng) for pmt in extra_positive_prompts]
|
||||
task_extra_negative_prompts = [apply_wildcards(pmt, task_rng) for pmt in extra_negative_prompts]
|
||||
task_negative_prompt = apply_wildcards(negative_prompt, task_rng, i, read_wildcards_in_order)
|
||||
task_extra_positive_prompts = [apply_wildcards(pmt, task_rng, i, read_wildcards_in_order) for pmt in extra_positive_prompts]
|
||||
task_extra_negative_prompts = [apply_wildcards(pmt, task_rng, i, read_wildcards_in_order) for pmt in extra_negative_prompts]
|
||||
|
||||
positive_basic_workloads = []
|
||||
negative_basic_workloads = []
|
||||
@@ -827,7 +821,7 @@ def worker():
|
||||
|
||||
try:
|
||||
if async_task.last_stop is not False:
|
||||
ldm_patched.model_management.interrupt_current_processing()
|
||||
ldm_patched.modules.model_management.interrupt_current_processing()
|
||||
positive_cond, negative_cond = task['c'], task['uc']
|
||||
|
||||
if 'cn' in goals:
|
||||
@@ -902,7 +896,7 @@ def worker():
|
||||
|
||||
d.append(('Sampler', 'sampler', sampler_name))
|
||||
d.append(('Scheduler', 'scheduler', scheduler_name))
|
||||
d.append(('Seed', 'seed', task['task_seed']))
|
||||
d.append(('Seed', 'seed', str(task['task_seed'])))
|
||||
|
||||
if freeu_enabled:
|
||||
d.append(('FreeU', 'freeu', str((freeu_b1, freeu_b2, freeu_s1, freeu_s2))))
|
||||
|
||||
+68
-30
@@ -3,12 +3,14 @@ import json
|
||||
import math
|
||||
import numbers
|
||||
import args_manager
|
||||
import tempfile
|
||||
import modules.flags
|
||||
import modules.sdxl_styles
|
||||
|
||||
from modules.model_loader import load_file_from_url
|
||||
from modules.util import get_files_from_folder, makedirs_with_log
|
||||
from modules.flags import Performance, MetadataScheme
|
||||
from modules.flags import OutputFormat, Performance, MetadataScheme
|
||||
|
||||
|
||||
def get_config_path(key, default_value):
|
||||
env = os.getenv(key)
|
||||
@@ -18,6 +20,7 @@ def get_config_path(key, default_value):
|
||||
else:
|
||||
return os.path.abspath(default_value)
|
||||
|
||||
|
||||
config_path = get_config_path('config_path', "./config.txt")
|
||||
config_example_path = get_config_path('config_example_path', "config_modification_tutorial.txt")
|
||||
config_dict = {}
|
||||
@@ -94,7 +97,7 @@ def try_load_deprecated_user_path_config():
|
||||
|
||||
try_load_deprecated_user_path_config()
|
||||
|
||||
def list_presets():
|
||||
def get_presets():
|
||||
preset_folder = 'presets'
|
||||
presets = ['initial']
|
||||
if not os.path.exists(preset_folder):
|
||||
@@ -103,11 +106,11 @@ def list_presets():
|
||||
|
||||
return presets + [f[:f.index(".json")] for f in os.listdir(preset_folder) if f.endswith('.json')]
|
||||
|
||||
available_presets = list_presets()
|
||||
available_presets = get_presets()
|
||||
|
||||
def update_presets():
|
||||
global available_presets
|
||||
available_presets = list_presets()
|
||||
available_presets = get_presets()
|
||||
|
||||
def try_get_preset_content(preset):
|
||||
if isinstance(preset, str):
|
||||
@@ -125,26 +128,16 @@ def try_get_preset_content(preset):
|
||||
print(e)
|
||||
return {}
|
||||
|
||||
def try_load_preset_global(preset):
|
||||
global config_dict
|
||||
|
||||
if isinstance(preset, str):
|
||||
preset_path = os.path.abspath(f'./presets/{preset}.json')
|
||||
try:
|
||||
if os.path.exists(preset_path):
|
||||
with open(preset_path, "r", encoding="utf-8") as json_file:
|
||||
config_dict.update(json.load(json_file))
|
||||
print(f'Loaded preset: {preset_path}')
|
||||
else:
|
||||
raise FileNotFoundError
|
||||
except Exception as e:
|
||||
print(f'Load preset [{preset_path}] failed')
|
||||
print(e)
|
||||
|
||||
try:
|
||||
with open(os.path.abspath(f'./presets/default.json'), "r", encoding="utf-8") as json_file:
|
||||
config_dict.update(json.load(json_file))
|
||||
except Exception as e:
|
||||
print(f'Load default preset failed.')
|
||||
print(e)
|
||||
|
||||
available_presets = get_presets()
|
||||
preset = args_manager.args.preset
|
||||
try_load_preset_global(preset)
|
||||
|
||||
config_dict.update(try_get_preset_content(preset))
|
||||
|
||||
def get_path_output() -> str:
|
||||
"""
|
||||
@@ -153,7 +146,7 @@ def get_path_output() -> str:
|
||||
global config_dict
|
||||
path_output = get_dir_or_set_default('path_outputs', '../outputs/', make_directory=True)
|
||||
if args_manager.args.output_path:
|
||||
print(f'[CONFIG] Overriding config value path_outputs with {args_manager.args.output_path}')
|
||||
print(f'Overriding config value path_outputs with {args_manager.args.output_path}')
|
||||
config_dict['path_outputs'] = path_output = args_manager.args.output_path
|
||||
return path_output
|
||||
|
||||
@@ -213,6 +206,7 @@ path_controlnet = get_dir_or_set_default('path_controlnet', '../models/controlne
|
||||
path_clip_vision = get_dir_or_set_default('path_clip_vision', '../models/clip_vision/')
|
||||
path_fooocus_expansion = get_dir_or_set_default('path_fooocus_expansion', '../models/prompt_expansion/fooocus_expansion')
|
||||
path_safety_checker_models = get_dir_or_set_default('path_safety_checker_models', '../models/safety_checker_models/')
|
||||
path_wildcards = get_dir_or_set_default('path_wildcards', '../wildcards/')
|
||||
path_outputs = get_path_output()
|
||||
|
||||
def get_config_item_or_set_default(key, default_value, validator, disable_empty_as_none=False):
|
||||
@@ -243,6 +237,36 @@ def get_config_item_or_set_default(key, default_value, validator, disable_empty_
|
||||
return default_value
|
||||
|
||||
|
||||
def init_temp_path(path: str | None, default_path: str) -> str:
|
||||
if args_manager.args.temp_path:
|
||||
path = args_manager.args.temp_path
|
||||
|
||||
if path != '' and path != default_path:
|
||||
try:
|
||||
if not os.path.isabs(path):
|
||||
path = os.path.abspath(path)
|
||||
os.makedirs(path, exist_ok=True)
|
||||
print(f'Using temp path {path}')
|
||||
return path
|
||||
except Exception as e:
|
||||
print(f'Could not create temp path {path}. Reason: {e}')
|
||||
print(f'Using default temp path {default_path} instead.')
|
||||
|
||||
os.makedirs(default_path, exist_ok=True)
|
||||
return default_path
|
||||
|
||||
|
||||
default_temp_path = os.path.join(tempfile.gettempdir(), 'fooocus')
|
||||
temp_path = init_temp_path(get_config_item_or_set_default(
|
||||
key='temp_path',
|
||||
default_value=default_temp_path,
|
||||
validator=lambda x: isinstance(x, str),
|
||||
), default_temp_path)
|
||||
temp_path_cleanup_on_launch = get_config_item_or_set_default(
|
||||
key='temp_path_cleanup_on_launch',
|
||||
default_value=True,
|
||||
validator=lambda x: isinstance(x, bool)
|
||||
)
|
||||
default_base_model_name = default_model = get_config_item_or_set_default(
|
||||
key='default_model',
|
||||
default_value='model.safetensors',
|
||||
@@ -277,28 +301,37 @@ default_loras = get_config_item_or_set_default(
|
||||
key='default_loras',
|
||||
default_value=[
|
||||
[
|
||||
True,
|
||||
"None",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
True,
|
||||
"None",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
True,
|
||||
"None",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
True,
|
||||
"None",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
True,
|
||||
"None",
|
||||
1.0
|
||||
]
|
||||
],
|
||||
validator=lambda x: isinstance(x, list) and all(len(y) == 2 and isinstance(y[0], str) and isinstance(y[1], numbers.Number) for y in x)
|
||||
validator=lambda x: isinstance(x, list) and all(
|
||||
len(y) == 3 and isinstance(y[0], bool) and isinstance(y[1], str) and isinstance(y[2], numbers.Number)
|
||||
or len(y) == 2 and isinstance(y[0], str) and isinstance(y[1], numbers.Number)
|
||||
for y in x)
|
||||
)
|
||||
default_loras = [(y[0], y[1], y[2]) if len(y) == 3 else (True, y[0], y[1]) for y in default_loras]
|
||||
default_max_lora_number = get_config_item_or_set_default(
|
||||
key='default_max_lora_number',
|
||||
default_value=len(default_loras) if isinstance(default_loras, list) and len(default_loras) > 0 else 5,
|
||||
@@ -363,7 +396,7 @@ default_max_image_number = get_config_item_or_set_default(
|
||||
default_output_format = get_config_item_or_set_default(
|
||||
key='default_output_format',
|
||||
default_value='png',
|
||||
validator=lambda x: x in modules.flags.output_formats
|
||||
validator=lambda x: x in OutputFormat.list()
|
||||
)
|
||||
default_image_number = get_config_item_or_set_default(
|
||||
key='default_image_number',
|
||||
@@ -540,22 +573,27 @@ with open(config_example_path, "w", encoding="utf-8") as json_file:
|
||||
|
||||
model_filenames = []
|
||||
lora_filenames = []
|
||||
wildcard_filenames = []
|
||||
|
||||
sdxl_lcm_lora = 'sdxl_lcm_lora.safetensors'
|
||||
sdxl_lightning_lora = 'sdxl_lightning_4step_lora.safetensors'
|
||||
|
||||
|
||||
def get_model_filenames(folder_paths, name_filter=None):
|
||||
extensions = ['.pth', '.ckpt', '.bin', '.safetensors', '.fooocus.patch']
|
||||
def get_model_filenames(folder_paths, extensions=None, name_filter=None):
|
||||
if extensions is None:
|
||||
extensions = ['.pth', '.ckpt', '.bin', '.safetensors', '.fooocus.patch']
|
||||
files = []
|
||||
for folder in folder_paths:
|
||||
files += get_files_from_folder(folder, extensions, name_filter)
|
||||
return files
|
||||
|
||||
|
||||
def update_all_model_names():
|
||||
global model_filenames, lora_filenames
|
||||
def update_files():
|
||||
global model_filenames, lora_filenames, wildcard_filenames, available_presets
|
||||
model_filenames = get_model_filenames(paths_checkpoints)
|
||||
lora_filenames = get_model_filenames(paths_loras)
|
||||
wildcard_filenames = get_files_from_folder(path_wildcards, ['.txt'])
|
||||
available_presets = get_presets()
|
||||
return
|
||||
|
||||
|
||||
@@ -679,4 +717,4 @@ def downloading_upscale_model():
|
||||
return os.path.join(path_upscale_models, 'fooocus_upscaler_s409985e5.bin')
|
||||
|
||||
|
||||
update_all_model_names()
|
||||
update_files()
|
||||
|
||||
+5
-5
@@ -73,14 +73,14 @@ class StableDiffusionModel:
|
||||
|
||||
loras_to_load = []
|
||||
|
||||
for name, weight in loras:
|
||||
if name == 'None':
|
||||
for filename, weight in loras:
|
||||
if filename == 'None':
|
||||
continue
|
||||
|
||||
if os.path.exists(name):
|
||||
lora_filename = name
|
||||
if os.path.exists(filename):
|
||||
lora_filename = filename
|
||||
else:
|
||||
lora_filename = get_file_from_folder_list(name, modules.config.paths_loras)
|
||||
lora_filename = get_file_from_folder_list(filename, modules.config.paths_loras)
|
||||
|
||||
if not os.path.exists(lora_filename):
|
||||
print(f'Lora file not found: {lora_filename}')
|
||||
|
||||
@@ -11,7 +11,7 @@ from extras.expansion import FooocusExpansion
|
||||
|
||||
from ldm_patched.modules.model_base import SDXL, SDXLRefiner
|
||||
from modules.sample_hijack import clip_separate
|
||||
from modules.util import get_file_from_folder_list
|
||||
from modules.util import get_file_from_folder_list, get_enabled_loras
|
||||
|
||||
|
||||
model_base = core.StableDiffusionModel()
|
||||
@@ -254,7 +254,7 @@ def refresh_everything(refiner_model_name, base_model_name, loras,
|
||||
refresh_everything(
|
||||
refiner_model_name=modules.config.default_refiner_model_name,
|
||||
base_model_name=modules.config.default_base_model_name,
|
||||
loras=modules.config.default_loras
|
||||
loras=get_enabled_loras(modules.config.default_loras)
|
||||
)
|
||||
|
||||
|
||||
|
||||
+17
-1
@@ -67,7 +67,7 @@ default_parameters = {
|
||||
cn_ip: (0.5, 0.6), cn_ip_face: (0.9, 0.75), cn_canny: (0.5, 1.0), cn_cpds: (0.5, 1.0)
|
||||
} # stop, weight
|
||||
|
||||
output_formats = ['png', 'jpg', 'webp']
|
||||
output_formats = ['png', 'jpeg', 'webp']
|
||||
|
||||
inpaint_mask_models = ['u2net', 'u2netp', 'u2net_human_seg', 'u2net_cloth_seg', 'silueta', 'isnet-general-use', 'isnet-anime', 'sam']
|
||||
inpaint_mask_cloth_category = ['full', 'upper', 'lower']
|
||||
@@ -96,6 +96,16 @@ metadata_scheme = [
|
||||
controlnet_image_count = 4
|
||||
|
||||
|
||||
class OutputFormat(Enum):
|
||||
PNG = 'png'
|
||||
JPEG = 'jpeg'
|
||||
WEBP = 'webp'
|
||||
|
||||
@classmethod
|
||||
def list(cls) -> list:
|
||||
return list(map(lambda c: c.value, cls))
|
||||
|
||||
|
||||
class Steps(IntEnum):
|
||||
QUALITY = 60
|
||||
SPEED = 30
|
||||
@@ -120,6 +130,12 @@ class Performance(Enum):
|
||||
def list(cls) -> list:
|
||||
return list(map(lambda c: c.value, cls))
|
||||
|
||||
@classmethod
|
||||
def has_restricted_features(cls, x) -> bool:
|
||||
if isinstance(x, Performance):
|
||||
x = x.value
|
||||
return x in [cls.EXTREME_SPEED.value, cls.LIGHTNING.value]
|
||||
|
||||
def steps(self) -> int | None:
|
||||
return Steps[self.name].value if Steps[self.name] else None
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ from gradio_client.documentation import document, set_documentation_group
|
||||
from gradio_client.serializing import ImgSerializable
|
||||
from PIL import Image as _Image # using _ to minimize namespace pollution
|
||||
|
||||
from gradio import processing_utils, utils
|
||||
from gradio import processing_utils, utils, Error
|
||||
from gradio.components.base import IOComponent, _Keywords, Block
|
||||
from gradio.deprecation import warn_style_method_deprecation
|
||||
from gradio.events import (
|
||||
@@ -275,7 +275,10 @@ class Image(
|
||||
x, mask = x["image"], x["mask"]
|
||||
|
||||
assert isinstance(x, str)
|
||||
im = processing_utils.decode_base64_to_image(x)
|
||||
try:
|
||||
im = processing_utils.decode_base64_to_image(x)
|
||||
except PIL.UnidentifiedImageError:
|
||||
raise Error("Unsupported image type in input")
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
im = im.convert(self.image_mode)
|
||||
|
||||
-133
@@ -1,136 +1,3 @@
|
||||
css = '''
|
||||
.loader-container {
|
||||
display: flex; /* Use flex to align items horizontally */
|
||||
align-items: center; /* Center items vertically within the container */
|
||||
white-space: nowrap; /* Prevent line breaks within the container */
|
||||
}
|
||||
|
||||
.loader {
|
||||
border: 8px solid #f3f3f3; /* Light grey */
|
||||
border-top: 8px solid #3498db; /* Blue */
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* Style the progress bar */
|
||||
progress {
|
||||
appearance: none; /* Remove default styling */
|
||||
height: 20px; /* Set the height of the progress bar */
|
||||
border-radius: 5px; /* Round the corners of the progress bar */
|
||||
background-color: #f3f3f3; /* Light grey background */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Style the progress bar container */
|
||||
.progress-container {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
flex-grow: 1; /* Allow the progress container to take up remaining space */
|
||||
}
|
||||
|
||||
/* Set the color of the progress bar fill */
|
||||
progress::-webkit-progress-value {
|
||||
background-color: #3498db; /* Blue color for the fill */
|
||||
}
|
||||
|
||||
progress::-moz-progress-bar {
|
||||
background-color: #3498db; /* Blue color for the fill in Firefox */
|
||||
}
|
||||
|
||||
/* Style the text on the progress bar */
|
||||
progress::after {
|
||||
content: attr(value '%'); /* Display the progress value followed by '%' */
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white; /* Set text color */
|
||||
font-size: 14px; /* Set font size */
|
||||
}
|
||||
|
||||
/* Style other texts */
|
||||
.loader-container > span {
|
||||
margin-left: 5px; /* Add spacing between the progress bar and the text */
|
||||
}
|
||||
|
||||
.progress-bar > .generating {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.progress-bar{
|
||||
height: 30px !important;
|
||||
}
|
||||
|
||||
.type_row{
|
||||
height: 80px !important;
|
||||
}
|
||||
|
||||
.type_row_half{
|
||||
height: 32px !important;
|
||||
}
|
||||
|
||||
.scroll-hide{
|
||||
resize: none !important;
|
||||
}
|
||||
|
||||
.refresh_button{
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
font-size: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.advanced_check_row{
|
||||
width: 250px !important;
|
||||
}
|
||||
|
||||
.min_check{
|
||||
min-width: min(1px, 100%) !important;
|
||||
}
|
||||
|
||||
.resizable_area {
|
||||
resize: vertical;
|
||||
overflow: auto !important;
|
||||
}
|
||||
|
||||
.aspect_ratios label {
|
||||
width: 140px !important;
|
||||
}
|
||||
|
||||
.aspect_ratios label span {
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
.aspect_ratios label input {
|
||||
margin-left: -5px !important;
|
||||
}
|
||||
|
||||
.lora_enable label {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.lora_enable label input {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.lora_enable label span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@-moz-document url-prefix() {
|
||||
.lora_weight input[type=number] {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
'''
|
||||
progress_html = '''
|
||||
<div class="loader-container">
|
||||
<div class="loader"></div>
|
||||
|
||||
+17
-3
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import importlib
|
||||
import importlib.util
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import re
|
||||
@@ -9,9 +10,6 @@ import importlib.metadata
|
||||
import packaging.version
|
||||
from packaging.requirements import Requirement
|
||||
|
||||
|
||||
|
||||
|
||||
logging.getLogger("torch.distributed.nn").setLevel(logging.ERROR) # sshh...
|
||||
logging.getLogger("xformers").addFilter(lambda record: 'A matching Triton is not available' not in record.getMessage())
|
||||
|
||||
@@ -101,3 +99,19 @@ def requirements_met(requirements_file):
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def delete_folder_content(folder, prefix=None):
|
||||
result = True
|
||||
|
||||
for filename in os.listdir(folder):
|
||||
file_path = os.path.join(folder, filename)
|
||||
try:
|
||||
if os.path.isfile(file_path) or os.path.islink(file_path):
|
||||
os.unlink(file_path)
|
||||
elif os.path.isdir(file_path):
|
||||
shutil.rmtree(file_path)
|
||||
except Exception as e:
|
||||
print(f'{prefix}Failed to delete {file_path}. Reason: {e}')
|
||||
result = False
|
||||
|
||||
return result
|
||||
+9
-10
@@ -376,7 +376,7 @@ class A1111MetadataParser(MetadataParser):
|
||||
data[key] = filename
|
||||
break
|
||||
|
||||
if 'lora_hashes' in data:
|
||||
if 'lora_hashes' in data and data['lora_hashes'] != '':
|
||||
lora_filenames = modules.config.lora_filenames.copy()
|
||||
if modules.config.sdxl_lcm_lora in lora_filenames:
|
||||
lora_filenames.remove(modules.config.sdxl_lcm_lora)
|
||||
@@ -430,16 +430,15 @@ class A1111MetadataParser(MetadataParser):
|
||||
if key in data:
|
||||
generation_params[self.fooocus_to_a1111[key]] = data[key]
|
||||
|
||||
lora_hashes = []
|
||||
for index, (lora_name, lora_weight, lora_hash) in enumerate(self.loras):
|
||||
# workaround for Fooocus not knowing LoRA name in LoRA metadata
|
||||
lora_hashes.append(f'{lora_name}: {lora_hash}: {lora_weight}')
|
||||
lora_hashes_string = ', '.join(lora_hashes)
|
||||
if len(self.loras) > 0:
|
||||
lora_hashes = []
|
||||
for index, (lora_name, lora_weight, lora_hash) in enumerate(self.loras):
|
||||
# workaround for Fooocus not knowing LoRA name in LoRA metadata
|
||||
lora_hashes.append(f'{lora_name}: {lora_hash}: {lora_weight}')
|
||||
lora_hashes_string = ', '.join(lora_hashes)
|
||||
generation_params[self.fooocus_to_a1111['lora_hashes']] = lora_hashes_string
|
||||
|
||||
generation_params |= {
|
||||
self.fooocus_to_a1111['lora_hashes']: lora_hashes_string,
|
||||
self.fooocus_to_a1111['version']: data['version']
|
||||
}
|
||||
generation_params[self.fooocus_to_a1111['version']] = data['version']
|
||||
|
||||
if modules.config.metadata_created_by != '':
|
||||
generation_params[self.fooocus_to_a1111['created_by']] = modules.config.metadata_created_by
|
||||
|
||||
@@ -6,8 +6,9 @@ import urllib.parse
|
||||
|
||||
from PIL import Image
|
||||
from PIL.PngImagePlugin import PngInfo
|
||||
from modules.util import generate_temp_filename
|
||||
from modules.flags import OutputFormat
|
||||
from modules.meta_parser import MetadataParser, get_exif
|
||||
from modules.util import generate_temp_filename
|
||||
|
||||
log_cache = {}
|
||||
|
||||
@@ -21,7 +22,7 @@ def get_current_html_path(output_format=None):
|
||||
|
||||
|
||||
def log(img, metadata, metadata_parser: MetadataParser | None = None, output_format=None) -> str:
|
||||
path_outputs = args_manager.args.temp_path if args_manager.args.disable_image_log else modules.config.path_outputs
|
||||
path_outputs = modules.config.temp_path if args_manager.args.disable_image_log else modules.config.path_outputs
|
||||
output_format = output_format if output_format else modules.config.default_output_format
|
||||
date_string, local_temp_filename, only_name = generate_temp_filename(folder=path_outputs, extension=output_format)
|
||||
os.makedirs(os.path.dirname(local_temp_filename), exist_ok=True)
|
||||
@@ -29,7 +30,7 @@ def log(img, metadata, metadata_parser: MetadataParser | None = None, output_for
|
||||
parsed_parameters = metadata_parser.parse_string(metadata.copy()) if metadata_parser is not None else ''
|
||||
image = Image.fromarray(img)
|
||||
|
||||
if output_format == 'png':
|
||||
if output_format == OutputFormat.PNG.value:
|
||||
if parsed_parameters != '':
|
||||
pnginfo = PngInfo()
|
||||
pnginfo.add_text('parameters', parsed_parameters)
|
||||
@@ -37,9 +38,9 @@ def log(img, metadata, metadata_parser: MetadataParser | None = None, output_for
|
||||
else:
|
||||
pnginfo = None
|
||||
image.save(local_temp_filename, pnginfo=pnginfo)
|
||||
elif output_format == 'jpg':
|
||||
elif output_format == OutputFormat.JPEG.value:
|
||||
image.save(local_temp_filename, quality=95, optimize=True, progressive=True, exif=get_exif(parsed_parameters, metadata_parser.get_scheme().value) if metadata_parser else Image.Exif())
|
||||
elif output_format == 'webp':
|
||||
elif output_format == OutputFormat.WEBP.value:
|
||||
image.save(local_temp_filename, quality=95, lossless=False, exif=get_exif(parsed_parameters, metadata_parser.get_scheme().value) if metadata_parser else Image.Exif())
|
||||
else:
|
||||
image.save(local_temp_filename)
|
||||
|
||||
+10
-6
@@ -2,13 +2,12 @@ import os
|
||||
import re
|
||||
import json
|
||||
import math
|
||||
import modules.config
|
||||
|
||||
from modules.util import get_files_from_folder
|
||||
|
||||
|
||||
# cannot use modules.config - validators causing circular imports
|
||||
styles_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../sdxl_styles/'))
|
||||
wildcards_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../wildcards/'))
|
||||
wildcards_max_bfs_depth = 64
|
||||
|
||||
|
||||
@@ -60,7 +59,7 @@ def apply_style(style, positive):
|
||||
return p.replace('{prompt}', positive).splitlines(), n.splitlines()
|
||||
|
||||
|
||||
def apply_wildcards(wildcard_text, rng, directory=wildcards_path):
|
||||
def apply_wildcards(wildcard_text, rng, i, read_wildcards_in_order):
|
||||
for _ in range(wildcards_max_bfs_depth):
|
||||
placeholders = re.findall(r'__([\w-]+)__', wildcard_text)
|
||||
if len(placeholders) == 0:
|
||||
@@ -69,10 +68,14 @@ def apply_wildcards(wildcard_text, rng, directory=wildcards_path):
|
||||
print(f'[Wildcards] processing: {wildcard_text}')
|
||||
for placeholder in placeholders:
|
||||
try:
|
||||
words = open(os.path.join(directory, f'{placeholder}.txt'), encoding='utf-8').read().splitlines()
|
||||
matches = [x for x in modules.config.wildcard_filenames if os.path.splitext(os.path.basename(x))[0] == placeholder]
|
||||
words = open(os.path.join(modules.config.path_wildcards, matches[0]), encoding='utf-8').read().splitlines()
|
||||
words = [x for x in words if x != '']
|
||||
assert len(words) > 0
|
||||
wildcard_text = wildcard_text.replace(f'__{placeholder}__', rng.choice(words), 1)
|
||||
if read_wildcards_in_order:
|
||||
wildcard_text = wildcard_text.replace(f'__{placeholder}__', words[i % len(words)], 1)
|
||||
else:
|
||||
wildcard_text = wildcard_text.replace(f'__{placeholder}__', rng.choice(words), 1)
|
||||
except:
|
||||
print(f'[Wildcards] Warning: {placeholder}.txt missing or empty. '
|
||||
f'Using "{placeholder}" as a normal word.')
|
||||
@@ -82,8 +85,9 @@ def apply_wildcards(wildcard_text, rng, directory=wildcards_path):
|
||||
print(f'[Wildcards] BFS stack overflow. Current text: {wildcard_text}')
|
||||
return wildcard_text
|
||||
|
||||
|
||||
def get_words(arrays, totalMult, index):
|
||||
if(len(arrays) == 1):
|
||||
if len(arrays) == 1:
|
||||
return [arrays[0].split(',')[index]]
|
||||
else:
|
||||
words = arrays[0].split(',')
|
||||
|
||||
+6
-2
@@ -163,7 +163,7 @@ def generate_temp_filename(folder='./outputs/', extension='png'):
|
||||
return date_string, os.path.abspath(result), filename
|
||||
|
||||
|
||||
def get_files_from_folder(folder_path, exensions=None, name_filter=None):
|
||||
def get_files_from_folder(folder_path, extensions=None, name_filter=None):
|
||||
if not os.path.isdir(folder_path):
|
||||
raise ValueError("Folder path is not a valid directory.")
|
||||
|
||||
@@ -175,7 +175,7 @@ def get_files_from_folder(folder_path, exensions=None, name_filter=None):
|
||||
relative_path = ""
|
||||
for filename in sorted(files, key=lambda s: s.casefold()):
|
||||
_, file_extension = os.path.splitext(filename)
|
||||
if (exensions is None or file_extension.lower() in exensions) and (name_filter is None or name_filter in _):
|
||||
if (extensions is None or file_extension.lower() in extensions) and (name_filter is None or name_filter in _):
|
||||
path = os.path.join(relative_path, filename)
|
||||
filenames.append(path)
|
||||
|
||||
@@ -360,3 +360,7 @@ def makedirs_with_log(path):
|
||||
os.makedirs(path, exist_ok=True)
|
||||
except OSError as error:
|
||||
print(f'Directory {path} could not be created, reason: {error}')
|
||||
|
||||
|
||||
def get_enabled_loras(loras: list) -> list:
|
||||
return [[lora[1], lora[2]] for lora in loras if lora[0]]
|
||||
|
||||
Reference in New Issue
Block a user