03. 为什么很多项目不做全量微调,而优先考虑参数高效微调?

整理全量微调与参数高效微调的成本差异与工程权衡。

简单回答

全量微调要更新模型所有参数,显存开销和算力成本都非常高,对于 7B 以上的模型大部分团队根本跑不起来。参数高效微调(PEFT)只更新极少量参数就能达到接近全量微调的效果,同时还能降低灾难性遗忘的风险、方便多任务部署,所以在实际项目中成了默认选择。

详细解释

先算一笔账就明白了。全量微调一个 7B 模型,模型参数本身要 14GB(FP16),优化器状态(Adam 要存一阶和二阶动量)再加 28GB,梯度再来 14GB,加上激活值,单卡 80GB 的 A100 基本刚好。如果是 13B 就必须多卡,70B 更是需要一整台多卡机器。而 LoRA 只更新两个低秩矩阵,可训练参数量通常只有原模型的 0.1%~1%,显存占用大幅下降,一张 A100 甚至消费级 GPU 就能微调 7B 模型。

但选 PEFT 不仅仅是因为"便宜"。还有几个很实际的工程考量:

第一是灾难性遗忘。全量微调会大幅修改所有参数,如果微调数据覆盖面不够广,模型在微调任务上表现好了,但通用能力可能严重退化。PEFT 方法因为只动了很少的参数,对原始模型的扰动小,遗忘问题天然就轻很多。

第二是多任务部署的灵活性。用 LoRA 的话,base model 只保存一份,不同任务训出来的 adapter 各几十 MB,推理时按需加载就行。如果是全量微调,每个任务都要存一份完整模型,几十 GB 一份,存储和部署成本完全不一样。在实际生产环境中,一个底座模型挂多个 LoRA adapter 服务不同业务线是很常见的架构。

第三是训练稳定性。全量微调的超参数比较敏感,学习率设高了容易崩,设低了训不动。PEFT 因为参数空间小,训练过程相对更稳定,调参成本也低。

当然 PEFT 也不是没有短板。在一些需要大幅改变模型行为的场景下(比如让一个英文模型完全转成中文),LoRA 的表达能力可能不够,这时候继续预训练+全量微调可能是必要的。另外在数据量非常充足、算力也够的情况下,全量微调的上限通常还是比 PEFT 高一些。所以选择上是一个成本-效果的 trade-off,大多数项目用 PEFT 就够了,少数需要深度改造模型的场景才上全量。

面试时可以这样答

选参数高效微调而不是全量微调,核心原因有三个:成本、遗忘和部署灵活性。

先说成本,全量微调一个 7B 模型,算上优化器状态和梯度,单卡 80G 显存刚好够用,更大的模型就得多卡甚至多机,大部分团队跑不起。而 LoRA 只训练 0.1% 到 1% 的参数,单卡就能搞定。

再说灾难性遗忘,全量微调动了所有参数,如果微调数据覆盖不全面,通用能力退化会很明显。PEFT 对原始参数扰动小,遗忘问题天然就轻。

还有部署灵活性,LoRA adapter 就几十 MB,一个底座模型可以挂多个 adapter 服务不同业务线,推理时按需加载。全量微调的话每个任务一份完整模型,存储和部署成本差很多。

当然 PEFT 不是万能的,如果需要大幅改变模型行为,比如语言迁移这种场景,LoRA 的表达能力可能不够,这时候可能得上全量。但在绝大多数应用场景里,PEFT 的效果已经非常接近全量微调了,是性价比最高的选择。

常见追问

  1. LoRA 和全量微调的效果差距大概有多少?在什么任务上差距最明显?
  2. 多个 LoRA adapter 同时推理时怎么做?会不会有性能问题?
  3. 除了 LoRA,还有哪些 PEFT 方法?各自的优劣是什么?