ANN(Approximate Nearest Neighbor)综述:从问题定义到主流算法路线
一句话总结
ANN(近似最近邻搜索)要解决的是:面对海量高维向量,如何不做全量扫描,也能很快找到“最像”的那几个点。 过去二十多年,业界和学界逐渐形成了几条主流路线:哈希、树、量化、图、磁盘图索引,以及它们的混合系统。 如果只记一句话,那么就是:
ANN 的本质,是在“速度、精度、内存、构建成本、更新能力”之间做结构化取舍。
这份报告写给谁
这篇报告按“数学小白也能读懂”的方式来讲,重点不是公式推导,而是:
- ANN 到底是什么问题
- 为什么这个问题这么难
- 主流方法到底各自像什么
- 重要论文各自贡献了什么
- 为什么今天很多系统最终偏爱 HNSW / IVF-PQ / DiskANN 这几条路
先讲最基本的问题:什么叫最近邻搜索
假设我们有很多向量:
- 文本 embedding
- 图片 embedding
- 用户画像向量
- 商品向量
- 多模态表示向量
当你给我一个查询向量 q 时,我想找数据库中距离它最近的若干个点。
这就叫:
- Nearest Neighbor Search(最近邻搜索)
- 或者更常见地找 Top-K:K-Nearest Neighbor Search
最笨的方法
最直接的办法就是:
- 拿
q和库里每个点都算一遍距离 - 然后选最小的 K 个
这叫 brute-force / linear scan。
它的优点:
- 绝对正确
- 实现最简单
它的缺点:
- 数据量一大就太慢
- 尤其当数据规模从百万到十亿时,几乎不可接受
所以 ANN 研究关注的问题是:
能不能不看所有点,也还能找到几乎正确的答案?
ANN 和精确搜索的区别
精确最近邻
要求:
- 找到的就是“真正最近”的点
- 一个都不能错
近似最近邻 ANN
允许:
- 偶尔不完全最优
- 只要大多数情况下足够接近真值即可
换来的好处:
- 大幅提速
- 降低内存访问
- 可以支撑大规模向量检索系统
所以 ANN 不是“做错了”,而是:
主动接受一点点误差,换取巨大的系统效率收益。
为什么高维会让问题变难
这是 ANN 里最核心的背景问题之一。
低维时,树通常很好用
比如二维平面里找最近点:
- 你可以很容易把空间切块
- 很多点可以快速排除
高维时,空间切分开始失效
当维度很高,比如 128 维、384 维、768 维时:
- 数据越来越稀
- 很多“边界剪枝”不再明显
- 树结构很容易退化
这就是大家常说的:
- curse of dimensionality(维度灾难)
它不是说“高维完全不能搜”,而是说:
低维里那些很好用的几何直觉,在高维下会迅速失灵。
这也是 ANN 百家争鸣的根本原因。
ANN 系统到底在权衡什么
ANN 不是一个单指标优化问题,而是多目标平衡。
通常要同时考虑:
1. 查询延迟
一次 query 多快返回。
2. Recall
是不是把真正的近邻找回来了。
3. 吞吐
单位时间能处理多少查询。
4. 内存占用
索引会不会太大。
5. 构建成本
建索引快不快。
6. 更新能力
新数据能不能增量插入,旧数据能不能删除。
7. 存储介质
全在内存里,还是要依赖 SSD / NVMe。
一个方法快,不代表它整体最好;它可能:
- 占内存太大
- 更新太差
- 构建太慢
- 或者 recall 不够
所以 ANN 本质上是系统工程问题。
评价 ANN 最常见的指标
Recall
最重要。
如果真实 Top-10 里你找回了 9 个:
- recall = 0.9
Recall 越高越接近真值。
QPS / Latency
- QPS:每秒查询数
- Latency:单次查询耗时
Build time
索引构建时间。
Memory footprint
索引内存大小。
Index size on disk
磁盘索引大小,尤其对磁盘型 ANN 很重要。
所以论文常见比较方式是:
在固定 recall 下,谁更快;或者在固定延迟下,谁 recall 更高。
ANN 的主要技术路线图
把几十年工作压缩一下,可以粗分成几类:
- 树方法:KD-tree、随机投影树、Annoy 一类
- 哈希方法:LSH 一类
- 量化方法:PQ、IVF-PQ、ADC、OPQ、ScaNN 一类
- 图方法:NSW、HNSW、NSG 一类
- 磁盘图方法:DiskANN 一类
- 混合系统:粗筛 + 精排 / 内存 + 磁盘 / 分区 + 图 / 分区 + PQ
下面按路线讲。
第一部分:哈希路线 —— LSH
直觉是什么
LSH(Locality-Sensitive Hashing)想做的事很朴素:
设计一种哈希,让“近的点更容易落到同一个桶里,远的点不容易”。
这和普通哈希恰好相反:
- 普通哈希希望分得尽量散
- LSH 希望保留“近似邻近关系”
数学小白版理解
想象你把空间切成很多随机投影形成的签名:
- 两个点很近,它们的签名大概率相似
- 两个点很远,它们的签名大概率不同
检索时:
- 不用扫全库
- 只去看和 query 哈希值相同/相近的那些桶
代表论文
Gionis, Indyk, Motwani (1999)
Similarity Search in High Dimensions via Hashing
- 链接:http://www.vldb.org/conf/1999/P49.pdf
- 贡献:奠定了 LSH 作为高维 ANN 经典路线的基础
论文摘要里最核心的意思是:
- 高维下树方法会被维度灾难打爆
- 近似搜索在很多实际应用里已经够用
- 可以通过哈希让近邻更高概率碰撞,从而加速搜索
优点
- 理论味很强
- 对某些距离族有漂亮分析
- 适合做概率保证型 ANN
缺点
- 桶设计和参数调优比较麻烦
- 很多场景下工程效果不如后来图方法强
- 在现代 embedding 检索里,不再是最主流的默认首选
你可以怎么记住它
LSH = 用“保邻近”的哈希来缩小候选集合。
第二部分:树路线 —— KD-tree、随机投影树、Annoy
直觉是什么
树方法想做的是:
把空间一层层切开,让 query 只访问少量区域,而不是全空间。
低维时这非常自然。
为什么后来不再统治高维 ANN
因为维度高了之后:
- 每次切分排除不了太多点
- 树深了也不代表有效剪枝
- 最终访问的节点可能还是很多
代表思路
KD-tree / randomized tree / FLANN
早期很经典。
- 低维或中低维仍然有价值
- 在某些数据上仍然实用
Annoy
Spotify 开源的经典库。 它本质上是:
- 多棵随机投影树
- 查询时同时走多棵树
- 聚合候选
Annoy 的优点:
- 实现简单
- 好部署
- 静态只读服务很方便
缺点:
- 在很多高 recall、高维、大规模场景下,往往不如 HNSW 强
你可以怎么记住它
树方法 = 先把空间切块,再只搜一小部分块。
它是最符合直觉的一路,但在高维里不是最强的一路。
第三部分:量化路线 —— PQ、IVF-PQ、Faiss、ScaNN
这条路线在工业界极其重要。
核心直觉
量化路线想做的是:
把向量压缩成短码,用短码快速估计距离,而不是总拿原始向量硬算。
换句话说:
- 少存点
- 少算点
- 更容易扩展到超大库
代表论文 1:Jégou et al. (2011)
Product Quantization for Nearest Neighbor Search
这篇论文是 PQ 路线的里程碑。
它的核心想法
把一个高维向量切成多个子空间:
- 每个子空间分别量化
- 每段只存一个短小的 code
- 整个向量就变成多个 code 拼起来的短码
然后距离不再直接用原始向量算,而是:
- 通过查表快速估计
为什么这很强
因为:
- 存储从“原始浮点向量”变成“紧凑编码”
- 距离计算也从大量浮点乘加,变成更轻量的查表
这篇论文摘要的核心内容
它明确说:
- 把空间拆成多个低维子空间
- 每个子空间单独量化
- 通过编码快速估计欧氏距离
- 再加 inverted file system 时效果更强
- 在十亿甚至二十亿级数据上具有很好扩展性
IVF 是什么
IVF = Inverted File
你可以理解成:
- 先做一个粗聚类
- 数据先分桶
- query 先找最可能的几个桶
- 再只在这些桶里做更细的 ANN
所以 IVF 的角色是:
粗筛候选分区
而 PQ 的角色是:
压缩和快速距离估计
这两个经常组合起来,就是:
- IVF-PQ
为什么 IVF-PQ 这么常见
因为它同时解决了两个大问题:
- 不用搜全库,只搜部分桶
- 候选点也不是原始全精度向量,而是压缩码
所以它特别适合:
- 超大规模库
- GPU/CPU 批量检索
- 内存压力敏感场景
代表论文 2:Johnson et al. (2017)
Billion-scale similarity search with GPUs
这篇论文也是 Faiss 路线的代表作。
它干了什么
核心不是提出全新 ANN 基础理论,而是:
- 把相似搜索在 GPU 上做得极强
- 优化 top-k selection、内存层次、PQ 搜索等关键路径
- 让十亿级相似搜索真正变得可工程化
这篇论文的重要意义
它告诉大家:
ANN 不只是索引结构问题,还是硬件利用问题。
后来的很多系统实践都深受影响。
代表论文 3:Guo et al. (2020)
Accelerating Large-Scale Inference with Anisotropic Vector Quantization
这是 ScaNN 背后的代表论文。
它的核心想法
传统量化方法主要最小化“重建误差”。 但在最大内积搜索(MIPS)里,真正重要的不是所有方向都同样精确,而是:
对影响排序最关键的方向,误差要更小。
ScaNN 的工作重点就是:
- 不再只追求一般性的重建精度
- 而是让量化更贴合检索目标本身
为什么重要
这说明量化路线在进化:
- 早期 PQ 更像通用压缩
- 后来的方法更像“任务感知型压缩”
量化路线的优点
- 内存效率高
- 更适合超大规模数据
- 很适合 GPU 和批量检索
- 工业界成熟度非常高
量化路线的缺点
- 通常需要训练码本 / 聚类中心
- 系统比单纯图结构更复杂
- 极高 recall 下未必总能赢图方法
- 更新/增量维护不一定像图那么自然
你可以怎么记住它
量化路线 = 先粗筛,再用压缩码快速比距离。
第四部分:图路线 —— NSW / HNSW
核心直觉
图路线想做的是:
把数据点连成一张“可导航”的图,然后让 query 在图上走,越走越接近目标。
这条路线在今天极其重要。
基础版:NSW
单层小世界图。
- 点连到邻居
- 查询从入口开始贪心走
- 借助 small world 性质快速接近目标
但 NSW 有缺点:
- 单层图既要负责远程导航又要负责局部精修
- 在低维、聚簇数据上可能退化
里程碑:Malkov & Yashunin (2016/2018)
Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs
这就是 HNSW。
为什么它这么重要
它把图索引推进到了一个非常好用的工程平衡点:
- 多层结构
- 高层做长距离导航
- 低层做局部精修
- 用更聪明的邻居选择 heuristic 保持图可导航性
为什么今天 HNSW 这么火
因为它同时满足:
- 快
- recall 高
- 增量构建友好
- 工程上不算复杂
- 对多种数据分布比较稳健
如果要一句话概括:
HNSW = 图版 skip list。
风车车前面已经给爹单独写过这篇精读。
图路线的优点
- 高 recall 表现强
- 很多 embedding 场景下效果非常好
- 参数相对直观(如
M,efSearch,efConstruction) - 查询延迟表现常常很优秀
图路线的缺点
- 内存占用往往不低
- 大规模删除/压缩/重构更麻烦
- 超大规模下,纯内存图会遇到容量问题
你可以怎么记住它
图路线 = 让 query 在一张好导航的图里“走路找近邻”。
第五部分:磁盘图路线 —— DiskANN
当数据继续大到:
- 内存放不下
- 但又想要高 recall、高吞吐
就需要新的路线。
核心问题
图索引很强,但纯图索引的一个大问题是:
- 图通常更偏内存型
- 数据到十亿量级时,内存压力巨大
那么问题来了:
能不能保留图索引的导航能力,同时把大部分数据放到 SSD 上?
代表工作:DiskANN
DiskANN: Fast Accurate Billion-point Nearest Neighbor Search on a Single Node
- 微软研究页面:https://www.microsoft.com/en-us/research/publication/diskann-fast-accurate-billion-point-nearest-neighbor-search-on-a-single-node/
- 项目仓库:https://github.com/microsoft/DiskANN
GitHub 项目自己的描述很直接:
- Graph-structured Indices for Scalable, Fast, Fresh and Filtered Approximate Nearest Neighbor Search
它的核心思想
可以粗略理解为:
- 仍然保留图导航思想
- 但把图和数据布局设计成更适合磁盘访问
- 尽量让 SSD 访问模式更高效
- 让超大规模 ANN 在单机上也能做到高精度、高吞吐
为什么它重要
因为它补上了图路线的一大短板:
- 纯内存太贵
DiskANN 所代表的,是 ANN 从“内存索引算法”走向“存储层级协同系统”的方向。
你可以怎么记住它
DiskANN = 把图索引从内存世界推进到 SSD 世界。
第六部分:ANN 不只是算法,还是系统设计
很多人初学 ANN,会以为:
- 选一个算法就完了
其实不是。
真正系统通常是多层结构:
- 粗筛:分区 / 聚类 / 哈希 / 路由
- 候选生成:图 / PQ / 量化 / 树
- 精排:原始向量重算距离
- 缓存 / 内存 / SSD 分层
- 增量更新 / 合并 / compaction
所以 ANN 更像数据库或检索系统设计问题,而不仅是单个算法问题。
现代常见组合
1. IVF + PQ
- 适合超大库
- 内存效率高
- GPU 很友好
2. HNSW
- 适合高 recall、低延迟、内存足够的场景
- 也是很多向量数据库的默认索引
3. DiskANN
- 适合超大规模、单机 SSD 场景
4. Graph + quantization / rerank
- 越来越多系统采用混合方案
第七部分:benchmark 视角告诉我们什么
代表工作
Aumüller et al. (2018)
ANN-Benchmarks: A Benchmarking Tool for Approximate Nearest Neighbor Algorithms
它的重要意义
这篇工作最大的贡献不是提出新索引,而是:
让大家能在统一框架下比较不同 ANN 方法。
这很重要,因为 ANN 太工程化了:
- 参数很多
- 数据集差异很大
- 一个方法在 A 数据集强,不代表在 B 数据集也强
ANN-Benchmarks 的一个非常重要的启发是:
没有绝对最好的 ANN 方法,只有更适合某个工作负载的方法。
这点非常值得记住。
第八部分:怎么建立一个“ANN 方法全景图”
如果把前面内容压成一张脑图,可以这么记:
路线 A:哈希
- 代表:LSH
- 核心:近点更容易碰撞进同一桶
- 关键词:概率保证、桶检索
路线 B:树
- 代表:KD-tree、随机投影树、Annoy
- 核心:递归切空间
- 关键词:空间分割、低维友好
路线 C:量化
- 代表:PQ、IVF-PQ、Faiss、ScaNN
- 核心:粗分区 + 压缩编码 + 快速距离估计
- 关键词:省内存、超大规模、高吞吐
路线 D:图
- 代表:NSW、HNSW
- 核心:可导航图
- 关键词:高 recall、低延迟、工程强势
路线 E:磁盘图
- 代表:DiskANN
- 核心:图索引 + SSD 友好布局
- 关键词:十亿规模、单机、存储层级协同
第九部分:如果我是初学者,我该怎么判断该学哪条路线
如果你想先建立全局认知
建议顺序:
- 先理解 ANN 问题定义和 recall
- 看 LSH:理解“近邻保真哈希”这个经典思路
- 看 PQ:理解“压缩 + 距离近似”
- 看 HNSW:理解“图导航”
- 看 DiskANN:理解“系统化扩展到磁盘”
如果你想更贴近今天工业界
建议顺序:
- 先看 HNSW
- 再看 IVF-PQ / Faiss
- 再看 DiskANN
- 最后补 LSH 和树,作为历史与理论背景
原因很简单:
- 现在很多生产系统最常见的核心路径就是图和量化
第十部分:如果我是工程师,我最该关心什么
1. 你的目标是高 recall 还是便宜吞吐
- 高 recall、低延迟、内存够:优先考虑图(如 HNSW)
- 超大规模、成本敏感:优先考虑量化(如 IVF-PQ)
- 数据上 SSD:看 DiskANN
2. 数据是静态还是动态
- 动态插入多:图方法通常更自然
- 批量离线构建:量化路线也很强
3. 内存预算多大
- 图通常更吃内存
- PQ/压缩路线更省
4. 距离类型是什么
- L2 / cosine / inner product 会影响适合的方法
- MIPS 问题下很多系统会做额外变换或专门优化
5. 你要不要 rerank
很多系统不是一次性给最终答案,而是:
- 先 ANN 找 100~1000 个候选
- 再用原始向量精排
这通常能显著改善最终质量。
第十一部分:我对 ANN 这件事的整体理解
我觉得 ANN 领域最值得记住的不是单个算法,而是这三个大方向:
方向 1:不要硬刚精确性
ANN 的伟大之处在于:
- 它接受“几乎正确”
- 从而把系统做大、做快、做实用
方向 2:结构比暴力更重要
真正快的系统,不是更快地算所有点, 而是:
- 让大部分点根本不用算
- 或者只用粗算
方向 3:今天最强的方法,本质都在做“候选缩减”
不同方法看起来很不一样,但本质都在做同一件事:
先缩小候选集,再更认真地算候选。
- 哈希:用桶缩小候选
- 树:用空间切分缩小候选
- IVF:用聚类桶缩小候选
- 图:用导航路径缩小候选
- DiskANN:用图 + 存储布局缩小候选
所以 ANN 的统一视角就是:
不要搜索整个空间,而要快速找到“最值得认真算的那一小撮点”。
第十二部分:给初学者的最终复述
如果爹只想记住最核心的一版,可以记下面这段:
ANN 是解决“如何在海量高维向量里快速找到最相似项”的技术。它之所以难,是因为高维让传统树索引很容易失效。后来形成了几条主要路线:LSH 用哈希缩小候选;树方法用空间切分缩小候选;PQ/IVF-PQ 用分区和压缩码降低搜索成本;HNSW 用多层图做高效导航;DiskANN 则把图索引推进到 SSD 场景。今天工业界最常见、最有代表性的主线,大致就是图索引和量化索引,以及二者与系统工程的混合体。
重要资料与论文清单
问题背景与基准
- ANN-Benchmarks: A Benchmarking Tool for Approximate Nearest Neighbor Algorithms
https://arxiv.org/abs/1807.05614 - ANN-Benchmarks 网站
https://ann-benchmarks.com/
哈希路线
- Similarity Search in High Dimensions via Hashing (Gionis, Indyk, Motwani, 1999)
http://www.vldb.org/conf/1999/P49.pdf
量化路线
- Product Quantization for Nearest Neighbor Search (Jégou et al., 2011)
https://ieeexplore.ieee.org/document/5432202 - Billion-scale similarity search with GPUs (Johnson et al., 2017)
https://arxiv.org/abs/1702.08734 - Accelerating Large-Scale Inference with Anisotropic Vector Quantization (Guo et al., 2020)
https://arxiv.org/abs/1908.10396
图路线
- Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs (Malkov & Yashunin, 2016/2018)
https://arxiv.org/abs/1603.09320
磁盘图路线
- DiskANN: Fast Accurate Billion-point Nearest Neighbor Search on a Single Node
https://www.microsoft.com/en-us/research/publication/diskann-fast-accurate-billion-point-nearest-neighbor-search-on-a-single-node/ - DiskANN GitHub
https://github.com/microsoft/DiskANN
可以继续展开的后续主题
- IVF / PQ / OPQ / ADC 到底各自是什么关系?
- MIPS(最大内积搜索)和普通 ANN 有什么区别?
- 向量数据库为什么常常提供 HNSW 和 IVF-PQ 两套索引?
- DiskANN 和 HNSW 的系统边界分别在哪里?
- 如何根据 recall、延迟、内存预算来选 ANN 索引?