Embedding 模型升级了,存量向量要全部重算吗?怎么平滑切换?
面试怎么回答
不同模型的向量不在同一个空间,不能混用,换模型就是全量重算加索引切换。先在自己的评测集上确认最终回答准确率确实提升,并估算重算、存储和在线推理的成本。切换按双写、回填、校验、灰度、保留回滚来做:新建索引,从某个时间点起新增更新双写,离线分批用新模型回填存量并可断点续跑,做数量对账和评测回归,再按比例把查询灰度到新模型和新索引,旧索引保留一段时间可回切。回填用批处理推理、限速避免影响在线服务;一定要保留 Chunk 原文,记录每条向量的模型版本,检索服务对外屏蔽模型细节,降低以后切换的成本。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
新的 Embedding 模型在评测中召回率提升了 8 个点,团队想换。但知识库里已经有 3 亿条向量,而且新旧模型的向量不在同一个向量空间里,不能混用。面试官问这题,想看你怎么把一次「全量重算 + 切换」做得安全、可回滚、成本可控。
为什么不能混用
不同模型生成的向量,维度可能不同,即使维度相同,含义也完全不一样。用新模型编码的问题去检索旧模型编码的文档,结果是无意义的。所以:换模型 = 全量重算 + 索引切换。
先确认值不值得换
- 在自己的检索评测集上对比,而不是只看公开榜单;
- 看最终回答准确率的提升,不只是召回率;
- 估算成本:3 亿条重算需要的 GPU 时间或 API 费用、新索引的存储、新模型推理的在线成本(维度变大,存储和检索成本也会变);
- 查询侧的延迟:新模型是否更慢。
切换方案:双写 + 回填 + 切换
- 新建索引:用新模型的维度和参数建一个新的集合;
- 双写:从某个时间点开始,新增和更新的文档同时写旧索引和新索引;
- 回填存量:离线批量任务把存量文档用新模型重算,写入新索引。按文档 ID 分批,记录进度,可断点续跑;
- 校验:数量对账(新旧索引的文档数、Chunk 数是否一致),抽样检查,评测集回归;
- 灰度切换查询:小比例流量用新模型编码问题、查新索引,对比效果和延迟,再逐步放量;
- 保留旧索引:全量切换后保留一段时间,出问题可以回切;
- 下线旧索引:确认稳定后停止双写,删除旧索引。
回填的工程要点
- 大批量 Embedding 用批处理推理,提高 GPU 利用率;
- 控制回填速度,不能影响在线的 Embedding 服务;
- 原始的 Chunk 文本要保留着,否则没法重算——这也是为什么一定要存原文,而不只是存向量;
- 记录每条向量的模型版本,方便核查。
减少未来的切换成本
- 检索服务对外屏蔽模型细节,业务方不直接依赖向量;
- 元数据里记录模型版本;
- Chunk 文本和向量分开存储,向量可以随时重建。