Low Rank Adpation -- Introduction[1]

2355 words12 min read

LoRA 是参数高效微调(parameter-efficient fine-tuning, peft)技术的一种。对比全量参数微调,LoRA 跟踪权重的变化而不是直接更新权重,通过低秩分解权重更新矩阵,从而减少训练参数量。LoRA 在大型语言模型上取得了很好的效果,比如 GPT-3 175B 模型如果全参数微调需要 1.2TB 的 VRAM,而 LoRA 只需要 350GB(秩 rr=1024)。

Source — Image generated using DALLE-3

Formally

假设 W0Rd×dW_0 \in \mathbb{R}^{d \times d} 是模型的参数矩阵,权重的更新 ΔW=UVT\Delta W=U \cdot V^T 会被低秩分解为 URd×rU \in \mathbb{R}^{d \times r}VRd×rV \in \mathbb{R}^{d \times r},其中 rd r \ll d。这样,一次前向传播可表示为: h=W0x+UVTxh = W_0 \cdot x + U \cdot V^T \cdot x。训练时 W0W_0 会被冻结,只训练 UUVV。初始化时,VV 通过 Gaussian 初始化,U=0U = 0

LoRA reparametrization.

LoRA 能够使用的原因或者背景是什么?这就要提到一个概念:The intrinsic rank hypothesis,即模型的低秩结构假设。这个假设认为,可以使用较低维的表示来捕获神经网络的显着变化。即假定 ΔW\Delta W 的所有元素并非同等重要,相反,只要一具较小的子集可以有效地“捕获”必要的调整。

从模型的训练角度上讲,大模型可能存在“容量过大”(over-parametized)的问题,即给定训练数据,模型的参数大于实际需要的参数。这种情况下,模型的参数可能会出现冗余性,鲁棒性和弹性。很多模型都存在低秩结构,Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning 论证了只需要优化(RoBERTA)小一部分参数,就能达到全微调 90% 的效果。

LoRA 基于这个假设,通过低秩分解,将权重更新矩阵分解为更小的矩阵,并使用它们来训练模型。

微调有多高效

以 GPT-3 175B 为例,全参数微调仅参数存储就需要占用 175B×4/10243651GB175B \times 4 / 1024^3 \approx 651GB 的内存,考虑到模型的梯度和其他内存需求,实际训练时内存需求加倍,因此需要 1.2TB 的 VRAM。

现假设所有 WK,WQ,WV,WOW_K, W_Q, W_V, W_O 参与运算的矩阵都使用低秩逼近,秩的值假定为 r=1024r=1024,那么 LoRA 只需要约 150 GB 的 VRAM,计算过程可见下面 题外话 小节。

注:原论文假设 WK,Q,V,OW_{K,Q,V,O} 的大小为 dmodel×dmodeld_{model} \times d_{model},不作多头区分,因此计算的参数量会有所不同。

Rank7B13B70B180B
10.002%0.002%0.001%0.000%
20.005%0.004%0.002%0.001%
40.010%0.007%0.003%0.002%
80.019%0.014%0.006%0.004%
160.038%0.028%0.012%0.008%
5121.224%0.898%0.387%0.241%
1,0242.448%1.796%0.774%0.483%
8,19219.583%14.370%6.193%3.862%
16,38439.165%28.739%12.385%7.723%

粗略的计算,LoRA 的参数量是全参数微调的 2r/d2 \cdot r / \sqrt{d}。因此,模型的参数量越大,LoRA 的优势越明显。如上表所示,当 d=180Bd=180B 时,秩为 1024 的 LoRA 的参数量仅占全量微调参数量的 0.483%0.483\%。因此 LoRA 有如下几个优势:

  • 极大地减少存储空间:比如 GPT-3 175B 模型,全参数微调需要 1.2TB 的 VRAM,而 LoRA 只需要 350GB(r=1024)。
  • 快速训练与领域适配:通过简化计算需求,LoRA 加速了大型模型针对新任务的训练和微调。
  • 支持在较小的设备上微调大模型:LoRA 的低内存需求使得在资源受限的设备上也可以进行大型模型的微调。

rr 的选择

LoRA 的核心思想是通过低秩近似来简化权重梯度,以牺牲一定的精度为代价,减少计算与存储负担。一个适合的秩应该在保证模型性能的同时,尽可能的减少参数量。

在 WikiSQL 及 MultiNLI 任务上,当 r=1r=1 时就达到了很好的效果,随着rr的增加,准确率开始下降。rr 的最佳区域是 4 或 8,也即是 WW 的梯度可以不损失太多信息的情况下,被压缩到一个较小的空间里。

Optimal rank

论文也验证了高秩 rr 学到的向量空间与低秩 rr 没有太大差异。具体地,分别取 r=8,64r=8, 64,各自通过 LoRA 去学习 ΔW\Delta W,然后作奇异值分解,得到两个右奇异向量矩阵 V8,V64V_8, V_{64}。最后通过 Grassmann distance 去度量相似性。

ϕ(V8,V64,i,j)=V8iTV64jmin(i,j)\phi(V_8,V_{64},i,j)=\frac{\lVert {V_8^i}^T V_{64}^j \rVert}{\min(i,j)}

其中 ViV^i 表示第 top-ii 个右奇异向量。从文中结果(下图)可以看到,秩为8和秩为64时学习到的自适应矩阵中,顶部的奇异向量方向有显著的重叠,而其他方向则没有。 一个可能的解释是:顶部奇异向量方向最为重要,而其他方向可能主要包含训练过程中累积的随机噪声。

Subspace similarity

变体

QLoRA

QLoRA 的思想是把高精度计算技术与低精度存储方法相结合,在保持模型尺寸较小的同时,仍确保模型的高性能和准确性。

QLoRA v.s. LoRA

LongLoRA

LongLoRA 相对于 LoRA 的改进:

  • 移位稀疏注意力(S2-Attn, Shifted Sparse Attention):LongLoRA 提出了一种新颖的移位稀疏注意力机制,有效地通过稀疏局部注意力在训练过程中扩展上下文,同时在推理时可以选择性地使用密集全局注意力。这种方法能够在维持与密集注意力相似的性能的同时,显著减少计算成本。
  • 改进的参数效率微调:LongLoRA改进了LoRA的参数效率微调策略,特别是在处理长上下文时。通过使嵌入层和归一化层可训练,LongLoRA解锁了长上下文LoRA微调的潜力,这一点在传统的LoRA方法中并未特别强调。
  • 兼容性和扩展性:LongLoRA不仅保留了原始模型的架构,而且与大多数现有技术(例如Flash-Attention)兼容。这种兼容性和扩展性使得LongLoRA可以轻松地应用于各种不同规模的模型和任务中,提高了方法的通用性。
  • 在单台机器上实现大规模上下文扩展:LongLoRA能够在单台8×A100 GPU机器上实现显著的上下文扩展,例如将Llama2模型的上下文从几千扩展到10万或更多,简直是资源有限、囊中羞涩的研究者的福音。

实证结果表明的高效性和有效性:LongLoRA在多个长上下文任务上展示了强大的实证结果,证明了其方法在提高训练效率的同时,能够保持甚至提升性能。

题外话:GPT-3 的 175B 这个值怎么来的 ?

根据 GPT-3 的介绍,GPT-3 有 175B 个参数,其中模型层数 nlayers=96n_\text{layers}=96,每层有 nheads=96n_\text{heads}=96 个注意力头,每个头的维度是 dhead=128d_\text{head}=128,模型维度是 dmodel=12288d_\text{model}=12288

Source: GPT-3 technical report

参数统计

词嵌入(Word Embedding)

词嵌入矩阵 WeW_e 将输入的词汇转换成密集向量。这个矩阵的大小是词汇量 nvocabn_\text{vocab} 乘以模型维度 dmodeld_\text{model},即词嵌入层参数的总数是 nvocabdmodeln_\text{vocab} * d_\text{model}。从 GPT-2 的paper中知道 nvocab=50,257n_\text{vocab}=50,257,因此 C(We)=50,25712288=617,558,016C(W_e)= 50,257 * 12288 = 617,558,016

位置嵌入(Position Embedding)参数

位置嵌入矩阵 WpW_p,在GPT中学习位置嵌入,其大小与输入序列的长度nctxn_\text{ctx}和模型维度dmodeld_\text{model}相同,因此其参数总数为 C(Wp)=nctxdmodel=204812288=25,165,824C(W_p)=n_\text{ctx} * d_{model} = 2048 * 12288 = 25,165,824

注意力机制(Attention)

注意力层的参数主要包含在以下几个部分:

  • 查询(Query)矩阵 WQW^Q
  • 键(Key)矩阵 WKW^K
  • 值(Value)矩阵 WVW^V
  • 输出(Output)矩阵 WOW^O

对于每个头,每个矩阵的维度是 (dmodel,dhead)(d_\text{model}, d_\text{head}),三个矩阵的参数总数是 3nheadsdmodeldhead3 * n_\text{heads} * d_\text{model} * d_\text{head}WOW^O 的维度是 (nheadsdhead,dmodel)(n_\text{heads} * d_\text{head}, d_\text{model}),因为它需要把所有头的输出合并起来。

一层的注意力机制参数总数是 4nheadsdmodeldhead4 * n_\text{heads} * d_\text{model} * d_\text{head}。GPT-3 的模型有 nlayers=96n_\text{layers}=96 层,因此注意力机制的参数总数是 4969612288128=57,982,058,4964 * 96 * 96 * 12288 * 128 = 57,982,058,496

FFN 层

这是参数另一个大头。

FFN 层有两个线性变换,每个变换有一个权重矩阵和一个偏置向量。

  • 第一个线性变换的权重矩阵 W1W_1 的大小是 (dmodel,dffn)(d_\text{model}, d_\text{ffn}),其中 dffn=4dmodeld_\text{ffn} = 4 * d_\text{model} (source: GPT-3 paper section 2.1)是 FFN 层的隐藏层大小,偏置项 b1b_1 的大小是 dffnd_\text{ffn}
  • 第二个线性变换的权重矩阵 W2W_2 的大小是 (dffn,dmodel)(d_\text{ffn}, d_\text{model}),偏置项 b2b_2 的大小是 dmodeld_\text{model}

一层 FFN 层的参数总数是 2dmodeldffn+5dmodel=81228812288+512288=1,208,020,9922 * d_\text{model} * d_\text{ffn} + 5 *d_\text{model}= 8 * 12288 * 12288 + 5 * 12288 = 1,208,020,992。96 层的 FFN 层的参数总数是 1,208,020,99296=115,970,015,2321,208,020,992 * 96 = 115,970,015,232

最终统计

  • 词嵌入层参数:617,558,016
  • 位置嵌入层参数:25,165,824
  • 注意力机制参数:57,982,058,496
  • FFN 层参数:115,970,015,232

总和是 174,594,797,568,与 GPT-3 175B 参数量误差为 0.23%。

参考