mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
@@ -1,5 +1,18 @@
|
||||
# Change Log for SD.Next
|
||||
|
||||
## Update for 2025-10-19
|
||||
|
||||
- **Features**
|
||||
- **offline mode**: enable in *settings -> hugginface*
|
||||
enables fully offline mode where previously downloaded models are used as-is
|
||||
- **Backend**
|
||||
- switch to `torch==2.9` for *ipex, rocm and openvino*
|
||||
- switch to `rocm==7.0` for nightlies
|
||||
- **Quantization**
|
||||
- improved SDNQ SVD and low-bit matmul performance
|
||||
- **Fixes**
|
||||
- startup error with `--profile` enabled if using `--skip`
|
||||
|
||||
## Update for 2025-10-18
|
||||
|
||||
- **Models**
|
||||
|
||||
+8
-3
@@ -1496,12 +1496,17 @@ def check_venv():
|
||||
|
||||
|
||||
# check version of the main repo and optionally upgrade it
|
||||
def check_version(offline=False, reset=True): # pylint: disable=unused-argument
|
||||
def check_version(reset=True): # pylint: disable=unused-argument
|
||||
if opts.get('offline_mode', False):
|
||||
log.warning('Offline mode enabled')
|
||||
args.skip_git = True # pylint: disable=attribute-defined-outside-init
|
||||
args.skip_all = True # pylint: disable=attribute-defined-outside-init
|
||||
return
|
||||
t_start = time.time()
|
||||
if args.skip_all:
|
||||
return
|
||||
if not os.path.exists('.git'):
|
||||
log.warning('Not a git repository, all git operations are disabled')
|
||||
log.warning('Not a git repository')
|
||||
args.skip_git = True # pylint: disable=attribute-defined-outside-init
|
||||
ver = get_version()
|
||||
log.info(f'Version: {print_dict(ver)}')
|
||||
@@ -1538,7 +1543,7 @@ def check_version(offline=False, reset=True): # pylint: disable=unused-argument
|
||||
else:
|
||||
log.warning('Repository: retrying upgrade...')
|
||||
git_reset()
|
||||
check_version(offline=offline, reset=False)
|
||||
check_version(reset=False)
|
||||
else:
|
||||
dt = commits["commit"]["commit"]["author"]["date"]
|
||||
commit = commits["commit"]["sha"][:8]
|
||||
|
||||
@@ -20,6 +20,8 @@ pbar = None
|
||||
|
||||
|
||||
def hf_login(token=None):
|
||||
if shared.opts.offline_mode:
|
||||
return False
|
||||
global loggedin # pylint: disable=global-statement
|
||||
token = token or shared.opts.huggingface_token
|
||||
token = token.replace("\n", "").replace("\r", "").strip() if token is not None else None
|
||||
@@ -38,7 +40,8 @@ def hf_login(token=None):
|
||||
if loggedin != token:
|
||||
stdout = io.StringIO()
|
||||
try:
|
||||
hf.logout()
|
||||
with contextlib.redirect_stdout(stdout):
|
||||
hf.logout()
|
||||
except Exception:
|
||||
pass
|
||||
with contextlib.redirect_stdout(stdout):
|
||||
|
||||
+15
-5
@@ -657,6 +657,15 @@ def load_diffuser(checkpoint_info=None, op='model', revision=None): # pylint: di
|
||||
unload_model_weights(op=op)
|
||||
return
|
||||
|
||||
# handle offline mode
|
||||
if shared.opts.offline_mode:
|
||||
shared.log.info(f'Load {op}: offline=True')
|
||||
diffusers_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')
|
||||
|
||||
# detect pipeline
|
||||
pipeline, model_type = sd_detect.detect_pipeline(checkpoint_info.path, op)
|
||||
set_huggingface_options()
|
||||
@@ -1247,14 +1256,15 @@ def unload_model_weights(op='model'):
|
||||
|
||||
|
||||
def hf_auth_check(checkpoint_info, force:bool=False):
|
||||
if shared.opts.offline_mode:
|
||||
shared.log.info('Offline mode: skipping auth check')
|
||||
return False
|
||||
login = None
|
||||
if not force:
|
||||
try:
|
||||
# skip check for single-file safetensors models
|
||||
if (checkpoint_info.path.endswith('.safetensors') and os.path.isfile(checkpoint_info.path)):
|
||||
if (checkpoint_info.path.endswith('.safetensors') and os.path.isfile(checkpoint_info.path)): # skip check for single-file safetensors models
|
||||
return True
|
||||
# skip check for local diffusers folders
|
||||
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'))):
|
||||
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 local diffusers folders
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
@@ -1263,7 +1273,7 @@ def hf_auth_check(checkpoint_info, force:bool=False):
|
||||
login = modelloader.hf_login()
|
||||
return hf.auth_check(repo_id)
|
||||
except Exception as e:
|
||||
shared.log.error(f'Load model: repo="{repo_id}" login={login} {e}')
|
||||
shared.log.error(f'Auth: repo="{repo_id}" login={login} {e}')
|
||||
return False
|
||||
|
||||
|
||||
|
||||
@@ -689,6 +689,7 @@ options_templates.update(options_section(('huggingface', "Huggingface"), {
|
||||
"huggingface_token": OptionInfo('', 'HuggingFace token', gr.Textbox, {"lines": 2}),
|
||||
"hf_transfer_mode": OptionInfo("rust", "HuggingFace download method", gr.Radio, {"choices": ['requests', 'rust', 'xet']}),
|
||||
"huggingface_mirror": OptionInfo('', 'HuggingFace mirror', gr.Textbox),
|
||||
"offline_mode": OptionInfo(False, 'Force offline mode', gr.Checkbox),
|
||||
|
||||
"diffusers_model_load_variant": OptionInfo("default", "Preferred Model variant", gr.Radio, {"choices": ['default', 'fp32', 'fp16']}),
|
||||
"diffusers_vae_load_variant": OptionInfo("default", "Preferred VAE variant", gr.Radio, {"choices": ['default', 'fp32', 'fp16']}),
|
||||
|
||||
@@ -37,12 +37,15 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage):
|
||||
|
||||
if not shared.opts.sd_checkpoint_autodownload or not shared.opts.extra_network_reference_enable:
|
||||
return []
|
||||
count = { 'total': 0, 'ready': 0, 'hidden': 0, 'experimental': 0 }
|
||||
for k, v in shared.reference_models.items():
|
||||
count['total'] += 1
|
||||
url = v['path']
|
||||
experimental = v.get('experimental', False)
|
||||
if experimental:
|
||||
if shared.cmd_opts.experimental:
|
||||
shared.log.debug(f'Networks: experimental model="{k}"')
|
||||
count['experimental'] += 1
|
||||
else:
|
||||
continue
|
||||
preview = v.get('preview', v['path'])
|
||||
@@ -61,6 +64,12 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage):
|
||||
path = f'{v.get("path", "")}+{v.get("subfolder", "")}'
|
||||
else:
|
||||
path = f'{v.get("path", "")}'
|
||||
ready = reference_downloaded(url)
|
||||
if not ready and shared.opts.offline_mode:
|
||||
count['hidden'] += 1
|
||||
continue
|
||||
if ready:
|
||||
count['ready'] += 1
|
||||
yield {
|
||||
"type": 'Model',
|
||||
"name": name,
|
||||
@@ -75,8 +84,9 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage):
|
||||
"info": {},
|
||||
"metadata": {},
|
||||
"description": v.get('desc', ''),
|
||||
"version": "ready" if reference_downloaded(url) else "download",
|
||||
"version": "ready" if ready else "download",
|
||||
}
|
||||
shared.log.debug(f'Networks: type="reference" items={count["total"]} ready={count["ready"]} hidden={count["hidden"]} experimental={count["experimental"]}')
|
||||
|
||||
def create_item(self, name):
|
||||
record = None
|
||||
|
||||
Reference in New Issue
Block a user