Chat with Milvus #12 :新版本、Postgres向量检索插件、比Faiss好用?

Attendee= 参会者

Attendee A:我现在只是属于试用阶段,还没有经过一个比较完整的使用场景的考验,所以现在主要就是说想学习一下,看看别人都是应用到什么样的场景。我们现在实际用的就是一个句子相似性的应用场景,只做了一个很小的测试,没有遇到很明显的问题。之前觉得检索的准确率不是很高,但是有一个人建议说我做向量的归一化,我还没有做测试,所以还不知道结果,就是这么一个情况。

顾老师@ Milvus:所以您那边是一个自然语言处理的场景是吧?

Attendee A:对,第一步是自然语言处理,然后后面可能就是说会用句子来搜图,然后图搜句子的这样的也会尝试一下。

顾老师@ Milvus:句子来搜图的话,您这边图片都是有标签的吗?

Attendee A:对,就是说就类似于那种表情图。一开始会试一些表情图。

顾老师@ Milvus:明白了,所以你们主要是现在还是在搜索,先帮助大家去搜索表情包是吗?

Attendee A:对。

顾老师@ Milvus:然后给这些表情包打上一些文字的这种标签,然后通过比如说用户给个句子,然后互相提取语义,然后去做匹配的搜索,是这样的一种效果是吧?

Attendee A:对。

顾老师@ Milvus:所以你们现在收集了多少个表情包呢?

Attendee A:这个就没有,因为只是做实验的,验证一下想法就行了,还没有说很正式的来推进这个事情。

顾老师@ Milvus:你们是用什么样的模型去把句子或者说问答的自然语言转换成向量的?

Attendee A:我们目前试过的最好的就是谷歌的 USE (Universal Sentence Encoder), 它比单独的 BERT 都还要好一点。

顾老师@ Milvus:效果比 BERT 还要好一些。好的明白了,我们也学习到了,因为我们原来之前的一个这个 QA 智能机器人,我们当中用的直接是用 BERT 的提取的句子的向量。感觉因为我们数据集的关系,我们也是一个这种 GitHub 上找的数据集,然后银行场景下的问答,然后试了一下就感觉还行,因为没有更多的数据可以去验证,所以就感觉还是不错,但如果有更特殊的数据的话,我想你说的 USE 可能会是会是一个更好的方式。所以你们大概这个想法最后会想去搜多少表情包呢?

Attendee A:表情包这一块如果就是说从设想这个阶段的话,会考虑的比较空泛一点,就比较大一点,说一开始是表情包,可能后面的有动作,现在做人体的动作识别其实也是比较准确的。然后还可以再加上一点动作,这样就不断的多尝试一下,然后看看什么样的效果好。

顾老师@ Milvus:相当于就动作也是表情包的动作是吗?

Attendee A:不是,就是动作的话,任何一个图片里面,然后他人就会有一个动作,比如说根据动作还可以判断他的情绪什么的。当然这就是说相当于是表情包的话,你就说你也可以通过句子来读真实的人的照片,你比如说电影里边的截图对吧?然后有的时间你搜到这一句话,电影的什么出处,那么就是说你同样是根据动作,我再搜跟这个动作相似的结果这样子就不是以图搜图,而是你搜到一个图,然后把里面的动作描述出来,然后搜到更多的类似的姿势的东西。

顾老师@ Milvus:相当于有一个从图片提取特征,然后再走一些结构化的标签的搜索这样的一种过程是吗?

Attendee A:对,就肯定要加一点结构化的东西在里面。

顾老师@ Milvus:明白,所以其实对于特征提取的丰富性还是要求比较高的,你们要不断的增加一些新的东西,就是会要有新的模型,然后把所有的东西都再过一遍这样。

Attendee A:对,因为就是说觉得你用向量搜索就可以做很多事情了,我们现在说并没有先把内容定下来,而是先把这种方式定下来,然后再试一下都在什么内容上才是有效果。

顾老师@ Milvus:好的,我觉得你们这个想法非常有趣。因为我们有可能会有一些这种把这种 pipeline,就是一些模型推理的这种预处理的 pipeline 结合到向量搜索当中的一些打算,其实可以为大家提供一些完整度更高的一些方案,因为我们现在的 demo 的话相对比较简单一点,就以图搜图的 demo 相对都是做的比较简单一点,就是他们你说有关联也有关联,但是也没有特别的这种完善的这种流程和机制。所以这方面我觉得以后大家都必须得去探讨,我觉得这是一个挺有意思的东西。从非结构化数据搜非结构化数据,然后从非结构化数据去做结构化的数据,再搜非结构化数据,这些流程都是挺有意思的。


Attendee B:我是大概半个月以前接触代码库的,我之前也是做开发的,但主要是 windows 平台 .net 那些的,Linux 这些都不太会。看你们只能在 Linux上,就学了好多东西。然后后来发现是 CPU 那个就不行了,因为我电脑是五六年以前的家里的电脑。我先说一下我要做什么东西吧,我是一个想参加一个创业公司,然后他们是做知识产权的,他们是给别人注册商标的。

他们想做的事就是说提交过来一个图片以后,他根据图片的信息,还有一些文字的信息看他注册成功率,所以图片相似度这块可以作为一个参考点。所以我研究了一下这些技术,然后向量搜索这一块我现在不太清楚,因为我之前看还有一种方案是把向量存到 PostgreSQL 数据库里面,然后它实现向量的索引,但是我不知道它是怎么实现的,效率的话不知跟你这个引擎相比是怎么样的。

然后我现在的情况就是我家里机器不支持,今天我刚上来我就听见你们又说现在可以了,有点懵逼,因为我刚买了一个电脑,2万多块钱准备就买回来,然后再测试这样的,实际上我还没有开始测试,只是在询问一下这些框架的东西。

顾老师@ Milvus:我觉得首先你买的电脑肯定不会浪费了,因为现在的尤其是你牵涉到图片的这些东西的话,其实 Milvus 只是一部分,因为你现在的图片那部分你还需要 GPU 去做推理什么的。

Attendee B:GPU 的话其实我买了一个 2080TI,应该测试的话够用了,然后内存的话是先买了个 32G 的。CPU 好像我听说要求不是很高,所以就用了 i7-9700。硬盘的话就 m20 那种硬盘,我觉得应该可以。

顾老师@ Milvus:对。

Attendee B:所以就准备装 Ubuntu 的系统,然后具体学一下,我现在真还没有开始用你们系统,所以现在也不好提什么问题,今天来看开会就进来看一下。

顾老师@ Milvus:好的,没有问题,其实因为怎么讲,因为过去的电脑的话它确实 CUDA 的,因为英伟达的显卡的版本的升级,各种各样事情其实都也挺麻烦的。所以如果你有一个稍微新一点的硬件的话,你去装 CUDA 的驱动,你去装那些 Tensorflow 什么的,我觉得都会相对容易一些。尤其对你如果不是特别熟悉 Linux 的话,那方面肯定可以帮你减省很多时间。

商标搜索其实我们的用户群当中也有一些做企业大数据,做企业征信的一些公司,他们也也在搞类似的东西,因为确实大家都有个诉求,就是一个公司要想一个好名字,想一个商标真的是不容易的事情,所以这确实是能帮助到很多人的一个方式。

然后你刚才说向量存 Postgres 里面,确实之前有人写了一些这种 PG 的插件去做这些向量搜索功能,但是怎么讲,因为在向量这一块的话,其实和 PG 这样针对传统的结构化数据的这种数据管理模式,它其实是挺不一样的。其实为 PG 去写这样一个插件,主要就是你能复用到 PG 的部分很有限,但是核心的向量计算的部分 PG 的框架也并帮不到太多,但当然还是取决于你的数据量有多少。因为像中国的话,可能最多的那一家,我听到搜集到的用这种企业的商标数量可能是在千万级的图片。

Attendee B:对,现在有 3400 万好像是。

顾老师@ Milvus:所以像 3400 万这样级别的话,你放在 PG 当中的插件去搞可能是会比较痛苦。

Attendee B:但是他有一个优点,他可以存其他的业务的字段。可能比这种你们这种引擎用起来可能稍微方便,但是我们不知道我还都没试过,他们也是号称什么几千万上亿的数据可以秒搜什么的,我只是看一些网页上的说明。

然后我这块还有一个问题,现在我准备先试一下 VGG 的模型,但是不知道就说图片向量生成这一块应该怎么去学,就是什么类型的图片适合一个什么算法这种东西?

顾老师@ Milvus:

这是个很好的问题,基本上你需要花一些时间一个一个场景去学。因为我感觉现在人工智能这个角度来讲,机器视觉其实大的领域当中通用性的算法并不是那么的多,因为比如说你做人脸的提取人脸的,就有人脸那个算法,然后就对象识别的就有专门的对象识别的算法,然后 VGG 相对来说是一个通用性相对高一点的,但是如果你要特别的一个领域的话,它可能就不是那么的突出。

Attendee B:我现在这方面也不是很在行,我想的是可能需要把这些图片做一个分类,或者是把它自己先预处理一部分,他们都大概是轮廓什么都给他弄出来,然后然后再套用现成这些算法,因为自己写那个算法好像也不是很现实。

顾老师@ Milvus:对,一般都是基于现有的模型这样去调整。其实这部分的话确实会需要花一些时间去进行相应的研究的。

Attendee B:因为现在我看阿里云上有商标,还有各种不同行业使用的一些服务,但是这个数据量倒进去,它价格就太高了,所以只能自己想办法弄。

顾老师@ Milvus:是的。

Attendee B:这块你们也有了解过是吧?阿里云上面有大数据的服务嘛。

顾老师@ Milvus:是的,我不知道你是哪一个服务的,因为他现在各种服务也挺多的。

Attendee B:有比如说商品,像什么商铺的那些图片搜索,还有也有商标这一类的。可能到时候就说我自己先做一个方案,然后在他那边再试一下,然后比较一下看他们能做到什么程度,然后尽量选一个比较好的方案。

顾老师@ Milvus:因为他图片搜索在阿里云上各种,他那边可能有不同的方案,所以你看到那个可能和我之前关注的可能不太一样,所以我还真的没概念说。

Attendee B:对他好像是好像是新出的,我现在打开看一下,它这个产品服务里面有一个有一个图相识别,就在大数据这一块。 他们用的我不知道后台是技术是什么,但感觉你家的好像合作的大厂挺多的,应该挺靠谱的,我觉得。

顾老师@ Milvus:我们之前有关注过阿里云上它有专门的人工智能方向的什么图像搜索。确实它价格可能也确实不是一个很小的数字,这也是真的。

Attendee B:他家是按你存入多少图片的量作为作为一个收费的依据,然后就以图搜图。还有一个是国外的什么引擎来着,好像也是就说多少图片,然后按周期收费的这种服务。腾讯我也看了一下,好像他家每天只能导入 1 千个还是 1 万个图片,我算了一下要把我那图片导进去的话要 70 多年,如果免费想导进去的话。他是不按照你最终导进去,它是限额每天导多少图片这种。反正我觉得还是自己弄好一点,因为他们服务实在是价格太高。

顾老师@ Milvus:我知道你说的模式就是他每天会有比如说 1000 张的免费额度,然后需要搞更多的图片的话,是要买他的资源包之类的。我觉得云厂商的服务肯定是有他们的优势和好处的,当然确实他们的成本也是在那边,门槛也是在那边,这也是没有办法的事情。

Attendee B:因为商标的库现在还没给我发过来,他们说是要企业的业务端什么的,然后应该成功发过来以后我要看一下,就说如果他是分好类的,比如说每个类里面,因为他搜索的时候是按行业,不同的行业可能下面就没有这么大的量了,量比较小。所以说可能机器配置或者是库的就是那些性能要求就会低一点,不需要直接从那么多,就是几千万的向量里面。所反正我现在跟你随便聊,我现在没有实际做过这个东西,大概了解一下。

顾老师@ Milvus:好的。等你开始之后,如果有什么问题的话,都可以在群里问问。

Attendee B:好的,谢谢了,你们挺专业的,有什么问题都知道。就是说如果你们现在图片搜索是 VGG16 的话,他向量生成出来是多少维的?

顾老师@ Milvus:512

Attendee B:512 就是说我的 3000 万图片的话,如果都存在内存里大概需要多大?

顾老师@ Milvus:因为压缩索引的话应该是一条就是 512 个字节,然后你再乘以 3000 万,给你估算一下,应该是在 10 几 G 内存的样子。

Attendee B: 其实配置要求也不是很高。

顾老师@ Milvus:当然这个只是向量的部分,你可能还有推理的部分,这个是没有算进去的。

Attendee B:推理是什么意思?

顾老师@ Milvus:你要把图片转成向量,这部分当然不会花太多的内存,但是它会有会花一些 CPU 之类的。

Attendee B:我可以本地就是说把这些东西都处理好,然后比如说我上线的时候再把数据库直接放出去,就不需要在线计算了,因为它商标更新的频率很低的,你大概几个月才进一批数据。

顾老师@ Milvus:对是的。

Attendee B:对,还有一个想问的,搜索的时候,有一些业务的字段必须要再建一个库,等它做出来以后有一个结果集,然后再用这个结果集跟库进行对比,在筛选这样?

顾老师@ Milvus:

对是的,现在需要一些外挂 PG 这样的方式去做一些后续的过滤。

Attendee B:我觉得你们要是搜索引擎可以实现,比如我导入数据的时候,给你提供一份一个结构的,比如说每一张图片对应的一个业务数据,然后你可以查询的时候根据这些字段筛选,这样的话我感觉效率应该挺高,也比较有使用价值。

顾老师@ Milvus:对,我们会在未来版本当中加入这样的支持。

Attendee B:那行吧,我现在也说不出什么东西,以后有问题再交流。我其实这方面还真的是外行,机器学习什么的,我以前其实只是看看,然后平时上班都用不上的,最近才开始研究这个东西。

顾老师@ Milvus:好的,有问题都可以大家在一起讨论。


Attendee C:我们现在实际上还是以一个向量检索的中间件为主,对吧?然后其实所有我们插入向量,包括搜索的时候都要求我们先要生成向量,然后才能做这样的插入?

顾老师@ Milvus:对是的。

Attendee C:然后我想问的话,你们后面会不会内置一些针对不同领域的,就直接我只需要提供语料集,然后你可以自己去选择,然后生成向量的这种方式?

顾老师@ Milvus:这个是把模型接进来,这个是可以做的,会考虑给大家做一个更容易使用的东西。因为其实这部分的话,除非是做到一个云服务的程度,如果是私有部署的话,其实对用户来讲的话,都是需要去关心这些推理的模型,模型怎么去推理,然后怎么插入向量等等。如果你是希望特别简单去用这些东西的话,我可能到那天我们提供了一个云服务,对你来说就会特别的简单。

Attendee C:因为是这样,现在我本身的场景是做文本匹配的,就相当于这个拿去做召回了,然后实际上我是 query 生成的句向量,然句向量的话,我如果查的话,其实我本身自己是做了一套服务,是基于 annoy 的去做的搜索服务,然后我后来看见你们,所以就用了一下感觉还不错,但是其实有个问题是这样的,因为一般拿 query 去做的话,其实我都是用词向量去求平均的,这个时候我其实只能把就求平均之后的句向量放到咱们里面,但是我在前置的一步的时候还是需要就每次 query 进来,我先要转化成词向量,然后直接这样,这两步是割裂开的。然后我也没有想到什么很统一的方案,因为对词向量的查找而言,我是一个精确解,然后对于句向量搜索而言,它是一个近似解。

顾老师@ Milvus:你的词向量转句向量是怎么转的来着?能不能再给我们详细的描述一下?

Attendee C:就是我先拿出词向量,然后简单的根据句长去求一下平均。

顾老师@ Milvus:因为我确实没有做过这方面的东西,所以我可能需要问一些问题。你说这句话当中有 5 个词,你这 5 个词是怎么平均成一个句向量的呢?

Attendee C:5 个词的话实际上就是我先去词相应的模型里面拿到这 5 个词对应的词向量,然后把它相加起来,然后除以它的长度。

顾老师@ Milvus:长度就是 5 嘛。

Attendee C:对,但是他词向量的维度可能是种256或者是128这种。

顾老师@ Milvus:我大概知道你想说的意思了。这个确实是可以考虑的一个东西,就是说我们有一个用户在说做视频去重的时候,其实比如说这 120 个向量的话,其实你就不需要去做 120 次的搜索,你可以把这 120 个向量融合成视频,然后再用融合的向量去进行搜索,去判断,去进行去重的判断的依据。其实在这个过程当中就有点像你说的这种情况,必须要把多个向量融合成一个向量,然后再去做一个搜索。所以确实原来我们是没有太多的考虑这方面的因素的,但是既然有两个人都提到这个问题的话,我觉得我们就可以去研究一下,看看这是不是一个非常共同的需求,然后是不是可以把他做的一个更简单,更让大家无感的去融合这种向量,然后去进行搜索,确实这个也可以考虑去尝试的一个方向。

Attendee C:Ok,然后这是一个点,另外一个点的话,其实我还想问一下,实际上我们的向量都是动态更新的,但是对于我们情况而言的话,我实际上创建一个分区是一个 collection,然后我在 collection 里面创建我的 partition 或者说其他的东西。然后假设我现在有一个就是关于服务 A 的向量,然后我创建一个Collection A,但实际上在这一段时间内,我可能只是有一部分的增加或者删除,然后可能在一周之内我向量的模型是不会变化的,但是一周之后我的向量更新了,然后又相当于我需要重新把这部分新的相关数据同步到 Milvus,旧的 collection 和我的新 collection,对于实际结果而言,它是一个新的 collection,但是由于我们不能创建同名的 collection,所以就需要我重新建一个 collection,然后在建完之后再把它覆盖掉。我觉得这个过程看起来不是特别友好。

顾老师@ Milvus:我想一下,所以你们向量有多大?

Attendee C:我向量其实不大,我现在是百万的数据集。因为我们是 B2B 的对话系统,现在数据集都不是很大。

顾老师@ Milvus:我觉得也许可以做一些 partition,collection 里面可以建 partition,我觉得也许是可以把 partition 的标识属性作为一个这个数据的版本号去对应到的模型的,我相信你的模型应该也有一个版本号,当你每次变的时候,你也会给他一个新版本,所以我觉得你可以把舊模型的版本号作为 partition 的版本号放在里面,这样的话就比较容易去看说这是版本 12345 的模型改成的向量都放在 partition 12345 里,后面你再有 abcd 的版本的模型,就放在 abcd 分区里面,partition 里面我觉得可能是一个可行的方式。

Attendee C:Ok,这里就有一个问题,现在我模型更新了,但是实际上如果我不去手动 drop 的话,我在 collection A 里面,我 partition A 可能没有去删除,但是我这里有 B 了,我后面的相当于我模型越来越多,然后我的 partition 越来越多,我的 collection 越来越大,需要我手动去管理那些旧的 partition 对吧?

顾老师@ Milvus:对是的。

Attendee C:然后我原来的方案实际上是这样的,我会相当于给我的索引建两份,就是一个向量索引一,一个向量索引二,我第一次初始化的时候我只会初始化向量索引一,然后我搜的时候也是会去搜索向量索引一,但是每次我模型更新之后,我只会把新数据放到索引二里面,然后当我新的模型新的数据有了索引建完之后,我直接把 ab 互换一下,然后把这个清空,然后这样的话其实就是完成了原子操作了,不需要再去做太多的手动管理,不知道这个对你们有没有用。

顾老师@ Milvus:你这方式是一个比较常见的一个 A/B 的这种双份的日志也好,什么也好的一种切换的思路,是比较常见的操作。确实在版本的上面,我们其实现在是没有自动 drop 这种这种机制的,因为确实数据的话,一般的数据库里也很难去做自动的 drop,因为这个东西他比较难以判断他不发展机制,所以我们只能是提供命令给用户,然后你可以手动去触发,其实对你来说会比较自由一点。我主要是想问一下您平时的检索的并发度会大概是在什么量级上?QPS 之类的这种?

Attendee C:QPS 大概在几百左右,高峰的时候是 300 多。

顾老师@ Milvus:对于一个企业的独立的这种场景的话,应该还算是比较高的吧。

Attendee C:对,相对来说比较高。就是高峰其实际上每个月统计下来可能峰值也就 100 多,他们只有在企业活动的时候会有这个量级。

顾老师@ Milvus:好的,您刚才问的问题是什么?

Attendee C:我们现在其实所有的数据存储像这样,它一个是向量索引会落盘,另外的是向量的元数据也会落盘。对吧?其实我有一个问题是这样的,然后我们向量数据它实际上对某些企业或者某些产品它的变更比较频繁。实际上我就想问一下你们当初设计的时候,为什么会考虑把它就落盘?

顾老师@ Milvus:这个也是考虑到后续再要去修改索引的这种便利性,用户不需要再去重导。

Attendee C:但是我从实际上来看的话,大部分情况下你的索引的新加的频率不会很高,因为你太高的话,实际上是会影响你整个向量分布的。你到了一定程度的时候,你相应的模型一定是重新训练的,包括你导入数据,你的向量数据也一定要是重导的,否则你的结果会变得不是那么好。

顾老师@ Milvus:我觉得这个是要看场景的,有一些场景下可能在你的场景下他是这样的情况,但是在其他的用户那边确实它是只需要去我们提供向量召回的,我们是可以通过 ID 去获取向量的数据的,他会非常频繁的去做这个事情,而且他会觉得说他是要更快的速度去从 ID 拿到向量本身,所以确实在不同的用户场景下,它的需求是不太一样。

Attendee C:Ok,能理解,因为我看你们的设计有点像 LevelDB,存储的时候。

顾老师@ Milvus:对,都有一些参照。

Attendee C:其他的没有什么问题,再补充一个后续的发展是 roadmap 是怎么样的,是会尽量云化,还是说在一段时间内是以中间件形式存在的?然后包括分布式的解决方案,你们有没有做过实际测试和一些场景报告?

顾老师@ Milvus:首先从项目本身来讲的话,因为这是一个已经是一个基金会项目,所以他作为核心向量组件的形态,它会一直保留下去的其实。当然去做云化服务也好,这些当然是我们也是会陆陆续续做一些这样的尝试吧。然后还有一个问题是什么来着?对分布式的的,网站上是有 ann-benchmarks 的测试,当然那是针对单节点的, 那分布式的的部署我们的用户当中有一些,但是我们确实自己没有测过一些的信任的报告,这可能要等我们看看后续有没有。因为这个测试它还是需要配合一些环境去搞,我们可能得看一下后续看看怎么组织一个这样的环境,因为对我们来讲比较大的挑战是说如果要 ann-benchmarks 这些去测,它可能更多看重检索的性能,他整个的测试框架当中它没有并发度的概念,而且我们也没有一些这种这种业务的应用可以去做这种模拟去接进来。

所以这种端到端的这种更加在真实场景中的测试,确实是对我们来说是一个挑战。所以我们也是希望我们的用户再部署完之后可以给我们一些反馈,告诉我们他们的硬件的配置是什么样子的,他们是怎么部置的,然后他们的场景下大概是一个什么样的并发度,然后目前大概检索的时延可以达到什么一个程度。

因为其实整个搜索的速度它会受到很多因素的影响,在有的用户那边的话,因为场景不一样,它其实真的会差异挺大的。在如果我们是一个比较静态的场景下去搜索的话,他其实都可以把数据,就是搜索速度都很快,但是因为每个人的应用场景不一样,限制条件也不一样,他其实未必能发挥到理论的极限速度,所以也比较好奇问你看看你们这边的话,你现在搜索的速度大概是在这种百万量级大概是在什么样的速度上面?毫秒级吗?还是几十毫秒级呢?

Attendee C:我没有单独测过速度,我们整体的流程下来大概控制在 200 毫秒以内,其中包括向量检索,然后后续的前期的业务数据处理和后续的业务处理,是在这个级别里面,然后我们机器的话大概是现在的硬件配置应该是 16 套 48G 的。我们是双节点部署的。

然后我还有一个问题就是想问一下我们这边的那就是分布式的解决方案,实际上是提供了一个 proxy,对吧?然后中间 proxy 那一层做了一个数据的分发,然后比如说我可能有几千万个数据,然后我使用上哈希分片录入到不同机器上去存的,对吧?应该是这样的。然后我查的时候实际上也是到不同机器去查,然后最后在 proxy 里面再做个排序,然后取出 topK 是这样的对吧?

顾老师@ Milvus:现在应该是可以把文件均匀的分布到那些节点上面,然后你去搜的时候,其实你会搜这些节点上所有的数据,因为这就是每个文件中取出 topK,最后再做一次归并得到一个最终的答案,是这样的一个模式。

Attendee C:那我在 proxy 那层就不做了吗?

顾老师@ Milvus:不做什么?

Attendee C:我理解是这样的,比如说我现在是有 6 个节点,我有 300 万数据,如果是均匀分发的话,对于每个节点实际上是 50 万的数据。如果我要选 100 条的话,按照您刚才的意思,实际上是在 6 个节点里面分别选择 100 条。

顾老师@ Milvus:对,最后再做一次合并。

Attendee C:最终的结果可能到我中间代理的 proxy 里面就变成 600 条,但实际上我只需要 100 条。

顾老师@ Milvus:对,他会做一次合并。我说的合并就是说 600 条当中选出最终的 100 条。

Attendee C:ok 明白你的意思,懂了。其他没有问题了。


Attendee D:其实我关注这个 Milvus 很久了,从最开始可能 17 年 、18 年左右其实就有这样的需求,就有一个特征检索的需求特征,按相似度排序,然后那时候找遍了互联网也没有这样的一个解决方案,我们也自己想了一些办法,一些 GPU 的矩阵运算,但是这个问题带来的问题就是它是静态数据,在动态的更新上面,可能问题也比较大。在上面如果想解决这个问题,我们可能要在上面做一系列的分装,这个工作量相对来说还是比较大的,也没有说去做这一块。然后其实在去年年底差不多,我们关注到 Facebook 的 Faiss 那种系统,它在介绍里面其实也提到了这个系统,但这个系统的问题是其实学习成本挺高的。我大概看了一眼,它里面一些包括语言,其实语言这一块其实可能就卡了很多人,他就是一个底层的对接这一块,对外暴露可能也是 C 或 C++,然后其实也暂时搁置了。

然后在前一段时间应该是在机器之心还是哪推荐你们的 Milvus,我突然就看到了,后来发现跟我们的需求非常的符合,然后就深入研究了一下,目前的情况,我们算是在我们的线上,就是生产环境上面已经用上了,主要是在人脸的检索和视频,也是您刚才提到的视频的重复视频的一个去重,但我们这个可能也不是一个去重,去找相似的视频,目前来说运行的情况还是不错的。也有一些问题想跟你们请教一下。

顾老师@ Milvus:你请说。

Attendee D:我一直有一个疑惑,然后刚才我翻了一下你们的英文的文档,之前一直看中文文档其中有一个 IVF,就是索引 IVF_SQ8 中文文档那地方写对特征向量有一定的压缩,就把索引压缩成 2 字节,然后我当时看到这块一直很疑惑。我想正常来说应该是 4 个字节,然后看一下说压缩变成 8 个字节,这里非常疑惑。

顾老师@ Milvus:这个我们会去改一下。(会后文档已更新)

Attendee D:然后还有一个两个名称的问题,我也是比较好奇的。Milvus 它是有全称吗?

顾老师@ Milvus:全称您指的是什么?因为我们这个项目的名字就叫 Milvus。然后全称您指的是什么意思呢?

Attendee D:我想了解就是 Milvus 是某一个一长串的一个单词的首字母的缩写,还是说...?

顾老师@ Milvus:不是不是,它就是一种鸟的名字。

Attendee D:然后还有一个问题, FLAT 这也是一个名称的缩写?我在网上查的,包括 Faiss 里面我看了一眼也没有看到它的一个全称。

顾老师@ Milvus:你可以认为他啥都没有,就是没有索引,暴力检索这样子。

Attendee D:这个是有全称吗?我比较想了解他这个字面背后的意思。

顾老师@ Milvus:其实这个 FLAT 就是就是一个单词。英文当中我们一般讲 flat file,就是说这是一个很平的文件,就一个文本文件,就是没有做任何什么花式的这种索引,这种技术处理他就是非常平直的一个文本文件这样的这种感觉。

Attendee D:明白,那第二种索引方式 IVF?

顾老师@ Milvus:应该这样讲,IV 这个词的意思是 inverted。但为什么要叫 inverted 呢?其实这个东西是和 inverted list,这是一种倒排索引,它为什么叫倒排索引?就是它和索引本身是什么很有关系。因为其实最早的话,其实可以引用像 ElasticSearch 当中解释,倒排索引就是从值去找对象,其实最早的所以都是从对象去找值,其实最早的所以都是来自于一个比较古老的学科叫做图书管理学,就是你有好多书,你怎么去分配他们,你就会把他们分配成比如说文学,然后这个都是文学里面的书一排,然后那边是什么农业的一堆书。

但是其实你真正可能用户现在你去图书馆去检索的时候,你都是给了一些关键字,然后再从关键字链接到那些书,那关键字链接到书它可能在不同的分类里面,所以它其实相当于来说相对传统的索引来说它是一种倒过来的索引, 所以 inverted 其实主要就是这个意思。

Attendee D:明白了,在咱们的系统当中那个值就是不同的 ID。

顾老师@ Milvus:应该来讲就是说 inverted 在索引当中称为 inverted 的话,我个人认为它的个人含义应该是指我通过内容去获取对象,那么其实你在做向量搜索的时候,你搜索的向量其实就是你提取的图片当中的特征的内容,所以你也是通过内容去找对象,所以也是称之为这种 inverted 这种索引。

因为这个名词其实最早出现在 03 年的一篇论文,就是一个所谓他做的一件事情就是content base image retrieval,就是基于内容的图像获取。这些基于内容所谓的内容最终都被提取成了特征向量,所以向量本身就是图片的内容。所以从这个角度去理解的话,我觉得就是他为什么要把它叫做 invited list,倒排索引的原因。因为它也是基于内容去获取对象。

Attendee D:明白了。

顾老师@ Milvus:然后您刚才也提到了 Faiss,其实从 Milvus 最开始的时候,我们也是受到 Faiss 启发,然后基于 Faiss 来做整个向量搜索引擎,当然 Milvus 在这个 Faiss 当中也做了很多的改动,因为要引入数据管理的这个概念,改动了以后会越来越多。源于 Faiss,但是希望能做的比 Faiss 更加能帮到大家一点,能不能做的更好,但是希望能做的更容易被大家使用。所以我不知道您开发软件是用的 Java 吗?因为我们是做了一个 Java 的 SDK,也是因为很多人说 Faiss 没有 Java 的 SDK,然后我们就做了一个 Java 的 SDK。

Attendee D:没有,我们倒没有用 Java,用的全都是 Python。然后我们在实际使用的过程中用的是 IVFLAT,我当时选的是用索引在 400 万的一个特征库上面做的一个检索,大概需要 6 秒。你们觉得这个时间正常吗?

顾老师@ Milvus:这个肯定是不正常的。这个和你的其他的参数有关系我觉得。我记得之前时不时会有人来问关于性能的东西,确实我们应该给出一些更好的东西,去跟大家解释一个性能。因为首先分类聚类的 nlist 就不应该设的太大,然后文件每个文件的大小也尽量能够设得大一些,其实都会对于性能会有帮助。当然因为这个也跟你具体的场景有关系,因为有的人场景没有办法,流式进来的数据特别多,所以他没有办法等到太大的文件才去建索引,所以他文件就设的比如说 256 这样比较小,这确实因为文件数多了,他是会影响性能,但也不可能说 400 万需要 6 秒的这种级别,因为如果你去看我们的 ann-benchmarks 测试的话,但是那是一个比较理想的状态的测试,100 万的向量的检索差不多也就是在两三个毫秒这样的一个量级上。

Attendee D:对,所以这是一块比较奇怪。

顾老师@ Milvus:对,所以你可以看一下你的这些参数的设置,然后索引是不是建好了之类的,都可以先检查一下,包括内存的缓冲区的大小的设定等等。

Attendee D:目前来说我用的都是默认的除了 nlist。

顾老师@ Milvus:这个的话可能可能后续的看一下一些参数的配置,因为它这个时间是一个不太正常的时间。

Attendee D:因为我看到你们这个文档里面写的都是 IVF_SQ8 这个索引,IVFLAT 的速度能比 IVF_SQ8 慢大概几倍?

顾老师@ Milvus:几倍是不至于,但确实会慢一些。因为它的原理在于说,虽然 SQ8 的压缩,它会带来一些额外的操作,就是当你要把一个 8 bit 的整型展开成一个 32 维的浮点数,它会有一些额外的操作。但是在整个过程当中的话,其实去做向量搜索过程当中是 CPU 计算是一部分时间,然后你还有 I/O 传输,读取内存也是另一部分时间。其实当中最大的矛盾还是在读取那几个速度上面,但是当你对他进行压缩之后,虽然你有额外的计算量,但是你的 I/O 效率是大大的提高了。所以其实整体的它还是会快那么一点点的,但这个比例不太好讲,也不会说到达几倍这种状态。

Attendee D:明白了,我看了一下我们的线上的 nlist 用的是 16,000 多,这个数字是为什么?

顾老师@ Milvus:你可以调小一点,我觉得你可以试试 1024,2048 这些数字。

Attendee D:好的,我回头试一下。然后我还有一个问题是咱们在批量查询的时候,它的速度是比单个的查询速度是有提升的。

顾老师@ Milvus:这是因为它是一个批量的过程,所以他会节省一些开销,他可以并发的去做一些计算。

Attendee D:主要是在计算的时候做一个并发,明白了。因为我们的数据量比较大,然后每天都会有将近几十万的一个特征插入,然后而且查询的业务的产品的需求是需要按照时间来查,比如说几月几号到几月几号,然后我这边的一个实践方案是通过 partition,怎么叫分库,按照日期,按照每一天建 partition。

顾老师@ Milvus:给数据对做一些时间的标签,对是的。很多人都这样搞。

Attendee D:Ok 好的,在查询的时候,比如说按照近三天,我就把近三天的 collection name 给指定上,然后这么下去。然后一个是硬件的搭配问题,一个 CPU 和 GPU,然后我仔细看一下你们的文档,我自己得出的结论是不是最佳的方案,是在硬件允许的条件下, CPU 和 GPU 搭配着来使用,能够达到一个性能最好的一个结果?

顾老师@ Milvus:对是。因为你要建索引的话肯定是 GPU 会快一些,搜索的时候你可能会更多的用到 CPU,如果你两部分的资源都有的话,你动态键索引的时候就不太会影响搜索了。

Attendee D:明白,然后还有一个在查询量,因为我看到有个参数叫阈值,小于这个阈值的话,它就用 CPU 来检索,大于一个阈值的时候他就用 GPU这个是...

顾老师@ Milvus:这个其实是结合你自己的实际的情况来看的,因为 GPU 的话内存存显存的速度会比较慢一点,所以你一定要量足够大,它的优势才能体现。所以给大家一个机会可以去选择,要不然的话 CPU 占用时间也会变得非常的长。

Attendee D:那单用 GPU 来检索的话,他在不同的查询量上面,他的时间几乎是恒定的。这块主要原因是什么?

顾老师@ Milvus:因为 I/O 时间远远高于计算的时间,所以你去做大规模计算的话,你得先把数据传进去,传输的时间其实是占了 99.9%,可能就只有千分之1的时间是计算的。所以 GPU 算再快,其实你感觉不到的。

Attendee D:明白。IO 的时间是从内存...

顾老师@ Milvus:内存到显存

Attendee D:那有没有从磁盘到内存?

顾老师@ Milvus:没有。我们一般会我们目前都是常驻内存,但是用 GPU 的时候会在从内存里面进入到显存里面,所以传输时间是一个硬伤,对 GPU 来说是它现在最大的短板。

Attendee D:对,确实是我们在做有一些模型的推理,需要比如说这张图片需要从内存存到显存里面 ,这块其实是个挺长时间耗时比较久的。

顾老师@ Milvus:是的,这个就是英伟达最大的挑战。

Attendee D:还有两个问题,我的问题比较多,不好意思。然后还有一个我看到你们有一个 Milvus Admin 这个可视化的工具我觉得还是很好用的。但最近我在用的时候,可能是不知道是不是因为数据量过大,他在查询一些 collection 或者是 partition的时候,就直接没有响应了。显示超时。

顾老师@ Milvus:你可以把你的问题开在 GitHub 上,我们可以看一下。因为确实这部分可能是会因为可视化的组件的话,它确实测试是有一定的挑战的,因为我们可能测试环境当中并没有那么大的数据量,我不知道您在查看一个多大的 collection 的时候,碰到这类似的问题,你可以在给我们开的 issue 当中都描述一下吗?

Attendee D:好的。最后一个问题,在 arm 上面适配吗?

顾老师@ Milvus:Arm 上面的话,我们原来适配过一个英伟达的 Jetson Nano 那样的 Arm 芯片, 那是一个早期的版本可以跑的。后来其实对他们的需求似乎不是特别的明显,所以我们就没有再往后面去做了。当然如果说大家有需要 Arm 的,或者说需要 Arm 定制版的话, 都可以单独再联系我们。

Attendee D:好的,我们现在因为涉及到一些硬件国产化的问题,我们可以倾向于选用华为, 那华为的话服务器都是 Arm 的。我们就在上面做了一个编辑尝试,然后他没有通过。缺少一些应该是指令集一些相关的文件,所以就失败了。

顾老师@ Milvus:是的,他工具链、程式库、指定集可能都会不一样,所以这个是需要额外的适配工作的。

Attendee D:好的,我们有需求在群里边再跟你们请教。

Attendee C:我们现在的 SDK 包括 Python 版本的实际上都是 gRPC 的,我们这边会提供 restful 的吗?

顾老师@ Milvus:有,我们本身就有 HTTP 的接口。

Attendee C:没有,但是我看代码里只有 gRPC 的啊?所有的查询的操作其实都是 gRPC 的。

顾老师@ Milvus:可能我们的文档是不是..回头我们把文章链接发给您看一下。

Attendee C:第二个问题是我看代码里有个 web server, web server 应该就是 Admin 的 server 对吧?就是可视化工具的。

老金@ Milvus:这个问题我来回答,是这样的,首先 restful 接口的话,http 就已经提供了,就是你看到那个 web server 的东西。

Attendee C:但是我看 py 的 SDK 里没注意到,我再看一下。我再补充一点就是能不能根据一个是不同数量级,另外一个根据当前的测试配置,然后推荐一些建索引的时候的配置的参数,就推荐参数这种。

顾老师@ Milvus:确实我们是想做这个事情的,后续我们看看怎么把这个东西弄得更好一点,更友好一点给大家。因为我发现其实大家在这种性能问题,其实有很大的原因在这当中的。所以我们会去看一下怎么给大家一个更好的方式去理解这些东西吧。我们会补充在 http://Milvus.io 官网有一个叫 sizing 的页面,我们会补充在页面上。

Attendee C:好的,谢谢。

猜你喜欢

转载自www.cnblogs.com/linyuan123/p/12941980.html