LoRA 的学习笔记

什么是 LoRA 模型

LoRA 的全称是 LoRA: Low-Rank Adaptation of Large Language Models,是一种以极低资源微调大模型的方法,其来自于论文 LoRA: Low-Rank Adaptation of Large Language Models ¹。

LoRA 的核心思想是冻结预训练的模型权重,并将可训练的秩分解矩阵注入 Transformer 架构的每一层,从而大大减少了下游任务的可训练参数数量。相比于完全微调,LoRA 可以节省显存、提高训练速度、减少推理延迟,并且保持或提升模型质量。

LoRA 可以应用于自回归模型(如 GPT 系列)和 Encoder-Decoder 模型(如 T5),并且可以与不同规模的预训练模型(如 RoBERTa, DeBERTa, GPT-2, GPT-3)兼容。

LoRA 的原理和实现

大模型微调的困境

随着模型规模的不断扩大,模型会“涌现”出各种能力。特别是对大语言模型 (LLM) 来说,随着规模的扩大其在 zero-shot、常识推理等能力上会有大幅度的提高。

但是,大模型的微调成本和部署成本也非常高。例如,GPT-3 175B 模型微调需要 1.2TB 的显存。此外,若针对不同下游任务微调多个模型,那么就需要为每个下游任务保存一份模型权重,成本非常高。在某些场景下,甚至可能需要针对不同的用户微调不同的模型,那么模型微调和部署的成本将不可接受。

因此,如何降低大模型微调和部署成本,将是大模型商用的重要一环。

LoRA 之前的方法

在 LoRA 方法提出之前,也有很多方法尝试解决大模型微调困境的问题。其中有两个主要的方向:

  • 添加 adapter 层;
  • 使用 prefix-tuning。

但是这两种方法都有局限性:

  • Adapter 层会引入推理时延。简单来说,它的主要思想是在预训练模型的每一层 Transformer 中插入一个小的可训练的模块,称为 adapter。这样可以保持预训练模型的权重不变,只更新 adapter 的参数,从而实现参数高效和灵活的迁移学习12。
  • Prefix-tuning 难以优化。prefix-tuning 方法是受语言模型 in-context learning 能力的启发,只要有合适的上下文则语言模型可以很好地解决自然语言任务。但是,针对特定的任务找到离散 token 的前缀需要花费很长时间,prefix-tuning 提出使用连续的 virtual token embedding 来替换离散 token。这些 virtual token embedding 需要作为可训练参数进行优化,而且会减少下游任务的序列长度。

LoRA 的方法

LoRA 为了更加参数高效,使用相对非常小的参数 Θ \Theta Θ 来表示任务相关的参数增量 Δ Φ = Δ Φ ( Θ ) \Delta\Phi=\Delta\Phi (\Theta) ΔΦ=ΔΦ(Θ) ,其中 ∣ Θ ∣ ≪ ∣ Φ 0 ∣ |\Theta|\ll |\Phi_0| ∣Θ∣Φ0 。寻找 Δ Φ \Delta\Phi ΔΦ 的任务就变成对 Θ \Theta Θ 的优化:

max ⁡ Θ ∑ ( x , y ) ∈ Z ∑ t = 1 ∣ y ∣ log ⁡ ( p Φ 0 + Δ Φ ( Θ ) ( y t ∣ x , y < t ) ) \max_ {\Theta}\sum_ { (x,y)\in\mathcal {Z}}\sum_ {t=1}^ {|y|}\log (p_ {\Phi_0+\Delta\Phi (\Theta)} (y_t|x,y_ {<t})) Θmax(x,y)Zt=1ylog(pΦ0+ΔΦ(Θ)(ytx,y<t))

LoRA 将会使用低秩表示来编码 Δ Φ \Delta\Phi ΔΦ ,同时实现计算高效和存储高效。当预训练模型是 175B GPT-3,可训练参数 ∣ Θ ∣ |\Theta| ∣Θ∣ 可以小至 ∣ Φ 0 ∣ |\Phi_0| Φ0 的 0.01% 。

对于预训练权重矩阵 W 0 ∈ R d × k W_0\in\mathbb {R}^ {d\times k} W0Rd×k ,可以通过低秩分解来表示其更新 W 0 + Δ W = W 0 + B A , B ∈ R d × r , A ∈ R r × k W_0+\Delta W=W_0+BA,B\in\mathbb {R}^ {d\times r},A\in\mathbb {R}^ {r\times k} W0+ΔW=W0+BABRd×r,ARr×k 且秩 r ≪ min ⁡ ( d , k ) r\ll\min (d,k) rmin(d,k) 。在训练过程中, W 0 W_0 W0 被冻结且不接受梯度更新, A A A B B 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 h=W_0x+\Delta Wx=W_0x+BAx h=W0x+ΔWx=W0x+BAx

对矩阵 A A A 使用随机高斯初始化,对矩阵 B B B 使用 0 进行初始化,因此 Δ W = B A \Delta W=BA ΔW=BA 在训练的开始为 0。使用 α r \frac {\alpha} {r} rα 来缩放 Δ W x \Delta Wx ΔWx 。当使用 Adam 优化时,经过适当的缩放初始化,调优 α \alpha α 与调优学习率大致相同。

当进行部署时,以显式的计算和存储 W = W 0 + B A W=W_0+BA W=W0+BA ,并正常执行推理。 W 0 W_0 W0 B A BA BA 都是 R d × k \mathbb {R}^ {d\times k} Rd×k 。当需要转换至另一个下游任务,可以通过减去 B A BA BA 来恢复 W 0 W_0 W0 ,然后添加不同的 B ′ A ′ B'A' BA

LoRA 的实验结果和分析

LoRA 的实验设置

论文中使用了四种不同规模的预训练模型:RoBERTa-base, DeBERTa-base, GPT-2-medium, GPT-3-175B。其中前两种是 Encoder 模型,后两种是 Decoder 模型。

论文中使用了八个下游任务:SQuAD v1.1, SQuAD v2.0, CoQA, RACE, MNLI, SST-2, QQP, QNLI。其中前四个是机器阅读理解任务,后四个是 GLUE 任务。

论文中将 LoRA 与以下方法进行了比较:

  • Full fine-tuning:完全微调所有参数;
  • Adapter:在每一层 Transformer 中添加 adapter 层;
  • Prefix-tuning:在每一层 Transformer 中添加 virtual token embedding;
  • Freeze:冻结所有参数,只微调输出层。

论文中使用了两种评价指标:模型质量和推理时延。模型质量使用 F1 或者准确率来衡量。推理时延使用单个 GPU 上的推理时间来衡量。

LoRA 的实验结果

论文中给出了各种方法在不同任务上的模型质量和推理时延的结果。这里只展示部分结果,完整结果可以参考原论文。

RoBERTa-base 在 GLUE 上的结果

LoRA 在模型质量上与 full fine-tuning 相当或者更好,并且远超过其他方法。同时,LoRA 的推理时延与 full fine-tuning 和 freeze 相同,并且比 adapter 和 prefix-tuning 小很多。

LoRA 的分析和讨论

论文中还对 LoRA 的一些性质和特点进行了分析和讨论,这里只简要介绍一些,完整内容可以参考原论文。

  • LoRA 的秩选择。论文中发现,对于不同的预训练模型和下游任务,LoRA 的最优秩是不同的。一般来说,秩越大,模型质量越高,但是也会增加计算和存储的开销。论文中提供了一些经验性的秩选择方法,例如根据预训练模型的层数或者下游任务的难度来选择秩。
  • LoRA 的初始化。论文中发现,对于 LoRA 的低秩矩阵 A A A B B B,使用随机高斯初始化 A A A,使用 0 初始化 B B B 是比较合理的。这样可以保证 Δ W = B A \Delta W=BA ΔW=BA 在训练开始时为 0,不会影响预训练模型的权重。同时,使用 α r \frac {\alpha} {r} rα 来缩放 Δ W x \Delta Wx ΔWx 可以避免过大或过小的梯度更新。
  • LoRA 的有效性。论文中通过实验发现,预训练模型在适应下游任务时,其权重更新具有低秩的特性。也就是说,只需要少量的参数就可以实现较大的性能提升。这也说明了 LoRA 的设计思想是合理的。

LoRA 的优缺点

根据论文和网上的一些资料²³,我们可以总结出 LoRA 模型的一些优缺点:

优点

  • 参数高效。LoRA 只需要少量的可训练参数就可以实现与完全微调相当或更好的模型质量。这样可以节省显存、提高训练速度、减少存储空间。
  • 推理高效。LoRA 不会增加额外的推理时延,因为它只是在预训练模型的权重上加上一个低秩矩阵,并不改变模型的结构和计算流程。
  • 通用性强。LoRA 可以应用于自回归模型和 Encoder-Decoder 模型,并且可以与不同规模的预训练模型兼容。
  • 灵活性强。LoRA 可以通过调整低秩矩阵的秩来平衡模型质量和计算开销。同时,LoRA 可以通过减去低秩矩阵来恢复预训练模型的权重,并添加不同的低秩矩阵来适应不同的下游任务。

缺点

  • 秩选择困难。LoRA 的低秩矩阵的秩对于模型质量和计算开销都有影响,但是没有一个统一的方法来确定最优的秩。需要根据不同的预训练模型和下游任务进行尝试和调整。
  • 初始化敏感。LoRA 的低秩矩阵的初始化对于模型的收敛和性能都有影响,需要使用合适的初始化方法和缩放因子。如果初始化不当,可能会导致模型无法收敛或者性能下降。
  • 低秩假设不一定成立。LoRA 的设计基于一个假设,即预训练模型在适应下游任务时,其权重更新具有低秩的特性。这个假设在一些实验中得到了验证,但是也可能存在一些反例,即需要较高秩的权重更新才能实现较好的模型质量。

LoRA 的应用场景

LoRA 模型作为一种以极低资源微调大模型的方法,可以应用于以下一些场景:

  • 需要使用大规模预训练语言模型来解决特定的自然语言处理任务,例如机器阅读理解、文本摘要、文本分类等,但是又受限于硬件资源或者成本预算的场景。
  • 需要根据不同的用户或者领域来定制化大规模预训练语言模型的生成风格或者内容,例如对话系统、文本生成、文本风格转换等,但是又不想为每个用户或者领域保存一份完整微调的模型的场景。
  • 需要在不同的下游任务之间快速切换大规模预训练语言模型的能力,例如多任务学习、元学习、迁移学习等,但是又不想重新训练或者加载完整微调的模型的场景。

LoRA 的代码实现

论文中提供了一个开源的代码库,可以方便地将 LoRA 集成到 PyTorch 模型中,并提供了 RoBERTa, DeBERTa, 和 GPT-2 的实现和模型检查点。代码库的地址是:https://github.com/microsoft/LoRA

代码库中包含了以下几个部分:

  • lora.py:包含了 LoRA 的核心实现,即低秩矩阵注入和参数恢复等功能。
  • models.py:包含了 RoBERTa, DeBERTa, 和 GPT-2 的 LoRA 版本的实现。
  • run_glue.py:包含了在 GLUE 任务上使用 RoBERTa 或者 DeBERTa 的 LoRA 版本进行微调和评估的脚本。
  • run_squad.py:包含了在 SQuAD 任务上使用 RoBERTa 或者 DeBERTa 的 LoRA 版本进行微调和评估的脚本。
  • run_race.py:包含了在 RACE 任务上使用 RoBERTa 或者 DeBERTa 的 LoRA 版本进行微调和评估的脚本。
  • run_coqa.py:包含了在 CoQA 任务上使用 GPT-2 或者 GPT-3 的 LoRA 版本进行微调和评估的脚本。

代码库中还提供了一些使用说明和示例命令,可以参考 README.md 文件。

Source: Conversation with Bing, 2023/6/12
(1) 你真的会用LORA吗?超详细讲解LORA分层控制 - 知乎. https://zhuanlan.zhihu.com/p/621260240.
(2) LoRA 指南 - 知乎. https://zhuanlan.zhihu.com/p/600628691.
(3) 什么是LoRA模型,如何使用和训练LoRA模型?你想要的都在这!. https://zhuanlan.zhihu.com/p/624230991.

Source: Conversation with Bing, 2023/6/12
(1) LoRA: Low-Rank Adaptation of Large Language Models. https://arxiv.org/abs/2106.09685.
(2) 【自然语言处理】【大模型】极低资源微调大模型方法LoRA … https://zhuanlan.zhihu.com/p/618073170.
(3) 论文阅读:LORA-大型语言模型的低秩适应 - 知乎. https://zhuanlan.zhihu.com/p/611557340.

补充

具体说说 lora 是怎么实现将可训练的秩分解矩阵注入 Transformer 架构的每一层,举个具体的例子

  • LoRA 的基本思想是对于预训练模型的权重矩阵 W 0 W_0 W0,使用一个低秩矩阵 Δ W = B A \Delta W=BA ΔW=BA 来表示其更新,其中 B B B A A A 是可训练的参数,而 W 0 W_0 W0 是固定的。这样可以保证 Δ W \Delta W ΔW 的参数数量远小于 W 0 W_0 W0 的参数数量,从而实现参数高效。
  • LoRA 可以应用于 Transformer 架构的不同部分,例如自注意力、交叉注意力、前馈网络等。具体来说,LoRA 可以将低秩矩阵注入到这些部分的输入或输出端,或者在这些部分的中间添加一个低秩矩阵。
  • 举个例子,假设我们要对一个自注意力层进行 LoRA 微调,该层的输入为 Q , K , V Q, K, V Q,K,V,输出为 Z Z Z。我们可以在输入端注入低秩矩阵 Δ Q \Delta Q ΔQ, Δ K \Delta K ΔK, Δ V \Delta V ΔV,即:

Q ′ = Q + Δ Q = Q + B Q A Q Q'=Q+\Delta Q=Q+B_QA_Q Q=Q+ΔQ=Q+BQAQ

K ′ = K + Δ K = K + B K A K K'=K+\Delta K=K+B_KA_K K=K+ΔK=K+BKAK

V ′ = V + Δ V = V + B V A V V'=V+\Delta V=V+B_VA_V V=V+ΔV=V+BVAV

然后使用 Q ′ Q' Q, K ′ K' K, V ′ V' V 来计算自注意力的输出 Z Z Z。这样相当于在输入端增加了一个残差连接。

  • 我们也可以在输出端注入低秩矩阵 Δ Z \Delta Z ΔZ,即:

Z ′ = Z + Δ Z = Z + B A Z'=Z+\Delta Z=Z+BA Z=Z+ΔZ=Z+BA

然后使用 Z ′ Z' Z 作为自注意力的输出。这样相当于在输出端增加了一个残差连接。

  • 我们还可以在自注意力的中间添加一个低秩矩阵 Δ A \Delta A ΔA,即:

A = s o f t m a x ( Q K T d k ) + Δ A = s o f t m a x ( Q K T d k ) + B A A=\mathrm {softmax} (\frac {QK^T} {\sqrt {d_k}})+\Delta A=\mathrm {softmax} (\frac {QK^T} {\sqrt {d_k}})+BA A=softmax(dk QKT)+ΔA=softmax(dk QKT)+BA

然后使用 A A A 来计算自注意力的输出 Z Z Z。这样相当于在自注意力的中间增加了一个残差连接。

  • 这些方法都可以实现将可训练的秩分解矩阵注入 Transformer 架构的每一层,从而实现 LoRA 微调。

Source: Conversation with Bing, 2023/6/12
(1) Using LoRA for Efficient Stable Diffusion Fine-Tuning … https://huggingface.co/blog/lora.
(2) Picotest-J2101A Injection Transformer 10Hz - 45MHz. https://www.picotest.com/products_J2101A.html.
(3) GitHub - Blealtan/RWKV-LM-LoRA: RWKV is a RNN with … https://github.com/Blealtan/RWKV-LM-LoRA.

为什么 adapter 会引入时延?
  • adapter 的基本形式是一个两层的前馈网络,其中第一层将输入从 hidden_size 降维到 bottleneck_size,第二层将输出从 bottleneck_size 升维到 hidden_size。这样可以保证 adapter 的输出与原始 Transformer 层的输出具有相同的维度,从而可以进行残差连接¹²。
  • 举个例子,假设我们要对一个自注意力层进行 adapter 微调,该层的输入为 Q Q Q, K K K, V V V,输出为 Z Z Z。我们可以在输入端或者输出端插入一个 adapter 层,例如:

Q ′ = Q + a d a p t e r ( Q ) Q'=Q+\mathrm {adapter} (Q) Q=Q+adapter(Q)

K ′ = K + a d a p t e r ( K ) K'=K+\mathrm {adapter} (K) K=K+adapter(K)

V ′ = V + a d a p t e r ( V ) V'=V+\mathrm {adapter} (V) V=V+adapter(V)

然后使用 Q ′ Q' Q, K ′ K' K, V ′ V' V 来计算自注意力的输出 Z Z Z。或者:

Z ′ = Z + a d a p t e r ( Z ) Z'=Z+\mathrm {adapter} (Z) Z=Z+adapter(Z)

然后使用 Z ′ Z' Z 作为自注意力的输出。

  • 这些方法都会引入推理时延,因为 adapter 层需要额外的计算和通信。具体来说,adapter 层需要计算两次矩阵乘法和两次激活函数,并且需要与原始 Transformer 层进行残差连接。这些操作都会增加推理时延,尤其是在大规模的预训练模型和下游任务上。

¹: Houlsby, N., Giurgiu, A., Jastrzebski, S., Morrone, B., de Laroussilhe, Q., Gesmundo, A., … & Gelly, S. (2019). Parameter-efficient transfer learning for NLP. arXiv preprint arXiv:1902.00751.

²: Pfeiffer, J., Rücklé, A., Eger, S., & Gurevych, I. (2020). AdapterHub: A framework for adapting transformers. arXiv preprint arXiv:2007.07779.

Source: Conversation with Bing, 2023/6/12
(1) Compacter: Efficient Low-Rank Hypercomplex Adapter Layers. https://arxiv.org/abs/2106.04647.
(2) Parameter-Efficient Transfer Learning for NLP - arXiv.org. https://arxiv.org/pdf/1902.00751.pdf.
(3) Adapters for Generative and Seq2Seq Models in NLP. https://adapterhub.ml/blog/2021/04/adapters-for-generative-and-seq2seq-models-in-nlp/.
(4) Adapters: A Compact and Extensible Transfer Learning … https://medium.com/dair-ai/adapters-a-compact-and-extensible-transfer-learning-method-for-nlp-6d18c2399f62.

那 lora 是不是也会引入推理时延?

不会。LoRA 是不会引入推理时延的,因为 LoRA 不会改变预训练模型的结构和计算流程。具体来说,LoRA 只是在预训练模型的权重矩阵上加上一个低秩矩阵,而这个低秩矩阵可以在训练时就计算好,并且与原始权重矩阵相加,得到一个新的权重矩阵。这样,在推理时,就不需要额外的计算和通信,只需要使用新的权重矩阵进行原始 Transformer 层的计算即可。因此,LoRA 是不会引入推理时延的,这也是它与 adapter 的一个优势。

lora 相对于只微调模型最后的输出层(freeze)的异同

  • LoRA 是在预训练模型的每一层 Transformer 中注入可训练的低秩矩阵,而 freeze 是只在预训练模型的最后一层添加一个可训练的输出层。
  • LoRA 的可训练参数数量取决于低秩矩阵的秩,而 freeze 的可训练参数数量取决于输出层的大小。一般来说,LoRA 的可训练参数数量会比 freeze 少很多。
  • LoRA 的模型质量与完全微调相当或者更好,而 freeze 的模型质量通常会比完全微调差很多。这是因为 LoRA 可以更好地利用预训练模型的各层信息,而 freeze 只能利用预训练模型的最后一层信息。
  • LoRA 的推理时延与完全微调和 freeze 相同,而 adapter 和 prefix-tuning 的推理时延会比完全微调和 freeze 大很多。这是因为 LoRA 不会改变预训练模型的结构和计算流程,而 adapter 和 prefix-tuning 会增加额外的计算和通信。
  • LoRA 和 freeze 都是为了降低大模型微调和部署的成本,使得大模型可以在有限的硬件资源和预算下适应特定的下游任务或者领域。
  • LoRA 和 freeze 都是基于一个假设,即预训练模型在适应下游任务时,其权重更新具有低秩或者稀疏的特性。也就是说,只需要少量的参数就可以实现较大的性能提升。

Source: Conversation with Bing, 2023/6/12
(1) Using LoRA for Efficient Stable Diffusion Fine-Tuning … https://huggingface.co/blog/lora.
(2) What is the difference between LoRa and LoRaWAN … https://www.techtarget.com/searchnetworking/answer/What-is-the-difference-between-LoRa-and-LoRaWAN.
(3) LoRA: Low-Rank Adaptation of Large Language Models. https://github.com/microsoft/LoRA.

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值