LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS
本文涉及奇异值分解算法,可参考此文
1. 摘要
~~~~~~~~ 现在大模型一般是预训练模型通过微调实现特定任务。预训练模型更大时,全量微调的实现代价高。本文提出低秩自适配(Low-Rank Adaptation, LoRA)微调技术,它冻结了预训练的模型权重,并将可训练的秩分解矩阵注入到Transformer架构的每一层,从而大大减少了下游任务的可训练参数的数量。GitHub仓库:https://github.com/microsoft/LoRA
2. 优势
LoRA具有几个关键优势。
-
不同任务训练不同的LoRA模块。可以固定预训练模型参数,通过替换图1中的矩阵A和B来有效地切换任务,从而显著降低存储需求和任务切换开销。
-
LoRA使训练更有效,并且在使用自适配优化器时将硬件门槛降低了3倍,因为我们不需要计算梯度或维护大多数参数的优化器状态,而只需要优化低秩矩阵的少量参数。
-
部署时可以合并低秩矩阵参数和预训练模型固定的参数,没有引入推理延迟。
-
LoRA可以与以往许多方法组合,例如prefix-tuning。
3. 术语和约定
- d m o d e l d_{model} dmodel是Transformerc层的输入输出
- W q , W k , W v , 和 W o W_q,W_k,W_v,和W_o Wq,Wk,Wv,和Wo是自注意力模块中 query/key/value/output 的投影矩阵
- W 或者 W 0 W或者W_0 W或者W0是预训练模型的权重矩阵
- Δ W \Delta W ΔW 是微调过程中累积的梯度更新。
- r r r是LoRA模块的秩的大小
4. 现有方法
4.1 prefix tuning
论文名称:Prefix-Tuning: Optimizing Continuous Prompts for Generation
-
该方法是在输入token之前构造一段任务相关的virtual tokens作为Prefix,相当于对于Transformer的每一层(不只是输入层,且每一层transformer的输入不是从上一层输出,而是随机初始化的embedding作为输入),都是在真实的句子表征前面插入若干个连续的可训练的virtual token embedding,这是token不必是词袋中有的词,而是可以自由调参的vector。
-
Encoder端添加前缀是为了引导输入部分的编码;Decoder端增加前缀是为了引导后续tokens的生成。
注意的问题
- 该方法和构造Prompt类似,Prompt是人为构造的“显式”的提示,无法更新参数,而Prefix是可以学习的“隐式”的提示。
- 为了防止直接更新Prefix的参数导致训练不稳定的情况,特在Prefix层前面加了MLP结构(相当于将Prefix分解为更小维度的Input与MLP的组合后输出的结果),训练完成后,只保留Prefix的参数。
- prefix-prompt的效果优于adapter tuning 和 finetune最上面的两层,最终和全参数finetune差不多,且在低资源情况下,效果优于finetune。
4.2 Adapter
~~~~~~~~ 论文名称:Parameter-Efficient Transfer Learning for NLP
- 在transformer的注意力层和前馈神经网络(FFN)层之后添加全连接网络。微调时,只对新增的Adapter结构和Layer Norm层进行微调,从而保证了训练的高效性,没每当出现新的下游任务,通过添加Adapter模块来产生一个容易扩展适配模块,可以避免全量微调与灾难性遗忘的问题。
- Adapters Tuning效率很高,通过微调不到4%的模型参数,可以实现与 fine-tuning相当的性能。
- Adapter模块整体是一个bottleneck结构,包括两个前馈子层(Feedforward)和skip-connection。
5. 现有方法缺陷
5.1 引入推理延迟
~~~~~~~~ Adapter层引入了推理延迟。适配器有许多变体。我们关注的是Houlsby等人提出的原始设计,其每个Transformer块包含两个适配器层。虽然可以通过剪枝层或利用多任务设置来减少整体延迟,但没有直接的方法绕过适配器层中的额外计算。因为适配器层的设计初衷就是通过具有较小的瓶颈维度来限制其参数量(有时不到原始模型的1%),从而减少其增加的FLOP。然而,大型神经网络依赖硬件并行性来保持较低的延迟,而适配器层必须按顺序处理。在在线推理设置中,这会产生影响,因为批处理大小通常只有一个。在没有模型并行性的通用场景下,例如在单个GPU上运行GPT-2的中等规模模型时,即使适配器层的瓶颈维度非常小,我们也会发现延迟明显增加(表1)。当我们需要像Shoeybi等人(2020);Lepikhin等人(2020)那样对模型进行分片时,这个问题会更加严重,因为额外的深度需要更多同步的GPU操作,例如AllReduce和Broadcast,除非我们将适配器参数冗余存储多次。
5.2 直接优化Prompt是很困难的
~~~~~~~~ 前缀调优很难优化,并且其性能在可训练参数中呈现非单调变化,这也在原始论文中得到了类似的观察。更根本的问题是,保留一部分序列长度用于适配必然会减少可用于处理下游任务的序列长度,这可能导致前缀调优的性能不如其他方法。
6. 方法
~~~~~~~~ 神经网络包含许多执行矩阵乘法的稠密层。这些层中的权重矩阵通常具有全秩。在适配特定任务时,Aghajanyan等人(2020)表明,预训练的语言模型具有较低的“内在维度”,即使通过随机投影到较小的子空间,模型仍然可以有效学习。受到此启发,我们假设在适配过程中,权重的更新也具有较低的“内在秩”。对于一个预训练的权重矩阵 W o ∈ R d × k W_o \in \mathbb{R}^{d\times k} Wo∈Rd×k,通过低秩分解来约束其更新,即 W o + Δ W = W 0 + B A W_o+\Delta W = W_0 + BA Wo+ΔW=W0+BA,其中 B ∈ R d × r B \in \mathbb{R}^{d \times r} B∈Rd×r, A ∈ R r × k A \in \mathbb{R}^{r \times k} A∈Rr×k,并且 r ≤ m i n ( d , k ) r\leq min(d,k) r≤min(d,k)。在训练过程中, W 0 W_0 W0被冻结,不会接受梯度更新, A 和 B A和B A和B包含可训练的参数。 W 0 W_0 W0和 Δ W = B A \Delta W=BA ΔW=BA都与相同的输入相乘,其各自的输出向量按坐标逐项相加,对于 h = W 0 x h=W_0x h=W0x,修改后的前向传递如下:
h = W 0 x + Δ W x = W 0 x + B A x (3) h=W_0x+\Delta Wx = W_0x+BAx\tag{3} h=W0x+ΔWx=W0x+BAx(3)
~~~~~~~~ 在图1中展示了重新参数化的过程。我们对矩阵 A A A 进行随机高斯初始化,并将矩阵 B B B 初始化为零,因此在训练开始时, Δ W = B A \Delta W = BA ΔW=BA 为零。然后我们将 Δ W x \Delta Wx ΔWx 缩放为 α r \frac{\alpha}{r}