Mergekit——任务向量合并算法Ties解析

Mergekit——高频合并算法 TIES解析

  • Ties背景
    • Ties 核心思想
    • 具体流程
    • 总结

mergekit项目地址
Mergekit提供模型合并方法可以概况为三大类:基本线性加权、基于球面插值、基于任务向量,今天我们来刷下基于任务向量的ties合并方法,熟悉原理和代码。

Ties背景

首先明确:Ties方法建立在“任务向量”的概念之上,任务向量表示参考的微调模型和基本模型之间的区别,这种方法在mergekit中非常多,Ties只是其中一种变体。
TIES-Merging ——可将多个同构不同参数的模型合并为单个多任务模型。主要解决模型合并中的两个主要挑战:

1.模型参数冗余:它识别并消除特定任务模型中的冗余参数。这是通过关注微调期间所做的更改、识别前 k% 最重要的更改并丢弃其余的来实现的。
2.参数符号之间的不一致:当不同模型对同一参数提出相反的调整时,就会出现冲突。TIES-Merging 通过创建一个统一的符号向量来解决这些冲突,该符号向量代表所有模型中最主要的变化方向。

Ties 核心思想

稀疏化密度:通过仅保留一小部分最重要的参数(密度参数)并将其余参数重置为零,减少特定于任务的模型中的冗余。
符号共识: 通过根据累积幅度的最主要方向(正或负)创建统一的符号向量,解决不同模型之间的符号冲突。
不相交合并:对与统一符号向量对齐的参数值进行平均,不包括零值。

具体表现为当多个模型进行合并时候,稀疏化密度只保留最重要的权重高化,符号共识**保留多个模型再更新方向上一致的参数。

具体流程

通过分析代码后,可以汇总为以下步骤:

  1. 计算任务向量——每个模型和base模型的差异,比较简单
   def get_task_vectors(weight_info: WeightInfo,base_model: ModelReference,tensors: ImmutableMap[ModelReference, torch.Tensor],tensor_parameters: ImmutableMap[ModelReference, ImmutableMap[str, Any]],
) -> Tuple[List[Dict[str, Any]], torch.Tensor]:keys = list(tensors.keys())base = tensors[base_model]parameter_name = weight_info.nameres = []for model in keys:if model == base_model:continuex = tensors[model].to(base.dtype)if x.shape != base.shape:if weight_info.is_embed:x = x[: base.shape[0], : base.shape[1]]logging.warning(f"Using submatrix of {model}:{parameter_name}")else:logging.warning(f"skipping {model}:{parameter_name} due to size mismatch")continuedelta = x - basedel xdel tensors[model]d = {}d["model"] = modeld["delta"] = deltafor p in tensor_parameters[model]:d[p] = tensor_parameters[model][p]res.append(d)return res, base
  1. 稀疏化权重
# sparsifyif self.method.sparsification_method:for tv_info in tvs:kwargs = {}if "gamma" in tv_info:kwargs["gamma"] = tv_info["gamma"]if "epsilon" in tv_info:kwargs["epsilon"] = tv_info["epsilon"]tv_info["delta"] = sparsify(tv_info["delta"],density=tv_info["density"],method=self.method.sparsification_method,rescale_norm=self.rescale_norm,**kwargs,)

然后,如何计算权重幅度等等,在源码中sparsify具备四种稀疏化方法:

  • magnitude: 基于权重大小的剪枝
  • random: 随机剪枝
  • magnitude_outliers: 去除极大值和极小值的剪枝
  • della_magprune: 基于概率的渐进式剪枝方法

这里我们主要说ties 基于权重幅度剪枝—— 保留绝对值最大的k个元素,k=density*总元素数,简单高效

def magnitude(tensor: torch.Tensor, density: float, rescale_norm: Optional[RescaleNorm] = None
) -> torch.Tensor:"""Masks out the smallest values, retaining a proportion of `density`."""if density >= 1:return tensork = int(density * tensor.numel())  #计算保留元素数量assert k > 0, "not gonna zero out the whole tensor buddy"mask = torch.zeros_like(tensor)w = tensor.abs().view(-1)if w.device.type == "cpu":w = w.float()topk = torch.argsort(w, descending=True)[:k]  #对绝对值进行降序排序,获取前k大值的索引mask.view(-1)[topk] = 1  #将掩码中对应top-k索引的位置设为1res = rescaled_masked_tensor(tensor, mask, rescale_norm)  #调用辅助函数应用掩码并根据需要重新缩放,保持特定的范数特性,保证输出和反向传播计算的稳定性return res

通过上述计算,可以保留所谓权重幅度最大的参数,完成稀疏化。
3. 权重应用

		deltas = torch.stack([tv["delta"] for tv in tvs], dim=0)weights = torch.tensor([tv["weight"] for tv in tvs], dtype=deltas.dtype, device=deltas.device)while len(deltas.shape) > len(weights.shape):weights.unsqueeze_(-1)weighted_deltas = deltas * weights

4.符号共识
Ties提供两种方式计算符号
”sum“: 加权,考虑参数幅度
”count“,基于符号数量统计

def get_mask(delta: torch.Tensor,method: Literal["sum", "count"] = "sum",mask_dtype: Optional[torch.dtype] = None,
):"""Returns a mask determining which delta vectors should be mergedinto the final model.For the methodology described in the TIES paper use 'sum'. For asimpler naive count of signs, use 'count'."""if mask_dtype is None:mask_dtype = delta.dtypesign = delta.sign().to(mask_dtype)  # 获取每个元素的符号(-1, 0, +1)if method == "sum":sign_weight = delta.sum(dim=0) # 沿模型维度求和majority_sign = (sign_weight >= 0).to(mask_dtype) * 2 - 1    # 转换为±1del sign_weightelif method == "count":majority_sign = (sign.sum(dim=0) >= 0).to(mask_dtype) * 2 - 1else:raise RuntimeError(f'Unimplemented mask method "{method}"')return sign == majority_sign  #生成bool mask

在Sum方法中也是ties的论文方法,考虑差异的幅度和方向:

对每个参数位置,计算所有模型差异的总和;如果总和≥0,多数符号为+1,否则为-1,这样幅度的差异大对结果影响较大;

在count方法中,对每个参数位置,统计正负号数量,正号多则多数符号为+1,否则为-1,忽略差异幅度,只考虑方向

计算更简单但可能不够精确。

  1. 合并

回到主线代码,这里我们已经拿到了掩码,可以确定哪些参数变化(deltas)应该被合并

if self.method.consensus_method:mask_dtype = torch.int8 if self.int8_mask else base.dtypemask = get_mask(weighted_deltas,method=self.method.consensus_method,mask_dtype=mask_dtype,) #拿到mask后mixed_delta = (weighted_deltas * mask).sum(dim=0) #直接对所有加权deltas求和divisor = (weights * mask).sum(dim=0) #计算有效权重的和(用于归一化)divisor[divisor == 0] = 1else:mixed_delta = weighted_deltas.sum(dim=0) #只保留被掩码选中的deltas并求和divisor = weights.sum(dim=0)divisor[divisor.abs() < 1e-8] = 1if self.normalize:  # 归一化mixed_delta /= divisor if self.lambda_ != 1: #系数缩放mixed_delta *= self.lambda_return (base + mixed_delta).to(base.dtype) 合并

总结

Mergekit ties的配置参考

models:- model: psmathur/orca_mini_v3_13b        #参考模型1parameters:density: [1, 0.7, 0.1] # density gradient   这是稀疏化的密度列表 对应不同层的稀疏化成都weight: 1.0                                #权重值- model: garage-bAInd/Platypus2-13B         #参考模型2 其余同上parameters:density: 0.5                           weight: [0, 0.3, 0.7, 1] # weight gradient- model: WizardLM/WizardMath-13B-V1.0       #参考模型3 其余同上parameters:density: 0.33weight:- filter: mlp  #对于MLP是取0.5 其他层是0value: 0.5- value: 0
merge_method: ties
base_model: TheBloke/Llama-2-13B-fp16      #选择这个模型作为基础模型
parameters:normalize: trueint8_mask: true
dtype: float16

这里当参数为List时候,Mergekit会进行映射到不同层,在处理每个参数时候根据位置选择List中的密度或者权重值,保留嵌入层 、中间层、末尾层对应不同密度稀疏,考虑使用线性插值来计算中间层的密度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/906257.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8 在单片机上部署的缺点和应对方案

YOLOv8 在单片机上部署的主要挑战与缺陷 将 YOLOv8 部署到单片机上确实面临诸多技术挑战&#xff0c;主要源于单片机有限的计算资源与 YOLOv8 模型的高复杂度之间的矛盾。以下是具体的缺陷和限制&#xff1a; 1. 计算资源严重不足 算力限制&#xff1a;典型单片机&#xff0…

搭建一个永久免费的博客

搭建永久免费的博客&#xff08;1&#xff09;基本介绍 HugoStackGitHub GitHub GitHub GitHub Build and ship software on a single, collaborative platform GitHub 下载安装git Git - Downloads Edge插件authenticator 2fa client Settings->Password and auth…

基于SpringBoot的小型民营加油站管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

推荐一个Winform开源的UI工具包

从零学习构建一个完整的系统 推荐一个开源、免费的适合.NET WinForms 控件的套件。 项目简介 Krypton是一套开源的.Net组件&#xff0c;用于快速构建具有丰富UI交互的WinForms应用程序。 丰富的UI控件&#xff0c;提供了48个基础控件&#xff0c;如按钮、文本框、标签、下拉…

社交平台推出IP关联机制:增强用户体验与网络安全的新举措

社交平台为我们提供与亲朋好友保持联系、分享生活点滴的便捷渠道&#xff0c;还成为了信息传播、观点交流的重要平台。然而&#xff0c;随着社交平台的普及&#xff0c;网络空间中的虚假信息、恶意行为等问题也日益凸显。为了应对这些挑战&#xff0c;许多社交平台相继推出IP关…

系统架构设计(八):三层架构

什么是三层架构&#xff08;Three-Tier Architecture&#xff09; 三层架构是将系统分为三大逻辑层&#xff1a;表示层&#xff08;Presentation&#xff09;、业务逻辑层&#xff08;Business Logic&#xff09;、数据访问层&#xff08;Data Access&#xff09;&#xff0c;…

C语法备注01

&#xff08;1&#xff09;char 字符类 char 既可以是 整数 类型&#xff0c;也可以是 字符 类型。z字符 类型可以转化为对应的ASC2值。 int main(){char c;char e;c 1;char d 1;e A;printf("c %d\n", c);printf("d %d\n", d);printf("e %d\n…

CVE-2015-2183 Zeuscart SQL注入漏洞

CVE-2015-2183 Zeuscart SQL注入漏洞 主页 访问/admin/进行登录 访问&#xff1a;http://192.168.1.3/admin/?doeditcurrency&cid1 单引号测试&#xff0c;发现页面发生变化&#xff0c;进一步测试 order by 5 &#xff0c;页面正常&#xff0c;order by 6时页面发生变…

Go 语言即时通讯系统开发日志-日志day2-5:架构设计与日志封装

Go语言即时通讯系统开发日志day2 计划&#xff1a;学习go中MySQL&#xff0c;Redis的使用&#xff0c;使用MySQL和Redis完成一个单聊demo。 总结&#xff1a;现在每天下午用来开发这个项目&#xff0c;如果有课的话可能学习时间只有3-4个小时&#xff0c;再加上今天的学习效率不…

对盒模型的理解

对CSS盒模型的深入理解 CSS盒模型是网页布局的基础概念&#xff0c;它描述了HTML元素在页面中所占的空间以及如何计算这些空间。以下是关于盒模型的全面解析&#xff1a; 1. 盒模型的基本组成 每个HTML元素都被视为一个矩形的盒子&#xff0c;这个盒子由内到外由四部分组成&…

RV1126多线程获取SMARTP的GOP模式数据和普通GOP模式数据

通过代码的方式同时获取SMARTP模式的VENC码流数据和普通GOP模式的VENC码流数据&#xff0c;并进行对比画质。 一.RV1126 VI采集摄像头数据并同时编码SMARTP模式和普通GOP模式的编码码流流程 RV1126利用多线程同时获取普通GOP的VENC码流数据和SMARTP的码流数据一般如上图&#…

在Ubuntu使用 Ansible 配置 Azure 资源的动态清单

使用 Ansible 配置 Azure 资源的动态清单 简介1.安装pipx2.通过 pipx 安装 Ansible3.安装azure.azcollection4.安装集合所需的依赖项5.生成动态库存 简介 在主机变化不定的云环境中&#xff0c;Ansible 的动态清单功能可以消除维护静态清单文件的负担 本教程将带你使用 Azure…

车载诊断架构 ---车载总线对于功能寻址的处理策略

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

Github 2025-05-16 Java开源项目日报 Top9

根据Github Trendings的统计,今日(2025-05-16统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目9Netty:异步事件驱动的网络应用程序框架 创建周期:5043 天开发语言:Java协议类型:Apache License 2.0Star数量:33219 个Fork数量:…

大语言模型(LLM)如何通过“思考时间”(即推理时的计算资源)提升推理能力

大语言模型(LLM)如何通过“思考时间”(即推理时的计算资源)提升推理能力 核心围绕人类思维机制、模型架构改进、训练方法优化等展开 一、人类思维的启发:快思考与慢思考 类比心理学: 人类思维分两种模式: 快思考(系统1):直觉驱动,快速但易出错(如估算简单问题)。…

【ubuntu24.04】pycharm 死机结束进程

windows 远程pycharm到ubuntu执行程序 pycharm 在调试过程中&#xff0c;内存耗尽&#xff0c;然后死机了 pycharm 进程 (base) rootk8s-master-pfsrv:/home/zhangbin/下载# ps -ef | grep pycharm root 121245 3230568 0 5月14 pts/8 00:00:00 /bin/bash --rcfile …

从虚拟仿真到行业实训再到具身智能--华清远见嵌入式物联网人工智能全链路教学方案

2025年5月23-25日&#xff0c;第63届中国高等教育博览会&#xff08;高博会&#xff09;将在长春中铁东北亚国际博览中心举办。作为国内高等教育领域规模大、影响力广的综合性展会&#xff0c;高博会始终聚焦教育科技前沿&#xff0c;吸引全国高校管理者、一线教师、教育科技企…

本地部署dify+ragflow+deepseek ,结合小模型实现故障预测,并结合本地知识库和大模型给出维修建议

1.准备工作 使用ollama 拉取deepseek-r1:7b 官网下载ollama ollama run deepseek-r1:7b ollama list Ragflow专注于构建基于检索增强生成&#xff08;RAG&#xff09;的工作流&#xff0c;强调模块化和轻量化&#xff0c;适合处理复杂文档格式和需要高精度检索的场景。Dify…

https://api.ipify.org/?format=json 不好使

https://api.ipify.org/?formatjson 打不开&#xff0c;用下面新地址 https://api64.ipify.org/?formatjson

Linux基础开发工具三(git,gdb/cgdb)

不知道你⼯作或学习时&#xff0c;有没有遇到这样的情况&#xff1a;我们在编写各种⽂档时&#xff0c;为了防⽌⽂档丢失&#xff0c;更改 失误&#xff0c;失误后能恢复到原来的版本&#xff0c;不得不复制出⼀个副本&#xff0c;⽐如&#xff1a; “报告-v1” “报告-v2” …