【LLM进阶-后训练&部署】3. PEFT训练 (参数高效微调,如LoRA等)


PEFT,全称是 参数高效微调 (Parameter-Efficient Fine-Tuning),是一套用于调整大型预训练模型(如大语言模型LLM)以适应特定下游任务的方法论,其核心思想是在 极小化计算和存储资源 的前提下,实现与全量微调(Full Fine-tuning)相媲美的模型性能。

一、 重参数化方法(Reparameterization-based)

1. LoRA (Low-Rank Adaptation)
  • 工作原理 :大模型虽然参数量巨大,但在学习特定的下游任务时,真正需要改变的参数空间其实非常小(即低秩的)。基于这个思想,LoRA 不去碰(冻结)原来那个庞大的权重矩阵 W0W_0W0,而是用两个很小的矩阵 AAA 和 BBB 相乘,来模拟原本需要更新的参数变化量 ΔW\Delta WΔW

    • 原来的前向传播: h=W0xh = W_0xh=W0x

    • 全量微调: h=(W0+ΔW)xh = (W_0 + \Delta W)xh=(W0+ΔW)x (此时你要训练完整的庞大矩阵 ΔW\Delta WΔW)

    • LoRA 微调: h=W0x+BAxh = W_0x + BAxh=W0x+BAx

      其中,xxx 的维度是 k×1k \times 1k×1,矩阵 AAA 的维度是 r×kr \times kr×k,矩阵 BBB 的维度是 d×rd \times rd×r。这里的 rrr 就是"秩"(Rank),它是一个远小于 ddd 和 kkk 的值(即 r≪min⁡(d,k)r \ll \min(d,k)r≪min(d,k))。

      通过这种"降维 (Ax=r×1Ax=r \times 1Ax=r×1) 再升维 (BAx=d×1BAx=d \times 1BAx=d×1) "的操作,需要训练的参数量直接呈指数级下降,极大地节省了显存和算力。

  • 额外增加的网络结构 (BA) 加在哪里? 这个额外的网络结构(即矩阵 AAA 和 BBB 组成的旁路分支),是 并联(旁路添加) 在原模型的特定层上的。在实际操作中,大语言模型(如 LLaMA、ChatGLM 等)主要由 Transformer 结构组成。LoRA 的旁路通常会加在 Transformer 块中的 线性投影层(Wq,Wk,Wv,WoW_q, W_k, W_v, W_oWq,Wk,Wv,Wo 以及 前馈神经网络(MLP)层) 上。

  • LoRA 微调的重要参数及其设置建议

参数名称 含义说明 设置建议
r (Rank) 秩的大小。 决定了矩阵 AAA 和 BBB 的维度,直接影响训练参数量和模型的表达能力。 一般从 816 开始尝试。如果任务非常复杂(比如注入大量新知识),可以增大到 32 或 64;如果只是简单的格式对齐或风格微调,r=4r=8 足矣。过大会增加过拟合风险。
lora_alpha 缩放系数。 LoRA 实际作用于原输出时,会乘上一个缩放因子 αr\frac{\alpha}{r}rα。它决定了 LoRA 权重对最终结果的影响力度。 一个经典的经验法则是:lora_alpha 设置为 r 的 1 倍或 2 倍 (例如 r=8r=8r=8 时,α=16\alpha=16α=16)。这样可以在改变 rrr 时保持权重的尺度相对稳定。过大会导致BA影响过大,甚至导致训练时梯度爆炸。过小则会导致效果不明显,训练时loss无法下降。
target_modules 目标模块。 指定将 LoRA 旁路添加到原模型的哪些网络层。 最基础的设置是 ["q_proj", "v_proj"]。但目前的最佳实践表明,应用到所有的线性层(Linear/Dense)(如 q, k, v, o, gate, up, down)通常能取得最好的微调效果。
lora_dropout 丢弃率。 用于防止过拟合的正则化手段,在训练时随机使部分神经元失活。 通常设置为 0.05 到 0.1。如果是数据量极小且很容易过拟合的任务,可以稍微调高到 0.1。
  • 局限性
    • 超参敏感 :需要手动调节秩(Rank rrr)和缩放系数(Alpha α\alphaα),调参不当会导致不收敛或效果差。
    • 复杂逻辑任务天花板:在极其复杂的推理任务或严重的领域偏移(Domain Shift)场景下,极低秩的 LoRA 效果有时仍略逊于全量微调(Full Tuning)。
2. QLoRA
  • 工作原理:将预训练模型的高精度权重(如 FP16)量化为极低精度的 4-bit NormalFloat (NF4) 格式以大幅缩减显存占用。同时引入"双重量化"和"分页优化器"技术防止内存溢出。在这个 4-bit 的冻结底座上,依然使用 FP16/BF16 训练常规的 LoRA 矩阵。
  • 局限性
    • 训练速度慢:因为在前向和反向传播时,必须将 4-bit 权重反量化(Dequantize)回 16-bit 参与计算,这增加了大量的计算开销,导致训练时间通常比常规 LoRA 长。
    • 精度损耗:由于极度压缩,对于某些对数值敏感的任务(如数学计算、代码生成),可能会出现极其轻微的性能下降。
3. AdaLoRA
  • 工作原理 :不同网络层对任务的"重要性"是不同的。AdaLoRA 通过模拟奇异值分解(SVD),在训练过程中动态评估各层的权重矩阵重要性。重要的层分配更高的秩(分配更多参数),不重要的层分配极低的秩甚至裁剪掉。

    传统的 LoRA 通过两个矩阵相乘来模拟权重变化:ΔW=BA\Delta W = B AΔW=BA。而 AdaLoRA 将这个增量矩阵参数化为奇异值分解(SVD)的形式:ΔW=PΛQ\Delta W = P \Lambda QΔW=PΛQPPP 和 QQQ:分别代表左奇异向量和右奇异向量,在训练中受到正交性约束。Λ\LambdaΛ:一个对角矩阵,对角线上的元素即为"奇异值"。在这个结构中,Λ\LambdaΛ 中的奇异值大小直接决定了对应秩(Rank)的重要性。

    初始高秩 :训练初期,AdaLoRA 会给所有目标模块分配一个较高的初始秩(init_r)。
    逐步剪枝 :随着训练的进行,模型会根据计算出的"重要性分数",逐步将 Λ\LambdaΛ 中得分最低的奇异值置为 0(即剪枝)。
    达到目标:这个剪枝过程会在指定的训练步数内持续进行,直到整个模型中非零奇异值的总数(即平均秩)下降到我们预设的最终目标秩(target_r)。

  • AdaLoRA 的训练超参数:

参数名称 类别 含义与作用 典型值 / 补充说明
init_r 核心预算 初始秩。训练初期分配给所有目标模块的较高 Rank 值,为模型提供足够的探索和剪枝空间。 通常设为 12, 16 或略高于你的目标秩
target_r 核心预算 目标平均秩。训练结束时期望达到的模型整体平均 Rank 值。模型会自适应地将参数集中分配到重要模块。 比如 8(根据你的显存预算和模型规模决定)
tinit 剪枝调度 初始预热步数。训练开始后,前多少步只更新参数而不进行剪枝(Warmup 阶段)。 视总训练步数而定,如 200
tfinal 剪枝调度 最终停止步数。训练进行到多少步时停止剪枝,固定当前的 Rank 结构继续微调。 通常设为总训练步数的 70%~80%
deltaT 剪枝调度 剪枝间隔步数。每隔多少个训练 Step 执行一次重要性打分和奇异值剪枝操作。 10 步,太小会增加计算开销,太大会影响剪枝平滑度
beta1 重要性评估 滑动平均系数 1。用于平滑处理当前步的权重和梯度,计算重要性分数的动量参数。 默认通常为 0.85
beta2 重要性评估 滑动平均系数 2 。同上,通常配合 beta1 使用,类似于 Adam 优化器中的机制。 默认通常为 0.85
ortha 正则化 正交惩罚系数 。损失函数中正交性正则化项的权重,确保 PPP 和 QQQ 矩阵保持正交。 默认通常为 0.1
lora_alpha 基础 LoRA 缩放因子 。控制增量矩阵 ΔW\Delta WΔW 对原始模型权重的缩放比例。 通常设为 target_r 的 1 到 2 倍(如 16 或 32)
lora_dropout 基础 LoRA Dropout 概率。在应用 LoRA 层之前对输入使用的 Dropout,用于防止过拟合。 一般为 0.050.1
target_modules 基础 LoRA 目标模块。指定要插入 AdaLoRA 结构的层名称。 ["q_proj", "v_proj"]["query", "value"]
  • 局限性
    • 计算开销大:在训练过程中频繁计算重要性分数并动态调整参数预算,使得底层代码实现复杂,且略微拖慢训练速度。
4. DoRA (Weight-Decomposed LoRA)
  • 工作原理:DoRA 的提出是为了解决标准 LoRA 的一个痛点:LoRA 在更新权重时,幅度和方向的更新是高度正相关的,而研究发现,全量微调(FT)中幅度和方向的更新呈现出一定程度的负相关(即幅度变小通常伴随方向的剧烈变化,反之亦然)。为了打破 LoRA 的这种限制,DoRA 引入了权重分解机制。将预训练权重矩阵分解为两部分:"幅度向量(Magnitude)"和"方向矩阵(Direction)"。微调时,幅度向量作为一个参数量极小的 1D 向量被全量微调,而方向矩阵则使用 LoRA 进行微调。

    任何一个预训练权重矩阵 W∈Rd×kW \in \mathbb{R}^{d \times k}W∈Rd×k 都可以被分解为一个幅度向量 m∈R1×km \in \mathbb{R}^{1 \times k}m∈R1×k 和一个方向矩阵 V∈Rd×kV \in \mathbb{R}^{d \times k}V∈Rd×k:W=mV∣∣V∣∣cW = m \frac{V}{||V||_c}W=m∣∣V∣∣cV其中,∣∣V∣∣c||V||_c∣∣V∣∣c 是矩阵 VVV 每列的向量范数。通过这种分解,权重的大小(mmm)和权重的方向(V∣∣V∣∣c\frac{V}{||V||_c}∣∣V∣∣cV)被完全解耦。

  • DoRA的训练超参数

参数名 含义说明 常用建议值 / 注意事项
use_dora DoRA 核心开关:是否启用权重分解。 True (在 PEFT 库中只需这一行配置即可从 LoRA 切换到 DoRA)。
r (Rank) 低秩矩阵的秩,决定了方向矩阵更新的参数规模和表达能力。 通常为 8, 16, 32, 64 。任务越复杂,r 值应适当增大,但显存占用也会随之增加。
lora_alpha 缩放系数,决定方向更新矩阵对原始预训练权重的影响权重。 经验法则是设为 r1倍或2倍(例如:r=16 时,alpha 设为 16 或 32)。
target_modules 指定应用 DoRA 的模型组件(通常是各类线性层)。 建议覆盖所有线性层 (如 q_proj, v_proj, k_proj, o_proj, gate_proj, up_proj, down_proj)。DoRA 覆盖越全,性能越逼近全量微调。
lora_dropout 为了防止低秩矩阵过拟合而设置的 Dropout 概率。 通常设置为 0.050.1
  • 局限性
    • 虽然效果往往优于 LoRA,但由于需要进行权重分解的范数计算,它的训练时间、反向传播的内存占用均略高于原生 LoRA。
5. PiSSA (Principal Singular values and Singular vectors Adaptation)
  • 工作原理 :普通 LoRA 的 AAA 和 BBB 矩阵是随机初始化的。PiSSA 则在微调前,对预训练权重进行一次真实的主成分奇异值分解(SVD),用最重要的主成分来初始化 AAA 和 BBB 矩阵,冻结剩下的残差部分。
  • PiSSA训练超参数 : 与LoRA一致,但是一般会有一个--init_weights=pissa (ms-swift框架)或 --init_lora_weights=pissa(PEFT框架)参数可以指定初始化权重方式为PiSSA。
  • 局限性
    • 初始化成本高:对几百亿参数的大模型权重做 SVD 分解极其耗费显存和时间,初始化的预备阶段成本偏高。
6. 不同LoRA框架的对比
技术名称 核心亮点 适用场景与总结 推荐指数
LoRA 经典低秩微调,冻结原模型,只训练极少参数。 万金油。如果不受显存限制,且不想折腾超参数,直接用 LoRA 最稳妥。 ⭐⭐⭐⭐⭐ (最稳)
QLoRA 模型 4-bit 量化 + LoRA。 硬件资源受限时的唯一神。适合在单卡或消费级显卡(如 RTX 3090/4090)上微调 7B~70B 大模型。 ⭐⭐⭐⭐⭐ (最火)
AdaLoRA 动态分配秩(Rank)。有的层需要多学,有的层不需要。 追求极致参数效率。在给定的极低参数预算下,AdaLoRA 效果比固定 Rank 的 LoRA 好,但实现复杂,训练可能稍慢。 ⭐⭐⭐
DoRA 权重分解为"方向"和"幅度"。高度逼近全参数微调。 追求极致模型性能 。几乎是 LoRA 的免费升级版,同等参数下效果更好,目前在各大框架中(如 PEFT)已经支持只需加一个参数 use_dora=True ⭐⭐⭐⭐ (性能佳)
PiSSA SVD 主成分初始化。收敛极快,误差小。 追求更快的收敛和更好的量化效果 。目前 HuggingFace PEFT 也已原生支持(init_lora_weights="pissa"),是取代传统 LoRA 初始化的极佳方案。 ⭐⭐⭐⭐ (潜力大)

二、 添加式方法(Additive Methods)

1. Adapter Tuning
  • 工作原理:在 Transformer Block 的核心组件(如 Self-Attention 和 FFN)之后,串联插入一个小型的神经网络模块(通常是两层 MLP,先降维再升维)。冻结原模型,只训练这些新插入的 MLP。
  • 局限性
    • 推理延迟(Latency):由于 Adapter 是"串行"插入的,数据必须先经过原模型网络,再经过 Adapter。这改变了模型结构,增加了真实的推理耗时(通常增加 10%~20% 延迟)。
2. Prompt Tuning
  • 工作原理:不改动模型内部,只在输入的 Token 序列最前面,拼接(Concat)上几个到几十个虚拟的"软提示(Soft Prompts)"向量。模型反向传播时只更新这几个虚拟 Token 的 Embedding 向量。
  • 局限性
    • 极难优化:非常依赖初始化的质量,训练容易陷入局部最优,收敛极慢。
    • 吃模型规模:通常只在参数量达到百亿或千亿级(如 100B)的超大模型上,表现才能媲美全量微调;在小模型上效果很差。
    • 占用上下文:虚拟 Token 会占用模型宝贵的输入上下文长度。
3. Prefix Tuning / P-Tuning v2
  • 工作原理 :不仅在输入层加,而是在 Transformer 每一层 的 Multi-Head Attention 中的 Key(键)和 Value(值)矩阵前面,拼接上一段可训练的虚拟"前缀(Prefix)"。
  • 局限性
    • 吞噬 KV Cache:这些虚拟的前缀需要永久驻留在每一层注意力的 KV Cache 中。这意味着它挤占了原本属于用户输入数据的 KV Cache 空间,导致模型实际可处理的序列长度缩短,也会轻微降低推理吞吐量。
4. IA³ (Infused Adapter)
  • 工作原理 :在 Transformer 中引入三个可学习的向量,分别与 Attention 的 Key、Value 以及 FFN 的中间激活值进行逐元素相乘(Element-wise Scaling),以此缩放特征的激活强度。
  • 局限性
    • 表达能力受限:逐元素缩放的数学表达能力远不及矩阵乘法(LoRA)。对于需要注入大量新领域知识的任务,IA³ 往往显得"力不从心"。

三、 选择式方法(Selective Methods)

1. BitFit
  • 工作原理 :神经网络的线性层由 y=Wx+by = Wx + by=Wx+b 组成。BitFit 直接冻结所有庞大的权重矩阵 WWW,只解冻并更新所有的偏置项 bbb(Bias)。
  • 局限性
    • 天花板极低:Bias 的参数量不到万分之一。如果微调任务与预训练任务差异巨大,或者需要模型学习全新语言/复杂逻辑,仅靠修改偏置项根本无法做到,很容易欠拟合。
2. Diff Pruning
  • 工作原理:为全量参数学习一个极度稀疏的"差异掩码(Sparse Mask)"。通过正则化手段,强迫网络在微调时只有极少数(如 0.5%)对当前任务最关键的权重发生改变,其余保持为 0。
  • 局限性
    • 非结构化稀疏难以加速:虽然理论上更新的参数极少,但在实际的 GPU 硬件底层,计算非结构化的稀疏矩阵效率很低。通常需要定制的 CUDA 算子才能真正省下显存和加速,工程落地难。

四、 表示微调(Representation-based)

1. ReFT / LoReFT
  • 工作原理:跳出了"修改权重参数"的思维定势,转而"干预神经元的激活值"。它在前向传播经过特定层时,将模型的隐状态(Hidden States)投射到一个低秩的正交子空间中,对其进行修改,然后再合并回去。
  • 局限性
    • 生态不成熟:由于是非常前沿的方法,目前 HuggingFace 等主流框架的原生支持度不如 LoRA 完善。
    • 干预位置难确定:需要实验决定干预哪些层、干预哪些 Token(例如仅干预 Prompt 的最后一个 Token 还是全部),比 LoRA 直接全局铺设要费心。

五、 统一与混合框架

1. UniPELT
  • 工作原理:一个缝合怪。将 LoRA(负责矩阵表达)、Prefix Tuning(负责注意力干预)和 Adapter(负责特征非线性变换)塞到一起,并设计一个"门控机制(Gating)"。模型在训练时自己决定对当前输入哪种方法更有效,门控权重会偏向那个方法。
  • 局限性
    • 训练极其笨重:哪怕每种 PEFT 单独都很小,把它们全实例化并加上门控网络,不仅导致微调时的显存消耗大幅增加,也丧失了 PEFT 原本"极致轻量优雅"的初衷。

总结一张图理解如何避坑:

  • 怕推理变慢? -> 绝对不要用 Adapter Tuning。选 LoRA 族。
  • 显存实在太小? -> 选 QLoRA 或 BitFit。
  • 要搞长文本且怕吃内存? -> 慎用 Prefix-Tuning / P-Tuning v2(吃 KV Cache),用 LoRA 或 LongLoRA。
  • 不懂底层的炼丹小白? -> 无脑闭眼选原生 LoRA 或 QLoRA,社区现成的代码直接 Run。

常见QA

Q1 : 以Qwen2.5-7B为例,使用梯度检查点后,fp16精度启动全参SFT需要多少显存?至少需要84.37 G。fp16占用2bytes,因此参数权重占用的显存为:27B=14G,记为 base
优化器需要存储 m,v(一阶动量,二阶记忆),精度一般为fp32。因此需要存储4
base

存储梯度值,一般与训练精度一致是bf16,因此需要存储 1base
激活值中间值,存储大约是 Batch_Size * Seq_Length * Hidden_Size * 层数数据精度,假设batch=1, 数据长度是2K,那么就是 12k358428
2Bytes=382M 。

总共占用 6*base + 382M = 84.37 G

相同情况下,LoRA与QLoRa训练时分别占用多少显存?

A1:

  • LoRA (16-bit) 训练显存计算:在常规 LoRA 中,底座模型依然以 FP16/BF16 加载。
  1. 原模型权重 (Base Weights): 精度为 FP16(2 Bytes)。全部冻结。

    占用:7B×2 Bytes=14 GB7\text{B} \times 2\text{ Bytes} = \mathbf{14\text{ GB}}7B×2 Bytes=14 GB

  2. LoRA 权重 (Trainable Weights):精度为 FP16(2 Bytes)。

    占用:35M×2 Bytes≈70 MB35\text{M} \times 2\text{ Bytes} \approx \mathbf{70\text{ MB}}35M×2 Bytes≈70 MB (几乎可以忽略)

  3. 优化器状态 (Optimizer States):精度一般为 FP32。因为 AdamW 需要存一阶动量(m)、二阶动量(v)和 FP32 的主权重(Master Weights),共计 12 Bytes。(注意:这 12 Bytes 只乘在 35M 上,而不是 7B 上!)

    占用:35M×12 Bytes≈420 MB35\text{M} \times 12\text{ Bytes} \approx \mathbf{420\text{ MB}}35M×12 Bytes≈420 MB

  4. 梯度 (Gradients): 与训练精度一致,为 FP16/BF16(2 Bytes)。同样只有 35M 参数有梯度。

    占用:35M×2 Bytes≈70 MB35\text{M} \times 2\text{ Bytes} \approx \mathbf{70\text{ MB}}35M×2 Bytes≈70 MB

  5. 激活值 (Activations):开启梯度检查点(Gradient Checkpointing)后,虽然不用存前向传播的完整计算图,但仍需保留一定量的中间激活值用于计算 LoRA 分支的梯度。这部分开销基本和全参 SFT 类似,甚至略大一点点(因为多了并联分支)。

    占用:预估约 0.5 GB∼1 GB\mathbf{0.5\text{ GB} \sim 1\text{ GB}}0.5 GB∼1 GB(取 1GB 计算)

    总共占用 (LoRA): 14 GB + 70 MB + 420 MB + 70 MB + 1 GB ≈ 15.56 GB

  • QLoRA (4-bit) 训练显存计算: 在 QLoRA 中,所有的变量开销与上述 LoRA 完全一致,唯一的区别在于底座模型权重的存放格式。
  1. 原模型权重 (Base Weights):精度被极度压缩为 4-bit (NF4格式,0.5 Bytes)。

    占用:7B×0.5 Bytes=3.5 GB7\text{B} \times 0.5\text{ Bytes} = \mathbf{3.5\text{ GB}}7B×0.5 Bytes=3.5 GB (实际框架中往往有一些量化块的额外索引开销,算作 4 GB)

  2. LoRA 权重、优化器、梯度、激活值:这些全部保持 16-bit 或 32-bit 参与运算,占用大小与上面的常规 LoRA 完全一模一样!因为你要保证微调的精度。

    合计占用:70 MB + 420 MB + 70 MB + 1 GB ≈ 1.56 GB

    总共占用 (QLoRA): 3.5 GB (算作 4 GB) + 1.56 GB ≈ 5.56 GB

总结对比表

训练模式 底座精度 底座显存占用 优化器/梯度等开销 (针对 7B) 总显存需求 (不考虑其他开销,仅从理论上计算的最小值) 能跑的最低显卡
全参SFT FP16 14 GB ∼70\sim 70∼70 GB (作用于 7B) ∼85\sim 85∼85 GB 2 × A6000 或 A100
LoRA FP16 14 GB ∼1.5\sim 1.5∼1.5 GB (仅作用于 35M) ∼16\sim 16∼16 GB 1 × RTX 4080 (16G)
QLoRA 4-bit ∼4\sim 4∼4 GB ∼1.5\sim 1.5∼1.5 GB (仅作用于 35M) ∼6−8\sim 6-8∼6−8 GB 1 × RTX 3060 (12G)
相关推荐
绘梨衣的sakura路1 小时前
[特殊字符] 2026 年 AI 自动化新范式:OpenClaw 核心 Skill 精选与实战指南
运维·人工智能·自动化
智算菩萨1 小时前
通用人工智能(AGI)的定义与ChatGPT 5.4的AGI资格评估
人工智能·ai·语言模型·chatgpt·agi
用户4815930195911 小时前
MCP 终极指南(基础篇):Anthropic 的"USB-C接口",为什么能改变 AI 工具生态
人工智能
两万五千个小时1 小时前
学习 Pi Coding Agent:系统提示词与工具设计深度解析
javascript·人工智能·架构
运维帮手大橙子1 小时前
自动驾驶等级
人工智能·机器学习·自动驾驶
程序员小明儿1 小时前
OpenClaw-RL 实战 09|OPD教师模型训练:如何让AI从“后悔”中学会“聪明”?
人工智能·openai
Daydream.V1 小时前
OpenCV高端操作——直方图及直方图均衡化
人工智能·opencv·计算机视觉
玦尘、1 小时前
光伏发电短期功率预测——从数据到模型的完整技术实践(LSTM · TCN · CNN-LSTM · TCN-LSTM)
人工智能·cnn·lstm·tcn
java1234_小锋1 小时前
基于LangChain的RAG与Agent智能体开发 - 使用LangChain调用大语言模型
人工智能·语言模型·langchain·rag