mirror of
https://github.com/lllyasviel/Fooocus.git
synced 2026-08-16 13:13:16 +02:00
Merge branch 'main' of https://github.com/lllyasviel/Fooocus into lora-reference-parsing
This commit is contained in:
+58
-32
@@ -1,4 +1,5 @@
|
||||
import threading
|
||||
import re
|
||||
from modules.patch import PatchSettings, patch_settings, patch_all
|
||||
|
||||
patch_all()
|
||||
@@ -45,6 +46,7 @@ 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
|
||||
<<<<<<< HEAD
|
||||
from modules.util import (
|
||||
remove_empty_str,
|
||||
HWC3, resize_image,
|
||||
@@ -56,6 +58,10 @@ def worker():
|
||||
ordinal_suffix,
|
||||
parse_lora_references_from_prompt
|
||||
)
|
||||
=======
|
||||
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, ordinal_suffix, get_enabled_loras
|
||||
>>>>>>> 978267f461e204c6c4359a79ed818ee2e3e1af39
|
||||
from modules.upscaler import perform_upscale
|
||||
from modules.flags import Performance
|
||||
from modules.meta_parser import get_metadata_parser, MetadataScheme
|
||||
@@ -132,14 +138,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,14 +155,19 @@ 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()
|
||||
<<<<<<< HEAD
|
||||
|
||||
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)])
|
||||
>>>>>>> 978267f461e204c6c4359a79ed818ee2e3e1af39
|
||||
input_image_checkbox = args.pop()
|
||||
current_tab = args.pop()
|
||||
uov_method = args.pop()
|
||||
@@ -261,6 +264,25 @@ def worker():
|
||||
adm_scaler_negative = 1.0
|
||||
adm_scaler_end = 0.0
|
||||
|
||||
elif performance_selection == Performance.LIGHTNING:
|
||||
print('Enter Lightning mode.')
|
||||
progressbar(async_task, 1, 'Downloading Lightning components ...')
|
||||
loras += [(modules.config.downloading_sdxl_lightning_lora(), 1.0)]
|
||||
|
||||
if refiner_model_name != 'None':
|
||||
print(f'Refiner disabled in Lightning mode.')
|
||||
|
||||
refiner_model_name = 'None'
|
||||
sampler_name = 'euler'
|
||||
scheduler_name = 'sgm_uniform'
|
||||
sharpness = 0.0
|
||||
guidance_scale = 1.0
|
||||
adaptive_cfg = 1.0
|
||||
refiner_switch = 1.0
|
||||
adm_scaler_positive = 1.0
|
||||
adm_scaler_negative = 1.0
|
||||
adm_scaler_end = 0.0
|
||||
|
||||
print(f'[Parameters] Adaptive CFG = {adaptive_cfg}')
|
||||
print(f'[Parameters] Sharpness = {sharpness}')
|
||||
print(f'[Parameters] ControlNet Softness = {controlnet_softness}')
|
||||
@@ -358,7 +380,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.')
|
||||
@@ -437,16 +459,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 = []
|
||||
@@ -802,7 +824,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:
|
||||
@@ -845,17 +867,21 @@ def worker():
|
||||
('Negative Prompt', 'negative_prompt', task['log_negative_prompt']),
|
||||
('Fooocus V2 Expansion', 'prompt_expansion', task['expansion']),
|
||||
('Styles', 'styles', str(raw_style_selections)),
|
||||
('Performance', 'performance', performance_selection.value),
|
||||
('Resolution', 'resolution', str((width, height))),
|
||||
('Guidance Scale', 'guidance_scale', guidance_scale),
|
||||
('Sharpness', 'sharpness', sharpness),
|
||||
('ADM Guidance', 'adm_guidance', str((
|
||||
modules.patch.patch_settings[pid].positive_adm_scale,
|
||||
modules.patch.patch_settings[pid].negative_adm_scale,
|
||||
modules.patch.patch_settings[pid].adm_scaler_end))),
|
||||
('Base Model', 'base_model', base_model_name),
|
||||
('Refiner Model', 'refiner_model', refiner_model_name),
|
||||
('Refiner Switch', 'refiner_switch', refiner_switch)]
|
||||
('Performance', 'performance', performance_selection.value)]
|
||||
|
||||
if performance_selection.steps() != steps:
|
||||
d.append(('Steps', 'steps', steps))
|
||||
|
||||
d += [('Resolution', 'resolution', str((width, height))),
|
||||
('Guidance Scale', 'guidance_scale', guidance_scale),
|
||||
('Sharpness', 'sharpness', sharpness),
|
||||
('ADM Guidance', 'adm_guidance', str((
|
||||
modules.patch.patch_settings[pid].positive_adm_scale,
|
||||
modules.patch.patch_settings[pid].negative_adm_scale,
|
||||
modules.patch.patch_settings[pid].adm_scaler_end))),
|
||||
('Base Model', 'base_model', base_model_name),
|
||||
('Refiner Model', 'refiner_model', refiner_model_name),
|
||||
('Refiner Switch', 'refiner_switch', refiner_switch)]
|
||||
|
||||
if refiner_model_name != 'None':
|
||||
if overwrite_switch > 0:
|
||||
@@ -867,22 +893,22 @@ 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))))
|
||||
|
||||
for li, (n, w) in enumerate(loras):
|
||||
if n != 'None':
|
||||
d.append((f'LoRA {li + 1}', f'lora_combined_{li + 1}', f'{n} : {w}'))
|
||||
|
||||
metadata_parser = None
|
||||
if save_metadata_to_images:
|
||||
metadata_parser = modules.meta_parser.get_metadata_parser(metadata_scheme)
|
||||
metadata_parser.set_data(task['log_positive_prompt'], task['positive'],
|
||||
task['log_negative_prompt'], task['negative'],
|
||||
steps, base_model_name, refiner_model_name, loras)
|
||||
|
||||
for li, (n, w) in enumerate(loras):
|
||||
if n != 'None':
|
||||
d.append((f'LoRA {li + 1}', f'lora_combined_{li + 1}', f'{n} : {w}'))
|
||||
|
||||
d.append(('Metadata Scheme', 'metadata_scheme', metadata_scheme.value if save_metadata_to_images else save_metadata_to_images))
|
||||
d.append(('Version', 'version', 'Fooocus v' + fooocus_version.version))
|
||||
img_paths.append(log(x, d, metadata_parser, output_format))
|
||||
|
||||
|
||||
+124
-50
@@ -3,13 +3,15 @@ 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 makedirs_with_log
|
||||
from modules.path_utils import get_files_from_folder
|
||||
from modules.flags import Performance, MetadataScheme
|
||||
from modules.flags import OutputFormat, Performance, MetadataScheme
|
||||
|
||||
def get_config_path(key, default_value):
|
||||
env = os.getenv(key)
|
||||
@@ -19,6 +21,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 = {}
|
||||
@@ -95,21 +98,36 @@ def try_load_deprecated_user_path_config():
|
||||
|
||||
try_load_deprecated_user_path_config()
|
||||
|
||||
|
||||
def get_presets():
|
||||
preset_folder = 'presets'
|
||||
presets = ['initial']
|
||||
if not os.path.exists(preset_folder):
|
||||
print('No presets found.')
|
||||
return presets
|
||||
|
||||
return presets + [f[:f.index('.json')] for f in os.listdir(preset_folder) if f.endswith('.json')]
|
||||
|
||||
|
||||
def try_get_preset_content(preset):
|
||||
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:
|
||||
json_content = json.load(json_file)
|
||||
print(f'Loaded preset: {preset_path}')
|
||||
return json_content
|
||||
else:
|
||||
raise FileNotFoundError
|
||||
except Exception as e:
|
||||
print(f'Load preset [{preset_path}] failed')
|
||||
print(e)
|
||||
return {}
|
||||
|
||||
available_presets = get_presets()
|
||||
preset = args_manager.args.preset
|
||||
|
||||
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)
|
||||
|
||||
config_dict.update(try_get_preset_content(preset))
|
||||
|
||||
def get_path_output() -> str:
|
||||
"""
|
||||
@@ -118,7 +136,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
|
||||
|
||||
@@ -177,8 +195,10 @@ path_inpaint = get_dir_or_set_default('path_inpaint', '../models/inpaint/')
|
||||
path_controlnet = get_dir_or_set_default('path_controlnet', '../models/controlnet/')
|
||||
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_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):
|
||||
global config_dict, visited_keys
|
||||
|
||||
@@ -207,7 +227,37 @@ def get_config_item_or_set_default(key, default_value, validator, disable_empty_
|
||||
return default_value
|
||||
|
||||
|
||||
default_base_model_name = get_config_item_or_set_default(
|
||||
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',
|
||||
validator=lambda x: isinstance(x, str)
|
||||
@@ -217,7 +267,7 @@ previous_default_models = get_config_item_or_set_default(
|
||||
default_value=[],
|
||||
validator=lambda x: isinstance(x, list) and all(isinstance(k, str) for k in x)
|
||||
)
|
||||
default_refiner_model_name = get_config_item_or_set_default(
|
||||
default_refiner_model_name = default_refiner = get_config_item_or_set_default(
|
||||
key='default_refiner',
|
||||
default_value='None',
|
||||
validator=lambda x: isinstance(x, str)
|
||||
@@ -241,31 +291,40 @@ 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),
|
||||
default_value=len(default_loras) if isinstance(default_loras, list) and len(default_loras) > 0 else 5,
|
||||
validator=lambda x: isinstance(x, int) and x >= 1
|
||||
)
|
||||
default_cfg_scale = get_config_item_or_set_default(
|
||||
@@ -327,7 +386,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',
|
||||
@@ -410,31 +469,32 @@ metadata_created_by = get_config_item_or_set_default(
|
||||
|
||||
example_inpaint_prompts = [[x] for x in example_inpaint_prompts]
|
||||
|
||||
config_dict["default_loras"] = default_loras = default_loras[:default_max_lora_number] + [['None', 1.0] for _ in range(default_max_lora_number - len(default_loras))]
|
||||
|
||||
possible_preset_keys = [
|
||||
"default_model",
|
||||
"default_refiner",
|
||||
"default_refiner_switch",
|
||||
"default_loras_min_weight",
|
||||
"default_loras_max_weight",
|
||||
"default_loras",
|
||||
"default_max_lora_number",
|
||||
"default_cfg_scale",
|
||||
"default_sample_sharpness",
|
||||
"default_sampler",
|
||||
"default_scheduler",
|
||||
"default_performance",
|
||||
"default_prompt",
|
||||
"default_prompt_negative",
|
||||
"default_styles",
|
||||
"default_aspect_ratio",
|
||||
"default_save_metadata_to_images",
|
||||
"checkpoint_downloads",
|
||||
"embeddings_downloads",
|
||||
"lora_downloads",
|
||||
]
|
||||
config_dict["default_loras"] = default_loras = default_loras[:default_max_lora_number] + [[True, 'None', 1.0] for _ in range(default_max_lora_number - len(default_loras))]
|
||||
|
||||
# mapping config to meta parameter
|
||||
possible_preset_keys = {
|
||||
"default_model": "base_model",
|
||||
"default_refiner": "refiner_model",
|
||||
"default_refiner_switch": "refiner_switch",
|
||||
"previous_default_models": "previous_default_models",
|
||||
"default_loras_min_weight": "default_loras_min_weight",
|
||||
"default_loras_max_weight": "default_loras_max_weight",
|
||||
"default_loras": "<processed>",
|
||||
"default_cfg_scale": "guidance_scale",
|
||||
"default_sample_sharpness": "sharpness",
|
||||
"default_sampler": "sampler",
|
||||
"default_scheduler": "scheduler",
|
||||
"default_overwrite_step": "steps",
|
||||
"default_performance": "performance",
|
||||
"default_prompt": "prompt",
|
||||
"default_prompt_negative": "negative_prompt",
|
||||
"default_styles": "styles",
|
||||
"default_aspect_ratio": "resolution",
|
||||
"default_save_metadata_to_images": "default_save_metadata_to_images",
|
||||
"checkpoint_downloads": "checkpoint_downloads",
|
||||
"embeddings_downloads": "embeddings_downloads",
|
||||
"lora_downloads": "lora_downloads"
|
||||
}
|
||||
|
||||
REWRITE_PRESET = False
|
||||
|
||||
@@ -475,21 +535,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
|
||||
|
||||
|
||||
@@ -539,6 +605,14 @@ def downloading_sdxl_lcm_lora():
|
||||
)
|
||||
return sdxl_lcm_lora
|
||||
|
||||
def downloading_sdxl_lightning_lora():
|
||||
load_file_from_url(
|
||||
url='https://huggingface.co/ByteDance/SDXL-Lightning/resolve/main/sdxl_lightning_4step_lora.safetensors',
|
||||
model_dir=paths_loras[0],
|
||||
file_name=sdxl_lightning_lora
|
||||
)
|
||||
return sdxl_lightning_lora
|
||||
|
||||
|
||||
def downloading_controlnet_canny():
|
||||
load_file_from_url(
|
||||
@@ -605,4 +679,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)
|
||||
)
|
||||
|
||||
|
||||
|
||||
+20
-6
@@ -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_engine_versions = ['None', 'v1', 'v2.5', 'v2.6']
|
||||
inpaint_option_default = 'Inpaint or Outpaint (default)'
|
||||
@@ -89,37 +89,51 @@ metadata_scheme = [
|
||||
(f'{MetadataScheme.A1111.value} (plain text)', MetadataScheme.A1111.value),
|
||||
]
|
||||
|
||||
lora_count = 5
|
||||
|
||||
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
|
||||
EXTREME_SPEED = 8
|
||||
LIGHTNING = 4
|
||||
|
||||
|
||||
class StepsUOV(IntEnum):
|
||||
QUALITY = 36
|
||||
SPEED = 18
|
||||
EXTREME_SPEED = 8
|
||||
LIGHTNING = 4
|
||||
|
||||
|
||||
class Performance(Enum):
|
||||
QUALITY = 'Quality'
|
||||
SPEED = 'Speed'
|
||||
EXTREME_SPEED = 'Extreme Speed'
|
||||
LIGHTNING = 'Lightning'
|
||||
|
||||
@classmethod
|
||||
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
|
||||
|
||||
def steps_uov(self) -> int | None:
|
||||
return StepsUOV[self.name].value if Steps[self.name] else None
|
||||
|
||||
|
||||
performance_selections = Performance.list()
|
||||
|
||||
@@ -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)
|
||||
|
||||
-139
@@ -1,142 +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 {
|
||||
flex-grow: 1 !important;
|
||||
}
|
||||
|
||||
.lora_enable label {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.lora_enable label input {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.lora_enable label span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lora_model {
|
||||
flex-grow: 5 !important;
|
||||
}
|
||||
|
||||
.lora_weight {
|
||||
flex-grow: 5 !important;
|
||||
}
|
||||
|
||||
'''
|
||||
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
|
||||
+28
-21
@@ -117,8 +117,8 @@ def get_resolution(key: str, fallback: str | None, source_dict: dict, results: l
|
||||
results.append(-1)
|
||||
else:
|
||||
results.append(gr.update())
|
||||
results.append(width)
|
||||
results.append(height)
|
||||
results.append(int(width))
|
||||
results.append(int(height))
|
||||
except:
|
||||
results.append(gr.update())
|
||||
results.append(gr.update())
|
||||
@@ -169,11 +169,20 @@ def get_freeu(key: str, fallback: str | None, source_dict: dict, results: list,
|
||||
|
||||
def get_lora(key: str, fallback: str | None, source_dict: dict, results: list):
|
||||
try:
|
||||
n, w = source_dict.get(key, source_dict.get(fallback)).split(' : ')
|
||||
w = float(w)
|
||||
results.append(True)
|
||||
results.append(n)
|
||||
results.append(w)
|
||||
split_data = source_dict.get(key, source_dict.get(fallback)).split(' : ')
|
||||
enabled = True
|
||||
name = split_data[0]
|
||||
weight = split_data[1]
|
||||
|
||||
if len(split_data) == 3:
|
||||
enabled = split_data[0] == 'True'
|
||||
name = split_data[1]
|
||||
weight = split_data[2]
|
||||
|
||||
weight = float(weight)
|
||||
results.append(enabled)
|
||||
results.append(name)
|
||||
results.append(weight)
|
||||
except:
|
||||
results.append(True)
|
||||
results.append('None')
|
||||
@@ -210,9 +219,8 @@ def parse_meta_from_preset(preset_content):
|
||||
height = height[:height.index(" ")]
|
||||
preset_prepared[meta_key] = (width, height)
|
||||
else:
|
||||
preset_prepared[meta_key] = items[settings_key] if settings_key in items and items[
|
||||
settings_key] is not None else getattr(modules.config, settings_key)
|
||||
|
||||
preset_prepared[meta_key] = items[settings_key] if settings_key in items and items[settings_key] is not None else getattr(modules.config, settings_key)
|
||||
|
||||
if settings_key == "default_styles" or settings_key == "default_aspect_ratio":
|
||||
preset_prepared[meta_key] = str(preset_prepared[meta_key])
|
||||
|
||||
@@ -377,7 +385,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)
|
||||
@@ -431,16 +439,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
|
||||
@@ -570,4 +577,4 @@ def get_exif(metadata: str | None, metadata_scheme: str):
|
||||
exif[0x0131] = 'Fooocus v' + fooocus_version.version
|
||||
# 0x927C = MakerNote
|
||||
exif[0x927C] = metadata_scheme
|
||||
return exif
|
||||
return exif
|
||||
|
||||
@@ -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,15 +22,15 @@ 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)
|
||||
|
||||
parsed_parameters = metadata_parser.parse_string(metadata) if metadata_parser is not None else ''
|
||||
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)
|
||||
@@ -90,7 +91,7 @@ def log(img, metadata, metadata_parser: MetadataParser | None = None, output_for
|
||||
</script>"""
|
||||
)
|
||||
|
||||
begin_part = f"<!DOCTYPE html><html><head><title>Fooocus Log {date_string}</title>{css_styles}</head><body>{js}<p>Fooocus Log {date_string} (private)</p>\n<p>All images are clean, without any hidden data/meta, and safe to share with others.</p><!--fooocus-log-split-->\n\n"
|
||||
begin_part = f"<!DOCTYPE html><html><head><title>Fooocus Log {date_string}</title>{css_styles}</head><body>{js}<p>Fooocus Log {date_string} (private)</p>\n<p>Metadata is embedded if enabled in the config or developer debug mode. You can find the information for each image in line Metadata Scheme.</p><!--fooocus-log-split-->\n\n"
|
||||
end_part = f'\n<!--fooocus-log-split--></body></html>'
|
||||
|
||||
middle_part = log_cache.get(html_name, "")
|
||||
|
||||
+11
-7
@@ -2,12 +2,12 @@ import os
|
||||
import re
|
||||
import json
|
||||
import math
|
||||
import modules.config
|
||||
|
||||
from modules.path_utils 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
|
||||
|
||||
|
||||
@@ -59,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:
|
||||
@@ -68,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.')
|
||||
@@ -81,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(',')
|
||||
@@ -93,9 +98,8 @@ def get_words(arrays, totalMult, index):
|
||||
return [word] + get_words(arrays[1:], math.floor(totalMult/len(words)), index)
|
||||
|
||||
|
||||
|
||||
def apply_arrays(text, index):
|
||||
arrays = re.findall(r'\[\[([\s,\w-]+)\]\]', text)
|
||||
arrays = re.findall(r'\[\[(.*?)\]\]', text)
|
||||
if len(arrays) == 0:
|
||||
return text
|
||||
|
||||
|
||||
@@ -355,6 +355,8 @@ def makedirs_with_log(path):
|
||||
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]]
|
||||
|
||||
def parse_lora_references_from_prompt(prompt: str, loras: List[Tuple[AnyStr, float]], loras_limit: int = 5):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user