资讯动态

大模型参数高效微调全解析:从 P-Tuning 到 LoRA 的技术对比与选型

发布时间:2026/10/17 8:44:25 来源:尧图企业网站定制
聊大模型微调我猜不少人被“冻结参数”“加前缀”“插模块”这些词砸得有点晕。P-Tuning、Prefix Tuning、Adapter、LoRA名字听起来都像“微调”但底层思路和实际效果差别非常大。这篇文章我想把这四种方法放在一起重新梳理一遍重点放在“它们到底动了模型的什么”“训练和推理时的真实代价”以及“什么场景下该选谁”上。我尽量用实际操作中的感受来讲而不是把论文公式堆一遍。先说清楚这篇文章适合谁。如果你正准备微调一个模型或者已经在用其中某一种方法但说不清楚它为什么有效那这篇文章能帮你把这块拼图补上。如果你只是听说过 LoRA 很省资源想了解它和其他方法的本质区别也能找到答案。下面我从头拆解。1. 全量微调的三个痛点为什么必须找“省着点”的路子讲四种方法之前得先把“为什么要参数高效微调”这个问题摆清楚。很多人一上来就对比四种方法的参数数量、效果指标但如果不理解全量微调在真实工程里有多痛你就很难理解这些方法的设计动机更别说做选型。1.1 显存与算力的账一个7B模型到底要吃掉多少资源先算一笔账。假设你想全量微调一个7B参数的模型参数以FP16精度加载光模型权重就要占约14GB显存。你以为这就是全部远不止。优化器状态比如AdamW的动量项按FP32保存这部分又是模型参数量的8倍——7B乘以8约56GB。再算上梯度、激活值、中间变量一个7B模型全量微调的显存需求动辄70GB以上。我自己实际跑的时候用一张24GB的消费级显卡加载完模型加数据就已经快爆了根本没法训练。就算你有A100那种80GB的卡全量微调一个7B模型训练时间也让人头疼。更关键的是微调一次就产出一个完整的7B模型副本你可能同时维护5个下游任务的模型每个都是全量参数存储成本同样爆炸。参数高效微调PEFT的思路就是既然只改一小部分参数就能达到还不错的任务效果那我为什么非要把整个模型的参数都动一遍1.2 灾难性遗忘与多任务困境全量微调还有一个容易被低估的问题灾难性遗忘。当你用一个小规模的数据集去微调一个基座模型时模型原本在大规模语料上学到的通用知识会被“覆盖”掉一部分。举个我踩过的例子微调一个对话模型去做某项文案改写改完确实符合了目标风格但它回答普通闲聊的能力明显下降了。这就是典型的灾难性遗忘。参数高效微调因为只训练少量参数大部分原始模型权重被冻结所以对原始能力的破坏要小得多。这一点在实际部署时非常重要——你并不想为了一个具体任务把模型变成一个只会做单任务的“偏科生”尤其当这个模型还要同时服务多个需求的时候。1.3 参数高效微调的基本思路参数高效微调的核心思路就一句话在不大动模型原有参数的前提下通过额外引入少量参数或部分训练某些参数让模型适配新任务。后面要讲的四种方法本质上都是对“引入哪些参数”“怎么引入”这两个问题的不同回答。P-Tuning 和 Prefix Tuning 走的是“额外输入”路线它们在模型输入或内部状态上做文章引入的是虚拟的连续向量Adapter 走的是“结构改造”路线在Transformer层里面插入新的小模块LoRA 走的则是“低秩约束”路线用低秩矩阵去近似微调过程中的权重更新量。理解了这几个大方向再往下看各自的实现细节就不会觉得乱了。2. 派别划分的价值先搞清楚软提示派和结构改造派可能有人会觉得分了派别又能怎样反正最后都是调参。但我个人经验是这个分类直接决定了你在调参时的思考方向——出了问题你知道去改哪里效果不好你知道是哪个环节的锅。2.1 软提示派P-Tuning 与 Prefix Tuning 的共同基因P-Tuning 和 Prefix Tuning 都属于“软提示”Soft Prompt派。这个思路的源头其实是对Prompt工程的一种反思既然手动设计文本提示词又费劲又脆弱那我就把“提示词”变成一组可学习的连续向量让模型自己去学这组向量该怎么表达。打比方说传统Prompt像是你递给模型一张写着“请帮我把这段文字改得更正式”的纸条词是固定的而软提示派是你递给模型一张白纸但你先在上面涂了一层“隐形的墨迹”这层墨迹的形态由训练决定模型未必能读出人类能懂的含义但它就是有用。理解这个基因很重要因为它决定了 P-Tuning 和 Prefix Tuning 的共同特点可训练参数都在“输入侧”或“状态侧”而不是去修改模型内部那些已经学好的权重矩阵。2.2 结构改造派Adapter 与 LoRA 的思路结构改造派的思路完全不同。它们不是往输入里加东西而是直接修改模型本身的结构或参数更新方式。Adapter 的做法很直观在Transformer层里插入一个新的小型前馈网络模块训练时只更新这个小模块的参数。可以理解为在一台精密的机器里加了一个可以独立调节的小旋钮机器原有齿轮不动你只需要调旋钮来改变输出。LoRA 更精妙一点。它不修改模型结构也不增加额外的推理层而是把微调时权重矩阵的更新量 ΔW 用两个低秩矩阵的乘积去近似。这意味着训练时你只需要训练这两个小矩阵训练完之后可以把它合并回原权重里——结构上等于什么都没加只是权重变了。2.3 为什么这个分类对选型很关键这个分类对你选型有直接的指导意义。如果你希望微调之后的模型在推理时完全没有额外计算负担LoRA 是最优解因为推理时可以直接合并权重如果你不介意推理时多一点点计算想尽量保留灵活切换多个任务的能力那 Prefix Tuning 和 Adapter 可能更适合如果你只想在输入侧加一点可学习的东西不想动模型内部任何结构P-Tuning 最贴合你的需求。每次有人问我“这四种有什么本质区别”我都会用这个分类来回答。不是说效果好就完事了而是你得知道自己每次微调到底“调”了哪里。3. P-Tuning用连续向量替换人工设计的模板P-Tuning 应该是这四种方法里最容易理解的一个。它的出发点非常朴素既然人工设计语言模板费时费力那我把模板换成一组随机初始化、可训练的向量行不行答案是行而且效果往往比手动写模板更稳。3.1 核心机制prompt encoder 怎么工作P-Tuning 的典型实现方式是在输入序列的embedding层前面拼接一组可训练的“虚拟token”embedding。这组embedding的维度跟模型本身的embedding维度一致但它不对应词表里的任何词。关键细节是P-Tuning 通常不会直接把这组向量喂给模型而是先经过一个 prompt encoder通常是一个轻量级网络做一次变换。这个设计的目的是为了解决“直接在embedding空间优化向量”带来的训练不稳定问题——因为预训练模型的embedding空间已经分布得很复杂直接硬优化可能陷入较差的局部最优。用一个小的编码器先映射一下相当于让优化过程走了一条更平稳的路。从参数量上说P-Tuning 的额外参数包括一组 virtual token 的embedding 加上一个极小的 MLP 或 LSTM 结构。我在实际项目里用这种方式微调过一个小模型做文本分类可训练参数大约只占模型总量的 0.1% 左右效果却能达到全量微调的九成以上。3.2 关键参数与可训练参数计算P-Tuning 里有两个参数需要你自己定一个是 virtual token 的数量通常叫 sequence length用 n 表示一个是替换的层数或者加在哪些位置。以我常用的设置来说对于 7B 以内规模的模型virtual token 数设置在 8 到 20 之间表现都还可以。可训练参数的计算方式比较直接ntoken数乘以 hidden size模型隐藏层维度再加上 prompt encoder 的参数。比如 hidden size 是 4096n 取 10那光 embedding 部分就有约 40960 个参数加上 encoder 里的参数总量依然很小。注意不要因为 P-Tuning 参数少就无限加大 n。我试过把 virtual token 从 10 加到 50效果并没有线性提升反而在某些任务上出现了下降。原因是过长的连续提示会把真实输入的位置信息稀释掉模型分不清哪些是提示、哪些是内容。3.3 实践中的注意事项P-Tuning 有一个明显的短板它对模型内部层的“影响”比较间接。因为只改了输入侧模型内部每一层对“提示语义”的加工是逐层传递的深层网络可能已经把提示信息弱化了。所以我自己的体会是P-Tuning 更适合那种“输入输出映射关系清晰、任务不太复杂”的场景比如文本分类、情感判断这类任务。到了需要复杂推理和长文本理解的任务它的表现会开始吃力。另外P-Tuning 和接下来的 Prefix Tuning 经常被混为一谈但其实它们最大的区别就在“加在哪里”P-Tuning 只加在最前面的输入 embedding 上而 Prefix Tuning 每一层都要额外加前缀。4. Prefix Tuning把前缀信息注入每一层Prefix Tuning 最早是为了解决语言模型生成任务设计的后来被推广到了更多场景。它的核心变化是不再把可训练向量局限于输入层而是给Transformer的每一层都加上一组可训练的“前缀键值对”。4.1 与 P-Tuning 的本质区别理解 Prefix Tuning 的关键是要明白它操作的对象是 attention 层。在Transformer每一层的 self-attention 计算中会生成 Query、Key、Value。Prefix Tuning 的做法是在 Key 和 Value 上分别拼接一组可训练的前缀向量。你可以把 Key 理解为“内容的索引”Value 是“实际被提取的信息”。拼接前缀之后模型在做注意力计算时会把前缀信息和真实输入放在一起考虑相当于每一层都有一个统一的“任务提示”。这个设计和 P-Tuning 的最大差异在于P-Tuning 的提示只进过一次门而 Prefix Tuning 的提示在每一层都在场。所以 Prefix Tuning 对模型行为的“控制力”更强也更适合生成类任务因为生成过程中的每一步都能持续受到这个前缀的影响。4.2 训练与推理的差异inference 时前缀怎么处理这里有一个实操中容易忽略的点Prefix Tuning 在训练时前缀参数参与每一层的注意力计算但在推理时这些前缀向量本质上是在重复计算。你训练完一组前缀推理时要把它拼接到每一层的 Key 和 Value 上。因为有这个额外拼接操作推理时会有一些额外的计算开销不过这个开销比 Adapter 要小因为它不增加新的网络层只是增加了一小块参与注意力计算的向量。还有一个更实际的问题前缀长度prefix length直接决定了额外显存占用。如果前缀长度为 10等价于每一层的注意力序列长度多了10个位置。层数多的时候这个累加效应会很可观。我从实操感受来说prefix length 设置在 5 到 10 之间比较稳妥超过 20 之后训练显存会明显增加但效果未必同步提升。4.3 实测感受与边界我试过用 Prefix Tuning 微调一个生成式模型做特定风格回复。相比 P-Tuning它生成的内容风格一致性确实更好因为每一层都“知道”当前任务是风格转换。但它的调节能力也带来了另一个问题前缀参数很难在不同任务之间迁移。你为任务A训练出来的前缀放到任务B上基本没用甚至可能干扰。所以当你有很多细分任务需要频繁切换时Prefix Tuning 的维护成本其实不低。另外如果你的基座模型本身很小比如 1B 以下Prefix Tuning 的效果可能会受到限制因为前缀能携带的信息量受限于模型本身的容量。小模型本身的表达能力就有限你再“指挥”它也容易到天花板。5. Adapter在 Transformer 内部插入小型网络Adapter 是这四种方法里“动手改结构”最明显的一个。它直接在Transformer层内部插入一个小型前馈网络训练时只更新这个网络其余全部冻结。5.1 结构细节bottleneck 与残差连接一个标准的 Adapter 模块通常是两层结构先把隐藏状态向量从一个较大的维度如 768压缩到一个较小的瓶颈维度如 96再映射回原来的维度。这个“先降维再升维”的设计就是瓶颈结构它强迫信息通过一个窄通道从而让新学习到的表征更加紧凑、去冗余。它还带一个残差连接把输入直接加到输出上。这个设计很关键如果没有残差连接Adapater 模块在初始化时如果输出分布和输入不一致会直接扰动模型原有行为有了残差连接即使新模块还没学到什么输入也能“绕过”它继续流动相当于初始状态下这个插入件是“透明”的。这种做法在工程上给了我很大的安全感。你可以放心往模型里插模块不用担心初始化就导致模型崩溃。5.2 训练策略不同的适配层位置对效果的影响Adapter 的一个经典变体是不像 P-Tuning 那样只加在输入侧也不是每个 Transformer 层都加。它可以选择加在前几层、后几层、或者每一层都加。我实践下来的经验是对于大多数任务每隔一层加一个 Adapter 的效果就已经足够好参数量还能少一半左右。更值得提的是瓶颈维度的选择。我见过有人把瓶颈维度设得跟隐藏层一样大这种做法已经失去了“参数高效”的意义训练出来的效果也没有明显提升。比较合理的做法是瓶颈维度取隐藏层的四分之一到八分之一之间。比如隐藏层维度 1024瓶颈维度取 128 到 256 之间是一个平衡效果与开销的区间。5.3 推理代价Adapter 最大的短板在推理阶段因为模块是“插在”模型里的推理时它必须真正参与计算。你每插入一个 Adapter就多了一点点额外的矩阵乘法和激活函数计算。如果你插很多层累积的计算开销不可忽视。关于部署还需要注意一点Adapter 的参数是独立于主模型存在的部署时你需要同时加载主模型权重和对应的 Adapter 权重。好处是如果你想同时服务多个任务可以共享主模型按需加载不同的 Adapter 模块坏处是推理框架得改造一下不是所有现成框架都天然支持这种“模块插拔”。6. LoRA低秩分解带来的范式转变LoRA 应该是目前社区里最热门的微调方法我自己用得也最多。它的优点是足够优雅训练时只训练两个小矩阵推理时却能完全合并回主权重不给部署增加任何负担。6.1 数学原理为什么 W BA 能近似 ΔWLoRA 的出发点是一个观察预训练模型在微调时权重矩阵的更新量 ΔW 通常具有较低的内在秩。换句话说ΔW 虽然是完整大小的矩阵但它的有效信息可以用更少的维度表达。基于这个观察LoRA 将 ΔW 分解为两个矩阵的乘积ΔW B × A。假设你的权重矩阵是 d × d你选择一个秩 r让 A 是 r × dB 是 d × r。它们的乘积就是 d × d但总参数从 d×d 变成了 2×r×d。当 r 远小于 d 时参数量大幅降低。比如隐藏层维度是 4096全量矩阵参数是 4096×4096约 1600万。而 r8 时两个低秩矩阵的总参数是 2×8×4096约 6万5千差了约 250 倍。这就是 LoRA 省参数的来源。训练完成后你可以直接计算 W_new W_orig B × A把两个低秩矩阵合并进原权重。推理时完全不需要额外模块模型结构和原始模型一模一样。这一点在实际落地时太方便了——你不用改推理框架也不用担心额外的计算延迟。6.2 r 的选择与初始化细节关于秩 r 的选择实践里有几个常见误区。第一个误区是“r 越大越好”。我见过有人把 r 设成 256说是怕信息丢失结果训练明显变慢、显存上升效果却没有比 r16 好多少。对于 7B 及以下的模型r 取 8 到 32 之间是一个经验区间。更复杂的任务可以适当提高但很少需要超过 64。第二个容易忽略的是缩放参数 alpha 的设置。LoRA 中输出通常会乘以 alpha/r 这个缩放系数。这意味着 alpha 与 r 的比值影响实际更新量。一个常见的工程做法是固定 alpha 为 r 的两倍比如 r16 时 alpha32。但这不是铁律需要根据你的学习率一起调节。还有一个初始化细节通常 B 矩阵初始化为全零A 矩阵初始化为高斯分布。这样训练开始时 BA 乘积为零不会扰动原模型输出。这个初始化我在实践中非常推荐——即使你只有很小的学习率也能保证模型稳定起步。6.3 特有优势可插拔、可合并、可组合LoRA 还有一个独有优势来自“可插拔”特性。因为训练时你只训练了 A 和 B主权重没动所以可以在同一个基座模型上训练多个 LoRA 模块分别适配不同任务。部署时根据用户的请求类型动态加载不同的 LoRA 参数而主模型权重在内存中只需加载一份。这在服务多任务场景下可以省下大量显存。更进一步LoRA 模块之间可以组合与插值。有实验表明将两个不同任务训练出的 LoRA 权重按比例相加比如 0.7 与 0.3可以在一定程度上结合两个任务的能力。这种操作做起来非常简单直观但效果未必稳定——我试过几次成功的也试过几次直接崩坏的不可控因素较多。不过作为一种低成本探索手段它挺有意思的。7. 横向对比与选型决策什么时候该选谁把四种方法放在一起对比很多人第一个想看的就是性能和参数量。但我必须强调公开数据里的指标差异在你自己的数据集上未必复现。所以我把对比重心放在“工程特征”上这比单纯比效果更实在。7.1 四个维度的对比表格我把四种方法的关键特性整理成一个表格方便你快速对照。对比维度P-TuningPrefix TuningAdapterLoRA核心操作输入侧加虚拟token每层attention加前缀插入bottleneck模块低秩分解权重更新量可训练参数占比约0.1%约0.1%–1%约0.5%–2%约0.1%–1%推理额外开销几乎无少量有取决于层数无可合并权重部署复杂度低中中低任务切换便利性中低中高生成任务表现一般好较好好这张表只是帮助你从工程维度做初筛实际效果一定要在自己的数据上跑一笔才知道。7.2 不同场景的推荐组合根据我实际跑过的项目不同场景下一般会这样选如果你的任务只是文本分类、情感分析这类输入输出关系相对固定、推理链路不复杂的任务P-Tuning 就够用了训练快部署简单。如果你做的是生成类任务比如风格化写作、对话系统Prefix Tuning 对生成行为的控制会更直接但部署时要小心推理时的额外前缀计算。如果对效果上限要求高同时GPU显存不多那 LoRA 基本是首选。它在各种任务上的泛化能力已经被社区反复验证工程上你唯一要小心的是 r 和 alpha 的取值。如果您想在模型内部加“可插拔的小脑”且推理延迟不是瓶颈Adapter 值得一试不过部署框架要额外做点支持工作。7.3 混合使用进阶LoRA P-Tuning 的效果最后说一个稍微进阶的思路这些方法并不是互斥的。实际项目中我就试过同时用 LoRA 和 P-Tuning——LoRA 负责改变模型内部的权重更新方式P-Tuning 负责在输入侧提供额外的任务信号。在这种组合下我观察到几个有意思的现象第一LoRA 的秩可以适当调低一点比如 r8因为 P-Tuning 的提示已经“分担”了一部分任务适配压力第二训练收敛速度比单独用其中一种更快第三组合后的效果在大多数情况下优于任一种单独使用但提升幅度不是“叠加式”的更多是相互补足。需要提醒的是组合使用意味着你要同时调两套超参数调试复杂度会上升。如果你是第一次接触参数高效微调我不建议一上来就玩组合先单独跑通一种方法理解了每种方法的行为特征之后再考虑混合策略会顺利得多。最后分享一点我自己的体会四种方法我都踩过坑也都在真实项目里验证过效果。如果你问我哪种最好我的回答只能是看场景。但如果说哪种方法最“耐用”我个人会选 LoRA因为它几乎不给工程链路添麻烦——训练时省显存推理时零负担切换任务时还能动态加载。P-Tuning 则适合快速验证一个想法Prefix Tuning 在你做生成式任务且没有太强的部署限制时很顺手Adapter 适合那些本来就允许改推理逻辑、且需要模块化扩展的系统。如果你正准备开始尝试我给一个最朴素的建议先跑通 LoRA拿一组固定数据对比一下全量微调和 LoRA 的结果你会发现差距没有想象中那么大但显存和时间的差距却大得惊人。之后再去尝试其他方法你会有更清晰的参照系。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑