🚀 免费试用 Zilliz Cloud,完全托管的 Milvus,体验 10 倍的性能提升!立即试用>

milvus-logo
LFAI
  • Home
  • Blog
  • 是什么增强了 Milvus 向量数据库的相似性搜索功能?

是什么增强了 Milvus 向量数据库的相似性搜索功能?

  • Engineering
May 10, 2022
Yudong Cai

cover image 封面图片

本文由蔡玉东撰写,倪安琪翻译。

作为核心向量执行引擎,Knowhere之于Milvus,就如同发动机之于跑车。本文将介绍什么是 Knowhere,它与 Faiss 有何不同,以及 Knowhere 的代码结构。

跳转到

Knowhere的概念

狭义地说,Knowhere是一个操作界面,用于访问系统上层的服务和系统下层的向量相似性搜索库(如FaissHnswlibAnnoy)。此外,Knowhere 还负责异构计算。更具体地说,Knowhere控制在哪种硬件(如CPU或GPU)上执行索引构建和搜索请求。这就是 Knowhere 名字的由来--知道在哪里执行操作符。未来的版本将支持更多类型的硬件,包括DPU和TPU。

从广义上讲,Knowhere还集成了其他第三方索引库,如Faiss。因此,从整体上看,Knowhere 是公认的 Milvus 向量数据库的核心向量计算引擎。

从Knowhere的概念可以看出,它只处理数据计算任务,而分片、负载均衡、灾难恢复等任务则超出了Knowhere的工作范围。

从Milvus 2.0.1开始,Knowhere(广义上的)从Milvus项目中独立出来。

Milvus 架构中的 Knowhere

knowhere architecture Knowhere 架构

Milvus 中的计算主要涉及向量和标量操作。Knowhere 只处理 Milvus 中对向量的操作符。上图展示了 Milvus 中的 Knowhere 架构。

最底层是系统硬件。第三方索引库位于硬件之上。然后,Knowhere通过CGO与顶层的索引节点和查询节点交互。

本文所讨论的Knowhere是广义上的Knowhere,即架构图中蓝色框内所标注的Knowhere。

Knowhere 与 Faiss

Knowhere不仅进一步扩展了Faiss的功能,还优化了性能。更具体地说,Knowhere 具有以下优势。

1.支持比特视图

最初,在 Milvus 中引入 bitset 是为了实现 "软删除"。软删除的向量仍然存在于数据库中,但在向量相似性搜索或查询时不会被计算。比特集中的每个比特都对应一个索引向量。如果某个向量在比特集中被标记为 "1",则表示该向量已被软删除,在向量搜索过程中将不会涉及。

比特集参数被添加到 Knowhere 中所有公开的 Faiss 索引查询 API 中,包括 CPU 和 GPU 索引。

进一步了解bitset 如何实现向量搜索的多功能性

2.支持更多二进制向量索引的相似度指标

Hamming 外,Knowhere 还支持JaccardTanimotoSuperstructureSubstructure。Jaccard 和 Tanimoto 可用于测量两个样本集之间的相似性,而 Superstructure 和 Substructure 可用于测量化学结构的相似性。

3.支持 AVX512 指令集

Faiss 本身支持多种指令集,包括AArch64SSE4.2AVX2。Knowhere 通过添加AVX512 进一步扩展了支持的指令集,与 AVX2 相比,AVX512将索引构建和查询性能提高 20% 至 30%

4.自动选择 SIMD 指令

Knowhere 的设计目标是在具有不同 SIMD 指令(如 SIMD SSE、AVX、AVX2 和 AVX512)的各种 CPU 处理器(本地部署和云平台)上良好运行。因此,面临的挑战是,给定一个软件二进制文件(即 Milvus),如何让它在任何 CPU 处理器上自动调用合适的 SIMD 指令?Faiss 不支持自动选择 SIMD 指令,用户需要在编译时手动指定 SIMD 标志(如"-msse4")。不过,Knowhere 是通过重构 Faiss 的代码库而构建的。依赖 SIMD 加速的常用函数(如相似性计算)被分解出来。然后为每个函数实现四个版本(即 SSE、AVX、AVX2、AVX512),并将每个版本放入单独的源文件中。然后,使用相应的 SIMD 标志对源文件进行单独编译。因此,在运行时,Knowhere 可以根据当前的 CPU 标志自动选择最合适的 SIMD 指令,然后使用挂钩功能链接正确的函数指针。

5.其他性能优化

阅读《Milvus: A Purpose-Built Vector Data Management System》,了解有关 Knowhere 性能优化的更多信息。

了解 Knowhere 代码

如第一节所述,Knowhere 只处理向量搜索操作。因此,Knowhere只处理实体的向量场(目前只支持一个 Collections 中实体的一个向量场)。索引建立和向量相似性搜索也是针对段中的向量场。要想更好地了解数据模型,请阅读此处的博客。

entity fields 实体字段

索引

索引是一种独立于原始向量数据的数据结构。索引需要四个步骤:创建索引、训练数据、插入数据和建立索引。

对于某些人工智能应用来说,数据集训练是一个独立于向量搜索的过程。在这类应用中,首先要对数据集的数据进行训练,然后将数据插入到 Milvus 这样的向量数据库中进行相似性搜索。开放数据集(如 sift1M 和 sift1B)为训练和测试提供了数据。然而,在 Knowhere 中,训练数据和搜索数据是混合在一起的。也就是说,Knowhere 会训练一个数据段中的所有数据,然后插入所有训练过的数据并为它们建立索引。

Knowhere 代码结构

DataObj 是 Knowhere 中所有数据结构的基类。Size() 是 DataObj 中唯一的虚拟方法。Index 类继承自 DataObj,并带有一个名为 "size_"的字段。Index 类还有两个虚拟方法--Serialize()Load() 。从 Index 派生的 VecIndex 类是所有向量索引的虚拟基类。VecIndex 提供的方法包括Train(),Query(),GetStatistics()ClearStatistics()

base clase 基类

上图右侧列出了其他索引类型。

  • Faiss 索引有两个子类:FaissBaseIndex 用于浮点向量上的所有索引,FaissBaseBinaryIndex 用于二进制向量上的所有索引。
  • GPUIndex 是所有 Faiss GPU 索引的基类。
  • OffsetBaseIndex 是所有自主开发索引的基类。索引文件中只存储向量 ID。因此,128 维向量的索引文件大小可以减少 2 个数量级。我们建议在使用这类索引进行向量相似性搜索时,也将原始向量考虑在内。

IDMAP IDMAP

从技术上讲,IDMAP不是索引,而是用于暴力搜索。当向量被插入到向量数据库时,不需要进行数据训练和建立索引。搜索将直接在插入的向量数据上进行。

不过,为了代码的一致性,IDMAP 也继承自 VecIndex 类及其所有虚拟接口。IDMAP 的用法与其他索引相同。

IVF 反转 文件

IVF(倒置文件)索引是最常用的索引。IVF 类派生自 VecIndex 和 FaissBaseIndex,并进一步扩展到 IVFSQ 和 IVFPQ。GPUIVF 衍生自 GPUIndex 和 IVF。然后 GPUIVF 进一步扩展到 GPUIVFSQ 和 GPUIVFPQ。

IVFSQHybrid 是一个自主开发的混合索引类,它在 GPU 上通过粗量化执行。而桶中的搜索则在 CPU 上执行。这种索引可以利用 GPU 的计算能力,减少 CPU 和 GPU 之间的内存拷贝。IVFSQHybrid 的召回率与 GPUIVFSQ 相同,但性能更好。

二进制索引的基类结构相对更简单。BinaryIDMAP 和 BinaryIVF 源自 FaissBaseBinaryIndex 和 VecIndex。

third-party index 第三方索引

目前,除了 Faiss 之外,只支持两种第三方索引:基于树的索引 Annoy 和基于图的索引 HNSW。这两种常用的第三方索引都源自 VecIndex。

向Knowhere添加索引

如果想在Knowhere中添加新的索引,可以先参考现有的索引:

  • 要添加基于量化的索引,请参考 IVF_FLAT。
  • 要添加基于图形的索引,请参考 HNSW。
  • 要添加基于树的索引,请参考 Annoy。

参考现有索引后,可以按照以下步骤向 Knowhere 添加新索引。

  1. IndexEnum 中添加新索引的名称。数据类型为字符串。
  2. 在文件ConfAdapter.cpp 中为新索引添加数据验证检查。验证检查主要用于验证数据训练和查询的参数。
  3. 为新索引创建一个新文件。新索引的基类应包括VecIndexVecIndex 的必要虚拟接口。
  4. VecIndexFactory::CreateVecIndex() 中添加新索引的索引构建逻辑。
  5. unittest 目录下添加单元测试。

关于深入研究系列

随着 Milvus 2.0正式宣布全面上市,我们精心策划了这个 Milvus 深度挖掘系列博客,对 Milvus 架构和源代码进行深入解读。本系列博客涉及的主题包括

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started

Like the article? Spread the word

扩展阅读