PEFT 详解

参数高效微调方法详解

PEFT 详解

一、概览

PEFT(Parameter-Efficient Fine-Tuning)是一个用于高效地将预训练模型适配到各种下游应用的方法族,无需对模型的所有参数进行微调。PEFT 方法仅微调少量(额外的)模型参数——显著降低了计算和存储成本——同时取得了与完全微调模型相当的性能。这使得在消费级硬件上训练和存储大型语言模型(LLM)更加容易。

PEFT 方法家族包括:

  • LoRA 系列:通过低秩分解实现参数高效微调
  • QLoRA:结合 4-bit 量化和 LoRA
  • 提示方法:Prefix Tuning、Prompt Tuning 等

二、LoRA 系列

2.1 LoRA:低秩适配

问题背景与动机

核心问题

  • 随着模型规模增大(GPT-3 175B+),全量微调变得不可行:存储成本高、训练资源消耗大
  • 传统适配器(Adapter)引入额外推理延迟
  • 提示微调(Prompt Tuning)优化困难,性能随可训练参数非单调变化

LoRA 的解决方案:核心假设是模型适应过程中的权重变化 ΔW 具有低"内在秩"(intrinsic rank)。

理论基础:Li et al. (2018) 和 Aghajanyan et al. (2020) 研究表明,尽管预训练模型是过参数化的,但针对特定任务适应时,权重矩阵的实际变化存在于较低的内在维度上。

核心机制

冻结预训练权重 W₀ ∈ ℝ^(d×k),引入低秩分解矩阵:

h = W₀x + ΔWx = W₀x + (α/r)BAx

其中:

  • A ∈ ℝ^(r×k),B ∈ ℝ^(d×r),r ≪ min(d,k)
  • α 为缩放因子,控制 LoRA 对原始权重的影响强度
  • 实际缩放比例:α/r(通常设置 α = 2r)
关键超参数
参数 作用 常用设置
r (rank) 低秩维度,控制参数量和表达能力 4, 8, 16, 32, 64
lora_alpha 缩放因子,调节 LoRA 影响强度 通常设为 2*r
target_modules 注入 LoRA 的目标模块 根据架构选择
lora_dropout LoRA 层的 dropout 率 0.0 - 0.1
bias 是否训练偏置项 "none", "all", "lora_only"
初始化策略(关键!)
# lora_A: Kaiming 均匀初始化(标准 Linear 层初始化)
self.lora_A = nn.Linear(in_features, r)
nn.init.kaiming_uniform_(self.lora_A.weight, a=math.sqrt(5))

# lora_B: 零初始化(确保训练初期不改变原始模型行为)
self.lora_B = nn.Linear(r, out_features)
nn.init.zeros_(self.lora_B.weight)

为什么 B 要零初始化?

  • 训练开始时:ΔW = B · A = 0,模型输出等价于原始预训练模型
  • 保证训练稳定性,从基线模型开始渐进学习
目标模块选择策略
配置 适用场景 说明
Wq + Wv (经典) 通用任务,资源受限 论文推荐,性价比最优
仅 Wq 极低资源场景 参数量最小,性能尚可
Wq + Wk + Wv 复杂注意力任务 需要更精细控制时
全部四个 (Q,K,V,O) 追求极致性能 参数量翻倍,收益递减
加入 Wo 特定架构(如 LLaMA) 视模型架构而定

注意:原论文发现 Wq+Wv 组合在参数效率和性能间达到最佳平衡。这不意味着 Wk "与预训练分布耦合紧密",而是实验观察到的收益递减现象。

核心优势:权重合并

训练阶段:h = W₀x + (α/r)BAx(并行计算)

推理阶段:可将 LoRA 权重合并回原矩阵:

W_merged = W₀ + (α/r)BA

合并后的优势:

  • 零额外推理延迟(与原始模型完全等价)
  • 零额外显存开销
  • 这是 LoRA 相比 Adapter 的关键优势
代码实践
from peft import get_peft_model, LoraConfig

# 1. 定义配置
lora_config = LoraConfig(
    r=8,                        # 低秩维度
    lora_alpha=32,                # 缩放因子(通常 = 2*r)
    target_modules=["q_proj", "v_proj"],  # 目标模块(LLaMA系列)
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

# 2. 包装模型
model = get_peft_model(base_model, lora_config)

# 3. 训练后合并权重(部署优化)
merged_model = model.merge_and_unload()  # 合并LoRA权重到基模型
LoRA 总结
维度 LoRA 特点
参数效率 可训练参数减少 10,000 倍(GPT-3 175B)
显存效率 GPU 显存需求降低 3 倍(vs 全量微调)
训练吞吐 高于 Adapter,接近全量微调
推理延迟 零额外延迟(权重合并后)
模型质量 与全量微调持平甚至更好
部署便利 支持动态切换、权重合并、量化兼容

2.2 QLoRA:量化 + LoRA

QLoRA 是一种参数高效微调方法,通过将预训练模型量化为 4-bit(NF4 格式)并结合低秩适配器,使得在单张消费级显卡上就能微调数百亿参数的大模型,且性能接近全量微调。

核心特性

  • 预训练模型的 4-bit 版本在训练全程持久保存在显存中
  • 计算时反量化为 16-bit 参与梯度计算
  • 梯度只更新 LoRA 适配器
  • 预训练模型始终保持 4-bit 冻结状态
4-bit NormalFloat (NF4)

核心思想:神经网络权重通常呈正态分布,NF4 利用这一特性,设计了一种信息论最优的量化格式。

实现步骤

  1. 分块量化:将权重张量分成小块(每块 64 或 256 个权重)
  2. 计算块统计量:计算每块的均值 μ 和标准差 σ
  3. 归一化:将权重映射到标准正态空间 N(0,1):x_norm = (x - μ) / σ
  4. 分位数量化:使用预计算的 N(0,1) 的 16 个等概率分位点进行查表量化
  5. 存储:存储 4-bit 索引,以及 μ 和 σ(后者再被二次量化)

名称含义

  • Normal:针对正态分布优化
  • Float:每个 4-bit 编码对应一个浮点数值(而非整数)

三、提示方法

3.1 Prefix Tuning

痛点与目标

痛点:对大型预训练语言模型(如 GPT-2、BART)进行全参数微调时,每个下游任务都需要存储一份完整的模型副本(例如 GPT-2 有 7.74 亿参数)。当任务数量增多时,存储开销极大。

目标:提出一种轻量级的替代方案,冻结大部分预训练参数,只引入少量可训练参数,同时保证在生成任务上的性能接近甚至超越全参数微调。

直觉来源
  • Prompting(提示) 启发——通过给模型添加合适的上下文(如"TL;DR"表示摘要),可以引导模型完成特定任务,而无需修改模型参数
  • 离散的、由自然语言构成的提示(如"请总结以下内容")对预训练模型效果有限,且离散优化困难
方法

在输入序列前添加一系列可学习的任务特定向量,同时保持预训练模型冻结。前缀参数被插入到模型的所有层中。

  • 在输入序列的最前面添加一组连续的、可训练的虚拟向量,称为 Prefix(前缀)
  • 前缀会参与到每一层 Transformer 的注意力计算中,被放在每个 multi-head attention 的 key 矩阵和 value 矩阵之前
  • 特征向量长度未变,相当于增加了原始的 token 和这些 soft prompt token 计算相似度,然后聚合
  • 训练时,冻结原始语言模型参数仅优化前缀参数
实验证实

离散提示 < Embedding-only 软提示 < Prefix-Tuning(每层)

3.2 Prompt Tuning

Prompt Tuning 给每个任务定义了自己的 Prompt,拼接到数据上作为输入,同时 freeze 预训练模型进行训练。在没有加额外层的情况下,可以看到随着模型体积增大效果越来越好,最终追上了精调的效果。

Prompt Tuning 还提出了 Prompt Ensembling,也就是在一个 batch 里同时训练同一个任务的不同 prompt,这样相当于训练了不同"模型",比模型集成的成本小多了。

Prompt Tuning vs Prefix Tuning
维度 Prompt Tuning Prefix Tuning
提出时间 2021 年(Google) 2021 年(斯坦福/清华)
训练位置 仅输入嵌入层 每一层的 Key/Value
参数量 更少(通常 20-100 个 token) 稍多(每层都有前缀)
模型侵入性 无侵入,完全冻结模型 需修改注意力机制
实现复杂度 更简单 较复杂
重参数化 不需要 需要 MLP 生成前缀
小模型表现 需要较大模型(>10B)才有效 中小模型也能工作
大模型表现 随着模型增大,差距缩小 始终稳定

四、总结

PEFT 方法族为大模型的高效微调提供了多种选择:

  • LoRA:最通用、最实用,支持权重合并,零推理延迟
  • QLoRA:在 LoRA 基础上加入 4-bit 量化,进一步降低显存需求
  • Prefix Tuning:适合生成任务,每层都有可学习前缀
  • Prompt Tuning:最简洁的方法,仅在输入层添加可学习向量

选择哪种方法取决于具体的任务需求、硬件约束和性能要求。在实践中,LoRA 因其简单高效而成为最流行的选择。

← 返回 3. Post-training