从零开始讲解LoRA——大语言模型的PEFT(Parameter-Efficient Fine-Tuning)系列

一、引言

        LoRA(Low-Rank Adaptation Of Large Language Model),是一种大语言模型的低秩自适应方法。LoRA 在保持预训练模型的权重不变的情况下,通过给做下游微调任务的模型注入可以训练的秩分解矩阵。通过这种方式,可以使预训练模型在下游的微调任务当中,不用去学习全量的训练参数,因此大大降低了模型的训练参数量,同时降低了GPU内存的需求。

        LoRA已经证实了在RoBERTa,DeBERTa,GPT系列模型以及一系列的LLM中证明了自己的效果。在175B 的GPT3使用Adam 的微调学习中,LoRA能降低10000倍的训练参数,同时GPU内存使用降低了三倍。在RoBERTa、DeBERTa、GPT-2和GPT-3上,LoRA在模型质量方面表现与微调相当或更好,LoRA具有更少的可训练参数、更高的训练吞吐量,且与适配器不同,它没有额外的推理延迟。

二、LoRA的具体实现

        LoRA 的具体实现可以参照上图,这也是LoRA论文中的说明图,非常的简洁而且易懂。LoRA 把预训练模型的权重冻结,将微调阶段学习到的权重的增量部分进行矩阵的秩分解,将秩分解后的矩阵A与B注入到模型的Transformer架构的每一层中。

        具体来说,对于预训练模型的transformer结构中的学习权重 W_{_{0}}\in R^{d \times k},LoRA 可以通过以下的方式来实现其权重的更新W_{0}x +\triangle W = W_{0}x + BA,其中B\in R^{d \times r}A\in R^{r \times k}。且秩r\ll min(d,k)。其中,W_{0}参数在学习中是被冻结的,更新的部分是\triangle W,通过LoRA转化为BA

        为什么秩r 需要远小于d和k?那是因为我们要更新的权重\triangle W的参数量为d*k个。而我们通过LoRA,把更新的那部分\triangle W转化为了BA。更新的参数量因此从d*k 转化为了 B的参数量 + A的参数量,即 d * r + r *k 个参数。因此,当 秩r 需要远小于d和k 时,我们可以大幅度的降低更新的参数量。

        同时,我们把模型的反馈函数转化为了:

                        h = W_{0}x +\triangle Wx = W_{0}x + BAx

三、关于LoRA的一些问题

问题1:LoRA用在模型的什么地方?

:LoRA 用在预训练模型的Transformer架构上的每一层。注意,是每一层!LoRA的主要思想是在预训练模型的每一层中保持训练前权重不变,同时在每一层中注入可训练的秩分解矩阵,从而大大减少了针对下游任务的可训练参数数量。因此,不管是Transformer的FFN,还是attention,都会注入LoRA的秩分解矩阵。

问题2:如何确定适当的秩分解矩阵大小?

答:确定适当的秩分解矩阵大小(即LoRA的秩r)需要考虑以下几点:

  1. 性能:选择合适的秩分解矩阵大小以实现理想的模型性能。在实验中,即使使用很小的r(例如1或2),LoRA仍然可以与完全微调相媲美,甚至表现更好。

  2. 子空间相似性:检查不同秩选择和不同随机种子下学习到的子空间之间的相似性。增加r并不能涵盖更有意义的子空间,这表明低秩适应矩阵就足够了。

  3. 适应矩阵与预训练权重的关系:研究适应矩阵∆W与预训练权重W之间的关系。∆W与W之间的相关性可以帮助了解适应预训练语言模型的机制。

        综上所述,选择适当的秩分解矩阵大小需要在性能、子空间相似性和适应矩阵与预训练权重的关系等方面进行综合评估。

问题3:LoRA(Low-Rank Adaptation)相对于其他自适应方法具有哪些优势?

答:

  1. 存储和计算效率:LoRA通过优化训练过程中权重更新的低秩分解矩阵,大大减少了可训练参数的数量,从而降低了存储和计算需求。

  2. 无需额外的推理延迟:与适配器层不同,LoRA在训练过程中并行地添加可训练的低秩矩阵,因此不会引入额外的推理延迟。

  3. 高度可组合性:LoRA可以与许多现有方法(如前缀调整)结合使用,进一步提高模型的效果和效率。

  4. 快速任务切换:LoRA允许在共享大部分模型参数的情况下快速切换任务,从而降低了存储需求和任务切换开销。

  5. 与模型质量相当或更好的表现:尽管LoRA具有较少的可训练参数、更高的训练吞吐量和与适配器不同的无额外推理延迟,但在RoBERTa、DeBERTa、GPT-2和GPT-3上的表现与完全微调相当或更好。

参考资料

1. https://arxiv.org/abs/2106.09685

### 大模型微调概述 大模型微调是指通过特定的技术手段,在预训练好的大规模语言模型(LLM)基础上进一步调整其参数,使其更好地适应特定任务或领域的需求。这种方法不仅能够显著减少重新训练整个模型所需的计算资源,还能提高模型在目标应用场景中的性能。 #### 微调方法分类 1. **全量微调 Full Finetuning** 这种方式涉及更新模型中所有的权重参数,尽管效果较好,但由于需要大量的数据和算力支持,并不总是最优的选择[^1]。 2. **基于提示的学习 Prompt-based Learning** - **Prompt Tuning**: 只有附加到输入序列上的连续向量是可训练的,而其他部分保持冻结状态。这种方式可以有效地利用少量标注样本实现较好的迁移学习效果[^3]。 3. **参数高效的微调 Parameter-efficient Fine-tuning (PEFT)** - **Low-Rank Adaptation (LoRA)**: 利用低秩分解的思想引入额外的小规模矩阵来近似原网络的变化方向,从而达到轻量化的目的。此策略已被证明可以在多个下游任务上取得接近甚至超越完全微调的效果[^4]。 - **Adapters**: 在原有架构之间插入小型模块——即适配器(Adapter),仅需优化这部分新增组件即可完成定制化改造工作。它同样属于高效且灵活的方法之一。 4. **Prefix Tuning 前缀调优** 通过对输入文本添加一段特殊的嵌入表示作为前置条件,使得模型可以根据不同的上下文环境做出更精准的理解与响应。这种做法既保留了一定程度上的结构变动空间,也提供了一个自动化提升效能的新途径。 ```python import torch.nn as nn class Adapter(nn.Module): def __init__(self, input_dim=768, hidden_dim=128): super().__init__() self.linear1 = nn.Linear(input_dim, hidden_dim) self.relu = nn.ReLU() self.linear2 = nn.Linear(hidden_dim, input_dim) def forward(self, x): z = self.linear1(x) z = self.relu(z) output = self.linear2(z) return output + x # Residual connection ``` #### 应用场景与时机判断 当面临如下情况时考虑实施微调操作可能是明智之举: - 当前可用的数据集较小不足以支撑从零开始构建新模型; - 对现有开源预训练成果进行个性化改进以满足特殊业务需求; - 寻求成本效益更高的解决方案而非投入过多硬件设施去执行端到端再训练过程; 综上所述,针对不同类型的项目背景选取合适的大模型微调方案至关重要,这有助于平衡开发周期、预算限制以及最终产出的质量等多个方面因素的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值