mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
update logging and model hashinh
This commit is contained in:
+11
-4
@@ -1,11 +1,18 @@
|
||||
# Change Log for SD.Next
|
||||
|
||||
## Update for 2023-08-21
|
||||
## Update for 2023-08-22
|
||||
|
||||
- general:
|
||||
- all system and image paths are now relative by default
|
||||
- fix extra networks previews
|
||||
- add settings validation when performing load/save
|
||||
- all system and image paths are now relative by default
|
||||
- fix extra networks previews
|
||||
- add settings validation when performing load/save
|
||||
- optimize model hashing
|
||||
- add cli param `--skip-all` that skips all installer checks
|
||||
use at personal discretion, but it can be useful for bulk deployments
|
||||
- add **openvino** (experimental) cpu optimized model compile and inference
|
||||
enable with `--use-openvino`
|
||||
thanks @disty0
|
||||
- add model **precompile** option (when model compile is enbled)
|
||||
|
||||
## Update for 2023-08-20
|
||||
|
||||
|
||||
Submodule extensions-builtin/a1111-sd-webui-lycoris updated: 912576970a...df9c0093bc
Submodule extensions-builtin/sd-webui-controlnet updated: 0cfc88b6a8...943197e1be
Submodule extensions-builtin/stable-diffusion-webui-images-browser updated: 65618f3e07...15c337914d
@@ -736,6 +736,8 @@ def check_extensions():
|
||||
|
||||
# check version of the main repo and optionally upgrade it
|
||||
def check_version(offline=False, reset=True): # pylint: disable=unused-argument
|
||||
if args.skip_all:
|
||||
return
|
||||
if not os.path.exists('.git'):
|
||||
log.error('Not a git repository')
|
||||
if not args.ignore:
|
||||
@@ -843,6 +845,7 @@ def add_args(parser):
|
||||
group.add_argument('--skip-extensions', default = False, action='store_true', help = "Skips running individual extension installers, default: %(default)s")
|
||||
group.add_argument('--skip-git', default = False, action='store_true', help = "Skips running all GIT operations, default: %(default)s")
|
||||
group.add_argument('--skip-torch', default = False, action='store_true', help = "Skips running Torch checks, default: %(default)s")
|
||||
group.add_argument('--skip-all', default = False, action='store_true', help = "Skips running all checks, default: %(default)s")
|
||||
group.add_argument('--experimental', default = False, action='store_true', help = "Allow unsupported versions of libraries, default: %(default)s")
|
||||
group.add_argument('--reinstall', default = False, action='store_true', help = "Force reinstallation of all requirements, default: %(default)s")
|
||||
group.add_argument('--test', default = False, action='store_true', help = "Run test only and exit")
|
||||
|
||||
@@ -154,6 +154,8 @@ if __name__ == "__main__":
|
||||
installer.setup_logging()
|
||||
installer.log.info('Starting SD.Next')
|
||||
installer.read_options()
|
||||
if args.skip_all:
|
||||
args.quick = True
|
||||
installer.check_python()
|
||||
if args.reset:
|
||||
installer.git_reset()
|
||||
@@ -166,7 +168,10 @@ if __name__ == "__main__":
|
||||
if args.reinstall:
|
||||
installer.log.info('Forcing reinstall of all packages')
|
||||
installer.quick_allowed = False
|
||||
if installer.check_timestamp():
|
||||
if args.skip_all:
|
||||
installer.log.info('Skipping all checks')
|
||||
installer.quick_allowed = True
|
||||
elif installer.check_timestamp():
|
||||
installer.log.info('No changes detected: Quick launch active')
|
||||
installer.install_requirements()
|
||||
installer.install_packages()
|
||||
|
||||
@@ -53,6 +53,7 @@ def get_optimal_device():
|
||||
|
||||
def get_device_for(task):
|
||||
if task in shared.cmd_opts.use_cpu:
|
||||
shared.log.debug(f'Forcing CPU for task: {task}')
|
||||
return cpu
|
||||
return get_optimal_device()
|
||||
|
||||
|
||||
+2
-5
@@ -15,10 +15,7 @@ def dump_cache():
|
||||
def cache(subsection):
|
||||
global cache_data # pylint: disable=global-statement
|
||||
if cache_data is None:
|
||||
if not os.path.isfile(cache_filename):
|
||||
cache_data = {}
|
||||
else:
|
||||
cache_data = shared.readfile(cache_filename)
|
||||
cache_data = {} if not os.path.isfile(cache_filename) else shared.readfile(cache_filename)
|
||||
s = cache_data.get(subsection, {})
|
||||
cache_data[subsection] = s
|
||||
return s
|
||||
@@ -59,7 +56,7 @@ def sha256(filename, title, use_addnet_hash=False):
|
||||
sha256_value = calculate_sha256(filename)
|
||||
hashes[title] = {
|
||||
"mtime": os.path.getmtime(filename),
|
||||
"sha256": sha256_value,
|
||||
"sha256": sha256_value
|
||||
}
|
||||
dump_cache()
|
||||
return sha256_value
|
||||
|
||||
+1
-1
@@ -448,7 +448,7 @@ def atomically_save_image():
|
||||
image_format = 'JPEG'
|
||||
if shared.opts.image_watermark_enabled:
|
||||
image = set_watermark(image, shared.opts.image_watermark)
|
||||
shared.log.debug(f'Saving image: {image_format} {fn} {image.size}')
|
||||
shared.log.debug(f'Saving image: type={image_format} size={image.size} {fn}')
|
||||
# actual save
|
||||
exifinfo = (exifinfo or "") if shared.opts.image_metadata else ""
|
||||
if image_format == 'PNG':
|
||||
|
||||
@@ -157,7 +157,7 @@ def load_diffusers_models(model_path: str, command_path: str = None):
|
||||
output.append(str(r.repo_id))
|
||||
except Exception as e:
|
||||
shared.log.error(f"Error listing diffusers: {place} {e}")
|
||||
shared.log.debug(f'Scanning diffusers cache: {model_path} {command_path} {len(output)}')
|
||||
shared.log.debug(f'Scanning diffusers cache: {model_path} {command_path} items={len(output)}')
|
||||
return output
|
||||
|
||||
|
||||
|
||||
+18
-9
@@ -4,6 +4,7 @@ import re
|
||||
import io
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import threading
|
||||
from os import mkdir
|
||||
from urllib import request
|
||||
@@ -38,7 +39,7 @@ skip_next_load = False
|
||||
sd_metadata_file = os.path.join(paths.data_path, "metadata.json")
|
||||
sd_metadata = None
|
||||
sd_metadata_pending = 0
|
||||
|
||||
sd_metadata_timer = 0
|
||||
|
||||
class CheckpointInfo:
|
||||
def __init__(self, filename):
|
||||
@@ -59,8 +60,8 @@ class CheckpointInfo:
|
||||
if name.startswith("\\") or name.startswith("/"):
|
||||
name = name[1:]
|
||||
self.name = name
|
||||
self.hash = model_hash(self.filename)
|
||||
self.sha256 = hashes.sha256_from_cache(self.filename, f"checkpoint/{name}")
|
||||
self.hash = self.sha256[0:8] if self.sha256 is not None else None
|
||||
self.path = abspath
|
||||
self.type = abspath.split('.')[-1].lower()
|
||||
self.name_for_extra = os.path.splitext(os.path.basename(filename))[0]
|
||||
@@ -155,7 +156,7 @@ def list_models():
|
||||
shared.opts.data['sd_model_checkpoint'] = checkpoint_info.title
|
||||
elif shared.cmd_opts.ckpt != shared.default_sd_model_file and shared.cmd_opts.ckpt is not None:
|
||||
shared.log.warning(f"Checkpoint not found: {shared.cmd_opts.ckpt}")
|
||||
shared.log.info(f'Available models: {shared.opts.ckpt_dir} {len(checkpoints_list)}')
|
||||
shared.log.info(f'Available models: {shared.opts.ckpt_dir} items={len(checkpoints_list)}')
|
||||
|
||||
if len(checkpoints_list) == 0:
|
||||
if not shared.cmd_opts.no_download:
|
||||
@@ -212,10 +213,14 @@ def model_hash(filename):
|
||||
try:
|
||||
with open(filename, "rb") as file:
|
||||
import hashlib
|
||||
t0 = time.time()
|
||||
m = hashlib.sha256()
|
||||
file.seek(0x100000)
|
||||
m.update(file.read(0x10000))
|
||||
return m.hexdigest()[0:8]
|
||||
shorthash = m.hexdigest()[0:8]
|
||||
t1 = time.time()
|
||||
shared.log.debug(f'Calculating short hash: {filename} hash={shorthash} time={(t1-t0):.2f}')
|
||||
return shorthash
|
||||
except FileNotFoundError:
|
||||
return 'NOFILE'
|
||||
except Exception:
|
||||
@@ -284,7 +289,7 @@ def write_metadata():
|
||||
shared.log.debug(f"Model metadata: {sd_metadata_file} no changes")
|
||||
return
|
||||
shared.writefile(sd_metadata, sd_metadata_file)
|
||||
shared.log.info(f"Model metadata saved: {sd_metadata_file} {sd_metadata_pending}")
|
||||
shared.log.info(f"Model metadata saved: {sd_metadata_file} items={sd_metadata_pending} time={sd_metadata_timer:.2f}s")
|
||||
sd_metadata_pending = 0
|
||||
|
||||
|
||||
@@ -300,6 +305,7 @@ def read_metadata_from_safetensors(filename):
|
||||
return res
|
||||
res = {}
|
||||
try:
|
||||
t0 = time.time()
|
||||
with open(filename, mode="rb") as file:
|
||||
metadata_len = file.read(8)
|
||||
metadata_len = int.from_bytes(metadata_len, "little")
|
||||
@@ -318,6 +324,9 @@ def read_metadata_from_safetensors(filename):
|
||||
sd_metadata[filename] = res
|
||||
global sd_metadata_pending # pylint: disable=global-statement
|
||||
sd_metadata_pending += 1
|
||||
t1 = time.time()
|
||||
global sd_metadata_timer # pylint: disable=global-statement
|
||||
sd_metadata_timer += (t1 - t0)
|
||||
except Exception as e:
|
||||
shared.log.error(f"Error reading metadata from: {filename} {e}")
|
||||
return res
|
||||
@@ -368,7 +377,6 @@ def get_checkpoint_state_dict(checkpoint_info: CheckpointInfo, timer):
|
||||
|
||||
def load_model_weights(model: torch.nn.Module, checkpoint_info: CheckpointInfo, state_dict, timer):
|
||||
shared.log.debug(f'Model weights loading: {memory_stats()}')
|
||||
sd_model_hash = checkpoint_info.calculate_shorthash()
|
||||
timer.record("hash")
|
||||
if model_data.sd_dict == 'None':
|
||||
shared.opts.data["sd_model_checkpoint"] = checkpoint_info.title
|
||||
@@ -407,7 +415,7 @@ def load_model_weights(model: torch.nn.Module, checkpoint_info: CheckpointInfo,
|
||||
# clean up cache if limit is reached
|
||||
while len(checkpoints_loaded) > shared.opts.sd_checkpoint_cache:
|
||||
checkpoints_loaded.popitem(last=False)
|
||||
model.sd_model_hash = sd_model_hash
|
||||
model.sd_model_hash = checkpoint_info.calculate_shorthash()
|
||||
model.sd_model_checkpoint = checkpoint_info.filename
|
||||
model.sd_checkpoint_info = checkpoint_info
|
||||
shared.opts.data["sd_checkpoint_hash"] = checkpoint_info.sha256
|
||||
@@ -795,7 +803,7 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No
|
||||
shared.log.info(f"Compiling pipeline={sd_model.__class__.__name__} shape={8 * sd_model.unet.config.sample_size} mode={shared.opts.cuda_compile_backend}")
|
||||
import torch._dynamo # pylint: disable=unused-import,redefined-outer-name
|
||||
if shared.opts.cuda_compile_backend == "openvino_fx":
|
||||
from modules.intel.openvino import openvino_fx
|
||||
from modules.intel.openvino import openvino_fx # pylint: disable=unused-import
|
||||
log_level = logging.WARNING if shared.opts.cuda_compile_verbose else logging.CRITICAL # pylint: disable=protected-access
|
||||
if hasattr(torch, '_logging'):
|
||||
torch._logging.set_logs(dynamo=log_level, aot=log_level, inductor=log_level) # pylint: disable=protected-access
|
||||
@@ -812,9 +820,10 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No
|
||||
if sd_model is None:
|
||||
shared.log.error('Diffuser model not loaded')
|
||||
return
|
||||
sd_model.sd_model_hash = checkpoint_info.calculate_shorthash() # pylint: disable=attribute-defined-outside-init
|
||||
sd_model.sd_checkpoint_info = checkpoint_info # pylint: disable=attribute-defined-outside-init
|
||||
sd_model.sd_model_checkpoint = checkpoint_info.filename # pylint: disable=attribute-defined-outside-init
|
||||
sd_model.sd_model_hash = checkpoint_info.hash # pylint: disable=attribute-defined-outside-init
|
||||
shared.opts.data["sd_checkpoint_hash"] = checkpoint_info.sha256
|
||||
if hasattr(sd_model, "set_progress_bar_config"):
|
||||
sd_model.set_progress_bar_config(bar_format='Progress {rate_fmt}{postfix} {bar} {percentage:3.0f}% {n_fmt}/{total_fmt} {elapsed} {remaining}', ncols=80, colour='#327fba')
|
||||
if op == 'refiner' and shared.opts.diffusers_move_refiner and not sd_model.has_accelerate:
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ def refresh_vae_list():
|
||||
vae_dict[name] = os.path.dirname(filepath)
|
||||
else:
|
||||
vae_dict[name] = filepath
|
||||
shared.log.info(f"Available VAEs: {vae_path} {len(vae_dict)}")
|
||||
shared.log.info(f"Available VAEs: {vae_path} items={len(vae_dict)}")
|
||||
return vae_dict
|
||||
|
||||
|
||||
|
||||
+6
-4
@@ -66,6 +66,7 @@ restricted_opts = {
|
||||
"outdir_save",
|
||||
"outdir_init_images"
|
||||
}
|
||||
compatibility_opts = ['clip_skip', 'uni_pc_lower_order_final', 'uni_pc_order']
|
||||
|
||||
|
||||
def is_url(string):
|
||||
@@ -720,11 +721,12 @@ class Options:
|
||||
if self.data_labels[k].default != v:
|
||||
diff[k] = v
|
||||
else:
|
||||
unused_settings.append(k)
|
||||
if k not in compatibility_opts:
|
||||
unused_settings.append(k)
|
||||
diff[k] = v
|
||||
writefile(diff, filename)
|
||||
if len(unused_settings) > 0:
|
||||
log.debug(f"Unknown settings: {unused_settings}")
|
||||
log.debug(f"Unused settings: {unused_settings}")
|
||||
except Exception as e:
|
||||
log.error(f'Saving settings failed: {filename} {e}')
|
||||
|
||||
@@ -748,10 +750,10 @@ class Options:
|
||||
info = self.data_labels.get(k, None)
|
||||
if info is not None and not self.same_type(info.default, v):
|
||||
log.error(f"Error: bad setting value: {k}: {v} ({type(v).__name__}; expected {type(info.default).__name__})")
|
||||
if info is None:
|
||||
if info is None and k not in compatibility_opts:
|
||||
unknown_settings.append(k)
|
||||
if len(unknown_settings) > 0:
|
||||
log.debug(f"Unknown settings: {unknown_settings}")
|
||||
log.warning(f"Unknown settings: {unknown_settings}")
|
||||
|
||||
def onchange(self, key, func, call=True):
|
||||
item = self.data_labels.get(key)
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ class StyleDatabase:
|
||||
self.styles[row["name"]] = PromptStyle(row["name"], prompt, negative_prompt)
|
||||
except Exception:
|
||||
log.error(f'Styles error: {self.path} {row}')
|
||||
log.debug(f'Loaded styles: {self.path} {len(self.styles.keys())}')
|
||||
log.debug(f'Loaded styles: {self.path} items={len(self.styles.keys())}')
|
||||
|
||||
def get_style_prompts(self, styles):
|
||||
return [self.styles.get(x, self.no_style).prompt for x in styles]
|
||||
|
||||
+4
-4
@@ -843,7 +843,7 @@ def create_ui(startup_timer = None):
|
||||
(latent_index, "Latent sampler"),
|
||||
(denoising_strength, "Denoising strength"),
|
||||
(refiner_start, "Refiner start"),
|
||||
(full_quality, "Full quality"), # TODO
|
||||
(full_quality, "Full quality"),
|
||||
(restore_faces, "Face restoration"),
|
||||
(batch_size, "Batch size"),
|
||||
(batch_count, "Batch count"),
|
||||
@@ -968,13 +968,13 @@ def create_ui(startup_timer = None):
|
||||
directml_override_opts()
|
||||
if cmd_opts.use_openvino:
|
||||
if not modules.shared.opts.cuda_compile:
|
||||
modules.shared.log.warn("OpenVINO: Enabling Torch Compile")
|
||||
modules.shared.log.warning("OpenVINO: Enabling Torch Compile")
|
||||
modules.shared.opts.cuda_compile = True
|
||||
if modules.shared.opts.cuda_compile_backend != "openvino_fx":
|
||||
modules.shared.log.warn("OpenVINO: Setting Torch Compiler backend to OpenVINO FX")
|
||||
modules.shared.log.warning("OpenVINO: Setting Torch Compiler backend to OpenVINO FX")
|
||||
modules.shared.opts.cuda_compile_backend = "openvino_fx"
|
||||
if modules.shared.opts.sd_backend != "diffusers":
|
||||
modules.shared.log.warn("OpenVINO: Setting backend to Diffusers")
|
||||
modules.shared.log.warning("OpenVINO: Setting backend to Diffusers")
|
||||
modules.shared.opts.sd_backend = "diffusers"
|
||||
try:
|
||||
opts.save(modules.shared.config_filename)
|
||||
|
||||
@@ -343,7 +343,7 @@ def create_ui(container, button, tabname, skip_indexing = False):
|
||||
ui.description_target_filename = gr.Textbox('Description save filename', elem_id=tabname+"_description_filename", visible=False)
|
||||
|
||||
for page in ui.stored_extra_pages:
|
||||
shared.log.debug(f"Create UI Extra Network Page: {page.title}")
|
||||
shared.log.debug(f"Extra network page: {page.title} tab={tabname}")
|
||||
page_html = page.create_html(ui.tabname, skip_indexing)
|
||||
with gr.Tab(page.title, id=page.title.lower().replace(" ", "_"), elem_classes="extra-networks-tab"):
|
||||
page_elem = gr.HTML(page_html, elem_id=tabname+page.name+"_extra_page", elem_classes="extra-networks-page")
|
||||
|
||||
Reference in New Issue
Block a user