前两篇文章我们聊了对比学习的原理和SBERT的架构,还手把手教你从零训练了一个嵌入模型。但现实中,从头训练一个高质量的嵌入模型成本极高------你需要海量的标注数据、昂贵的GPU资源和漫长的时间。那有没有捷径?当然有!微调(Fine-tuning) 就是那个让你站在巨人肩膀上的秘诀。
今天,我们就来深入探讨如何微调嵌入模型,以及当标注数据不足时,如何用增强型SBERT(Augmented SBERT) 技术,用小数据撬动大模型,实现性能的逆袭。
一、为什么微调比从头训练更香?
在上一节中,我们用了5万条MNLI数据,从bert-base-uncased开始训练,最终在STSB上得到了0.81的pearson余弦相似度。这个成绩不错,但你有没有想过:如果用一个已经在更大规模数据上预训练好的嵌入模型作为起点,结果会怎样?
答案很明显:效果更好,训练更快。因为预训练模型已经学习到了通用的语言表示,你只需要在自己的小数据上"点拨"一下,它就能快速适应你的任务。
sentence-transformers框架提供了大量高质量的预训练模型,比如all-MiniLM-L6-v2,它体积小、速度快,在许多任务上表现优异。我们就用它来试试。
二、监督学习微调:预训练模型+你的数据=更强模型
微调的过程和之前几乎一样,只是把基座模型换成了预训练的sentence-transformers模型。
2.1 准备数据
我们依然使用MNLI的前5万条样本,并保持同样的处理方式(不重新映射标签,因为我们要用MNR损失,只需要正例对)。但这里为了简化,我们沿用之前用MNR损失时的三元组数据(锚点、正例、负例)。
2.2 加载预训练模型
python
from sentence_transformers import SentenceTransformer
embedding_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
这个模型只有22M参数,比BERT-base(110M)小得多,但效果却不输给很多大模型。
2.3 训练和评估
我们用同样的MNR损失,同样的训练参数,只跑1个epoch。结果如何?
text
pearson_cosine: 0.851
spearman_cosine: 0.848
0.85!比我们从零训练的0.81又提升了4个百分点。而且别忘了,这个预训练模型本身就是在完整MNLI(39万对)上训练过的,我们只用了其中5万对微调,就达到了这么高的分数。这说明:
-
预训练模型已经学到了丰富的语义知识,只需要少量领域数据就能适配。
-
微调的成本远低于从头训练,无论是时间还是数据需求。
当然,如果你觉得用已经在MNLI上训过的模型再在MNLI子集上微调有点"作弊",那我们可以换个场景:假设你有一个自己的小众领域数据集,比如医疗问答、法律文书,那么用通用预训练模型微调,效果会远好于从BERT-base开始训练。
三、增强型SBERT:当标注数据稀缺时的救命稻草
监督微调虽然好,但它依然需要一定量的标注数据。如果只有几百条标注样本怎么办?比如你是一个创业公司,刚起步,只有几千条用户反馈,想训练一个语义搜索模型。这时候,增强型SBERT(Augmented SBERT) 就是为你准备的。
3.1 核心思想:用交叉编码器给未标注数据打标签
我们知道,交叉编码器(cross-encoder)虽然速度慢,但精度高。双编码器(bi-encoder,即SBERT)速度快,适合大规模检索,但精度稍逊。增强型SBERT巧妙地将两者结合:
-
用小规模标注数据(黄金数据集)训练一个交叉编码器。
-
用这个交叉编码器给大量未标注的句子对打标签,生成一个"白银数据集"。
-
用黄金数据集+白银数据集一起训练双编码器。
这样一来,你只需要少量人工标注,就能获得大规模的训练数据,而且白银数据集的标签质量有交叉编码器保障。
3.2 实战:用1万条标注生成4万条白银数据
我们回到MNLI场景,假设只有1万条标注数据(黄金数据集),剩下4万条未标注(实际上是有原始标签的,但假设我们不知道,只用前提和假设作为句子对)。我们的目标是用这1万条数据,训练出一个接近全量5万条数据效果的模型。
步骤1:训练交叉编码器
我们用这1万条黄金数据训练一个交叉编码器。注意,交叉编码器需要将两个句子拼接后输入,输出相似度分数(二分类:相似/不相似)。我们将蕴含(label=0)视为相似(1),中性和矛盾视为不相似(0)。
python
from sentence_transformers.cross_encoder import CrossEncoder
from sentence_transformers.datasets import NoDuplicatesDataLoader
# 准备黄金数据,格式为InputExample
gold_examples = [InputExample(texts=[row["premise"], row["hypothesis"]], label=mapping[row["label"]]) for row in gold_dataset]
gold_dataloader = NoDuplicatesDataLoader(gold_examples, batch_size=32)
cross_encoder = CrossEncoder("bert-base-uncased", num_labels=2)
cross_encoder.fit(train_dataloader=gold_dataloader, epochs=1, warmup_steps=100)
步骤2:用交叉编码器标注未标注数据
剩下的4万对句子(前提-假设),我们用训练好的交叉编码器预测它们的相似度(0或1)。这就得到了白银数据集。
python
silver_pairs = list(zip(silver["premise"], silver["hypothesis"]))
output = cross_encoder.predict(silver_pairs, apply_softmax=True)
silver_labels = np.argmax(output, axis=1) # 取概率最大的类别
步骤3:合并数据集,训练双编码器
将黄金和白银数据合并,去重(防止黄金数据在白银中出现),然后用余弦相似度损失训练一个SBERT模型(这里用bert-base-uncased作为基座,方便对比)。
python
combined = pd.concat([gold_df, silver_df]).drop_duplicates(subset=["sentence1", "sentence2"])
train_dataset = Dataset.from_pandas(combined)
model = SentenceTransformer("bert-base-uncased")
train_loss = losses.CosineSimilarityLoss(model)
# ... 训练
结果:20%的数据,95%的性能
最终在STSB上评估,我们得到了pearson_cosine=0.71。而之前用完整5万数据训练余弦相似度损失模型时,得分是0.72。也就是说,我们用20%的标注数据,达到了全量数据98.6%的效果!这简直是小数据福音。
3.3 生成白银数据的更多技巧
上面我们只是简单用了剩下的未标注句子对。但在实际应用中,你可能没有现成的句子对,只有一堆独立的句子。这时,你可以通过以下方式生成候选对:
-
随机组合:随机抽取两个句子组成一对,然后用交叉编码器打分。但这样会产生大量不相似的对,效率低。
-
使用嵌入模型检索:先用一个现成的嵌入模型(即使不是微调的)对所有句子编码,然后对每个句子检索最相似的top-k个句子作为候选对。这样生成的句子对更可能相似,交叉编码器标注时也能得到更多正例,有助于平衡数据集。
四、为什么增强型SBERT能成功?
这个方法的成功源于两个关键点:
-
交叉编码器的精度:交叉编码器能捕捉句子间的深层交互,因此它标注的白银数据质量远高于随机噪声。即使有少量错误,大量数据下模型也能学到正确模式。
-
双编码器的泛化能力:双编码器将句子映射到向量空间,通过对比学习,它能从大规模(即使有噪声)数据中提炼出有效的语义表示。
五、总结:微调的艺术
从这一节的探索中,我们可以总结出几条实战经验:
-
微调是王道 :只要有合适的预训练模型,微调几乎总是优于从头训练。选对基座模型(如
all-MiniLM-L6-v2或all-mpnet-base-v2)可以事半功倍。 -
数据不足怎么办? 增强型SBERT提供了一个优雅的解决方案:用少量标注数据训练一个交叉编码器,然后用它给大量未标注数据打标签,再用来训练双编码器。效果惊人。
-
难负例仍是核心:无论是MNR损失还是增强型SBERT,本质上都在创造更有挑战性的负例。如果条件允许,引入人工构造的难负例,模型性能还能再上一层楼。
-
别忘了数据质量:黄金数据集的质量直接决定了整个链条的上限。确保你的少量标注数据准确、多样,是成功的前提。
微调嵌入模型,就像让一个已经读过万卷书的学者去专攻某个领域,只需要给他几本专业书,他就能迅速成为专家。而增强型SBERT,则是让这个学者去教学生,学生再帮其他同学,最终形成一支强大的团队。掌握这些技巧,你就能用最小的成本,打造出最适合自己业务的嵌入模型。
附:清空显存提醒
每次实验后,别忘了执行torch.cuda.empty_cache()或重启Python环境,确保显存释放,以免影响后续训练。
本文参考:图解大模型:生成式AI原理与实战
书籍pdf免费下载地址:https://pan.baidu.com/s/1mTaUQ5czcfGpBM8KvJuS2g?pwd=un44