大模型的PEFT~ 参数高效微调 Parameter-Efficient Fine-Tuning

Parameter-Efficient Fine-Tuning pəˈræmətər ɪˈfɪʃnt faɪn ˈtuːnɪŋ 参数高效微调

Tuning ˈtjuːnɪŋ n. 调音;起音,定音;音调;(电子或收音机)调谐;协调一致

LoRA dominates modern practice, but it is not the only parameter-efficient method. For completeness, the main alternatives:

PEFT method families. LoRA is the de facto standard for LLM fine-tuning; the others are included for historical context and niche use cases.

LoRA 在现代实践中占据主导地位,但它并非唯一一种参数效率高(parameter-efficient)的方法。

为了完整性,这里还列出了其他主要的方法:PEFT 方法家族

LoRA 是 LLM 微调的默认标准;其他方法则因历史原因存在,且主要用于特定领域的应用场景

niche niːʃ 小众

n. 合适(称心)的工作(活动)(one's niche);壁龛;(产品的)商机;生态位(一个生物所占生境的最小单位)

v. 把......放在壁龛中

adj. (产品)针对特定小群体的

Adapters

定义

MLP = 多层感知机(Multi-Layer Perceptron),就是最简单的全连接神经网络

普通 MLP 结构:输入 → Linear → 激活 → Linear → 输出

小型 MLP:相比 Transformer 主干巨大维度,它宽度很小、参数量远少于主干模型

瓶颈 Bottleneck 结构:先压缩维度 → 激活 → 再恢复维度

假设 Transformer 层输出维度 d_model = 512,hidden_dim 远小于 d_model

输入(512) → Linear(512→64) → Activation(GELU) → Linear(64→512) → 输出

先降维压缩到很小的通道(比如 64),再升维还原;中间窄通道就是 "瓶颈" bottleneck;整套模块参数量很少,属于小型子网络

原始 Transformer:Self-Attention → FFN

插入 Adapter 后:Self-Attention → Adapter(小型瓶颈MLP) → FFN → Adapter(小型瓶颈MLP)

只训练这些新增的小 MLP,主干大模型冻结,属于参数高效微调

为什么叫 Bottleneck

优点

模块化,可以自由插入、堆叠;理论上表达能力很强

缺点(也是现在很少用的原因)

推理时串行执行,必须等 Adapter 计算完才能往下走,增加推理时延

LoRA 直接在权重矩阵旁附加低秩矩阵,推理时可以预先合并,没有额外延迟

和 LoRA 直观对比

Adapter:新增独立小型网络,推理多一套计算,延迟上升

LoRA:新增低秩矩阵,推理前可以融合进原始权重,无额外时延

为什么说LoRA 修改线性层计算路径,而Adapter 额外插入独立子网络

误区,LoRA 也是新增网络?

LoRA 只是新增两个矩阵,嵌入原有算子,没有形成独立 "网络模块"

Adapter 是完整的「线性→激活→线性」小型网络,是独立子模块

LoRA:不插新模块,在线性层内部并行追加一条计算支路,能合并消除额外开销

Adapter:在层与层之间塞进一套独立小型网络,数据必须串行走一遍,无法消除推理延迟

训练流程

这套是 Houlsby Adapter(2019 原始论文标准方案),放两个 Adapter

text 复制代码
SelfAttention
    ↓
Adapter(两层全连接子网络)
    ↓
FFN
    ↓
Adapter(两层全连接子网络)

相当于

text 复制代码
SelfAttention  ← 计算token关联
    ↓
【Adapter1】← 修正注意力输出的特征
    ↓
FFN  ← 独立加工每个token特征
    ↓
【Adapter2】← 修正FFN输出的特征

Transformer 有两处信息变换阶段:自注意力模块输出、前馈网络 FFN 输出,两处都需要引入可学习微调支路

模型需要在特征两个不同阶段注入微调能力

Transformer 单层原生结构回顾

plaintext 复制代码
→ SelfAttention(捕捉token之间关系)
→ FFN(对每个token独立做非线性特征变换)
→ 输出

两个模块负责完全不同的语义运算:

Self-Attention:交叉 token 关系建模(上下文关联)

FFN:单 token 独立特征映射(词本身语义加工)

为什么两处都插 Adapter?

原始论文设计思路:微调信号既需要修正「token 之间的关联计算」,也需要修正「单个 token 内部特征变换」

简单理解:

注意力算完上下文 → 先微调一次;

FFN 加工单词特征 → 再微调一次。

变体对比(拓展)

后来有人提出 Parallel Adapter / 只放一处:只在 Attention 之后放一套 Adapter,参数量更少

但大量实验证明:Houlsby 双 Adapter 表达能力更强,微调效果普遍优于单 Adapter。代价就是参数量翻倍、推理延迟更高

小节

小型瓶颈 MLP 就是一套窄通道的两层全连接网络,作为独立插件插入 Transformer 层之间

训练时只更新插件权重,实现高效微调,代价是推理变慢

为什么 LoRA 是赢家

LoRA 之所以成为行业标准,是因为它同时具备四大独特优势:

  • 零推理额外开销(zero inference overhead)
    LoRA 适配器权重可以直接合并进基础模型权重;反观 Adapter、Prefix Tuning,要么增加推理延迟,要么占用输入上下文长度
  • 可组合性(热切换能力,composability)
    多套独立 LoRA 适配器,在模型服务运行阶段可以动态切换,非常适合多租户(multi-tenant deployments)业务部署场景
  • 完善生态支持(ecosystem support)
    HuggingFace PEFT、TRL、vLLM 以及各大主流框架,都对 LoRA 提供原生一级支持(first-class support)
  • 大规模生产场景验证成熟
    Meta、Google 均在生产环境落地;同时 HuggingFace 绝大多数开源模型微调项目都使用 LoRA

除非你遇到 LoRA 无法满足的特殊约束,否则默认优先选择 LoRA

LoRA 胜出四大核心:

① 推理无额外时延

② 支持在线动态切换权重,适配多租户

③ 主流开源框架全面原生支持

④ 经过大厂大规模生产验证

Prefix Tuning

针对 Transformer 每一层 Attention,在该层的 keys、values 前方,拼接一组可学习的虚拟 Token(prefix 前缀向量)

Prompt Tuning 只在最顶层输入加虚拟 token

Prefix Tuning:每层 Transformer 内部都单独拥有一套可学习前缀向量

优点

完全不改动主干模型权重,只新增少量前缀参数

在生成类任务(文本续写)效果表现很好

短板(consumes context length)

永久占用上下文窗口长度

假设设置前缀数量为 10,那么输入可用长度 = 最大上下文长度 - 10

用户真实文本能塞进模型的 token 变少

推理无法合并消除开销

每一层 Attention 都要拼接前缀 KV,推理全程额外运算,带来延迟

长文本任务退化明显

为什么现在很少用(被 LoRA 挤压)

前缀永久占用上下文长度,挤压用户输入 token 上限

推理时每层都要拼接 KV,存在持续额外计算开销,不能像 LoRA 一样权重合并,持续带来推理时延

多层独立前缀参数量比 Prompt Tuning 更大,长文本场景性能衰减

定位:Niche(小众方案),一般只用在部分生成类专项实验,线上业务几乎不用

示例

原始标准Attention

text 复制代码
Q = [T1_q, T2_q, T3_q]
K = [T1_k, T2_k, T3_k]
V = [T1_v, T2_v, T3_v]
Attention(Q, K, V)

Prefix Tuning 改造后

text 复制代码
# Queries 完全不变,只有真实token,不加任何前缀
Q = [T1_q, T2_q, T3_q]

# Keys:前面拼接可学习虚拟前缀 P1,P2
K = [P1_k, P2_k, T1_k, T2_k, T3_k]

# Values 和 Keys 保持对齐,同样前置拼接前缀
V = [P1_v, P2_v, T1_v, T2_v, T3_v]

Attention(Q, K, V)

Query 只有 3 条(来自真实 token);KV 序列长度变成 2+3=5

所以每个真实 token Query,会同时去匹配:2 个虚拟前缀 P1、P2,3 个真实 token T1、T2、T3

虚拟前缀没有对应的 Query!前缀之间不会互相做注意力匹配

前缀只充当「全局上下文线索」,给真实 token 提供额外可学习的先验信息

假设模型最大上下文窗口 max_seq_len = 512,固定设置 prefix_len=2,用户能输入的真实 token 上限 = 512 - 2 = 510

虚拟前缀永久抢占 2 个位置,用户可用长度被压缩

什么叫给模型注入任务专属的 "先验指导信息"

不改动预训练大模型主干权重,只通过在每一层注意力引入可学习的虚拟前缀 KV 向量,给模型注入任务专属的 "先验指导信息",让模型适配下游生成任务

大模型主干冻结:预训练模型知识保留完整,避免微调破坏通用能力;只训练少量新增前缀参数,属于参数高效微调

虚拟前缀充当「任务提示」

可以把 P_1,P_2...P_n 理解成模型学出来的隐形任务指令,不是人工写的文本 prompt,是可学习向量

人工 prompt:请用诗歌风格回答:xxxx

Prefix Tuning:模型自动学习一组向量,等价于记住「当前任务该怎么生成」

它最适合的场景

自回归生成任务(文本续写、摘要、对话)

模型生成下一个 token 时,每个 Query 都能看到这组全局虚拟前缀,持续约束生成风格、格式、任务目标

Prompt Tuning = 在你问题最前面,塞一句固定提示词;

Prefix Tuning = 在模型每一层思考环节,都放一张隐形备忘录,持续提醒模型:你现在的任务是写摘要。

为什么放在每一层 Attention 的 KV 上,而不是输入开头?

早期发现:只在输入层加软 prompt(Prompt Tuning),信号很难穿透深层 Transformer

把前缀放到每一层注意力内部,任务信号可以直接作用于每一层特征变换,长文本生成任务效果明显更强

Prefix Tuning 目标:冻结主干模型,在 Transformer 每一层 Attention 的 KV 前端拼接可学习虚拟前缀向量,为下游生成任务持续注入任务先验;相比仅输入层加软提示,任务信号能直达网络深层,生成效果更强;代价是占用上下文窗口,推理存在额外开销

训练流程

text 复制代码
真实文本Token
     ↓
Transformer Layer l
Q = 真实token投影
K = [前缀K] + [真实K]
V = [前缀V] + [真实V]
     ↓
Attention计算
     ↓
FFN...输出预测token
     ↓
计算Loss
     ↓
反向传播:只更新每层的Prefix KV,主干锁住不动

Prompt Tuning(提示微调)

Prompt Tuning = 软提示(Soft Prompt)微调

冻结整个大模型主干权重;只在输入 Embedding 层、真实文本最前面,拼接一组可学习的虚拟 Token 向量,仅训练这一小部分向量实现下游任务适配

硬提示和软提示

人工手写提示词 "翻译成中文:xxx" → Hard Prompt(硬提示)

模型自动学习的连续向量前缀 → Soft Prompt(软提示,Prompt Tuning)

示例

设定:虚拟 token 数量 = 2(P1,P2);真实输入 token T1,T2,T3

Prompt Tuning 输入序列构造

text 复制代码
输入Embedding序列 = [P1, P2, T1, T2, T3]

整条序列送入 Transformer第一层,之后后续所有网络层不再新增任何向量

简单对比 Prefix Tuning:

Prompt Tuning:只在最开头加一次虚拟 Token,贯穿所有层

Prefix Tuning:Transformer 每一层 Attention 内部,都单独新增一套 KV 前缀

训练流程

冻结主干:预训练模型全部参数 requires_grad=False

初始化参数:创建一组可学习向量 P = p1,p2...pn(虚拟软提示)

前向传播

真实文本编码得到 T1,T2,T3;在序列头部拼接软提示:P1,P2,T1,T2,T3;完整序列送入 Transformer 逐层前向计算

反向传播

计算预测 Loss,梯度只更新 P1、P2 向量;主干模型完全不动

保存产物:训练完成只保存这一小段软提示向量

优点

参数量极少(<0.01%),所有 PEFT 里最轻量方案之一

实现最简单,不用改动模型内部注意力逻辑

缺点(weaker than LoRA for complex tasks)

任务指令信号只在输入层注入,随着层层前向传播,引导能力会不断衰减

复杂任务、长文本任务效果明显弱于 LoRA、Prefix Tuning

相关推荐
minglie12 小时前
zynq中axi_dma的三个实验-第1课:PL搭建
学习
xianrenli382 小时前
Android14自动时区更新
android·学习·framework·aosp14·自动时区
MartinYeung52 小时前
[论文学习]Unsafe LLM-Based Search: AI搜索引擎安全风险的定量分析与缓解
人工智能·学习·搜索引擎
LiaoWL1233 小时前
【SpringCloud合集-06】Spring Cloud Gateway网关学习笔记
笔记·学习·spring cloud
Lhappy嘻嘻3 小时前
网络(二)|Java Socket 编程全实战:UDP 回显 / 词典服务器、TCP 单线程→多线程线程池演进
java·开发语言·网络·学习·面试·udp·tcp
鱼听禅3 小时前
ubuntu学习笔记-使用ls-ml-toolkit工具识别Label Studio数据数据训练yolo模型
笔记·学习·ubuntu
xian_wwq13 小时前
【学习笔记】模型权重管理:Safetensors与私有化Hub(23/35)
笔记·学习
其实防守也摸鱼14 小时前
运维--学习阶段问题解答(1)(自测)
linux·运维·服务器·数据库·学习·自动化·命令模式
ctrl_v助手14 小时前
Halcon学习笔记2
人工智能·笔记·学习