系统学习 AI 学习路径:从 GPU 运行时到推理、微调与 RAG 评估

版本信息最后核对:2026-10-25

embedding-model-migration

更换 embedding 模型:维度、归一化、距离度量、索引重建、双写灰度与回滚的迁移路径。

现象

迁移的起因通常是召回质量不足、成本或合规要求、模型停止维护,或需要更长的输入长度。迁移过程本身会制造一批“看起来像模型退化”的故障:

典型错误包括维度不一致、索引 mapping 不允许修改、NaN 或全零向量、相似度分数整体偏移。很多问题不会抛异常,只会静默地降低质量,因此不能只看任务是否成功。

快速判断

先确认四个一致:查询侧与文档侧是否同一模型、同一 revision;是否使用相同的 query/passage 前缀;是否采用相同的归一化;索引的距离度量是否与模型训练和评分方式匹配。

# 取一条 query 和一条文档,检查维度、范数与是否含 NaN
python - <<'PY'
import numpy as np
for name, vec in [("query", q), ("doc", d)]:
    v = np.asarray(vec, dtype="float32")
    print(name, "dim=", v.shape, "norm=", float(np.linalg.norm(v)),
          "nan=", bool(np.isnan(v).any()), "zero=", bool(not v.any()))
PY

再抽样比较新旧模型对同一批 query-doc 对的相似度和排名。只看单条结果容易误判,至少覆盖几十条并包含困难负例。

线索 更可能的方向
查询或写入直接报维度错误 配置未切换、索引未重建
分数整体偏移但排序基本合理 归一化、距离度量或阈值未校准
排序明显错乱、时好时坏 新旧向量混用或双写不完整
只有部分文档搜不到 回填未完成、任务失败、增量未追平
新模型召回更差 语言或领域不匹配、前缀错误、截断
延迟或显存明显上升 模型更大、批处理不当、服务容量不足
账单上升 按 token 计费、重复回填、缓存未命中

回答四个问题:

  1. 迁移是原地替换还是新索引并行?原地替换几乎没有安全回滚空间。
  2. 查询侧和文档侧是否同时切换?只切一边必然出现向量空间错配。
  3. 评测集是否覆盖真实分布?长文档、表格、代码、多语言和困难负例都要有。
  4. 回滚需要多久?旧模型服务、旧索引和旧缓存是否仍然可用。

常见原因

维度与距离度量

不同模型的向量维度不同,向量库的索引通常按固定维度建立,不能原地修改。距离度量也要匹配:模型用 cosine 训练,索引却用内积或 L2,分数含义会改变。是否归一化同样关键,归一化前后混用会让排序失真。

前缀与输入处理

不少模型要求 query 和 passage 使用不同指令前缀,或要求特定分词与截断方式。前缀漏掉、query 与文档用反、最大输入长度变化导致尾部被截断,都会让新模型表现低于预期。

索引重建不完整

全量回填中断、失败重试遗漏、增量任务仍写旧模型、别名提前切换,都会留下混合索引。混合索引最难排查:单条查询可能碰巧正确,整体指标却持续偏低。

双写与灰度设计缺陷

只写新索引没有回填旧数据、只切读流量没有双写、灰度按请求而不是按租户导致同一用户会话前后不一致,都会让迁移期的结果不稳定。缓存 key 没有带模型版本,旧向量会被继续使用。

容量与成本

更大的模型、更长的输入、更高的维度都会增加显存、延迟和存储。回填通常是一次性的大批量任务,如果与在线查询共享服务,容易互相拖垮。托管模型按 token 计费,重复回填和失败重试会放大成本。

评测口径

沿用旧模型的评测集、top-k 和阈值,或者只比较平均分不看分桶,可能得出错误结论。新模型在不同语言、长度和领域上的表现差异很大,必须分桶看。

排查步骤

第一步:写清迁移清单

列出模型 ID 与 revision、维度、是否归一化、距离度量、最大输入长度、query/passage 前缀、许可证、部署方式、单条成本。清单不完整,后面的验证就无法复现。

第二步:建立离线评测集

从真实流量抽取 100 到 300 条 query,标注相关文档和困难负例,覆盖短查询、长文档、表格、代码、多语言和专有名词。先在新旧模型上各跑一遍,比较 recall@k、MRR、nDCG 和分桶结果。分数接近时,优先看 bad case 的具体差异,而不是只看平均值。

第三步:影子索引与双读对比

新建索引写入新模型向量,线上仍读旧索引;同时把同一批 query 发给新旧两条检索链路,记录 top-k 重合度、标准文档排名和延迟。影子阶段不影响用户,适合发现维度、度量和前缀问题。

第四步:校验向量与回填

检查维度、范数、NaN、全零和重复向量;对比源文档数、成功 chunk 数、失败明细和索引可检索数量。抽样用文档 ID 反查,确认 chunk 文本与向量对应。回填任务要可断点续跑,失败要有明细而不是只报总数。

第五步:设计双写与灰度

迁移期同时写新旧索引,读流量按租户或白名单灰度切换。同一会话必须固定读一侧,避免上下文前后不一致。缓存 key 加入模型版本和索引版本,切换时主动失效或双版本共存。

第六步:演练回滚

在测试环境演练别名切回、旧模型服务恢复、缓存失效和双写停止。确认旧索引在迁移期间持续更新,否则回滚后会出现数据缺口。回滚时间要写入预案,而不是等故障时再讨论。

第七步:评估容量与成本

用真实输入长度分布压测新模型的吞吐和延迟,观察 GPU 显存、队列和超时。回填安排在低峰期或独立资源池,限制并发,避免拖垮在线服务。对比迁移前后的存储、算力和调用成本。

修复与验证

验证要同时满足:离线指标不低于旧模型或达到预定目标、分桶无严重退化、回填数量对账一致、灰度租户无异常反馈、延迟和成本在预算内、回滚演练成功。只完成“索引建好且能查”不算迁移完成。

切换别名、删除旧索引、批量重刷向量都是高风险操作:先在测试环境验证,保留旧索引和旧模型服务至少一个观察窗口,选低峰期执行,并确认回滚步骤有人负责。生产环境不要直接删除 collection,也不要在没有备份的情况下修改 mapping。

预防

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. 为什么不能直接在原索引上修改向量维度?
  2. 新旧模型分数整体偏移但排序尚可,应该先检查什么?
  3. 迁移完成后,为什么旧索引和旧模型服务不能立刻删除?
答案
  1. 向量库的索引和字段通常按固定维度建立,维度和距离度量在创建时确定;原地修改会导致写入失败或旧向量无法比较。正确做法是新建索引、全量回填、校验后通过别名切换。
  2. 先检查归一化方式、距离度量(cosine、内积或 L2)以及 reranker 阈值是否沿用旧模型。分数分布变化不一定代表排序变差,但阈值和融合权重必须重新校准。
  3. 需要保留回滚能力。迁移后可能发现分桶退化、特定语言或长文档效果差、成本超预算;旧索引和旧服务应至少保留一个观察窗口,并确认旧索引仍在更新,否则回滚会出现数据缺口。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令