此博客为Datawhale 组队学习打卡笔记


PEFT 技术综述

当模型参数规模从 BERT 的数亿级别跃升至 GPT-3 的千亿级别时,传统的全量微调(Full Fine-Tuning)遇到了挑战:

  • 高昂的训练成本
  • 巨大的存储压力
  • 灾难性遗忘:在针对特定任务进行微调时,模型很可能会“忘记”在预训练阶段学到的海量通用知识,损害其泛化能力。
  • 训练不稳定性:大模型的网络结构“又宽又深”,其训练过程对学习率等超参数极为敏感,很容易出现梯度消失/爆炸等问题,导致训练失败。
  • 参数高效微调(PEFT):核心思想:冻结(freeze) 预训练模型 99% 以上的参数,仅调整其中极小一部分(通常<1%)的参数,或者增加一些额外的“小参数”,从而以极低的成本让模型适应下游任务。

PEFT 技术发展脉络

  • Adapter Tuning。 Adapter 模块自身的结构

    • 一个“降维”的全连接层(Feedforward down-project),将高维特征映射到低维空间。
    • 一个非线性激活函数(Nonlinearity)。
    • 一个“升维”的全连接层(Feedforward up-project),再将特征映射回原始维度。
    • 一个贯穿该模块的残差连接,将模块的输出与原始输入相加,保证信息流的稳定。
  • Prefix Tuning

    • 为了达到更好的效果,Prefix Tuning 不仅在输入层添加前缀,还在 Transformer 的每一层都添加了对应的可学习 Prefix,并通过一个小型的前馈网络(MLP)来生成这些参数。
    • 较高的参数效率;显存友好;通用性强
    • 训练不稳定,直接优化 Prefix 向量比微调 Adapter 更困难,对超参数和初始化较为敏感。
    • 占用上下文长度
  • Prompt Tuning

    • Prefix Tuning 的一个简化版;只在输入的 Embedding 层添加可学习的虚拟 Token(称为 Soft Prompt)
    • 它的成功强依赖于模型的规模,在中小型模型上效果不佳
  • P-Tuning v1

    • 解决离散提示(Discrete Prompts) 的“不稳定性”问题,添加可学习的Embedding
    • 在较小模型上收益有限,而在更大模型上更稳定、更具优势),并且在一些复杂的自然语言理解(NLU)任务(特别是序列标注)上表现不佳。
  • P-Tuning v2

    • 引入深层提示(Deep Prompts):最核心的改进。借鉴了 Prefix Tuning 的思想,在 Transformer 的每一层都添加了可学习的提示
    • 摒弃 Verbalizer:Verbalizer建立 label ↔ word(s) 的映射关系。P-Tuning v2 移除了对任务高度敏感的 Verbalizer,回归到传统微调的方式,在模型顶层增加一个随机初始化的线性分类头输出类别;而在生成式任务中,仍通过语言模型头进行生成。这样既能轻松处理序列标注等复杂任务,又增强了通用性。

LoRA 方法详解

低秩近似的核心思想

  • 假设:大语言模型是过参数化的(Over-parametrized),它们在针对特定任务进行微调时,权重更新矩阵 ΔW 具有一个很低的“内在秩”(Intrinsic Rank)。
    LoRA 的核心思想就是用两个更小的“低秩”矩阵 A A A B B B 的乘积,来模拟(近似)这个庞大的更新矩阵 Δ W ΔW ΔW

Δ W = B ⋅ A \Delta W = B \cdot A ΔW=BA

初始化与缩放技巧

  • 初始化:如图 11-7 所示,旁路矩阵有特殊的初始化方式。矩阵 A 通常使用高斯分布进行随机初始化( A = N ( 0 , σ 2 ) A = \mathcal{N}(0, \sigma^2) A=N(0,σ2) ),而矩阵 B 则初始化为全零( B = 0 B=0 B=0 )。这样做可以确保在训练开始时,旁路输出为零,微调是从原始的预训练模型状态开始的,保证了训练初期的稳定性。
  • 缩放:LoRA 的前向计算公式会包含一个缩放因子 s s s: h = W 0 ⋅ x + s ⋅ ( B ⋅ A ) ⋅ x h = W_0 \cdot x + s \cdot (B \cdot A) \cdot x h=W0x+s(BA)x。这个 s s s 通常设为 α / r \alpha/r α/r,其中 α \alpha α 是一个可调超参。这个缩放操作有助于在调整秩 r r r 时,减少对学习率等其他超参数的重新调整需求,让训练过程更稳定。
  • 优势

    • 更高的参数与存储效率
    • 零额外推理延迟:LoRA 的旁路结构在训练完成后,可以通过矩阵加法 ( W ′ = W 0 + s ⋅ B ⋅ A ) (W' = W_0 + s \cdot B \cdot A) (W=W0+sBA) 直接“合并”回原始权重中。模型的网络结构与原始模型完全一致。
    • 效果媲美全量微调,且不占用输入长度
    • 良好的可组合性:LoRA 的设计是 正交的,它可以与 Prefix-Tuning 等其他 PEFT 方法结合使用,取长补短,进一步提升模型性能。
  • 关键实践

    • 仅在注意力模块中应用 LoRA,并冻结模型的其余部分
    • 秩 r 的选择不是越大越好
    • 学习到的是那些在预训练中学习到但未被充分强调、却对下游任务至关重要的“隐藏特征”,并对其进行大幅放大

AdaLoRA 自适应微调

  • 所有矩阵和所有层级设置一个统一的、固定的秩 r,远非最优解
  • 根据权重的重要性,动态地、有选择地为不同模块分配参数预算

基于 SVD 的参数化

不再是使用两个简单的矩阵 B ⋅ A B \cdot A BA,而是引入了经典的奇异值分解 (SVD) 思想来参数化更新矩阵 Δ W \Delta W ΔW

Δ W = P Λ Q \Delta W = P \Lambda Q ΔW=PΛQ

两大好处:

  1. 避免了高昂的计算成本:它只是在形式上模拟了 SVD,在训练时 P , Λ , Q P, \Lambda, Q P,Λ,Q 都是可训练的参数,并不需要对 Δ W \Delta W ΔW 进行真正的、计算开销极大的 SVD 分解。
  2. 结构化的重要性:这种分解将 Δ W \Delta W ΔW 的更新信息解耦为三个部分: P P P Q Q Q 决定了更新的“方向”,而 Λ \Lambda Λ 中的奇异值 λ i \lambda_i λi 则决定了在对应方向上的更新“幅度”。这使得我们可以通过调整奇异值的大小来直接控制每个“更新分量”的重要性,也即调整矩阵的秩。

为确保 P P P Q Q Q 在训练中保持正交性(这是奇异向量的性质),AdaLoRA 还在训练损失中加入了一个正交正则化项,以保证分解的稳定性和有效性。

重要性评分与动态预算分配

  • 每个奇异值和其对应的左右奇异向量组合成一个“三元组”
  • 根据参数自身大小与其梯度,计算重要性评分
  • 预设的参数预算(总秩),裁剪掉那些得分最低的三元组

全局预算调度器与目标函数

  • 全局预算调度器
    • 热身阶段 ( 0 ≤ t < t i 0 \le t < t_i 0t<ti):从一个比目标预算 b ( T ) b^{(T)} b(T) 略高的初始预算 b ( 0 ) b^{(0)} b(0) 开始训练,让模型有更充分的机会去“探索”所有参数的潜在重要性。
    • 裁剪阶段 ( t i ≤ t < T − t f t_i \le t < T-t_f tit<Ttf):按照一个三次方的调度曲线,逐步地裁剪掉重要性分数较低的奇异值,将预算平滑地降低到最终的目标值
    • 微调阶段:在预算分配基本稳定后,固定预算为 b ( T ) b^{(T)} b(T)(即锁定了最重要的参数),继续对模型进行微调直至收敛。

QLoRA 参数压缩

  • 4-bit NormalFloat (NF4)
    • 被证明是一种 信息论上最优 的数据类型,其设计哲学基于“分位数量化(Quantile Quantization)”
    • 分位数量化旨在让每个量化“桶”中,都包含相同数量的来自目标分布的值
  • 双量化 (Double Quantization)
    • 上述量化过程需要为每一组(block)权重存储一个对应的“量化常数”(通常是 32-bit 的浮点数)。 双量化的思想是,对这些量化常数本身,再进行一次量化。
  • 分页优化器 (Paged Optimizers):内存管理

基于 peft 库的 LoRA

参考

[1] https://datawhalechina.github.io/base-llm

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐