Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Last updated: Monday 07 September 2026 @ 20:44:27

High-Throughput, Cost-Effective Billion-Scale Vector Search with a Single GPU

可以。先不要陷进 CUDA kernel 和实验参数里,这篇论文真正需要先抓住的是它的系统观念变化:

GustANN 认为:在“追求极高吞吐量”的 SSD 图 ANN 场景里,瓶颈不一定是 SSD,而可能是 CPU 根本产生不了足够快的图搜索计算与 I/O 请求。于是它把 graph traversal 整体搬到 GPU,只让 CPU 做 I/O 搬运辅助。

论文是 GustANN: High-Throughput, Cost-Effective Billion-Scale Vector Search with a Single GPU,SIGMOD 2025。


1. 一句话理解 GustANN

它的硬件结构可以概括成:

                    ┌──────── GPU ────────┐
                    │ PQ vectors          │
Query ──> Pivot ──> │ graph traversal     │
                    │ distance / sort     │
                    │ dedup / next node   │
                    └─────────┬───────────┘
                              │ 需要 node u
                              ↓
SSD ──4KB page──> CPU DRAM ──record──> GPU
       ~60 GB/s                  ~<1KB

论文做的不是:

CPU 搜索 + GPU 算距离

而是:

GPU 搜索 + CPU 帮 GPU 搬 SSD 数据

作者称其为:

GPU-centric, CPU-assisted architecture。

这是整篇论文最关键的设计定位。


2. 为什么作者觉得 DiskANN 这一类系统不够好?

建议你重点看论文 §3.1,PDF 第 5–6 页。

传统认识通常是:

DiskANN
CPU computation 很快
        ↓
SSD random I/O 很慢
        ↓
SSD 是瓶颈

所以 DiskANN 等工作大量关注:

  • 减少 SSD I/O;

  • beam search;

  • latency hiding;

  • cache;

  • 更好的图结构。

但 GustANN 说:

这个结论主要适用于 latency-critical workload。

如果目标变成:

几十万 QPS

问题发生变化了。

论文测得 DiskANN:

  • 单 worker 大约:

    • 1/6 时间 computing

    • 5/6 时间等 SSD;

  • 乍一看明显是 SSD-bound。

但是作者做了一个很重要的思想实验:

假设 SSD I/O latency 完全可以隐藏。

那么 CPU 可以把原来 1/6 的计算时间扩展到全部时间:

DiskANN 实际:
CPU compute : 1
SSD wait    : 5

perfect overlap 后:
CPU 可以做约 6× computation
→ 约 6× I/O throughput

他们实际 DiskANN 只有大约:

6 GB/s

那么理想情况下也只有:

6 × 6 GB/s ≈ 36 GB/s

但 6 块 SSD 的理论带宽是:

6 × 10 GB/s = 60 GB/s

于是即使 I/O 完全不等待:

CPU 依然喂不满 6 块 SSD。

作者进一步估算,他们的 56-core CPU,大约只能支撑 3.6 块 SSD 的计算需求。


3. 这其实是论文最重要的 insight

这里非常值得和你之前讨论 DiskANN 的问题联系起来。

GustANN 并没有说 SSD 随机访问不重要。

它说的是:

latency-oriented

单 query:

compute → SSD read → compute → SSD read
            ↑
         latency 大

所以 SSD latency 是核心问题。


throughput-oriented

同时跑:

40,000 queries

大量 query 可以覆盖 I/O latency:

Q1: compute ---- IO ----
Q2:    compute ---- IO ----
Q3:       compute ---- IO ----
...

此时问题变成:

你的 CPU 能不能足够快地执行图遍历、距离计算、candidate management,从而不断生成 SSD I/O?

GustANN 的答案是:

CPU 不够。

所以需要 GPU。

这就是这篇论文与很多 DiskANN-style 工作最大的视角区别。


4. 那为什么不能直接让 GPU 搜索 SSD?

这就是论文的第二层问题。

已有两种架构。

A. CPU-centric, GPU-assisted

例如:

CPU:
graph traversal
candidate management
SSD access
       │
       ↓
GPU:
distance calculation

论文认为这不解决问题,因为:

graph traversal 仍然在 CPU。

CPU 仍然是 throughput bottleneck。


B. GPU-only

变成:

GPU
 ├ graph traversal
 ├ distance
 ├ candidate management
 └ direct SSD access

例如 BaM / GDS 这类 GPU direct storage。

这解决 CPU 计算瓶颈,却引出了两个新瓶颈:

  1. GPU memory

  2. SSD → GPU PCIe bandwidth

所以 GustANN 的三个核心设计,正好是一一解决这些问题。


5. Design 1:Memory-Efficient GPU Graph Traversal

这是 §4.2,也是算法层面最有技术含量的一部分。

传统 ANN 搜索都会维护:

visited set

例如:

hash table
Bloom filter
bitmap

原因很简单:

假设展开节点 u:

neighbors:
A B C D E

其中 C 之前已经访问过:

visited(C) = true

那么:

不要再算 PQ-distance(C, q)

CPU 上这是很合理的:

用 memory 换 computation。


但 GPU 上作者反过来了

论文提出一个非常 GPU-oriented 的思想:

GPU 上少做几个 distance computation 未必能让程序更快。

因为 GPU 是 SIMT:

warp = 32 threads

如果:

thread 0:发现 duplicate,不计算
thread 1~31:都计算

thread 0 实际上也得等。

所以作者干脆:

先把 duplicate 也算了。

即:

传统:

deduplicate
    ↓
distance
    ↓
insert


GustANN:

distance
    ↓
sort
    ↓
deduplicate

也就是论文非常核心的一句话:

Sort first, then deduplicate.


6. 为什么这能省这么多显存?

传统 visited table 至少需要:

L×R

假设:

L = 300
R = 128

节点 ID 4 bytes:

300×128×4≈150KB

考虑 hash table/Bloom filter load factor 等,实际可能:

>300 KB/query

而 GustANN 目标是:

~40,000 concurrent queries

于是:

300KB×40000≈12GB

光 visited table 就差不多 12 GB。

A100-40GB 上还有:

1B vectors × 32 B PQ
≈ 30 GB

所以根本放不下。


GustANN 怎么 dedup?

先:

new neighbors
    ↓
PQ distance
    ↓
sort

然后 candidate array 已经按照距离排序。

对于 duplicate ID,它们会被检测出来,再通过 GPU warp primitives:

compare
↓
ballot / broadcast
↓
bitcount
↓
prefix-sum-like position calculation
↓
compact

完成并行去重。

论文 Figure 5(PDF 第 11 页)就是这个过程。

最终:

BANG     ≈ 480 KB/query
GustANN  ≈ 40.22 KB/query

大约:

11.93× 更省 per-query GPU memory。

这使 40K concurrent queries 成为可能。


7. Design 2:CPU-Assisted Transfer

我认为这是整篇论文中最漂亮的系统设计。

先看硬件。

论文机器:

6 × PCIe 5.0 SSD
        ↓
aggregate ≈ 60 GB/s

A100 PCIe 4.0 ×16
        ↓
GPU inbound ≈ 24 GB/s

于是如果:

SSD → GPU

直接搬:

60 GB/s
   ↓
24 GB/s bottleneck

你有 6 块 SSD 也没意义。

论文 Figure 6 专门画了这个瓶颈。


8. 关键观察:GPU 根本不需要整个 SSD page

SSD 最小读取单位:

4 KB

但 graph node record 大约:

vector
+
neighbor IDs

例如 DEEP1B:

vector:
96 × float
= 384B

neighbors:
128 × int
= 512B

total:
896B

也就是说:

SSD read = 4096B
实际需要 = 896B

只需要:

896/4096≈22%


所以 GustANN 做:

          4096 B
SSD ───────────────→ DRAM
                        │
                        │ 896 B
                        ↓
                       GPU

而不是:

          4096 B
SSD ───────────────→ GPU

这就是所谓:

CPU-assisted selective transfer

DRAM 在这里本质上就是:

bounce buffer

不是用来存整个 index。


9. 为什么绕 CPU 一圈反而更快?

表面看:

SSD → DRAM → GPU

明显比:

SSD → GPU

多了一跳。

但问题在于瓶颈的位置不同。

Direct:

SSD 60GB/s
   ↓
GPU PCIe 24GB/s
   ↓
只能使用 ~24GB/s

GustANN:

SSD
│ 60GB/s
↓
DRAM
│
│ selective ~25%
↓
GPU
≈15GB/s

满足:

15<24GB/s

于是 GPU inbound PCIe 不再成为瓶颈。

所以这里是典型的:

多走一步,但少搬 75% 数据。

结果实验中:

GustANN vs BaM-ANN
≈2.50–2.71× throughput

这部分对应 PDF 第 12–13、19–20 页。


10. Design 3:Pivot Search

第三个问题很容易被低估:

为什么 RAID-0 已经把 page 均匀条带化到 6 块 SSD,仍然会负载不均?

作者认为原因来自:

single entry graph search

DiskANN-style graph:

       entry
         ●
       / | \
      ●  ●  ●
     ...

所有 query 都从:

同一个 entry point

开始。

于是前几轮都会访问:

entry 周围的一小片 graph region

而这一片 region 的 node:

可能并没有均匀落在 SSD1~SSD6 上。

于是:

SSD1: ███████████
SSD2: ███
SSD3: █████
SSD4: ██
...

形成作者所谓的:

micro-scale load imbalance。


11. Pivot graph 是怎么解决的?

GPU 上额外放一个非常小的 graph:

完整 dataset
1 billion vectors
      ↓ random sample
~1 million vectors
      ↓
pivot graph

query 先:

Query
  ↓
pivot graph search
  ↓
找到一个 query-specific pivot
  ↓
从这个节点进入 SSD graph

于是不同 query:

Q1 → region A
Q2 → region F
Q3 → region C
Q4 → region A
...

不再全部拥挤在:

single entry region

它带来两个效果:

  1. SSD load balance;

  2. 入口本身离 query 更近。

论文实验:

throughput:最多 +1.50×
SSD bandwidth:最多 +1.23×

而且 6 个 SSD 的 tail latency divergence 明显减小。

对应 Figure 12、13,PDF 第 20 页。


12. 不过 Pivot Search 本身并不是完全新的

作者自己也承认:

Starling 有:

navigation graph

也是:

small graph
→ 找一个更好的 SSD search entry

区别是论文宣称:

Starling

主要目的:

减少 SSD I/O

GustANN

主要目的:

multi-SSD load balance

而且:

Starling:CPU search navigation graph
GustANN:GPU search pivot graph

所以这里更像是:

已有 navigation idea 在 GPU + multi-SSD throughput 问题上的重新定位。

这是阅读这篇论文时需要保持清醒的一点。


13. 整个 Query 到底怎么跑?

理解这一段后,整篇论文基本就通了。

单个 query:

① GPU pivot search
        ↓
找到 entry node

② GPU:
选择当前 exploring node u
        ↓

③ CPU:
向对应 SSD 发 4KB read
        ↓
SSD → DRAM
        ↓
从 page 提取 node record
        ↓
DRAM → GPU

④ GPU:
full-distance(u)
neighbor PQ-distance
sort
dedup
update candidate set
选择 next exploring node
        ↓

⑤ 回到③

注意:

CPU 并不负责 graph traversal。

CPU 基本只是:

I/O scheduling
SSD queue management
memory copy
batch dispatch

所以论文声称只需要:

8 CPU cores

其中:

2 threads:query / GPU / SSD dispatch
6 threads:6 SSD I/O queues

14. 单 query 还是串行,那吞吐量怎么上去?

这里有一个重要设计:

inter-query pipelining

单 query:

SSD → GPU → SSD → GPU → SSD → GPU

有严格 dependency:

不知道 next node
→ 就不知道下一次读哪个 SSD page

所以无法把单 query 变成完全流水。

GustANN 改为许多 mini-batch:

time →

Batch A:
SSD ███
        GPU ███
                SSD ███

Batch B:
    SSD ███
            GPU ███

Batch C:
        SSD ███
                GPU ███

于是:

单 query 内不能 pipeline,queries 之间可以 pipeline。

这和你之前讨论 PipeANN / FlowANN 时其实是一个很值得注意的共同模式:

用不同 query / batch 的独立性去填满不同硬件阶段。

但 GustANN 的阶段是:

SSD/CPU transfer
↕
GPU graph search

而不是简单的 CPU ↔ SSD compute-I/O pipeline。


15. 实验结果怎么看?

论文最核心数字不用全记,只记四个。

SSD utilization

最高:

86.7%

6 块 SSD × 10 GB/s:

理论 ~60GB/s
实际 ~52GB/s

vs DiskANN

billion-scale:

SIFT1B  : 7.81×
DEEP1B  : 6.98×

vs GPU systems

论文报告至少:

2.50× throughput

Cost-effectiveness

以 $ / QPS:

vs CPU+GPU:2.62× better

论文摘要还给出了单 GPU + 6 SSD:

247K billion-scale vector searches/s

的代表性结果。


16. 但这篇论文有一个非常重要的代价

latency

GustANN 是非常明确的:

Throughput-first

要到最大 throughput:

latency ≈ 140 ms

如果限制:

latency < 25ms

那么只能获得:

约 1/5 peak throughput

所以它不是要取代传统低延迟 DiskANN。

作者的 argument 是:

RAG:
ANN retrieval      ~100ms
LLM prefill/generation
                  ~100ms–1s

所以 ANN 多几十毫秒没那么致命。

换句话说:

GustANN 本质上是在用 batching latency 换 hardware utilization。


17. 这篇论文真正的三个贡献,我会这样评价

如果去掉作者的包装,我认为可以压缩成:

设计本质
Sort-then-dedup用 GPU 的冗余计算换显存
CPU-assisted transfer用 DRAM 做 page → record 过滤,减少 GPU PCIe 流量
Pivot search把 query 从单入口热点区域打散到整个 graph

其中我认为 novelty / systems insight 强度大致是:

CPU-assisted selective transfer
        >
GPU memory-efficient traversal
        >
pivot search

Pivot graph 的概念本身并不新;它主要是找到了一个新的系统问题——multi-SSD tail load imbalance——并把 navigation graph 用到了这里。


18. 它与你最近在看的 FlowANN / PipeANN 有什么区别?

这里先给你一个粗定位,后续我们可以专门比较。

PipeANN / 类似设计

主要问题通常是:

CPU computation
↔
SSD I/O

怎么 overlap。

GustANN

更进一步认为:

CPU computation 本身就不够

所以直接变成:

GPU traversal
↔
SSD

然后发现新的:

SSD aggregate bandwidth
>
GPU inbound PCIe bandwidth

再引入:

SSD → CPU DRAM → GPU

所以有一种很有意思的演化:

DiskANN
SSD latency bottleneck
    ↓
pipeline
    ↓
CPU throughput bottleneck
    ↓
GPU
    ↓
GPU PCIe bottleneck
    ↓
CPU-assisted selective transfer

每解决一层瓶颈,下一层瓶颈就冒出来。

这其实就是这篇论文最值得学习的系统研究思路。


19. 我建议你按这个顺序读

不要从第一页顺读到第 27 页。最高效的顺序是:

  1. §3.1–3.3:Motivation
    先理解为什么 CPU 变成 bottleneck。

  2. Figure 4 + §4.1
    把 GustANN 总架构彻底搞明白。

  3. §4.3 CPU-Assisted Transfer
    这是最关键、最好理解的设计。

  4. §4.2 GPU Graph Traversal
    再深入 sort-before-dedup 和 warp-level dedup。

  5. §4.4 Pivot Search
    理解 single-entry → micro-scale imbalance。

  6. §5.3 Breakdown
    看三个设计到底各贡献多少,而不是先看 Overall Performance。

  7. 最后看 §5.4–5.6
    重点寻找适用边界和 weakness。


如果把这篇论文压成一张“脑内结构图”,就是:

                 High-throughput SSD ANN
                           │
                    CPU 算力不够
                           │
                           ▼
                    GPU graph search
                           │
           ┌───────────────┼────────────────┐
           │               │                │
       GPU memory       PCIe inbound     SSD imbalance
           │               │                │
           ▼               ▼                ▼
 sort then dedup    SSD→DRAM→GPU       pivot search
           │               │                │
           └───────────────┼────────────────┘
                           ▼
                40K concurrent queries
                           │
                  inter-query pipeline
                           │
                           ▼
                  ~87% SSD utilization

下一步最值得做的是逐行拆 §3.1 的“CPU 为什么会成为瓶颈”,因为这恰好会触及你之前对 DiskANN“到底应该减少 SSD I/O,还是应该高度并行 I/O”的那个问题;GustANN 给出的答案比表面上的“GPU 比 CPU 快”要深得多。