From 71eb040afceb539005de7dff8c1c3c729640dc46 Mon Sep 17 00:00:00 2001 From: Justin Dhillon Date: Sat, 10 Feb 2024 08:36:56 -0800 Subject: [PATCH 01/16] Fix broken links (#2217) * https://github.com/rlaphoenix/VSGAN/blob/master/vsgan/archs/esrgan.py * https://github.com/huggingface/pytorch-image-models/blob/main/timm/layers/drop.py * https://kornia.readthedocs.io/en/latest/ --- ldm_patched/contrib/external_canny.py | 6 +++--- ldm_patched/pfn/architecture/HAT.py | 4 ++-- ldm_patched/pfn/architecture/RRDB.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ldm_patched/contrib/external_canny.py b/ldm_patched/contrib/external_canny.py index 42c2221..7347ba1 100644 --- a/ldm_patched/contrib/external_canny.py +++ b/ldm_patched/contrib/external_canny.py @@ -78,7 +78,7 @@ def spatial_gradient(input, normalized: bool = True): Return: the derivatives of the input feature map. with shape :math:`(B, C, 2, H, W)`. .. note:: - See a working example `here `__. Examples: >>> input = torch.rand(1, 3, 4, 4) @@ -120,7 +120,7 @@ def rgb_to_grayscale(image, rgb_weights = None): grayscale version of the image with shape :math:`(*,1,H,W)`. .. note:: - See a working example `here `__. Example: @@ -176,7 +176,7 @@ def canny( - the canny edge magnitudes map, shape of :math:`(B,1,H,W)`. - the canny edge detection filtered by thresholds and hysteresis, shape of :math:`(B,1,H,W)`. .. note:: - See a working example `here `__. Example: >>> input = torch.rand(5, 3, 4, 4) diff --git a/ldm_patched/pfn/architecture/HAT.py b/ldm_patched/pfn/architecture/HAT.py index 6694742..7e12ad0 100644 --- a/ldm_patched/pfn/architecture/HAT.py +++ b/ldm_patched/pfn/architecture/HAT.py @@ -14,7 +14,7 @@ from .timm.weight_init import trunc_normal_ def drop_path(x, drop_prob: float = 0.0, training: bool = False): """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - From: https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/layers/drop.py + From: https://github.com/huggingface/pytorch-image-models/blob/main/timm/layers/drop.py """ if drop_prob == 0.0 or not training: return x @@ -30,7 +30,7 @@ def drop_path(x, drop_prob: float = 0.0, training: bool = False): class DropPath(nn.Module): """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks). - From: https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/layers/drop.py + From: https://github.com/huggingface/pytorch-image-models/blob/main/timm/layers/drop.py """ def __init__(self, drop_prob=None): diff --git a/ldm_patched/pfn/architecture/RRDB.py b/ldm_patched/pfn/architecture/RRDB.py index b50db7c..8d318b9 100644 --- a/ldm_patched/pfn/architecture/RRDB.py +++ b/ldm_patched/pfn/architecture/RRDB.py @@ -13,7 +13,7 @@ import torch.nn.functional as F from . import block as B -# Borrowed from https://github.com/rlaphoenix/VSGAN/blob/master/vsgan/archs/ESRGAN.py +# Borrowed from https://github.com/rlaphoenix/VSGAN/blob/master/vsgan/archs/esrgan.py # Which enhanced stuff that was already here class RRDBNet(nn.Module): def __init__( From fdc4dc1d8793e71a43c89e75e73f3e050d3dd308 Mon Sep 17 00:00:00 2001 From: rsl8 <138326583+rsl8@users.noreply.github.com> Date: Sat, 10 Feb 2024 17:42:30 +0100 Subject: [PATCH 02/16] delay importing of modules.config (#2195) --- launch.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launch.py b/launch.py index 9dbd3b6..36fad9e 100644 --- a/launch.py +++ b/launch.py @@ -21,7 +21,6 @@ import fooocus_version from build_launcher import build_launcher from modules.launch_util import is_installed, run, python, run_pip, requirements_met from modules.model_loader import load_file_from_url -from modules import config REINSTALL_ALL = False @@ -84,6 +83,8 @@ if args.gpu_device_id is not None: print("Set device to:", args.gpu_device_id) +from modules import config + def download_models(): for file_name, url in vae_approx_filenames: load_file_from_url(url=url, model_dir=config.path_vae_approx, file_name=file_name) From d1a450c581490d66fa0238c6ac69d9f020054df8 Mon Sep 17 00:00:00 2001 From: V1sionVerse <155375712+V1sionVerse@users.noreply.github.com> Date: Sat, 10 Feb 2024 17:50:41 +0100 Subject: [PATCH 03/16] Fixed mistakes in HTML generation (#2187) Added declaration instead of
instead of
--- modules/private_logger.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/private_logger.py b/modules/private_logger.py index 968bd4f..49f17dc 100644 --- a/modules/private_logger.py +++ b/modules/private_logger.py @@ -68,7 +68,7 @@ def log(img, dic): """ ) - begin_part = f"Fooocus Log {date_string}{css_styles}{js}

Fooocus Log {date_string} (private)

\n

All images are clean, without any hidden data/meta, and safe to share with others.

\n\n" + begin_part = f"Fooocus Log {date_string}{css_styles}{js}

Fooocus Log {date_string} (private)

\n

All images are clean, without any hidden data/meta, and safe to share with others.

\n\n" end_part = f'\n' middle_part = log_cache.get(html_name, "") @@ -83,15 +83,15 @@ def log(img, dic): div_name = only_name.replace('.', '_') item = f"

\n" - item += f"" + item += f"" item += "" item += "
{only_name}
{only_name}
" for key, value in dic: - value_txt = str(value).replace('\n', '
') + value_txt = str(value).replace('\n', '
') item += f"\n" item += "" js_txt = urllib.parse.quote(json.dumps({k: v for k, v in dic}, indent=0), safe='') - item += f"
" + item += f"
" item += "
\n\n" From 95f93a1f4bc32bc6d114fe3c314b3f69da207d5a Mon Sep 17 00:00:00 2001 From: rsl8 <138326583+rsl8@users.noreply.github.com> Date: Sat, 10 Feb 2024 17:42:30 +0100 Subject: [PATCH 04/16] delay importing of modules.config (#2195) --- launch.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launch.py b/launch.py index 9dbd3b6..36fad9e 100644 --- a/launch.py +++ b/launch.py @@ -21,7 +21,6 @@ import fooocus_version from build_launcher import build_launcher from modules.launch_util import is_installed, run, python, run_pip, requirements_met from modules.model_loader import load_file_from_url -from modules import config REINSTALL_ALL = False @@ -84,6 +83,8 @@ if args.gpu_device_id is not None: print("Set device to:", args.gpu_device_id) +from modules import config + def download_models(): for file_name, url in vae_approx_filenames: load_file_from_url(url=url, model_dir=config.path_vae_approx, file_name=file_name) From ac10e51364054a849251d6f09b8007842a33f054 Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Sat, 10 Feb 2024 18:10:54 +0100 Subject: [PATCH 05/16] add auth to --listen and readme (#2127) * Update webui.py * Update readme.md * Update webui.py Only enable AuthN for --listen and --share Co-authored-by: Manuel Schmid <9307310+mashb1t@users.noreply.github.com> * docs: rephrase documentation changes for auth --------- Co-authored-by: Manuel Schmid <9307310+mashb1t@users.noreply.github.com> Co-authored-by: Manuel Schmid --- readme.md | 7 +++++++ webui.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 7765381..7310cff 100644 --- a/readme.md +++ b/readme.md @@ -281,6 +281,13 @@ Given different goals, the default models and configs of Fooocus are different: Note that the download is **automatic** - you do not need to do anything if the internet connection is okay. However, you can download them manually if you (or move them from somewhere else) have your own preparation. +## UI Access and Authentication +In addition to running on localhost, Fooocus can also expose its UI in two ways: +* Local UI listener: use `--listen` (specify port e.g. with `--port 8888`). +* API access: use `--share` (registers an endpoint at `.gradio.live`). + +In both ways the access is unauthenticated by default. You can add basic authentication by creating a file called `auth.json` in the main directory, which contains a list of JSON objects with the keys `user` and `pass` (see example in [auth-example.json](./auth-example.json)). + ## List of "Hidden" Tricks diff --git a/webui.py b/webui.py index fadd852..a3de149 100644 --- a/webui.py +++ b/webui.py @@ -618,6 +618,6 @@ shared.gradio_root.launch( server_name=args_manager.args.listen, server_port=args_manager.args.port, share=args_manager.args.share, - auth=check_auth if args_manager.args.share and auth_enabled else None, + auth=check_auth if (args_manager.args.share or args_manager.args.listen) and auth_enabled else None, blocked_paths=[constants.AUTH_FILENAME] ) From b7715b0a0cf3f2b4bfceaf5f4b7aad0df928a28a Mon Sep 17 00:00:00 2001 From: Manuel Schmid <9307310+mashb1t@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:33:28 +0100 Subject: [PATCH 06/16] fix: prevents outdated history log link after midnight (#1979) * feat: update history link date after each generation prevents outdated date in link after midnight * delay importing of modules.config (#2195) * fix: disable queue for initial queue loading --------- Co-authored-by: rsl8 <138326583+rsl8@users.noreply.github.com> --- webui.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/webui.py b/webui.py index a3de149..b9b620d 100644 --- a/webui.py +++ b/webui.py @@ -255,8 +255,14 @@ with shared.gradio_root: seed_random.change(random_checked, inputs=[seed_random], outputs=[image_seed], queue=False, show_progress=False) - if not args_manager.args.disable_image_log: - gr.HTML(f'\U0001F4DA History Log') + def update_history_link(): + if args_manager.args.disable_image_log: + return gr.update(value='') + + return gr.update(value=f'\U0001F4DA History Log') + + history_link = gr.HTML() + shared.gradio_root.load(update_history_link, outputs=history_link, queue=False, show_progress=False) with gr.Tab(label='Style'): style_sorter.try_load_sorted_styles( @@ -586,6 +592,7 @@ with shared.gradio_root: .then(fn=generate_clicked, inputs=ctrls, outputs=[progress_html, progress_window, progress_gallery, gallery]) \ .then(lambda: (gr.update(visible=True, interactive=True), gr.update(visible=False, interactive=False), gr.update(visible=False, interactive=False), False), outputs=[generate_button, stop_button, skip_button, state_is_generating]) \ + .then(fn=update_history_link, outputs=history_link) \ .then(fn=lambda: None, _js='playNotification').then(fn=lambda: None, _js='refresh_grid_delayed') for notification_file in ['notification.ogg', 'notification.mp3']: From e4929a9ed79f8d461b387f8b013b23ad23f3cb90 Mon Sep 17 00:00:00 2001 From: rsl8 <138326583+rsl8@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:42:18 +0100 Subject: [PATCH 07/16] fix: do not overwrite $GRADIO_SERVER_PORT if it is already set (#1921) --- launch.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launch.py b/launch.py index 36fad9e..db174f5 100644 --- a/launch.py +++ b/launch.py @@ -10,7 +10,8 @@ os.chdir(root) os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1" os.environ["PYTORCH_MPS_HIGH_WATERMARK_RATIO"] = "0.0" -os.environ["GRADIO_SERVER_PORT"] = "7865" +if "GRADIO_SERVER_PORT" not in os.environ: + os.environ["GRADIO_SERVER_PORT"] = "7865" ssl._create_default_https_context = ssl._create_unverified_context From 231956065ff88da523c3472c7228a0072cffed70 Mon Sep 17 00:00:00 2001 From: "Dr. Christoph Mittendorf" <34183942+Cassini-chris@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:51:03 +0100 Subject: [PATCH 08/16] Removing unnecessary comments / old code (#1905) --- javascript/contextMenus.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js index 2f32af1..7494674 100644 --- a/javascript/contextMenus.js +++ b/javascript/contextMenus.js @@ -154,12 +154,8 @@ let cancelGenerateForever = function() { let generateOnRepeatForButtons = function() { generateOnRepeat('#generate_button', '#stop_button'); }; - appendContextMenuOption('#generate_button', 'Generate forever', generateOnRepeatForButtons); -// appendContextMenuOption('#stop_button', 'Generate forever', generateOnRepeatForButtons); -// appendContextMenuOption('#stop_button', 'Cancel generate forever', cancelGenerateForever); -// appendContextMenuOption('#generate_button', 'Cancel generate forever', cancelGenerateForever); })(); //End example Context Menu Items From 98ba1d5d475fa04bc37c88a09e7eb8f47f2cc68a Mon Sep 17 00:00:00 2001 From: Manuel Schmid <9307310+mashb1t@users.noreply.github.com> Date: Sat, 10 Feb 2024 19:03:26 +0100 Subject: [PATCH 09/16] fix: correctly sort files, display deepest dir level first (#1784) --- modules/util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/util.py b/modules/util.py index 052b746..de9bd5b 100644 --- a/modules/util.py +++ b/modules/util.py @@ -164,14 +164,14 @@ def get_files_from_folder(folder_path, exensions=None, name_filter=None): filenames = [] - for root, dirs, files in os.walk(folder_path): + for root, dirs, files in os.walk(folder_path, topdown=False): relative_path = os.path.relpath(root, folder_path) if relative_path == ".": relative_path = "" - for filename in files: + for filename in sorted(files): _, file_extension = os.path.splitext(filename) if (exensions == None or file_extension.lower() in exensions) and (name_filter == None or name_filter in _): path = os.path.join(relative_path, filename) filenames.append(path) - return sorted(filenames, key=lambda x: -1 if os.sep in x else 1) + return filenames From c32b9bdc44e8955947ba66fce4e9dfd2e1e6f259 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Sat, 10 Feb 2024 21:15:10 +0300 Subject: [PATCH 10/16] fix: replace regexp to support unicode chars (#1424) --- modules/launch_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/launch_util.py b/modules/launch_util.py index 8d92fad..b483d51 100644 --- a/modules/launch_util.py +++ b/modules/launch_util.py @@ -15,7 +15,7 @@ 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()) -re_requirement = re.compile(r"\s*([-_a-zA-Z0-9]+)\s*(?:==\s*([-+_.a-zA-Z0-9]+))?\s*") +re_requirement = re.compile(r"\s*([-\w]+)\s*(?:==\s*([-+.\w]+))?\s*") python = sys.executable default_command_live = (os.environ.get('LAUNCH_LIVE_OUTPUT') == "1") From b9d7e77b0df97e54f7cb9670d6257ffc09b65ada Mon Sep 17 00:00:00 2001 From: Praveen Kumar Sridhar <69740366+PraveenKumarSridhar@users.noreply.github.com> Date: Sat, 10 Feb 2024 10:28:10 -0800 Subject: [PATCH 11/16] replaced the custom lcm function with math.lcm (#1122) Co-authored-by: Manuel Schmid --- ldm_patched/modules/conds.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ldm_patched/modules/conds.py b/ldm_patched/modules/conds.py index ed03bd6..0ee184b 100644 --- a/ldm_patched/modules/conds.py +++ b/ldm_patched/modules/conds.py @@ -3,8 +3,6 @@ import math import ldm_patched.modules.utils -def lcm(a, b): #TODO: eventually replace by math.lcm (added in python3.9) - return abs(a*b) // math.gcd(a, b) class CONDRegular: def __init__(self, cond): @@ -41,7 +39,7 @@ class CONDCrossAttn(CONDRegular): if s1[0] != s2[0] or s1[2] != s2[2]: #these 2 cases should not happen return False - mult_min = lcm(s1[1], s2[1]) + mult_min = math.lcm(s1[1], s2[1]) diff = mult_min // min(s1[1], s2[1]) if diff > 4: #arbitrary limit on the padding because it's probably going to impact performance negatively if it's too much return False @@ -52,7 +50,7 @@ class CONDCrossAttn(CONDRegular): crossattn_max_len = self.cond.shape[1] for x in others: c = x.cond - crossattn_max_len = lcm(crossattn_max_len, c.shape[1]) + crossattn_max_len = math.lcm(crossattn_max_len, c.shape[1]) conds.append(c) out = [] From eb3f4d745c5d8736d5f22cacfabd9856909ab00f Mon Sep 17 00:00:00 2001 From: hisk2323 <114307999+hisk2323@users.noreply.github.com> Date: Sat, 10 Feb 2024 14:39:36 -0600 Subject: [PATCH 12/16] feat: add suffix ordinals (#845) * add suffix ordinals with lambda * delay importing of modules.config (#2195) * refactor: use easier to read version to find matching ordinal suffix --------- Co-authored-by: rsl8 <138326583+rsl8@users.noreply.github.com> Co-authored-by: Manuel Schmid Co-authored-by: Manuel Schmid <9307310+mashb1t@users.noreply.github.com> --- modules/async_worker.py | 5 ++--- modules/util.py | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/async_worker.py b/modules/async_worker.py index b2af671..67c2e70 100644 --- a/modules/async_worker.py +++ b/modules/async_worker.py @@ -40,7 +40,7 @@ def worker(): 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 + get_image_shape_ceil, set_image_shape_ceil, get_shape_ceil, resample_image, erode_or_dilate, ordinal_suffix from modules.upscaler import perform_upscale try: @@ -732,8 +732,7 @@ def worker(): done_steps = current_task_id * steps + step async_task.yields.append(['preview', ( int(15.0 + 85.0 * float(done_steps) / float(all_steps)), - f'Step {step}/{total_steps} in the {current_task_id + 1}-th Sampling', - y)]) + f'Step {step}/{total_steps} in the {current_task_id + 1}{ordinal_suffix(current_task_id + 1)} Sampling', y)]) for current_task_id, task in enumerate(tasks): execution_start_time = time.perf_counter() diff --git a/modules/util.py b/modules/util.py index de9bd5b..c309480 100644 --- a/modules/util.py +++ b/modules/util.py @@ -175,3 +175,7 @@ def get_files_from_folder(folder_path, exensions=None, name_filter=None): filenames.append(path) return filenames + + +def ordinal_suffix(number: int) -> str: + return 'th' if 10 <= number % 100 <= 20 else {1: 'st', 2: 'nd', 3: 'rd'}.get(number % 10, 'th') From 2037de3fcb683434355cee4b5504046dfd9dc483 Mon Sep 17 00:00:00 2001 From: Manuel Schmid Date: Sat, 10 Feb 2024 21:54:50 +0100 Subject: [PATCH 13/16] chore: fix typos and adjust wording (#1521, #1644, #1691, #1772) --- .github/ISSUE_TEMPLATE/bug_report.md | 4 ++-- ldm_patched/pfn/architecture/face/codeformer.py | 2 +- readme.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 331426a..624cfe3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,10 +9,10 @@ assignees: '' **Read Troubleshoot** -[x] I admit that I have read the [Troubleshoot](https://github.com/lllyasviel/Fooocus/blob/main/troubleshoot.md) before making this issue. +[x] I confirm that I have read the [Troubleshoot](https://github.com/lllyasviel/Fooocus/blob/main/troubleshoot.md) guide before making this issue. **Describe the problem** A clear and concise description of what the bug is. **Full Console Log** -Paste **full** console log here. You will make our job easier if you give a **full** log. +Paste the **full** console log here. You will make our job easier if you give a **full** log. diff --git a/ldm_patched/pfn/architecture/face/codeformer.py b/ldm_patched/pfn/architecture/face/codeformer.py index 0661400..a0e2e98 100644 --- a/ldm_patched/pfn/architecture/face/codeformer.py +++ b/ldm_patched/pfn/architecture/face/codeformer.py @@ -2,7 +2,7 @@ Modified from https://github.com/sczhou/CodeFormer VQGAN code, adapted from the original created by the Unleashing Transformers authors: https://github.com/samb-t/unleashing-transformers/blob/master/models/vqgan.py -This verison of the arch specifically was gathered from an old version of GFPGAN. If this is a problem, please contact me. +This version of the arch specifically was gathered from an old version of GFPGAN. If this is a problem, please contact me. """ import math from typing import Optional diff --git a/readme.md b/readme.md index 7310cff..fa7e829 100644 --- a/readme.md +++ b/readme.md @@ -202,7 +202,7 @@ AMD is not intensively tested, however. The AMD support is in beta. Use `python entry_with_update.py --preset anime` or `python entry_with_update.py --preset realistic` for Fooocus Anime/Realistic Edition. -### Windows(AMD GPUs) +### Windows (AMD GPUs) Note that the [minimal requirement](#minimal-requirement) for different platforms is different. @@ -295,7 +295,7 @@ The below things are already inside the software, and **users do not need to do 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). 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 [Drawing Things](https://apps.apple.com/us/app/draw-things-ai-generation/id6444050820) will support Negative ADM Guidance. 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.) 5. We modified the style templates a bit and added the "cinematic-default". 6. We tested the "sd_xl_offset_example-lora_1.0.safetensors" and it seems that when the lora weight is below 0.5, the results are always better than XL without lora. From ee3ce9556689264cffa0151d891c12525a20cf24 Mon Sep 17 00:00:00 2001 From: Manuel Schmid Date: Sat, 10 Feb 2024 21:59:13 +0100 Subject: [PATCH 14/16] docs: update version --- fooocus_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fooocus_version.py b/fooocus_version.py index ff5a883..91c2ddd 100644 --- a/fooocus_version.py +++ b/fooocus_version.py @@ -1 +1 @@ -version = '2.1.864' +version = '2.1.865' From 074b655dff89bfb69bcbe9a08cc947f2a0e33568 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Sun, 11 Feb 2024 04:03:10 -0800 Subject: [PATCH 15/16] fix: implement output path argument (#2074) * added function to check output path arg and override, other wise, use temp or fallback to config * added function to check output path arg and override, other wise, use temp or fallback to config #2065 * Revert to 1bcbd650 * moved path output arg handling inside config start up * Revert "added function to check output path arg and override, other wise, use temp or fallback to config" This reverts commit fecb97b59ccd3bde3a5fc2d2302245611eb85d2c. * Updated tag to uppercase * updated docstring to standard double quotes. Co-authored-by: Manuel Schmid <9307310+mashb1t@users.noreply.github.com> * removed extra check on image log flag per feedback * feat: update config_dict value when overriding path_outputs, change message --------- Co-authored-by: Manuel Schmid <9307310+mashb1t@users.noreply.github.com> Co-authored-by: Manuel Schmid --- modules/config.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/config.py b/modules/config.py index 5810780..1f4e82e 100644 --- a/modules/config.py +++ b/modules/config.py @@ -102,6 +102,18 @@ if isinstance(preset, str): print(e) +def get_path_output() -> str: + """ + Checking output path argument and overriding default path. + """ + global config_dict + path_output = get_dir_or_set_default('path_outputs', '../outputs/') + if args_manager.args.output_path: + print(f'[CONFIG] 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 + + def get_dir_or_set_default(key, default_value): global config_dict, visited_keys, always_save_keys @@ -132,7 +144,7 @@ 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_outputs = get_dir_or_set_default('path_outputs', '../outputs/') +path_outputs = get_path_output() def get_config_item_or_set_default(key, default_value, validator, disable_empty_as_none=False): From f4a8bf24cf33c8315101b67098298118eacbe572 Mon Sep 17 00:00:00 2001 From: Manuel Schmid Date: Sun, 11 Feb 2024 15:12:41 +0100 Subject: [PATCH 16/16] fix: correctly calculate refiner switch when overwrite_switch is > 0 (#2165) When using custom steps, the calculation of switching timing is wrong. Now it is modified to calculate "steps x timing" after custom steps are used. By @xhoxye --- modules/async_worker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/async_worker.py b/modules/async_worker.py index 67c2e70..40abb7f 100644 --- a/modules/async_worker.py +++ b/modules/async_worker.py @@ -335,11 +335,11 @@ def worker(): ip_adapter.load_ip_adapter(clip_vision_path, ip_negative_path, ip_adapter_path) ip_adapter.load_ip_adapter(clip_vision_path, ip_negative_path, ip_adapter_face_path) - switch = int(round(steps * refiner_switch)) - if advanced_parameters.overwrite_step > 0: steps = advanced_parameters.overwrite_step + switch = int(round(steps * refiner_switch)) + if advanced_parameters.overwrite_switch > 0: switch = advanced_parameters.overwrite_switch