让音乐伴随你左右-Milvus 在丸音的应用

✏️  作者介绍:

Jason,不亦乐乎科技算法工程师

陈室余,Zilliz 数据工程师

 

| 背景

丸音 APP 是一款基于 AI 音乐创作的音乐分享社区。我们希望通过丸音,让更多喜欢音乐的人能轻松地进行音乐创作,在丸音拥有属于你自己的音乐!

丸音的库中有用户上传的海量音乐。我们的首要任务是如何基于用户的历史行为,从海量音乐中筛选出用户感兴趣的音乐。关于推荐系统模型,我们考虑了最经典的基于用户的协同过滤(User-based CF)和基于项目的协同过滤(Item-based CF):

  • 基于用户的协同过滤:用相似统计的方法得到具有相似爱好或者兴趣的相邻用户。有了最近邻用户集合,就可以对目标用户的兴趣进行预测,产生推荐结果。

  • 基于项目的协同过滤:由亚马逊推出的 Item-to-Item (I2I) CF 推荐系统广为人知。该算法通过计算项目之间的相似性来代替计算用户之间的相似性,所依据的基本假设是 “能够引起用户兴趣的项目,必定与其之前评分高的项目相似”。

基于用户的协同过滤在用户总数较多的情况下会导致漫长的计算时间,同时考虑到产品特性,我们打算使用 I2I 实现音乐推荐。但由于目前并没有太多的歌曲信息,想做 I2I 只能从歌曲本身下手,所以需要通过一定手段提取歌曲特征向量。我们的做法是将歌曲转成梅尔频谱图;然后设计 CNN 网络来提取特征向量,作为歌曲的表征;最后通过查找相似向量来实现音乐推荐。

 

| 选择特征向量检索工具

有了特征向量,剩下的问题就是如何在海量特征向量中找到指定向量的相似结果。关于特征向量检索工具,我们想到了 Faiss 和 Milvus。Milvus 是 2019 年 11 月份在 GitHub 榜单刷到的,了解了一下项目,感觉像一个高阶 API(当时还是 0.5.x 版本,现在已发布了 0.10.2 版本)。

两款工具中其实我们更倾向于使用 Milvus。一方面因为之前用过 Faiss,这次想尝试点新东西。另一方面,Faiss 更 “底层” 一些,用起来相对麻烦。在进一步了解后,我们决定使用  Milvus,主要原因有两点:

  • 十分易用,只需要拉取 Docker 镜像,然后根据自身情况修改一些参数就可以运行了。

  • 支持的索引更多,关于索引使用方法有详细的文档。

总的来说,Milvus 对用户十分友好,官网的文档也相当详细。遇到问题先查文档基本都能解决,解决不了的可以在社区交流群请教。

 

| Milvus 集群服务

在决定使用 Milvus 特征向量检索引擎后,我们配置了单机服务在 DEV 环境运行。几天下来发现效果不错,打算提到 FAT 环境测试。又考虑到在生产环境中若单节点宕机了,那么服务也就不可用了,应该配置高可用的特征向量检索服务。

Milvus 提供了 Mishards 集群分片中间件,而且在配置方面,官方提供了 Milvus-Helm。我们只需要根据需求修改参数,然后打包部署到 Kubernetes 即可,所以部署 Milvus 集群的过程十分方便。关于 Mishards 的工作原理,可参考官方文档里的示意图:      

   

Mishards 工作原理图

Mishards 将上游过来的请求拆分,然后路由到子服务。子服务完成后,将各子服务查询结果汇总,返回给上游。其集群方案架构如下图:

关于 Mishards 的官方介绍很清晰,感兴趣的小伙伴可以查阅 Milvus 文档。

https://milvus.io/cn/docs/v0.10.2/mishards.md

在目前的音乐推荐服务中,我们基于 Milvus-Helm 部署了一个写节点、两个读节点和一个 Mishards 中间件实例到 Kubernetes,并且在 FAT 环境里运行了一段时间。服务稳定运行后已经在生产环境使用了,目前服务仍在正常运行。当然,美中不足的是目前只支持单写节点,相信后续官方会有更好的方案。

 

| I2I 音乐推荐

前面已经介绍了丸音的 I2I 音乐推荐系统从歌曲本身下手,首先会将用户上传的新歌做音轨分离,也就是把人声(Vocal)和伴奏(BGM)分开,提取伴奏中的特征向量作为该歌曲的表征(音轨分离也基本解决了翻唱过滤需求),然后将这些特征向量存入 Milvus,然后基于用户听过的歌在 Milvus 中召回相似歌曲,再经过排序和重排实现音乐推荐,具体实现流程如下图:

 

| 重复歌曲筛选

我们应用 Milvus 的另一个场景是重复歌曲筛选。有的用户会把同一首歌或者其片段上传多次,这些重复的歌可能会出现在某一用户的推荐列表里。若不去重就展现给用户,很可能会降低用户的听歌体验。因此我们需要找出哪些歌是同一首歌,然后对其做一些处理,以免同时出现在同一列表里。

我们的思路同样是通过筛选相似的歌曲特征向量来实现,首先对音乐做音轨分离,然后基于 Milvus 召回一定量级的相似歌曲。为了实现重复歌曲的精准筛选,我们会提取音乐的音频指纹(比如 Echoprint、Chromaprint 等技术),再对 Milvus 召回的歌曲进行音频指纹的一对一匹配,取一个阈值,相似度高于该阈值的则判为重复歌曲。音频指纹匹配这一过程可以让重复歌曲筛选更加准确,但也十分耗时,所以针对海量的音乐库筛选,我们选择先利用 Milvus 筛选出候选的重复歌曲。

 

| 总结

为了实现丸音对海量歌曲做 I2I 推荐,我们通过提取歌曲特征向量来表征歌曲。然后对相似向量进行召回,经过排序、重排后展现给用户。为实现实时召回推荐,我们使用了相较于 Faiss 更易用且更成熟的 Milvus 向量相似度检索引擎。并基于此思路实现了实时重复歌曲筛选,提升了业务效率。

你可以下载丸音,体验好“丸”的音乐:https://enjoymusic.ai/wanyin

 

参考资料:

1. Mishards 文档:

https://milvus.io/cn/docs/v0.10.2/mishards.md

2. Mishards: 

https://github.com/milvus-io/milvus/tree/master/shards

3. Milvus-Helm: 

https://github.com/milvus-io/milvus-helm/tree/master/charts/milvus

 

| 欢迎加入 Milvus 社区

github.com/milvus-io/milvus | 源码

milvus.io | 官网

milvusio.slack.com | Slack 社区

zhihu.com/org/zilliz-11/columns | 知乎

zilliz.blog.csdn.net | CSDN 博客

space.bilibili.com/478166626 | Bilibili