Lora原理分析
(1)LoRA整体架构
图中左侧表示“全参数finetune”的场景。我们将参数分成了两个部分:
- W ∈ R d ∗ d W \in \mathbb{R}^{d*d} W∈Rd∗d:预训练权重
- Δ W ∈ R d ∗ d \Delta W \in \mathbb{R}^{d*d} ΔW∈Rd∗d:finetune增量权重
全参数finetune可以理解成**“冻住的预训练权重” + “微调”**过程中产生的权重更新量”,设输入为 x ,输出为 h ,则有:
h
=
W
x
+
Δ
W
x
h=Wx+\Delta Wx
h=Wx+ΔWx
图中右侧表示“LoRA finetune”的场景。在LoRA中,我们用矩阵A和B来近似表达
Δ
W
\Delta W
ΔW:
- W ∈ R r ∗ d W \in \mathbb{R}^{r*d} W∈Rr∗d:低秩矩阵 A ,其中** r r r被称为秩**,对 A 用高斯初始化。
- Δ W ∈ R r ∗ d \Delta W \in \mathbb{R}^{r*d} ΔW∈Rr∗d:低秩矩阵 B ,对B采用零初始化。
经过这样一番拆分,我们将
Δ
W
\Delta W
ΔW 改写成
Δ
W
=
B
A
\Delta W=BA
ΔW=BA的形式,使得微调参数量从
d
∗
d
d*d
d∗d降低至
2
∗
r
∗
d
2*r*d
2∗r∗d,同时不改变输出数据的维度,即在LoRA下我们有:
h
=
W
x
+
B
A
x
h=Wx+BAx
h=Wx+BAx
另外,在原论文中提到过对于两个低秩矩阵,会用超参 α (一个常数)来做调整,但没有说明这个超参的作用位置。在读完LoRA的源码后,我发现这个超参是作为scaling rate直接和低秩矩阵相乘的,也就是最终的输出为:
h
=
W
x
+
α
r
B
A
x
h=Wx+\frac{\alpha}{r}BAx
h=Wx+rαBAx
在实操中,一般取
α
≥
r
\alpha \ge r
α≥r ,例如在LoRA源码对GPT2微调,做NLG任务时,就取
α
=
32
,
r
=
4
\alpha=32,r=4
α=32,r=4 。
(2)LoRA的训练和推理过程
1.训练
在训练过程中,我们固定住预训练权重 W ,只对低秩矩阵 A 和 B 进行训练。在保存权重时,我们只需保存低秩矩阵的部分即可。
2.推理
在推理过程中,我们按照 W = W + α r B A W=W+ \frac{α}{r}BA W=W+rαBA 的方式,合并低秩矩阵和预训练权重,然后正常做forward推理。这样我们完全不会更改模型的架构,因此不会像Adapter Tuning一样产生推理上的延时。图展示了论文中的实验效果,推理时长的单位是milliseconds,可以发现,LoRA的推理速度显著高于Adapter Tuning。
(3)LoRA低秩适配的原理
1.什么是秩
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)。
有了对秩的这层认识,我们自然会想到,全参数微调中的增量权重 ΔW 可能也存在冗余的信息,因此我们并不需要用完整的 d ⋅ d d \cdot d d⋅d 尺寸来表示它。那么,我们要如何找出ΔW中真正有用的特征维度呢?SVD分解(奇异值分解),可以帮我们解决这个问题
2.SVD
矩阵 M 是我们需要做信息量检查的矩阵,假设在输入数据的特征空间中,存在一组正交的单位向量
v
1
⃗
\vec{v_1}
v1,
v
2
⃗
\vec{v_2}
v2,经过 M 的变换后,它们变成另一组正交向量
KaTeX parse error: Can't use function '$' in math mode at position 20: …lta_1 \vec{u_1}$̲,$\delta_2 \vec…
,其中
u
1
⃗
,
u
2
⃗
\vec{u_1},\vec{u_2}
u1,u2 也是一组正交的单位向量,
δ
1
,
δ
2
\delta_1, \delta_2
δ1,δ2分别表示对应方向上的模。这一顿变幻,可以写成:
M
[
v
1
⃗
,
v
2
⃗
]
=
[
δ
1
u
1
⃗
,
δ
2
u
1
⃗
]
M[\vec{v_1},\vec{v_2}]=[\delta_1\vec{u_1},\delta_2\vec{u_1}]
M[v1,v2]=[δ1u1,δ2u1]
改写为:
M
=
[
u
1
⃗
,
u
2
⃗
]
[
δ
1
0
0
δ
2
]
[
v
1
⃗
v
2
⃗
]
M=[\vec{u_1},\vec{u_2}] \begin{bmatrix} \delta_1 & 0 \\ 0 & \delta_2 \end{bmatrix} \begin{bmatrix} \vec{v_1} \\ \vec{v_2} \end{bmatrix}
M=[u1,u2][δ100δ2][v1v2]
再近似等价为:
M
=
U
Σ
V
T
M=U \Sigma V^T
M=UΣVT
当我们找到这样的 U,Σ,V 矩阵后,我们再从这三者中取出对应的top r
行(或列),不就相当于关注到了 M 最强调的那几维特征,进而就能用更低维的矩阵,来近似表达 M 了
3.LoRA低秩适配
- 对 ΔW 做SVD:能直接做SVD的前提是ΔW是确定的,而现实中ΔW作为全参数微调中的权重增量,如果你不全参数微调一遍,又怎么能知道ΔW长什么样呢
- 对预训练权重 W 做SVD:微调的目的是给模型注入和下游任务相关的领域新知识。也就是说,ΔW和 W 的表达含义是不同的,前者是新知识,后者是旧知识,我们的目的是要去新知识中拆解信息量丰富的维度。
**那既然通过数学方法直接做SVD行不通,那就让模型自己去学怎么做SVD。**因此LoRA最终的低秩适配策略是:我把秩 r 当成一个超参,再让模型自己去学低秩矩阵 A,B 。
4.超参 α \alpha α
回顾一下我们的输出计算方法为:
h
=
W
x
+
α
r
B
A
x
h=Wx+\frac{\alpha}{r}BAx
h=Wx+rαBAx
其中, W 表示预训练权重(旧知识),
α
r
B
A
\frac{\alpha}{r}BA
rαBA 表示增量权重 ΔW 的近似(新知识)。当 r 较小时,我们提取的是 ΔW 中信息含量最丰富的维度,此时信息精炼,但不全面;当 r 较大时,我们的低秩近似越逼近ΔW**,此时信息更加全面,但带来的噪声也越多(含有很多冗余无效的信息)**。
基于这个猜想,当我们第一次做实验时,我们会尽量把 r 调得大些,例如32、64,并假设在这个秩下,低秩权重已经非常近似 ΔW 了,因此这时我们设置 α=r ,意味着我们假定LoRA低秩微调的效果和全参数微调持平。
那么接下来,我们肯定就要往小的 r 进行尝试了。
(4)LoRA实验:验证低秩矩阵的有效性
1.整体效果
2.低秩矩阵信息量验证
当 r 越小时,低秩矩阵所含的信息越精炼,但同时也可能越不全面。那么到底 r 要取多少才合适呢?
- 直接验证不同r值下的微调效果
尽管理论上我们可以在模型的任意一层嵌入低秩适配器(比如Embedding, Attention,MLP等),但LoRA中只选咋在Attention层嵌入,并做了相关实验(论文中也鼓励读者可以多做别的尝试),我们来看下Attention层的实验效果:
WikiSQL
和MultiNLI
是用于微调的数据集,Weight Type指明在Attention的哪一部分做了低秩适配。可以发现, r=4,8 于 r=64 的效果几乎持平,甚至还略优于 r=64 。这更加说明了“低秩”的有效性。为了更具象化地验证这一点,我们进一步来看 r=8 和 r=64 这两个低秩空间的相交程度
- 不同低秩空间的相交程度
假设 A r = 8 A_r=8 Ar=8 和 A r = 64 A_r=64 Ar=64 分别是在 r = 8 r=8 r=8和 r = 6 r=6 r=6 下训练出来的低秩矩阵,我们现在想做这么一件事:
- 从 Ar=8 中取出 topi 个信息最丰富的维度
- 从 Ar=64 中取出 topj 个信息最丰富的维度
- 计算这 t o p i top_i topi个维度和 t o p j top_j topj个维度的相交程度
找出top个信息最丰富的维度:
- 表示 A r = 8 A_{r=8} Ar=8 的右奇异矩阵, U A r = 8 i U_{A_{r=8}}^i UAr=8i表示该右奇异矩阵信息量最丰富的 $top_i 个维度( 个维度( 个维度(M=U \Sigma V^T$)
- 表示 A r = 64 A_{r=64} Ar=64 的右奇异矩阵, U A r = 64 i U_{A_{r=64}}^i UAr=64i表示该右奇异矩阵信息量最丰富的 $top_i 个维度( 个维度( 个维度(M=U \Sigma V^T$)
相交程度计算:
相交程度(Grassmann distance)位于 [0,1] 之间,该值越大,表示相应的两个子空间越相似。
实验结果:
作者是在 W q , W v W_q,W_v Wq,Wv 上都做了低秩分解,所以1、3图和2、4图分别为一组,我们就选1、3图来看吧。
作者做这个实验的目的,其实是想看高秩空间中到底包含了多少低秩空间的信息,这样才能解释为什么 r=64 和 r=8 **的效果基本持平。所以作者在计算Grassmann distance和绘制图表时的逻辑是:**对 A r = 8 A_r=8 Ar=8 ,当 i = 1 i=1 i=1 时,我想和 A r = 64 A_r=64 Ar=64 的 t o p j , j > = 1 top_j,j>=1 topj,j>=1 进行相似度计算,这样我就能知道, A r = 8 A_r=8 Ar=8 中最丰富的那1维信息,究竟包含了多少在 A r = 64 A_r=64 Ar=64 的 t o p 1 , t o p 2 , ⋯ , t o p 64 top_1,top_2,\cdots,top_{64} top1,top2,⋯,top64 中。然后以此类推。
好,解释完这一点,我们再具体来看图例。颜色越浅,表示相似度越高。在图1中,我们不难发现 i=1 这一行的颜色是最浅的,随着 i 的增加,颜色逐渐变深。这说明小秩空间中,信息量越高的那几维特征,和大秩空间的相交度越高,因此它们也是小秩空间表现能持平大秩空间的主要原因,这也更加论证了作者所说的“低秩”的有效性。