Embedding 模型微调:领域效果不够时的最后一招
王王老师476 阅读
如果你的领域比较垂直(比如法律、医疗、代码),通用 embedding 模型可能不够用。此时有两种选择:换更大模型,或者微调。这篇文章记录我微调 bge-m3 的完整过程。
什么时候值得微调:
- 通用模型在你的领域测试集上 Recall@10 < 0.7
- 你有一定量的领域数据(几百到几千条查询-文档对)
- 领域术语多、语义特殊(比如"退货"在电商和物流语境里语义不同)
如果没有以上条件,先别微调,调分块和检索参数收益更大。
训练数据怎么造:
最简单有效的方案是合成数据:
Python
# 用 LLM 生成 查询-文档 对
pairs = []
for doc in domain_docs:
q = llm(f"基于以下文档生成 3 个相关问题:\n{doc}")
pairs.append((q, doc)) # 正样本
# 负样本:随机取其他文档,或让 LLM 生成难负例
正样本是"问题-对应文档",负样本是"问题-不相关文档"。难负例(表面相似但实际无关)对训练效果最关键。
微调:
用 sentence-transformers 的 MultipleNegativesRankingLoss:
Python
from sentence_transformers import SentenceTransformer, losses, InputExample
from torch.utils.data import DataLoader
model = SentenceTransformer("BAAI/bge-m3")
loss = losses.MultipleNegativesRankingLoss(model)
# 训练 3-5 个 epoch,学习率 2e-5
坑:
-
epoch 别太多。embedding 微调很容易过拟合,3 个 epoch 和 10 个 epoch 效果差别很大,我试过 10 个 epoch 反而比通用模型还差。
-
混合训练。用领域数据微调时,最好混入一部分通用数据,防止领域偏移太狠。
-
评估要分开。微调前后用同一套测试集对比,别用训练集里的数据评估,那肯定虚高。
实测效果:在内部代码文档场景,微调 1000 对数据后,Recall@10 从 0.72 提到 0.88。但说实话,这个提升主要来自"术语对齐"——如果领域术语不多,微调收益有限。
微调是最后的手段,先把其他环节调好再考虑它。
评论0
还没有评论,来抢沙发~