mirror of
https://github.com/lllyasviel/Fooocus.git
synced 2026-08-16 13:13:16 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28cdc2f104 | ||
|
|
ee96b854d9 | ||
|
|
9155d94067 | ||
|
|
e54fb54f91 | ||
|
|
e965bfc39c | ||
|
|
e241c53f0e | ||
|
|
c3fd57acb9 | ||
|
|
fb94394b10 | ||
|
|
4ea3baff50 | ||
|
|
90839430da | ||
|
|
4945fc9962 | ||
|
|
6db14acf8e | ||
|
|
41e88a4e8d | ||
|
|
4f4d23f4e3 | ||
|
|
9c30961efd |
+1
-1
@@ -1 +1 @@
|
||||
version = '2.2.0-rc1'
|
||||
version = '2.2.1'
|
||||
|
||||
+1
-1
@@ -379,7 +379,7 @@
|
||||
"Metadata": "Metadata",
|
||||
"Apply Metadata": "Apply Metadata",
|
||||
"Metadata Scheme": "Metadata Scheme",
|
||||
"Image Prompt parameters are not included. Use a1111 for compatibility with Civitai.": "Image Prompt parameters are not included. Use a1111 for compatibility with Civitai.",
|
||||
"Image Prompt parameters are not included. Use png and a1111 for compatibility with Civitai.": "Image Prompt parameters are not included. Use png and a1111 for compatibility with Civitai.",
|
||||
"fooocus (json)": "fooocus (json)",
|
||||
"a1111 (plain text)": "a1111 (plain text)"
|
||||
}
|
||||
+30
-21
@@ -22,6 +22,7 @@ def worker():
|
||||
import traceback
|
||||
import math
|
||||
import numpy as np
|
||||
import cv2
|
||||
import torch
|
||||
import time
|
||||
import shared
|
||||
@@ -79,16 +80,20 @@ def worker():
|
||||
return
|
||||
|
||||
def build_image_wall(async_task):
|
||||
results = async_task.results
|
||||
results = []
|
||||
|
||||
if len(results) < 2:
|
||||
if len(async_task.results) < 2:
|
||||
return
|
||||
|
||||
for img in results:
|
||||
for img in async_task.results:
|
||||
if isinstance(img, str) and os.path.exists(img):
|
||||
img = cv2.imread(img)
|
||||
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
||||
if not isinstance(img, np.ndarray):
|
||||
return
|
||||
if img.ndim != 3:
|
||||
return
|
||||
results.append(img)
|
||||
|
||||
H, W, C = results[0].shape
|
||||
|
||||
@@ -553,8 +558,8 @@ def worker():
|
||||
direct_return = False
|
||||
|
||||
if direct_return:
|
||||
d = [('Upscale (Fast)', '2x')]
|
||||
uov_input_image_path = log(uov_input_image, d, output_format)
|
||||
d = [('Upscale (Fast)', 'upscale_fast', '2x')]
|
||||
uov_input_image_path = log(uov_input_image, d, output_format=output_format)
|
||||
yield_result(async_task, uov_input_image_path, do_not_show_finished_images=True)
|
||||
return
|
||||
|
||||
@@ -825,17 +830,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:
|
||||
@@ -852,17 +861,17 @@ def worker():
|
||||
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))
|
||||
|
||||
|
||||
+4
-3
@@ -264,7 +264,7 @@ default_loras = get_config_item_or_set_default(
|
||||
)
|
||||
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(
|
||||
@@ -474,6 +474,7 @@ with open(config_example_path, "w", encoding="utf-8") as json_file:
|
||||
|
||||
model_filenames = []
|
||||
lora_filenames = []
|
||||
sdxl_lcm_lora = 'sdxl_lcm_lora.safetensors'
|
||||
|
||||
|
||||
def get_model_filenames(folder_paths, name_filter=None):
|
||||
@@ -533,9 +534,9 @@ def downloading_sdxl_lcm_lora():
|
||||
load_file_from_url(
|
||||
url='https://huggingface.co/lllyasviel/misc/resolve/main/sdxl_lcm_lora.safetensors',
|
||||
model_dir=paths_loras[0],
|
||||
file_name='sdxl_lcm_lora.safetensors'
|
||||
file_name=sdxl_lcm_lora
|
||||
)
|
||||
return 'sdxl_lcm_lora.safetensors'
|
||||
return sdxl_lcm_lora
|
||||
|
||||
|
||||
def downloading_controlnet_canny():
|
||||
|
||||
+4
-10
@@ -112,10 +112,6 @@ progress::after {
|
||||
margin-left: -5px !important;
|
||||
}
|
||||
|
||||
.lora_enable {
|
||||
flex-grow: 1 !important;
|
||||
}
|
||||
|
||||
.lora_enable label {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -128,12 +124,10 @@ progress::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lora_model {
|
||||
flex-grow: 5 !important;
|
||||
}
|
||||
|
||||
.lora_weight {
|
||||
flex-grow: 5 !important;
|
||||
@-moz-document url-prefix() {
|
||||
.lora_weight input[type=number] {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
@@ -379,7 +379,8 @@ class A1111MetadataParser(MetadataParser):
|
||||
|
||||
if 'lora_hashes' in data:
|
||||
lora_filenames = modules.config.lora_filenames.copy()
|
||||
lora_filenames.remove(modules.config.downloading_sdxl_lcm_lora())
|
||||
if modules.config.sdxl_lcm_lora in lora_filenames:
|
||||
lora_filenames.remove(modules.config.sdxl_lcm_lora)
|
||||
for li, lora in enumerate(data['lora_hashes'].split(', ')):
|
||||
lora_name, lora_hash, lora_weight = lora.split(': ')
|
||||
for filename in lora_filenames:
|
||||
@@ -460,7 +461,8 @@ class FooocusMetadataParser(MetadataParser):
|
||||
def parse_json(self, metadata: dict) -> dict:
|
||||
model_filenames = modules.config.model_filenames.copy()
|
||||
lora_filenames = modules.config.lora_filenames.copy()
|
||||
lora_filenames.remove(modules.config.downloading_sdxl_lcm_lora())
|
||||
if modules.config.sdxl_lcm_lora in lora_filenames:
|
||||
lora_filenames.remove(modules.config.sdxl_lcm_lora)
|
||||
|
||||
for key, value in metadata.items():
|
||||
if value in ['', 'None']:
|
||||
|
||||
@@ -26,7 +26,7 @@ def log(img, metadata, metadata_parser: MetadataParser | None = None, output_for
|
||||
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':
|
||||
@@ -90,7 +90,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, "")
|
||||
|
||||
@@ -94,9 +94,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
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ In both ways the access is unauthenticated by default. You can add basic authent
|
||||
|
||||
The below things are already inside the software, and **users do not need to do anything about these**.
|
||||
|
||||
1. GPT2-based [prompt expansion as a dynamic style "Fooocus V2".](https://github.com/lllyasviel/Fooocus/discussions/117#raw) (similar to Midjourney's hidden pre-processsing and "raw" mode, or the LeonardoAI's Prompt Magic).
|
||||
1. GPT2-based [prompt expansion as a dynamic style "Fooocus V2".](https://github.com/lllyasviel/Fooocus/discussions/117#raw) (similar to Midjourney's hidden pre-processing and "raw" mode, or the LeonardoAI's Prompt Magic).
|
||||
2. Native refiner swap inside one single k-sampler. The advantage is that the refiner model can now reuse the base model's momentum (or ODE's history parameters) collected from k-sampling to achieve more coherent sampling. In Automatic1111's high-res fix and ComfyUI's node system, the base model and refiner use two independent k-samplers, which means the momentum is largely wasted, and the sampling continuity is broken. Fooocus uses its own advanced k-diffusion sampling that ensures seamless, native, and continuous swap in a refiner setup. (Update Aug 13: Actually, I discussed this with Automatic1111 several days ago, and it seems that the “native refiner swap inside one single k-sampler” is [merged]( https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/12371) into the dev branch of webui. Great!)
|
||||
3. Negative ADM guidance. Because the highest resolution level of XL Base does not have cross attentions, the positive and negative signals for XL's highest resolution level cannot receive enough contrasts during the CFG sampling, causing the results to look a bit plastic or overly smooth in certain cases. Fortunately, since the XL's highest resolution level is still conditioned on image aspect ratios (ADM), we can modify the adm on the positive/negative side to compensate for the lack of CFG contrast in the highest resolution level. (Update Aug 16, the IOS App [Draw Things](https://apps.apple.com/us/app/draw-things-ai-generation/id6444050820) will support Negative ADM Guidance. Great!)
|
||||
4. We implemented a carefully tuned variation of Section 5.1 of ["Improving Sample Quality of Diffusion Models Using Self-Attention Guidance"](https://arxiv.org/pdf/2210.00939.pdf). The weight is set to very low, but this is Fooocus's final guarantee to make sure that the XL will never yield an overly smooth or plastic appearance (examples [here](https://github.com/lllyasviel/Fooocus/discussions/117#sharpness)). This can almost eliminate all cases for which XL still occasionally produces overly smooth results, even with negative ADM guidance. (Update 2023 Aug 18, the Gaussian kernel of SAG is changed to an anisotropic kernel for better structure preservation and fewer artifacts.)
|
||||
|
||||
+15
-1
@@ -1,4 +1,18 @@
|
||||
# 2.1.865
|
||||
# [2.2.1](https://github.com/lllyasviel/Fooocus/releases/tag/2.2.1)
|
||||
|
||||
* Fix some small bugs (e.g. image grid, upscale fast 2x, LoRA weight width in Firefox)
|
||||
* Allow prompt weights in array syntax
|
||||
* Add steps override and metadata scheme to history log
|
||||
|
||||
# [2.2.0](https://github.com/lllyasviel/Fooocus/releases/tag/2.2.0)
|
||||
|
||||
* Isolate every image generation to truly allow multi-user usage
|
||||
* Add array support, changes the main prompt when increasing the image number. Syntax: `[[red, green, blue]] flower`
|
||||
* Add optional metadata to images, allowing you to regenerate and modify them later with the same parameters
|
||||
* Now supports native PNG, JPG and WEBP image generation
|
||||
* Add Docker support
|
||||
|
||||
# [2.1.865](https://github.com/lllyasviel/Fooocus/releases/tag/2.1.865)
|
||||
|
||||
* Various bugfixes
|
||||
* Add authentication to --listen
|
||||
|
||||
@@ -355,13 +355,13 @@ with shared.gradio_root:
|
||||
for i, (n, v) in enumerate(modules.config.default_loras):
|
||||
with gr.Row():
|
||||
lora_enabled = gr.Checkbox(label='Enable', value=True,
|
||||
elem_classes=['lora_enable', 'min_check'])
|
||||
elem_classes=['lora_enable', 'min_check'], scale=1)
|
||||
lora_model = gr.Dropdown(label=f'LoRA {i + 1}',
|
||||
choices=['None'] + modules.config.lora_filenames, value=n,
|
||||
elem_classes='lora_model')
|
||||
elem_classes='lora_model', scale=5)
|
||||
lora_weight = gr.Slider(label='Weight', minimum=modules.config.default_loras_min_weight,
|
||||
maximum=modules.config.default_loras_max_weight, step=0.01, value=v,
|
||||
elem_classes='lora_weight')
|
||||
elem_classes='lora_weight', scale=5)
|
||||
lora_ctrls += [lora_enabled, lora_model, lora_weight]
|
||||
|
||||
with gr.Row():
|
||||
@@ -438,7 +438,7 @@ with shared.gradio_root:
|
||||
save_metadata_to_images = gr.Checkbox(label='Save Metadata to Images', value=modules.config.default_save_metadata_to_images,
|
||||
info='Adds parameters to generated images allowing manual regeneration.')
|
||||
metadata_scheme = gr.Radio(label='Metadata Scheme', choices=flags.metadata_scheme, value=modules.config.default_metadata_scheme,
|
||||
info='Image Prompt parameters are not included. Use a1111 for compatibility with Civitai.',
|
||||
info='Image Prompt parameters are not included. Use png and a1111 for compatibility with Civitai.',
|
||||
visible=modules.config.default_save_metadata_to_images)
|
||||
|
||||
save_metadata_to_images.change(lambda x: gr.update(visible=x), inputs=[save_metadata_to_images], outputs=[metadata_scheme],
|
||||
@@ -521,6 +521,7 @@ with shared.gradio_root:
|
||||
results += [gr.update(choices=['None'] + modules.config.model_filenames)]
|
||||
for i in range(modules.config.default_max_lora_number):
|
||||
results += [gr.update(interactive=True), gr.update(choices=['None'] + modules.config.lora_filenames), gr.update()]
|
||||
return results
|
||||
|
||||
model_refresh.click(model_refresh_clicked, [], [base_model, refiner_model] + lora_ctrls,
|
||||
queue=False, show_progress=False)
|
||||
|
||||
@@ -18,7 +18,7 @@ Chihuahua
|
||||
Chimpanzee
|
||||
Chinchilla
|
||||
Chipmunk
|
||||
Comodo Dragon
|
||||
Komodo Dragon
|
||||
Cow
|
||||
Coyote
|
||||
Crocodile
|
||||
@@ -97,4 +97,4 @@ Whale
|
||||
Wolf
|
||||
Wombat
|
||||
Yak
|
||||
Zebra
|
||||
Zebra
|
||||
|
||||
Reference in New Issue
Block a user