本周二我们在线上与 Milvus 的朋友们进行了一场精彩的问答。我们也为不能参加的朋友们做了一个完整的文字实录。觉得字数多看起来很累的朋友们可以根据自己想了解的内容观看影片回放。[影片请看这里!]
也想加入我们的讨论吗?我们会定期在每周二 8:00PM 举办这个活动, 快与zilliz 小助手(微信:zilliz-tech)报名下周的活动, 或是扫描 QR 码直接报名!
Q&A 影片/文字实录
* 语音转文字可能会有些许差异,实际内容以影音为准
User 1: 你好, 我目前也在做特征检索这个东西,我想了解一下:你刚刚说的有个特征分析,然后你们近期会做一些混合查询的功能。你们将来会支持标准的 SQL 吗?
Milvus:标准的 SQL 这一块,因为我们现在在做 DSL 设计,所以我们可能会先去支持像是 ElasticSearch 那样的一种描述语言。SQL 这部分的话相对来说可能暂时会放在优先级比较低一点的顺序。我不知道在您的场景下面你现在是怎么做的呢?
User 1: 我们的话也计划做这个东西, 但可能会考虑结合其他有已有的数据库譬如 PostgreSQL 这些东西来改一下。
Milvus:那您这边的话也是做向量相似度搜索然后希望把它整合到一个关系型的数据库里是吗?
User 1: 是的。
Milvus:这部分的话其实在阿里云上他们有做这样的一个尝试,但是其实如果你仔细思考它向量数据背后的存储的和边缘计算的方式,和结构化数据的那种方式其还是差异挺大的。
因为在整个传统的结构化数据库当中他比较精华的部分可能是一个这种 B+ 树的索引, 然后基于 B+ 树的索引怎么去做这个 SQL 的优化器的访问路径的生成、优化,但在向量这部分其实都用不上,所以可复用的部分我感觉是比较少的。
User 1: 因为目前 PG(PostgreSQL)不是出了一个类似相似性检索的插件嘛,他们也就是为了推广 PG 做了一些类似于这样的索引。
Milvus:之前有一个叫 PG-ANN 的项目但是现在这项目好像感觉有点不怎么活跃, 当时做了时间也不长,所以这块的探索确实会有一些挑战。
User 1: 我看过咱们的代码,咱们是否没有用一些其他的存储引擎?
Milvus:是的,目前的话并没有用。因为数据库的存储引擎其实还是根据这种数据库本身的形式去做的存储引擎,像那些交易型的数据库他可能是按照页来组织它的数据文件做的存储引擎。还有像这种 KV 型的,那可能就是 KV 格式的。但向量其实会和他们的需求不太一样,向量有点像 KV 但又不那么像,因为我们在索引的时候比如聚类的索引,有的IVF索引其实是需要带一些聚类的信息在里面的。
所以这部分确实和目前已有的数据存储引擎会有比较大的差异。所以这部分确实是我们自己做的,但是底层承载这个数据文件的这部分,我们接下来的版本是希望对接到S3的存储当中。这样的话数据文件放在 S3 的存储上做高可用和分布式都会比较容易一些。
User 1: 有没有考虑过之后结合 HBase or HDFS 这样的数据库?
Milvus:HBase 的这块暂时还没有想过,因为可能场景会太一样。 因为像 HBase 和 HDFS 的话它都是一个一个数据块嘛,但是在一个向量检索的场景下面,
其实我们的文件你也可以把它说是一个数据块, 但是我们这个数据块它其实是会承载更多的信息的。首先他有聚类的信息,如果是 IVF 索引的话。然后呢,为了这个 IO 的效率和检索效率呢其实我们也是希望这个数据块能够尽可能的大一点, 那和 HDFS这部分考虑的因素可能就不太一样。HDFS 可能就是为一个文件分成若干块,然后每块可能要128MB大小分布在多个机器上面。那如果我们的文件这样分的话,在很多情况下可能我的这个聚类信息都是在最初的那个块上。
那很多情况下我一个文件都是希望在一起读的,如果要去到不同的节点上读的话,不同的节点载入不同的分片之后又没有那个聚类的信息,那就会比较尴尬。
User 1: 我们现在有一些业务场景, 譬如除了相似检索还有一些特征聚类的业务还有一些其他分类的业务。我们的特征已经存进去了,想把我们自己的聚类、分类这样的一些算子集成在这个项目(Milvus)里头,这个项目提供这些开放的接口吗?
Milvus:是这样的,就是说其实在我们现在的现有的用户端场景当中, Milvus 就是负责存向量特征这部分的;用户的应用和模型都是在上层自己去构建的, 在目前这个阶段。所以对于你们来讲的话也是一样的,你的算子也行你的应用也好都是在上层的,然后你把特征存到 Milvus 当中然后做一个索引和搜索加速就可以了。
User 1: 那目前只提供检索这一个功能?
Milvus:您是希望(比如说你有100万的向量)把这个向量建完索引后聚类的信息能够获得吗?
User 1: 是的,这些聚类的信息比如果动态的一些聚类,比如每天入10万的向量进去然后我就每天发就算是更新这样的一些算子,基本上就是存储,然后上面算子是一层也有检索的算子还有分类的一些算子。
Milvus:我大概明白你的意思,但是它的实现是这个样子:比如说原始的 FAISS 当中, 假定你有10万的数据先作预训练,他会预训练出一个大的分类, 那么你后续插入的数据那就是根据这个原来训练出来的大的分类然后把这个数据放在那里面。那么,这种情况你可以说你是做了一个分类也好或是聚类也好, 但是在我们的这种向量搜索引擎,因为提供向量就更进一步的向量数据管理的情况下,其实是这个样子:就说你这边假定有了100万条个向量过来,那可能这100万假定他们放在了同一个文件里面,那这100万条向量,他在这个文件里面他就是形成了一个比如说 IVF 的这个分类的结果。
明天你又来了100万条向量,它可能也在一个文件里面,那个文件又是单独的。另一个就是这个索引会训练另一套分类的结果,所以其实你不断的有新的东西进来,它们会新建新的索引文件,当它达到预值之后。所以在这种情况下,如果说你要去把它做聚类或分类的话,那你就需要在这个东西上面一层(业务层)你需要有个大的总体的分类指导的一个件, 比如说就这个东西过来它和最初的, 譬如说你有100个分类, 那和最初的100个分类去比较它和哪个最近。所以这个会有点不太一样。因为我们把流式更新进来的数据分成了若干个文件,然后每个文件的聚类信息都不一样,所以回给你的东西可能就不会是一个统一的一个东西。目前 Milvus 的定位就是一个比较基础的为 AI 服务的一个向量搜索引擎。
User 1: 在后期没有考虑集成更多的机器学习的算子?譬如 SVM,逻辑回归等。
Milvus:这一部分的话目前还没有计划放在里面。我们现在目前在做的一些集成有像是一些新的 ANN 算法。譬如,我们原本没有 HNSW 或是 ANNOY,我们后续会把他们集成进去。
User 1: Milvus 有的现有的应用场景?
Milvus:深度学习方面,比如说这种安防类的智慧城市、智慧零售,也有这种互联网的一些做SaaS平台的,做这种智能海报生成,它会有很多基础的图片的元素然后根据用户需求去搜索图片库,形成一个个性化的海报。还有一部分是做这个推荐系统的,就是给用户推荐一些视频、短视频这些场景, 还有一部分是自然语言处理方向。因为像大家现在可能比较多的用了这种 Bert 的模型,生成的也是这种高维的向量。在我们 Milvus 的网站上面我们还有一个化合物分子分析的 demo,那部分它不是一个 AI 的模型,它是一个基于规则的模型转换成一个特征向量,然后呢我们用这种计算谷本相似度。
User 2: 您刚才这边说你们的这个索引固件是文件分块之后重新训练码本,这样的话会不会存在说这个码本不统一?
Milvus:是的, 因为每个分片他都是重新训练的分类,所以其实每个文件当中的分类信息都不一样,那其实这样做呢它当然因为重新训练它会有一定的代价。当然如果 GPU 的话会很快。它的一个好处在于说他后续进来的数据分布如果和原来不一样的话其实不会造成太大的影响,因为像比如说我用20%的数据训练出来一个分类的话,那其实后续的数据可能和先前训练的数据的分布情况不一样,那就可能会出现在某一个聚类当中的数据特别多,那你索搜某些地方的时候时间的响应就会不太均衡。
像我们现在这种模式的好处就是, 后进来的数据反正它也都是重新训练的, 所以当我去索搜固定空间大小的时候,它的响应时间相对来说是比较一致的。
User 2: 我的想法是我们要不要就是采用这个分布式的结构然后对全局的数据加码本,这样的话码本是统一的,还有一个就是使用数据分部监控的方式会不会对精度会更好一些?
Milvus:先回答之前的第一个问题:如果假定我有两个节点,在两节点上共享这个码本,但其实还是没办法解决之前讲到的那个问题。就是你训练的集合你真实进来的, 它可能分布上是不一样的。它可能会出现一些分类的不均,造成性能波动, 这个其实问题无法避免。另外一种情况是像 Facebook 当中他做的那个用 FAISS 当集群的时候他是把, 比如说他分200个类好了,他弄个20台机器,2 台一组, 那每一组他去 host 200个类中的10%,比如20个类就在那个机器上面,那你新来的数据呢他根据你的所属的类的去插入到具体的某一组机器上面。
那其实这个也是一样的问题,就是当你后来的系数据他分布发生了比较显着的变化的时候,那你可能就是在这10组机器有一些可能特别的忙,存的向量数据特别的多,还是会造成问题。然后当在这种情况下我们如果对全局的所有的向量数据做一次重新的分类的训练的话,其实代价会比较大。这个就有点像传统数据库表当中你老往里面插数据,然后不停的删数据之后你的索引就乱了,就必须做一些全局的索引的重建,而这个是会造成一定时间的向量搜索服务的不可用。
所以也是因为这个原因,我们现在考虑下来的这种模式也算是一种权衡吧。FAISS 在他们论文当中讲的那种模式,可能就是20台机器,两台一组,每组分一些分类(以及其他方式)在理论上来讲它能够提供非常好的查询的性能,但是在实际实操的时候尤其当你不断数据进去的时候他的维护成本其实是比较比较大的。
第2个问题:统一码本的另一个挑战就像是传统数据库一样的,需要有个实时的统计信息然后定期去查看,因为这些比如说聚类型的索引它最基础的算法都是 K-means,那 K-means 的含义就是 K 个 means, 希望均匀分成 K 个类,所以就是如果是个统一码本就需要不停的去监控这些东西,然后一定确保说当这个数据在不同类当中的这个分布不均匀到一定程度的时候是需要去触发重新建索引、重新计算所有分类的这个操作。所以其实就个是这种监控它会给用户带来一个更更加容易的一种方式去发现潜在的性能问题。但是当你重建整个分类的时候所造成的这种维护成本和不可用的时间其实还是在那,只是当用户是有意识的去触发这个事情的时候,他可以放在一个相对来说业务低谷的时候,那不可用造成的影响可以降到比较小。
User 1: 现在这个系统的单机容量最大的多少?实测的单机容量
Milvus:是这样的,就是在我们自己的这个物理机上我们实测的一个最大的数据集是来自于sift-1b,它是128维的数据10亿条,那我们测试的机器那是一个 512G内存的一个双路的机器。但是通过我们因为在 IVF 索引中可以用一种 scalar quantization 转 SQ8 索引, 那它实际的内存消耗是在140G 左右。然后在我们一些实际部署的一些用户的产品下面因为他们是1024维的向量,基本上每一台做个千万上亿级的也是没有问题。就人脸的那种1024维的向量一般的这种512GB内存或256GB内存的机器支持到上亿条是没有问题。
User 3: 算子扩展怎么支持?
Milvus:如果是指 ANNS 的算子扩展的话那其实在我们的代码结构当中有一些说明。因为之前有一个做智慧零售的用户有问到说他们如果想增加一些我们现在还没有的索引应该怎么做。在我们 index 的相关目录下有一个开发的说明。如果您这边有兴趣的话的话会后我们把链接发给你, 我们也可以在群里交流。
欢迎加入Milvus社区
Milvus 源码
github.com/milvus-io/milvus
Milvus 官网
milvus.io
Milvus Slack 社区
milvusio.slack.com
© 2020 ZILLIZ™