SPTAG
微软开源的分布式近似最近邻向量搜索库,支持十亿级向量毫秒级检索与实时增量更新
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
微软开源的分布式近似最近邻向量搜索库,支持十亿级向量毫秒级检索与实时增量更新
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
想象你在一个拥有10亿张图片的图书馆里,想找出与「故宫角楼」最相似的100张。不是找完全相同的复制品,而是找构图、色调、风格相近的图片——这是典型的**近似最近邻搜索(ANN)**需求。
传统做法是把每张图片与10亿张逐一比对,计算相似度,在单机上这需要执行10亿次计算,哪怕每次只用0.1毫秒,也要消耗约28小时的算力。这在实际生产环境中完全不可接受。
SPTAG(Space Partition Tree And Graph)正是为了解决这个难题而生——它将搜索时间从「28小时」缩短到「毫秒级」。
SPTAG 由微软亚洲研究院(MSRA)和微软必应搜索团队联合开发,于2018年正式开源。该项目脱胎于必应的实际生产场景——每天处理数十亿次图片和文本搜索请求的背后,亟需一种高效、可扩展的向量相似度检索方案。
SPTAG 的论文已被引用超过1200次(Google Scholar 数据),是向量检索领域被引用最广泛的工业级开源库之一。项目还于2021年在 NeurIPS 发表配套论文 SPANN(Spilling-based Partitioned ANN),2023年更是在操作系统顶级会议 SOSO 和 OSDI 上连发两篇重量级论文——SPFresh(增量原地更新)和 VBASE(统一向量检索与关系查询),充分证明其在学术界和工业界均获得高度认可。
图1:SPTAG 核心架构——空间划分树与邻域图的混合索引结构
SPTAG 的设计哲学可以这样理解:想象你要在城市里找最近的地铁站,你不会挨个问每栋楼里的人「你们楼离地铁近吗」,而是先看城市地图分区,再在相关区域里沿街道走过去。
SPTAG 将这一思路工程化,具体包含两套索引策略:
SPTAG-KDT(KD树方案):基于经典 KD 树(K-Dimensional Tree),将高维空间递归地沿各维度中点切分,形成树状结构。优势在于建索引速度快,适合数据维度相对较低(<100维)的场景。KD树通过计算每个节点的分割边界,快速排除大量不相关区域,将搜索范围从「全局10亿」收敛到「局部数千」。
SPTAG-BKT(K-Means 树方案):用平衡 K-Means 聚类替代简单中点切分,用 K 个簇中心代替二叉分支。优势在于高维数据(>100维)下搜索精度更高,因为 K-Means 能更好地捕捉数据的实际分布结构,避免 KD 树在高维下因「维度诅咒」导致的边界估计失效问题。
搜索时,SPTAG 先在树结构中定位若干「种子节点」,再以这些种子为起点,沿相对邻域图(RNG) 逐步向外扩展。RNG 基于 K 近邻图构建,节点间的边代表真实的相似关系。树负责快速定位,图负责精细搜索,两者迭代配合,最终收敛到最近的若干邻居。
图2:微软亚洲研究院标识
SPTAG 最值得关注的功能特性有两点:
在线增量更新(Fresh Update):传统向量索引一旦建好便「固化」,新增数据需要全量重建,代价极高。SPTAG 支持在线插入和删除向量,无需重建整个索引。2023年发表的 SPTAG-SPFresh 论文进一步实现了「原地增量更新」,在十亿级数据集上实现毫秒级插入延迟,且不影响现有索引的搜索精度。这是目前工业界见过的最具挑战性的问题之一。
分布式在线服务(Distributed Serving):SPTAG 支持跨多台机器的水平扩展。IndexBuilder 负责在后台建索引,IndexSearcher 负责实时搜索,Aggregator 负责结果聚合。通过简单的 TCP 连接即可构建分布式向量检索集群,满足高并发、低延迟的生产需求。
从代码组织来看,SPTAG 是一个高度模块化的 C++ 工程:
构建系统使用 CMake,支持 Linux/Windows 双平台。Dockerfile(标准版)和 Dockerfile.cuda(GPU 版)已提供,可通过 docker build 快速构建容器化镜像。
虽然核心是 C++ 实现,但 SPTAG 提供了完善的 Python 封装。官方文档中包含一份端到端教程(docs/Tutorial.ipynb),演示了从数据导入、索引构建到查询检索的完整流程。
上手门槛主要在于依赖较多(CMake、Boost、swig、GCC ≥ 7,以及可选的 RocksDB/SPDK)。Linux 下完整编译需要约15-30分钟,包含 RocksDB 等重型依赖时可达1小时。对于只是想体验核心功能的用户,推荐使用 Docker 方式绕过编译:
docker build -t sptag -f Dockerfile .
docker run --rm sptag
Python 端使用示例:
from SPTAG import VectorIndex
index = VectorIndex()
index.Build(vectors, dimension)
results = index.Search(query_vector, top_k=10)
注意:SPTAG 是纯算法库,没有 Web UI 或 HTTP 服务,需要自行通过 Python/C++ SDK 封装 HTTP 接口。如果需要开箱即用的向量检索服务,可以考虑结合 FastAPI 或 gRPC 自行封装。
根据论文和公开 Benchmark 数据,在 SIFT-1M(约100万128维向量)数据集上,SPTAG 在单核 CPU 上即可实现 QPS 超过3000、延迟低于1ms 的检索性能。在 Deep-1B(10亿96维向量)数据集上,通过多机分布式扩展,SPTAG 可将十亿级向量的最近邻查询延迟控制在10ms 以内,同时召回率达到95%以上。
相比 Facebook FAISS、Spotify Annoy、HNSWlib 等同类方案,SPTAG 在「支持在线更新」这一维度上有独特优势——HNSWlib 等基于图的方法在插入新向量时需要重建图结构,而 SPTAG 的增量更新开销极小。
SPTAG 是微软在向量检索领域的核心技术资产,经过了必应搜索每日数十亿次请求的生产验证。其「空间划分树 + 相对邻域图」的混合索引架构,在召回率、延迟、增量更新三个维度上实现了良好的平衡。
SPTAG 代表了一个重要趋势:随着大模型(LLM)的爆发,向量数据库已成为 RAG(检索增强生成)系统的核心组件。文本、图片、音频首先被 embedding 模型转换为高维向量,再通过 SPTAG 这样的 ANN 库进行高效检索——这是当前 RAG Pipeline 的标准范式。对于正在构建 AI 应用的开发者而言,SPTAG 既是底层基础设施,也是理解向量搜索原理的绝佳学习样本。