2. PEFT
介绍参数高效微调(PEFT)技术及其应用
什么是参数高效微调
基本思想
像 BERT、GPT-3 以及其他 Transformer 这样的现代大规模模型,通常拥有数亿甚至数十亿个参数
针对每一个新任务都对这些模型进行完整微调,不仅计算开销巨大,而且内存占用也很高,尤其是在需要为多个任务分别维护模型副本的情况下
参数高效微调(Parameter-Efficient Fine-Tuning,PEFT)方法正是为了解决这一问题而提出的
其核心思想是:只调整模型中极小一部分参数,或者在模型中引入轻量级的附加模块,同时将绝大多数预训练权重保持冻结状态
通过这种方式,可以在显著降低存储和计算成本的前提下,将预训练模型高效地适配到新的任务上
PEFT 的类型

PEFT Methods PEFT 可以大致分为三类
引入额外参数(Additive-based):包括适配器(Adapters)、软提示(Soft prompts)、hard prompts
选择部分参数(Selective-based):选择参数进行更新
引入重参数(Reparametrization-based):LoRA(Low-rank Adaptation)系列
Additive-based Methods
基本思想
基于额外参数的方法通过向预训练模型中引入额外的参数或层,并且只训练这些新加入的部分来实现微调
这是 PEFT 方法中规模最大、研究也最为广泛的一类。
在这一大类中,又发展出了两个重要的子方向:Adapter 类方法和 Soft Prompt(软提示)方法
Adapters
Adapters是一种典型的基于额外参数的 PEFT 方法,它在 Transformer 的子层之后插入小型的全连接网络
这一思想被广泛采用(Pfeiffer et al., 2020b,见 https://github.com/adapter-hub/adapter-transformers),并且衍生出了多种变体,包括
改变 Adapter 的插入位置
对 Adapter 进行剪枝
通过重参数化来减少可训练参数数量
Soft Prompts
语言模型提示旨在通过修改输入文本来控制语言模型的行为,输入通常由任务描述和少量上下文示例组成,然而,这类方法往往难以优化,并且受限于模型的最大输入长度
为了解决这些问题,引入了“软提示”(Soft prompts)的概念,其核心思想是:通过梯度下降直接微调模型输入嵌入的一部分,这样就把在离散空间中搜索提示的问题,转化为了一个连续优化问题
软提示既可以只作用在输入层(Prompt Tuning),也可以扩展到模型的所有层(Prefix Tuning)
近期的一些研究还探索了对软提示进行预训练或部分复用,以进一步降低微调成本
基于额外参数的方法是一种非常多样化的参数高效微调技术,其范围不仅限于 Adapter 和 Soft Prompt
为什么要增加参数
尽管这些方法向网络中引入了额外参数,但它们依然能够在速度和内存占用上带来显著提升,原因在于,它们大幅减少了梯度和优化器状态的规模
以 Adam 为例,对于每 1 字节的可训练参数,需要额外 1 字节来存储梯度,以及 2 字节来存储优化器状态(梯度的一阶矩和二阶矩),因此在实际训练中,模型训练所需的 GPU 内存通常是模型权重本身的 12–20 倍
通过减少优化器状态和梯度的内存占用,并对冻结的模型参数进行量化,基于额外参数的方法使得微调更大规模的网络成为可能,或者允许使用更大的 microbatch size,从而提升 GPU 上的训练吞吐率。其中,batch size 的关系为
Batch size=microbatch size×gradient accumulation×num. devices此外,由于需要更新的参数数量更少,PEFT 方法中的优化器更新步骤相比全量微调要快得多,这一点在实际中非常明显
同时,在分布式训练环境下,优化参数数量的减少还会显著降低通信量,这对大规模训练尤为重要
Adapters

基本思想
全参数微调的参数量 $O(|\theta|)$,显存、通信、checkpoint 成本极高
但是下游任务通常只需要改变模型的“行为偏置”,而不是重塑整个表示空间
Adapter 的核心思想是冻结原模型参数,只引入一小组可训练参数,用极低成本实现任务适配
模型结构
Adapter 是插入在 Transformer 层中的一个小瓶颈网络(bottleneck module)
Adapter(x)=x+Wupσ(Wdownx)$x \in \mathbb{R}^h$:Transformer 层的隐藏状态
$W_{\text{down}} \in \mathbb{R}^{r \times h}$、$W_{\text{up}} \in \mathbb{R}^{h \times r}$
$r \ll h$:瓶颈维度
$\sigma$:非线性激活函数(ReLU / GELU)
每个 Adapter 模块中的第一个全连接层会将输入投影到一个低维表示空间中;第二个全连接层再将该低维表示投影回原始的输入维度
这样,低秩瓶颈限制了 Adapter 的表达能力,而残差连接保证初始状态等价于原模型,不会破坏预训练分布
参数量计算
hidden size = $h$、bottleneck = $r$、Transformer 层数 = $L$
每层 Adapter 参数量:
∣Wdown∣+∣Wup∣=hr+rh=2hr全模型 Adapter 参数量:
2hrL全参数微调参数量:
O(h2L)比例:
Full FTAdapter≈hr当 $h = 4096$、$r = 16$ 时,参数比例 $\approx 0.4%$,参数规模显著更小
根据最初的 Adapter 论文结果,使用 Adapter 方法训练的 BERT 模型,在仅训练 3.6% 参数的情况下,就可以达到与全参数微调的 BERT 模型相当的性能
同时,可以针对不同的任务使用不同的 Adapter,主干则是共享的
伪代码
Pfeiffer 发现
如果只在每个 Transformer block 中的 self-attention 之后(LayerNorm 之后)插入一个 adapter,其性能几乎与在同一个 block 中插入两个 adapter(通常是 attention 后一个、MLP 后一个)相当
attention 后的 hidden state 已经包含了任务相关的结构性信息,token 之间的依赖模式,在 attention 之后插入 adapter 收益较大
在 MLP 后加一个 adapter,能学到的新自由度其实高度相关,信息增益很小,但参数和计算翻倍
LayerNorm 之后的表示具有数值尺度稳定、各层分布一致、更接近“模型的自然表示空间”的性质,从而使得 adapter 接收的是一个“干净、稳定、语义明确”的表示,这样 adapter 的低秩更新更容易学习,不容易破坏主干网络,这也是为什么 Adapter、LoRA、Prefix / Prompt(在隐空间)几乎都偏好 LN 后或 residual 分支中插入
Prompt-Tuning
Soft / Hard Prompt Tuning
Hard Prompt Tuning 指使用真实的离散 token,作为 prompt 拼接到输入中,prompt 本身是自然语言或符号,不可微、不可直接反向传播——也就是一般提到的提示工程
Soft Prompt Tuning 也即一般的 Prompt / Prefix Tuning,这时 prompt 不再是离散 token,而是可训练的连续向量,直接作为 embedding 使用
核心问题:全参数微调代价太高,而 Adapter 仍然需要改动网络内部结构或权重,是否能只通过“输入”来控制模型行为?
Prompt / Prefix Tuning 的统一思想:冻结整个 Transformer,仅学习一小段连续向量,通过影响注意力分布来“操控”模型
本质上:不改模型,不加模块,只改模型看到的上下文表示
Prompt Tuning 学习的是一段连续向量 prompt,直接拼接到输入 embedding 前面
设原始输入 token embedding:
X=[x1,x2,…,xT],xi∈Rh可训练 prompt:
P=[p1,p2,…,pm],pi∈Rh模型实际输入为:
[P;X]其中 $P$ 即为学习的参数,而 $X$ 是数据,Transformer 权重完全冻结
Prompt Tuning 的参数量:
m⋅h当 $m = 20 \sim 100$、$h = 4096$ 时,参数量 $\sim 10^5$,相比 Adapter / LoRA 更小
训练时,梯度只更新 prompt embedding,非常稳定
推理时,prompt 作为额外 token,序列长度增加 $m$,注意力计算成本略增
本质上,Prompt Tuning 是在调整模型的“条件分布起点”,改变输出风格、任务偏好
Prefix-tuning

Prompt Tuning 的核心限制在于 prompt 只在 embedding 层起作用,深层 Transformer 只能“间接感知”
Prefix Tuning 的关键改进:在每一层注意力中都插入可学习前缀
形式化定义
Transformer 第 $l$ 层注意力:
Attn(Ql,Kl,Vl)Prefix Tuning 学习的是:
PlK∈Rm×h,PlV∈Rm×h实际注意力计算变为:
Attn(Ql,[K(PlK);K(X)],[V(PlV);V(X)])Prefix 不参与 Query,只影响 Key / Value,且在每一层都生效

img
参数规模
若每层都有 prefix,参数量为
2⋅m⋅h⋅L其中,$2$ 来自 $K$ 和 $V$,$L$ 是 Transformer 层数
为了压缩参数,实际常共享低维 prefix,使用 MLP 投影到各层
训练时,梯度流入每一层,比 Prompt Tuning 更强
推理时,prefix 不增加序列长度,但会增加注意力 Key / Value 缓存
Prefix Tuning 实际上是在学习每一层的注意力偏置,这意味着能影响深层语义,并模拟一部分 Adapter 的效果,但仍然不改 FFN / 权重
伪代码
Adaptive Prefix Tuning
出发点
普通 Prefix Tuning 的隐含假设是 prefix 是静态的,与输入 $X$ 无关,对同一任务的所有样本使用同一组 $P_l^K, P_l^V$
这带来的问题是表达能力受限,无法针对不同输入动态调整注意力偏置,在复杂任务(推理、多域、多风格)上效果不稳定
实际上,静态 prefix ≈ 固定注意力 bias,但多样性要求输入不同,prefix 也不同,于是引出 Adaptive Prefix Tuning
基本思想
Prefix 不再是参数本身,而是由输入条件生成的函数输出,即:
PlK,PlV=gϕ(X)其中,$g_\phi$ 是一个小型可训练网络,$\phi$ 是唯一需要更新的参数,而Transformer 主模型依然保持完全冻结
对于标准 Prefix Tuning,第 $l$ 层注意力:
Attn(Ql(X),[K(PlK);K(X)],[V(PlV);V(X)])其中,$P_l^K, P_l^V$ 是直接可训练参数,与输入无关
Adaptive Prefix Tuning 引入条件生成器 $g_\phi$:
(PlK,PlV)=gϕ(h(X))其中 $h(X)$ 通常是输入 embedding 的池化或某一层的 CLS / mean 表示
这样,注意力变为:
Attn(Ql(X),[K(gϕK(h(X)));K(X)],[V(gϕV(h(X)));V(X)])
参数规模
假设 prefix 长度 $m$、hidden size $h$、条件向量维度 $d$、层数 $L$
普通 Prefix:$2 \cdot m \cdot h \cdot L$
Adaptive Prefix(共享 MLP):$d \cdot h + 2 \cdot m \cdot h$
Adaptive Prefix(每层独立):$L \cdot (d \cdot h + 2 \cdot m \cdot h)$
参数量略高于静态 Prefix,但远低于 Adapter / LoRA
根本区别
标准 Prefix Tuning 学习的是 $\mathbb{E}_X[\text{attention bias}]$
Adaptive Prefix Tuning 学习的是 $\text{attention bias}(X)$
伪代码
Intrinsic Prompt Tuning (IPT)
出发点
IPT 针对的是 Soft Prompt Tuning 的两个核心痛点:Prompt tuning 在新任务上收敛慢,每个任务都要训练一整段 prompt,参数量仍然不小($m \times h$)
IPT 的核心假设是:虽然 soft prompt 定义在高维空间 $\mathbb{R}^{m \times h}$,但不同任务的 prompt 实际上位于一个低维的“内在任务子空间”中,即原始 prompt:$P \in \mathbb{R}^{m \times h}$,展平后:$p \in \mathbb{R}^{m h}$,存在低维表示 $z \in \mathbb{R}^d$,其中 $d \ll m h$
这与 Intrinsic Dimension Hypothesis、Lottery Ticket / Low-rank adaptation 在思想上是一致的
算法流程
阶段一:标准 Prompt Tuning(多任务)
给定一组任务 ${T_1, \dots, T_K}$,对每个任务,独立训练一个 soft prompt
阶段二:学习 prompt 的低维表示(Autoencoder)
将每个 prompt 展平:$p_i \in \mathbb{R}^{m h}$,输入自编码器
Encoder 学到“任务内在坐标”,Decoder 学到“从子空间到 prompt 的映射”
阶段三:新任务的 IPT 训练
对一个新任务,丢弃 Encoder,冻结 Decoder(或微调)
只训练一个低维向量 $z \in \mathbb{R}^d$
每个新任务只需要训练 $d$ 个参数,而不是 $m \times h$
参数规模对比——Prompt Tuning:$m \times h$,IPT:$d$,其中 $d \ll m h$
伪代码
P-Tuning
Selection-based Methods
基本思想
最早的选择式 PEFT 方法之一是只微调网络顶部的少数几层
现代方法通常基于层的类型,或者基于模型的内部结构来进行选择,例如只微调模型中的偏置参数,或者仅微调特定的参数行
稀疏训练是选择式 PEFT 的另一种形式,它往往不显式考虑模型结构,而是根据精心设计的选择准则来决定哪些参数参与微调
然而,稀疏参数更新在工程实现和计算效率方面面临诸多挑战
近年来的一些研究在参数重配置(Parameter Reconfiguration)以及 NxM 稀疏性方面对这些问题进行了部分缓解
但即便如此,在当前主流硬件上,完全不受约束的非结构化稀疏仍然不具备实用性
BitFit (Bias Fine-Tuning)
Sparse Fine-Tuning
Reparametrization-based Methods
基本思想
基于重参数化的 PEFT 方法通过利用低秩表示来最小化可训练参数的数量
神经网络具有低维表示这一观点,已经在深度学习的经验研究和理论分析中被广泛探讨
Aghajanyan et al. (2020) 证明了在低秩子空间中同样可以有效地进行微调,同时发现对于规模更大的模型,或者预训练时间更长的模型,所需进行适配的子空间维度反而更小
他们提出的方法被称为 Intrinsic SAID,该方法利用 Fastfood 变换对神经网络参数的更新进行重参数化
这一思想启发了多种后续方法,包括 IntrinsicSAID、LoRA 以及 KronA
在这些方法中,最为人熟知的是 Low-Rank Adaptation(LoRA),其采用一种简单的低秩矩阵分解来参数化权重更新:
δW=WdownWup这种方法实现起来非常直接,并且已经在参数规模高达 1750 亿的模型上进行了验证
此外,一些工作还探索了使用 Kronecker 积进行重参数化:
δW=A⊗B这种方式在秩大小与参数数量之间提供了更优的权衡
Intrinsic SAID
Intrinsic SAID 研究的是一个非常根本的问题
微调一个大模型时,真正“有用”的参数自由度到底有多少?
换句话说,虽然模型参数维度是 $D$(动辄 $10^9$),但是否只需要在一个远小于 $D$ 的子空间中更新,就能达到同样效果?
这就是 Intrinsic Dimensionality(内在维度) 问题
Aghajanyan 等人的研究发现
为了达到同样的微调性能,模型越大,所需的内在可调维度越低
即原始参数为 $\theta_0 \in \mathbb{R}^D$,而实际需要优化的自由度:$d \ll D$
这为两个方向提供了理论基础:
模型越大,越适合参数高效微调
不必显式地修改少量参数(如 Adapter),也可以低维控制“全模型更新”
Intrinsic SAID 的核心技术是 Fastfood Transform,它定义了一个映射:
F:Rd→RD并用它来表示参数更新:
θ=θ0+F(θd)$\theta_d \in \mathbb{R}^d$ 是唯一需要训练的参数
$F(\theta_d)$ 是一个投影到全参数空间的“低秩扰动”
Fastfood 是一种随机但结构化、计算高效、不需要显式存储 $D \times d$ 矩阵的高维扩展方法
它的关键性质是计算复杂度:$O(D \log d)$,内存复杂度:$O(D)$,可以近似一个随机高斯投影
直觉上,$\theta_d$ 是“控制旋钮”,而Fastfood 把它“扩散”成作用于所有参数的更新方向
Intrinsic SAID 与“选择性微调”的根本区别
其他 PEFT 方法(Adapter / LoRA / Prompt):只更新模型的一小部分参数,其余参数完全冻结
Intrinsic SAID:更新所有模型参数,但更新方向被限制在一个低维子空间中
也就是说,参数空间是 $D$ 维,但可达更新空间是 $d$ 维
Intrinsic SAID 在工程上几乎不可用
Fastfood 本身需要 $O(D)$ 内存,虽然不训练 $D$ 个参数,但 Fastfood 需要存储结构化映射,并在每一步生成 $D$ 维更新
每次更新都要对所有参数生效,无法像 LoRA / Adapter 那样局部注入
Intrinsic SAID 不适合 ZeRO / FSDP,不适合参数分片,不适合增量 checkpoint
LoRA

基本思想
设一个大模型包含一个权重矩阵 $W \in \mathbb{R}^{\text{in} \times \text{out}}$
例如总参数规模是 7B,在标准微调中,反向传播会学习一个与 $W$ 同形状的更新量:
ΔW∈Rin×outWupdated=W+ΔW问题在于,$\Delta W$ 和 $W$ 一样大,需要存梯度、optimizer states(Adam: 2×FP32),显存和带宽成本与模型规模线性增长,这在 7B、70B 甚至 175B 模型上是不可承受的
LoRA(Hu et al., 2022)基于一个关键观察:虽然 $W$ 是高维的,但任务相关的权重更新 $\Delta W$ 通常位于一个低秩子空间
因此,LoRA 不直接学习 $\Delta W$,而是令:
ΔW=WAWBWA∈Rin×r,WB∈Rr×out,r≪min(in,out)这就是 LoRA 的低秩分解
参数量节省
原始微调需要优化的参数量:$|\Delta W| = \text{in} \times \text{out}$
LoRA 需要优化的参数量:$|W_A| + |W_B| = r(\text{in} + \text{out})$
当 $r$ 很小时(如 4、8、16),参数量下降 10–100×,梯度、optimizer states 同比例下降,显存占用显著减少
LoRA 的关键工程优势在于:
训练时从不构造 $\Delta W$,只在前向中引入一个额外的低秩路径
前向计算为 $h = xW + \alpha \cdot x W_A W_B$,其中缩放因子通常是 $\alpha = \frac{1}{r}$
训练阶段:冻结 $W$,只训练 $W_A, W_B$,梯度只回传到低秩矩阵
推理 / 合并阶段:可以显式合并权重 $W' = W + \alpha W_A W_B$,推理时无额外计算开销,与原模型结构完全一致
LoRA 的思想直接继承自 Intrinsic SAID:
Intrinsic SAID:更新在低维子空间中,低维变量 → Fastfood → 更新所有参数(不实用)
LoRA:用显式低秩矩阵来参数化这个子空间,低维变量 → 低秩矩阵 → 局部权重(工程可行)
LoRA 是 Intrinsic SAID 的“工程化版本”
LoRA 应用到哪些部分
最常见的位置是多头注意力中的 $W_Q$、$W_K$、$W_V$、$W_O$
原因是注意力对任务适配高度敏感,权重矩阵形状规则、适合低秩分解
但后续研究表明对所有线性层应用 LoRA,效果最好,包括 MLP 的 up / down / gate 投影
伪代码
KronA

LoRA 的局限
LoRA 用的是低秩矩阵乘法来参数化权重更新:
δW=WAWB其中 $W_A \in \mathbb{R}^{\text{in} \times r}$、$W_B \in \mathbb{R}^{r \times \text{out}}$
这在工程上非常高效,但有一个结构性限制:$\operatorname{rank}(\delta W) \le r$
也就是说,参数量和可表达的秩是线性绑定的,想要更高表达能力,就必须增大 $r$,参数量随之线性增加
KronA 的核心想法是:能不能在相同参数预算下,得到更高“有效秩”的更新?
KronA 的核心思想:用 Kronecker 积代替矩阵乘法
KronA 不再使用矩阵乘法,而是改为
δW=WA⊗WB其中 $W_A \in \mathbb{R}^{n \times m}$、$W_B \in \mathbb{R}^{k \times l}$、$\delta W \in \mathbb{R}^{(n k) \times (m l)}$
关键性质是 Kronecker 积的秩:
rank(A⊗B)=rank(A)⋅rank(B)这意味着如果 $A$ 和 $B$ 都是低秩的,它们的 Kronecker 积可以拥有显著更高的秩
为什么 Kronecker 积更划算
假设 LoRA:参数量 $\sim r(\text{in} + \text{out})$,秩 $\le r$,KronA:参数量 $\sim nm + kl$,秩 $\le \operatorname{rank}(A)\operatorname{rank}(B)$
在合理拆分矩阵形状的情况下,KronA 用相同甚至更少参数,可以表达更复杂的线性变换结构,尤其适合具有二维或块结构的权重矩阵
直觉上,LoRA 是“一条低维通道”,而 KronA 是“两个低维结构的张量化组合”
和 LoRA 一样,KronA 也不会显式构造 Kronecker 积,而是直接计算:
x(WA⊗WB)利用 Kronecker 积的恒等式:
vec(AXB)=(B⊤⊗A)vec(X)KronA 的实现思路是先把向量 $x$ reshape 成矩阵,然后左乘 $A^\top$,再右乘 $B$,最后 flatten 回向量
在 GLUE 上,参数预算约为 $0.07%$ 时:
性能:KronA ≥ LoRA ≈ Adapter ≈ Compacter
推理速度:KronA 显著快于 Adapter 和 Compacter
训练参数量:相同
其优势主要来自更高表达秩、无中间层、纯线性算子
KronA-resB——带残差的并行 Adapter
伪代码
Kronecker 积定义为:
A⊗B=a1,1B⋮am,1B⋯⋱⋯a1,nB⋮am,nB其本质是用 $A$ 的每个元素去缩放整个 $B$,构造一个具有强结构性的“大矩阵”
PyTorch 中可用 einsum 实现 batch 版本:
DoRA

方向变化与模长变化的关系
设某一层权重矩阵为 $W$,比较微调前后:
方向变化:$\Delta D$
模长变化:$\Delta M$
DoRA 对全量微调的多个 checkpoint 和多层权重做了统计,发现:
full fine-tuning 中,$\Delta D$ 与 $\Delta M$ 呈显著负相关
要改变方向很多,模长变化往往很小
模长变化很大时,方向反而变化较小
但在 LoRA 微调中,现象恰好相反:
$\Delta D$ 与 $\Delta M$ 正相关
方向变化越大,模长也被迫一起变大
这说明 LoRA 在结构上把“方向”和“模长”耦合在了一起
这是由于在 LoRA 的权重更新中,$W_A W_B$ 同时决定了权重方向和权重整体模长,优化器无法“只调方向、不动模长”或“只调模长、不改方向”
DoRA 借鉴了 weight normalization 的思想,将权重拆成:
W=m⋅v,∣v∣2=1其中 $v$ 表示方向(direction),$m$ 表示模长(magnitude,可学习标量)
方向由 LoRA-style 的低秩更新负责,模长由一个独立的可学习参数 $m$ 负责
这种重参数化带来的直接后果是改变 $W_A, W_B$ 主要影响 $v$(方向),改变 $m$ 只影响整体尺度
因此模型可以用很小的模长变化实现大的方向旋转,或保持方向稳定,仅缩放权重强度
这在理论上恢复了 full fine-tuning 中观察到的现象
DoRA 在低秩设置下提升尤其明显
在 rank 很小(如 4, 8)时LoRA 的表达能力严重受限,每一次方向改变都会“浪费”参数去同时调整模长
而 DoRA 把有限的低秩参数全部用于“方向调整”,把“模长自由度”单独交给 $m$
结果是在极低 rank 下,DoRA 的有效表达能力显著高于 LoRA,指令微调、few-shot 场景中 sample efficiency 更高
伪代码
GLoRA(Generalized-LoRA)

标准 LoRA 只通过“加法”改变权重,不改变输入、激活或偏置的缩放结构,表达能力受限于低秩与仅加性更新,这在复杂任务(分布变化大、非线性强)上可能不够
GLoRA 的假设是 LoRA 只改变“权重的加性部分”还不够,更强的适配需要权重缩放、激活缩放、偏置修正,但仍希望训练时参数可学习推理时不引入额外结构或计算,因此提出了 Generalized-LoRA(GLoRA)
GLoRA 对线性层的更新为:
f(x)=(W0+W0A+B)x+CW0+Db0+E+b0冻结参数 $W_0$:预训练权重、$b_0$:预训练偏置
可训练参数:
$A$:权重缩放(右乘),相当于对原始权重进行任务相关的 re-scaling,能表达通道级、子空间级的适配
$B$:LoRA-style 权重增量,等价于 LoRA 的 $\Delta W x$,负责主要的方向性变化
$C$:输出平移(activation shift),类似一个 data-independent 的残差,用于任务级 bias / prior 注入
$D$:偏置缩放
$E$:偏置平移
其中 A、B、C 矩阵都可以进行低秩分解来减少参数量;A、C、D、E 可以退化为对角矩阵/向量/标量,从而严格控制参数预算
模型合并,所有可学习参数在训练后都可以合并进:
新权重:
W′=W0+W0A+B新偏置:
b′=b0+CW0+Db0+E
伪代码
AdaLoRA
出发点
标准 LoRA 有一个关键超参数:秩 $r$,问题在于:
$r$ 在训练前固定,但是不同层、不同任务对 rank 的需求差异极大
统一使用相同 $r$ 会导致:有些层 rank 过高,浪费参数,而有些层 rank 不够,限制性能
AdaLoRA 的核心目标是在给定参数预算下,自动把 rank 分配到“更重要”的层和方向上,训练过程中动态降低不重要的 rank
AdaLoRA 将 LoRA 的更新写成一种 SVD-like 形式:
W=W0+WAΛWB其中 $W_A \in \mathbb{R}^{d_{\text{in}} \times r}$、$W_B \in \mathbb{R}^{r \times d_{\text{out}}}$、$\Lambda \in \mathbb{R}^{r \times r}$ 是对角矩阵
可以把它类比为:
ΔW≈i=1∑rλiuivi⊤每一维 rank 都有一个独立的重要性系数 $\lambda_i$,而 rank 是否“有用”,由 $\lambda_i$ 决定
AdaLoRA 的核心思想是剪掉不重要的奇异值
并非所有 rank 维度对 loss 同样重要,如果某个 $\lambda_i$ 对 loss 影响很小,就可以把这一 rank 删除
因此 AdaLoRA 在训练中不断计算每个 rank 维度的重要性分数,剪掉分数最低的 rank,逐步降低有效秩
AdaLoRA 定义 importance score 来衡量当前 rank 维度对 loss 的影响程度
分数依赖于参数本身 $W_A, W_B, \lambda$ 和梯度信息 $dW_A, dW_B, d\lambda$
形式上是一个加权组合
为了避免抖动,AdaLoRA 使用指数滑动平均(EMA)平滑 importance score
Rank 剪枝(pruning)过程
给定当前 rank $r$ 和 目标剪枝数 $k$
计算 importance score $s \in \mathbb{R}^r$,找到最小的 $k$ 个维度
对这些维度执行剪枝:将对应的 $\lambda_i = 0$,停止这些维度的梯度更新,等价于删除对应 rank
这样,有效 rank 从 $r$ 变为 $r-k$
为了让 SVD-like 解释成立,AdaLoRA 还引入了 $W_A$ 和 $W_B$ 的正交正则项,目的是为了减少不同 rank 维度之间的信息冗余,让每个 $\lambda_i$ 更“可解释”
相关实验发现,Transformer 的浅层不需要高 rank 更新,而深层对 rank 更敏感,AdaLoRA 会自动把 rank “迁移”到深层
AdaLoRA 的代价
需要维护额外状态变量:$I$、$\bar I$、$\bar U$、$S$
剪枝过程依赖梯度统计和EMA
当模型很大或初始 rank 很高时,内存开销显著
所以后来的工作尝试选择更轻量 rank 或无需额外状态的自适应 LoRA
伪代码
GaLore
GaLore 要解决的根本问题
大多数 PEFT 方法(LoRA、Adapter、Prefix 等)的共同特点是冻结大部分模型参数、只训练一小部分参数,用“参数受限”换取“显存节省”
但这样做有一个根本代价:表达能力下降,和全量微调之间存在不可避免的性能差距
GaLore 的核心问题意识是全量微调真正吃显存的不是参数本身,而是优化器状态(动量和方差),特别是 Adam 类优化器需要存储和参数等大的一阶动量和二阶动量,总显存 $\approx 3 \times |\theta|$
GaLore 不减少可训练参数数量,而是在低秩子空间中表示梯度、做动量更新、做正则化,然后再把更新后的梯度投影回原空间
即参数是 full-rank,但是梯度统计是 low-rank
GaLore 和 LoRA 的对比
LoRAGaLore是否冻结参数
是
否
是否低秩参数
是($\Delta W$)
否
是否低秩梯度
否
是
显存节省来源
参数 + 梯度
优化器状态
表达能力
受限
接近全量微调
数学流程
假设当前参数为 $w$,梯度为 $G = \nabla_w \mathcal{L}$
(1) 梯度的低秩分解
对梯度矩阵做 SVD 分解:
G=UΣV⊤选择较小的一侧作为投影基,若 $m < n$,选 $U$,否则选 $V$,记投影矩阵为 $P$
(2) 梯度投影到低维空间
G′=P⊤G$G'$ 是低维梯度,后续优化器状态都只维护在这个空间中
(3) 低维空间中的 Adam 更新
在低维空间维护一阶动量 $m$ 和二阶动量 $v$,并做标准 Adam 更新:
g^=v+ϵm
(4) 投影回原始参数空间
G~=α⋅(Pg^)(5) 最终参数更新:
w←w−ηG~
假设参数维度 $D$,投影维度 $d \ll D$,Adam 状态显存从 $O(D)$ 降低到 $O(d)$,但参数本身仍是 full-rank
GaLore 的理论分析表明大模型的梯度天然集中在低秩子空间,只在该子空间中维护历史统计,不会显著损害优化轨迹
伪代码
Quantization and LoRA (QLoRA)

LoRA 仍然基于大模型本身
LoRA 的基本假设是冻结 backbone LLM,只训练低秩矩阵 $\Delta W = W_A W_B$
这在训练参数数量上非常省,但存在一个被忽略的问题:冻结的 backbone 仍然以 FP16 / BF16 / FP32 存在于 GPU 中
也就是说,LoRA 解决了“反向传播”,但没解决“模型本体太大”
QLoRA 的目标是
在不损失 LoRA 效果的前提下,把 frozen backbone 的显存占用压到极限
关键洞察是冻结权重不需要高精度,只要前向数值足够稳定即可
4-bit NormalFloat (NF4)
QLoRA 使用了一种新的 4-bit 量化格式:NormalFloat 4(NF4)
假设权重服从近似正态分布,使用非均匀量化点,在 4-bit 下最大化信息保留
相比 INT4 和 FP4,NF4 在语言模型权重上表现更稳定
这样,backbone 权重从 BF16(2 bytes)降到 4-bit(0.5 bytes),显存直接缩小 4 倍
Double Quantization(量化的量化)
量化权重通常需要 scale 和 zero-point,这些量化常数本身是 FP16 / FP32,会带来额外显存开销
QLoRA 引入对量化常数再做一次量化,即权重被量化,量化参数也被量化
Optimizer State Paging(CPU–GPU 分页)
即使 LoRA 参数很小,Adam 仍然可能在梯度 spike、梯度累积、多任务 batch时造成显存峰值
QLoRA 的解决方案是将 optimizer states 放在 CPU,按需 paging 到 GPU,这使得单卡消费级 GPU 也能训 65B 模型
QloRA 在训练时:
backbone:4-bit NF4 + frozen
LoRA 参数:FP16 / BF16 + trainable
前向:量化权重 on-the-fly dequant
反向:梯度只流经 LoRA
一个现实问题是 QLoRA 训练完成后,通常希望部署一个全量化模型,但研究发现对 LoRA-tuned 模型再做 post-training quantization,性能明显下降,原因在于 LoRA 学到的更新假设权重是高精度的,导致训练阶段与部署阶段数值分布不一致,从而引出了 Group-wise Quantization
混合方法
一些方法将多个 PEFT 类别中的思想结合在一起,这种做法允许在不同的算法权衡之间进行组合,以针对特定目标进行优化,例如减少可训练参数的数量
MAM Adapter 同时结合了 Adapter 和 Prompt Tuning
UniPELT 在此基础上进一步引入了 LoRA
Compacter 和 KronAresB 通过使用 Kronecker 积对 Adapter 进行重参数化,从而减少其参数量
下表比较了不同 PEFT 方法在存储(disk)、内存(RAM)以及计算效率方面的表现
计算效率包括反向传播成本(BP)的降低以及推理阶段的额外开销(inference overhead)
✓ 表示该方法在该维度上优于全参数微调,✗ 表示劣于全参数微调
A:基于额外参数的方法
S:选择性方法
R:基于重参数化的方法
表 2 展示了不同 PEFT 方法在不同模型规模(<1B、<20B、>20B 参数)上的评估情况,以及文献中报告的典型可训练参数比例
%Trainable parameters:可训练参数占模型总参数的百分比
%Changed parameters:训练后发生变化的参数占比
Adapters
0.1–6
0.1–6
✓
✓
✓
AdaMix
0.1–0.2
0.1–0.2
✓
✗
✗
SparseAdapter
2.0
2.0
✓
✗
✗
BitFit
0.05–0.1
0.05–0.1
✓
✓
✓
DiffPruning
200
0.5
✓
✗
✗
Fish-Mask
0.01–0.5
0.01–0.5
✓
✓
✗
Prompt Tuning
0.1
0.1
✓
✓
✓
Prefix-Tuning
0.1–4.0
0.1–4.0
✓
✓
✓
IPT
56.0
56.0
✓
✗
✗
MAM Adapter
0.5
0.5
✓
✗
✗
Parallel Adapter
0.5
0.5
✓
✗
✗
Intrinsic SAID
0.001–0.1
100
✓
✓
✗
LoRA
0.01–0.5
约 30
✓
✓
✓
DoRA
0.01–0.5
约 30
✗
✓
✗
UniPELT
1.0
1.0
✓
✗
✗
Compacter
0.05–0.07
约 0.1
✓
✓
✗
PHM Adapter
0.2
约 1.0
✓
✗
✗
KronA
0.07
约 30.0
✓
✗
✗
KronAresB
0.07
约 1.0
✓
✗
✗
(IA)3
0.02
0.02
✗
✓
✗
Ladder Side-Tuning
7.5
7.5
✓
✓
✗
FAR
6.6–26.4
6.6–26.4
✓
✗
✗
S4-model
0.5
>0.5
✓
✓
✗
LlaMA-Adapter

详细细节

LlaMA-Adapter-detail 核心结构
Adapter Prompt
LLaMA-Adapter 引入了一组 learnable adapter tokens,长度通常很短(如 10–20 tokens),维度与 LLaMA hidden size 相同,不来自 tokenizer,直接作为 embedding 学习
但关键区别在于:它们不是简单拼接在输入序列前,而是通过 attention 机制注入
Zero-initialized Attention
Adapter Prompt 通过一个额外的 attention 分支注入:
Query:来自原始 token
Key / Value:来自 adapter prompt
该 attention 分支 初始化为 0
初始阶段几乎不影响原模型行为
这带来两个重要好处:
训练稳定(不破坏预训练分布)
适合小数据 / 指令微调
在每一层 Transformer block 中原始 self-attention 保持不变,新增一条 adapter-attention 路径,两者输出相加
可以理解为,LLaMA 主干负责“语言能力”,而 Adapter Prompt 负责“新任务偏置”
前向传播过程
设 $X$ 为原始 token hidden states,$P$ 为 adapter prompt(可学习)
原 attention:$\text{Attn}_{\text{orig}}(X)$
Adapter attention:$\text{Attn}_{\text{adapter}}(Q=X,\ K=P,\ V=P)$
最终输出:
X′=X+Attnorig(X)+Attnadapter(X,P)
伪代码
Last updated
Was this helpful?