BERT-tiny 迁移学习实验:LoRA 的参数效率到底值不值
这次实验主要想验证一个问题:
在医学文本分类任务里,不同微调方式到底差在哪里?
我选了一个比较轻量的设置:
模型:BERT-tiny数据集:PubMed-RCT20k任务:医学论文摘要句子分类硬件:NVIDIA A10训练轮数:3 epoch实验一共跑了四组:
random_initfreeze_bertlorafull_finetune最后结果如下:
| 方法 | Accuracy | Macro-F1 | 训练时间/s | 显存/MB | 可训练参数比例 |
|---|---|---|---|---|---|
| random_init | 0.8032 | 0.7314 | 62.91 | 294.83 | 100.0000% |
| freeze_bert | 0.5927 | 0.4756 | 61.43 | 96.40 | 0.0147% |
| lora | 0.7613 | 0.6866 | 61.88 | 221.90 | 0.2011% |
| full_finetune | 0.8216 | 0.7537 | 61.72 | 294.71 | 100.0000% |
结果比较直观:
full_finetune 效果最好random_init 在全样本下表现也不错lora 参数效率很高freeze_bert 最省资源,但效果明显不足一、实验背景
Section titled “一、实验背景”迁移学习在 NLP 任务里非常常见。
一般情况下,我们不会直接从零训练一个语言模型,而是先拿一个已经预训练过的模型,再让它适应自己的下游任务。
比如 BERT 已经在大规模语料上学习过语言表示。
当我们要做医学文本分类时,可以直接复用它已有的语言知识,而不是让模型重新学习词汇、句法和基础语义。
不过,复用预训练模型也有很多方式。
有些方法只训练最后的分类头,有些方法更新整个模型,还有些方法只训练少量额外参数。
这次实验就是想比较这些策略的差异。
二、任务设置
Section titled “二、任务设置”实验任务是医学文本分类。
数据集使用 PubMed-RCT20k。
这个数据集里的每条样本是一句医学论文摘要中的句子,模型需要判断这句话属于摘要中的哪个部分。
常见类别包括:
BACKGROUNDOBJECTIVEMETHODSRESULTSCONCLUSIONS举个例子,输入可能是:
The patients were randomly assigned to the treatment group or control group.模型需要判断它更像是方法部分、结果部分,还是背景部分。
这个任务本质上是一个多分类问题:
输入:一句医学文本输出:摘要结构类别三、为什么用 BERT-tiny
Section titled “三、为什么用 BERT-tiny”这次没有直接用 bert-base-uncased,而是用了更小的模型:
prajjwal1/bert-tiny原因很简单:这次实验重点不是刷最高准确率,而是比较训练策略。
BERT-tiny 参数量小,训练速度快,很适合做课程实验和策略对比。
它的优势是:
训练快显存占用低方便多组实验对比A10 上一分钟左右就能跑完一组如果换成 BERT-base,结果可能更接近正式论文实验,但训练时间也会明显增加。
四、四种训练策略
Section titled “四、四种训练策略”这次实验比较了四种方法。
它们的区别主要在于两个问题:
是否使用预训练权重?训练时更新哪些参数?整理成表格就是:
| 方法 | 是否使用预训练权重 | 训练哪些参数 | 含义 |
|---|---|---|---|
| random_init | 否 | 全部参数 | 不使用迁移学习,模型从零训练 |
| freeze_bert | 是 | 只训练分类头 | 把 BERT 当作固定特征提取器 |
| lora | 是 | LoRA 参数和分类头 | 参数高效微调 |
| full_finetune | 是 | 全部参数 | 标准全参数微调 |
五、random_init:不用预训练的对照组
Section titled “五、random_init:不用预训练的对照组”第一组是 random_init。
这组只使用 BERT-tiny 的模型结构,不加载预训练权重。
也就是说,模型一开始什么都没有学过,所有参数都是随机初始化的。
BERT-tiny 结构↓随机初始化↓在医学文本分类数据上训练全部参数这组实验的作用是提供一个对照。
它回答的是:
不使用预训练模型,直接训练这个任务,能做到什么程度?
结果是:
Accuracy = 0.8032Macro-F1 = 0.7314可训练参数比例 = 100%这个结果其实不差。
原因也很容易理解:这次用的是全样本训练,而且 BERT-tiny 比较小,所有参数都可以更新,所以模型有足够空间去拟合这个任务。
六、freeze_bert:只训练分类头
Section titled “六、freeze_bert:只训练分类头”第二组是 freeze_bert。
这组加载了 BERT-tiny 的预训练权重,但冻结了 BERT 主体参数,只训练最后的分类头。
预训练 BERT-tiny↓冻结 BERT 主体↓只训练分类层它的可训练参数非常少:
可训练参数量 = 645可训练参数比例 = 0.0147%结果是:
Accuracy = 0.5927Macro-F1 = 0.4756显存占用 = 96.40 MB这组显存最低,但效果也是最差的。
原因很明确:只训练分类头,模型主体没有机会根据医学文本分类任务进行调整。
换句话说,它只是把预训练 BERT 当成一个固定特征提取器。
如果这个固定表示刚好适合当前任务,效果可能还可以;如果不够适配,分类头能做的事情就很有限。
七、LoRA:只训练少量适配参数
Section titled “七、LoRA:只训练少量适配参数”第三组是 lora。
LoRA 也是基于预训练模型的迁移学习方法。
它不是不用预训练模型,而是在预训练模型基础上只训练少量新增参数。
简单来说:
加载预训练 BERT↓冻结原始模型主体↓在注意力层加入 LoRA 低秩适配参数↓训练 LoRA 参数和分类头本实验中 LoRA 的可训练参数量是:
可训练参数量 = 8,837可训练参数比例 = 0.2011%结果是:
Accuracy = 0.7613Macro-F1 = 0.6866显存占用 = 221.90 MB这个结果明显好于 freeze_bert:
| 方法 | Accuracy | Macro-F1 |
|---|---|---|
| freeze_bert | 0.5927 | 0.4756 |
| lora | 0.7613 | 0.6866 |
这说明,只训练分类头太弱,而 LoRA 提供了更强的任务适配能力。
它没有更新整个 BERT,但通过少量适配参数,让模型能够更好地适应医学文本分类任务。
八、full_finetune:预训练模型全参数微调
Section titled “八、full_finetune:预训练模型全参数微调”第四组是 full_finetune。
这组加载预训练 BERT-tiny,然后训练全部参数。
预训练 BERT-tiny↓所有参数参与训练↓完成医学文本分类任务适配结果是:
Accuracy = 0.8216Macro-F1 = 0.7537可训练参数比例 = 100%这是四组里面效果最好的。
它比 random_init 更高:
| 方法 | Accuracy | Macro-F1 |
|---|---|---|
| random_init | 0.8032 | 0.7314 |
| full_finetune | 0.8216 | 0.7537 |
这说明预训练权重确实有帮助。
虽然 BERT-tiny 很小,但预训练模型作为初始点,仍然能让最终效果更好。
九、完整结果分析
Section titled “九、完整结果分析”完整实验结果如下:
| 方法 | Accuracy | Macro-F1 | 训练时间/s | 显存/MB | 总参数量 | 可训练参数量 | 可训练参数比例 |
|---|---|---|---|---|---|---|---|
| random_init | 0.8032 | 0.7314 | 62.91 | 294.83 | 4,386,565 | 4,386,565 | 100.0000% |
| freeze_bert | 0.5927 | 0.4756 | 61.43 | 96.40 | 4,386,565 | 645 | 0.0147% |
| lora | 0.7613 | 0.6866 | 61.88 | 221.90 | 4,395,402 | 8,837 | 0.2011% |
| full_finetune | 0.8216 | 0.7537 | 61.72 | 294.71 | 4,386,565 | 4,386,565 | 100.0000% |
按分类性能排序:
full_finetune > random_init > lora > freeze_bert按可训练参数量排序:
freeze_bert < lora << random_init = full_finetune如果只看最高准确率,full_finetune 最好。
如果考虑参数效率,lora 更值得关注。
十、为什么 LoRA 没有超过 random_init
Section titled “十、为什么 LoRA 没有超过 random_init”这个结果一开始容易让人困惑。
因为 LoRA 使用了预训练模型,而 random_init 没有使用预训练模型。
但是两者的训练自由度完全不同。
random_init:不使用预训练权重,但训练全部参数。
lora:使用预训练权重,但只训练 0.2011% 的参数。这次实验使用的是全样本数据。
在数据量比较充足的情况下,BERT-tiny 这种小模型即使随机初始化,只要允许全部参数更新,也可以学得不错。
所以 random_init 比 lora 高,并不代表 LoRA 没有价值。
更合理的理解是:
random_init 用大量可训练参数换来了更高性能,而 LoRA 用很少参数换来了还不错的效果。
LoRA 的优势不在于所有场景都超过全参数训练,而在于参数效率。
十一、LoRA 最应该和谁比较
Section titled “十一、LoRA 最应该和谁比较”LoRA 最有意义的比较对象有两个。
1. 和 freeze_bert 比
Section titled “1. 和 freeze_bert 比”两者都使用预训练模型,也都冻结了大部分参数。
但是结果差距很明显:
freeze_bert Accuracy = 0.5927lora Accuracy = 0.7613这说明 LoRA 的适配能力明显强于只训练分类头。
分类头只能利用固定特征,而 LoRA 能让模型内部的注意力层产生一定变化。
2. 和 full_finetune 比
Section titled “2. 和 full_finetune 比”全参数微调效果最好,但成本也最大。
full_finetune 可训练参数 = 4,386,565lora 可训练参数 = 8,837全参数微调的可训练参数量约为 LoRA 的:
4,386,565 / 8,837 ≈ 496 倍但 LoRA 的 Accuracy 达到了 full_finetune 的:
0.7613 / 0.8216 ≈ 92.7%也就是说,LoRA 只训练了极少的参数,但保留了相当一部分性能。
这就是它的价值。
十二、显存和训练时间
Section titled “十二、显存和训练时间”显存占用如下:
| 方法 | 显存/MB |
|---|---|
| freeze_bert | 96.40 |
| lora | 221.90 |
| full_finetune | 294.71 |
| random_init | 294.83 |
freeze_bert 最省显存,因为它只训练分类头。
lora 显存高于冻结方法,但低于全参数训练。
full_finetune 和 random_init 都训练全部参数,所以显存接近。
训练时间方面,四组差异不明显:
random_init 62.91sfreeze_bert 61.43slora 61.88sfull_finetune 61.72s主要原因是模型太小,A10 也比较快。
所以这次实验里,训练时间不是最重要的指标。
更应该关注:
分类性能显存占用可训练参数比例十三、实验结论
Section titled “十三、实验结论”这次实验可以得出几个结论。
第一,full_finetune 效果最好。
Accuracy = 0.8216Macro-F1 = 0.7537说明预训练模型经过全参数微调后,能够很好地适应医学文本分类任务。
第二,random_init 在全样本条件下也表现不错。
Accuracy = 0.8032Macro-F1 = 0.7314这说明当数据量比较充足、模型规模比较小时,从零训练也可以取得较强结果。
第三,freeze_bert 成本最低,但效果明显不足。
可训练参数比例 = 0.0147%Accuracy = 0.5927这说明只训练分类头的表达能力有限。
第四,lora 在性能和成本之间取得了比较好的平衡。
可训练参数比例 = 0.2011%Accuracy = 0.7613Macro-F1 = 0.6866它明显优于冻结 BERT,并且在只训练极少参数的情况下达到了全参数微调 92.7% 左右的 Accuracy。
十四、我对迁移学习的理解
Section titled “十四、我对迁移学习的理解”这次实验之后,我对迁移学习的理解更具体了。
迁移学习不是简单地说:
用了预训练模型,所以一定更好。更关键的是:
预训练权重怎么用?哪些参数允许更新?下游数据量有多少?算力和显存是否受限?目标是最高性能还是最高效率?在这次实验里,四种方法各自代表一种选择:
| 方法 | 适合场景 |
|---|---|
| full_finetune | 追求最高效果 |
| lora | 参数和显存受限,但希望保留较好效果 |
| freeze_bert | 快速验证任务是否可行 |
| random_init | 数据充足、模型较小、不依赖预训练权重 |
如果是课程实验,四组方法一起比较可以很好地说明迁移学习的不同使用方式。
如果是真实大模型场景,LoRA 的意义会更明显。
因为模型越大,全参数微调成本越高,而 LoRA 的参数效率优势也越重要。
十五、后续可以继续补充的实验
Section titled “十五、后续可以继续补充的实验”这次实验已经能说明基本问题,但还可以继续扩展。
1. 小样本实验
Section titled “1. 小样本实验”当前用的是全样本。
如果只取:
100030005000条训练样本,结果可能会发生变化。
小样本条件下,预训练模型的优势通常会更明显,而随机初始化可能更难训练。
2. 更大的模型
Section titled “2. 更大的模型”可以把 BERT-tiny 换成:
bert-base-uncased或者医学领域模型:
BioBERTPubMedBERTClinicalBERT这样结果会更接近真实医学 NLP 场景。
3. LoRA 超参数对比
Section titled “3. LoRA 超参数对比”当前 LoRA 只跑了一组配置。
后面可以比较:
r = 4 / 8 / 16lora_alpha = 8 / 16 / 32target_modules = query / value / key / dense这样可以进一步观察 LoRA 参数量和性能之间的关系。
4. 不同训练轮数
Section titled “4. 不同训练轮数”当前统一训练 3 epoch。
后续可以跑:
1 epoch3 epoch5 epoch10 epoch不同方法的收敛速度可能不一样。
这次实验的核心结论是:
全参数微调效果最好,LoRA 参数效率最高,冻结 BERT 最省资源但效果不足,随机初始化在全样本条件下也有较强表现。
更具体地说:
full_finetune:使用预训练模型,训练全部参数,性能最高。
lora:使用预训练模型,只训练少量适配参数,性能明显优于冻结 BERT,参数效率很高。
freeze_bert:使用预训练模型,只训练分类头,资源开销最低,但任务适应能力不足。
random_init:不使用预训练模型,训练全部参数,在全样本条件下表现不错。这次实验让我更清楚地看到:
迁移学习不是一个固定答案,而是一组取舍:效果、参数量、显存、数据规模和训练成本都要一起看。
如果只追求指标,full_finetune 是最好的选择。
如果希望在较低训练成本下获得可接受效果,LoRA 更有代表性。