{"id":18619951,"url":"https://github.com/ljleb/sd-mecha","last_synced_at":"2026-04-01T17:45:42.947Z","repository":{"id":222242969,"uuid":"756634492","full_name":"ljleb/sd-mecha","owner":"ljleb","description":"Executable State Dict Recipes","archived":false,"fork":false,"pushed_at":"2026-03-14T18:53:38.000Z","size":1183,"stargazers_count":81,"open_issues_count":11,"forks_count":10,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-03-15T06:09:48.065Z","etag":null,"topics":["llm","model-merging","stable-diffusion"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ljleb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"ljleb","patreon":"ljleb"}},"created_at":"2024-02-13T01:54:39.000Z","updated_at":"2026-03-14T18:21:04.000Z","dependencies_parsed_at":"2024-03-28T05:28:40.147Z","dependency_job_id":"9d15f227-2f8c-497f-aa99-c52d160a9569","html_url":"https://github.com/ljleb/sd-mecha","commit_stats":null,"previous_names":["ljleb/sd-mecha"],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/ljleb/sd-mecha","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljleb%2Fsd-mecha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljleb%2Fsd-mecha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljleb%2Fsd-mecha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljleb%2Fsd-mecha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ljleb","download_url":"https://codeload.github.com/ljleb/sd-mecha/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljleb%2Fsd-mecha/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["llm","model-merging","stable-diffusion"],"created_at":"2024-11-07T04:04:16.644Z","updated_at":"2026-04-01T17:45:42.929Z","avatar_url":"https://github.com/ljleb.png","language":"Python","funding_links":["https://github.com/sponsors/ljleb","https://patreon.com/ljleb"],"categories":[],"sub_categories":[],"readme":"# sd-mecha\n\n[![PyPI version](https://badge.fury.io/py/sd-mecha.svg)](https://badge.fury.io/py/sd-mecha)\n[![Discord Server](https://dcbadge.vercel.app/api/server/2EPaw6fxxm?style=flat)](https://discord.gg/invite/2EPaw6fxxm)\n\n```python\nimport sd_mecha\n\n# create the merge plan\na = sd_mecha.model(\"path/to/model_a.safetensors\")\nb = sd_mecha.model(\"path/to/model_b.safetensors\")\nrecipe = sd_mecha.weighted_sum(a, b, alpha=0.5)\n\n# merge!\nsd_mecha.merge(recipe, output=\"path/to/model_out.safetensors\")\n```\n\nsd-mecha is a general memory-efficient model merging library. It can merge *any* model:\n- Diffusion models\n- LLMs\n- VLMs\n- Aesthetic scorers\n- etc.\n\n## Features\n\n- Memory efficient model merging: merge a very large number of models in a single execution\n- Textual and interpretable format for storage and execution (.mecha)\n- Extensible library interface:\n  - add custom models\n  - add custom merge methods\n- Builtin support for popular diffusion models:\n  - Stable Diffusion 1.5\n  - Stable Diffusion XL\n  - Stable Diffusion 3\n  - FLUX Schnell/Dev\n- Merge LyCORIS networks together and to checkpoints\n- Block-wise hyperparameters for precise control of blocks (aka MBW)\n\n## Install\n\n```commandline\npip install sd-mecha\n```\n\nMake sure to install the appropriate release of [`torch`](https://pytorch.org/get-started/locally/) to get the best performance.\n\n## Usage\n\n### Merge models\n\nTo merge models, mecha uses recipes.\nA recipe is a list of instructions that describes the exact steps needed to derive a state dict from inputs.\n\nHere's an example script that merges three models:\n\n```python\nimport sd_mecha\n\n# create the merge plan\nmodel_a = sd_mecha.model(\"path/to/model_a.safetensors\")\nmodel_b = sd_mecha.model(\"path/to/model_b.safetensors\")\nrecipe = sd_mecha.weighted_sum(model_a, model_b, alpha=0.5)\n\n# merge!\nsd_mecha.merge(recipe, output=\"path/to/model_out.safetensors\")\n```\n\nSee the [examples](/examples) directory for more examples.\n\n### Get Model-Specific Information\n\nThe library uses a \"model config\" to designate any specific set of keys of a certain shape.\n\nIt is possible to list all available model configs through the `sd_mecha.extensions.model_configs` module:\n\n```python\nfrom sd_mecha.extensions import model_configs\n\nall_configs = model_configs.get_all()\n\nprint([config.identifier for config in all_configs])\n# [\"sd1-ldm-base\", \"sdxl-sgm-base\", \"sd3-sgm-base\", ...]\n```\n\nA *component* of a model config is a subset of keys of the config that belong to the same logical group.\nFor example, all keys starting with \"first_stage_model.\" in Stable Diffusion models belong to the component \"vae\".\n\nIt is possible to query the different components of a model config:\n\n```python\nfrom sd_mecha.extensions import model_configs\n\nconfig = model_configs.resolve(\"sd1-ldm\")\nfor component_id, component in config.components().items():\n      # component.keys contains the state dict keys that the component owns\n      print(f\"{component_id}\")\n\n# this prints:\n#   clip_l\n#   vae\n#   diffuser\n```\n\n## Motivation\n\nKeeping track of full merge recipes has always been a problem for me.\nI needed something that allows to store merge recipes in a readable format while also being executable.\nI also needed something that allows to fully merge an entire tree of models without having to save intermediate models to disk.\n\nTypically, mergers load all models in memory before initiating the merge process.\nThis can be very inefficient when the merge focuses on each key individually:\n\n![image of typical merge graph](/media/memory-gone.PNG)\n\nsd-mecha doesn't have this problem as it saves keys as soon as it can:\n\n![image of sd-mecha merge graph](/media/did-you-see-something.PNG)\n\nThis allows to merge a very large number of models simultaneously on low-end hardware.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fljleb%2Fsd-mecha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fljleb%2Fsd-mecha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fljleb%2Fsd-mecha/lists"}