起点论文Parameter-Efficient Transfer Learning for NLP(Houlsby et al., 2019)
核心问题:当基础模型越来越大时,怎样让每个下游任务只学习并保存一小段“变化”,而非复制整套模型?
一句话结论:PEFT 的价值不只是省显存;它把基础模型、领域能力和任务版本拆成了可以独立训练、分发、切换与审计的对象。

结论先行

参数高效微调(Parameter-Efficient Fine-Tuning,PEFT)指的是:冻结预训练模型的大部分或全部参数,只训练占比很小的新增参数或提示参数,以完成领域迁移、指令对齐或特定任务适配。

它解决的是全量微调在大模型时代的三个结构性问题:

  1. 训练成本:梯度、优化器状态和检查点随全模型参数增长;
  2. 服务成本:一个底座服务很多客户或任务时,不能为每个任务常驻一份完整权重;
  3. 版本治理:任务能力应当像代码补丁一样可追溯、可回滚、可组合。

PEFT 不是单一算法,而是一族方法。它们都在回答同一个问题:在冻结的大模型旁边,应该把有限的可学习自由度放在哪里?

方法族在哪里加入可训练参数代表工作强项主要限制
AdapterTransformer 层内插入小瓶颈模块Houlsby Adapter模块边界清晰、迁移性好默认会增加推理路径
Soft Prompt输入嵌入前添加虚拟 tokenPrompt Tuning参数量极低、实现简洁小模型与复杂任务上更不稳定
Prefix / P-Tuning为各层注意力提供可训练前缀Prefix-Tuning、P-Tuning v2生成任务、少样本适配强KV / 序列开销会增加
Low-rank update为线性层权重学习低秩增量LoRA可合并、生态成熟、部署友好目标层与 rank 需调优
Quantized PEFT在量化底座上训练适配器QLoRA大幅降低训练显存训练链路和量化兼容性更复杂

如果没有特殊约束,今天的 LLM 指令微调通常应以 LoRA / QLoRA 为默认起点;但理解 Adapter 论文仍然重要,因为它最早清晰地提出了“共享底座 + 任务小模块”这一产品与系统架构。

1. 为什么全量微调不再是默认答案

设基础模型参数为 WW,一个下游任务训练后得到 WtW_t。全量微调会为任务 tt 保存完整的新权重:

Wt=FineTune(W,Dt)W_t = \operatorname{FineTune}(W, D_t)

当有 NN 个任务时,直观做法需要维护 NN 份完整模型。即使这些任务只改变了模型行为中的一小部分,存储、发布、加载和回滚仍按完整模型规模付费。

PEFT 换了一种表示:保留共享的 WW,只学习任务增量 θt\theta_t

ft(x)=f(x;W,θt),θtWf_t(x) = f(x; W, \theta_t), \qquad |\theta_t| \ll |W|

这个写法包含两个关键假设:

  • 预训练模型已经拥有大量通用语言、知识与推理表征;
  • 下游任务需要的变化,位于相对低维、结构化的子空间中。

它并不声称小参数在所有任务上都等价于全量微调。更准确地说,PEFT 用可控的容量约束换取了更低成本、更易运维和常常足够好的质量。

全量微调
Base Model ──训练──> Task A Model
           └─训练──> Task B Model
           └─训练──> Task C Model

PEFT
Base Model(共享、冻结)
├── Adapter / LoRA A
├── Adapter / LoRA B
└── Adapter / LoRA C

2. 起点论文:Adapter 如何工作

Houlsby 等人在 BERT 的每个 Transformer block 中插入两个小型 Adapter:一个位于注意力子层之后,另一个位于前馈网络之后。原始 BERT 参数冻结,训练时只更新 Adapter、LayerNorm 以及最终任务头。

Adapter 的典型形式是一个带残差连接的瓶颈 MLP:

Adapter(h)=h+Wupσ(Wdownh)\operatorname{Adapter}(h) = h + W_{up}\,\sigma(W_{down}h)

其中 WdownRm×dW_{down} \in \mathbb{R}^{m \times d} 将隐藏状态从 dd 维降到很小的瓶颈维度 mmWupRd×mW_{up} \in \mathbb{R}^{d \times m} 再投影回去,且 mdm \ll d

因此每层增加的可训练参数约为:

2dm2dm

论文在多项 GLUE 任务及文本分类任务上表明:只训练约几个百分点甚至更少的任务参数,能够取得接近全量微调的效果;各任务只需保存自己的 Adapter,而共享同一份 BERT。

2.1 Adapter 的真正贡献

今天看来,Adapter 的模块结构并不复杂,但它建立了三条至今仍成立的原则:

  1. 冻结底座仍可有效迁移:高质量预训练表征不必为每个任务重写;
  2. 任务变化应有独立载体:一个任务的更新可被单独保存和加载;
  3. 容量应显式可控:瓶颈维度就是适配容量的旋钮。

它的缺点也很直接:Adapter 是额外的运行时模块,不能像某些权重增量一样无损地合并回原线性层。对每 token 延迟极端敏感的在线服务,这会是实际成本。

3. 三条技术路线:模块、提示与权重增量

3.1 模块式适配:把能力放进网络内部

Adapter、IA3^3 等方法在网络内部加入少量任务参数。IA3^3 更进一步,不再使用完整小 MLP,而是对注意力的 Key / Value 和前馈层激活做按通道缩放:

kK,vV,ffFFN(x)\ell_k \odot K, \quad \ell_v \odot V, \quad \ell_{ff} \odot \operatorname{FFN}(x)

这类方法参数极省,也适合希望明确控制“哪些计算被任务改变”的场景。代价是实现与推理框架需要认识这些额外结构。

3.2 提示式适配:把能力放进上下文

Prompt Tuning 直接学习一串连续向量 PP,与真实输入嵌入拼接:

[P;E(x)]Frozen Model[P; E(x)] \rightarrow \text{Frozen Model}

Prefix-Tuning 则为每一层注意力提供可训练的 Key / Value 前缀。它不是修改权重,而是改变模型在计算注意力时能看到的“虚拟上下文”。

优势是参数数量可以小到惊人,且对原模型侵入低;挑战在于虚拟 token 并不天然可解释,较小模型、长输出或任务偏移较大时,效果有时不如权重增量稳定。此外,前缀会占用上下文或 KV Cache 预算。

3.3 权重增量:把能力放进一个小补丁

LoRA 把线性层的任务变化表示为低秩矩阵:

W=W+ΔW=W+αrBAW' = W + \Delta W = W + \frac{\alpha}{r}BA

其中 WW 冻结,ARr×dinA \in \mathbb{R}^{r \times d_{in}}BRdout×rB \in \mathbb{R}^{d_{out} \times r} 可训练,且 rr 很小。

这条路线成为 LLM 主流,原因不只是质量好:训练后可以把 BABA 合并进 WW,固定任务的推理路径就恢复为普通线性层;同时适配器权重仍可独立分发,适合模型仓库与多租户服务。

flowchart LR
    X[输入 x] --> W[冻结权重 W]
    X --> A[可训练 A]
    A --> B[可训练 B]
    W --> Add[相加]
    B --> Scale[缩放 α / r]
    Scale --> Add
    Add --> Y[输出]

4. QLoRA:为什么量化改变了 PEFT 的可用范围

LoRA 降低的是可训练参数、梯度与优化器状态,但训练时仍要把基础模型加载进显存。对于几十亿到数百亿参数模型,底座本身仍然是最大门槛。

QLoRA 的思路是:将冻结的基础模型以 4-bit 量化格式存储和计算,同时保持 LoRA 适配器可训练。其关键工程组合包括:

  • NF4:面向近似正态分布权重的 4-bit 数据类型;
  • Double Quantization:进一步量化量化常数,继续压缩内存;
  • Paged Optimizers:用统一内存等机制缓解峰值显存压力;
  • LoRA 更新:梯度只用于小型适配器,而非 4-bit 基础权重。

因此,QLoRA 把问题从“如何少训练参数”扩展为“如何在有限显存中保留足够大的冻结底座”。这使单机或较少 GPU 的高质量领域适配成为现实,但也带来量化内核、精度、吞吐与硬件兼容性的额外验证成本。

5. 如何选择:先识别瓶颈,再选方法

你的主要约束优先选择原因
显存非常有限、要微调较大开源模型QLoRA先解决基础模型驻留显存
固定任务且延迟敏感LoRA 并合并权重可去掉额外推理分支
需频繁切换大量租户 / 领域未合并 LoRA + Adapter Registry共享底座,小权重热切换
研究输入控制或极低参数预算Prompt / Prefix Tuning不必直接修改网络权重
经典编码器任务、多任务模块化迁移Adapter隔离与复用边界清楚
数据多、任务与底座差异极大更高 rank 或评估全量微调小增量可能成为容量瓶颈

这里最容易犯的错误是只根据“参数比例”选择。实际效果还取决于数据质量、提示模板、目标模块、上下文长度、学习率、训练 token 数量与评测集是否贴近真实请求。

6. 生产系统:适配器应当是一等资源

一个成熟的 PEFT 系统不应把适配器当作临时训练产物。它至少要把下列元数据与权重一起版本化:

Adapter Package
├── base_model: 精确版本与哈希
├── tokenizer / chat template
├── method: LoRA / IA³ / Prefix
├── target_modules 与超参数
├── dataset / license / evaluation card
├── safety policy version
└── adapter weights

在服务层,推荐把“模型选择”和“适配器选择”拆开:

请求

Model Router ──> 共享 Base Model
  ↓                     ↓
Tenant / Task Policy ─> Adapter Registry

                       Cache / Hot Swap / Merge

这套拆分带来几个可操作的好处:

  • 新领域上线只发布小型 adapter,不复制底座;
  • 可以按租户快速回滚或灰度某一项能力;
  • 可以在评测通过前拒绝加载不兼容的底座版本;
  • 可以将适配器视作受治理的软件供应链制品,而非随意的权重文件。

7. 常见误区

“PEFT 总是比全量微调更好”

不对。PEFT 优化的是成本、运维与大多数常见迁移任务的性价比。若任务数据很充足、分布偏移极大,或需要深度重塑模型能力,全量微调仍可能更有上限。

“更高的 LoRA rank 一定更好”

不对。rank 增加的是可表达容量,也会增加训练成本和过拟合空间。应以独立验证集、目标任务指标和推理预算共同选择,而不是只追求 rank 数字。

“适配器文件小,所以风险也小”

不对。适配器可以强烈改变输出行为。它必须绑定基础模型、数据来源、许可证、评测与安全审查;错误加载到近似但不相同的底座,可能产生不可预测的语义退化。

“合并 LoRA 后就不需要保留原 adapter”

不建议。合并权重适合部署,但应保留可追溯的原始 adapter 和合并记录。否则无法清晰回答某次线上行为来自哪一个训练数据版本或配置。

8. 对今天的实践建议

对于绝大多数开源 LLM 领域适配项目,可以从下面的路径开始:

  1. 先建立不微调的基线与固定评测集;
  2. 用 LoRA 对 q_projv_proj 做小 rank 试验;
  3. 显存不足时切换 QLoRA,而不是先牺牲数据与评测;
  4. 将底座版本、模板和 adapter 配置作为一个不可分割的发布单元;
  5. 对低延迟固定场景进行合并部署,对多任务场景保留动态加载;
  6. 只有当 PEFT 的验证结果稳定触顶时,再评估更高容量配置或全量微调。

PEFT 最值得继承的不是某一组超参数,而是一种系统设计:让昂贵且通用的能力保持共享,让便宜且专用的变化独立演化。 Adapter 论文提出了这个方向,Prompt 方法探索了输入侧控制,LoRA 与 QLoRA 则让它成为今天大模型训练与部署的常规工具。

延伸阅读