论文:VSAG: An Optimized Search Framework for Graph-based Approximate Nearest Neighbor Search

开源代码库:https://github.com/antgroup/vsag

本文由蚂蚁集团、同济大学、英特尔和上海交大联合发表,旨在解决图基近似最近邻搜索(ANNS)在生产环境中的性能瓶颈。

📚 论文核心概览

背景问题:图基ANNS算法(如HNSW)虽然精度高,但在生产环境中面临三大瓶颈:

  1. 内存访问开销大:图遍历的随机跳跃导致严重的缓存未命中。
  2. 参数调优成本高:性能对参数极度敏感,手动调参需反复重建索引,耗时数小时甚至数天。
  3. 距离计算开销大:高维向量的距离计算耗时。

解决方案 VSAG:一个开源的图基ANNS优化框架,通过三大核心优化解决上述问题,在保证相同召回率的情况下,比工业标准库 HNSWlib 快高达4倍。

1. 背景与挑战详解

论文以 GIST1M 数据集(使用 SQ4 量化的 HNSW 作为基线)为例,量化了生产环境中的痛点:

指标 基线表现 (HNSW+SQ4) VSAG 优化效果

L3缓存未命中率

67.42% (内存访问占总时间63%)

降至 39.23%

参数调优成本

暴力搜索需 >60小时

仅需 2.92小时

距离计算开销

占搜索时间 26.12%

降至 0.1ms

表1:VSAG与现有算法在GIST1M上的对比(数据来源:原文Table 1)

2. 核心优化一:内存访问优化

图算法的根本问题在于随机内存访问。VSAG 从软件和硬件两个层面进行了优化。

2.1 软件预取:从被动到主动

传统的被动加载会导致CPU stall(等待数据)。VSAG利用 _mm_prefetch 指令,在计算当前向量时,提前将下一个邻居向量加载到缓存中。

  • 确定性访问:传统预取会预取已访问过的邻居(浪费带宽)。VSAG 先批量过滤出未访问的邻居,只对有效邻居发起预取。
  • 步长预取:预取时机很关键,太早会被驱逐,太晚则无效。VSAG 通过参数 控制在计算第 个向量时预取第 个向量。

图解:三种预取策略对比(参考原文Figure 3)

(a) 传统方式:预取了已访问的 ,且 预取太晚。

(b) 确定性访问:跳过 ,直接安排预取

(c) 步长预取:在计算 时预取 ,利用计算时间掩盖内存延迟。

2.2 硬件预取与 PRS (Partial Redundant Storage)

硬件预取器擅长处理连续内存(如IVF分区),但不擅图结构的随机访问。VSAG 提出了 PRS(部分冗余存储) 机制:

  • 原理:在每个图节点处,冗余存储其邻居的压缩向量。这样在访问邻居列表时,向量数据在内存中是连续的,完美触发了硬件预取。
  • 资源平衡:通过冗余率 控制冗余度。
    • 计算受限场景(高吞吐):增大 ,用内存换CPU效率,减少缓存未命中。
    • 内存受限场景:减小 ,节省内存。

图解:冗余率

(a) 高吞吐/高召回场景,全冗余,最大化CPU利用率。

(b) 内存受限场景,无冗余,允许降配实例(如4C16G降到2C8G)节省成本。

3. 核心优化二:自动参数调优

VSAG 将参数分为三类,并分别设计了自动化策略,这是本文最大的亮点。

参数类型 影响范围 调优难度 VSAG策略 例子

环境级 (ELPs)

仅QPS

网格搜索

预取步长 、深度

查询级 (QLPs)

QPS + Recall

机器学习模型 (GBDT)

搜索候选池大小

索引级 (ILPs)

QPS + Recall + 构建时间

极高

基于标签的压缩索引

最大度数 、剪枝率

3.1 查询级参数 (QLPs) 自动调优

观察发现:99%的简单查询只需很小的参数即可达标,1%的困难查询才需要大参数。VSAG 训练了一个 GBDT 分类器,根据查询特征(如扫描点数、Top-5距离分布)动态决定每个查询的 ,实现了个性化参数配置。

3.2 索引级参数 (ILPs) 自动调优(核心创新)

痛点:调节 通常需要重建整个索引,耗时数小时。

VSAG方案只建一次图,通过标签模拟不同参数的图。

  • 数学基础:论文证明了子图包含性质(Theorem 4.1 & 4.2)。即在固定其他参数下,用严格参数(小度数/小剪枝率)构建的图,是用宽松参数构建的图的子图
  • 标签机制
    • 1) 构建时:使用最宽松的参数(如最大度数64)建图,并为每条边打上一个标签 ,表示这条边在哪个剪枝率阈值下会被保留。
    • 2) 搜索时:如果想模拟严格参数(如度数16,剪枝率1.2),只需在搜索过程中过滤掉标签大于1.2的边即可。

图解:标签化调参示例(参考原文Figure 5)

假设节点 有5个邻居,标签分别为

若设置搜索参数 ,则标签为1.4的边 被过滤;若设置 ,则只保留前3个有效邻居。

效果:无需重建索引,即可在运行时动态尝试不同的索引参数组合。

4. 核心优化三:距离计算加速

4.1 截断标量量化

传统SQ4量化使用向量的最大/最小值作为量化范围,容易受异常值影响,导致量化精度损失。

VSAG 采用 99分位数 作为量化边界,舍弃1%的异常值,大幅提升有效量化精度。

图解:截断量化(参考原文Figure 6)

利用99%的数据分布范围进行量化,避免被极值干扰。

4.2 选择性重排序

全精度计算耗时,低精度计算有误差。VSAG 采用两阶段策略:

  1. 使用低精度(INT8/INT4)进行图遍历。
  2. 仅对最终候选集进行全精度(FLOAT32)重排序。

5. 实验评估

5.1 整体性能

VSAG 在所有数据集上均达到SOTA。特别是在高维数据(如OPENAI 1536维)上,相比HNSWlib有 4倍 的加速。

图表:整体性能对比(参考原文Figure 7)

在 GIST1M 和 OPENAI 等高维数据集上,VSAG(红色/左上角曲线)在相同 Recall 下 QPS 显著高于 hnswlib 和 faiss。

5.2 消融实验

下表展示了各项优化技术的累积效果:

策略叠加 GIST1M QPS L3 缓存未命中率 说明

Baseline

510

93.89%

基础图搜索

+ 1. 量化

1272

67.42%

大幅降低距离计算耗时

+ 2. 软件预取

1490

71.71%

改善部分访问延迟

+ 3. 步长预取

1517

64.57%

优化预取时机

+ 4. ELP自动调优

2052

45.88%

找到最佳预取参数,效果显著

+ 5. 确定性访问

2167

39.23%

减少无效预取

+ 6. PRS ()

2255

55.75%

内存与算力平衡

+ 7. PRS ()

2377

71.62%

极致吞吐量(牺牲部分缓存指标换CPU效率)

表2:VSAG策略消融实验(数据来源:原文Table 5)

5.3 调优成本对比

方法 GIST1M 调优时间 GIST1M 内存占用

FIX (固定参数)

3.20 H

3.83 G

BF (暴力搜索)

61.64 H

89.87 G

VSAG (标签法)

2.92 H

4.07 G

表3:ILPs调优成本对比(数据来源:原文Table 6)

分析:VSAG的调优时间仅为暴力搜索的 1/20,内存占用仅为 1/22,且性能更优。

6. 总结

VSAG 通过深入理解硬件特性(缓存行、预取器)和算法特性(图结构的子图包含性),提出了三大针对性优化:

  1. 内存:软件预取 + PRS冗余存储,治好了图算法的“缓存缺失病”。
  2. 调参:基于标签的索引压缩,将“重建索引调参”降维为“搜索时过滤边”,实现了秒级参数切换。
  3. 计算:截断量化 + SIMD指令 + 重排序,平衡了速度与精度。

该框架已应用于蚂蚁集团的支付和推荐系统,并在大模型(RAG)的高维向量检索中展现出巨大潜力。