全参数训练 vs LoRA vs Adapter:模型训练方法的深度对比
"老板给了我一 A100,说要把Llama-3-70B微调一下用于客服场景。"
你深吸一口气,然后打开了显卡驱动。然后你发现——显存不够。
这不是段子,这是无数工程师真实面临的困境。70B参数的模型,全参数训练需要多少显存?简单算一下:模型参数 70B × 2(Adam优化器需要保存一阶和二阶动量)× 4 bytes(FP32)= 560GB。这还没算激活值和梯度,真实需求通常是参数的 4-8 倍。
所以问题来了:有没有一种方法,能用更少的资源 finetune 大模型?
答案是肯定的,而且选择还不少。LoRA、Adapter、Prefix Tuning、P-Tuning……这些名字你可能都听过,但它们到底是什么?有什么区别?为什么有些公司 all in LoRA,有些却坚持全参数训练?
今天这篇文章,就是要把这个问题彻底讲透。
一、全参数训练:重装步兵的代价
先说全参数训练(Full Fine-tuning,也叫 Dense Fine-tuning)。这是最"朴素"的方法——把预训练模型的所有参数都打开,在新任务上进行梯度下降更新。
原理很简单:假设你有一个 7B 参数的模型,全参数训练就是对这 70 亿个参数全部计算梯度、全部更新。没有花哨的技巧,就是"大力出奇迹"。
这种方式的好处是效果最好。因为所有参数都可以被任务特化,模型有最大的自由度去学习新知识。学术上的结论也很一致:在大多数任务上,全参数训练的 benchmark 分数是最高的。
但代价呢?两个字:烧卡。
- 模型参数:7B × 2 bytes ≈ 14GB(FP16)
- 梯度:7B × 2 bytes ≈ 14GB
- 优化器状态(Adam):7B × 2 × 2 bytes ≈ 28GB
- 激活值:通常还需要 10-20GB
除了显存,还有一个问题:灾难性遗忘(Catastrophic Forgetting)。当你在任务 A 上全参数微调后,模型在任务 B 上的能力往往会下降。因为所有参数都被"覆盖"了,原有的知识被新知识替代。
- ✅ 优点:效果最优,模型容量最大,可学习最复杂的任务模式
- ❌ 缺点:显存需求极高,训练时间长,存在灾难性遗忘问题
一句话:这是"重装步兵",火力猛,但太烧资源。
二、LoRA:太极的智慧
LoRA(Low-Rank Adaptation,低秩适配)的核心思想是:不直接修改原模型参数,而是学习一组"残差"参数。
假设原模型的权重是 W(一个大的矩阵),LoRA 不直接修改 W,而是学习两个小矩阵 A 和 B。在前向传播时,输出变成:
# 原始前向传播
output = W @ x
# LoRA 后的前向传播
output = (W + BA) @ x
# 其中 B 是 (d × r),A 是 (r × k)
关键是:r(秩)可以比 d 和 k 小好几个数量级。如果原始 W 是 4096 × 4096,那么 BA 的参数量是 4096×32 + 32×4096 = 262,144,只相当于原参数的 0.5%!
1. 显存大幅降低
训练时只需要保存 LoRA 的参数(几个 MB),不需要保存完整的梯度。7B 模型用 LoRA 单卡 A100 就能跑,70B 模型也只需要 2-4 张卡。
2. 推理零延迟
推理时可以把 LoRA 的权重"合并"(merge)回原模型,和全参数训练的效果完全等价,没有任何额外的推理延迟。这点 Adapter 就做不到。
3. 灵活切换
你可以训练多组 LoRA 权重,随时切换——一个用于客服,一个用于文案生成,一个用于代码补全。这就像给同一个大脑加载不同的"技能卡"。
LoRA 也不是完美的。最大的问题是:效果略逊于全参数训练。特别是在一些需要"深度理解"的任务上,LoRA 的表现可能会差 1-3 个百分点。
三、Adapter:插入式模块的巧妙设计
如果说 LoRA 是"给权重打补丁",那 Adapter 就是"给模型插管子"。
Adapter 的核心思想是:在 Transformer 的每一层中,插入一个小型的神经网络模块。这些模块是随机初始化的,在下游任务上训练;而原始的预训练参数被完全冻结。
# Adapter 核心结构
def adapter(x):
down = nn.Linear(d_model, r) # 降维
nonlinearity = nn.ReLU()
up = nn.Linear(r, d_model) # 升维
output = up(nonlinearity(down(x)))
return output * scaling + x # 残差连接
- LoRA:在注意力矩阵的计算中引入低秩分解
- Adapter:在每一层后插入新模块
- 效果差不多,但 Adapter 推理开销更大
Adapter 的优势:模块化、可扩展性强。
Adapter 的劣势:无法合并回原模型,推理延迟 10-20%。
四、其他方法:Prefix Tuning 与 P-Tuning
Prefix Tuning 和 P-Tuning 的核心思想是——不修改模型参数,而是在输入上"做文章"。
4.1 Prefix Tuning:给输入"加前缀"
不改动模型的任何部分,而是在输入序列前面加一段"可学习的虚拟 token"。只训练这几个虚拟 token,就能让模型完成特定任务。
4.2 P-Tuning:更智能的"提示词"
P-Tuning 是 Prefix Tuning 的改进版:让模型自己学习虚拟 token 应该放在哪里,并引入 LSTM/MLP 编码让学习更稳定。
- Prefix Tuning:~0.1% 参数,效果不稳定
- P-Tuning:~0.2-0.5% 参数,效果较稳定
- P-Tuning v2:~1% 参数,效果接近全参数
五、五种方法全景对比
| 方法 | 参数量 | 显存需求 | 推理延迟 | 效果 | 灾难性遗忘 |
|---|---|---|---|---|---|
| 全参数训练 | 100% | 极高(80GB+) | 无 | ⭐⭐⭐⭐⭐ | 严重 |
| LoRA | ~0.5-2% | 低(单卡) | 零(可合并) | ⭐⭐⭐⭐ | 无 |
| Adapter | ~1-3% | 中低 | 10-20% | ⭐⭐⭐⭐ | 无 |
| Prefix Tuning | ~0.1% | 极低 | 可忽略 | ⭐⭐⭐ | 轻微 |
| P-Tuning | ~0.2-0.5% | 极低 | 可忽略 | ⭐⭐⭐⭐ | 轻微 |
六、适用场景分析
场景 1:资源充足,效果优先
你有多卡服务器(比如 8 张 H100),任务非常重要。
选择:全参数训练
场景 2:资源有限,快速迭代
你只有 1-2 张消费级显卡,需要频繁微调、快速验证。
选择:LoRA(首选)或 P-Tuning
场景 3:需要同时维护多个任务
产品需要支持多种能力,需要随时切换。
选择:LoRA(推荐)或 Adapter
场景 4:云端推理,延迟敏感
模型部署在云端,对延迟敏感。
选择:LoRA(唯一解)
因为只有 LoRA 可以把权重合并回原模型,实现零推理延迟。
场景 5:只是做简单任务
比如只是做一个简单的分类器,或者只是调整输出格式。
选择:Prefix Tuning 或 P-Tuning
参数量最少,足够应付简单任务。
七、如何选择你的训练方法
最后,让我给你一个简单的决策流程:
- 问自己:我的硬件资源有多少?
- 8+ 卡 H100/A100 → 全参数训练
- 1-2 卡 A100/3090 → LoRA
- 消费级显卡 → LoRA + 量化
- 问自己:我对效果的要求有多高?
- 不允许任何折扣 → 全参数训练
- 可以接受 1-3% 的差距 → LoRA
- 问自己:推理延迟重要吗?
- 非常重要 → LoRA
- 可以接受 10-20% 延迟 → Adapter
- 问自己:需要同时支持多少任务?
- 1-2 个任务 → 都可以
- 多个任务,需要动态切换 → LoRA 或 Adapter
记住一句话:没有最好的方法,只有最适合你的方法。根据你的硬件、你的需求、你的场景来做出选择,这才是真正的工程思维。