一句话定义:点积检索(dot product search)直接拿两个向量的内积作为相似度分数;余弦检索(cosine similarity search)先除掉向量自身的长度,只比较两个向量之间的夹角。两者唯一实质区别就是有没有做归一化(normalization)。
一个公式就能说清
点积:a·b = |a||b|cosθ
余弦:cosθ = a·b / (|a||b|)
所以余弦就是“归一化之后的点积”。给库里每个向量先除以自己的模长,再算内积,排序结果和余弦完全一致。工程上大家常这么做:向量库对“内积”这条路径的支持通常比专门的余弦度量更完备,预归一化后还能省掉每次查询时的除法。
打个生活化的比方
把向量想成一支“意见箭头”:方向代表你关心什么,长度代表你说得多大声。
点积像是在会议室投票:它既看你立场跟我一不一致,也看你嗓门多大。嗓门大的人更容易被听见。
余弦则只看立场:不管你是小声嘀咕还是拍桌子,只要方向一致,得分就一样。
什么时候该保留长度
关键问题在于:长度里到底有没有信息量?这取决于 embedding 是怎么来的。
- 有些场景长度自带语义:用户向量的模长可能反映活跃度,文档向量的模长可能反映信息量或置信度,这时点积更合适。
- 但更多时候长度是噪声:文本越长越啰嗦,某些模型产出的向量模长就越大。此时用点积,检索会系统性地偏向长文档,你想找的“语义相近”被“体量大”污染了。
| 点积检索 | 余弦检索 | |
|---|---|---|
| 是否归一化 | 否 | 是 |
| 打分含义 | 方向 × 长度 | 只看方向 |
| 取值范围 | 无界 | 一般落在 [-1, 1] |
| 适合 | 长度有意义 | 长度是噪声 |
| 计算成本 | 低 | 略高,预归一化后等价 |
三个常见问题
1. 训练方式和检索方式最好保持一致。 有的 embedding 模型训练时用余弦目标,有的直接拿内积训练;用与训练一致的方式打分更稳妥。归一化后再做点积,对按余弦训练的模型没问题;但反过来,把按内积训练的模型强行归一化,可能丢掉它本来想用的长度信息。具体以模型的官方文档为准。
2. 相似度阈值不能跨度量复用。 点积无界,余弦有界;一旦换了度量,之前调好的阈值就得重新校准。
3. 索引配错。 向量库通常把内积和余弦列为不同的索引参数;数据没归一化却选了内积,结果就会偏向模长大的向量。
实际意义
对从业者来说,上线前可以采样看一批 Top-K 结果,检查是不是“又长又水”的内容占了便宜。如果是,先做归一化,这是成本最低的一次排查。
对普通人来说,当你觉得搜索“推了一堆很长但不太相关的东西”,或者相似推荐里混进明显不搭的条目,问题很可能出在度量方式上,模型本身未必不行。
