以下文章来源于爱奇艺技术产品团队 ,作者爱奇艺推荐中台

图片

随着深度学习浪潮的兴起,embedding 技术快速发展。Embedding 自身表达能力的增强使得直接利用该技术生成推荐列表成了可行的选择。因此,利用 embedding 向量的相似性,将 embedding 作为推荐系统召回层的方案逐渐被推广开来。

在了解 embedding 生成的常用算法模型之余,对于推荐系统的实现而言,了解其工程化实践也非常重要,本文将介绍在线向量召回服务在爱奇艺的工程化实践。

背景综述:深度学习的兴起

推荐系统的架构已在多本书籍与多篇文章中被提及,而较为经典的流程描述之一如图1 所示。从图中我们可知,一个推荐服务包括几个模块:推荐池、用户画像、特征工程、召回、排序、策略等。整个推荐流程中,召回处于整个环节的第一环,它从整体内容池中圈定了一个子集,供推荐系统从中再择优吐出至用户面前。从这个角度而言,召回候选集的好坏,从很大程度上决定了推荐的整体好坏,召回的重要性也就不言而喻。

图片

图1. 推荐系统的技术架构示意图

对于召回而言,有不少耳熟能详的方法,常见模型对比如下。

模型优势不足
协同过滤简单直接、应用广泛泛化能力差,处理稀疏矩阵的能力也差,容易使得推荐结果的头部效应明显
矩阵分解相对于协同过滤而言,泛化能力和稀疏矩阵的处理能力有所加强除了用户历史行为数据,难以利用其它用户、物品特征有所加强以及上下文特征
LR将推荐问题转换成了类似CTR预测的二分类问题,能够融合多种类型的不同特征模型不具备特征组合能力,表达能力也较差
FM相比 LR 具备了二阶特征交叉能力由于组合爆炸问题的限制,不易扩展到三阶特征交叉
FFM相比FM 进一步加强了特征交叉能力训练开销较大
基于GBDT的组合模型使得特征工程模型化,具备了更高阶特征组合的能力模型更新所需的训练时长也较长
LS-PLM对样本进行了分片,在每个分片内部构建LR模型,使得模型结构类似三层神经网络相比于深度学习过于简单

我们可以看到,模型的不断更迭,都是为了能加强特征组合与选择,以及整体泛化能力的强化,而随着深度学习浪潮的兴起,这些问题又进一步被推进,深度学习可以使得模型同时具备记忆能力与泛化能力。

⚠️ 注:记忆能力可以理解为模型直接学习并利用历史数据中物品或者特征的共现频率的能力;泛化能力可以理解为模型传递特征的相关性,以及发掘稀疏甚至从未出现过的稀有特征与最终标签相关性的能力。

深度学习的流行与 embedding 技术的发展,使得 embedding 具备了综合信息的能力强、能将高维稀疏特征向量转换成低维稠密特征向量、能通过向量运算揭示内容及用户相似度等特点。embedding 本身也是极其重要的特征向量。embedding 自身表达能力的增强使得直接利用 embedding 生成推荐列表成了可行的选择。因此,利用 embedding 向量的相似性,将 embedding 作为推荐系统召回层的方案逐渐被推广开来。以下图2 是 YouTube 推荐利用 embedding 进行候选物品进行召回的做法。

图片

图2 YouTube 向量召回模型结构图

对于 embedding 的算法模型有很多,如对 embedding 具有奠基性意义的 Word2Vec,基于 Word2Vec 在推荐领域推广出来的 Item2Vec,亦有广义的 Item2Vec(如 DSSM 双塔模型),也有引入了更多结构信息的图嵌入技术的 graph embedding(如 DeepWalk,Node2vec,EGES等),其对应的实现也有较多论文与文章讲述,因此本文中我们对算法模型不再过多讲述,而是将焦点置于工程上如何能快速部署在线向量召回服务,并能让推荐引擎在线上高效访问,也就是图2 的工程化落地实现。

在线向量召回服务化实践

1. 效率是第一生产力

在业务开发中,作为工程师都知道,单一服务于某个业务与同时向多个业务服务,所要考虑的点是有较多不同的,后者需要更多的抽象与通用性,而这也是推荐中台要解决的问题,只有这样,才能提升服务搭建的效率,解放人力用于更多的业务思考当中,而不是重复工作。

在一个推荐系统的研发过程中,往往需要算法工程师与系统研发工程师的紧密协作,前者的职责是基于业务实现可用的算法模型,而后者的职责,一者是协同算法工程师将模型封装服务化,二者是开发推荐引擎及其它依赖子服务将整个推荐流程进行串联,供下游调用推荐接口,如图3 所示。

image.png

图3 推荐系统工程师的一般职责划分

如果我们基于图3,来看向量召回服务的接入过程,将会得到图4 的结果。算法工程师将基于业务特点,进行算法编写并产出 embedding,同时,系统研发工程师和算法工程师将协作搭建起在线的向量召回服务,供推荐引擎调用,推荐引擎负责线上所有用户的推荐,其对性能的要求是非常高的,因此向量召回服务的性能也极其重要。对于不同业务而言,如果向量召回服务没有通用化与服务化,则不同业务的算法与系统开发工程师各自需要重复搭建,且需要自行进行服务运维,这无疑是增加了推荐开发工程师的负担,也是对开发效率的损耗。

图片

图4 向量召回服务的接入过程

对于单业务支撑而言,我们只需考虑如何搭建起一个向量召回服务,从而能对海量 embedding 数据进行 top N 检索,同时保证服务的高性能即可。而对于推荐中台而言,在服务于多业务的情况下,需要在此基础之上再考虑如何将这个服务的搭建与运维简易化、自助化、自动化以及平台化。

2. 高维向量检索引擎选型

近似最近邻算法(ANN)目前是对海量高维向量求 TOPN 相似内容的主流算法。而 Facebook 实现的 C++ 库 faiss 也是经常被使用的 lib,基于 faiss去实现向量召回服务是一个选择。此外,业界常用的开发框架 vearch和 Milvus 数据库也是可选的服务之一,图5 是服务选型对比。

Milvus 数据库本身是为海量特征向量的近似最近邻搜索而设计,相比于 faiss 这样的算子库,其提供了完整的向量数据更新、索引与查询框架。Milvus 数据库也支持利用 GPU 进行索引加速与查询加速,可大幅提高单机性能。目前 Milvus 也已经得到了头部机器视觉公司的技术认可,技术社区氛围活跃。

vearch 是一个分布式向量搜索系统,可以用来计算向量相似度,能应用于图像识别、视频识别或自然语言处理等机器学习领域。vearch 也是基于 faiss实现,提供了快速的向量检索功能。其提供类似 elasticsearch 的 restful api,可以方便地对数据及表结构进行管理查询等工作。

image.png

图5 选型对比

自实现服务与开源框架的功能基本类似,且基本都是基于 C++ 实现。对于 0-1 的服务搭建,以及在充分借力社区效率的考量下,在已有的服务框架下进行开发是个不错的选择。在综合考虑各服务实现的 sdk 丰富度、性能指标、是否开源,开源社区是否活跃,再结合业务上推荐引擎使用 java 语言实现的比例越来越高,最终选用 Milvus 框架来实现在线向量召回服务。

3. 向量召回服务化具体实现

在构建在线向量召回服务时,我们考虑到算法同学经常会针对不同场景去调整算法实现,因此,只通过封装并内置某些 embedding 算法实现,会使算法同学产生束缚感。因此,我们设定了 embedding 模型的 schema,并当算法同学在推荐中台上创建了服务后,开放给算法同学一个指定路径供存放 embedding 模型,此后,在设置一些必要参数后,可在推荐中台上启动在线向量召回服务,并暴露出规范接口供推荐引擎调用。其具体设计如图6 所示,在向量检索引擎上,推荐中台与爱奇艺深度学习平台进行了合作共建。基于 Milvus 框架,我们进行上层应用构建,来降低推荐业务开发同学的搭建成本;支持数据版本管理,来提高业务侧稳定性;支持多机房部署与服务健康检测机制,提高底层容灾能力。

图片

图6 在线向量召回服务的整体架构

在使用过程中,我们也发现了一些问题。例如,Milvus 数据库在索引构建时 CPU 使用率会非常高,导致查询服务基本不可用,针对这个问题,我们也进行了解决,当我们进行数据版本更新时,我们会另起一个服务单独更新,而当更新完成时,会进行线上服务的替换,线上数据版本会保留最近 2 个版本。如图7 所示。

图片

图7 解决 Milvus 索引构建时 CPU 使用率过高问题

考虑到业务推荐引擎使用 java 语言实现的比例越来越高,而 Milvus 数据库的查询接口以 grpc 接口为主,因此,我们在其之上进行了 dubbo 接口的封装,便于 java 服务框架进行接入,这会在很大程度上简化服务的接入难度。通过 dubbo 服务发现,也实现了多机房部署对业务侧的无感知。

image.png

图8 向量召回服务的 dubbo 服务封装示意图

在此服务封装与实现下,业务同学要创建在线向量召回服务时可达到无门槛分钟级创建,且支持在线调试。在 Milvus(2核 6G)& dubbo 查询服务(4核 12G)88 实例下,对 600w 64 维数据进行查询,当查询 QPS 在 3k时,p99 延迟在 20ms 左右。而业务同学的接入流程亦如图9 所示,不需要再封装与搭建向量召回服务。

image.png

图9 向量召回服务化后的接入过程

在线推理召回一体化

在上述服务化实现中,做到了服务的通用化抽象,当在一个业务中,推荐系统开发人员要接入一个在线向量召回服务时,可以在平台上通用自助操作后,在分钟级就能获得一个服务并暴露一个通用接口供推荐引擎调用。但细心一点会发现(可以参考图9),在向量召回过程中,查询 query 的向量生成并没有包含到服务中,仍然在推荐引擎模块中。而 query 向量的生成方法,一种较为简单的方式为可根据业务特点通过规则或简单算法对已有相关 embedding 进行加权生成,另一种就是利用 embedding 生成模型,在提供输入特征后实时生成。显然,将 query 向量的生成包含在服务中,无论是对于解放业务同学而言,还是对于整体推荐服务构建效率提升而言,都是比较重要的。

在对整体方案与选型进行了再评估后,首先对于 0-1 的快速实现,选择成熟封装好的 ANN 服务性价比是比较高的,这也是最终选择 Milvus 框架的原因之一。而随着服务建设的持续推进,后续对性能、功能的优化速度与契合度有较多考量,类似于 YouTube DNN 这种在线向量召回,希望把推理与召回封装到一起,如果基于 Milvus 数据库会涉及到新功能的依赖以及与社区迭代计划的匹配,与现阶段的内部诉求不一定一致。另外在之前的实践过程中,我们发现 Milvus 还有一定的问题存在,当然 Milvus 社区也比较活跃,所存在的问题也在逐步解决。但在综合评估之后,我们决定联合爱奇艺深度学习平台,基于 hnsw lib 进行改造。之所以可以进行快速切换,主要原因有:

(1)爱奇艺深度学习平台对 hnsw lib 进行了封装,并产出了一套类似于Milvus 数据库的服务,并在快速迭代升级;

(2)基于 hnsw lib 封装的服务在索引创建时,服务依然可用,可以解决 Milvus 在索引创建时,cpu load 较高而查询不可用问题,也能简化整体设计;

(3)基于hnsw lib在实现类似YouTube DNN的在线推理召回一体化时相较于milvus较为便捷(我们应该是轮子的使用者,而不是重复造轮子的人,除非已无轮子可用);

(4)hnsw 的 ann 算法实现在效果上表现最好,如图10 是在 2020-07-12 在 fashion-mnist-784-euclidean 数据集上的测试结果,越往右越靠上代表效果越好;

(5)在图6 的设计过程中,我们基于 Milvus 数据库作为底层镜像向上构建应用,并在设计之初也保留了将来对其切换为其它服务框架的考虑,因此,对 Milvus 进行切换具有可行性。

image.png

图10 2020-07-12在fashion-mnist-784-euclidean数据集上的测试结果

为了将向量的在线推理部分纳入进来,我们需要将模型的训练部分进行接管,但考虑在实现上,算法工程师需要保留其自主修改算法的权利,因此在模型服务层面会支持其选用中台内置模型或使其按照中台定的规范去自实现算法。在原来的整体架构上进行一定调整后,在线推理及召回一体化的设计如图11 所示。

image.png

图11 在线向量推理召回一体化服务整体设计

在对整体方案进行调整后,向量召回服务的接入过程如图12所示,此时,推荐引擎内部不需要关心 query embedding 向量的生成实现过程,其只需提供需要的特征即可。

图片

图12 在线embedding推理召回一体化实现后的接入过程

总结与展望

本文已大致介绍了爱奇艺推荐中台关于在线向量召回服务的工程化实践过程。对于推荐中台,对服务进行通用化、平台化抽象,提升业务方服务构建效率,亦是提升业务迭代速度,协助业务方提升推荐效果的关键一环。

在线向量召回服务的工程化落地过程中,有一些关注点:

(1)底层检索引擎的选型,我们认为 Milvus 数据库与 vearch 各有优势,如milvus在SDK上较为丰富,在与不同语言的后端服务进行对接时有较好的优势,其活跃的社区也让其一些问题的解决更为快速。而 vearch 在 embedding 数据量巨大时(如 6亿条 128维向量数据)会更为适用,但在耗时上也会更高一些。

(2)服务性能和稳定性是重中之重,这是线上推荐引擎服务能否良好运作及推荐效果是否能得到提升的关键之一。

(3)将 query embedding 的推理过程与top N 的召回过程进行统一,能够为业务方接入得到最大提效。

(4)模型会更新,对应的 embedding 数据也会更新,因此服务需要考虑数据版本的管理,这也是业务诉求之一。

(5)考虑实时 embedding 内容的入库问题

当然,在向量召回服务还是可以继续进行不断优化的,例如:

(1)embedding 的生成算法有很多,可以考虑将业务上需要的生成模型不断内置化;

(2)在不同召回率的情况下,可以继续对高 QPS 下的响应性能进行优化。


Zilliz
154 声望829 粉丝

Vector database for Enterprise-grade AI