大模型微调系列01 Lora

255 阅读10分钟

LoRA技术详解:大模型高效微调的革命性方法 - 知乎
一文了解Lora的理论和具体代码实现细节 - 知乎
microsoft/LoRA: Code for loralib, an implementation of "LoRA: Low-Rank Adaptation of Large Language Models"

Lora 是什么?

image.png Lora 的全称是 LOW-RANK ADAPTATION 低秩自适应,是革命性的微调技术。通过使用Lora微调技术,可以在极小的训练成本下(原本的1/100不到),得到不同风格的模型。 image.png

传统微调的困境

随着预训练模型规模的爆炸性增长,我们面临着几个核心挑战:

  • 计算资源壁垒:以GPT-3(1750亿参数)为例,全参数微调需要数百GB的GPU内存,即使使用模型并行和混合精度训练,仍需多台高端GPU
  • 优化器开销:使用Adam等自适应优化器时,每个参数需额外存储两个状态向量(一阶矩和二阶矩),使实际内存需求达到模型大小的3倍以上
  • 梯度计算:全参数微调需为每个参数计算和存储梯度,计算密集且内存占用大
  • 灾难性遗忘:在小数据集上微调大模型时,容易过拟合并丢失预训练获得的通用能力

LoRA的数学原理

LoRA 的核心思想是:

  • 将预训练模型的权重矩阵 W 分解为两个低秩矩阵 A 和 B(这个 A 和 B 也被称为Lora层,原本不存在),
  • 只微调这些低秩矩阵,而不是整个权重矩阵。
  • 更新的时候通过公式WW+AB W≈W​+A⋅B更新,我们只用计算A和B的梯度,不用计算整个W的。这样减少了参数量。

image.png

1. 低秩分解(Low-Rank Decomposition)

低秩分解是一种数学技术,用于将一个矩阵分解为两个或多个较小的矩阵的乘积。对于一个矩阵 W∈Rm×nW∈Rm×n,低秩分解可以表示为:

W=ABW=A⋅B

其中:

  • W的参数是m×nW的参数是 m×n
  • A的参数是m×rA的参数是 m×r
  • B的参数是r×nB的参数是 r×n
  • r 是秩(rank)。

通过这种分解,原始的 m×n 矩阵 W 被近似为两个较小的矩阵 A 和 B 的乘积,从而减少了参数的数量。

2. 秩(Rank)

秩(rank)是矩阵的一个重要属性,表示矩阵中线性无关的行或列的最大数量。在低秩分解中,秩 r 决定了分解后矩阵的大小和复杂度:

  • 较小的秩:分解后的矩阵更小,参数更少,计算效率更高,但可能丢失一些信息。
  • 较大的秩:分解后的矩阵更大,参数更多,计算成本更高,但能更好地近似原始矩阵。

2.1 最优的秩

image.png

在 LoRA 中,秩 r 是一个超参数,需要在模型性能和计算成本之间进行权衡。

2.2 矩阵A 和 B的初始化

image.png

image.png

3. LoRA 的工作原理

LoRA 的核心思想是将预训练模型的权重矩阵 W 分解为两个低秩矩阵 A 和 B,并只微调这些低秩矩阵,而不是整个权重矩阵。具体步骤如下:

步骤 1:插入低秩矩阵
  • 在预训练模型的某些层(如注意力层的权重矩阵)中插入低秩矩阵 A 和 B。
  • 原始权重矩阵 W 被冻结(不更新),而低秩矩阵 A 和 B 是可训练的。
步骤 2:前向传播
  • 在前向传播过程中,原始权重矩阵 W 被替换为 W+A⋅BW+A⋅B。
  • 这样,模型的输出可以表示为:

y=(W+AB)xy=(W+A⋅B)⋅x

其中 x 是输入,y 是输出。

步骤 3:反向传播
  • 在反向传播过程中,只更新低秩矩阵 A 和 B 的参数,而原始权重矩阵 W 保持不变。

image.png

步骤 4:微调
  • 通过微调低秩矩阵 A 和 B,模型可以适应新的任务,同时保持预训练模型的大部分知识。

低秩分解的物理意义

矩阵的秩 r 反映了其内在的“信息冗余度”。如果矩阵的秩远小于其维度,说明它可以通过更少的参数(低秩矩阵)来近似表示。例如:

  • 自然语言处理:预训练模型的权重矩阵中可能包含大量冗余信息(如通用语言特征),低秩分解可以提取核心特征。
  • 计算机视觉:图像的特征表示通常具有空间冗余性,低秩分解能有效压缩信息

Lora 和全量微调的对比

维度Full Fine-tuning(全参数微调)LoRA(低秩适应)联系
参数更新范围更新预训练模型的所有参数。仅更新注入的低秩矩阵(A 和 B),原始模型参数冻结。两者均通过调整参数使模型适配下游任务,但 LoRA 是参数高效微调(PEFT)的一种实现。
资源消耗显存占用高,计算成本大(需存储并更新所有参数的梯度)。显存和计算量大幅降低(仅需更新 0.1% - 1% 的参数)。目标一致,但 LoRA 通过压缩参数更新量优化资源效率。
灾难性遗忘容易因过度拟合新任务而遗忘预训练知识。原始参数固定,仅通过旁路矩阵调整输出,保留更多预训练知识。均需平衡新任务性能与预训练知识保留,但 LoRA 天然缓解遗忘问题。
训练速度较慢(需更新大量参数)。更快(仅优化少量参数,梯度计算量小)。训练目标相同,但 LoRA 通过减少参数加速收敛。
应用场景资源充足、任务复杂(如数据分布与预训练差异极大)。资源有限、任务轻量(如单卡训练、快速迭代或多任务适配)。均为适配下游任务的微调方法,但适用场景不同。
灵活性模型完全适配新任务,但难以复用。模块化设计,不同任务可独立训练 LoRA 权重并灵活切换。LoRA 通过解耦适配层实现更高灵活性,而 Full Fine-tuning 绑定任务。
推理效率直接使用微调后的模型,无额外计算。推理时可合并 W' = W + BA ,与原始模型计算量相同。最终推理效果等价,但 LoRA 需额外合并步骤(可选)。

面试常见问题

  1. Lora的出发点和优势
  2. Lora的原理
  3. Lora增加多少计算量,减少了多少参数
  4. Lora在反向传播过程中什么省不了
  5. Lora的劣势

相关问题的回答:

LoRA的出发点和优劣势

出发点: LoRA的出发点在于为大型预训练模型的高效微调提供一种有效方案。在自然语言处理等领域,预训练模型通常规模庞大,参数众多。直接对整个模型进行微调不仅计算资源消耗大,而且容易导致过拟合等问题,尤其是当目标任务数据量相对较少时。LoRA通过引入低秩近似的方法,对模型中的权重矩阵进行分解和适应性调整,使得在微调过程中只需更新少量参数,从而在降低计算成本和资源消耗的同时,仍能保持模型在目标任务上的性能提升。

优势

  • 参数高效:相比全参数微调,LoRA仅需学习和更新低秩矩阵中的少量参数,大大减少了需要优化的参数数量,降低了模型过拟合的风险,尤其适用于目标任务数据有限的情况。
  • 计算资源友好:由于参数量的减少,LoRA在训练和推理过程中所需的计算资源也相应减少,包括显存占用和计算时间,使得在资源受限的设备上进行模型微调和部署成为可能。
  • 性能保持:尽管参数量大幅减少,但LoRA能够在多种自然语言处理任务上取得与全参数微调相当甚至更好的性能,有效利用了预训练模型中已有的知识,通过低秩矩阵的适应性调整,精准地捕捉目标任务的相关特征和模式。
  • 灵活性和通用性:LoRA可以应用于各种基于Transformer架构的预训练模型,如BERT、GPT等,无需对模型架构进行大规模修改,是一种通用的模型微调方法,能够根据不同的目标任务和数据特点灵活调整低秩矩阵的维度等超参数。

劣势
表达能力受限

  • 低秩近似限制:LoRA通过低秩矩阵分解来近似原始权重矩阵的变化,这种方法虽然减少了参数量,但也可能丢失一些细微但重要的模式和特征,无法完全还原原始权重矩阵的复杂性,从而限制了模型的表达能力和性能上限。
  • 特定任务适应性不足:在一些对模型表达能力要求极高的复杂任务中,如多轮对话、文本生成等,LoRA可能无法像全参微调那样充分挖掘模型的潜力,导致模型在处理这些任务时表现不够理想。

LoRA的计算量和显存相比全量微调的变化

1. 全量微调的显存计算

假设权重矩阵 WR10×10 W∈R10×10,参数总量 10×10=100。
全量微调需要存储以下内容:

  • 参数本身:100 单位(存储 W 的当前值)。
  • 梯度:100 单位(反向传播时计算的 ∇W)。
  • 优化器状态:200 单位(例如 Adam 优化器需要存储动量 m 和方差 v,各占 100 单位)。

因此,总显存占用为:

100 (参数)+100 (梯度)+200 (优化器状态)=400 单位100(参数)+100(梯度)+200(优化器状态)=400单位

简写为公式:4×100=400。

2. LoRA 的显存计算

LoRA 冻结原始参数 W,仅训练两个低秩矩阵 AR10×2A∈R10×2 和 BR2×10B∈R2×10,总参数量为:

10×2+2×10=20+20=40

LoRA 需要存储以下内容:

  • 原始冻结参数 WW:100 单位(仅存储值,无梯度或优化器状态)。
  • LoRA 参数 A,B:40 单位。
  • LoRA 梯度:40 单位(反向传播时计算的 ∇A 和 ∇B)。
  • LoRA 优化器状态:80 单位(Adam 的动量 m 和方差 v,各占 40 单位)。

因此,总显存占用为:

100 (冻结参数)+(40+40+80) (LoRA 部分)=100+160=260 单位100(冻结参数)+(40+40+80)(LoRA 部分)=100+160=260单位

简写为公式:10×10+4×40=260。

3. 关键对比
阶段全量微调LoRA差异说明
前向传播100100 + 40 = 140LoRA 需额外存储低秩矩阵 A,B
反向传播30040 + 80 = 120LoRA 仅需更新低秩矩阵的梯度和优化器状态
4. 简单总结
  • 原本矩阵是 m * m, A矩阵是m * R B矩阵是R * m
  • 向前传播
    • 原本:m * m
    • Lora:m * R * 2
  • 反向转播
    • 原本:m * m * (1+1+2)(原本参数+梯度+优化器)
    • Lora:m * R * 2 * (1+1+2)(Lora参数+梯度+优化器)
  • 总显存占用
    • 原本:m * m * (1+1+2)(原本参数+梯度+优化器)
    • Lora:m * m + m * R * 2 * (1+1+2)【原本参数+(Lora参数+梯度+优化器)】
  • 总结:
    • 全量微调:原始参数的值、梯度、优化器状态均需存储,总显存为 4N。
    • LoRA:仅存储原始参数的值,省去梯度和优化器状态,新增低秩矩阵的存储,总显存为 N+4MN(M≪N)。