模型、维度与归一化选择

本节目标

你将把“选一个 embedding 模型”改写成可验证决策:先定义任务和数据,再记录输入角色、模型 revision、维度、metric、归一化、限制、许可、隐私、延迟与成本,最后在自己的 gold set 上比较。

先写任务卡,再看模型卡

至少回答:

问题为什么重要
输入是什么语言、领域和长度分布?通用英文平均分不能代替中文专业语料
是对称相似度还是 query→document 检索?决定角色、指令和评测任务
文本、代码、图片还是多模态?只有模型训练支持的模态才能比较
query 典型多长,document chunk 多长?影响输入限制、截断与召回粒度
需要云 API 还是本地部署?影响数据出境、许可、GPU、运维和延迟
top-k 候选给谁消费?reranker 和 LLM 的预算决定召回规模
数据更新与删除频率?决定编码吞吐、缓存和迁移成本
哪些子组不能退化?需要语言、领域、权限与关键业务门禁

公开榜单和 MTEB 适合发现候选,但其任务、语料、聚合方式与版本不一定代表你的目标查询。最终决策必须使用固定 chunk/query/gold、开发集与保留测试集。

把空间契约写完整

建议为每个候选记录:

space_id: candidate-2026-07  # 为这一套不可混用的向量空间取稳定标识,而不是仅写展示名。
provider: <provider-or-local-runtime>  # 记录实际生成向量的云服务商或本地运行时。
model: <model-id>  # 填入官方模型 ID,便于日后复现和追溯。
revision: <immutable-revision-or-date>  # 固定模型版本、不可变提交或核对日期,防止 alias 静默漂移。
query_role: <method-task-or-prefix>  # 写明 query 的官方 method、task type 或输入前缀。
document_role: <method-task-or-prefix>  # 写明 document 的对应角色;不能从 query 设置猜测。
dimension: <integer>  # 填写实际输出维度,它决定索引字段与向量长度校验。
dtype: float32  # 记录每个维度的数值类型,影响存储、量化与数值误差。
metric: cosine  # 记录检索使用的度量;必须与模型建议和索引配置一致。
normalized: false  # 明确向量是否已做 L2 归一化,不能根据分数范围推断。
tokenizer: <name-and-revision>  # 保存输入计量器及版本,保证长度预算可复现。
input_limit: <official-source-and-date>  # 指向已核对日期的官方限制,而不是把易变数值写死。
truncation_policy: reject  # 超长输入的明确策略;这里选择拒绝并回到切分阶段。
pooling: <if-local-model>  # 本地模型需记录池化方式;云 API 不适用时应明确为空。
license: <model-or-service-terms>  # 保存模型许可或服务条款,供上线前合规核验。
data_policy: <approved-processing-boundary>  # 写明哪些数据可在此处理边界内发送或存储。

space_id 是索引隔离标识,不应只是展示名称。Revision、角色、维度、pooling、归一化或任务指令变化,都可能形成新的候选空间。

Query/document 角色是动态契约

非对称检索中,短 query 与长 document 的训练方式可能不同。模型常见三种设计:

  1. 两套 encoder;
  2. 同一 encoder,但用 query/document prompt 或 task type;
  3. 同一调用且没有角色差异。

截至 2026-07-22 的官方示例:

  • Sentence Transformers 为检索推荐 encode_query() / encode_document();若模型没有专用 prompt/route,两者可能等价。
  • Cohere 文档区分 search_query 与 search_document input type。
  • Gemini 不同 embedding 代际对任务指令的表达方式不同:gemini-embedding-001 使用 task_type,而 gemini-embedding-2 不支持该参数;后者做纯文本检索时需按其当前文档把 query/document 任务指令写入实际输入。001 迁到 2 的向量空间不兼容,必须全量重编码,不能混索引或复用旧阈值。
  • OpenAI 当前向量指南使用统一 embeddings endpoint;不要因此把其他模型的角色规则类推过去。

这些只是“契约随模型和版本而变”的例子。不要自己发明前缀,也不要从另一个模型复制。角色错误往往仍返回合法维度,所以必须用检索回归测试发现“无报错的错”。

维度影响什么

若有 个向量、维度 、每值 bytes,原始向量理论下限约为:

例如 float32 的 。真实存储还包含 ID、metadata、索引图、对齐和副本;这个公式不能代替容量压测。

维度增加通常会提高:

  • 网络响应与写入体积;
  • exact 点积运算;
  • 向量字段和 ANN 索引内存;
  • 重建与备份成本。

但维度更大不保证业务质量更高。训练、数据、任务与模型容量同样重要。

可变维度不是任意截断

Matryoshka Representation Learning(MRL)训练表示的前缀,使较短前缀也具备可用结构。部分当前服务明确提供 dimensions / output_dimensionality / output_dimension 参数。

正确规则:

  • 只有模型/官方 API 明确支持时才缩短;
  • 使用官方参数优先于自行切片;
  • 若官方要求重新归一化,按该模型版本执行;
  • 每个维度视为独立候选空间与索引字段;
  • 在业务 gold、延迟、内存和费用上分别评测。

不能把任意向量的前 256 维截下并假设等价。MRL 是训练性质,不是所有向量数组的通用性质。

Cosine、dot 与 Euclidean

Cosine similarity

它比较方向,忽略共同尺度;零向量无定义。

L2 归一化

单位向量上:

且:

因此同一组单位向量上,按 cosine、dot 和 Euclidean 距离得到相同排序(分数数值不同)。未归一化时 dot 会受模长影响,排序不一定相同。

选择规则

  • 先看模型卡/官方文档的训练与推荐 metric;
  • 明确向量是否已经归一化;
  • 索引和应用使用相同配置;
  • 拒绝零向量、NaN、Inf 和错维;
  • 分数阈值按空间、任务与开发集校准。

OpenAI 当前指南明确其 embeddings 为单位长度,并说明 cosine 可用 dot 计算;这是该服务当前行为,不应推广为所有模型默认。

输入限制与截断

模型可能按 token、字符、项目数、总 payload 或模态定义限制。具体数值会变化,必须保存官方链接与核对日期。

最安全的基线:

  1. 使用对应 tokenizer 或官方计数方式;
  2. 在 [[Knowledge/AI Agent Engineer/docs-CN/Chunking策略/00-目录|Chunking策略]]阶段控制长度;
  3. 超长输入显式拒绝或重新切分;
  4. 若确需截断,保存实际 embedding input、hash、截断位置和告警;
  5. 绝不让数据库正文与实际被编码文本静默不一致。

部分 API 可自动截断输入。例如 Gemini API 暴露自动截断配置;一次成功响应不证明完整正文被编码。应在空间契约中显式选择拒绝、重新切分或截断,记录请求设置;若提供商响应报告截断状态,也将其纳入审计和检索回归。不得把提供商默认行为当成长度策略。

同一模型的 query 与 document 也可能有不同推荐长度或指令;分别记录。

归一化和量化都要版本化

Float16、int8、binary 等压缩可以节省存储和加速,但会引入数值/排序变化。提供商或库支持不等于你的索引、metric 和质量门禁自动兼容。

比较时区分:

  • 模型表示误差;
  • 维度截短误差;
  • dtype/量化误差;
  • ANN 近似误差。

一次只改一层,先以原始 float exact search 为 ground truth,再测压缩与 ANN 的 top-k agreement/recall。

模型候选实验

固定:

  • canonical chunks、query 与 relevance;
  • query/document 角色;
  • exact search 或同一 ANN 配置;
  • metric、k、过滤与 rerank;
  • 开发/测试划分;
  • 机器、批大小与并发(性能比较时)。

报告:

质量子组系统
Recall@k、MRR、nDCG、hard negatives中文/英文、领域、短/长 query、代码、数字P50/P95、吞吐、失败、原始/索引存储、费用
无答案阈值与误报/漏报权限、关键业务、低资源语言冷启动、重建时长、缓存命中

总体均值相近时,关键子组、稳定性、成本和治理约束可能决定选择。

常见错误与排查

  • 只看排行榜总分:回到业务 query 和关键子组。
  • 角色漏配却无报错:打印空间契约,不打印正文;加 query/document 回归。
  • 维度相同就混合向量:校验 provider/model/revision/role/dimension/metric 签名。
  • 所有向量都强制 normalize:先核对模型训练和官方建议。
  • 静默截断:对比正文 hash 与实际 embedding input hash。
  • 新模型分数更低就判差:分数刻度跨空间不可比,应比较排序与业务指标。
  • MTEB 第一就直接上线:榜单是筛选证据,不是目标域验收。

练习

  1. 为“中文运维手册问答”填写一张完整空间契约,未知动态字段写“需查官方”,不要猜值。
  2. 计算 1,000,000 个 768 维 float32 的原始向量字节;列出公式未计入的 5 类开销。
  3. 证明单位向量上 Euclidean distance 与 dot 排序等价。
  4. 设计 4 个角色错误 smoke queries,其中至少包含短问找长文和代码检索。
  5. 为 256/768/1536 三个官方支持维度设计公平实验;写出不能同时改变的变量。
  6. 解释为什么新旧模型 cosine 分数不能直接用同一个阈值。

掌握检查

  • 我先定义任务与数据,再看模型榜单。
  • 每个空间有完整且不可歧义的 provider/model/revision/role 契约。
  • 我只在模型明确支持时改变维度,并重新评测。
  • 我能推导 cosine、dot、Euclidean 在单位向量上的关系。
  • metric、归一化与索引配置一致。
  • 超长输入按显式拒绝、切分或截断策略处理,并可审计是否发生截断。
  • 模型决策同时覆盖质量、子组、延迟、存储、费用、许可和隐私。

小结与下一步

选择模型只完成了“生成什么向量”的定义。下一步要保证数千或数百万输入在失败、限流和重跑时仍逐项对齐、可缓存且不产生旧向量:[[Knowledge/AI Agent Engineer/docs-CN/Embedding/03-批处理缓存与可靠性|批处理、缓存与可靠性]]。

参考资料

来源获取日期:2026-07-22。返回 [[Knowledge/AI Agent Engineer/docs-CN/Embedding/00-目录|Embedding 目录]]。