- 大模型
- 模型优化
- AI 应用
【免费下载链接】mergekit
Tools for merging pretrained large language models.
mergekit-multi是 mergekit 提供的命令行工具,用于执行包含多个相互依赖阶段(stage)的复杂模型合并工作流:它可以串联多次合并操作、把前一步的输出作为后续步骤的输入、自动解析合并步骤之间的依赖关系,并缓存中间结果以加速重复运行。读完本文,你将掌握mergekit-multi的完整命令用法、YAML 多文档配置格式(含最终合并与全命名合并两种形态)、关键命令行选项,以及其背后的依赖图调度与懒执行原理。
什么是 mergekit-multi
mergekit-multi解决的是"一次合并不够用"的问题。常规的 mergekit-yaml 只执行一次合并,而现实中的模型融合方案往往需要分阶段递进,例如:
- 先用
linear将两个领域微调模型平均,得到一个中间模型; - 再以该中间模型为输入,用
slerp向另一个指令微调模型插值; - 最后用
dare_ties把前两步产物与更多模型做一次任务向量合并,得到最终模型。
这种"合并的合并"(merge of merges)正是mergekit-multi的核心场景。它允许你:
- 将多次合并操作串联(chain)在一起;
- 使用前一次合并的输出作为后续合并的输入;
- 自动处理各合并步骤之间的依赖关系;
- 缓存中间结果,让重复运行更快(默认启用懒执行)。
入口命令为mergekit-multi,其实现位于 mergekit/scripts/multimerge.py,在 pyproject.toml 的[project.scripts]中注册为mergekit-multi = "mergekit.scripts.multimerge:main"。
基本命令结构
mergekit-multi <config.yaml> \ --intermediate-dir ./intermediates \ ([--out-path ./final-merge] | 仅当配置中存在未命名合并时需要) \ [options]其中:
<config.yaml>:一个 YAML 文件,内含多个由---分隔的 YAML 文档(document),每个文档都是一份独立的 mergekit 合并配置;--intermediate-dir(可缩写-I):存放中间合并结果的目录,必填;--out-path:最终合并结果的输出路径,仅当配置中存在一个未命名(无name字段)的合并时必填。
命令行定义见 mergekit/scripts/multimerge.py:config_file是位置参数(要求文件存在),--out-path是可选的(会在主函数中进一步校验),--intermediate-dir必填。此外,mergekit-multi通过@add_merge_options继承了 mergekit 的全部标准合并选项,并且其--help输出使用PrettyPrintHelp按类别分组展示。
out-path 的取值规则
--out-path与配置中是否存在未命名合并是成对约束的,源码中的校验逻辑如下(multimerge.py):
- 若配置中存在未命名合并(即某个 YAML 文档没有
name字段),则该合并被视为最终合并,--out-path为必填项,否则直接报错:--out-path is required when configuration contains an unnamed final merge - 若配置中所有合并都有名字,则不需要
--out-path,全部结果都会写入--intermediate-dir。
配置文件格式
核心约定
配置文件是一个包含多个 YAML 文档的文件,每个文档用---分隔,各自包含一份完整的 mergekit 合并配置,并遵守以下规则:
- 每个中间合并必须带有
name字段,作为唯一标识符(重复的name会直接报错Duplicate merge name <name>); - 最终合并不应带有
name字段(配置中最多只能有一个未命名合并,否则报错Multiple unnamed merge configurations are not supported); - 每个文档内部使用 mergekit 标准的配置参数(
merge_method、models、base_model、parameters等); - 关键:在
models列表中,可以通过其他合并的name来引用前序合并的输出,作为本次合并的输入模型。
配置解析在 load_config 中完成:先用yaml.safe_load_all读取所有文档,剔除name字段后用MergeConfiguration.model_validate校验每个文档,然后扫描每个配置中引用的模型名,凡是命中已知合并名的都会在运行时被替换为intermediate_dir/<name>的实际本地路径(见patched_config,multimerge.py)。
标准配置参数说明
每个 YAML 文档内可用的标准配置参数(由 mergekit/config.py 定义)包括:
| 字段 | 说明 |
|---|---|
merge_method | 合并方法,必填。如linear、slerp、dare_ties、task_arithmetic等(完整清单见 docs/merge_methods.md) |
models | 参与合并的输入模型列表,每项是{ model: ... , parameters: {...} };相互之间用name引用前序合并 |
base_model | 某些合并方法(如slerp、task_arithmetic、dare_ties)需要的基础模型 |
parameters | 合并参数,如weight、density、t、lambda等,也可下沉到单个模型级别 |
dtype/out_dtype | 合并运算与输出权重的数据类型 |
tokenizer_source/tokenizer | 输出 tokenizer 的构建方式("union"、"base"或指定模型路径) |
chat_template | 输出模型的对话模板 |
含最终合并的示例(multimerge.yaml)
下面这份配置演示了三种方法(linear→slerp→dare_ties)的完整流水线,其中前两步是带name的中间合并,最后一步是不带name的最终合并:
name: first-merge merge_method: linear models: - model: mistralai/Mistral-7B-v0.1 - model: BioMistral/BioMistral-7B parameters: weight: 0.5 --- name: second-merge merge_method: slerp base_model: first-merge # 引用上一次合并的输出 models: - model: NousResearch/Hermes-2-Pro-Mistral-7B parameters: t: 0.5 --- # 最终合并(无 name) merge_method: dare_ties base_model: mistralai/Mistral-7B-v0.1 models: - model: second-merge parameters: density: 0.6 weight: 0.5 - model: teknium/OpenHermes-2.5-Mistral-7B parameters: density: 0.8 weight: 0.5要点解读:
second-merge的base_model直接写成first-merge,mergekit-multi 会将其解析为./intermediates/first-merge这个本地目录;- 最终合并的
models中,second-merge同样会被解析为中间结果路径,因此最终合并实际是在合并"上一步的合并产物"和"原始模型"; - 模型名解析发生在
patched_config中:它遍历整个配置的数据结构,凡是model字段的路径与某个合并名完全一致的,就替换为os.path.join(intermediate_dir, base)(multimerge.py)。
全部命名的示例
如果希望所有合并都是中间合并(不产出"最终"模型),可以全部携带name:
name: first-merge merge_method: task_arithmetic ... --- name: second-merge merge_method: slerp ... --- name: third-merge merge_method: linear ...这种写法不需要--out-path,三个合并的结果会分别落在--intermediate-dir下的first-merge/、second-merge/、third-merge/。
实际运行命令
对应"含最终合并"的配置,运行命令为:
mergekit-multi multimerge.yaml \ --intermediate-dir ./intermediates \ --out-path ./final-merge \ --cuda对应"全部命名"的配置,则省略--out-path:
mergekit-multi multimerge.yaml --intermediate-dir ./intermediates关键命令行选项
mergekit-multi专属选项如下(见 multimerge.py):
| 选项 | 说明 |
|---|---|
--intermediate-dir/-I | 存放中间合并结果的目录,必填。所有带name的合并都会以intermediate_dir/<name>保存 |
--out-path | 最终合并的输出路径,仅当配置中存在未命名合并时必填 |
--lazy/--no-lazy | 是否跳过已存在的中间合并。默认--lazy(true):若某个合并的输出目录中已存在config.json且至少一个权重文件,则跳过该步骤;--no-lazy强制全部重新执行 |
此外,mergekit-multi继承了 mergekit 的全部标准合并选项(mergekit/options.py 中MergeOptions定义的字段会自动生成 CLI 参数),常用包括:
--cuda/--device <device>:在 GPU / 指定设备上做矩阵运算(device支持auto自动探测);--out-shard-size <size>:输出分片大小,支持k/m/b后缀(如5B),默认5B;--multi-gpu:使用多 GPU 并行图执行引擎;--low-cpu-memory:把结果与中间值存放在加速器上(适合 VRAM 大于 RAM 的场景);--gpu-rich:--cuda --low-cpu-memory --read-to-gpu --multi-gpu的组合别名;--copy-tokenizer/--no-copy-tokenizer:是否把 tokenizer 复制到输出(默认开启);--safe-serialization/--no-safe-serialization:是否以 safetensors 保存输出(默认开启);--trust-remote-code:信任来自 Hugging Face 仓库的远程代码(危险选项);--allow-crimes:允许混用不同架构(危险选项);--random-seed <seed>:为随机性合并方法(如 DARE 类)设置固定随机种子;--num-threads/-j:CPU 并行线程数;--write-model-card/--no-write-model-card:是否生成 README.md 模型卡与mergekit_config.yml(默认开启);-v(可重复):提高日志详细程度。
工作原理:依赖图调度与懒执行
1. 解析配置并构建依赖关系
load_config(multimerge.py)完成两件事:读取全部 YAML 文档得到merge_configs(以name为键、None表示最终合并),以及通过patched_config扫描出每个合并引用了哪些中间合并,得到dependencies映射。patched_config同时会把引用到的合并名改写成intermediate_dir/<name>的本地路径,这样后续每次run_merge就能直接读取磁盘上的中间模型。
2. 递归建图,检测循环依赖
make_tasks(multimerge.py)为每个合并创建一个 MergeModelTask,并通过input_merges字段把依赖的合并任务递归地串联起来:
- 带
name的合并输出到intermediate_dir/<name>; - 未命名合并输出到
--out-path; - 若在递归过程中再次遇到正在构建中的任务,会抛出
Circular dependency detected involving <name>,即配置中存在循环引用时直接报错。
3. 拓扑排序,顺序执行
构建好的任务集合交给 Executor(来自 mergekit/graph.py)执行。Executor 通过build_schedule(graph.py)使用 networkx 对任务依赖图做字典序拓扑排序(networkx.lexicographical_topological_sort),生成一个同时满足依赖顺序、并按priority/group_label排序的执行计划,随后按序执行每个MergeModelTask。MergeModelTask.execute内部会用解析好的配置调用 run_merge(mergekit/merge.py),完成加载模型、规划合并图、写权重与 tokenizer 等全流程。
值得说明的是:mergekit-multi外层 Executor 使用math_device="cpu"、storage_device="cpu"(multimerge.py),注释中明确指出"内层执行器负责处理加速器"——即每个单独合并真正跑矩阵运算时仍会使用你在命令行传入的--cuda/--multi-gpu等设备选项,外层只负责编排顺序与传递结果路径。
4. 懒执行:命中即跳过
MergeModelTask.execute(multimerge.py)在执行前检查:若lazy为 True,且输出目录中已存在config.json,并且存在以下任一权重文件之一:
model.safetensors pytorch_model.bin model.safetensors.index.json pytorch_model.bin.index.json则记录日志Model already exists at <path>, skipping并直接返回该路径,跳过本次合并。这就是默认行为下重复运行会"秒过"已完成的中间步骤的原因;如需强制重跑所有合并(例如参数或输入模型发生了变化),使用--no-lazy。
实践建议与注意事项
- 复用与缓存:
--intermediate-dir是工作流的核心资产。中间合并按name落盘后,你既可以在后续阶段引用它,也可以单独用mergekit-yaml加载它做其他实验;默认懒执行让多轮迭代只重算真正变化的步骤。 - 为每个中间步骤命名:命名不仅是引用手段,也是目录名(
intermediate_dir/<name>)。建议使用语义化名称(如base-avg、chat-slerp)便于追溯。 - 依赖只在
models的模型引用中生效:合并名引用通过模型路径匹配识别(multimerge.py),因此把前序合并写在models[].model或base_model中均可被解析,但务必保证字符串与前序name完全一致。 - 最终合并唯一性:未命名合并只能有一个,且必须配合
--out-path;否则 CLI 会直接拒绝运行。 - 设备与内存:每个阶段独立执行并写盘,中间模型不常驻内存,因此整体内存峰值由单次最大合并决定;需要加速时加
--cuda,多卡环境可用--multi-gpu。 - 与单一 mergekit-yaml 的区别:
mergekit-yaml一次只执行一份配置;mergekit-multi则把多份配置、跨阶段引用与缓存编排统一在一个 YAML 文件与一条命令中。
延伸阅读
- mergekit README(多阶段合并章节)
- 合并方法指南(linear、slerp、dare_ties 等参数详解)
- MergeConfiguration 与参数定义
- 图执行引擎 Executor 与拓扑排序
- run_merge 单次合并执行流程
- mergekit-multi 入口实现
- 大模型
- 模型优化
- AI 应用
【免费下载链接】mergekit
Tools for merging pretrained large language models.
相关推荐
Sandcastle 并行多分支合并阶段实战:深入解析 merge-prompt.md 与分支合入流水线
Sandcastle 并行多分支合并阶段实战:深入解析 merge prompt.md 与分支合入流水线 本文聚焦 Sandcastle 仓库中 paralle
终极指南:如何用iptv-checker高效管理500+IPTV频道?3分钟快速部署教程
终极指南:如何用iptv checker高效管理500+IPTV频道?3分钟快速部署教程 还在为IPTV播放源频繁失效而烦恼吗?面对成百上千个频道列表,手动测试
后端任务调度音视频MergeKit:模型合并工具箱指南
MergeKit:模型合并工具箱指南 项目目录结构及介绍 MergeKit是一个用于合并预训练语言模型的工具包,旨在资源受限环境下执行复杂的模型合并操作。以下是
大模型模型优化AI 应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考