Faiss 向量相似性搜索库:核心原理、索引体系与实战入门全解
本文基于 Faiss 仓库的 README.md 及其关联的安装、变更日志文档展开,系统讲解 Faiss 的定位与相似性搜索模型、以 Index 为核心的索引抽象、conda/CMake 两条安装路径、GPU 索引的 drop-in 用法,以及演示程序与调优入口,帮助读者快速建立对这一 C++/Python 向量检索库的完整认知,并能独立完成安装、构建与首次检索实操。
Faiss 是什么:面向亿级向量的相似性搜索与聚类库
README.md 对 Faiss 的定义是:一个用于稠密向量高效相似性搜索(similarity search)与聚类(clustering)的库。其关键特性可以归纳为四点:
- 规模上限高:包含针对“任意规模向量集合”的搜索算法,覆盖“大到可能装不进 RAM”的场景,即向量超出内存容量时仍可查询;
- 附带评估与调参工具:仓库不仅提供索引实现,还内置评测与参数调优(AutoTune)的支持代码;
- C++ 内核 + 完整 Python/numpy 封装:核心算法用 C++ 实现,Python 接口基于 Swig 自动生成,可直接操作 numpy 数组;
- 部分关键算法有 GPU 实现:README 指出“最常用的一些算法在 GPU 上有实现”,且 GPU 索引可作为 CPU 索引的直接替换(drop-in replacement)。
Faiss 主要由 Meta 的 Fundamental AI Research 团队开发,MIT 协议开源(见 LICENSE)。当前仓库版本号为 1.15.0,在 faiss/Index.h 中以宏 FAISS_VERSION_MAJOR/MINOR/PATCH 定义;CHANGELOG.md 显示 1.15.0 于 2026-07-31 发布,新增了 EDEN 量化器、Metal(Apple GPU)IVF-PQ 索引、cuVS IVF-SQ 后端、RISC-V RVV 距离内核等特性。
相似性搜索的数学模型:L2、内积与余弦相似
README 的“Introduction”部分明确了 Faiss 的基本假设:
- 实例被表示为向量,并以整数 ID 标识;
- 向量间的比较基于 L2(欧氏)距离或点积(dot product);
- “相似”的定义:与查询向量 L2 距离最小,或点积最大的向量;
- 余弦相似(cosine similarity)也被支持,其实现原理是“在归一化向量上的点积”——即向量归一化后余弦相似等价于内积,因此 Faiss 无需为余弦单独实现一套距离核。
这一设计在源码中有直接对应。faiss/MetricType.h 定义了 MetricType 枚举,覆盖 METRIC_INNER_PRODUCT、METRIC_L2、METRIC_L1、METRIC_Linf、METRIC_Lp,以及一组与 scipy.spatial.distance 对齐的扩展度量(METRIC_Canberra、METRIC_BrayCurtis、METRIC_JensenShannon、METRIC_Jaccard、METRIC_NaNEuclidean、METRIC_GOWER)。同文件中的 is_similarity_metric()(faiss/MetricType.h)区分“相似度”(越大越近,如内积)与“差异度”(越小越近,如 L2)两类度量——这是 Faiss 用统一代码路径同时支撑 min/max 两种检索语义的关键开关。
索引抽象:围绕 Index 的权衡体系
README 的“How Faiss works”一节指出,Faiss 构建在一个核心抽象上:一种存储向量集合、并支持 L2 与/或点积比较的索引类型。其中部分索引(如精确检索的 Flat 索引)是简单基线,其余索引结构则对应一组可调节的权衡维度:
- 搜索时间(search time)
- 搜索质量(search quality)
- 每个向量占用的内存(memory per vector)
- 训练时间(training time)
- 添加向量的时间(adding time)
- 是否需要外部数据做无监督训练(need for external data for unsupervised training)
这个抽象在 C++ 端体现为基类 faiss::Index,见 faiss/Index.h。它包含如下核心成员:
struct Index {
int d; ///< 向量维度
idx_t ntotal; ///< 已索引向量总数
bool verbose; ///< 详细输出开关
bool is_trained; ///< 是否无需训练 / 已完成训练
MetricType metric_type; ///< 索引使用的度量类型
float metric_arg; ///< 度量的参数(如 METRIC_Lp 的 p)
explicit Index(idx_t d_in = 0, MetricType metric = METRIC_L2) ...
};
注意 is_trained 字段:IVF 类等需要先做 k-means 训练才能 add 向量的索引,正是通过该标志表达“训练前置”约束;Flat 类索引则默认无需训练。头文件注释(faiss/Index.h)还说明了贯穿全库的数据布局约定:n 个 d 维向量以 float* 行主序紧凑存储,元素 x[i * d + j] 是第 i 个向量的第 j 个分量——这与 Python 侧传入的 numpy 二维数组(C-contiguous)完全一致,因此 Swig 封装可以零拷贝传递。
Python 侧所有具体索引都继承自该基类,例如 faiss/python/init.pyi 中的 IndexFlatL2(IndexFlat) 与 第 1817 行 的 IndexIVFFlat(IndexIVF)。README 特别提到两类代表性路线:
- 压缩表示路线:基于二值向量和紧凑量化码(compact quantization codes)的方法只使用向量的压缩表示,无需保留原始向量。代价是精度下降,但可以“在单台服务器的内存中扩展到数十亿(billions)向量”;
- 图上索引路线:HNSW 和 NSG 等索引在原始向量之上叠加图结构来提升检索效率,保留原始向量、精度更高。
用 index_factory 一行代码构建复杂索引
Python 接口提供了字符串驱动的工厂函数,是权衡上述维度最便捷的入口(faiss/python/init.pyi):
import faiss
d, n = 128, 100_000
x = faiss.random_norm(d, n).astype("float32")
# "IVF4096,PQ16" 表示:4096 个倒排桶 + 16 维乘积量化
index = faiss.index_factory(d, "IVF4096,PQ16", faiss.METRIC_L2)
index.train(x)
index.add(x)
# IVF 索引支持运行时参数,如 nprobe
params = faiss.IndexIVFSearchParameters()
params.nprobe = 32
D, I = index.search(x[:10], 10) # 返回距离矩阵 D 与 ID 矩阵 I
同文件还导出了 clone_index(深拷贝索引)、write_index/read_index(序列化/反序列化,见 第 2393-2399 行)等工具函数,构成“构建—训练—添加—检索—持久化”的完整闭环。
安装 Faiss:conda 预编译包与源码构建
README 的“Installing”一节给出两条路径:conda 预编译库与 CMake 源码构建。完整细节在 INSTALL.md,以下是与源码互相印证后的完整说明。
路径一:conda 预编译包(推荐)
稳定版与 nightly 预发布版定期推送到 pytorch conda 频道,提供三个包:
| 包名 | 平台 | 说明 |
|---|---|---|
faiss-cpu |
Linux(x86-64 / aarch64)、macOS(arm64)、Windows(x86-64) | 仅 CPU 索引 |
faiss-gpu |
Linux(x86-64),CUDA 11.4 与 12.1 | CPU + GPU 索引 |
faiss-gpu-cuvs |
Linux(x86-64),CUDA 13.2 | GPU 索引由 NVIDIA cuVS 26.06 提供 |
安装命令(摘自 INSTALL.md):
# 仅 CPU
$ conda install -c pytorch -c conda-forge faiss-cpu=1.15.0
# GPU(+CPU)
$ conda install -c pytorch -c nvidia -c conda-forge faiss-gpu=1.15.0
# GPU(+CPU),NVIDIA cuVS 后端
$ conda install -c pytorch -c nvidia -c rapidsai -c conda-forge libnvjitlink faiss-gpu-cuvs=1.15.0
要点:conda-forge 频道是必需的(x86-64 上提供最新 MKL、ARM 上提供 OpenBLAS,主 Anaconda 频道更新不及时);faiss-gpu 需额外 nvidia 频道获取 CUDA;AMD ROCm 版 GPU 包“尚不可用”(文档原文明确标注 not yet available)。除 conda 外,INSTALL.md 还给出了 Pixi 的等价命令(pixi init -c pytorch -c conda-forge 后 pixi add faiss-cpu=1.15.0)。
路径二:CMake 源码构建
基本依赖(INSTALL.md):
- 必需:C++20 编译器(OpenMP 2 以上)、一个 BLAS 实现(Intel 机器强烈建议 MKL);
- 可选:GPU 索引需要 nvcc 与 CUDA toolkit;AMD GPU 需要 ROCm;cuVS 实现需要
libcuvs=26.06;Python 绑定需要 Python 3、numpy 和 swig。
构建流程分四步,README 称“它用 cmake 编译”:
# Step 1: 配置(常用开关见下)
$ cmake -B build .
# Step 2: 构建 C++ 库(默认 libfaiss.a;-DBUILD_SHARED_LIBS=ON 时为 libfaiss.so)
$ make -C build -j faiss
# Step 3: 构建并安装 Python 绑定(可选)
$ make -C build -j swigfaiss
$ (cd build/faiss/python && python setup.py install)
# Step 4: 安装 C++ 库与头文件(可选)
$ make -C build install
常用 CMake 选项(完整清单见 INSTALL.md):
-DFAISS_ENABLE_GPU=OFF/-DFAISS_ENABLE_PYTHON=OFF:关闭 GPU 索引 / Python 绑定;-DFAISS_OPT_LEVEL=avx2(x86-64 可选generic、avx2、avx512、avx512_spr;aarch64 可选generic、sve):启用对应 SIMD 指令集编译,此时需构建faiss_avx2/faiss_avx512/faiss_avx512_spr目标;-DBUILD_TESTING=OFF、-DBUILD_SHARED_LIBS=ON、-DFAISS_ENABLE_C_API=ON(构建 C API,说明见 c_api/INSTALL.md);-DBLA_VENDOR=Intel10_64_dyn -DMKL_LIBRARIES=/path/to/mkl/libs:指定 Intel MKL,文档称其显著快于 OpenBLAS;-DFAISS_ENABLE_CUVS=ON:启用 cuVS 的 IVF-Flat、IVF-PQ 与 CAGRA GPU 索引(前提-DFAISS_ENABLE_GPU=ON);-DFAISS_ENABLE_SVS=ON:集成 Intel SVS 图索引(如 Vamana),CMake 会自动拉取并构建 SVS 运行时;-DCMAKE_CUDA_ARCHITECTURES="75;72":指定目标 GPU 架构。
Python 侧绑定由 Swig 驱动,接口声明文件为 faiss/python/swigfaiss.swig,类型存根为 faiss/python/init.pyi。
验证安装:演示程序
INSTALL.md 给出由浅入深的验证路径,与仓库 demos/ 目录一一对应:
# 小型 IVFPQ 示例:建索引、存储、检索,常规机器约 20s,MKL 加速下约 2.5s
$ make -C build demo_ivfpq_indexing
$ ./build/demos/demo_ivfpq_indexing
# GPU 版等价示例(含索引在 CPU/GPU 间的搬运)
$ make -C build demo_ivfpq_indexing_gpu
$ ./build/demos/demo_ivfpq_indexing_gpu
# SIFT1M 实测:高层 AutoTune API 演示(需先把 ANN_SIFT1M 数据集解包到源码根目录 sift1M/)
$ make -C build demo_sift1M
$ ./build/demos/demo_sift1M
demos/demo_auto_tune.py 则把 SIFT1M 测试扩展到多种索引类型,自动寻找最优工作点;将其 keys_to_test 改为 keys_gpu 并置 use_gpu = True 即可测 GPU 代码。更多 Python 教程见 tutorial/python/(如 1-Flat.py、6-HNSW.py、7-PQFastScan.py)。
GPU 实现:CPU 索引的 drop-in 替换
README 的 Introduction 末尾专门描述了 GPU 行为,要点有三:
- 输入来源灵活:GPU 索引的输入可以来自 CPU 内存或 GPU 显存,从 CPU/GPU 显存到 GPU 的拷贝自动处理;
- drop-in 替换:在带 GPU 的服务器上,可直接把
IndexFlatL2替换为GpuIndexFlatL2等 GPU 索引;若输入输出都常驻 GPU,速度更快; - 支持单卡与多卡:README 明确“单卡与多卡用法均受支持”。
从源码结构看,这一说法对应到 faiss/gpu/GpuIndexFlat.h 中的 GpuIndexFlatL2 类,以及 faiss/gpu/GpuCloner.h 的 GpuCloner——后者负责把任意 CPU 索引按 GpuClonerOptions 配置翻译/搬移到 GPU。多卡场景则由 StandardGpuResources(faiss/gpu/StandardGpuResources.h)管理多张卡的资源分配,C API 层也暴露了对应的封装(c_api/gpu/StandardGpuResources_c.h)。
README 还提到可选的 NVIDIA cuVS 后端:启用后用户可以在 Faiss 原生 GPU 实现与 cuVS 实现之间按算法选择。这与 INSTALL.md 的描述一致——cuVS 提供 GPU 上近似近邻与聚类的先进实现,构建 Faiss 时开启 FAISS_ENABLE_CUVS 即可在两种实现间切换。
文档、基准测试与延伸阅读
README 的“Full documentation”一节列出了文档入口。在仓库内部可落地的有:
- benchs/README.md:复现论文基准(Polysemous codes、Billion-scale similarity search with GPUs)的说明;benchs/link_and_code/README.md 对应“Link and code”图索引论文;
- demo/ 与 tutorial/ 目录:C++ 与 Python 的完整用法示例;
- tests/ 目录:C++ 与 Python 测试套件,
make -C build test可运行全部 C++ 测试; - c_api/:纯 C 接口,供不便链接 C++ 运行时的语言/环境使用;
- contrib/:高层工具,如 contrib/datasets.py、contrib/evaluation.py、contrib/ivf_tools.py。
README 同时指向 wiki(入门教程、FAQ、故障排查)、Doxygen 逐类文档与 issues/discussions 社区入口;这些为仓库外资源,本文不展开。
学术引用与项目背景
若在自己的研究论文中使用 Faiss,README 给出的引用信息为:
@article{douze2024faiss,
title={The Faiss library},
author={Matthijs Douze and Alexandr Guzhva and Chengqi Deng and Jeff Johnson and Gergely Szilvasy and Pierre-Emmanuel Mazaré and Maria Lomeli and Lucas Hosseini and Hervé Jégou},
year={2024},
eprint={2401.08281},
archivePrefix={arXiv},
primaryClass={cs.LG}
}
GPU 版本的引用:
@article{johnson2019billion,
title={Billion-scale similarity search with {GPUs}},
author={Johnson, Jeff and Douze, Matthijs and J{\'e}gou, Herv{\'e}},
journal={IEEE Transactions on Big Data},
volume={7},
number={3},
pages={535--547},
year={2019},
publisher={IEEE}
}
主要作者分工(README “Authors”一节):Hervé Jégou 发起项目并写出首个实现;Matthijs Douze 实现大部分 CPU Faiss;Jeff Johnson 实现全部 GPU Faiss;Lucas Hosseini 实现二值索引与构建系统;Chengqi Deng 实现 NSG、NNdescent 及大量加性量化代码;Alexandr Guzhva 负责 SIMD、内存分配与布局、向量编解码快速解码内核等优化;Gergely Szilvasy 负责构建系统与基准测试框架。
小结:从 README 出发的一条上手路线
- 先跑 conda 安装:
conda install -c pytorch -c conda-forge faiss-cpu=1.15.0,用faiss.index_factory(d, "IVF4096,PQ16")走通“train → add → search”流程(度量语义见 faiss/MetricType.h); - 再跑演示:
demos/demo_sift1M与 demos/demo_auto_tune.py 体验 AutoTune 自动调参; - 需要性能时看权衡维度:按 README 列出的六个权衡轴(搜索时间/质量/内存/训练/添加/外部数据)选择 IVF+PQ、FastScan、HNSW 或 NSG 等结构,并用 INSTALL.md 的
FAISS_OPT_LEVEL=avx2/avx512与 MKL 选项压榨 CPU 性能; - 有 GPU 时做 drop-in 替换:把
IndexFlatL2换成GpuIndexFlatL2,借助GpuCloner搬运索引,输入输出常驻显存以获得最高吞吐。
以上所有路径与参数均以当前仓库(版本 1.15.0)的实际内容为准;GPU 平台支持范围、CUDA 版本要求等适用前提,请对照 INSTALL.md 中对应条目确认。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00