大语言模型微调技术

Adapter

参考资料:《Parameter-efficient transfer learning for nlp》

adpater首先将原始的d维特征映射到较小的维度m,应用非线性函数,然后再重新映射回d维。总的参数量(包含biases)为 2md+d+m, 当m远小于d时,就能限制每个任务被增加的参数量。

adapter内部也有残差连接,也就是当adapter内的参数初始化为接近0时,相当于是一个增加adpater层前相同的模型。

在微调过程中更新以下参数:

1. adapter内部参数

2. layer norm层参数(实验表明单独训练layer norm层无法达到好结果)

3. 根据任务在最上层添加的层(例如分类任务的分类层)的参数

实验结果:

在GLUE参数集上,总体效果和所有参数重新训练的效果差不多,但训练的参数量减少很多。

Diff Pruning

参考资料:《Parameter-efficient transfer learning with diff pruning》

主要思路是学习一个diff vector \delta _{\tau },加到预训练的模型参数\theta _{pretrained}上,微调后使用的模型参数为\theta _{\tau }

微调训练时需要最小化的函数为

其中,

当 \delta _{\tau }稀疏时,就有,从而使微调时需要训练更新的参数是比较少的。就是\delta _{\tau }的L0-norm,使\delta _{\tau }尽量稀疏。

实验结果:

Prefix-tuning

参考资料:《Prefix-Tuning:Optimizing Continuous Prompts for Generation》

初衷是一个合适的上下文能在不改变参数的情况下使得语言模型的表现更好。但是,不同于让专家优化单个词,单个词容易受具体的词的影响,不同的词有不同的向量表示。而是将引导的上下文作为连续的词向量来优化,这样能通过前向传播影响整个网络中的所有层。

Prefix-tuning给了自回归的语言模型一个prefix,,或者同时给编码和解码结构一个prefix,,其中上图中的P_{idx}表示序列中prefix的序号。

P_{\theta }是初始化的一个可训练的prefix对应的参数矩阵,参数维度是\left | P_{idx} \right |\times dim(h_{i})

微调过程中的损失函数不变,仍然是自回归语言模型的损失函数,为

微调训练过程中更新的参数仅P_{\theta },初始语言模型的参数\phi不变。

微调过程中更新的参数:

直接更新P_{\theta }会导致优化不稳当以及最终效果的略微下降,P_{\theta }用一个MLP压缩到一个较小的矩阵{P_{\theta}}'{P_{\theta}}'P_{\theta }矩阵行数相同,列维度不同。当训练完成后,{P_{\theta}}'被丢弃,保留P_{\theta }

实验结果:

P-Tuning v2

参考资料:《P-Tuning v2:Prompt Tuning can be comparable to fine-tuning universally across scales and tasks》

【Prefix-tuning在后面都简称为P-tuning】

P-tuning的缺点:1. 并不能做到在所有规模参数的模型上表现都好,超过10 billion参数的模型表现好,100 million到1 billion规模参数的模型上相比全参数微调差很多。 2.不同任务上的表现不统一,例如在序列标注任务上表现差。

图左(a)是P-tuning的示意图,可以看出可训练的参数量(橘黄色部分)较少,而且并不直接作用于输出层。图右(b)在不同层都添加prompts当作prefix tokens,使得可训练参数量增加,且对预测输出的作用更直接。

实验结果:

相同参数量的prompt添加到不同层的结果如下图,可以看出在从深层添加会比从开头的浅层添加最终效果好。

LoRA

参考资料:《LoRA: Low-Rank adaption of large language models》

之前方法的不足:Adapter因为顺序计算会导致推断速度慢(如下图),P-tuning会占用一部分序列长度。

对于一个预训练的权重矩阵W_{0}\in R^{d\times k},将参数更新表示为W_{0}+\Delta W=W_{0} +BA,其中B\in R^{d\times r}A\in R^{r\times k}, r\ll min(d,k),也就是将后面更新部分用一个低秩分解表示。将前向计算表示为:。A使用高斯分布随机初始化,B初始化为0,\Delta W在训练开始时时0。然后将\Delta Wx乘以\frac{\alpha }{r}, 其中\alpha是一个常量, 改变其大小可以认为相当于学习率的作用。

如何理解r\alpha

以下代码摘自 Code LoRA from Scratch - a Lightning Studio by sebastiacode

【Code LoRA from Scratch这个对理解LoRA非常用帮助】

class LoRALayer(torch.nn.Module):
    def __init__(self, in_dim, out_dim, rank, alpha):
        super().__init__()
        std_dev = 1/torch.sqrt(torch.tensor(rank)).float()
        # rank是低秩矩阵的秩,较小的r会有一个较简单的低秩矩阵,使得微调过程中的参数较少,但所能捕捉到的信息也较少
        # A的维度 (in_dim, rank), B的维度 (rank, out_dim)
        self.A = torch.nn.Parameter(torch.randn(in_dim, rank)*std_dev)
        self.B = torch.nn.Parameter(torch.zeros(rank, out_dim))
        self.alpha = alpha

    def forward(self,x):
        # alpha决定了LoRA层的变化有多少作用给原始参数,值越大,对原参数的调整越大
        x = self.alpha* (x @ self.A @ self.B)
        return x

# 可以将原来的线性层用LinearWithLoRA来替换
class LinearWithLoRA(torch.nn.Module):
    def __init__(self, linear, rank, alpha):
        super().__init__()
        self.linear = linear
        self.lora = LoRALayer(linear.in_features, linear.out_features, rank, alpha)

    def forward(self,x):
        return self.linear(x) + self.lora(x)

论文认为这种形式。当r等于预训练参数矩阵的秩时,类似于一个通用的全部参数的fine-tune,。而且这种形式没有推断延迟。

将LoRA应用到Transformer中时,论文只调整attention参数,冻结MLP模块的参数,自注意力模块含四个参数矩阵(W_{q}, W_{k}, W_{v}, W_{o})

实验结果

论文作者还研究了以下问题:

1.应该对Transformer的哪个部分使用LoRA?

调整W_{q},W_{v}的效果不错,而且从表中可以看出调整多个矩阵会比调整单个矩阵的效果好。

2. LoRA最好的秩r是什么?

上表可以看出很小的r就能有不错的效果。

3. \Delta WW之间的关系,是否高度相关?【这部分暂时还没看】

如何在python中使用LoRA?

GitHub - microsoft/LoRA: Code for loralib, an implementation of "LoRA: Low-Rank Adaptation of Large Language Modelscan

参考quickstart部分,或者也可以使用 PEFT, 已经集成仅PEFT里面了GitHub - huggingface/peft: 🤗 PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.

 LoRA的变种:

1. DoRA--Weight-Decomposed Low-Rank Adaptation

以下内容参考 Improving LoRA: Implementing Weight-Decomposed Low-Rank Adaptation (DoRA) from Scratch

DoRA可以用两步来概括,第一步是将一个预训练的参数矩阵分解成一个长度向量m和一个方向矩阵V。因为任何向量可以表示为长度和方向的乘积(如下图左)。在DoRA中,是对参数矩阵分解,而不是向量,矩阵的每一列参数连接了输入到输出,也就是将每一列看作向量做分解(如下图右)。

第二步是分别训练m 和 将LoRA作用于V。

预训练参数W_{0}=m\frac{V}{\left \| V \right \|_{c}}, 其中\left \| V \right \|_{c}是向量维度的norm。

DoRA后的参数{W}'=m\frac{V+\Delta V}{\left \| V+\Delta V \right \|}_{c}=m\frac{V+BA}{\left \| V+BA \right \|}_{c}

class LoRALayer(torch.nn.Module):
    def __init__(self, in_dim, out_dim, rank, alpha):
        super().__init__()
        std_dev = 1/torch.sqrt(torch.tensor(rank)).float()
        # rank是低秩矩阵的秩,较小的r会有一个较简单的低秩矩阵,使得微调过程中的参数较少,但所能捕捉到的信息也较少
        # A的维度 (in_dim, rank), B的维度 (rank, out_dim)
        self.A = torch.nn.Parameter(torch.randn(in_dim, rank)*std_dev)
        self.B = torch.nn.Parameter(torch.zeros(rank, out_dim))
        self.alpha = alpha

    def forward(self,x):
        # alpha决定了LoRA层的变化有多少作用给原始参数,值越大,对原参数的调整越大
        x = self.alpha* (x @ self.A @ self.B)
        return x

class LinearWithDoRAMerged(torch.nn.Module):
    def __init__(self, linear, rank, alpha):
        super().__init__()
        self.linear = linear
        self.lora = LoRALayer(linear.in_feature,linear.out_features, rank, alpha)
        # self.linear.weight.norm(p=2) 计算公式 sum(abs(x)**2)**(1./2), 即平方求和开根号
        self.m = torch.nn.Parameter(self.linear.weight.norm(p=2, dim=0, keepdim=True))

    def forward(self,x):
        lora = self.lora.A @ self.lora.B
        numerator =self.linear.weight + self.lora.alpha*lora.T
        denomator =numerator.norm(p=2, dim=0, keepdim=True)
        # norm之后可以使训练过程更稳定
        directional_component = numerator/denomator
        # self.m能动态调整在训练过程中结合参数向量到参数矩阵过程中每个参数向量的大小,类似参数向量的重要性
        new_weight = self.m * directional_component
        return F.linear(x, new_weight, self.linear.bias)

DoRA相比于LoRA的结果

当参数量仅为LoRA的一半时,DoRA的效果也比LoRA的效果好。

当超参rank变化时,DoRA的鲁棒性比LoRA更好。

DoRA方法也已经被集成到PEFT, GitHub - huggingface/peft: 🤗 PEFT: State-of-the-art Parameter-Efficient Fine-Tuning.

2. LISA

参考资料:《LISA: Layerwise Importance Sampling for Memory-Efficient Large Language Model Fine-Tuning》

为什么会想到LISA这个方法?

对模型每一层的参数计算mean_weight_norm, ,上图x轴表示的是层id,即哪一层,从embedding层到最后输出层,y轴表示的是norm值。可以看出,在LoRA中embedding层和head层的norm值明显大于中间层,而在全参数训练中这种现象不明显。LoRA对每层的重要性判断和全参数微调不同。

LISA认为norm值较小的层应该有较小的概率来对参数微调,但具体方法不是给每一层不同的学习率,而是对层采样。

其中, \left \{ p_{l} \right \}_{l=1}^{N_{L}}=\left \{ 1.0, \gamma /N_{L},\gamma /N_{L},\cdots ,\gamma /N_{L},1.0 \right \}\gamma控制更新多少层。表示0到1之间的均匀分布。

因为embedding层和head层的概率值为1,的条件不会被满足,这两层的参数一定会更新。

部分实验结果:

平均得分来看比LoRA高较多。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法打卡day38

今日任务: 1)完全背包理论基础(卡码网52. 携带研究材料) 2)518.零钱兑换II 3)377. 组合总和 Ⅳ 4)复习day13 完全背包理论基础(卡码网52. 携带研究材料) 题目链接:52. 携带研究材料(第七期模拟…

以大学生活为主题的演讲稿(3篇)

以大学生活为主题的演讲稿(3篇) 以下是三篇以大学生活为主题的演讲稿范文,供您参考: 演讲稿一:拥抱大学生活,绽放青春梦想 尊敬的老师、亲爱的同学们: 大家好! 今天,我…

VLAN知识点总结

首先对交换机等设备进行了解 中继器:物理层设备 只能提供电流信息的电压恢复,但无法恢复波形,所以无法理论无限延长传输距离 集线器:物理层设备 多接口的中继器 二层交换机的作用: 区别集线器(HUB&#…

【问题处理】银河麒麟操作系统实例分享,服务器操作系统VNC远程问题分析

1.服务器环境以及配置 【内核版本】 4.19.90-23.8.v2101.ky10.aarch64 【OS镜像版本】 0518-server 2.问题现象描述 服务器通过vncserver:1.service服务启动的vnc服务后,普通用户用vnc连接时,锁屏后,然后输入登陆密码会报密码错误&…

五款3dmax常用插件推荐(含云渲染工具)

在三维建模和动画设计领域,3ds Max软件因其强大功能和灵活性而广受欢迎。为了进一步提升工作效率和创作质量,有许多插件可供选择。本文推荐五款常用3ds Max插件,帮助你更好实现复杂的模型和动效创作。 五款3dmax常用插件推荐 1、Kitchen Cab…

RocketMQ并发消息消费重试DEMO

无序消息的重试只针对集群消费模式生效;广播消费模式不提供失败重试特性 Producer 发了100个对象消息 public class AddProducer {public static void main(String[] args) throws Exception {DefaultMQProducer producer new DefaultMQProducer("a-group&q…

计算机视觉入门:探索机器如何“看见”世界

计算机视觉是人工智能领域的一个令人兴奋的分支,它使计算机能够从图像和视频中“看见”和理解世界。这项技术已经渗透到我们生活的方方面面,从智能手机的面部识别到自动驾驶汽车的导航系统。但是,计算机视觉是如何工作的呢?让我们…

U盘管理软件 设置U盘权限的软件

U盘管理软件 设置U盘权限的软件 我们都知道U盘的功能很强大,携带也很方便,但是它的危险指数也是相当高的,既容易携带病毒,又可以拷贝公司里的保密文件。所以很多企业都很关注对U盘使用的管理,而方法,最好的…

PLSQL的下载与安装

个人介绍 hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的…

色彩的魔力:渐变色在设计中的无限可能性

夕阳,天空,湖面,夕阳...随着距离和光影的变化,颜色的渐变色,近大远小、近实远虚的透视,为大自然营造了浪漫的氛围。延伸到UI/UX设计领域,这种现实、惊艳、独特的渐变色也深受众多设计师的喜爱。…

JavaEE初阶Day 13:多线程(11)

目录 Day 13:多线程(11)常见的锁策略1. 悲观锁 vs 乐观锁2. 重量级锁 vs 轻量级锁3. 自旋锁 vs 挂起等待锁4. 可重入锁 vs 不可重入锁5. 公平锁 vs 非公平锁6. 互斥锁 vs 读写锁 synchronized实现原理1. 锁升级2. 锁消除3. 锁粗化 CAS Day 13…

“捡到一束光,日落时还给太阳”

数据结构初阶题解 1.移除元素2.合并两个有序数组3.移除链表元素4.反转链表5.合并两个有序链表6.链表的中间结点7.环形链表的约瑟夫问题8.分割链表有感:其实我早就死了,死在破碎的三观里;死在飘渺的理想里;死在幻想的感情里&#x…

[AHK]自定义消息实现两个脚本之间通信

自己编写的两个脚本,用自定义消息实现,一个脚本控制另一个脚本,让被控脚本挂起或退出。 从aaa.ahk向bbb.ahk发送一个消息,bbb.ahk捕获消息后再进行处理,比如: 从aaa.ahk中向bbb.ahk发送特定的数字&#xff…

gpt-6有望成为通用工具

OpenAI CEO山姆奥特曼(Sam Altman)在最新的博客访谈中,提到gpt-6有望成为通用工具。 奥特曼还认为,目前的模型不够聪明,“使用GPT-2进行科学研究曾被认为是不切实际的想法。而如今,虽然人们使用GPT-4进行科…

短视频评论ID批量爬虫提取获客软件|DY评论下载采集工具

短视频评论批量抓取软件:智能拓客,精准抓取用户反馈 在当今数字化营销时代,了解用户的需求和反馈对于企业的发展至关重要。而作为流行的短视频平台,短视频评论蕴含了丰富的用户信息和市场洞察。为了帮助企业高效获取这些宝贵数据…

一秒内传输50万对纠缠光子?!纽约市量子网络刷新纪录

量子网络技术行业的领军企业Qunnect宣布,在纽约市的GothamQ网络上,其偏振量子比特的传输性能刷新了纪录。Qunnect利用现有的商用光缆实现了每秒传输50万对高保真度纠缠光子的速率,且该网络的正常运行时间超过了99%。 纽约34公里长的GothamQ量…

LIUNX文件系统

目录 1.磁盘的物理结构 2.CHS定位法 3.磁盘的逻辑存储 4.系统层面 inode.block[15] 创建文件的流程 查找文件的流程 了解文件系统,首先要了解磁盘是如何存储和读取数据的。 1.磁盘的物理结构 可以理解这个盘上有很多的小磁铁,通过旋转盘面和摆动…

C# 整数转罗马数字

罗马数字包含以下七种字符:I,V,X,L,C,D和M。 例如,罗马数字2写做 II ,即为两个并列的 1。12 写做XII,即为XII。27写做 XXVII,即为XXV II 。 通常情况下,罗马数字中小的数字在大的数字…

显示msvcp140.dll丢失要如何解决?这5种方法高效修复msvcp140.dll

msvcp140.dll是Microsoft Visual C Redistributable软件包中的一个文件,主要用于支持使用C编程语言编写的软件的正常运行。如果你的电脑出现缺少msvcp140.dll的错误消息,可能会影响到某些程序的启动和运行。然而,不必过度担心,因为…

【SQL每日一练】分组过滤练习题

文章目录 前言MySQL语法注意: 前言 题目:现在运营想查看每个学校用户的平均发贴和回帖情况,寻找低活跃度学校进行重点运营,请取出平均发贴数低于5的学校或平均回帖数小于20的学校。 drop table if exists user_profile; CREATE …
最新文章