模型、维度与归一化选择
本节目标
你将把“选一个 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 的训练方式可能不同。模型常见三种设计:
- 两套 encoder;
- 同一 encoder,但用 query/document prompt 或 task type;
- 同一调用且没有角色差异。
截至 2026-07-22 的官方示例:
- Sentence Transformers 为检索推荐
encode_query()/encode_document();若模型没有专用 prompt/route,两者可能等价。 - Cohere 文档区分
search_query与search_documentinput 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 或模态定义限制。具体数值会变化,必须保存官方链接与核对日期。
最安全的基线:
- 使用对应 tokenizer 或官方计数方式;
- 在
[[Knowledge/AI Agent Engineer/docs-CN/Chunking策略/00-目录|Chunking策略]]阶段控制长度; - 超长输入显式拒绝或重新切分;
- 若确需截断,保存实际 embedding input、hash、截断位置和告警;
- 绝不让数据库正文与实际被编码文本静默不一致。
部分 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,000,000 个 768 维 float32 的原始向量字节;列出公式未计入的 5 类开销。
- 证明单位向量上 Euclidean distance 与 dot 排序等价。
- 设计 4 个角色错误 smoke queries,其中至少包含短问找长文和代码检索。
- 为 256/768/1536 三个官方支持维度设计公平实验;写出不能同时改变的变量。
- 解释为什么新旧模型 cosine 分数不能直接用同一个阈值。
掌握检查
- 我先定义任务与数据,再看模型榜单。
- 每个空间有完整且不可歧义的 provider/model/revision/role 契约。
- 我只在模型明确支持时改变维度,并重新评测。
- 我能推导 cosine、dot、Euclidean 在单位向量上的关系。
- metric、归一化与索引配置一致。
- 超长输入按显式拒绝、切分或截断策略处理,并可审计是否发生截断。
- 模型决策同时覆盖质量、子组、延迟、存储、费用、许可和隐私。
小结与下一步
选择模型只完成了“生成什么向量”的定义。下一步要保证数千或数百万输入在失败、限流和重跑时仍逐项对齐、可缓存且不产生旧向量:[[Knowledge/AI Agent Engineer/docs-CN/Embedding/03-批处理缓存与可靠性|批处理、缓存与可靠性]]。
参考资料
- Sentence Transformers Usage
- MTEB Overview
- MTEB original paper
- Kusupati et al., Matryoshka Representation Learning
- OpenAI: Vector embeddings
- Gemini API: Embeddings
- Cohere: Introduction to Embeddings
来源获取日期:2026-07-22。返回 [[Knowledge/AI Agent Engineer/docs-CN/Embedding/00-目录|Embedding 目录]]。