Milvus 2.0 Knowhere 概览
编者按:本文详细介绍了 Milvus 2.0 系统的核心计算引擎 Knowhere,包括代码概览、如何添加索引,及对 Faiss 所做的优化。
目录
Knowhere 概述
Knowhere 代码概览
Milvus 数据模型
Index 索引建立
Knowhere 代码架构
Knowhere 如何添加索引
Knowhere 对 Faiss 的优化
Knowhere 概述
如果把 Milvus 比喻为一辆跑车,Knowhere 就是这辆跑车的引擎。Knowhere 的定义范畴分为狭义和广义两种。狭义上的 Knowhere 是下层向量查询库(如Faiss、HNSW、Annoy)和上层服务调度之间的操作接口。同时,异构计算也由 Knowhere 这一层来控制,用于管理索引的构建和查询操作在何种硬件上执行, 如 CPU 或 GPU,未来还可以支持 DPU/TPU/……这也是 Knowhere 这一命名的源起 —— know where。广义上的 Knowhere 还包括 Faiss 及其它所有第三方索引库。因此,可以将 Knowhere 理解为 Milvus 的核心运算引擎。
从上述定义可以得知,Knowhere 只负责处理数据运算相关的任务,其他系统层面的任务如数据分片、负载均衡、灾备等,都不在它的功能范畴中。另外,从 Milvus 2.0.1 开始,广义的 Knowhere 已从 Milvus 项目中剥离出来,成为了一个单独的项目。
作为一个 AI 数据库,Milvus 的运算可以分成标量运算和向量运算。Knowhere 只负责处理向量运算。
上图是 Knowhere 模块在 Milvus 项目中的架构图。从下往上依次是系统硬件、第三方向量查询库、Knowhere,再往上通过 CGO 和 index_node 和 query_node 交互。橙色所示部分是狭义上的 Knowhere,蓝色框所示部分是广义上的 Knowhere。本文介绍的是广义上的 Knowhere。
Knowhere 代码概览
对 Knowhere 的代码结构有大致了解,用户在后续看代码或是贡献代码时都能更加便利。
Milvus 数据模型
首先介绍 Milvus 的数据模型。
- Database,现在 Milvus 还不支持多租户,所以只有一个 database
- Collection,因为是分布式系统,所以一个 collection 可以被加载到多个 node 上,每个 node 加载该 collection 的一个分片,每个分片称为 shard
- Partition,数据的逻辑分片,可加速查询
- Segment,是 Partition 中的数据块
在 Milvus 中查询的最小单位是 segment,对 collection 的查询操作最终会被分解为对该 collection 或若干 partition 中所有 segment 的查询。最后,对所有 segment 的查询结果进行归并,并得到最终结果。
如上图所示,为了支持流式数据插入,segment 分为 growing segment 和 sealed segment。growing segment 是可以继续添加 data 的动态 segment,但是它没有索引,只能用“暴搜”来查询;到达 size 或时间阈值后,growing segment 会变为 sealed segment。每个 segment 包含多个 field,其中,Primary Key 和 Timestamp 是系统默认自带的 field,其余 field 由用户建表时指定。
现在一个 collection 只支持一列 vector field;Knowhere 只处理 vector field;建索引和查询也都只是针对 segment 中的 vector field 。
Index 索引建立
索引是独立于原始向量数据的一种数据结构。绝大部分的索引构建需要经历 4 个步骤,创建(create) - 数据插入(insert) - 训练(train) - 构建(build) 。
对于有的 AI 应用,其训练数据集和查询数据集是分开的,先用训练数据集做训练,再基于该训练结果插入查询数据。如公开数据集 sift1M / sift1B,其中就分专门的训练数据和测试数据。 但对于 Knowhere,不区分训练数据和查询数据。对于每一个 segment,Knowhere 都是用该 segment 的全量数据做训练,再基于该训练结果插入全量数据构建索引。
Knowhere 代码架构
Knowhere 里所有的操作都是针对 index 的操作。
下图最左侧的 DataObj 是 Knowhere 中所有数据结构的基类,只有一种虚方法 Size();Index 类继承了 DataObj,并有一个 field 名为 size_,有 Serialize() 和 Load() 两种虚方法。由 Index 派生出的 VecIndex 是所有向量索引的纯虚基类。从图中可见,它提供了训练(Train)、查询(Query)、统计信息(GetStatistics、ClearStatistics)等方法。
上图右侧展示了其他几种索引类型。
- Faiss 原生索引有 2 个基类:FaissBaseIndex 是所有 Faiss 原生 FLOAT 索引的基类;FaissBaseBinaryIndex 是所有 Faiss 原生 BINARY 索引的基类。
- GPUIndex 是所有 Faiss 原生 GPU 索引的基类。
- OffsetBaseIndex 是自研的索引基类,在索引里只存向量 ID,对于128纬向量,索引文件能减小2个数量级。因此,该索引在查询时需要配合原始向量一起使用。
IDMAP 是一种不是索引的索引,俗称“暴搜”。原始向量插入后,不需要训练和构建,直接用暴搜对原始向量数据进行查询。但是为了和其他索引一致,IDMAP 也继承自 VecIndex,并且实现了它所有的虚接口,因此它和其他索引的使用方法相同。
上图是 IVF 系列,也是目前使用最多的索引接口类型。由 VecIndex 和 FaissBaseIndex 派生出了 IVF,由 IVF 再派生出 IVFSQ 和 IVFPQ;由 GPUIndex 和 IVF 派生出了 GPUIVF,由 GPUIVF 再派生出 GPUIVFSQ 和 GPUIVFPQ。
IVFSQHybrid 是自研的混合索引,coarse quantizer 在 GPU 上执行,桶内查询在 CPU 上执行,它利用了 GPU 运算能力强的特点,又减少了 CPU 和 GPU 之间的内存拷贝,所以查询召回率和 GPUIVFSQ 一样,但查询性能更高。
另外 Binary 类型索引的基本类架构比较简单,由 FaissBaseBinaryIndex 和 VecIndex 派生出 BinaryIDMAP 和 BinaryIVF,不再展开介绍。
目前除了 Faiss 系列的索引,其它的第三方索引只支持两种,一种是基于树的索引 Annoy,一种是基于图的索引 HNSW。这两种索引是现在使用最多的,且都是直接从 VecIndex 派生出来。
Knowhere 如何添加索引
想在 Knowhere 中添加新索引,推荐参考现有索引。若添加基于矢量量化的索引,推荐参考 IVF_FLAT;若添加基于图的索引,推荐参考 HNSW;若添加基于树的索引,推荐参考 Annoy。
具体步骤如下:
- 在
IndexEnum
中添加新索引名称字符串; - 在 [ConfAdapter.cpp] 中加入新索引参数的合法性检查(主要是在 train 和 query 时的参数检查);
- 为新索引新建单独文件,新索引的基类应该至少包含 VecIndex,实现 VecIndex 需要的虚接口;
- 在
VecIndexFactory::CreateVecIndex()
中添加新索引的创建逻辑; - 最后,在
unittest
目录下添加单元测试。
Knowhere 对 Faiss 的优化
Knowhere 对 Faiss 做了很多功能上的扩展和性能上的优化。
1、支持 BitsetView
最开始引入 Bitset 是为了支持 “soft delete”,Bitset 里的每个 bit 对应 index 中的一行向量,若 bit 位为 1,表明该行向量已被删除,该行向量在查询时不参与运算。
后来 Bitset 的应用有了扩展,不再局限于支持 delete,但 Bitset 的基本语义不变,只要 bit 为 1 就表明其对应的向量不参与查询。
Knowhere 所有对外暴露的 Faiss 索引查询接口都添加了 Bitset 参数,包括 CPU 索引和 GPU 索引。
Bitset 的详细说明可参考 干货分享|Bitset 应用详解
2、支持更多的 Binary Index 距离计算方式: Jaccard, Tanimoto, Superstructure, Substructure
Jaccard 距离和 Tanimoto 距离可用于计算样本间的相似度;SuperStructure 和 Substructure 可用于计算化学分子式之间的相似度。
3、支持 AVX512 指令集
FAISS 原生支持的指令集包括 AARCH64 / SSE42 / AVX2,我们在 AVX2 的基础上添加了对于指令集 AVX512 的支持。相比于 AVX2,AVX512 在构建索引和查询时能提升性能 20% - 30%。
可参考文章 Milvus 在 AVX-512 与 AVX2 的性能对比
4、支持指令集动态加载
原生 Faiss 支持哪种指令集需要在编译时通过参数宏指定,如果采用这种方式,Milvus 在 release 时就需要为每种指令集编译特定的 Milvus 镜像,用户在使用时也必须根据硬件环境选择特定的 Milvus 镜像。这就给 Milvus 发行和用户使用带来了不便。
为了解决这一问题,Knowhere 定义了不同指令集需要实现的统一函数接口,并把不同指令集的函数实现分别放到不同的文件中,然后用不同的编译参数同时编译所有的文件。
在运行时,Knowhere 也提供了接口,允许用户手动选择运行的指令集函数;或者 Knowhere 会先检查当前运行环境的 CPU 所能支持的最高指令集,然后挂载该指令集对应的函数。
5、其它性能优化
可参考我们在 SIGMOD 发表的论文 Milvus: A Purpose-Built Vector Data Management System
完整版视频讲解请戳:
Deep dive# Milvus 2.0 Knowhere 概述_哔哩哔哩_bilibili
如果你在使用的过程中,对 Milvus 有任何改进或建议,欢迎在 GitHub 或者各种官方渠道和我们保持联系~
Zilliz 以重新定义数据科学为愿景,致力于打造一家全球领先的开源技术创新公司,并通过开源和云原生解决方案为企业解锁非结构化数据的隐藏价值。
Zilliz 构建了 Milvus 向量数据库,以加快下一代数据平台的发展。Milvus 数据库是 LF AI & Data 基金会的毕业项目,能够管理大量非结构化数据集,在新药发现、推荐系统、聊天机器人等方面具有广泛的应用。
Milvus 2.0 Knowhere 概览相关推荐
- 一月 Z 星月度速览 | Milvus 2.0 GA 来了、开源的 embedding 框架与社区 Towhee 官宣……...
#January Z 星月度速览 最热|Milvus 2.0 GA 版本正式发布! 最热|Towhee,开源的 embedding 框架与社区 直播|向量数据库研讨会:NeurIPS 向量检索比赛方案 ...
- Hyperledger Fabric1.0架构概览
Hyperledger是被业界非常看到的联盟链的实现,包括IBM.Intel.R3.各个大型商业银行等都参与其中,带给我们关于区块链技术与软件工业.金融.保险.物流等领域碰撞结合的想象空间:在这个联盟 ...
- USB 3.0规范中译本 第3章 USB 3.0体系结构概览
原文链接 https://www.cnblogs.com/coryxie/p/3956220.html 本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章 ...
- VMware Workstation 6.0全貌概览
尽管VMware Infrastructure 3是VMware的旗舰产品,但是大多数博友接触到的个人版VMware产品VMware Workstation居多,不久前VMware隆重推出的Works ...
- BLE-1の蓝牙4.0协议栈概览
1. 协议栈结构图: 1.1 控制器 1.2 主机 1.3 补充资料: 1.物理层(Physical Layer,简写 PHY): PHY层用来指定BLE所用的无线频段,调制解调方式和方法等.是1Mb ...
- 基于 Milvus 的以图搜图系统 2.0
Milvus 以图搜图 1.0 版本自发布以来便受到广大用户的欢迎.近日,Zilliz 推出了 Milvus 以图搜图系统 2.0 版.本文将介绍 Milvus 以图搜图系统 2.0 版的主要更新内容 ...
- Milvus Committer 嵇斌:参与开源是一种对自己的投资
✏️ 编者按: 2022 年 3 月,嵇斌在社区一致投票通过后正式加入了 Milvus committer 的行列. 在过去 3 个月的时间里,他除了为社区提交了 40 个 PR 外,也活跃于 Mil ...
- Milvus 图形化管理工具 Attu 来袭!
面对高速增长的非结构化数据处理需求,Milvus 2.0 应运而生.Milvus 2.0 是一款面向 AI.专为大规模生产级场景设计的向量数据库系统.如何快速上手这款非结构化数据处理神器?除了 Mil ...
- 腾讯 angel 3.0:高效处理模型
腾讯 angel 3.0:高效处理模型 紧跟华为宣布新的 AI 框架开源的消息,腾讯又带来了全新的全栈机器学习平台 angel3.0.新版本功能特性覆盖了机器学习的各个阶段,包括:特征工程.模型训练. ...
最新文章
- 什么检索是借助计算机技术进行自动标引的,自动文献检索系统
- Android Studio中的代码格式快捷方式
- 计算几个变量之间的相关系数,计算协方差矩阵时:TypeError: cannot perform reduce with flexible type
- Java FAQ(6)
- boost::python::to_python_converter相关的测试程序
- ViewResolvers
- LibAOM与AV1的最新研发进展
- @ConfigurationProperties和@Value不同的使用场景,@Bean添加组件 (6.spring boot配置文件注入)...
- PyQt中从RAM新建QIcon对象 / Create a QIcon from binary data
- spring更新后 外层事务查不到_再深一点:面试工作两不误,源码级理解Spring事务...
- java 按照概率生成随机数_JAVA 根据设置的概率生成随机数的方法
- 漫画 |《程序员十二时辰》,内容过于真实 ...
- @spoj - lcs2@ Longest Common Substring II
- c语言80c51控制系统设计,89C51单片机的步进电动机控制系统设计
- 计算机图形学基础-第二章 VB.NET 绘图基础
- c语言浪漫烟花表白,C语言实战之浪漫烟花表白程序.pdf
- css网站变灰色代码
- 32位微型计算机能不能安装64位操作系统,32位cpu能装64位系统吗|32位cpu可以装64位系统吗...
- 计算机基础课教学心得,浅谈高专院校计算机基础课程的教学心得体会养
- 搭建exchange邮件服务器一定要ad域么?_域渗透神器-AD Explorer使用指南
热门文章
- 用好搜索神器Everything,盘活你的文件
- mysql 聚簇索引与非聚簇索引
- 【新手入门Python必看】1000+常用Python库一览
- mysql查询本用户的表的列名等信息_mysql常用命令查询手册
- 《新概念英语》英语的学习方法(完整版)
- Android开发工程师笔试题
- qq手机令牌 for android3.3 官方安装版,腾讯手机管家app下载 腾讯手机管家(原QQ手机管家) for Android v8.8.3 官方安卓版 下载-脚本之家...
- 联发科处理器手机安装linux,BQ Aquaris Ubuntu 智能手机配 4.5 英寸屏幕四核CPU
- Docker 镜像仓库 -- Harbor 搭建
- 维基解密主站点WikiLeaks.org在美国恢复访问