前言
本文将会介绍Knowhere这个概念,它是milvus向量执行引擎的核心。
概览
Knowhere是milvus向量咨询引擎的核心,它将好几个向量相似搜索库聚集在一起(包括faiss、hnswlib、annoy)。Knowhere也被设计支持异构计算。它控制在什么硬件(CPU或GPU)上执行索引构建和查询请求.为什么取Knowhere作为名字的原因就是因为它知道在哪里执行这些操作。更多类型的硬件包括DPU和TPU将会在未来的版本中进行支持。
milvus架构中的Knowhere
下图展示了milvus架构中Knowhere的地位:
最底层的那一次是系统硬件。第三方索引库位于硬件之上。Knowhere通过它上层的CGO来与索引节点和查询节点进行互动。CGO是一个允许通过GO包来调用C代码的组件。
Knowhere的优势
下面通过faiss来介绍Knowhere的优势
支持Bitset视图
milvus引入Bitset机制来实现软删除。软删除的向量仍然存在数据库当中,仅仅是不会再向量相似搜索或查询的时候参与计算。
Bitset中的每一位与索引的向量相对应。如果一个向量在Bitset中被标记为“1”,则表示该向量已经被软删除并将不会参与向量搜索。在Knowhere中,所有暴露出来的faiss索引查询api都会使用bitset参数,包括CPU和GPU索引。
对于二进制向量支持多种相似度算法
Knowhere支持Hamming, Jaccard, Tanimoto, Superstructure, 和 Substructure算法,Jaccard和Tanimoto可以被用来计算两个样本集的相似度。Superstructure和 Substructure可以被用来计算化学结构的相似度。
支持AVX512指令集
除了faiss已经支持的AArch64,SSE4.2和AVX2指令集,Knowhere还支持AVX512,相比于AVX2,AVX512可以提高20%到30%的索引构建和查询的性能。
自动选择SIMD指令
Knowhere支持在任何的CPU处理器(私有部署或者云平台)自动调用合适的SIMD指令(比如SIMD SSE, AVX, AVX2, and AVX512),所以在计算过程中不需要用户手动声明SIMD标志(比如“-msse4”)
Knowhere是通过重构Faiss的代码库构建的.依赖SIMD加速的通用的功能(比如相似度计算)被分离出来,针对每个功能,4个版本(也就是SSE, AVX, AVX2, AVX512)的实现已经被分离到不同的源文件。源文件在未来将会被相应的SIMD标志独立编译。因此,在运行过程中,Knowhere可以基于当前的CPU标志自动选择最好的SIMD指令和利用钩子链接最正确的函数指针。
其他性能优化
Knowhere代码结构
milvus主要进行向量和标量操作的计算,Knowhere仅仅负责向量索引的操作。
索引的数据结构独立于原始的向量数据。通常索引需要四个步骤:创建索引,训练数据,插入数据和构建索引。在有些AI应用中,数据训练是独立于向量搜索。数据集中的数据首先被训练,然后再插入到像milvus这样的数据库中进行相似搜索。例如开源数据集sift1M和sift1B就有不同的训练数据和测试数据。
然后,在Knowhere中,数据训练和搜索是一样的,Knowhere在段里面训练所有的数据,然后插入所有的训练数据并为它们构建索引。
DataObj:基类
在Knowhere中,DataObj是所有数据结构的基类。Knowhere中唯一的虚拟方法是Size()。Index类继承DataObj并且有一个“size_”的字段。Index类也有两个虚拟方法:Serialize()和 Load()。VecIndex类继承自Index,其也是所有向量索引的虚拟基类。VecIndex提供的方法包括:Train(), Query(), GetStatistics(), 和ClearStatistics()
其他索引类型列在了上图的右边。
- faiss索引有两个基类:FaissBaseIndex:负责所有浮点数向量的索引;FaissBaseBinaryIndex:负责所有二进制索引。
- GPUIndex:所有faiss GPU索引的基类
- OffsetBaseIndex:所有自己开发索引的基类,假设在索引文件中仅存储矢量ID,则128维矢量的文件大小可以减少2个数量级。
IDMAP:暴力搜索
从技术上讲,IDMAP不是索引,而是用于暴力搜索。当向量插入到数据库,既不需要数据训练也不需要索引构建,就能直接搜索插入的数据。
然而,为了代码一致性,IDMAP也继承自VecIndex类,这样IDMAP也使用也就和其他的索引一样。
IVF索引
IVF(倒排文件)索引非常频繁的被用到。IVF类继承自VecIndex和 FaissBaseIndex,进一步扩展到IVFSQ和IVFPQ.GPUIVF继承自GPUIndex和IVF.它也进一步扩展到GPUINVFSQ,GPUIVFPQ.
IVFSQHybrid是自主研发的混合索引。当在CPU上面搜索桶的时候,粗放的量化器将会在GPU上面执行。这种类型的索引利用GPU的算力可以降低CPU和GPU之间的内存拷贝。IVFSQHybrid拥有和GPUIVFSQ一样的召回率同时还有更好的性能。
二进制索引的类结构相对比较简单,BinaryIDMAP和BinaryIVF继承自FaissBaseBinaryIndex和VecIndex.
第三方索引
当前除了Faiss,只有两种类型的第三方索引被支持:基于树的索引 Annoy和基于图的索引HNSW。这两个经常被用到的第三方索引都继承VecIndex.