向量检索是语义搜索和RAG系统的核心能力,ScaNN、Faiss和Milvus是三大主流引擎。本文从检索精度、吞吐性能、分布式支持和易用性等维度对比三者的特点,帮助开发者根据场景选择合适的向量检索方案。适合搭建向量搜索和RAG应用的工程师。

岗位关联

需要学习ScaNN/Faiss/Milvus引擎对比,这是你的核心专业课,从倒排索引到向量检索,推荐系统的全链路技术。本篇涵盖召回/排序/重排、向量检索、语义搜索,帮助你构建搜索推荐系统。

目录
  1. 可视化演示
  2. 三大引擎定位与核心差异
  3. ScaNN各向异性量化技术
  4. Faiss索引类型与GPU加速
  5. Milvus分布式架构设计
  6. 引擎选型与基准测试
  7. AI 应用场景
  8. Python 演示
  9. 常见问答
  10. 常见误区
  11. 参考来源

可视化演示

通过多维度雷达对比、最近邻检索动画和索引结构图,直观展示ScaNN、Faiss、Milvus三大引擎的核心差异与选型策略。

本节配有交互动效(进入视口后自动加载,约 3KB)。

三引擎多维雷达对比 ScaNN:精度最优,各向异性量化 Faiss:索引最丰富,GPU加速 Recall@k = |ANN ∩ GT| / k Milvus:分布式架构,全功能向量数据库

三大引擎定位与核心差异

在大规模向量检索领域,ScaNN、Faiss和Milvus是三大主流引擎,它们分别面向不同的应用场景和部署模式。ScaNN由Google Research开发,核心创新在于各向异性向量量化(Anisotropic Vector Quantization, AVQ),专注于单机环境下的高精度近似最近邻搜索。Faiss由Meta AI开源,提供了最丰富的索引类型组合(IVF、HNSW、PQ及其变体),并支持GPU加速大规模批量检索。Milvus则是一个完整的分布式云原生向量数据库,提供存算分离架构、动态数据更新和高可用保障。

定位对比: | 维度 | ScaNN | Faiss | Milvus | |------|-------|-------|--------| | 开发者 | Google Research | Meta AI | Zilliz/LF AI | | 定位 | 高精度单机检索库 | 通用向量检索库 | 分布式向量数据库 | | 分布式 | 不支持 | 不支持(需自建) | 原生支持 | | GPU加速 | 不支持 | 支持 | 支持 | | 动态更新 | 不支持 | 有限支持 | 完整CRUD | | 适用规模 | 百万级 | 亿级(单机) | 十亿级+ | 可以用一个类比来理解:ScaNN是跑车(精度最高但载量小),Faiss是卡车(灵活载货),Milvus是物流车队(分布式运营)。

ScaNN各向异性量化技术

ScaNN的核心创新是各向异性向量量化(Anisotropic Vector Quantization, AVQ)。传统的乘积量化(PQ)采用各向同性策略,将向量空间均匀划分为子空间并独立量化每个子空间。这种方法最小化了整体的均方误差,但对于内积检索任务来说并非最优。

AVQ的核心思想: 内积检索的目标是最大化查询向量与文档向量的内积,而非最小化量化误差。AVQ通过以下方式优化: 1. 在量化时考虑查询向量的方向分布 2. 允许量化误差在平行于查询向量的方向上更大,在垂直方向上更小 3. 这种各向异性的误差分配使得内积估计的偏差更小 数学直觉: 设原始向量为 v,量化向量为 Q(v),内积误差为 <q, v> - <q, Q(v)> = <q, v - Q(v)>。AVQ通过使量化误差 v - Q(v) 与查询向量 q 的方向尽量正交,来减小内积误差。 局限性: ScaNN不支持分布式部署,数据规模受限于单机内存。适合百万级向量的高精度检索场景。

Faiss索引类型与GPU加速

Faiss(Facebook AI Similarity Search)由Meta AI开源,是目前使用最广泛的向量检索库。它提供了最丰富的索引类型组合,可以根据数据规模和延迟要求进行灵活选择。

核心索引类型: 1. Flat(暴力搜索):100%召回率,O(n)复杂度,适合小规模数据或baseline 2. IVF(倒排文件索引):将向量空间划分为nlist个Voronoi单元,查询时只搜索最近的nprobe个单元。复杂度O(n·nprobe/nlist) 3. HNSW(分层导航小世界图):基于图的索引,O(log n)查询复杂度,内存占用较高 4. PQ(乘积量化):将高维向量分割为多个子空间并独立量化,大幅压缩内存 5. OPQ(优化乘积量化):在PQ之前加一个旋转矩阵,使子空间之间的方差更均匀 组合索引: Faiss支持将多种索引组合使用,如 IVF-PQ(先IVF粗筛再PQ精排)、IVF-HNSW(IVF粗筛+HNSW精搜)。最常用的生产配置是 IVF-HNSW-PQ。 GPU加速: Faiss的GPU实现基于CUDA,支持批量查询的并行加速。在大规模批量检索场景下(如离线处理),GPU可以将吞吐量提升10-100倍。但GPU加速主要适用于Flat和IVF类索引,HNSW的GPU支持有限。

Milvus分布式架构设计

Milvus是一个完整的分布式云原生向量数据库,与ScaNN和Faiss(都是检索库)不同,Milvus提供了完整的数据管理能力,包括CRUD操作、事务、权限控制和监控。

存算分离架构: Milvus采用存算分离的三层架构: 1. 接入层(Coordinator):负责元数据管理、调度和负载均衡 2. 计算层(Worker Nodes):包括数据节点(Data Node)、查询节点(Query Node)、索引节点(Index Node) 3. 存储层(Storage):基于对象存储(如S3/MinIO),数据持久化到远程存储 这种架构使得计算和存储可以独立扩缩容。当查询负载增加时,只需增加Query Node;当数据量增加时,只需增加Data Node和存储空间。 动态数据更新: 与Faiss不同,Milvus完整支持数据的增删改操作: - Insert:新向量实时可查(近实时,取决于refresh间隔) - Delete:通过标记删除实现,后台异步清理 - Update:先删除旧向量再插入新向量 高可用保障: - 数据多副本:每个segment有多个副本分布在不同节点 - 查询节点无状态:可水平扩展,故障自动恢复 - WAL(Write-Ahead Log):保证数据不丢失 类比:如果Faiss只管找书,Milvus还管入库、借阅、盘点,是一个完整的图书管理系统。

引擎选型与基准测试

选择合适的向量检索引擎需要综合考虑数据规模、延迟要求、吞吐需求、运维成本等多个维度。没有绝对最优的引擎,只有最适合业务场景的选择。

选型决策树: 1. 数据规模 < 百万级,追求最高精度 → ScaNN - 优势:AVQ量化精度最高,单机recall最优 - 限制:不支持分布式,无GPU加速 2. 数据规模 百万~亿级,需要GPU加速 → Faiss - 优势:索引类型丰富,GPU批量加速,社区活跃 - 限制:需自行管理数据持久化和分布式 3. 数据规模 亿级以上,需要分布式和高可用 → Milvus - 优势:原生分布式,完整数据管理,云原生 - 限制:运维复杂度较高,资源开销大 基准测试维度: | 指标 | 说明 | 建议阈值 | |------|------|----------| | Recall@10 | top-10结果中相关文档的比例 | > 95% | | P99延迟 | 99%查询的响应时间 | < 50ms | | QPS | 每秒查询数 | 根据业务需求 | | 内存占用 | 索引占用的内存 | 根据预算 | | 构建时间 | 索引构建耗时 | 根据更新频率 | 实际案例: 某RAG问答系统需要检索亿级文档向量。对比三引擎后选择Milvus,因为需要分布式部署和动态数据更新,亿级向量检索延迟8ms。Faiss单机GPU加速适合实验验证,ScaNN精度最高但无法分布式。

AI 应用场景

大规模推荐系统向量召回

RAG检索增强生成系统

多模态搜索引擎

Python 演示

python49 行
import numpy as npimport timefrom typing import List, Tuple def benchmark_flat(vecs: np.ndarray, queries: np.ndarray, k: int = 10) -> Tuple[List[int], float]:    """暴力搜索baseline(等价于Faiss IndexFlatIP)"""    norms_v = vecs / (np.linalg.norm(vecs, axis=1, keepdims=True) + 1e-8)    norms_q = queries / (np.linalg.norm(queries, axis=1, keepdims=True) + 1e-8)    start = time.time()    scores = norms_q @ norms_v.T    indices = np.argsort(-scores, axis=1)[:, :k]    elapsed = time.time() - start    return indices.tolist(), elapsed def benchmark_ivf(vecs: np.ndarray, queries: np.ndarray, k: int = 10, nlist: int = 100, nprobe: int = 10) -> Tuple[List[int], float]:    """IVF索引模拟(等价于Faiss IndexIVFFlat)"""    from sklearn.cluster import KMeans    dim = vecs.shape[1]    kmeans = KMeans(n_clusters=nlist, random_state=42).fit(vecs)    centroids = kmeans.cluster_centers_    buckets = [[] for _ in range(nlist)]    for i, v in enumerate(vecs):        cid = kmeans.predict([v])[0]        buckets[cid].append(i)    start = time.time()    results = []    for q in queries:        centroid_dists = np.linalg.norm(centroids - q, axis=1)        probe_ids = np.argsort(centroid_dists)[:nprobe]        candidates = []        for pid in probe_ids:            candidates.extend(buckets[pid])        candidate_vecs = vecs[candidates]        scores = candidate_vecs @ q        top_k_local = np.argsort(-scores)[:k]        top_k_global = [candidates[idx] for idx in top_k_local]        results.append(top_k_global)    elapsed = time.time() - start    return results, elapsed def compare_engines(n_vecs=10000, dim=128, n_queries=100):    """对比Flat和IVF的性能"""    vecs = np.random.randn(n_vecs, dim).astype(np.float32)    queries = np.random.randn(n_queries, dim).astype(np.float32)    _, flat_time = benchmark_flat(vecs, queries)    _, ivf_time = benchmark_ivf(vecs, queries)    print(f'Flat: {flat_time*1000:.1f}ms, IVF: {ivf_time*1000:.1f}ms')    print(f'IVF speedup: {flat_time/ivf_time:.1f}x')    return flat_time, ivf_time
  1. Flat暴力搜索:归一化向量后通过矩阵乘法计算所有内积,argsort取top-k。等价于Faiss IndexFlatIP。
  2. IVF索引构建:使用KMeans将向量空间划分为nlist个簇,每个向量分配到最近的簇。
  3. IVF查询:找到距离查询最近的nprobe个簇,只在候选簇内计算精确距离。
  4. 在候选向量中计算内积并取top-k,映射回全局索引。
  5. 对比函数:生成随机数据,分别运行Flat和IVF,对比延迟和加速比。

常见问答

ScaNN、Faiss、Milvus三者的核心定位差异是什么?
ScaNN是Google开发的高精度单机检索库,核心创新是各向异性量化;Faiss是Meta开源的通用向量检索库,索引类型最丰富且支持GPU;Milvus是分布式云原生向量数据库,提供完整的数据管理和高可用保障。
为什么ScaNN的精度最高但不适合大规模生产环境?
ScaNN的AVQ量化针对内积检索优化,精度最高。但它不支持分布式部署,数据规模受限于单机内存,也不支持GPU加速。大规模生产环境需要分布式和高可用能力,应选择Milvus。
Faiss和Milvus的本质区别是什么?
Faiss是一个检索库(library),只提供向量索引和搜索功能,需要开发者自行管理数据持久化、分布式部署和高可用。Milvus是一个完整的向量数据库(database),提供CRUD操作、事务、权限控制、监控等完整的数据管理能力。
如何选择向量检索引擎?
数据规模<百万且追求精度选ScaNN;百万~亿级需要GPU加速选Faiss;亿级以上需要分布式和高可用选Milvus。选型需综合考虑recall、延迟、内存、吞吐、运维成本等多维度指标。
Milvus的存算分离架构有什么优势?
计算节点(Query Node/Data Node)和存储层(对象存储)独立扩缩容。查询负载增加时加Query Node,数据量增加时加Data Node和存储。避免传统架构中计算和存储绑定导致的资源浪费。

常见误区

误区认为ScaNN精度最高就适合所有场景

正解ScaNN单机无分布式能力,大规模生产环境需Milvus或Faiss加自研分布式层。精度只是选型的维度之一,还需考虑分布式能力、动态更新、运维成本等。

误区认为Faiss和Milvus功能完全等价

正解Faiss是库需自行管理数据持久化和分布式,Milvus是完整数据库提供CRUD和高可用。两者在架构层面有本质区别。

误区认为recall最高的引擎就是最佳选择

正解选型需综合考虑recall、延迟、内存、吞吐、数据规模和运维成本,不能只看单一指标。

误区认为向量数据库只是传统数据库加了向量字段

正解向量数据库在索引结构(ANN vs B+Tree)、查询模式(近似搜索 vs 精确匹配)、存储优化(列式压缩 vs 行存储)上与传统数据库有本质区别。

参考来源