欢迎光临
我们一直在努力

向量距离早停:哪条不等式保正确,哪种剪枝会掉召回

封面

距离计算里跳过一段维度,和图搜索里少走一段路径,是两种不同的剪枝。前者有时能用不等式证明不会错,后者往往需要用召回率付账。混在一起写“确定性提速”,读者很难知道丢掉了什么。

本文专属原理图

原理示意,非真实系统截图或性能测量。

平方L2有非负部分和

若d²=Σ(aᵢ−bᵢ)²,计算一部分维度得到的和不会大于完整结果。因此部分和已经严格大于当前可接受的最差距离时,这个点不可能更优,可以不再算余下维度。

这里用“严格大于”。若等于阈值,文档ID等并列规则可能仍决定是否入选;不能随手改成大于等于。

def bounded_l2(a,b,bound):
if len(a)!=len(b):
raise ValueError("dimension mismatch")
total=0.0
for x,y in zip(a,b):
total+=(x-y)**2
if total>bound:
return None
return total

for n in [0,1,3,4,5,31,33]:
a=list(range(n));b=[0]*n
exact=sum((x-y)**2 for x,y in zip(a,b))
assert bounded_l2(a,b,exact)==exact
if exact>0:
assert bounded_l2(a,b,exact/2) is None
# Inner products have negative terms: a partial value is not such a bound.
assert sum([10,-20]) < 10
print("PASS tail dimensions and exact threshold; dot-product counterexample")

本地Python 3.9.6通过这些边界。这个逐元素版本用来说明证明,不是优化实现。真正分块时必须处理最后不足整块的尾维;dim//4再固定算四段,会漏掉余数。

内积不能照抄这条早停

内积项可以为负。先算到10,后面再加−20,完整值是−10。要给余项建立界,需要另外的范数、量化误差界或索引结构条件。Faiss的度量文档区分了内积与平方L2;不能因为二者在某些归一化条件下排序相关,就把部分和性质也搬过去。

同样,某个图节点本身距离不好,不代表经由它不能通向更好的点。候选评分和图导航承担的职责不同。“连续若干步没改善就停止”是启发式,不是从非负平方项推出来的定理。

少算了,也可能没有更快

分段判断增加分支;块太小,节省的乘加可能抵不过分支和随机访存。改完代码应同时记录距离计算次数、Recall、P99、CPU与缓存行为。仅比较平均一次距离函数,不能代替完整图搜索。

cuVS CAGRA文档把建图和搜索描述为近似算法。若改它的停止条件,应在同一精确金标与查询集上看召回变化。

这里没有运行HNSW/CAGRA,没有GPU或千万向量压测,也没有30%的吞吐数字。已证明的只有平方L2部分和边界,已运行的只有完整Python反例。把这两个范围写清,比先挑一个好看的百分比稳妥。

赞(0)
未经允许不得转载:171主机测评 » 向量距离早停:哪条不等式保正确,哪种剪枝会掉召回
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址