fix(model): make saved modular pipelines self-contained and listed

Saving a modular pipeline now rewrites the component references in its
index to the destination folder, so a reload uses the saved quantized
weights instead of following the specs back to the source repositories.
The folder scan accepts modular_model_index.json for direct folders,
matching the snapshot branch, so saved pipelines list in the model
dropdown.
This commit is contained in:
CalamitousFelicitousness
2026-08-08 02:43:23 +01:00
parent ca9495cbe2
commit 9e72bebc8c
2 changed files with 10 additions and 2 deletions
+5 -2
View File
@@ -152,10 +152,13 @@ def load_diffusers_models(clear=True):
continue
name = name.replace("--", "/")
friendly = os.path.join(place, name)
has_index = os.path.exists(os.path.join(folder, 'model_index.json'))
index_file = os.path.join(folder, 'model_index.json')
if not os.path.exists(index_file):
index_file = os.path.join(folder, 'modular_model_index.json') # modular pipelines carry their own index flavor
has_index = os.path.exists(index_file)
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') }
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': index_file }
diffuser_repos.append(repo)
continue
+5
View File
@@ -1648,6 +1648,9 @@ def save_model(name: str, path: str | None = None, shard: str = "5GB", overwrite
try:
t0 = time.time()
log.info(f'Save model: path="{model_name}" cls={shared.sd_model.__class__.__name__} start')
if hasattr(shared.sd_model, '_component_specs'): # modular pipeline: the saved index must reference the destination folder, not the source repos; save_sdnq_model lives in the sdnq submodule and does not pass this flag
import functools
shared.sd_model.save_pretrained = functools.partial(shared.sd_model.save_pretrained, overwrite_modular_index=True)
save_sdnq_model(
model=shared.sd_model,
model_path=model_name,
@@ -1662,6 +1665,8 @@ def save_model(name: str, path: str | None = None, shard: str = "5GB", overwrite
errors.display(e, 'Save model')
return f'Error: {e}'
finally:
if 'save_pretrained' in vars(shared.sd_model):
del shared.sd_model.save_pretrained # drop the instance shadow, restoring the class method
shared.state.end(jobid)