精确扫描、近似索引与过滤
精确扫描对所有N个d维向量计算距离,代价约O(Nd),适合建立小规模正确性基线。近似最近邻用空间结构少看一部分候选,以召回损失换延迟;“近似”意味着可能漏掉真正最近的点,不意味着返回分数可以任意计算。
下面用确定的候选集合模拟近似索引遗漏,观察两种召回的不同含义:
python
vectors = {'a': [1.,0.], 'b':[0.9,0.1], 'c':[-1.,0.], 'd':[0.,1.]}
q = [1.,0.]
def search(ids, k):
return sorted(ids, key=lambda key: sum((x-y)**2 for x,y in zip(q,vectors[key])))[:k]
exact = search(vectors, 2)
approx = search(['b','c','d'], 2)
assert exact == ['a','b']
assert approx == ['b','d']
ann_recall = len(set(exact)&set(approx))/len(exact)
assert ann_recall == 0.5
print(exact, approx, ann_recall)这里0.5是ANN相对于精确top-2的召回,不是业务相关性标注召回。即使ANN召回100%,embedding模型也可能不懂查询。测试索引时先固定向量,测试模型时先固定扫描方式,才能区分误差来源。
三类常见结构的工作过程
HNSW把向量连成多层近邻图,从稀疏上层找入口、下层扩展候选。查询探索宽度更大通常增加召回与延迟;建图连边与构建探索参数影响内存和质量,不能用查询参数修复所有构建缺陷。IVF先把向量分配到聚类桶,查询仅探测若干桶;探测太少会漏掉邻近桶,数据分布漂移会恶化原聚类。PQ将向量子空间量化为码本索引,用紧凑编码近似距离;减少内存同时引入量化误差,必要时取回原向量精排。
这些说明给出调参方向,不承诺所有实现单调更快或召回必升。实际对比应固定数据、硬件、并发、k,记录p50/p95、内存和ANN召回,再查看业务召回。
过滤与近似搜索可能交织。后过滤从全局top-k删除未授权项,会返回不足k条;预过滤必须由引擎支持,且小候选集时精确扫描可能更合算。租户隔离不是把租户名加进向量文本,而是检索执行层的硬条件。删除项的墓碑、压实和重建策略也要与引擎契约对应。
练习
把模拟候选改成a、b、c,并证明ANN召回恢复为1。再说明为什么仍不能宣称检索任务准确率为100%。
完成后查看本章答案。
下一章:混合召回、查询增强与重排。