From edd886cea48611d1142ef1a83181386a674eb03f Mon Sep 17 00:00:00 2001 From: Manuel Schmid Date: Mon, 8 Jul 2024 15:08:32 +0200 Subject: [PATCH 1/3] feat: make hash generation multi-threaded, change --rebuild-hash-cache from bool to int keep in mind that most likely the drive is going to be the bottleneck now --- args_manager.py | 4 ++-- modules/config.py | 20 ++------------------ modules/hash_cache.py | 31 +++++++++++++++++++++++++++++++ modules/util.py | 2 -- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/args_manager.py b/args_manager.py index 27fe14a55..5e187629e 100644 --- a/args_manager.py +++ b/args_manager.py @@ -34,8 +34,8 @@ args_parser.parser.add_argument("--always-download-new-model", action='store_true', help="Always download newer models", default=False) -args_parser.parser.add_argument("--rebuild-hash-cache", action='store_true', - help="Generates missing model and LoRA hashes.", default=False) +args_parser.parser.add_argument("--rebuild-hash-cache", help="Generates missing model and LoRA hashes.", + type=int, nargs="?", metavar="CPU_NUM_THREADS", const=-1) args_parser.parser.set_defaults( disable_cuda_malloc=True, diff --git a/modules/config.py b/modules/config.py index e9e6b1cf1..fa2a7238f 100644 --- a/modules/config.py +++ b/modules/config.py @@ -7,7 +7,7 @@ import tempfile import modules.flags import modules.sdxl_styles -from modules.hash_cache import load_cache_from_file, save_cache_to_file +from modules.hash_cache import init_cache from modules.model_loader import load_file_from_url from modules.extra_utils import makedirs_with_log, get_files_from_folder, try_eval_env_var @@ -756,20 +756,4 @@ def downloading_safety_checker_model(): update_files() -load_cache_from_file() - -if args_manager.args.rebuild_hash_cache: - from modules.hash_cache import sha256_from_cache - from modules.util import get_file_from_folder_list - - print('[Cache] Rebuilding hash cache') - for filename in model_filenames: - filepath = get_file_from_folder_list(filename, paths_checkpoints) - sha256_from_cache(filepath) - for filename in lora_filenames: - filepath = get_file_from_folder_list(filename, paths_loras) - sha256_from_cache(filepath) - print('[Cache] Done') - -# write cache to file again for sorting and cleanup of invalid cache entries -save_cache_to_file() +init_cache(model_filenames, paths_checkpoints, lora_filenames, paths_loras) diff --git a/modules/hash_cache.py b/modules/hash_cache.py index 105665604..c33e675ed 100644 --- a/modules/hash_cache.py +++ b/modules/hash_cache.py @@ -1,6 +1,10 @@ import json import os +from concurrent.futures import ThreadPoolExecutor +from multiprocessing import cpu_count +import args_manager +from modules.util import get_file_from_folder_list from modules.util import sha256, HASH_SHA256_LENGTH hash_cache_filename = 'hash_cache.txt' @@ -10,7 +14,9 @@ def sha256_from_cache(filepath): global hash_cache if filepath not in hash_cache: + print(f"[Cache] Calculating sha256 for {filepath}") hash_value = sha256(filepath) + print(f"[Cache] sha256 for {filepath}: {hash_value}") hash_cache[filepath] = hash_value save_cache_to_file(filepath, hash_value) @@ -51,3 +57,28 @@ def save_cache_to_file(filename=None, hash_value=None): fp.write('\n') except Exception as e: print(f'[Cache] Saving failed: {e}') + + +def init_cache(model_filenames, paths_checkpoints, lora_filenames, paths_loras): + load_cache_from_file() + + if args_manager.args.rebuild_hash_cache: + max_workers = args_manager.args.rebuild_hash_cache if args_manager.args.rebuild_hash_cache > 0 else cpu_count() + rebuild_cache(lora_filenames, model_filenames, paths_checkpoints, paths_loras, max_workers) + + # write cache to file again for sorting and cleanup of invalid cache entries + save_cache_to_file() + + +def rebuild_cache(lora_filenames, model_filenames, paths_checkpoints, paths_loras, max_workers=cpu_count()): + def thread(filename, paths): + filepath = get_file_from_folder_list(filename, paths) + sha256_from_cache(filepath) + + print('[Cache] Rebuilding hash cache') + with ThreadPoolExecutor(max_workers=max_workers) as executor: + for model_filename in model_filenames: + executor.submit(thread, model_filename, paths_checkpoints) + for lora_filename in lora_filenames: + executor.submit(thread, lora_filename, paths_loras) + print('[Cache] Done') diff --git a/modules/util.py b/modules/util.py index 5003f79ab..5b2882dc5 100644 --- a/modules/util.py +++ b/modules/util.py @@ -176,13 +176,11 @@ def generate_temp_filename(folder='./outputs/', extension='png'): def sha256(filename, use_addnet_hash=False, length=HASH_SHA256_LENGTH): - print(f"Calculating sha256 for {filename}: ", end='') if use_addnet_hash: with open(filename, "rb") as file: sha256_value = addnet_hash_safetensors(file) else: sha256_value = calculate_sha256(filename) - print(f"{sha256_value}") return sha256_value[:length] if length is not None else sha256_value From efb6ca01d389b6e14620ea7733a9736ff361baba Mon Sep 17 00:00:00 2001 From: Manuel Schmid Date: Sat, 13 Jul 2024 15:49:07 +0200 Subject: [PATCH 2/3] fix: prevent inference tensor version counter tracking issue for GroundingDINO use no_grad and inference_mode on predict_with_caption see https://github.com/lllyasviel/Fooocus/discussions/3213#discussioncomment-10017126 --- extras/GroundingDINO/util/inference.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extras/GroundingDINO/util/inference.py b/extras/GroundingDINO/util/inference.py index bc8b64291..34ab8f011 100644 --- a/extras/GroundingDINO/util/inference.py +++ b/extras/GroundingDINO/util/inference.py @@ -19,6 +19,8 @@ def __init__(self): self.load_device = torch.device('cpu') self.offload_device = torch.device('cpu') + @torch.no_grad() + @torch.inference_mode() def predict_with_caption( self, image: np.ndarray, From f4d21e6fa11c63ddb8e440336c576e268fb65cf5 Mon Sep 17 00:00:00 2001 From: Manuel Schmid Date: Sat, 13 Jul 2024 15:52:06 +0200 Subject: [PATCH 3/3] release: bump version to 2.6.0-rc2, update changelog --- fooocus_version.py | 2 +- update_log.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/fooocus_version.py b/fooocus_version.py index a37e9c40b..d709b1292 100644 --- a/fooocus_version.py +++ b/fooocus_version.py @@ -1 +1 @@ -version = '2.6.0-rc1 (mashb1t)' +version = '2.6.0-rc2 (mashb1t)' diff --git a/update_log.md b/update_log.md index 03b8b9fb6..6cf1ed71c 100644 --- a/update_log.md +++ b/update_log.md @@ -1,3 +1,9 @@ +# [2.6.0-rc2](https://github.com/mashb1t/Fooocus/releases/tag/v2.6.0-rc2) + +* Add hash generation multi-threading support, change `--rebuild-hash-cache` from bool to int (number of CPU cores) +* Fix inference tensor version counter tracking issue for GroundingDINO after using Enhance (see [discussion](https://github.com/lllyasviel/Fooocus/discussions/3213)) + + # [2.6.0-rc1](https://github.com/mashb1t/Fooocus/releases/tag/v2.6.0-rc1) * Update default models to latest versions