diff --git a/CHANGELOG.md b/CHANGELOG.md index be248b001..a040a9634 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,22 +2,27 @@ ## Update for 2025-07-03 -- **Models** - - Add **FLUX.1-Kontext-Dev** inpaint workflow - **UI** - major update to modernui layout - redesign of the Flat UI theme +- **Models** + - Add **FLUX.1-Kontext-Dev** inpaint workflow - **Compute** - support for [SageAttention2++](https://github.com/thu-ml/SageAttention) provides 10-15% performance improvement over default SDPA for transformer-based models! enable in *settings -> compute settings -> sdp options* - *note*: SD.Next will use either SageAttention v1 or v2, depending which one is installed - until authors provide pre-build wheels for v2, you need to install it manually or SD.Next will auto-install v1 + *note*: SD.Next will use either SageAttention v1/v2/v2++, depending which one is installed + until authors provide pre-build wheels for v2++, you need to install it manually or SD.Next will auto-install v1 - **Fixes** - allow theme type `None` to be set in config - installer dont cache installed state - fix Cosmos-Predict2 retrying TAESD download - better handle startup import errors + - fix diffusers models non-unique hash + - fix loading of manually downloaded diffuser models + - improve model type autodetection + - improve model auth check for hf repos + - improve Chroma prompt padding as per recommendations - **Refactoring** - override `gradio` installer - major refactoring of requirements and dependencies to unblock `numpy>=2.1.0` diff --git a/modules/modelloader.py b/modules/modelloader.py index 6ef7e275b..5ad1d540b 100644 --- a/modules/modelloader.py +++ b/modules/modelloader.py @@ -304,7 +304,6 @@ def download_diffusers_model(hub_id: str, cache_dir: str = None, download_config def load_diffusers_models(clear=True): - excluded_models = [] # t0 = time.time() place = shared.opts.diffusers_dir if place is None or len(place) == 0 or not os.path.isdir(place): @@ -315,20 +314,21 @@ def load_diffusers_models(clear=True): try: for folder in os.listdir(place): try: - if any([x in folder for x in excluded_models]): # noqa:C419 # pylint: disable=use-a-generator - continue - if "--" not in folder: - continue - if folder.endswith("-prior"): - continue - _, name = folder.split("--", maxsplit=1) - name = name.replace("--", "/") + name = folder[8:] if folder.startswith('models--') else folder folder = os.path.join(place, folder) + if name.endswith("-prior"): + continue + if not os.path.isdir(folder): + continue + name = name.replace("--", "/") friendly = os.path.join(place, name) - if os.path.exists(os.path.join(folder, 'model_index.json')): # direct download of diffusers model + has_index = os.path.exists(os.path.join(folder, 'model_index.json')) + + if has_index: # direct download of diffusers model repo = { 'name': name, 'filename': name, 'friendly': friendly, 'folder': folder, 'path': folder, 'hash': None, 'mtime': os.path.getmtime(folder), 'model_info': os.path.join(folder, 'model_info.json'), 'model_index': os.path.join(folder, 'model_index.json') } diffuser_repos.append(repo) continue + snapshots = os.listdir(os.path.join(folder, "snapshots")) if len(snapshots) == 0: shared.log.warning(f'Diffusers folder has no snapshots: location="{place}" folder="{folder}" name="{name}"') diff --git a/modules/sd_detect.py b/modules/sd_detect.py index be57edb4b..f51a1f82b 100644 --- a/modules/sd_detect.py +++ b/modules/sd_detect.py @@ -8,130 +8,140 @@ from modules import shared, shared_items, devices, errors, model_tools debug_load = os.environ.get('SD_LOAD_DEBUG', None) -def detect_pipeline(f: str, op: str = 'model', warning=True, quiet=False): +def guess_by_size(fn, current_guess): + if os.path.isfile(fn) and fn.endswith('.safetensors'): + size = round(os.path.getsize(fn) / 1024 / 1024) + if (size > 0 and size < 128): + shared.log.warning(f'Model size smaller than expected: file="{fn}" size={size} MB') + elif (size >= 316 and size <= 324) or (size >= 156 and size <= 164): # 320 or 160 + shared.log.warning(f'Model detected as VAE model, but attempting to load as model: file="{fn}" size={size} MB') + return 'VAE' + elif (size >= 2002 and size <= 2038): # 2032 + return 'Stable Diffusion 1.5' + elif (size >= 3138 and size <= 3142): #3140 + return 'Stable Diffusion XL' + elif (size >= 3361 and size <= 3369): # 3368 + return 'Stable Diffusion Upscale' + elif (size >= 4891 and size <= 4899): # 4897 + return 'Stable Diffusion XL Inpaint' + elif (size >= 4970 and size <= 4976): # 4973 + return 'Stable Diffusion 2' # SD v2 but could be eps or v-prediction + elif (size >= 5791 and size <= 5799): # 5795 + return 'Stable Diffusion XL Refiner' + elif (size > 5692 and size < 5698) or (size > 4134 and size < 4138) or (size > 10362 and size < 10366) or (size > 15028 and size < 15228): + return 'Stable Diffusion 3' + elif (size >= 6420 and size <= 7220): # 6420, IustriousRedux is 6541, monkrenRealisticINT_v10 is 7217 + return 'Stable Diffusion XL' + elif (size >= 9791 and size <= 9799): # 9794 + return 'Stable Diffusion XL Instruct' + elif (size >= 18414 and size <= 18420): # sd35-large aio + return 'Stable Diffusion 3' + elif (size >= 20000 and size <= 40000): + return 'FLUX' + return current_guess + + +def guess_by_name(fn, current_guess): + if 'instaflow' in fn.lower(): + return 'InstaFlow' + elif 'segmoe' in fn.lower(): + return 'SegMoE' + elif 'hunyuandit' in fn.lower(): + return 'HunyuanDiT' + elif 'pixart-xl' in fn.lower(): + return 'PixArt Alpha' + elif 'stable-diffusion-3' in fn.lower(): + return 'Stable Diffusion 3' + elif 'stable-cascade' in fn.lower() or 'stablecascade' in fn.lower() or 'wuerstchen3' in fn.lower() or ('sotediffusion' in fn.lower() and "v2" in fn.lower()): + if devices.dtype == torch.float16: + shared.log.warning('Stable Cascade does not support Float16') + return 'Stable Cascade' + elif 'pixart-sigma' in fn.lower(): + return 'PixArt Sigma' + elif 'sana' in fn.lower(): + return 'Sana' + elif 'lumina-next' in fn.lower(): + return 'Lumina-Next' + elif 'lumina-image-2' in fn.lower(): + return 'Lumina 2' + elif 'kolors' in fn.lower(): + return 'Kolors' + elif 'auraflow' in fn.lower(): + return 'AuraFlow' + elif 'cogview3' in fn.lower(): + return 'CogView 3' + elif 'cogview4' in fn.lower(): + return 'CogView 4' + elif 'meissonic' in fn.lower(): + return 'Meissonic' + elif 'monetico' in fn.lower(): + return 'Monetico' + elif 'omnigen' in fn.lower(): + return 'OmniGen' + elif 'omnigen2' in fn.lower(): + return 'OmniGen2' + elif 'sd3' in fn.lower(): + return 'Stable Diffusion 3' + elif 'hidream' in fn.lower(): + return 'HiDream' + elif 'chroma' in fn.lower(): + return 'Chroma' + elif 'flux' in fn.lower() or 'flex.1' in fn.lower(): + size = round(os.path.getsize(fn) / 1024 / 1024) + if size > 11000 and size < 16000: + shared.log.warning(f'Model detected as FLUX UNET model, but attempting to load a base model: file="{fn}" size={size} MB') + return 'FLUX' + elif 'flex.2' in fn.lower(): + return 'FLEX' + elif 'cosmos-predict2' in fn.lower(): + return 'Cosmos' + return current_guess + + +def guess_by_diffusers(fn, current_guess): + index = os.path.join(fn, 'model_index.json') + if os.path.exists(index) and os.path.isfile(index): + index = shared.readfile(index, silent=True) + cls = index.get('_class_name', None) + if cls is not None: + pipeline = getattr(diffusers, cls, None) + if pipeline is None: + pipeline = cls + if callable(pipeline): + pipelines = shared_items.get_pipelines() + for k, v in pipelines.items(): + if v is not None and v.__name__ == pipeline.__name__: + return k, v + else: + return 'unknown', pipeline + return current_guess, None + + +def guess_variant(fn, current_guess): + if 'inpaint' in fn.lower(): + if current_guess == 'Stable Diffusion': + return 'Stable Diffusion Inpaint' + elif current_guess == 'Stable Diffusion XL': + return 'Stable Diffusion XL Inpaint' + elif 'instruct' in fn.lower(): + if current_guess == 'Stable Diffusion': + return 'Stable Diffusion Instruct' + elif current_guess == 'Stable Diffusion XL': + return 'Stable Diffusion XL Instruct' + return current_guess + + +def detect_pipeline(f: str, op: str = 'model'): guess = shared.opts.diffusers_pipeline - warn = shared.log.warning if warning else lambda *args, **kwargs: None size = 0 pipeline = None if guess == 'Autodetect': try: - guess = 'Stable Diffusion XL' if 'XL' in f.upper() else 'Stable Diffusion' - # guess by size - if os.path.isfile(f) and f.endswith('.safetensors'): - size = round(os.path.getsize(f) / 1024 / 1024) - if (size > 0 and size < 128): - warn(f'Model size smaller than expected: {f} size={size} MB') - elif (size >= 316 and size <= 324) or (size >= 156 and size <= 164): # 320 or 160 - warn(f'Model detected as VAE model, but attempting to load as model: {op}={f} size={size} MB') - guess = 'VAE' - elif (size >= 2002 and size <= 2038): # 2032 - guess = 'Stable Diffusion 1.5' - elif (size >= 3138 and size <= 3142): #3140 - guess = 'Stable Diffusion XL' - elif (size >= 3361 and size <= 3369): # 3368 - guess = 'Stable Diffusion Upscale' - elif (size >= 4891 and size <= 4899): # 4897 - guess = 'Stable Diffusion XL Inpaint' - elif (size >= 4970 and size <= 4976): # 4973 - guess = 'Stable Diffusion 2' # SD v2 but could be eps or v-prediction - elif (size >= 5791 and size <= 5799): # 5795 - if op == 'model': - warn(f'Model detected as SD-XL refiner model, but attempting to load a base model: {op}={f} size={size} MB') - guess = 'Stable Diffusion XL Refiner' - elif (size > 5692 and size < 5698) or (size > 4134 and size < 4138) or (size > 10362 and size < 10366) or (size > 15028 and size < 15228): - guess = 'Stable Diffusion 3' - elif (size >= 6420 and size <= 7220): # 6420, IustriousRedux is 6541, monkrenRealisticINT_v10 is 7217 - guess = 'Stable Diffusion XL' - elif (size >= 9791 and size <= 9799): # 9794 - guess = 'Stable Diffusion XL Instruct' - elif (size >= 18414 and size <= 18420): # sd35-large aio - guess = 'Stable Diffusion 3' - elif (size >= 20000 and size <= 40000): - guess = 'FLUX' - # guess by name - if 'instaflow' in f.lower(): - guess = 'InstaFlow' - if 'segmoe' in f.lower(): - guess = 'SegMoE' - if 'hunyuandit' in f.lower(): - guess = 'HunyuanDiT' - if 'pixart-xl' in f.lower(): - guess = 'PixArt Alpha' - if 'stable-diffusion-3' in f.lower(): - guess = 'Stable Diffusion 3' - if 'stable-cascade' in f.lower() or 'stablecascade' in f.lower() or 'wuerstchen3' in f.lower() or ('sotediffusion' in f.lower() and "v2" in f.lower()): - if devices.dtype == torch.float16: - warn('Stable Cascade does not support Float16') - guess = 'Stable Cascade' - if 'pixart-sigma' in f.lower(): - guess = 'PixArt Sigma' - if 'sana' in f.lower(): - guess = 'Sana' - if 'lumina-next' in f.lower(): - guess = 'Lumina-Next' - if 'lumina-image-2' in f.lower(): - guess = 'Lumina 2' - if 'kolors' in f.lower(): - guess = 'Kolors' - if 'auraflow' in f.lower(): - guess = 'AuraFlow' - if 'cogview3' in f.lower(): - guess = 'CogView 3' - if 'cogview4' in f.lower(): - guess = 'CogView 4' - if 'meissonic' in f.lower(): - guess = 'Meissonic' - pipeline = 'custom' - if 'monetico' in f.lower(): - guess = 'Monetico' - pipeline = 'custom' - if 'omnigen' in f.lower(): - guess = 'OmniGen' - pipeline = 'custom' - if 'omnigen2' in f.lower(): - guess = 'OmniGen2' - pipeline = 'custom' - if 'sd3' in f.lower(): - guess = 'Stable Diffusion 3' - if 'hidream' in f.lower(): - guess = 'HiDream' - if 'chroma' in f.lower(): - guess = 'Chroma' - if 'flux' in f.lower() or 'flex.1' in f.lower(): - guess = 'FLUX' - if size > 11000 and size < 16000: - warn(f'Model detected as FLUX UNET model, but attempting to load a base model: {op}={f} size={size} MB') - if 'flex.2' in f.lower(): - guess = 'FLEX' - if 'cosmos-predict2' in f.lower(): - guess = 'Cosmos' - # guess for diffusers - index = os.path.join(f, 'model_index.json') - if os.path.exists(index) and os.path.isfile(index): - index = shared.readfile(index, silent=True) - cls = index.get('_class_name', None) - if cls is not None: - pipeline = getattr(diffusers, cls, None) - if pipeline is None: - pipeline = cls - if callable(pipeline) and 'Flux' in pipeline.__name__ and guess != 'FLEX': - guess = 'FLUX' - if callable(pipeline) and 'StableDiffusion3' in pipeline.__name__: - guess = 'Stable Diffusion 3' - if callable(pipeline) and 'Lumina2' in pipeline.__name__: - guess = 'Lumina 2' - - # switch for specific variant - if guess == 'Stable Diffusion' and 'inpaint' in f.lower(): - guess = 'Stable Diffusion Inpaint' - elif guess == 'Stable Diffusion' and 'instruct' in f.lower(): - guess = 'Stable Diffusion Instruct' - if guess == 'Stable Diffusion XL' and 'inpaint' in f.lower(): - guess = 'Stable Diffusion XL Inpaint' - elif guess == 'Stable Diffusion XL' and 'instruct' in f.lower(): - guess = 'Stable Diffusion XL Instruct' - - # get actual pipeline + guess = 'Stable Diffusion XL' if 'XL' in f.upper() else 'Stable Diffusion' # set default guess + guess = guess_by_size(f, guess) + guess = guess_by_name(f, guess) + guess, pipeline = guess_by_diffusers(f, guess) + guess = guess_variant(f, guess) pipeline = shared_items.get_pipelines().get(guess, None) if pipeline is None else pipeline if debug_load is not None: shared.log.info(f'Autodetect {op}: detect="{guess}" class={getattr(pipeline, "__name__", None)} file="{f}" size={size}MB') @@ -150,16 +160,14 @@ def detect_pipeline(f: str, op: str = 'model', warning=True, quiet=False): return None, None else: try: - size = round(os.path.getsize(f) / 1024 / 1024) pipeline = shared_items.get_pipelines().get(guess, None) if pipeline is None else pipeline - if not quiet: - shared.log.info(f'Load {op}: detect="{guess}" class={getattr(pipeline, "__name__", None)} file="{f}" size={size}MB') + shared.log.info(f'Load {op}: detect="{guess}" class={getattr(pipeline, "__name__", None)} file="{f}"') except Exception as e: shared.log.error(f'Load {op}: detect="{guess}" file="{f}" {e}') if pipeline is None: shared.log.warning(f'Load {op}: detect="{guess}" file="{f}" size={size} not recognized') - pipeline = diffusers.StableDiffusionPipeline + pipeline = diffusers.DiffusionPipeline return pipeline, guess diff --git a/modules/sd_models.py b/modules/sd_models.py index 707cf8031..c4ade2a5a 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -8,6 +8,7 @@ from enum import Enum import diffusers import diffusers.loaders.single_file_utils import torch +import huggingface_hub as hf from installer import log from modules import paths, shared, shared_state, shared_items, modelloader, devices, script_callbacks, sd_vae, sd_unet, errors, sd_models_config, sd_models_compile, sd_hijack_accelerate, sd_detect, model_quant, sd_hijack_te from modules.timer import Timer, process as process_timer @@ -1157,3 +1158,19 @@ def unload_model_weights(op='model'): model_data.sd_refiner = None devices.torch_gc(force=True) shared.log.debug(f'Unload {op}: {memory_stats()}') + + +def hf_auth_check(checkpoint_info): + login = None + try: + if os.path.exists(checkpoint_info.path) and os.path.isdir(checkpoint_info.path) and os.path.isfile(os.path.join(checkpoint_info.path, 'model_index.json')): # skip check for already downloaded models + return True + except Exception: + pass + try: + login = modelloader.hf_login() + repo_id = path_to_repo(checkpoint_info) + hf.auth_check(repo_id) + except Exception as e: + shared.log.error(f'Load model: repo="{repo_id}" login={login} {e}') + return False diff --git a/modules/sd_models_legacy.py b/modules/sd_models_legacy.py index ec21da7b7..36d9a7d93 100644 --- a/modules/sd_models_legacy.py +++ b/modules/sd_models_legacy.py @@ -50,7 +50,6 @@ def repair_config(sd_config): def load_model_weights(model, checkpoint_info, state_dict, timer): - # _pipeline, _model_type = sd_detect.detect_pipeline(checkpoint_info.path, 'model') from modules.modeldata import model_data from modules.memstats import memory_stats from modules import devices, sd_vae diff --git a/modules/sd_models_utils.py b/modules/sd_models_utils.py index 9ef0024b7..5f3359227 100644 --- a/modules/sd_models_utils.py +++ b/modules/sd_models_utils.py @@ -32,16 +32,21 @@ def get_call(cls): return signature.parameters -def path_to_repo(fn: str = ''): - if isinstance(fn, CheckpointInfo): - fn = fn.name - repo_id = fn.replace('\\', '/') - if 'models--' in repo_id: +def path_to_repo(checkpoint_info): + if isinstance(checkpoint_info, CheckpointInfo): + if os.path.exists(checkpoint_info.path) and 'models--' not in checkpoint_info.path: + return checkpoint_info.path # local models + repo_id = checkpoint_info.name + else: + repo_id = checkpoint_info # fallback if fn is used with str param + repo_id = repo_id.replace('\\', '/') + if repo_id.startswith('Diffusers/'): + repo_id = repo_id.split('Diffusers/')[-1] + if repo_id.startswith('models--'): repo_id = repo_id.split('models--')[-1] - repo_id = repo_id.split('/')[0] - repo_id = repo_id.split('/') - repo_id = '/'.join(repo_id[-2:] if len(repo_id) > 1 else repo_id) - repo_id = repo_id.replace('models--', '').replace('--', '/') + repo_id = repo_id.replace('--', '/') + if repo_id.count('/') != 1: + shared.log.warning(f'Model: repo="{repo_id}" repository not recognized') return repo_id diff --git a/modules/shared_items.py b/modules/shared_items.py index f785ae5a5..1cd8f8cb9 100644 --- a/modules/shared_items.py +++ b/modules/shared_items.py @@ -47,6 +47,8 @@ pipelines = { # dynamically imported and redefined later 'Meissonic': getattr(diffusers, 'DiffusionPipeline', None), # dynamically redefined and loaded in sd_models.load_diffuser + 'Monetico': getattr(diffusers, 'DiffusionPipeline', None), # dynamically redefined and loaded in sd_models.load_diffuser + 'OmniGen2': getattr(diffusers, 'DiffusionPipeline', None), # dynamically redefined and loaded in sd_models.load_diffuser 'InstaFlow': getattr(diffusers, 'DiffusionPipeline', None), # dynamically redefined and loaded in sd_models.load_diffuser 'SegMoE': getattr(diffusers, 'DiffusionPipeline', None), # dynamically redefined and loaded in sd_models.load_diffuser } diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index ca4c5c855..bd280c9ef 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -227,13 +227,16 @@ class ExtraNetworksPage: return f"
Network page not ready
Click refresh to try again
" subdirs = {} allowed_folders = [os.path.abspath(x) for x in self.allowed_directories_for_previews() if os.path.exists(x)] + diffusers_base = os.path.basename(shared.opts.diffusers_dir) for parentdir, dirs in {d: files_cache.walk(d, cached=True, recurse=files_cache.not_hidden) for d in allowed_folders}.items(): for tgt in dirs: tgt = tgt.path if os.path.join(paths.models_path, 'Reference') in tgt and shared.opts.extra_network_reference_enable: subdirs['Reference'] = 1 + continue if shared.native and shared.opts.diffusers_dir in tgt: - subdirs[os.path.basename(shared.opts.diffusers_dir)] = 1 + subdirs[diffusers_base] = 1 + continue if 'models--' in tgt: continue subdir = tgt[len(parentdir):].replace("\\", "/") @@ -247,7 +250,7 @@ class ExtraNetworksPage: if self.name == 'model' and shared.opts.extra_network_reference_enable: subdirs['Local'] = 1 subdirs['Reference'] = 1 - subdirs[os.path.basename(shared.opts.diffusers_dir)] = 1 + subdirs[diffusers_base] = 1 if self.name == 'style' and shared.opts.extra_networks_styles: subdirs['Local'] = 1 subdirs['Reference'] = 1 @@ -291,7 +294,7 @@ class ExtraNetworksPage: htmls.append(self.create_html(item, tabname)) self.html += ''.join(htmls) self.page_time = time.time() - self.html = f"
{subdirs_html}
{self.html}
" + self.html = f"
{subdirs_html}
{self.html}
" shared.log.debug(f'Networks: type="{self.name}" items={len(self.items)} subfolders={len(subdirs)} tab={tabname} folders={self.allowed_directories_for_previews()} list={self.list_time:.2f} thumb={self.preview_time:.2f} desc={self.desc_time:.2f} info={self.info_time:.2f} workers={shared.max_workers}') if len(self.missing_thumbs) > 0: threading.Thread(target=self.create_thumb).start() @@ -386,13 +389,17 @@ class ExtraNetworksPage: if item.get('local_preview', None) is None: item['local_preview'] = f'{base}.{shared.opts.samples_format}' if shared.opts.diffusers_dir in base: - match = re.search(r"models--([^/^\\]+)[/\\]", base) - if match is None: - match = re.search(r"models--(.*)", base) - base = os.path.join(reference_path, match[1]) - model_path = os.path.join(shared.opts.diffusers_dir, match[0]) - item['local_preview'] = f'{os.path.join(model_path, match[1])}.{shared.opts.samples_format}' - all_previews += list(files_cache.list_files(model_path, ext_filter=exts, recursive=False)) + if 'models--' in base: + match = re.search(r"models--([^/^\\]+)[/\\]", base) + if match is None: + match = re.search(r"models--(.*)", base) + base = os.path.join(reference_path, match[1]) + model_path = os.path.join(shared.opts.diffusers_dir, match[0]) + item['local_preview'] = f'{os.path.join(model_path, match[1])}.{shared.opts.samples_format}' + all_previews += list(files_cache.list_files(model_path, ext_filter=exts, recursive=False)) + else: + if os.path.isdir(base): + item['local_preview'] = os.path.join(base, f'{os.path.basename(base)}.{shared.opts.samples_format}') base = os.path.basename(base) for file in [f'{base}{mid}{ext}' for ext in exts for mid in ['.thumb.', '.', '.preview.']]: if file in all_previews_fn: diff --git a/modules/ui_settings.py b/modules/ui_settings.py index 6fb9fe1f7..c340dd5f1 100644 --- a/modules/ui_settings.py +++ b/modules/ui_settings.py @@ -166,7 +166,8 @@ def run_settings_single(value, key, progress=False): from modules.dml import directml_override_opts directml_override_opts() shared.opts.save(shared.config_filename) - shared.log.debug(f'Setting changed: {key}={value} progress={progress}') + if key not in ['sd_model_checkpoint', 'sd_model_refiner', 'sd_vae', 'sd_te', 'sd_unet']: + shared.log.debug(f'Setting changed: {key}={value} progress={progress}') return get_value_for_setting(key), shared.opts.dumpjson() diff --git a/pipelines/model_auraflow.py b/pipelines/model_auraflow.py index 790095cae..3d66c02b3 100644 --- a/pipelines/model_auraflow.py +++ b/pipelines/model_auraflow.py @@ -8,7 +8,7 @@ debug = shared.log.trace if os.environ.get('SD_LOAD_DEBUG', None) is not None el def load_auraflow(checkpoint_info, diffusers_load_config={}): - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) if 'torch_dtype' not in diffusers_load_config: diffusers_load_config['torch_dtype'] = torch.float16 debug(f'Load model: type=AuraFlow repo="{repo_id}" config={diffusers_load_config}') diff --git a/pipelines/model_chroma.py b/pipelines/model_chroma.py index 262b698e5..29190399e 100644 --- a/pipelines/model_chroma.py +++ b/pipelines/model_chroma.py @@ -24,7 +24,7 @@ def load_chroma_quanto(checkpoint_info): quantization_map = os.path.join(repo_path, "transformer", "quantization_map.json") debug(f'Load model: type=Chroma quantization map="{quantization_map}" repo="{checkpoint_info.name}" component="transformer"') if not os.path.exists(quantization_map): - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) quantization_map = hf_hub_download(repo_id, subfolder='transformer', filename='quantization_map.json', cache_dir=shared.opts.diffusers_dir) with open(quantization_map, "r", encoding='utf8') as f: quantization_map = json.load(f) @@ -50,7 +50,7 @@ def load_chroma_quanto(checkpoint_info): quantization_map = os.path.join(repo_path, "text_encoder", "quantization_map.json") debug(f'Load model: type=Chroma quantization map="{quantization_map}" repo="{checkpoint_info.name}" component="text_encoder"') if not os.path.exists(quantization_map): - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) quantization_map = hf_hub_download(repo_id, subfolder='text_encoder', filename='quantization_map.json', cache_dir=shared.opts.diffusers_dir) with open(quantization_map, "r", encoding='utf8') as f: quantization_map = json.load(f) @@ -184,15 +184,8 @@ def load_transformer(file_path): # triggered by opts.sd_unet change def load_chroma(checkpoint_info, diffusers_load_config): # triggered by opts.sd_checkpoint change fn = checkpoint_info.path - repo_id = sd_models.path_to_repo(checkpoint_info.name) - login = modelloader.hf_login() - try: - auth_check(repo_id) - except Exception as e: - repo_id = None - if not os.path.exists(fn): - shared.log.error(f'Load model: repo="{repo_id}" login={login} {e}') - return None + repo_id = sd_models.path_to_repo(checkpoint_info) + sd_models.hf_auth_check(checkpoint_info) prequantized = model_quant.get_quant(checkpoint_info.path) shared.log.debug(f'Load model: type=Chroma model="{checkpoint_info.name}" repo={repo_id or "none"} unet="{shared.opts.sd_unet}" te="{shared.opts.sd_text_encoder}" vae="{shared.opts.sd_vae}" quant={prequantized} offload={shared.opts.diffusers_offload_mode} dtype={devices.dtype}') diff --git a/pipelines/model_cogview.py b/pipelines/model_cogview.py index 0f1f4a3f7..38759fdb2 100644 --- a/pipelines/model_cogview.py +++ b/pipelines/model_cogview.py @@ -5,7 +5,7 @@ from modules import shared, devices, sd_models, model_quant, modelloader def load_cogview3(checkpoint_info, diffusers_load_config={}): modelloader.hf_login() - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) load_args, quant_args = model_quant.get_dit_args(diffusers_load_config, module='Model') shared.log.debug(f'Load model: type=CogView3 transformer="{repo_id}" quant="{model_quant.get_quant_type(quant_args)}" args={load_args}') @@ -42,7 +42,7 @@ def load_cogview3(checkpoint_info, diffusers_load_config={}): def load_cogview4(checkpoint_info, diffusers_load_config={}): modelloader.hf_login() - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) load_args, quant_args = model_quant.get_dit_args(diffusers_load_config, module='Model') shared.log.debug(f'Load model: type=CogView4 transformer="{repo_id}" quant="{model_quant.get_quant_type(quant_args)}" args={load_args}') diff --git a/pipelines/model_cosmos.py b/pipelines/model_cosmos.py index 6d7b17f33..87b85db0d 100644 --- a/pipelines/model_cosmos.py +++ b/pipelines/model_cosmos.py @@ -1,7 +1,6 @@ import os import transformers import diffusers -from huggingface_hub import auth_check from modules import shared, devices, sd_models, model_quant, modelloader, sd_hijack_te @@ -57,13 +56,8 @@ def load_text_encoder(repo_id, diffusers_load_config={}): def load_cosmos_t2i(checkpoint_info, diffusers_load_config={}): - repo_id = sd_models.path_to_repo(checkpoint_info.name) - login = modelloader.hf_login() - try: - auth_check(repo_id) - except Exception as e: - shared.log.error(f'Load model: repo="{repo_id}" login={login} {e}') - return False + repo_id = sd_models.path_to_repo(checkpoint_info) + sd_models.hf_auth_check(checkpoint_info) transformer = load_transformer(repo_id, diffusers_load_config) text_encoder = load_text_encoder(repo_id, diffusers_load_config) diff --git a/pipelines/model_flex.py b/pipelines/model_flex.py index 169d704e6..f531dac79 100644 --- a/pipelines/model_flex.py +++ b/pipelines/model_flex.py @@ -1,7 +1,6 @@ import os import transformers import diffusers -from huggingface_hub import auth_check from modules import shared, devices, sd_models, model_quant, modelloader, sd_hijack_te @@ -54,13 +53,8 @@ def load_text_encoders(repo_id, diffusers_load_config={}): def load_flex(checkpoint_info, diffusers_load_config={}): - repo_id = sd_models.path_to_repo(checkpoint_info.name) - login = modelloader.hf_login() - try: - auth_check(repo_id) - except Exception as e: - shared.log.error(f'Load model: repo="{repo_id}" login={login} {e}') - return False + repo_id = sd_models.path_to_repo(checkpoint_info) + sd_models.hf_auth_check(checkpoint_info) transformer = load_transformer(repo_id, diffusers_load_config) text_encoder_2 = load_text_encoders(repo_id, diffusers_load_config) diff --git a/pipelines/model_flux.py b/pipelines/model_flux.py index 574904f14..7b0908bf5 100644 --- a/pipelines/model_flux.py +++ b/pipelines/model_flux.py @@ -4,7 +4,7 @@ import torch import diffusers import transformers from safetensors.torch import load_file -from huggingface_hub import hf_hub_download, auth_check +from huggingface_hub import hf_hub_download from modules import shared, errors, devices, modelloader, sd_models, sd_unet, model_te, model_quant, sd_hijack_te @@ -24,7 +24,7 @@ def load_flux_quanto(checkpoint_info): quantization_map = os.path.join(repo_path, "transformer", "quantization_map.json") debug(f'Load model: type=FLUX quantization map="{quantization_map}" repo="{checkpoint_info.name}" component="transformer"') if not os.path.exists(quantization_map): - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) quantization_map = hf_hub_download(repo_id, subfolder='transformer', filename='quantization_map.json', cache_dir=shared.opts.diffusers_dir) with open(quantization_map, "r", encoding='utf8') as f: quantization_map = json.load(f) @@ -50,7 +50,7 @@ def load_flux_quanto(checkpoint_info): quantization_map = os.path.join(repo_path, "text_encoder_2", "quantization_map.json") debug(f'Load model: type=FLUX quantization map="{quantization_map}" repo="{checkpoint_info.name}" component="text_encoder_2"') if not os.path.exists(quantization_map): - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) quantization_map = hf_hub_download(repo_id, subfolder='text_encoder_2', filename='quantization_map.json', cache_dir=shared.opts.diffusers_dir) with open(quantization_map, "r", encoding='utf8') as f: quantization_map = json.load(f) @@ -204,13 +204,8 @@ def load_transformer(file_path): # triggered by opts.sd_unet change def load_flux(checkpoint_info, diffusers_load_config): # triggered by opts.sd_checkpoint change - repo_id = sd_models.path_to_repo(checkpoint_info.name) - login = modelloader.hf_login() - try: - auth_check(repo_id) - except Exception as e: - shared.log.error(f'Load model: repo="{repo_id}" login={login} {e}') - return False + repo_id = sd_models.path_to_repo(checkpoint_info) + sd_models.hf_auth_check(checkpoint_info) prequantized = model_quant.get_quant(checkpoint_info.path) shared.log.debug(f'Load model: type=FLUX model="{checkpoint_info.name}" repo="{repo_id}" unet="{shared.opts.sd_unet}" te="{shared.opts.sd_text_encoder}" vae="{shared.opts.sd_vae}" quant={prequantized} offload={shared.opts.diffusers_offload_mode} dtype={devices.dtype}') diff --git a/pipelines/model_hidream.py b/pipelines/model_hidream.py index 9acd92e38..47667e72a 100644 --- a/pipelines/model_hidream.py +++ b/pipelines/model_hidream.py @@ -1,7 +1,6 @@ import os import transformers import diffusers -from huggingface_hub import auth_check from modules import shared, devices, sd_models, model_quant, modelloader, sd_hijack_te @@ -60,7 +59,7 @@ def load_text_encoders(repo_id, diffusers_load_config={}): llama_repo = shared.opts.model_h1_llama_repo if shared.opts.model_h1_llama_repo != 'Default' else 'meta-llama/Meta-Llama-3.1-8B-Instruct' shared.log.debug(f'Load model: type=HiDream te4="{llama_repo}" quant="{model_quant.get_quant_type(quant_args)}" args={load_args}') - auth_check(llama_repo) + sd_models.hf_auth_check(llama_repo) text_encoder_4 = transformers.LlamaForCausalLM.from_pretrained( llama_repo, output_hidden_states=True, @@ -80,13 +79,8 @@ def load_text_encoders(repo_id, diffusers_load_config={}): def load_hidream(checkpoint_info, diffusers_load_config={}): - repo_id = sd_models.path_to_repo(checkpoint_info.name) - login = modelloader.hf_login() - try: - auth_check(repo_id) - except Exception as e: - shared.log.error(f'Load model: repo="{repo_id}" login={login} {e}') - return False + repo_id = sd_models.path_to_repo(checkpoint_info) + sd_models.hf_auth_check(checkpoint_info) transformer = load_transformer(repo_id, diffusers_load_config) text_encoder_3, text_encoder_4, tokenizer_4 = load_text_encoders(repo_id, diffusers_load_config) diff --git a/pipelines/model_lumina.py b/pipelines/model_lumina.py index 306881bbd..3c8794654 100644 --- a/pipelines/model_lumina.py +++ b/pipelines/model_lumina.py @@ -21,7 +21,7 @@ def load_lumina(_checkpoint_info, diffusers_load_config={}): def load_lumina2(checkpoint_info, diffusers_load_config={}): transformer, text_encoder, vae = None, None, None - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) if os.path.isdir(checkpoint_info.filename) and not repo_exists(repo_id): repo_id = checkpoint_info.filename diff --git a/pipelines/model_meissonic.py b/pipelines/model_meissonic.py index da7ea1429..650035913 100644 --- a/pipelines/model_meissonic.py +++ b/pipelines/model_meissonic.py @@ -12,7 +12,7 @@ def load_meissonic(checkpoint_info, diffusers_load_config={}): shared_items.pipelines['Meissonic'] = PipelineMeissonic modelloader.hf_login() - fn = sd_models.path_to_repo(checkpoint_info.path) + fn = sd_models.path_to_repo(checkpoint_info) cache_dir = shared.opts.diffusers_dir diffusers_load_config['variant'] = 'fp16' diff --git a/pipelines/model_omnigen.py b/pipelines/model_omnigen.py index ba60eb389..88f379dc8 100644 --- a/pipelines/model_omnigen.py +++ b/pipelines/model_omnigen.py @@ -6,7 +6,7 @@ debug = shared.log.trace if os.environ.get('SD_LOAD_DEBUG', None) is not None el def load_omnigen(checkpoint_info, diffusers_load_config={}): # pylint: disable=unused-argument - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) vae = None load_config, quant_config = model_quant.get_dit_args(diffusers_load_config, module='Model') diff --git a/pipelines/model_omnigen2.py b/pipelines/model_omnigen2.py index 33c354931..84b0b828b 100644 --- a/pipelines/model_omnigen2.py +++ b/pipelines/model_omnigen2.py @@ -5,7 +5,7 @@ debug = shared.log.trace if os.environ.get('SD_LOAD_DEBUG', None) is not None el def load_omnigen2(checkpoint_info, diffusers_load_config={}): # pylint: disable=unused-argument - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) from pipelines.omnigen2 import OmniGen2Pipeline, OmniGen2Transformer2DModel, Qwen2_5_VLForConditionalGeneration import diffusers diff --git a/pipelines/model_pixart.py b/pipelines/model_pixart.py index 7edcee7ac..c7798109a 100644 --- a/pipelines/model_pixart.py +++ b/pipelines/model_pixart.py @@ -6,7 +6,7 @@ from huggingface_hub import file_exists def load_pixart(checkpoint_info, diffusers_load_config={}): from modules import shared, devices, modelloader, sd_models, model_quant modelloader.hf_login() - repo_id = sd_models.path_to_repo(checkpoint_info.name) + repo_id = sd_models.path_to_repo(checkpoint_info) repo_id_tenc = repo_id repo_id_pipe = repo_id diff --git a/pipelines/model_sana.py b/pipelines/model_sana.py index 4de29f0d8..7d0b65b62 100644 --- a/pipelines/model_sana.py +++ b/pipelines/model_sana.py @@ -26,8 +26,7 @@ def load_quants(kwargs, repo_id, cache_dir): def load_sana(checkpoint_info, kwargs={}): modelloader.hf_login() - fn = checkpoint_info if isinstance(checkpoint_info, str) else checkpoint_info.path - repo_id = sd_models.path_to_repo(fn) + repo_id = sd_models.path_to_repo(checkpoint_info) kwargs.pop('load_connected_pipeline', None) kwargs.pop('safety_checker', None) diff --git a/pipelines/model_sd3.py b/pipelines/model_sd3.py index 8bfea1afa..f43b74a54 100644 --- a/pipelines/model_sd3.py +++ b/pipelines/model_sd3.py @@ -1,7 +1,6 @@ import os import diffusers import transformers -from huggingface_hub import auth_check from modules import shared, devices, errors, sd_models, sd_unet, model_quant, model_tools, modelloader @@ -90,14 +89,8 @@ def load_missing(kwargs, fn, cache_dir): def load_sd3(checkpoint_info, cache_dir=None, config=None): - repo_id = sd_models.path_to_repo(checkpoint_info.name) - login = modelloader.hf_login() - try: - auth_check(repo_id) - except Exception as e: - shared.log.error(f'Load model: repo="{repo_id}" login={login} {e}') - return False - + repo_id = sd_models.path_to_repo(checkpoint_info) + sd_models.hf_auth_check(checkpoint_info) fn = checkpoint_info.path kwargs = {}