一、向量是什么
embedding 模型把一段文本映射成一个固定长度的数字数组,例如 768 个浮点数。这个数组可以理解为「语义坐标」:意思相近的文本,坐标也相近。
关键性质:
- 维度固定:同一个模型输出的维度一致(384、768、1024、1536 等)。
- 不能跨模型比较:不同模型的向量空间互不相通,换模型必须重建索引。
- 不保证可解释:单个维度通常没有明确含义。
二、相似度怎么算
余弦相似度:看两个向量的夹角,取值 -1 到 1,越接近 1 越相似。
cos(A, B) = (A · B) / (|A| × |B|)
欧氏距离:看两点之间的直线距离,越小越相似。
区别:
- 余弦只看方向,忽略长度,适合文本(长度差异不该影响语义相似度)。
- 欧氏距离对长度敏感。
- 如果向量已归一化(长度为 1),余弦相似度与欧氏距离等价(单调对应)。
所以多数向量库默认用余弦或内积(归一化后等价)。
三、阈值怎么定
「相似度 0.8 算重复吗」没有统一答案,取决于模型与数据。正确做法是用标注样本校准:
- 收集 50–100 对文本,人工标注「相似 / 不相似」。
- 计算每对的相似度。
- 看两类的分布,选一个能分开的阈值。
经验值(仅参考):同一模型下,0.9 以上通常高度相似,0.75–0.9 相关,0.6 以下多半无关。但不同模型分布差异很大,必须自己校准。
四、四个典型用途
语义搜索:把查询和文档都向量化,取 top-k。比关键词搜索更能处理同义表达。
聚类:对向量做 KMeans 或层次聚类,把相似文本归组(如工单分类、评论主题发现)。
去重:相似度超过阈值视为重复。注意「近似重复」(改了几个字)用哈希查不出来,向量可以。
推荐:用户历史内容的向量平均,找相近内容。
五、模型选择
考虑四点:
- 语言:中文场景选对中文优化过的模型(多语言模型通常也可以)。
- 维度:维度越高表达力越强,但存储与计算成本也高。
- 最大输入长度:超过会被截断,长文档要先切分。
- 是否支持指令:有些模型支持「为检索任务生成向量」,效果更好。
同一批数据用同一个模型;升级模型时要做离线评估,别直接切换。
六、维度与性能
- 100 万条 × 768 维 × 4 字节 ≈ 3GB,纯内存索引还能承受;上千万条就需要专门的向量库与量化。
- 量化(float32 → int8)能省 4 倍空间,精度略降。
- 降维(PCA 或模型自带的
dimensions参数)能减少存储与查询时间。 - 近似最近邻(HNSW、IVF)用少量精度换大幅提速,是向量库的默认选择。
七、常见坑
- 长文本直接向量化:一篇 5000 字的文章压成一个向量,会丢失细节。应按段落切分,每段一个向量。
- 查询与文档不对称:有些模型对「问题」和「段落」需要不同的处理方式(如加前缀),要按文档要求来。
- 归一化不一致:一部分向量归一化了,一部分没有,相似度就不可比。
- 跨语言:中文查询检索英文文档,需要多语言模型,否则效果很差。
- 阈值定太高:召回率过低,用户搜不到东西;定太低则噪声多。
八、实践建议
- 先做小规模验证(几千条),确认相似度分布合理。
- 建一个「查询 → 期望结果」的评估集,量化召回率。
- 向量检索 + 关键词检索混合,弥补各自的短板。
- 记录每次检索的 top-k 与用户点击,持续调优。
小结
embedding 是语义坐标,同模型内可比;余弦看方向、欧氏看距离,归一化后等价;阈值必须用标注样本校准;长文本先切分再向量化;换模型要重建索引。