ScaNN

ScaNN

Google Research 开源的大规模向量检索库,主打各向异性向量量化

核心功能

ScaNN(Scalable Nearest Neighbors)来自 Google Research,实现了论文中的搜索空间剪枝与各向异性向量量化,主要面向最大内积检索,也支持欧氏距离等度量。它同时提供 Python 原生绑定和可选的 TensorFlow op 绑定,可把检索算子嵌入 SavedModel。它是进程内的算法库而非服务;实现针对带 AVX 支持的 x86 处理器优化。

功能亮点

三段式检索

分区剪枝、AH 打分、精确重排依次执行,官方把三个阶段的调参入口对应到不同 builder 方法

各向异性量化

量化损失按最大内积检索目标加权,学术依据是 ICML 2020 的 Anisotropic Quantization 论文

查询时可再调

search_batched 支持传 leaves_to_search、pre_reorder_num_neighbors 临时覆盖建索引时的配置

可进 SavedModel

安装 scann[tf] 后可经 scann.scann_ops 把检索算子嵌入 TensorFlow SavedModel 与 TF Serving

适用场景

• 百万到十亿量级 embedding 的最大内积检索,例如推荐系统的候选集召回
• 已有 TensorFlow 服务栈,希望把近邻检索算子一起打进 SavedModel 部署到 TF Serving
• 在固定召回率目标下压低查询延迟,用 num_leaves_to_search 与重排数量做速度精度权衡

安装配置

bash
pip(PyPI 上提供 manylinux_2_27 兼容 wheel):
pip install scann

需要 TensorFlow op 绑定时(README 说明自 ScaNN 1.4.0 起该功能不再默认启用):
pip install scann[tf]

平台要求(README 原文):
- 仅支持 Linux 环境下的 Python 3.9 至 3.13
- x86 wheel 需要 AVX 与 FMA 指令集支持,ARM wheel 需要 NEON
- 操作系统需提供 libstdc++ 3.4.23 及以上版本

从源码构建(README):需先安装 bazel 7.x、Clang 19、C++17 的 libstdc++ 头文件,再执行:
python configure.py
CC=clang-19 bazel build -c opt --features=thin_lto --copt=-mavx --copt=-mfma --cxxopt="-std=c++17" --copt=-fsized-deallocation --copt=-w :build_pip_pkg
./bazel-bin/build_pip_pkg

使用方法

python
官方 docs/example.ipynb 中的用法(GloVe 数据集):

import numpy as np
import scann

normalized_dataset = dataset / np.linalg.norm(dataset, axis=1)[:, np.newaxis]
# configure ScaNN as a tree - asymmetric hash hybrid with reordering
# anisotropic quantization as described in the paper; see README

# use scann.scann_ops.build() to instead create a TensorFlow-compatible searcher
searcher = scann.scann_ops_pybind.builder(normalized_dataset, 10, "dot_product").tree(
    num_leaves=2000, num_leaves_to_search=100, training_sample_size=250000).score_ah(
    2, anisotropic_quantization_threshold=0.2).reorder(100).build()

# 批量查询
neighbors, distances = searcher.search_batched(queries)

# 查询时临时提高召回
neighbors, distances = searcher.search_batched(queries, leaves_to_search=150)
neighbors, distances = searcher.search_batched(queries, leaves_to_search=150, pre_reorder_num_neighbors=250)

# 动态调整返回数量
neighbors, distances = searcher.search_batched(queries, final_num_neighbors=20)

# 单条查询,API 与批量一致
neighbors, distances = searcher.search(queries[0], final_num_neighbors=5)

配置建议(docs/algorithms.md):小于 2 万点直接用暴力检索;小于 10 万点用 AH 打分加重排;超过 10 万点则先分区、再 AH 打分、最后重排。

关键指标

尚未核验对标产品,此处只列本工具自身指标,不做对比结论。

指标ScaNN
价格免费
开源
上手难度专家

相关工具

优点

  • README 称其在 ann-benchmarks.com 的 glove-100-angular 数据集上达到 state-of-the-art 性能
  • 算法有论文支撑:各向异性向量量化出自 ICML 2020,SOAR 索引改进出自 NeurIPS 2023
  • docs/algorithms.md 给出可直接照做的配置经验法则(2 万点以下用暴力、10 万点以上先分区、num_leaves 取 sqrt(n)、dimensions_per_block 取 2)
  • 查询时可动态覆盖 leaves_to_search、pre_reorder_num_neighbors、final_num_neighbors,调参不必重建索引

缺点

  • 官方 wheel 只覆盖 Linux 上的 Python 3.9–3.13,Windows 与 macOS 没有官方发布包
  • x86 wheel 硬性要求 AVX 与 FMA 指令集、ARM wheel 要求 NEON,且需系统 libstdc++ 3.4.23 以上,老环境跑不起来
  • README 明确写明代码是为研究用途(research purposes)发布的
  • 自 ScaNN 1.4.0 起 TensorFlow 集成不再默认启用,需要显式安装 scann[tf] 才能用 scann.scann_ops