← 返回题目列表

RAG 的 Embedding 如何用对比学习微调?难负样本和假负样本有什么区别?

中等 第 19 / 29 题 更新于 2026/09/07
RAGEmbedding对比学习难负样本InfoNCE

简化版

检索 Embedding 微调通过对比学习提高问题与相关文档的相对相似度,让相关文档排在不相关文档前面。难负样本是“很像但不能回答”的文档,假负样本却是“本来相关却被错标为负”的文档,后者会把训练方向推反。

详细版

  1. 训练数据可以是问题与正例文档对,也可以额外提供已确认不相关的负例。
  2. 常用 batch 内负例:对一个问题,把同批其他问题的文档当作候选负例,前提是它们确实不相关。
  3. InfoNCE 类损失对候选相似度做 softmax,提高正例相对概率;温度控制区分强度。
  4. 难负例可由 BM25 或已有向量模型召回后审核得到,能训练模型区分相近概念与业务条件。
  5. 去重、多正例处理和相关性复核可减少假负例,不能把所有未标注结果都当成错误答案。
  6. 验收用隔离的检索评测集,保持分块、候选库和指标口径一致;模型更新后通常需要重新生成文档向量。

完整版教学

一、为什么通用语义相似不等于业务相关

问题“企业版怎么退费”与“个人版怎么退费”字面非常接近,但适用政策可能不同。 通用向量模型容易学到共同的“退费”主题,却未必足够重视版本、日期或资格条件。 检索微调的目标是让向量空间体现任务相关性,而不只是同义词关系。 因此正例应是能够支持回答的文档,不能简单选择词汇最多的片段。

例如问题明确询问企业版,正例包含企业版退款条件,难负例包含个人版退款条件。 如果两个版本恰好适用同一政策,后者又可能成为相关文档,必须按真实业务判断。 标签表达的是“对于该问题是否相关”,不是文档本身永久属于好或坏。

二、对比损失怎样推动排序

设一个问题 q 对应正例 d+,另外有若干负例。 分别编码问题与文档,计算相似度,再把相似度除以温度送入 softmax。 对正例概率取负对数,正例相对其他候选越突出,损失越小。 这里优化的是候选间相对区分,不要求余弦相似度本身就是经过校准的相关概率。

s(q,d) = cosine(encode_query(q), encode_document(d))
P(正例 | 当前候选集) = exp(s(q,d+)/τ) / Σ_j exp(s(q,d_j)/τ)
L = -log P(正例 | 当前候选集)
τ > 0;分母包含正例与所有候选负例

例如正例和两个负例的相似度为 0.8、0.6、0.2,温度取 0.2。 缩放后 logits 是 4、3、1,正例概率约 0.705,loss 约 0.349。 若正例变成 0.9,其余不变,概率约为 0.798,loss 约为 0.226。 这个变化来自相对间隔扩大,而不是模型突然学会了输出一个可信的置信度。

三、为什么同批文档可以充当负例

一个 batch 有 B 对问题与正例时,可以计算 B×B 的相似度矩阵。 对角线是每个问题自己的正例,非对角线通常作为负例。 这样文档编码一次就能给多个问题提供对比信号,减少单独构造随机负例的成本。 但“别人的正例就是我的负例”只是数据假设,不能自动成立。

          d1   d2   d3
q1        正   负   负
q2        负   正   负
q3        负   负   正

B=3:共有 9 个相似度,每个问题有 1 个正例、2 个候选负例

如果 q1 和 q2 都在问退款期限,d2 可能也能回答 q1,矩阵里的“负”就错了。 这会要求模型同时拉近和推远语义相近的有效答案,形成冲突监督。 可通过相关文档分组、去重采样或多正例损失处理,不能只靠增大 batch。 这种训练组织方式可参考 Sentence Transformers 的损失说明

四、如何区分难负例与假负例

负例有价值,是因为它要求模型识别决定答案是否适用的细微条件。 随机抽一篇天气预报作为退款问题的负例通常太容易,模型很快就能分开。 换成另一个套餐的退款政策,模型才需要学习套餐约束。 但如果误把有效的另一份退款说明当负例,再难也只是错误标签。

类型退款问题中的示例训练影响
容易负例无关的天气预报学会粗粒度主题区分
难负例不适用的另一套餐政策学习细粒度适用条件
假负例能回答问题的另一份政策说明错误地推远有效证据
正例对应套餐的有效退款条款提供应被拉近的目标

一种流程是先检索前 50 条候选,排除已知正例和重复文档,再审核语义相近的候选。 可让重排模型辅助筛选,但高分不自动说明它是假负例,低分也不证明它一定无关。 应抽检边界案例,保存采样模型版本,定期更新负例以免训练长期只面对同一种错误。 难度与标签可信度要同时考虑,不存在“越难越好”的通用规则。

五、微调后怎样证明检索真的更好

训练集与测试集应按文档来源、业务实体或时间划分,避免近重复问题落入两边。 比较时固定分块策略与文档库,否则检索提升可能来自数据变化而非向量模型。 先在精确向量搜索中观察排序质量,再测试实际近似索引,分开模型误差和索引误差。 除平均分外,还要单看日期、版本、缩写、长文档等易错分组。

假设每个问题只有一份标注相关文档,100 个测试问题里有 72 个在前 5 条找到了它,Recall@5 就是 72%。 如果每题有多个相关文档,则应计算该题“召回相关数/相关总数”再按口径聚合,不能仍套用单正例命中率。 排序靠前与否还可以用 MRR 或 nDCG 检查,并观察下游回答是否有可支持的证据。 检索 loss 降低并不保证这些保留集指标同步提高。

构造相关性标签 -> 划分独立评测集 -> 微调问题/文档编码器
  -> 重编码文档库 -> 构建新索引 -> 固定查询回归 -> 切换模型与索引版本

模型改变后,新问题向量与旧文档向量即使维度相同,也未必处于兼容空间。 因此应让模型版本、文档向量版本和索引版本绑定,并保留成套回滚能力。 还要确认问题与文档使用的前缀、池化和归一化方式与训练一致。 否则会把部署格式错误误判成微调无效。

六、常见误区与追问

  • 误区:未标注相关的文档就是负例。 相关性标注往往不完整,未标注只代表未知,应排查可回答问题的其他文档。
  • 误区:负例越难效果越好。 最相似的候选更可能含假负例,应同时控制标签可靠性、难度分布和评测收益。
  • 追问:一个问题有多个正确文档怎么办? 可使用多正例目标或屏蔽已知相关候选,避免把另一个正确答案放在负例位置。
  • 追问:温度越低越好吗? 温度降低会放大相似度差异,也可能放大错误负例的影响,应结合数据噪声和验证集调节。
  • 误区:训练 loss 下降就代表 RAG 答得更准。 训练目标只反映当前候选上的排序,还需检验保留集检索与下游证据利用。
  • 追问:微调后只替换问题编码器可以吗? 常规双塔微调通常要求同步更新文档向量;只有明确设计并验证了兼容训练方案才可例外。

七、加强记忆

把检索微调想成训练“能否用这份材料回答这个问题”的判断:正例给方向,难负例教边界,假负例则把正确道路封住。先保证标签可信,再用对比损失拉开相对距离,最后以独立测试集和成套更新的索引验证效果。记住相似不一定适用,未标注也不等于不相关,才能把公式与真实业务连起来。

记忆钩子:难负例是像答案但答不了,假负例是能回答却被错判;先修标签,再谈拉开距离。