ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Embedding 增量微调后的兼容性:别用平均漂移决定免重建

Embedding 增量微调后的兼容性:别用平均漂移决定免重建

平均余弦漂移只有 0.01,可以不重刷旧向量吗?这个数字看起来很小,仍可能藏着一组方向完全翻转的长尾实体。平均值回答的是整体变化量,不是每个查询是否仍然安全。

表示学习方法会改变信息分配方式。MRL 通过训练目标支持不同表示粒度,也不能推出任意增量微调后旧文档表示与新查询表示自动兼容。论文 把“模型还能编码同样维度”与“新旧空间可以混检”分开,是一次升级评估的起点。

配对锚点,比两份无关样本均值更有解释力

同一批文档分别经过旧模型和新模型,可以计算每个锚点的位移。还应比较按语言、实体类别与文档年代切分的分布。若只是拿新旧时期两批不同业务文本比较,变化可能来自数据内容,不能全归给模型。

然后做三组检索:旧查询对旧库、新查询对新库、新查询对旧库。第三组专门评估过渡期混用;前两组区分新方案质量与兼容性。ANN 的近似误差另与同空间的精确搜索比较,不要把所有差值塞进“漂移”一个指标。

用一个低均值、高尾部的反例拒绝万能阈值

下面 200 个配对向量里只有一个翻转。它让均值仍低于 0.015,但最坏点漂移达到 2。这个反例说明平均阈值不够,不代表生产里一定以这个概率发生翻转。

图中的多个检查闸门不是已有的行业认证标准,而是建议分别保留的证据。是否接受新旧混用,应由业务查询与相关性评测决定。

import math def cosine(a, b): na = math.sqrt(sum(x*x for x in a)) nb = math.sqrt(sum(x*x for x in b)) if na == 0 or nb == 0 or len(a) != len(b): raise ValueError("invalid pair") return sum(x*y for x, y in zip(a, b))/(na*nb) old = [(1.0, 0.0)]*200 new = [(1.0, 0.0)]*199 + [(-1.0, 0.0)] drifts = [1-cosine(a, b) for a, b in zip(old, new)] mean = sum(drifts)/len(drifts) worst = max(drifts) assert mean < 0.015 and worst == 2.0 assert mean == 0.01 long_tail = drifts[-1:] assert sum(long_tail)/len(long_tail) == 2.0 print("mean drift=0.01; worst drift=2.0; mean threshold hid tail failure")

内图的分布、召回曲线与 Exact/ANN 曲线仅为示意,没有对应实验点,也不表示漂移与召回存在必然单调关系。

例子跑通以后,还要验证什么

这段代码已在本地 macOS、CPython 3.9.6 下运行,实际输出为mean drift=0.01; worst drift=2.0; mean threshold hid tail failure。它验证的是例子中的数据约束与分支,不包含线上服务的吞吐或延迟测量。

未训练 Embedding、计算 CKA、执行索引重建或上线切换。代码只验证一个数学反例。真实评估应保存配对锚点、模型 revision、归一化和分块协议,记录尾部分位数及分组召回;没有一条未经验证的平均漂移阈值可以保证免重建。

延伸阅读

  • Matryoshka Representation Learning:表示能力来自训练设定;跨模型兼容性仍需独立检验。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进