Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:AUTOMATIC1111 Stable diffusion webui Run modelmerger

From Leeroopedia


Knowledge Sources
Domains Model Merging, Checkpoint Merging, Memory Management
Last Updated 2026-02-08 00:00 GMT

Overview

Concrete tool for executing the full checkpoint merging pipeline including model loading, two-pass weight interpolation, and output generation provided by stable-diffusion-webui.

Description

The run_modelmerger function is the main entry point for the checkpoint merging workflow. It orchestrates the entire merge pipeline:

  1. Validates input parameters and resolves model names to CheckpointInfo objects via the global checkpoints_list.
  2. Selects the interpolation method from the theta_funcs dispatch dictionary.
  3. Pass 1 (conditional): For "Add difference" mode, loads models B and C, computes B - C per key using get_difference, then frees model C.
  4. Pass 2: Loads model A and iterates over its state dict, applying the interpolation function (weighted_sum or add_difference) for each key present in both A and B. Handles shape mismatches for inpainting and instruct-pix2pix models.
  5. Applies FP16 conversion per-tensor via to_half during the merge loop.
  6. Optionally bakes in an external VAE by overwriting first_stage_model.* keys.
  7. Optionally discards weight keys matching a regex pattern.
  8. Constructs the output filename (auto-generated or custom) and saves in the specified format.
  9. Optionally embeds metadata including a machine-readable merge recipe.
  10. Refreshes the model registry via sd_models.list_models() and computes the shorthash of the new checkpoint.

The function uses shared.state for job management and progress reporting, and returns a list of Gradio UI updates plus a status message.

Usage

This function is called from the Gradio UI's "Merge" button handler. It can also be invoked programmatically through the WebUI's API. It should be called as a background task (via id_task) since merging large models can take several minutes.

Code Reference

Source Location

Signature

def run_modelmerger(
    id_task,
    primary_model_name,
    secondary_model_name,
    tertiary_model_name,
    interp_method,
    multiplier,
    save_as_half,
    custom_name,
    checkpoint_format,
    config_source,
    bake_in_vae,
    discard_weights,
    save_metadata,
    add_merge_recipe,
    copy_metadata_fields,
    metadata_json
):
    ...

Import

from modules.extras import run_modelmerger

I/O Contract

Inputs

Name Type Required Description
id_task str Yes Task identifier for progress tracking
primary_model_name str Yes Title/key of model A in checkpoints_list
secondary_model_name str Yes Title/key of model B (required for Weighted sum and Add difference)
tertiary_model_name str Yes Title/key of model C (required only for Add difference)
interp_method str Yes One of: "Weighted sum", "Add difference", "No interpolation"
multiplier float Yes Interpolation alpha value, typically in [0, 1]
save_as_half bool Yes Whether to convert float32 weights to float16
custom_name str Yes Custom output filename (empty string for auto-generated name)
checkpoint_format str Yes Output format: "safetensors" or "ckpt"
config_source int Yes Config file source: 0=A/B/C, 1=B, 2=C, 3=None
bake_in_vae str Yes VAE name to bake in (empty or name from sd_vae.vae_dict)
discard_weights str Yes Regex pattern for keys to discard (empty to keep all)
save_metadata bool Yes Whether to embed metadata in the output file
add_merge_recipe bool Yes Whether to include merge recipe in metadata
copy_metadata_fields bool Yes Whether to copy metadata from source models
metadata_json str Yes Additional JSON metadata string to embed

Outputs

Name Type Description
return list A list containing 4 gr.Dropdown.update objects (refreshed model dropdowns) followed by a status message string

Execution Flow

1. shared.state.begin(job="model-merge")
2. Resolve model names -> CheckpointInfo objects
3. Select (filename_generator, theta_func1, theta_func2) from theta_funcs[interp_method]
4. IF theta_func1 (Add difference mode):
   a. Load model B state dict (theta_1)
   b. Load model C state dict (theta_2)
   c. For each key in theta_1:
      - Skip keys in checkpoint_dict_skip_on_merge
      - If "model" in key and key in theta_2:
          theta_1[key] = get_difference(theta_1[key], theta_2[key])
      - Else if "model" in key:
          theta_1[key] = zeros_like(theta_1[key])
   d. Delete theta_2
5. Load model A state dict (theta_0)
6. For each key in theta_0:
   a. Skip keys in checkpoint_dict_skip_on_merge
   b. If theta_1 exists and "model" in key and key in theta_1:
      - Handle shape mismatches (inpainting/instruct-pix2pix)
      - theta_0[key] = theta_func2(theta_0[key], theta_1[key], multiplier)
      - theta_0[key] = to_half(theta_0[key], save_as_half)
7. Delete theta_1
8. IF bake_in_vae: load VAE and overwrite first_stage_model.* keys
9. IF save_as_half and no theta_func2: convert remaining tensors
10. IF discard_weights: remove matching keys
11. Generate output filename and path
12. Save as safetensors or ckpt with optional metadata
13. sd_models.list_models() to refresh registry
14. Calculate shorthash of new model
15. Copy config file if applicable
16. shared.state.end()
17. Return [dropdown_updates..., status_message]

Error Handling

The function uses an internal fail(message) helper that:

  • Sets shared.state.textinfo to the error message
  • Calls shared.state.end() to clean up the job
  • Returns a list of gr.update() placeholders plus the error message

Specific error conditions:

  • Missing primary model: "Failed: Merging requires a primary model."
  • Missing secondary model for interpolation methods that require it
  • Missing tertiary model for "Add difference" method
  • Shape mismatch where A has fewer channels than B raises RuntimeError

Usage Examples

Basic Usage

from modules.extras import run_modelmerger

# Weighted sum merge at 30% model B
result = run_modelmerger(
    id_task="merge-001",
    primary_model_name="v1-5-pruned-emaonly.safetensors [6ce0161689]",
    secondary_model_name="dreamshaper_8.safetensors [abcd1234ef]",
    tertiary_model_name="",
    interp_method="Weighted sum",
    multiplier=0.3,
    save_as_half=True,
    custom_name="my_merged_model",
    checkpoint_format="safetensors",
    config_source=0,
    bake_in_vae="",
    discard_weights="",
    save_metadata=True,
    add_merge_recipe=True,
    copy_metadata_fields=True,
    metadata_json="{}"
)
# result[-1] == "Checkpoint saved to /models/Stable-diffusion/my_merged_model.safetensors"

Add Difference Merge

from modules.extras import run_modelmerger

# Transfer specialization from B over base C to model A
result = run_modelmerger(
    id_task="merge-002",
    primary_model_name="v1-5-pruned-emaonly.safetensors [6ce0161689]",
    secondary_model_name="specialized_model.safetensors [1234abcdef]",
    tertiary_model_name="base_model.safetensors [fedcba4321]",
    interp_method="Add difference",
    multiplier=1.0,
    save_as_half=True,
    custom_name="",
    checkpoint_format="safetensors",
    config_source=0,
    bake_in_vae="vae-ft-mse-840000-ema-pruned",
    discard_weights="",
    save_metadata=True,
    add_merge_recipe=True,
    copy_metadata_fields=False,
    metadata_json="{}"
)

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment