NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - AI模型在线查看 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 - 3D道路快速建模
假设你有多个 LLM:一个擅长解决数学问题,另一个擅长编写代码。在两个模型之间切换可能很棘手,因此你可以将它们结合起来以充分利用两全其美的优势。这确实是可能的!你甚至不需要 GPU 来完成这项任务。
模型合并是一种最近越来越流行的新技术。它允许通过将多个模型合并为一个来组合它们。这样做不仅可以保留质量,还可以获得额外的好处。新模型开始在任务上表现更好,这在 Open LLM 排行榜上得到了清晰的展示:
在本文中,我们将探索各种合并算法,研究如何实现它们,并深入研究它们的工作原理。我们将通过示例展示如何使用mergekit工具包合并Mistral,WizardMath和CodeLlama等模型。最后会有有用的链接和资源来进一步探讨这个主题。
本文的简短摘要如下:
- 模型合并提高了最终模型的质量。凭借正确的专业知识和模型选择,你可以获得SOTA结果。
- 有许多合并算法,其中大多数使用加权平均值。然而,出现了像DARE和TIES这样的新方法,解决了以前技术的局限性。
- 可以合并具有混合架构的模型,例如:LLaMA 2 + Mistral + Wizard。
- 本文讨论的所有算法都可以通过mergekit工具访问,其“示例”文件夹中提供了更多使用示例。
1、合并算法
有几种用于合并模型的算法。其中许多算法使用各种加权平均值组合。但是,有些算法提出了不同的方法。在本文中,我将重点介绍一些我发现有趣的算法,并按复杂度增加的顺序排列它们。
1.1 任务向量算法
此方法引入了一种使用“任务向量”修改神经网络行为的新范式。这些向量表示预训练模型权重空间中的方向,指向特定任务的改进性能。
可以通过负数和加法等算术运算来操纵向量,从而允许在模型中进行有针对性的行为更改:
- 否定以降低性能:否定任务向量会降低模型在目标任务上的性能,同时保持其在控制任务上的行为。
- 添加以改进多任务:添加任务向量可以同时增强模型在多个任务上的性能。
- 类比任务改进:结合来自相关任务的任务向量(基于类比关系)可以提高第四个任务的性能,即使不使用此任务的数据。
任务向量算法的优点:
- 高效的模型编辑:这种方法提供了一种简单有效的模型编辑方法,可以提高性能、减轻偏差并使用新信息更新模型。
- 跨模型和任务的多功能性:该方法已被证明可以很好地适用于各种模型和任务。
总之,基于任务向量的模型编辑提供了一种新颖且通用的方法来控制和提高神经网络模型在各种任务中的性能。
文章 | 代码
1.2 SLERP
SLERP 解决了传统权重平均在模型合并中的局限性。它提供了一种更细致入微的方法,以一种在高维空间中保留每个父模型的独特特征和曲率的方式混合模型。
SLERP 的优势:
- 平滑过渡:确保更平滑的参数过渡,这在高维向量插值中至关重要。
- 特征保留:保持两个父模型的独特特征和曲率。
- 细致入微的混合:考虑向量空间中的几何和旋转特性,从而产生准确反映两个模型特征的混合。
SLERP 实施步骤:
- 归一化:将输入向量归一化为单位长度,关注方向而不是幅度。
- 角度计算:使用这些向量之间的点积确定它们之间的角度。它根据插值因子和向量之间的角度计算比例因子。
- 向量加权和求和:用这些因子对原始向量进行加权并求和以获得插值向量。
SLERP 的特点是能够以一种在参数之间平滑过渡并保留每个模型的独特特征的方式合并模型,使其成为复杂模型合并任务的首选方法。虽然 SLERP 很受欢迎并且对于同时合并两个模型很有效,但它仅限于成对组合。
很好的解释视频 | 代码
1.3 TIES
传统的模型合并方法面临着巨大的挑战,特别是在处理来自不同模型的参数之间的干扰方面。这种干扰导致合并多个模型时性能大幅下降。
为了克服这些挑战,TIES 方法引入了三个步骤:
- 重置参数:重置在微调过程中仅发生微小变化的参数。此步骤有助于减少冗余。
- 解决符号冲突:解决因模型间参数值符号不同而引起的冲突。
- 选择性合并:仅合并与最终商定符号一致的参数。
TIES-Merging 方法已证明在各种设置下优于现有的几种合并方法。它有效地解决了干扰问题,尤其是符号干扰,从而提高了合并模型的整体性能。
文章 | 代码
1.4 DARE
DARE 是一种无需重新训练或 GPU 的新方法。它主要侧重于学习类似(同源)模型的参数以获得新功能。它使用与 TIES 类似的方法,但有两个主要区别:
- Delta 参数修剪:通过将大多数 delta 参数(微调参数和预训练参数之间的差异)设置为零来识别和消除它们。此过程不会显著影响模型的功能。较大的模型可以丢弃更高比例的这些参数。
- 重新缩放权重:包括重新缩放步骤,其中调整模型的权重以保持输出预期大致不变。这涉及使用比例因子将模型的重新缩放权重添加到基础模型的权重中。
该算法按照以下步骤工作:
- 修剪:将微调后的权重重置为其原始预训练值,减少不必要的参数更改。
- 合并:对来自多个模型的参数进行平均以创建单一统一的模型。
- 重新缩放:调整合并模型的权重以保持其预期性能。
总之,DARE 通过策略性地修剪和重新缩放参数,提供了一种独特而有效的语言模型合并方法,从而无需进行大量重新训练即可获得具有增强和多样化功能的模型。
文章 | 代码
2、实现
为了合并模型,我们将使用mergekit,这是一个专为合并预训练语言模型而设计的工具包。它支持上述所有算法,并且设置起来非常简单。模型合并可以在CPU上运行,但只需8 GB的VRAM就可以加快速度。
2.1 安装mergekit
python3 -m pip install --upgrade pip
git clone https://github.com/cg123/mergekit.git
cd mergekit && pip install -q -e .
2.2 在 YAML 文件中编写合并配置
我将结合 LLM 与混合架构:Mistral-7b、WizardMath-7b 和 CodeLlama-7b。这是我的 ultra_llm_merged.yaml 配置:
models:
- model: mistralai/Mistral-7B-v0.1 # no parameters necessary for base model
- model: WizardLM/WizardMath-7B-V1.0
parameters:
density: 0.5 # fraction of weights in differences from the base model to retain
weight: # weight gradient
- filter: mlp
value: 0.5
- value: 0
- model: codellama/CodeLlama-7b-Instruct-hf
parameters:
density: 0.5
weight: 0.5
merge_method: ties
base_model: mistralai/Mistral-7B-v0.1
parameters:
normalize: true
int8_mask: true
dtype: float16
2.3 运行合并
mergekit-yaml ultra_llm_merged.yaml output_folder \
--allow-crimes \ # Allow mixing architectures
--copy-tokenizer \ # Copy a tokenizer to the output
--out-shard-size 1B \ # Number of parameters per output shard
--low-cpu-memory \ # Store results and intermediate values on GPU. Useful if VRAM > RAM
--write-model-card \ # Output README.md containing details of the merge
--lazy-unpickle # Experimental lazy unpickler for lower memory usage
就是这样!现在你可以部署此模型或将其直接上传到 Hugging Face。
请记住,同时合并多个模型需要大量资源。对于我之前描述的配置,使用具有 1x A10 (24Gb) GPU 和 30 个 vCPU 的系统,资源和时间承诺如下:
- 下载模型:大约 5 分钟。
- 合并过程:大约 7 分钟。
- 峰值 RAM 使用量:30Gb。
请记住,这些时间和资源消耗可能会因系统的规格和要合并的特定模型而异。
3、结束语
我们探索了合并模型的关键可能性,并深入研究了几种算法的工作原理。我相信在不久的将来,我们将看到越来越多的通过合并创建的模型。这是一种经济高效的方式,可以结合有用的技能,而无需进行微调。
原文链接:Merge Large Language Models
BimAnt翻译整理,转载请标明出处