lora的各种变体:
-
lora+:对A(靠近输入端)和B(靠近输出端)设置不同的学习率以加速收敛,对B的学习率通常是A的4到16倍,这是因为近输出层的梯度更加稳定,近输入层的梯度相对不稳定,如果设置的学习率过大,容易梯度爆炸。
-
vera:VeRA 是对 LoRA 的一种改进,基于低秩更新框架,但在更新矩阵的设计上引入了随机投影和向量驱动的适配机制。VeRA 使用随机初始化的矩阵结合少量可训练向量来生成更新矩阵,从而大幅减少可训练参数量。 对于预训练权重矩阵\(\mathbf{W}\in\mathbb{R}^{d \times k}\),,VeRA 定义更新公式为:\(W_0x + \Delta W x = W_0x + \Lambda_b \cdot B \cdot \Lambda_d \cdot A \cdot x\)(其中B和A无需为低秩矩阵,因为这两个矩阵是被随机初始化的,其参数无需被存储),可以看到向量\(b\)和\(a\)在公式被表示为了相应的对角矩阵,但是实际上存储的确实是两个向量,只是用对角矩阵写更加容易表达实际在pytorch中的运算形式罢了。可以看下列代码理解:
# 这行代码:
result = Λ_b @ B @ Λ_d @ A# 实际上等价于:
temp1 = B * d.unsqueeze(0) # B的每一列乘以d的对应元素
temp2 = b.unsqueeze(1) * temp1 # 结果的每一行乘以b的对应元素
result = temp2 @ A
可以注意到此处B @ Λ_d被对应成了B * d.unsqueeze(0),所以说实现的时候是使用了tensor类型重载的*而非矩阵乘法@,实现了等效的矩阵的列的缩放。
-
LoRA-FA:这是LoRA与Frozen-A的缩写,在LoRA-FA中,矩阵A在初始化后被冻结,因此作为随机投影。矩阵B不是添加新的向量,而是在用零初始化之后进行训练(就像在原始LoRA中一样)。这将参数数量减半,同时具有与普通LoRA相当的性能。
-
lora-drop:先训练几次,然后对于每个层的lora的output进行评估,然后根据评估结果来选择需要再训练的lora,剩下的那些层的lora使用同一个AB矩阵进行训练。
-
Qlora:即Quantization Lora,QLoRA的优化有三个核心要点:首先是定义了一种4位标准浮点数(Normal Float 4-bit,NF4)量化,基于分块的分位数量化的量化策略;其次是双重量化,包含对普通参数的一次量化和对量化常数的再一次量化,可以进一步减小缓存占用;最后是分页优化器(Page Optimizer),用来在显存过高时用一部分内存代替显存。
由于4bit只能够表示16种不同的数值,所以通常的将数值进行寻常的缩放误差过大,故诞生了NF4(将标准正态分布左右两边同时舍去0.0322917后将0的左边分成7个等概率区域,0的右边分成8个等概率区域,然后将这些区域的总共16个端点归一化到[-1,1],由此得到NF4能表示的16个值:['-1.0000', '-0.6962', '-0.5251', '-0.3949', '-0.2844', '-0.1848', '-0.0911', '0.0000', '0.0796', '0.1609', '0.2461', '0.3379', '0.4407', '0.5626', '0.7230', '1.0000']),为了进一步减少额外需要存储的空间,作者提出了双量化(对于单量化,将一个权重张量进行量化后,不仅需要将保存量化后的张量,还需要额外一个32位的浮点数以表示其标准差(即),其占用32个比特的空间。因此,如果只做第一次量化,则需要额外存储的空间(除了存储量化张量以外)为32个比特,假如张量的大小(blocksize,即张量各个维度的乘积)为64,则其实就是对64个数字进行量化,那 额外需要的32比特平均到每个数字上,就是32/64=0.5比特。作者为了把这个额外空间进一步降低,将
进行进一步的量化。假如我们用64$*\(256个数字需要量化,那就将其分为256个block,每64个数字划分到一个block中,对64个block中进行量化会产生256个****。为了降低额外空间,需要对这256个****进行第二次量化。具体做法是**将其量化到8比特的浮点数格式FP8,并且再用一个FP32表示这256个\)c^{fp32}_2$的标准差,即为
。所以,对64*256个数字进行量化所需要的额外空间为(8*256+32)/(64*256)=8/64+32/(64*256)=0.127比特,量化每个数字所需要的额外空间从0.5减少到0.127,所以减少了0.373**。 (注意不是每个权重值量化所需要的空间,而是所需要的额外空间)。)
-
AdaLoRA:LORA的局限性在于其预先规定了每个增量矩阵的秩必须相同。这样就忽略了不同层、不同类型参数对下游任务的重要程度。AdaLORA改进了LORA可微调参数的分配方式,根据每个参数的重要程度自动得为其分配可微调参数的预算。具体的,AdaLORA采用奇异值分解(SVD)的形式参数化增量更新。这种参数化方式在规避大量SVD运算的同时,允许我们高效裁剪不重要更新中的奇异值,降低增量过程中的资源消耗。AdaLORA增量矩阵显式的替换为\(W = W^{(0)} + ∆ = W^{(0)} + PΛQ\)并对损失函数增加正则项
\( R(P, Q) = \left\| P^\top P - I \right\|_F^2 + \left\| Q Q^\top - I \right\|_F^2 \)来使得P和Q趋近于一个正交矩阵。对于某个奇异值的重要性评估的知识点可参照(11 条消息) LORA微调系列(三):AdaLORA和它的基本原理 - 知乎
-
LongLora:其实这一变体的改动不在lora而是在注意力机制,LongLoRA 引入了 SHIFT(移位)操作。例如,对于长度为 8192 的序列,若组大小为 2048,在第一个组(token 1-2048)之后,下一个组并非从 token 2049 开始,而是从 token 1025(即 2048/2)开始,到 token 3072 结束。