LoRA:大模型下游任务的低秩适应

news2024/12/28 20:49:30

论文标题:LoRA: Low-Rank Adaptation of Large Language Models 

论文链接:https://arxiv.org/abs/2106.09685

论文来源:NVIDIA

一、概述

自然语言处理中的一个重要范式是在通用域数据上进行大规模预训练,然后在特定任务或域上适配。然而随着模型规模(比如GPT-3这样规模模型的出现)越来越大,对大模型的全参数微调变得更加困难,这在存储和部署上都非常具有挑战性。

目前的一些研究试图通过只微调一部分参数或为新任务学习外部模块来缓解这个问题。这样,我们只需要在进行每个任务时存储和加载少量的任务特定参数以及预训练模型,大大提高了部署时的操作效率。然而,现有的技术也存在一些问题,比如其通过扩展模型深度(adapter等方法)增加了推理延迟(inference latency),或者减少了模型可用的序列长度。更重要的是,这些方法通常无法达到微调baseline的效果,需要在效率和模型性能之间进行权衡。

我们的方法Low-Rank Adaptation (LoRA)灵感来源于一些前人的研究,即过度参数化的神经网络模型在训练后会呈现低秩特性,也就是说过度参数化的模型拥有一个很小的内在维度(low intrinsic dimension)。因此我们猜测,在模型微调适应的过程中权重的变化也具有“低秩”特性,这启发我们用低秩分解来表示权重的更新,而不是全参数训练。LoRA允许我们通过优化密集层(dense layer)在适应过程中的秩分解矩阵(rank decomposition matrices)来间接训练神经网络中的一些密集层,这个过程中保持预训练的参数不变,如下所示。以GPT-3 175B为例,我们证明了设置一个非常低的秩(也就是把下图中的设置成是1或2这样很小的值)就足够用来微调,虽然GPT-3的满秩高达12,288(也就是GPT-3的隐层维度),因此LoRA在存储和计算上是非常高效的。

ffa2424482c6127ee399581b68730d64.jpeg
LoRA

总体来说,LoRA有以下几个关键的优点: 

①预训练模型在不同的下游任务上可以共享,我们可以为不同的任务构建多个相应的LoRA模块。我们可以冻结预训练模型,在切换任务时只需要替换上图中的矩阵和即可,这可以显著降低存储需求和任务切换的开销。 

②当使用Adam等优化器时,LoRA使训练更高效,其将模型硬件要求的门槛降低了3倍,这是因为我们不需要计算预训练模型的梯度,也不需要维护其大多数参数的优化器状态,只需要优化插入的低秩矩阵的参数。 

③低秩矩阵是线性的设计,这允许我们在部署时可以将可训练低秩矩阵与冻结的预训练模型权重合并,这与全参数微调的模型相比,不会引入推理延迟。 

④LoRA与许多先前的方法是正交的,可以与其中的许多方法组合,例如prefix-tuning。

二、背景

在本文中,我们将Transformer模型的输出维度记作,使用来表示多头自注意力模块中的query/key/value/output密集层参数矩阵,用或者来表示预训练的权重矩阵,表示适应过程中梯度的累积更新,LoRA模块中的秩用表示。

对于一些下游任务(如摘要、机器阅读理解、NL2SQL等),在进行模型的全参数微调时,模型会被预训练权重初始化,然后按照梯度更新为以最大化下游任务数据上的条件概率:

❝ ❞

全参数微调在模型参数规模很大时在存储和部署上成本很高。在本文中,模型特定于任务的参数增量被使用更小规模的参数集来编码,也就是,这里的。寻找的过程也就变成了对的优化:

❝ ❞

三、方法

注意尽管在实验中我们只关注Transformer语言模型中的某些权重,但是LoRA适用于深度学习模型中的任何密集层。

  1. 低秩参数化的更新矩阵

一个神经网络包含许多执行矩阵乘法的密集层,这些层中的权重矩阵通常都是满秩的。当适应特定任务时,早先研究表明预训练语言模型在随机投影到较小的子空间后仍然可以高效地学习,或者说它们具有较低的内在维度或者内在秩。受此启发,我们假设在微调适应期间权重的更新也具有低的“内在秩”。对于一个预训练权重矩阵 ,微调时其权重更新为,我们通过将表示为一个低秩分解来限制这个更新过程,即,其中,,秩。在训练过程中,是冻结的,并不接收梯度更新,而和包含可训练参数。注意和都与相同的输入相乘,并且它们各自的输出向量按坐标求和。对于,我们修改后的前向传播为:

❝ ❞

前面的图1中说明了这个重参数化过程。我们对使用随机高斯矩阵初始化,对使用零矩阵初始化,因此在训练开始时为零。然后我们通过缩放,其中是一个常数,也就变成了:

❝ ❞

当使用Adam优化时,如果我们适当地缩放初始化,那么调整大致相当于调整学习率,这是因为反向传播时对和求导,以参数矩阵为例参数更新过程变成了:

❝ ❞

因此,我们简单地将设置为我们尝试的第一个,并不对其进行调优。这种缩放有助于减少我们在变化时需要重新调优超参数的需求。

LoRA方法是全参数微调的泛化。微调的一种更普遍的形式是训练预训练参数的一个子集。LoRA进一步地不要求在适应过程中权重矩阵的累积梯度更新具有满秩。这意味着当我们将LoRA应用于所有权重矩阵并训练所有偏置时,通过设置LoRA秩为预训练权重矩阵的秩,我们大致恢复了全参数微调的表达能力。换句话说,随着可训练参数的增加,LoRA的训练大致收敛到原始模型的训练,而基于adapter的方法收敛到MLP,基于prefix的方法收敛到无法处理长输入序列的模型。

LoRA不会引入额外推理延迟。在生产环境中部署时,我们可以明确计算并存储,并像往常一样执行推理。注意,和维度都是。当我们需要切换到另一个下游任务时,我们可以通过先减去恢复然后添加不同的,这是一个内存开销很小的快速操作。关键在于,这可以保证与微调模型相比,我们在推理期间不会引入任何额外延迟,这是由结构确定的。

  1. 将LoRA应用于Transformer

原则上,我们可以将LoRA应用于神经网络中的任何权重子集以减少可训练参数的数量。 在Transformer体系结构中,自注意力模块中有四个权重矩阵(, , , ),MLP模块中有两个。即使(或, )的输出维度通常被切片成注意力头,我们也将视为单个矩阵。在本文实验中我们限制仅对自注意力模块中的权重应用LoRA(实际上是只对和使用),冻结MLP模块(也就是说它们在下游任务中不被训练)。

LoRA方法 最重要的好处是内存和存储使用的减少。对于用Adam训练的大型Transformer,如果,由于我们不需要为大多数参数存储优化器状态,因此VRAM使用量减少了多达2/3。 在GPT-3 175B上,我们将训练期间的VRAM消耗从1.2TB降低到350GB。 当设置且仅适应query和value参数矩阵时,检查点大小约减少了10000倍(从350GB减少到35MB)。这允许我们用明显更少的GPU进行训练,并避免I/O瓶颈。 由于我们不需要计算绝大多数参数的梯度,与全参数微调相比,在GPT-3 175B上训练时,我们还观察到了25%的加速。

LoRA也有其局限性。如果合并和到中,会增加推理效率,但是会减少不同人物模块的灵活性。如果不合并,可以灵活地为不同任务动态选择模块,但推理效率可能会降低。

四、实验

本文在RoBERTa、DeBERTa、GPT-2、GPT-3等模型上进行了实验,实验结果如下:

707c2c902bedcdd6750180d784daf5dd.jpeg
实验
68ce12614be84c6683703492cc851a8a.jpeg
实验
57b8ff16a9eecc69a3060d2384d76ee6.jpeg
实验
6014bc313fb963c80990370404bb0561.jpeg
实验

五、理论分析

我们希望进一步解释从下游任务中学习的低秩更新的属性。注意,低秩结构不仅降低了硬件需求的门槛,从而使我们能够并行运行多个实验,而且还使更新权重与预训练权重的相关性更具可解释性。我们在GPT-3 175B上进行了一系列实证研究,以回答以下问题: 

①在参数预算约束下,我们应该适应哪些预训练Transformer中的权重子集以最大化下游任务的性能? 

②“最优”适应矩阵确实低秩吗?如果是这样,实践中使用将秩设置成多少比较好? 

③与有什么关系?与高度相关吗?(数学上,主要包含在的顶部奇异值方向中吗?)此外,与相对应的方向中,有多大?

我们相信,对问题②和③的回答可以阐明使用预训练语言模型进行下游任务的基本原理,这是自然语言处理中的一个关键主题。

  1. 我们应该对Transformer中的哪些矩阵使用LoRA?

给定有限的参数预算,哪种类型的权重应该被使用LoRA适应以获得下游任务的最佳性能效果?我们仅考虑自注意力模块中的权重矩阵。我们在GPT-3 175B上设置参数预算为18M(如果以FP16存储约需要35MB),这相当于(如果我们适应一种类型的注意力权重)或(如果我们适应两种类型),对于所有96层都是这样来设置。结果如下表所示。

04ca7d09a5d57cbded45f3ad22b530da.jpeg
实验

注意,将所有参数都适应在或中会导致性能显著降低,而适应和两者会产生最佳结果。这表明即使rank为4也可以在中捕获足够的信息。与使用更大的rank适应单个权重类型相比,适应更多权重矩阵是更合适的。

  1. LoRA的最优秩是多少?

  • 最优秩的设置

我们将注意力转向rank对模型性能的影响。我们适应仅、、,并进行比较。实验结果如下图所示:

637a690adb679ec60bb6dd4621b25f15.jpeg
实验

令我们惊讶的是,在这些数据集上,仅适应和时,rank为1就足够了,而仅训练需要更大的。实验结果表明增大不会覆盖更有意义的子空间,因此在使用LoRA时设置一个较小的即可。

  • 不同rank之间子空间的相似度

给定和,它们分别是使用相同预训练模型学习得到的rank为8和64的适应矩阵。我们对它们进行奇异值分解,得到右奇异矩阵和。我们希望回答:当我们分别取的前个奇异向量和的前个奇异向量(其中,)生成的子空间时,这两个子空间有多大的重叠?我们用一种基于Grassmann距离的归一化子空间相似度来衡量:

❝ ❞

其中表示对应于前个奇异向量的多个列。

的值域在,其中1表示子空间完全重叠,0表示完全正交。参见下图中随着和的变化的变化情况。由于篇幅所限,我们仅查看第48层(总共96层),但结论对其他层同样成立。

6c746e4b593dc93a333efc56c1c83455.jpeg
实验

从上图中可以观察到一个重要的结果:

和的顶部奇异向量对应的方向有很大的重叠,而其他的方向则不相容。具体来说,和的(或者)在维度为1时共享一个子空间,其归一化相似度在0.5以上。这可以解释为什么在我们的之前的实验中的表现已经相当不错。

由于和都是用同一个预训练模型学习得到的,上图3表明和的靠前的奇异向量方向是最有用的,而其他方向可能大多包含了训练过程中累积的随机噪声。因此,适应矩阵确实具有非常低的秩。

  • 不同随机种子之间子空间的相似度

我们进一步通过绘制在时两个随机种子(也就是初始化随机高斯矩阵时的随机种子)的归一化子空间相似度来确认这一点,结果如下图所示。与相比,似乎具有更高的“内在秩”,因为两次实验中共享的奇异值方向更多,这与我们在上表6中的观察到的结果一致。为了比较,我们还绘制了两个随机高斯矩阵的归一化子空间相似度,它们之间没有共享任何奇异值方向。

7bcc371fa1f410b637fbc31649760bc7.jpeg
实验
  1. 与的关系如何?

我们进一步研究和之间的关系。具体而言,是否与高度相关?(数学上,主要包含在的顶部奇异值方向中吗?)此外,与相对应的方向中,有多大?这可以阐明适应预训练语言模型的基本机制。

为了回答这些问题,我们通过计算,其中是的左/右奇异向量矩阵,将投影到的维子空间上。然后,我们比较和的Frobenius范数。作为比较,我们还通过将替换为或随机矩阵的前个奇异向量来计算。实验结果如下表所示。

7cc59f701c2d111d177ba7ec2f4925b6.jpeg
实验

我们从上表中得出几个结论: 

①首先,与随机矩阵相比,与之间存在更强的相关性,表明放大了中已经存在的某些特征。 

②其次,并不是重复中的靠前的奇异值方向,而是放大了中没有强调的方向。 

③放大系数是相当大的:对于,它是。

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

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

相关文章

开发一个RISC-V上的操作系统(二)—— 系统引导程序(Bootloader)

目录 文章传送门 一、什么是Bootloader 二、简单的启动程序 三、上板测试 文章传送门 开发一个RISC-V上的操作系统(一)—— 环境搭建_riscv开发环境_Patarw_Li的博客-CSDN博客 开发一个RISC-V上的操作系统(二)—— 系统引导…

SpringBoot中接口幂等性实现方案-自定义注解+Redis+拦截器实现防止订单重复提交

场景 SpringBootRedis自定义注解实现接口防刷(限制不同接口单位时间内最大请求次数): SpringBootRedis自定义注解实现接口防刷(限制不同接口单位时间内最大请求次数)_redis防刷_霸道流氓气质的博客-CSDN博客 以下接口幂等性的实现方式与上面博客类似,…

实战攻防Demo|如何轻松形成自动响应的安全闭环?

从威胁阻断角度来说,拦住黑客的第一步攻击尤为重要。同样,对于攻击者来说,第一步攻击的成本也往往是最高的。日常工作中人们会遇到很多类型的攻击,但暴力破解或者撞库攻击往往被作为黑客的第一步攻击。这主要源于其技术含量低&…

express编写一个简单的get接口

/01编写get接口.jsconst express require(express) const app express()// 创建路由 const useRouter require(./router/user.js) // 注册路由 app.use(/api,useRouter)app.listen(8080, (req, res) > {console.log(8080监听) }) ./02编写post接口 // 注意:如…

ESP32(MicroPython) 两轮差速五自由度机械臂小车

这次的项目在软件上没多少调整,但本人希望分享一下硬件上的经验。 小车使用两轮差速底盘,驱动轮在小车中间,前后都要万向轮。这种形式可以实现0转弯半径,但受万向轮及用于加高的铜柱的规格限制,两个万向轮难以调到相同…

3ds MAX 洗菜池

在家居中我们显然离不开这个对吧 首先绘制一个长方体作为基础 注意设置长宽高的网格大小,方便后续调整 俯视图网格线如下: 长方形变换为可编辑网络,并在【多边形】界面选择底面的所有多边形,按delete删除,形成一个壳体…

AtcoderABC233场

A - 10yen StampA - 10yen Stamp 题目大意 Takahashi已有X日元邮票,计算出Takahashi至少需要再贴多少个10日元的邮票才能使得信封上的邮票总价值达到Y日元。 思路分析 我们只需要计算Y - X,即Y日元减去X日元的差值。如果该差值大于等于0,则…

MyBatisPlus分页功能实现

MyBatisPlus分页功能实现 1. MyBatisPlus分页使用1.1 设置分页拦截器作为Spring管理的bean1.2 执行分页查询 2. 开启MyBatisPlus日志3. 解决日志打印过多问题3.1 取消初始化spring日志打印3.2 取消SpringBoot启动banner图标3.3 取消MybatisPlus启动banner图标 1. MyBatisPlus分…

零信任安全解决方案

什么是零信任 零信任网络架构 (ZTNA) 或零信任安全是一种新的组织网络安全方法。它旨在修复传统基于边界的安全性中的缺陷并简化网络设计。 它以“永不信任,始终验证”的原则运作。这意味着,无论用户或设备位于何处,…

基于自适应运动补偿的双向运动估计算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..........................................................................% 单向运动法 …

繁體標楷體 如何安装使用?

中文繁體標楷體。 ——这个地方下载:http://www.downcc.com/font/316365.html ——下载下来被叫做“台湾标楷体DFKai-SB.ttf” ——安装到“C:\Windows\Fonts”以后名字叫 ——在WPS中使用,被称为这个

使用node内置test runner,和 Jest say 拜拜

参考 https://nodejs.org/dist/latest-v20.x/docs/api/test.html#test-runner 在之前,我们写单元测试,必须安装第三方依赖包,而从node 20.0.0 版本之后,可以告别繁琐的第三方依赖包啦,可直接使用node的内置test runner…

【搜索引擎Solr】Apache Solr 神经搜索

Sease[1] 与 Alessandro Benedetti(Apache Lucene/Solr PMC 成员和提交者)和 Elia Porciani(Sease 研发软件工程师)共同为开源社区贡献了 Apache Solr 中神经搜索的第一个里程碑。 它依赖于 Apache Lucene 实现 [2] 进行 K-最近邻…

龙芯iTOP-2K1000开发板制作启动U盘

我们准备一个 U 盘(最小不要小于 4G,最大不要大于 32G),U 盘有且只有一个分区,U 盘格式化成 FAT32 分区,,如不满足要求,请格式化您的 U 盘,准备完成如下图所示 格式化软…

推荐系统(十)用户行为序列建模-Pooling 路线

对推荐系统而言,准确捕捉用户兴趣是其面临的核心命题。不管是样本、特征还是模型结构等方面的优化,本质上做的事情都是在提高推荐系统对用户兴趣的捕捉能力,因此如何提高这种能力,对推荐效果的提升有重要作用,也是算法…

性能优化问题

提升首屏的加载速度,是前端性能优化中「最重要」的环节,这里笔者梳理出一些 常规且有效 的首屏优化建议 1、路由懒加载 SPA 项目,一个路由对应一个页面,如果不做处理,项目打包后,会把所有页面打包成一个文…

使用lua脚本操作redis

redis中实现事务有两种方法: 1.WATCH监视键的变动,然后MULTI开始事务,EXEC提交事务 WATCH key [key…]:监视一个或多个键,如果在事务执行之前被修改,则事务被打断。 MULTI:标记一个事务的开始。…

Redis原理篇(二)

Redis原理 Redis数据结构 Redis网络模型 RESP协议 Redis内存回收 Redis原理篇 一、原理篇-Redis数据结构 1.1 Redis数据结构-动态字符串 我们都知道Redis中保存的Key是字符串,value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。 不…

JVM理论(六)执行引擎--垃圾回收

概述 垃圾: 指的是在运行程序中没有任何指针指向的对象垃圾回收目的: 为了及时清理空间使得程序可以正常运行垃圾回收机制: JVM采取的是自动内存管理,即JVM负责对象的创建以及回收,将程序员从繁重的内存管理释放出来,更加专注业务的开发垃圾回收区域: 频繁收集Young区(新生代)…

【前端知识】React 基础巩固(三十二)——Redux的三大原则、使用流程及实践

React 基础巩固(三十二)——Redux的三大原则 一、Redux的三大原则 单一数据源 整个应用程序的state被存储在一颗object tree 中,并且这个object tree 只存储在一个store中;Redux并没有强制让我们不能创建多个Store,但是那样做不利于数据维护…