diff --git a/installer.py b/installer.py index ed59080b4..6a8948ff7 100644 --- a/installer.py +++ b/installer.py @@ -386,6 +386,9 @@ def pip(arg: str, ignore: bool = False, quiet: bool = True, uv = True): t_start = time.time() originalArg = arg arg = arg.replace('>=', '==') + if opts.get('offline_mode', False): + log.warning('Offline mode enabled') + return package = arg.replace("install", "").replace("--upgrade", "").replace("--no-deps", "").replace("--force-reinstall", "").replace(" ", " ").strip() uv = uv and args.uv and not package.startswith('git+') pipCmd = "uv pip" if uv else "pip" diff --git a/modules/control/proc/depth_anything/__init__.py b/modules/control/proc/depth_anything/__init__.py index cf7ee92e2..4709727e4 100644 --- a/modules/control/proc/depth_anything/__init__.py +++ b/modules/control/proc/depth_anything/__init__.py @@ -27,7 +27,7 @@ class DepthAnythingDetector: PrepareForNet()]) @classmethod - def from_pretrained(cls, pretrained_model_or_path: str, cache_dir: str) -> str: + def from_pretrained(cls, pretrained_model_or_path: str, cache_dir: str, local_files_only=False) -> str: from modules.control.proc.depth_anything.dpt import DPT_DINOv2 import huggingface_hub as hf model = ( @@ -40,7 +40,7 @@ class DepthAnythingDetector: .to(devices.device) .eval() ) - model_path = hf.hf_hub_download(repo_id=pretrained_model_or_path, filename="pytorch_model.bin", cache_dir=cache_dir) + model_path = hf.hf_hub_download(repo_id=pretrained_model_or_path, filename="pytorch_model.bin", cache_dir=cache_dir, local_files_only=local_files_only) model_dict = torch.load(model_path) model.load_state_dict(model_dict) return cls(model) diff --git a/modules/control/proc/dwpose/__init__.py b/modules/control/proc/dwpose/__init__.py index e97ade3e6..9e8466a69 100644 --- a/modules/control/proc/dwpose/__init__.py +++ b/modules/control/proc/dwpose/__init__.py @@ -51,7 +51,7 @@ def check_dependencies(): status = [installed(p, reload=False, quiet=True) for p in packages] debug(f'DWPose required={packages} status={status}') if not all(status): - log.info(f'Installing DWPose dependencies: {packages}') + log.info(f'Installing dependencies: for=dwpose packages={packages}') cmd = 'install --upgrade --no-deps --force-reinstall ' pkgs = ' '.join(packages) pip(cmd + pkgs, ignore=False, quiet=True, uv=False) diff --git a/modules/control/proc/hed.py b/modules/control/proc/hed.py index e0144c41f..06610921e 100644 --- a/modules/control/proc/hed.py +++ b/modules/control/proc/hed.py @@ -60,12 +60,12 @@ class HEDdetector: self.model = model @classmethod - def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None, local_files_only=False): filename = filename or "ControlNetHED.pth" if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) model = ControlNetHED_Apache2() model.load_state_dict(torch.load(model_path, map_location='cpu')) model.float().eval() diff --git a/modules/control/proc/leres/__init__.py b/modules/control/proc/leres/__init__.py index 63040bc49..e2f358c7d 100644 --- a/modules/control/proc/leres/__init__.py +++ b/modules/control/proc/leres/__init__.py @@ -20,13 +20,13 @@ class LeresDetector: self.pix2pixmodel = pix2pixmodel @classmethod - def from_pretrained(cls, pretrained_model_or_path, filename=None, pix2pix_filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, filename=None, pix2pix_filename=None, cache_dir=None, local_files_only=False): filename = filename or "res101.pth" pix2pix_filename = pix2pix_filename or "latest_net_G.pth" if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) checkpoint = torch.load(model_path, map_location=torch.device('cpu')) model = RelDepthModel(backbone='resnext101') model.load_state_dict(strip_prefix_if_present(checkpoint['depth_model'], "module."), strict=True) @@ -34,7 +34,7 @@ class LeresDetector: if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, pix2pix_filename) else: - model_path = hf_hub_download(pretrained_model_or_path, pix2pix_filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, pix2pix_filename, cache_dir=cache_dir, local_files_only=local_files_only) opt = TestOptions().parse() if not torch.cuda.is_available(): opt.gpu_ids = [] # cpu mode diff --git a/modules/control/proc/lineart.py b/modules/control/proc/lineart.py index afd55d9a7..61d3ce8b4 100644 --- a/modules/control/proc/lineart.py +++ b/modules/control/proc/lineart.py @@ -95,7 +95,7 @@ class LineartDetector: self.model_coarse = coarse_model @classmethod - def from_pretrained(cls, pretrained_model_or_path, filename=None, coarse_filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, filename=None, coarse_filename=None, cache_dir=None, local_files_only=False): filename = filename or "sk_model.pth" coarse_filename = coarse_filename or "sk_model2.pth" @@ -103,8 +103,8 @@ class LineartDetector: model_path = os.path.join(pretrained_model_or_path, filename) coarse_model_path = os.path.join(pretrained_model_or_path, coarse_filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) - coarse_model_path = hf_hub_download(pretrained_model_or_path, coarse_filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) + coarse_model_path = hf_hub_download(pretrained_model_or_path, coarse_filename, cache_dir=cache_dir, local_files_only=local_files_only) model = Generator(3, 1, 3) model.load_state_dict(torch.load(model_path, map_location=torch.device('cpu'))) diff --git a/modules/control/proc/lineart_anime.py b/modules/control/proc/lineart_anime.py index 541fcad61..c70da3784 100644 --- a/modules/control/proc/lineart_anime.py +++ b/modules/control/proc/lineart_anime.py @@ -117,12 +117,12 @@ class LineartAnimeDetector: self.model = model @classmethod - def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None, local_files_only=False): filename = filename or "netG.pth" if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) norm_layer = functools.partial(nn.InstanceNorm2d, affine=False, track_running_stats=False) net = UnetGenerator(3, 1, 8, 64, norm_layer=norm_layer, use_dropout=False) ckpt = torch.load(model_path) diff --git a/modules/control/proc/midas/__init__.py b/modules/control/proc/midas/__init__.py index ba6d1b0e5..0ca4b4fee 100644 --- a/modules/control/proc/midas/__init__.py +++ b/modules/control/proc/midas/__init__.py @@ -17,7 +17,7 @@ class MidasDetector: self.model = model @classmethod - def from_pretrained(cls, pretrained_model_or_path, model_type="dpt_hybrid", filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, model_type="dpt_hybrid", filename=None, cache_dir=None, local_files_only=False): if pretrained_model_or_path == "lllyasviel/ControlNet": filename = filename or "annotator/ckpts/dpt_hybrid-midas-501f0c75.pt" else: @@ -25,7 +25,7 @@ class MidasDetector: if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) model = MiDaSInference(model_type=model_type, model_path=model_path) return cls(model) diff --git a/modules/control/proc/mlsd/__init__.py b/modules/control/proc/mlsd/__init__.py index ea26c5b0d..e46ac865c 100644 --- a/modules/control/proc/mlsd/__init__.py +++ b/modules/control/proc/mlsd/__init__.py @@ -16,7 +16,7 @@ class MLSDdetector: self.model = model @classmethod - def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None, local_files_only=False): if pretrained_model_or_path == "lllyasviel/ControlNet": filename = filename or "annotator/ckpts/mlsd_large_512_fp32.pth" else: @@ -24,7 +24,7 @@ class MLSDdetector: if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) model = MobileV2_MLSD_Large() model.load_state_dict(torch.load(model_path), strict=True) model.eval() diff --git a/modules/control/proc/normalbae/__init__.py b/modules/control/proc/normalbae/__init__.py index ba10570c6..16e613dc9 100644 --- a/modules/control/proc/normalbae/__init__.py +++ b/modules/control/proc/normalbae/__init__.py @@ -33,12 +33,12 @@ class NormalBaeDetector: self.norm = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) @classmethod - def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None, local_files_only=False): filename = filename or "scannet.pt" if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) args = types.SimpleNamespace() args.mode = 'client' args.architecture = 'BN' diff --git a/modules/control/proc/openpose/__init__.py b/modules/control/proc/openpose/__init__.py index 80649e213..746351718 100644 --- a/modules/control/proc/openpose/__init__.py +++ b/modules/control/proc/openpose/__init__.py @@ -76,7 +76,7 @@ class OpenposeDetector: self.face_estimation = face_estimation @classmethod - def from_pretrained(cls, pretrained_model_or_path, filename=None, hand_filename=None, face_filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, filename=None, hand_filename=None, face_filename=None, cache_dir=None, local_files_only=False): if pretrained_model_or_path == "lllyasviel/ControlNet": filename = filename or "annotator/ckpts/body_pose_model.pth" @@ -96,9 +96,9 @@ class OpenposeDetector: hand_model_path = os.path.join(pretrained_model_or_path, hand_filename) face_model_path = os.path.join(face_pretrained_model_or_path, face_filename) else: - body_model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) - hand_model_path = hf_hub_download(pretrained_model_or_path, hand_filename, cache_dir=cache_dir) - face_model_path = hf_hub_download(face_pretrained_model_or_path, face_filename, cache_dir=cache_dir) + body_model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) + hand_model_path = hf_hub_download(pretrained_model_or_path, hand_filename, cache_dir=cache_dir, local_files_only=local_files_only) + face_model_path = hf_hub_download(face_pretrained_model_or_path, face_filename, cache_dir=cache_dir, local_files_only=local_files_only) body_estimation = Body(body_model_path) hand_estimation = Hand(hand_model_path) diff --git a/modules/control/proc/pidi.py b/modules/control/proc/pidi.py index 078525f2b..2b18eedf9 100644 --- a/modules/control/proc/pidi.py +++ b/modules/control/proc/pidi.py @@ -16,12 +16,12 @@ class PidiNetDetector: self.model = model @classmethod - def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, filename=None, cache_dir=None, local_files_only=False): filename = filename or "table5_pidinet.pth" if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) model = pidinet() model.load_state_dict({k.replace('module.', ''): v for k, v in torch.load(model_path)['state_dict'].items()}) model.eval() diff --git a/modules/control/proc/segment_anything/__init__.py b/modules/control/proc/segment_anything/__init__.py index d698b46fc..121421c18 100644 --- a/modules/control/proc/segment_anything/__init__.py +++ b/modules/control/proc/segment_anything/__init__.py @@ -23,12 +23,12 @@ class SamDetector: self.model = mask_generator @classmethod - def from_pretrained(cls, model_path, filename, model_type, cache_dir=None): + def from_pretrained(cls, model_path, filename, model_type, cache_dir=None, local_files_only=False): """ Possible model_type : vit_h, vit_l, vit_b, vit_t download weights from https://github.com/facebookresearch/segment-anything """ - model_path = hf_hub_download(model_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(model_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) sam = sam_model_registry[model_type](checkpoint=model_path) sam.to(devices.device) mask_generator = SamAutomaticMaskGenerator(sam) diff --git a/modules/control/proc/zoe/__init__.py b/modules/control/proc/zoe/__init__.py index bb18201e0..a6550d605 100644 --- a/modules/control/proc/zoe/__init__.py +++ b/modules/control/proc/zoe/__init__.py @@ -20,12 +20,12 @@ class ZoeDetector: self.model = model @classmethod - def from_pretrained(cls, pretrained_model_or_path, model_type="zoedepth", filename=None, cache_dir=None): + def from_pretrained(cls, pretrained_model_or_path, model_type="zoedepth", filename=None, cache_dir=None, local_files_only=False): filename = filename or "ZoeD_M12_N.pt" if os.path.isdir(pretrained_model_or_path): model_path = os.path.join(pretrained_model_or_path, filename) else: - model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir) + model_path = hf_hub_download(pretrained_model_or_path, filename, cache_dir=cache_dir, local_files_only=local_files_only) if model_type == "zoedepth": model_cls = ZoeDepth elif model_type == "zoedepth_nk": diff --git a/modules/control/processors.py b/modules/control/processors.py index baca2fbb3..1f5b0494b 100644 --- a/modules/control/processors.py +++ b/modules/control/processors.py @@ -172,15 +172,13 @@ class Processor(): return f' Processor(id={self.processor_id} model={self.model.__class__.__name__})' if self.processor_id and self.model else '' def reset(self, processor_id: str = None): - from modules.shared import opts if self.model is not None: debug(f'Control Processor unloaded: id="{self.processor_id}"') self.model = None self.processor_id = processor_id devices.torch_gc(force=True, reason='processor') - # self.override = None - # devices.torch_gc() self.load_config = { 'cache_dir': cache_dir } + from modules.shared import opts if opts.offline_mode: self.load_config["local_files_only"] = True os.environ['HF_HUB_OFFLINE'] = '1' diff --git a/modules/control/units/lite.py b/modules/control/units/lite.py index fbabe2280..107ebb0a0 100644 --- a/modules/control/units/lite.py +++ b/modules/control/units/lite.py @@ -108,8 +108,15 @@ class ControlLLLite(): self.model = ControlNetLLLite(model_path) else: import huggingface_hub as hf + offline_config = {} + if opts.offline_mode: + offline_config["local_files_only"] = True + os.environ['HF_HUB_OFFLINE'] = '1' + else: + os.environ.pop('HF_HUB_OFFLINE', None) + os.unsetenv('HF_HUB_OFFLINE') folder, filename = os.path.split(model_path) - model_path = hf.hf_hub_download(repo_id=folder, filename=f'{filename}.safetensors', cache_dir=cache_dir) + model_path = hf.hf_hub_download(repo_id=folder, filename=f'{filename}.safetensors', cache_dir=cache_dir, **offline_config) self.model = ControlNetLLLite(model_path) if self.device is not None: self.model.to(self.device) diff --git a/modules/control/units/t2iadapter.py b/modules/control/units/t2iadapter.py index 35ba8ab43..b9e049779 100644 --- a/modules/control/units/t2iadapter.py +++ b/modules/control/units/t2iadapter.py @@ -2,7 +2,7 @@ import os import time from typing import Union import threading -from diffusers import pipelines, StableDiffusionPipeline, StableDiffusionXLPipeline, T2IAdapter, MultiAdapter, StableDiffusionAdapterPipeline, StableDiffusionXLAdapterPipeline # pylint: disable=unused-import +from diffusers import StableDiffusionPipeline, StableDiffusionXLPipeline, T2IAdapter, MultiAdapter, StableDiffusionAdapterPipeline, StableDiffusionXLAdapterPipeline # pylint: disable=unused-import from installer import log from modules import errors, sd_models from modules.control.units import detect @@ -104,6 +104,13 @@ class Adapter(): return model_path, model_args = all_models[model_id] self.load_config.update(model_args) + from modules.shared import opts + if opts.offline_mode: + self.load_config["local_files_only"] = True + os.environ['HF_HUB_OFFLINE'] = '1' + else: + os.environ.pop('HF_HUB_OFFLINE', None) + os.unsetenv('HF_HUB_OFFLINE') if model_path is None: log.error(f'Control {what} model load failed: id="{model_id}" error=unknown model id') return @@ -168,6 +175,7 @@ class AdapterPipeline(): adapter=adapter, ) sd_models.move_model(self.pipeline, pipeline.device) + sd_models.apply_balanced_offload(self.pipeline, force=True) elif detect.is_sd15(pipeline): self.pipeline = StableDiffusionAdapterPipeline( vae=pipeline.vae, @@ -181,6 +189,7 @@ class AdapterPipeline(): adapter=adapter, ) sd_models.move_model(self.pipeline, pipeline.device) + sd_models.apply_balanced_offload(self.pipeline, force=True) else: log.error(f'Control {what} pipeline: class={pipeline.__class__.__name__} unsupported model type') return diff --git a/modules/control/units/xs.py b/modules/control/units/xs.py index f727a0111..2d56fd7ff 100644 --- a/modules/control/units/xs.py +++ b/modules/control/units/xs.py @@ -100,6 +100,12 @@ class ControlNetXS(): # log.debug(f'Control {what} model: id="{model_id}" path="{model_path}" already loaded') return self.load_config['time_embedding_mix'] = time_embedding_mix + if opts.offline_mode: + self.load_config["local_files_only"] = True + os.environ['HF_HUB_OFFLINE'] = '1' + else: + os.environ.pop('HF_HUB_OFFLINE', None) + os.unsetenv('HF_HUB_OFFLINE') log.debug(f'Control {what} model loading: id="{model_id}" path="{model_path}" {self.load_config}') if model_path.endswith('.safetensors'): self.model = ControlNetXSModel.from_single_file(model_path, **self.load_config) @@ -140,6 +146,7 @@ class ControlNetXSPipeline(): controlnet=controlnet, # can be a list ) sd_models.move_model(self.pipeline, pipeline.device) + sd_models.apply_balanced_offload(self.pipeline, force=True) elif detect.is_sd15(pipeline): self.pipeline = StableDiffusionControlNetXSPipeline( vae=pipeline.vae, @@ -153,6 +160,7 @@ class ControlNetXSPipeline(): controlnet=controlnet, # can be a list ) sd_models.move_model(self.pipeline, pipeline.device) + sd_models.apply_balanced_offload(self.pipeline, force=True) else: log.error(f'Control {what} pipeline: class={pipeline.__class__.__name__} unsupported model type') return diff --git a/modules/framepack/framepack_load.py b/modules/framepack/framepack_load.py index 281bfe010..4b99126ef 100644 --- a/modules/framepack/framepack_load.py +++ b/modules/framepack/framepack_load.py @@ -140,14 +140,14 @@ def load_model(variant:str=None, pipeline:str=None, text_encoder:str=None, text_ shared.log.debug(f'FramePack load: module=llm {model["text_encoder"]}') load_args, quant_args = model_quant.get_dit_args({}, module='TE', device_map=True) text_encoder = LlamaModel.from_pretrained(model["text_encoder"]["repo"], subfolder=model["text_encoder"]["subfolder"], cache_dir=shared.opts.hfcache_dir, **load_args, **quant_args, **offline_config) - tokenizer = LlamaTokenizerFast.from_pretrained(model["tokenizer"]["repo"], subfolder=model["tokenizer"]["subfolder"], cache_dir=shared.opts.hfcache_dir) + tokenizer = LlamaTokenizerFast.from_pretrained(model["tokenizer"]["repo"], subfolder=model["tokenizer"]["subfolder"], cache_dir=shared.opts.hfcache_dir, **offline_config) text_encoder.requires_grad_(False) text_encoder.eval() sd_models.move_model(text_encoder, devices.cpu) shared.log.debug(f'FramePack load: module=te {model["text_encoder_2"]}') text_encoder_2 = CLIPTextModel.from_pretrained(model["text_encoder_2"]["repo"], subfolder=model["text_encoder_2"]["subfolder"], torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir, **offline_config) - tokenizer_2 = CLIPTokenizer.from_pretrained(model["pipeline"]["repo"], subfolder='tokenizer_2', cache_dir=shared.opts.hfcache_dir) + tokenizer_2 = CLIPTokenizer.from_pretrained(model["pipeline"]["repo"], subfolder='tokenizer_2', cache_dir=shared.opts.hfcache_dir, **offline_config) text_encoder_2.requires_grad_(False) text_encoder_2.eval() sd_models.move_model(text_encoder_2, devices.cpu) diff --git a/modules/ipadapter.py b/modules/ipadapter.py index 88a01e2cd..a74575440 100644 --- a/modules/ipadapter.py +++ b/modules/ipadapter.py @@ -190,14 +190,15 @@ def load_image_encoder(pipe: diffusers.DiffusionPipeline, adapter_names: list[st if pipe.image_encoder is None or clip_loaded != f'{clip_repo}/{clip_subfolder}': jobid = shared.state.begin('Load encoder') try: + offline_config = { 'local_files_only': True } if shared.opts.offline_mode else {} if shared.sd_model_type == 'sd3': - image_encoder = transformers.SiglipVisionModel.from_pretrained(clip_repo, torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir) + image_encoder = transformers.SiglipVisionModel.from_pretrained(clip_repo, torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir, **offline_config) else: if clip_subfolder is None: - image_encoder = transformers.CLIPVisionModelWithProjection.from_pretrained(clip_repo, torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir, use_safetensors=True) + image_encoder = transformers.CLIPVisionModelWithProjection.from_pretrained(clip_repo, torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir, use_safetensors=True, **offline_config) shared.log.debug(f'IP adapter load: encoder="{clip_repo}" cls={pipe.image_encoder.__class__.__name__}') else: - image_encoder = transformers.CLIPVisionModelWithProjection.from_pretrained(clip_repo, subfolder=clip_subfolder, torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir, use_safetensors=True) + image_encoder = transformers.CLIPVisionModelWithProjection.from_pretrained(clip_repo, subfolder=clip_subfolder, torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir, use_safetensors=True, **offline_config) shared.log.debug(f'IP adapter load: encoder="{clip_repo}/{clip_subfolder}" cls={pipe.image_encoder.__class__.__name__}') sd_models.clear_caches() image_encoder = model_quant.do_post_load_quant(image_encoder, allow=True) @@ -220,8 +221,9 @@ def load_feature_extractor(pipe): if pipe.feature_extractor is None: try: jobid = shared.state.begin('Load extractor') + offline_config = { 'local_files_only': True } if shared.opts.offline_mode else {} if shared.sd_model_type == 'sd3': - feature_extractor = transformers.SiglipImageProcessor.from_pretrained(SIGLIP_ID, torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir) + feature_extractor = transformers.SiglipImageProcessor.from_pretrained(SIGLIP_ID, torch_dtype=devices.dtype, cache_dir=shared.opts.hfcache_dir, **offline_config) else: feature_extractor = transformers.CLIPImageProcessor() if hasattr(pipe, 'register_modules'): @@ -343,6 +345,8 @@ def apply(pipe, p: processing.StableDiffusionProcessing, adapter_names=[], adapt kwargs['weight_name'] = names if len(names) > 1 else names[0] if len(revisions) > 0: kwargs['revision'] = revisions[0] + if shared.opts.offline_mode: + kwargs["local_files_only"] = True pipe.load_ip_adapter(repos, **kwargs) adapters_loaded = names if hasattr(p, 'ip_adapter_layers'): diff --git a/modules/sd_offload.py b/modules/sd_offload.py index 0d9defd5d..59aea6fd0 100644 --- a/modules/sd_offload.py +++ b/modules/sd_offload.py @@ -409,7 +409,7 @@ def report_model_stats(module_name, module): shared.log.error(f'Module stats: name={module_name} {e}') -def apply_balanced_offload(sd_model=None, exclude=[]): +def apply_balanced_offload(sd_model=None, exclude=[], force=False): global offload_hook_instance # pylint: disable=global-statement if shared.opts.diffusers_offload_mode != "balanced": return sd_model @@ -424,7 +424,7 @@ def apply_balanced_offload(sd_model=None, exclude=[]): return sd_model cached = True checkpoint_name = sd_model.sd_checkpoint_info.name if getattr(sd_model, "sd_checkpoint_info", None) is not None else sd_model.__class__.__name__ - if (offload_hook_instance is None) or (offload_hook_instance.min_watermark != shared.opts.diffusers_offload_min_gpu_memory) or (offload_hook_instance.max_watermark != shared.opts.diffusers_offload_max_gpu_memory) or (checkpoint_name != offload_hook_instance.checkpoint_name): + if force or (offload_hook_instance is None) or (offload_hook_instance.min_watermark != shared.opts.diffusers_offload_min_gpu_memory) or (offload_hook_instance.max_watermark != shared.opts.diffusers_offload_max_gpu_memory) or (checkpoint_name != offload_hook_instance.checkpoint_name): cached = False offload_hook_instance = OffloadHook(checkpoint_name)