先给结论:检索的核心操作是「给查询向量,从一大堆里找最近的几个」。精确扫一遍,几千条还行,过亿就废了。近似近邻用召回换延迟:少比一些、每次比得更便宜、或把数据放到更慢的盘上。局部敏感哈希、低维树、倒排簇、乘积量化、分层小世界图,砍的是不同的比较次数。过亿以后内存装不下全精度图,要把图放到固态盘,内存只留压缩码。

为什么「再加几台机器线性扫」填不上检索缺口

痛点是延迟和内存同时爆。局部敏感哈希把向量投到随机方向上分桶,查询只搜同桶。它故意最大化碰撞,和普通哈希相反。随机投影条数一多,加速就被吃掉,现在基本退成背景知识:神经网络学出来的嵌入,可以看成学过的语义哈希。k 维树按单维切、平衡二分,低维好用,嵌入这种高维会退化。随机投影森林改成:建多棵树,切分不再取中位数,而是随机两点连线的方向。倒排簇先对全体做聚类,查询先比簇中心,再只打开最近几个簇。边界上的真近邻会落在没打开的簇里,召回掉。常见补法是每个向量挂到好几个近簇,从两侧兜住边界。

乘积量化砍的是「每一次比较」而不是「比多少条」。向量切成子段,各段分别聚类,存成短整数码。查询同样切开,预先算好查询子段到每个中心的平方距离,存储向量的距离变成查表相加,不再做全精度点积。子段之间相关会让切分吃亏,优化版先学一个旋转,让各子空间方差更匀、更去相关,再切。分层小世界图是中等规模(大约千万级)的主流:在向量上建邻近图,贪心走向查询;上层稀疏走远,下层加密精修。边不能只连当时的最近邻,否则走错区就出不来。随机顺序插入、在插入瞬间连当时的 M 个近邻,早插入的点会留下长边,图才可导航。支持增量插入,但建图和插入都贵,删除别扭,图还得住内存。

五步把近邻从精确扫收成可验收的索引课表

  1. 先写预算:目标召回、延迟、建索引时间、内存。四项不写,方法对比没有意义。
  2. 百万级以内优先图。分层图查询快,但要承认删除难、必须常驻内存。过滤条件(租户、日期)不能退化成全表扫描,图遍历要带着过滤走。
  3. 倒排簇当粗筛。只开 top 簇,边界用多分配。簇数和探测数是召回–延迟旋钮,要在同一套查询集上画曲线,不要口头说「差不多」。
  4. 量化当内存阀。乘积量化把全精度换成码本;查询用非对称距离(查询保持高精度、库用码)。相关强就先旋转。量化误差会伤排序,重要查询要留一层全精度重打分。
  5. 过亿上盘。内存只放压缩码和路由,全精度向量和图在固态盘。图构造要偏向少而远的跳,因为每次缓存未命中就是一次盘往返。簇方案同样:中心路由在内存,簇内容在盘。跨方法还要算上 GPU 吞吐和带过滤的混合检索,引擎层通常是图或倒排加量化再加运维,没有新算法。
方法 砍什么 典型失败 门禁
精确扫描 不砍 过万就慢 只能当金标准
倒排簇 打开的簇数 边界召回 多分配 + 召回曲线
乘积量化 每次比较和内存 子段相关、排序误差 旋转 + 重打分
分层邻近图 走的边数 删除、内存、过滤 千万级优先,过亿上盘
盘上图 / 盘上簇 内存里的全精度 跳数一多盘往返爆炸 跳必须少而远

现场有三条。其一,局部敏感哈希和低维树不是当前默认,但语义哈希的思路还在:嵌入本身就是把相似的东西投到近处。其二,库和引擎会换皮,算法族相对稳。选型要对着公开基准核实时数字,不要背名单。其三,真实查询几乎都带过滤。索引若不能在过滤下保持近似,生产里会静默退化成扫描。

近似近邻没有免费午餐:召回、延迟、内存、建库时间四角只能压三角。课表要把四条曲线画在同一张查询集上,再决定砍哪一角。现场还要分清「库」和「引擎」:库实现索引族,引擎加上分段、复制、过滤和混合检索。换引擎不等于换算法。评测要对着同一查询集和同一过滤条件,否则延迟数字没有意义。

若只能改检索栈一处:禁止默认精确扫。先定召回下限,再在倒排、量化和图三条里选,过亿必须报内存里到底留了全精度还是只留码。量化后的排序误差要用重打分兜底:候选集用码距拉出来,最终名次用全精度算。没有重打分,召回曲线会看起来很好,业务排序却是错的。

结论:近邻系统是在显式买卖召回,不是在「尽量快一点」

哈希、树、簇、量化、图砍的是不同比较。过亿要把图放到盘上。仍把精确扫当默认,是在用实验室规模覆盖生产规模。

你下次上向量检索,先报召回、延迟、内存和是否带过滤。四项缺一,近似就不能写进架构图。

效率龙虾 会带着下面这段开聊

按文章《近似近邻是在用召回换延迟:哈希树图和量化各砍不同的比较次数》把卡点收成可执行步骤:先做什么、别踩哪条、怎么验证。

用效率龙虾试这篇

本文侧重全链路风控方法论。落地时请用自身业务单据做回放验证,不要把示例阈值直接当生产策略。 相关:风控体检 · 方案资源

常见问题 FAQ

近似近邻检索用召回换延迟,具体是什么意思?

精确扫描要一个不落地比对所有向量,数据量大了速度和内存都扛不住。近似近邻的思路就是“放弃一点精确性,换取快得多的速度”。比如,用哈希或树结构快速过滤掉大部分明显不相关的向量,只对剩下的一小部分做精确比较,或者用量化技术把每次比较的计算成本大大降低。这相当于一场“交易”,用找到部分真实结果的概率(召回率),来换取系统在实际使用中能接受的响应时间。

为什么不能通过“多加几台机器做线性扫描”来解决大规模向量检索的问题?

因为瓶颈是“延迟”和“内存”同时爆炸。精确扫描是O(N)的计算和O(N)的内存,数据量翻十倍,需求也翻十倍。单纯加机器只是把计算任务分摊了,但每个节点仍然需要加载海量数据,且网络传输和合并结果会带来新的延迟。内存总量和查询的端到端延迟很难通过简单横向扩展线性解决,无法填上数据规模带来的性能缺口。

面对百万级和亿级数据,选择索引方法的优先策略是什么?

文章给了一个清晰的优先级:百万级以内,优先考虑分层小世界图索引,它查询快,但要接受其删除困难和必须常驻内存的特点。当数据规模超过一亿时,内存已经放不下完整的图结构,必须将图或倒排索引等结构的详细数据放到固态硬盘上,内存只保留压缩码、聚类中心或图的高层路由信息。这时需要特别优化,确保从硬盘加载数据的次数尽可能少。

在生产环境中部署向量检索,最容易忽略的一个陷阱是什么?

最容易忽略的陷阱是“过滤条件导致检索退化”。真实业务查询几乎都带过滤(比如按用户、时间、类别)。如果索引方法在带过滤查询时,无法高效地在索引内部完成过滤,而是被迫退化成全表扫描,那么精心设计的近似加速就完全失效了。所以,索引必须支持高效的“带过滤的近似近邻”查询,否则生产环境的性能会远低于预期。

分层小世界图和乘积量化这两种主流方法,在解决的问题上有什么核心区别?

它们解决的问题层次完全不同。分层小世界图(如HNSW)主要解决“比多少条”的问题:它通过图结构的贪心导航,快速找到可能相近的少数候选向量,从而大幅减少需要精确比较的向量数量。而乘积量化解决的是“每一次比较怎么做”的问题:它通过将向量压缩为短码,用查表操作代替耗时的全精度点积,让每一次比对的计算开销变得极低。一个是在“数量”上优化,一个是在“单次成本”上优化。

如果只能对现有的检索系统做一处优化,最优先应该改什么?

最优先要“禁止默认使用精确扫描”。首先设定一个召回率下限(比如95%),然后在这个约束下,在倒排簇、乘积量化和分层图这三条技术路线中进行选择和组合。对于亿级以上的数据,必须明确内存里存的到底是全精度向量还是压缩码。最后,一定要用全精度结果对量化排序后的候选集进行“重打分”,否则表面召回率高,但业务看到的排序可能是错的。