6、LORA微调

1、相关数学

1、什么是秩

秩(Rank)
为了从方程组中去掉多余的方程,引出了“矩阵的秩”。矩阵的秩度量的就是矩阵的行列之间的相关性。为了求矩阵A的秩,我们是通过矩阵初等变换把A化为阶梯型矩阵,若该阶梯型矩阵有r个非零行,那A的秩rank(A)就等于r。 如果矩阵的各行或列是线性无关的,矩阵就是满秩的,也就是秩等于行数。矩阵的秩度量的就是矩阵的行列之间的相关性。如果矩阵的各行或列是线性无关的,矩阵就是满秩的,也就是秩等于行数。

我们首先来看一个矩阵A:
https://zhuanlan.zhihu.com/p/646831196

A = [[1, 2, 3],
     [2, 4, 6],
     [3, 6, 9]]

该矩阵中,row2 = row1 * 2,row3 = row1*3,也就是说,矩阵中的每一行,都可以通过第一行线性表示。
我们再来看一个矩阵B:

B = [[1, 2, 3],
     [7, 11, 5],
     [8, 13, 8]]

该矩阵中,任意一行,总可以用其他两行的线性组合来表示。
我们最后再来看一个矩阵C:

C = [[1, 0, 0],
     [0, 1, 0],
     [0, 0, 1]]

该矩阵中,任意一行,都不能从其余行的线性组合中推导而来。
调用np.linalg.matrix_rank函数,我们可以算出任意矩阵的秩,上面三个矩阵的秩分别为:

A = np.array(A)
B = np.array(B)
C = np.array(C)
print("Rank of A:", np.linalg.matrix_rank(A)) # 1
print("Rank of B:", np.linalg.matrix_rank(B)) # 2
print("Rank of C:", np.linalg.matrix_rank(C)) # 3

对矩阵A来说,由于只要掌握其中的任意一行,其余行都可以由这一行线性推导而来,因此A的秩是1。
对矩阵B来说,由于只要掌握其中的任意两行,其余行都可以由这两行线性组合推导而来,因此B的秩是2。
对矩阵C来说,由于必须完全掌握三行,才能得到完整的C,因此C的秩是3。
看到这里,你是不是已经对秩有了感性的理解了? 秩表示的是矩阵的信息量。如果矩阵中的某一维,总可以通过其余维度线性推导而来,那么对模型来说,这一维的信息是冗余的,是重复表达的。 对A和B的情况,我们称为秩亏(rank deficient),对C的情况,我们称为满秩(full rank)。更严谨的数学定义,大家可以参考《线性代数》(狗头)。
有了对秩的这层认识,我们自然会想到,全参数微调中的增量权重
可能也存在冗余的信息,因此我们并不需要用完整的d*d 尺寸来表示它。那么,我们要如何找出
中真正有用的特征维度呢?SVD分解(奇异值分解),可以帮我们解决这个问题

2、低秩分解

  1. 秩(Rank)
      为了从方程组中去掉多余的方程,引出了“矩阵的秩”。矩阵的秩度量的就是矩阵的行列之间的相关性。为了求矩阵A的秩,我们是通过矩阵初等变换把A化为阶梯型矩阵,若该阶梯型矩阵有r个非零行,那A的秩rank(A)就等于r。 如果矩阵的各行或列是线性无关的,矩阵就是满秩的,也就是秩等于行数。矩阵的秩度量的就是矩阵的行列之间的相关性。如果矩阵的各行或列是线性无关的,矩阵就是满秩的,也就是秩等于行数。

  2. 低秩(Low-Rank)
      如果X是一个m行n列的数值矩阵,rank(X)是X的秩,假如rank (X)远小于m和n,则我们称X是低秩矩阵。低秩矩阵每行或每列都可以用其他的行或列线性表出,可见它包含大量的冗余信息。利用这种冗余信息,可以对缺失数据进行恢复,也可以对数据进行特征提取。

3、低秩分解
假设我们有一个m×n的矩阵A,我们希望对其进行低秩分解,即将其分解为两个低秩矩阵的乘积:A ≈ UV^T。其中,U是一个m×k的矩阵,V是一个n×k的矩阵,k远远小于m和n。
LoRA引入了两个矩阵A和B,如果参数W的原始矩阵的大小为d × d,则矩阵A和B的大小分别为d × r和r × d,r为分解后的秩,其中r要小得多(通常小于100)。参数r称为秩。如果使用秩为r=16的LoRA,则这些矩阵的形状为16 x d,这样就大大减少了需要训练的参数数量。

3、特征值分解和奇异值分解

https://blog.csdn.net/qfikh/article/details/103994319
特征值分解和奇异值分解在机器学习领域的方法,让机器学会抽取重要的特征。 可以将一个比较复杂的矩阵用更小更简单的几个子矩阵的相乘来表示,这些小矩阵描述的是矩阵的重要的特性。两者关系紧密,特征值分解和奇异值分解的目的都是一样,就是提取出一个矩阵最重要的特征。区别在于,特征值分解针对方阵而言,奇异值分解可以针对任意矩阵进行分解。

1)特征值、特征向量

如果一个向量v是矩阵A的特征向量,将一定可以表示成下面的形式:
Aa=ra
其中,λ是特征向量v对应的特征值,一个矩阵的一组特征向量是一组正交向量。
对于矩阵A,有一组特征向量v,将这组向量进行正交化单位化,就能得到一组正交单位向量。特征值分解,就是将矩阵A分解为如下式:
在这里插入图片描述
其中,Q是矩阵A的特征向量组成的矩阵,则是一个对角阵,对角线上的元素就是特征值。我们来分析一下特征值分解的式子,分解得到的Σ矩阵是一个对角矩阵,里面的特征值是由大到小排列的,这些特征值所对应的特征向量就是描述这个矩阵变换方向(从主要的变化到次要的变化排列)。
在这里插入图片描述
SVD分解的应用
异值分解的应用有很多,比如:用SVD解PCA、潜在语言索引也依赖于SVD算法。可以说,SVD是矩阵分解、降维、压缩、特征学习的一个基础的工具,所以SVD在机器学习领域相当的重要。
1)降维。
通过奇异值分解的公式,我们可以很容易看出来,原来矩阵A的特征有n维。经过SVD分解后,可以用前r个非零奇异值对应的奇异向量表示矩阵A的主要特征,这样就把矩阵A进行了降维。

2)压缩。
通过奇异值分解的公式,我们可以看出来,矩阵A经过SVD分解后,要表示原来的大矩阵A,我们只需要存储U、Σ、V三个较小的矩阵即可。而这三个较小规模的矩阵占用内存上也是远远小于原有矩阵A的,这样SVD分解就起到了压缩的作用。

4、奇异值分解

SVD(Singular value decomposition,奇异值分解)是一种矩阵分解的方法,任何矩阵,都可以通过SVD的方法分解成几个矩阵相乘的形式。
其中和是正交矩阵,是特征值矩阵。

在这里插入图片描述

对于机器学习,SVD一个主要优点是对矩阵降维,对于高维矩阵可以通过SVD表示成三个维度相对较低的矩阵、和。在推荐系统中,可以将用户行为构造成User-Item的评分矩阵 ,其中m和n分别表示平台的User数和Item数。 表示用户对物品的评分(也可以是点击、互动、播放、下载等行为),用于刻画User对Item的有效操作。采用SVD算法将分解成 、和。虽然,从形式上看SVD分解简单直接,但由于日常User-Item的评分矩阵事高度稀疏的,而SVD分解要求矩阵是稠密的,通常采用对评分矩阵中的缺失值进行补全(比如补0、全局平均值、用户物品平均值补全等)得到稠密矩阵。再用SVD分解并降维。但实际过程中,元素缺失值是非常多的,导致了传统SVD不论通过以上哪种方法进行补全都是很难在实际应用中起效果。此外传统SVD在实际应用中还有一个严重的问题——计算复杂度(时间复杂度是,空间复杂度是)。当用户数和物品总量过大(如千上万级),对矩阵做SVD分解是非常耗时。这是得传统的SVD分解方法很难在实际业务中应用起来。
研究者们做了大量工作来解决传统SVD的稀疏数据不适用和高计算复杂度的问题,其中主要的有FunkSVD、BiasSVD和SVD++算法。
在这里插入图片描述

LORA

https://zhuanlan.zhihu.com/p/618073170
https://zhuanlan.zhihu.com/p/646791309
微调的含义,就是把已经训练好的模型(pretrained model)拿来,给它吃特定的下游任务数据,使得模型在预训练权重上继续训练,直至满足下游任务性能标准。预训练模型就像一个特征提取器,能够基于先前训练数据中学到的经验,为我们提取有效的特征,大大提升下游任务的训练效果和收敛速度。Lora作用于W权重,改变W所在的层的权重值。

1.全参数微调
在这里插入图片描述
全参数微调指的是,在下游任务的训练中,对预训练模型的每一个参数都做更新。例如图中,给出了Transformer的Q/K/V矩阵的全量微调示例,对每个矩阵来说,在微调时,其d*d个参数,都必须参与更新。

2.局部微调办法
.局部微调办法:Adapter Tuning与Prefix Tuning。
我们来看在LoRA出现前,两种主流的局部微调办法:Adapter Tuning与Prefix Tuning。这也是LoRA的原始论文中,重点比对的两种微调方式。
Adapter Tuning:
在这里插入图片描述
在微调时,除了Adapter的部分,其余的参数都是被冻住的(freeze),这样我们就能有效降低训练的代价。Adapter的内部架构不是本文所述的重点,这里我们就不再介绍了。但这样的设计架构存在一个显著劣势:添加了Adapter后,模型整体的层数变深,会增加训练速度和推理速度,原因是:
需要耗费额外的运算量在Adapter上。
当我们采用并行训练时(例如Transformer架构常用的张量模型并行),Adapter层会产生额外的通讯量,增加通讯时间。

Prefix Tuning:
对于GPT这样的生成式模型,在输入序列的最前面加入prefix token,图例中加入2个prefix token,在实际应用中,prefix token的个数是个超参,可以根据模型实际微调效果进行调整。对于BART这样的Encoder-Decoder架构模型,则在x和y的前面同时添加prefix token。在后续微调中,我们只需要冻住模型其余部分,单独训练prefix token相关的参数即可,每个下游任务都可以单独训练一套prefix token。Prefix Tuning虽然看起来方便,但也存在以下两个显著劣势;
较难训练,且模型的效果并不严格随prefix参数量的增加而上升。
会使得输入层有效信息长度减少。为了节省计算量和显存,我们一般会固定输入数据长度。增加了prefix之后,留给原始文字数据的空间就少了,因此可能会降低原始文字中prompt的表达能力。

3、Lora原理
https://blog.csdn.net/deephub/article/details/136735670
Lora作用于W权重矩阵,改变W所在的层的权重值,主要通过低秩分解(不是奇异值分解)用AB矩阵代替ow,是一种PEFT(参数高效性微调方法)。LoRA引入了两个矩阵A和B,如果参数W的原始矩阵的大小为d × d,则矩阵A和B的大小分别为d × r和r × d,其中r要小得多(通常小于100)。参数r称为秩。如果使用秩为r=16的LoRA,则这些矩阵的形状为16 x d,这样就大大减少了需要训练的参数数量。LoRA的最大的优点是,与微调相比,训练的参数更少,但是却能获得与微调基本相当的性能。LoRA的一个技术细节是:在开始时,矩阵A被初始化为均值为零的随机值,但在均值周围有一些方差。矩阵B初始化为完全零矩阵。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

主要参数:

  • 1.^W=AB:用奇异值分解矩阵AB代替oW
  • 2.参数r:代表秩,rank是一个超参数,用于控制矩阵A和B rank的内部维度。换句话说,该参数控制着LoRA引入的额外参数的数量,是决定模型适应性和参数效率之间平衡的关键因素。
  • 3.参数a:alpha控制svd奇异值分解对角线元素的值大小,第二个超参数alpha是应用于低秩自适应输出的缩放超参数。它本质上控制了适应层的输出允许影响正在适应的层的原始输出的程度。这可以被视为调节低秩适应对层输出的影响的一种方法。
  • 4.秩(Rank):矩阵的秩度量的就是矩阵的行列之间的相关性。为了求矩阵A的秩,我们是通过矩阵初等变换把A化为阶梯型矩阵,若该阶梯型矩阵有r个非零行,那A的秩rank(A)就等于r。 如果矩阵的各行或列是线性无关的,矩阵就是满秩的,也就是秩等于行数。矩阵的秩度量的就是矩阵的行列之间的相关性。如果矩阵的各行或列是线性无关的,矩阵就是满秩的,也就是秩等于行数。
  • 5.SVD:(Singular value decomposition,奇异值分解)是一种矩阵分解的方法,任何矩阵,都可以通过SVD的方法分解成几个矩阵相乘的形式。其中和是正交矩阵,是特征值矩阵。(用的是低秩分解)

通过数学方法直接做SVD行不通,那就让模型自己去学怎么做SVD吧!因此LoRA最终的低秩适配策略是:我把秩当成一个超参,再让模型自己去学低秩矩阵,这不就简单又省事吗!在我们采用Adam做优化器时,调整a的作用就相当于调整learning rate。
在这里插入图片描述

QLORA

https://zhuanlan.zhihu.com/p/681519805
https://zhuanlan.zhihu.com/p/647378373
https://zhuanlan.zhihu.com/p/648239462
QLORA是一种基于LoRA(Low-rank Adapter)的微调方法,其中适配器位于每个网络层。通过一系列创新工作,如引入4位NormalFloat、双量化和Paged Optimizers等方法,QLORA对LoRA方法进行了更好的调优,降低内存使用同时保持性能。通过在每个网络层添加适配器,QLORA避免了以前工作中观察到的几乎所有的准确性折衷。这种方法将65B参数模型的内存需求从>780GB降低到<48GB,使得在单个GPU上微调最大的公开可用模型成为可能。
在这里插入图片描述
QLORA引入了几项创新来节省内存而不牺牲性能,包括

  • 一种新的数据类型4位NormalFloat(NF4);
  • 双重量化以减少平均内存占用;
  • 分页优化器来管理内存峰值。

4位正态浮点量化
量化基础 - 正态浮点(NF)数据类型: 正态浮点(NormalFloat, NF)数据类型是建立在分位数量化的基础上。分位数量化是一种信息论上的最优数据类型,它确保每个量化区间有相同数量的输入张量值。通过经验累积分布函数估算输入张量的分位数来实现。
在这里插入图片描述

在这里插入图片描述

AdaLORA

https://zhuanlan.zhihu.com/p/649756885
在这里插入图片描述
在这里插入图片描述
AdaLORA解决方案
AdaLORA主要包含两个模块:(i) SVD形式参数更新(SVD-based adaptation):直接将增量矩阵
参数化为SVD的形式,避免了在训练过程中进行SVD计算带来的资源消耗;(ii) 基于重要程度的参数分配(Importance-aware rank allocation): 裁剪一些冗余的奇异值。
SVD和LoRA对是对原来复杂度较高的矩阵进行了低秩分解。但是如果我们直接对LoRA进行秩的调整的话将会带来很多问题,首先对 AB直接减小秩的话相当于将 AB的某些列以及的某些行置0,这样丢失的信息难免有些多,也造成了特征恢复几乎不太可能实现。另外 A 和 B 并不是正交矩阵,也就意味着它们的行之间或者列之间的特征有很大的相关性,直接将特征置0的话将会破坏这种相关性。为了解决LoRA不适合直接调整秩的问题,AdaLoRA将LoRA的两项式替换为SVD的三项式。
AdaLoRA通过将所有添加了适配器的模块的秩的值看做了一组超参,然后通过模型剪枝的思想对LoRA的秩进行了自适应的计算。同时为了剪枝后模型效果的稳定,AdaLoRA使用SVD的三元组替代了LoRA的二元组,充分利用了SVD奇异矩阵的正交性和奇异向量的绝对值和特征重要性的相关性设计剪枝策略,非常精彩。

在这里插入图片描述

三种Lora对比

一、LoRA(低秩分解)
LoRA是一种基于低秩分解的大模型参数高效微调技术。其核心思想是通过低秩分解来模拟参数的改变量,从而以极小的参数量来实现大模型的间接训练。在涉及到矩阵相乘的模块,LoRA在原始的PLM旁边增加一个新的通路,通过前后两个矩阵A,B相乘,第一个矩阵A负责降维,第二个矩阵B负责升维,中间层维度为r,从而来模拟所谓的本征秩(intrinsic rank)。可训练层维度和预训练模型层维度一致为d,先将维度d通过全连接层降维至r,再从r通过全连接层映射回d维度,其中,r<<d,r是矩阵的秩,这样矩阵计算就从d x d变为d x r + r x d,参数量减少很多。第一个矩阵的A的权重参数会通过高斯函数初始化,而第二个矩阵的B的权重参数则会初始化为零矩阵,这样能保证训练开始时新增的通路BA=0从而对模型结果没有影响。
二、AdaLoRA(奇异值分解)
AdaLoRA是一种自适应的低秩分解技术,它在LoRA的基础上进一步优化了参数的训练过程。与LoRA不同,AdaLoRA不再预先设定降维后的维度r,而是通过自适应的方式在训练过程中不断调整r的大小。这样可以在保证模型性能的同时进一步减少参数量。
三、QLoRA(量化)
QLoRA是一种基于量子计算的大模型参数高效微调技术。它将低秩分解与量子计算相结合,利用量子比特的量子叠加和量子纠缠等特性,对大模型的参数进行高效的微调。通过将一部分参数映射到量子比特上,QLoRA可以在量子计算机上利用量子算法进行高效的参数优化。
Lora系列:https://blog.csdn.net/deephub/article/details/136735670

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值