导读:本文将分享淘宝个性化推荐场景中关于自适应和无监督的多场景建模的思考及实践。这项工作发表在2022年CIKM上(论文题目: Scenario-Adaptive and Self-Supervised Model for Multi-Scenario Personalized Recommendation)。文中将介绍多场景建模是如何细粒度地刻画全域场景和单场景的迁移关系来实现领域自适应,以及如何在多场景建模中引入无监督数据,还将介绍多场景建模在推荐召回阶段的落地实践。
01 背景介绍和方案动机
首先介绍多场景建模的业务背景、建模动机以及方案选型。本文将聚焦于推荐系统的多场景建模问题,这也是目前各个推荐系统普遍存在且亟待解决的问题。具体围绕 5 个问题进行介绍。
1. 问题一:什么是多场景
可以从业务视角和模型视角分别进行解释。从业务视角来看,“场景”可以简单地理解为推荐平台上不同的推荐入口或者推荐承载页面。举例来说,比如在广告领域中,相同的广告可以在不同的媒体端进行投放,同时又可以对应不同的投放形式,比如信息流形式的广告,或者开屏广告。在电商领域中,也会有非常丰富的推荐投放页面,以淘宝为例,有首页猜你喜欢的商品推荐界面、购物车内的推荐场景以及商品详情页上的相关推荐等场景。在内容推荐领域,比如我们的实际业务 -- 淘宝逛逛,推荐页面包含了一跳的双列展示场景,以及点击进入二跳后上下滑的沉浸式的无尽流的推荐等形式。在这些例子当中,每一个承载的页面都可以作为一个场景,而同样一个推荐平台也会有多种推荐场景,呈现出多场景的特点。
从模型建模的视角来看,多场景问题可以简单的定义为共享同样的特征空间和 label 空间,但是数据分布不同的多个数据集合。每一个推荐场景里记录的数据都可以构成对应的数据集合,尽管每个数据集合有不同的来源,但是他们的特征体系以及 label 空间是一致的。
2. 问题二:多场景的特点
第一点,流量重叠,从用户的角度出发,对于同一个用户,他在一个推荐产品或者一个推荐系统中是可以访问到不同的场景的,并且在多个场景中会留下相应的浏览、点击等一些交互行为。
第二点,供给重叠,不管是广告、商品还是内容的投放,都可以投放到不同场景并在不同场景展现。
第三点,场景间的分布差异,从行为模式上,同一个用户访问了多个不同的场景,而该用户在场景当中的行为可能是不一样的;同样的,从供给的角度看,对于同一个广告、商品或者内容,它在不同的场景上面的投放所展现出的曝光表现以及互动表现也是不一样的。因此在数据分布上,不同场景之间是存在差异的。因此, 我们现在面临的多场景推荐问题,集中体现了对场景共性和特性的刻画:用户可能具有可延续的兴趣,但在不同场景下的表现形式可能是不同的。
第四点,场景间的特征空间以及目标是一致的,不同场景之间更多反映的是在数据分布上的差异,而在特征体系上其实是相对一致的。另外,场景间的 label 空间是一样的,也就是说在多个场景之间建模的任务其实是相同的。比如在商品场景上建模点击的任务,或者是在内容场景上建模完播或者长播等类型的任务。
3. 问题三:多场景建模的目标
结合具体的业务背景,我们希望通过多场景问题的建模来重点实现以下两个方面的目标。
第一个是在效果上的目标,重点优化数据稀疏的问题。单一推荐场景通常面临用户行为数据比较稀疏的问题,而这种现象在一些小场景或者新场景上表现得尤其明显。多场景问题其中一个重要目标就是希望能够通过多个场景之间的信息共享去缓解数据稀疏的问题,提升所有场景的业务指标。
第二个是在迭代及运维成本上的目标,传统的优化方式是针对每一个场景分配专门的人员去维护并优化独立的模型,而当一些新的场景接入时,可能又需要重复整个接入流程以及模型训练过程。这样就相当于所有的人员分配、模型部署工作以及维护成本都是和场景的数量呈正相关的,这会导致整个维护成本以及迭代成本相对较高。
从实际成本上考虑,我们希望能够搭建统一的一套算法框架,同时服务到各个场景中,并且能够支持新场景的快速接入,这是我们想通过多场景建模达到的另一个目标。
另外需要强调的是,多场景问题和目前大家已知的多目标以及跨域问题是有区别的。多场景问题重点体现在共享相同的特征体系,拥有多个不同的数据源,并且有相同的目标。多目标是针对同一个数据源有多个不同的优化目标。而跨域问题通常是分成一个源域和一个目标域,一般是假设源域的数据量和效果都是较优的,然后通过源域来辅助提升目标域的效果。而多场景问题里每个场景并没有优劣关系,建模目标是希望提升所有场景的效果。
4. 问题四:多场景问题的相关解决方案
在实际应用落地的前期,针对这种多场景问题的建模我们对目前业界已有的方案进行了简单的分类,大致分成以下四种类型。
第一种是最直观的,也是目前很多业务实践落地选用的一个方案,即针对每个单独的场景,采用这些场景各自的数据去分别训练单独的模型,然后在上线部署以及预估时,每个场景会有单独的模型。这种方式可以在不同场景下选择目前业界已有的模型结构来进行建模。
当然这种方案也存在一些不足之处,主要集中在以下几点,第一点就是这种方式不能很好地解决单场景的数据稀疏问题,这是因为无法利用到同类型的其他场景的特征信息补充,尤其在一些数据量比较小,或者行为数据比较稀疏的场景上,数据稀疏问题更为突出。第二点之前提到,这种单场景单模型的建模方式在模型维护和迭代成本方面,对人力和资源的消耗都比较高。第三点就是当业务上有一些新场景接入时,也会存在成本较高的问题。
既然单场景单模型的方式存在样本稀疏的问题,那么第二种解决方案就是把所有场景的样本数据进行混合,用混合数据训练一个模型,然后将同一个模型部署到所有场景上。这种方式可以缓解第一类方案中的两个问题,因为这种方案用到了所有场景的样本,并且所有的场景共用同一个模型。然而它的不足之处体现在,这种比较粗暴的数据样本混合训练破坏了各个场景之间自身的数据分布,会引入一些噪声。另外,整体的模型效果可能会被其中某几个大场景的数据主导,从而影响到一些小场景的效果。
第三类解决方案是采用两阶段的训练方式,也就是先把所有的场景的样本进行混合训练,训练一个 base 模型,然后再用每个场景各自独立的样本对原来的 base 模型进行场景内微调。在模型的部署和预估上,同样是每个场景用各自场景数据微调之后的模型进行上线和预估。这种方式的不足之处是每个场景需要单独部署自己的模型。另外这种直接的预训练加微调的方式,也没有很好的去建模场景和场景之间的关联关系。
最后一类是目前业界主流的用来进行多场景建模的方式,通过借鉴多任务的学习架构,在模型结构上考虑各个场景的数据来进行联合建模,并且通过模型结构的设计来刻画场景之间的共性表达以及差异性的表达。近两年在业界有比较多的尝试和落地,比如 SAR-Net 通过类似 MMOE 的方式进行训练,STAR 则通过构建这种全局共享的网络以及每个场景特有的网络,通过模型参数之间矩阵映射的方式来实现这种场景差异性的刻画,以及其它通过动态参数网络的方式来刻画这种场景差异性的一些工作。
考虑到前三类方法的不足,我们选择了基于联合训练的方式展开后续工作。
5. 问题五:实际业务中多场景建模面临的挑战
而在我们实际的业务落地过程中,对于这种通过统一的模型来进行多场景的联合建模,我们也面临着一些更加具体的挑战,主要体现在以下几个方面。
挑战一:我们采用联合建模的方式,是希望能充分利用所有场景的信息来解决单场景的数据稀疏问题,其本质是希望把其他场景的有效信息迁移到指定场景中,尽管前面提到的一些方法通过参数矩阵运算或者动态参数网络等方式来刻画场景的共性和差异,但这些变换方式是相对隐性的,无法可解释地量化其他场景是否向指定场景迁移了信息,以及迁移了多少信息。因此, 如何实现精细化的有效场景信息迁移,是我们面临的第一个挑战。简单来说就是,怎么来建模是否要迁移信息,以及迁移多少信息。
挑战二:我们在模型训练的时候主要还是基于用户交互行为,比如商品点击或者视频完播这样的正反馈信号来构造正样本,也就是在有标签的样本数据上进行训练,这对于一些行为较少的场景会存在比较严重的数据稀疏问题。如果我们能够借助一些无监督的任务,将训练数据从有标签样本空间扩展到无标签样本空间,将有助于缓解数据稀疏的问题。
挑战三:我们都知道整个推荐链路分为召回、排序等几个核心阶段。在前期的调研中,我们发现针对多场景问题的联合建模,主要都是集中在了排序阶段,包括前面列出的一些模型,基本都是排序的模型。而召回作为整个推荐链路的第一阶段,面对的候选规模和检索方式和排序是有很大差别的。因此,如何把多场景联合建模如何在召回阶段进行落地也是我们面临的一个挑战。
02 场景自适应与无监督的多场景模型(SASS)
下面介绍一下我们在实际业务落地时的模型方案,这个模型简称为 SASS。这一方案主要聚焦于三个核心关键词,第一个是场景的自适应迁移(Scenario-Adaptive),第二个是无监督(Self-Supervised),第三个是针对召回任务的落地探索。
整体的模型框架包含了两个阶段,一个是预训练任务,另一个是微调任务。其中阶段一是在无标签的样本集合上构建一个无监督的预训练任务,通过对比学习来建模场景和场景之间的关系。另外,因为整个模型是在召回阶段落地,需要对 user 侧和 item 侧进行独立建模,因此在 user 侧和 item 侧我们进行了对称的结构设计。
第二个阶段是微调任务,会在第一阶段的基础上进行模型结构的复用,包括加载第一阶段预训练的 embedding 和网络结构参数。此外,第二阶段是在有标签的样本空间上训练一个召回的任务,然后输出 user 侧和 item 侧的表征向量。接下来具体介绍一下这两个阶段。
1. 阶段一:预训练任务
首先,在第一个阶段的预训练任务中,我们构建一个场景和场景之间的对比学习的无监督任务。如图右上角部分所示,大家应该对对比学习的经典训练范式都比较熟悉,同一个对象x通过两种不同的数据增强的方式得到两个不同的特征集合,然后通过特征的抽取网络及映射网络,最终得到同一个对象的两个不同的向量表达,随后就可以通过对比学习的度量 loss 来拉近这两个向量之间的表征距离,以此来实现无监督的预训练任务。
在对比学习思路的启发下,我们将多场景建模中场景和场景之间的对齐表达和对比学习的预训练任务进行了结合。前面提到了同一个用户可能会访问多个不同的场景,并且在不同的场景中有不同的交互行为,并留下一些和场景相关的统计信息。因此我们可以把这种用户在不同场景上面的行为差异视作一种天然的数据增强的方式,同一个用户的兴趣有延续性,但是他在不同的场景之间的表达可能存在一定的差别。然后我们在此基础上构建一个对比学习的无监督的任务。
从具体的模型看,如图左侧所示, 我们对不同的场景会构建一个统一的特征体系, 但特征的具体取值是和场景对应的,比如我们把用户的行为序列分场景拆开,用户在各自场景有对应的兴趣偏好等统计特征。通过这样的拆分方式,同一用户有场景相关的多个不同的特征值集合。比如图中同一个用户在场景 a 和场景 b 的特征,然后通过一个统一的表征网络(这个表征网络后面会介绍),我们可以得到同一用户在不同场景各自的表征向量,最后通过对比学习的 loss 来拉近两者的度量距离。
刚才说的是 user 侧的训练方式,在召回任务里 user 侧和 item 侧通常都是各自独立建模的。因此 item 侧也采用对称的结构和任务来训练,并且 user 侧和 item 侧是共享相同的 embedding 层的。具体来说,对于同一个 item,我们把 item 侧的特征取值也分场景拆分开,通过 item 侧的表征网络后,得到每个场景各自的向量表达,然后采用相同的对比学习 loss 进行训练。
在样本构造的时候我们有个特殊处理是,一个用户访问的场景可能大于 2 个,因此在构造对比学习的训练任务的时候,我们会对用户访问过的场景两两组合来构造出多条训练样本。同样在 item 侧也是通过这种两种组合的方式来构造出多条样本。
在具体的对比学习任务上,我们沿用了 InfoNCE 的 loss 形式来进行训练。
我们通过建模场景和场景之间对比学习的任务来实现多个场景之间对于无标签数据的预训练,接下来介绍整个模型框架里面比较重要的表征网络的设计细节。
模型中场景表征网络是一个多层的、场景的自适应的迁移网络。首先从整体模型结构上,在模型的 embedding 层是共享参数的。而这种表征网络从整体上可以分为几个组成部分,第一个是全场景共享的网络,也就是图中模型左侧的蓝色部分,这里的全局共享网络是所有场景的样本都会经过这里进行训练,可以看作是对 user 侧或者 item 侧所有的场景样本混合进行训练的表征结构。
第二部分是每一个场景各自特有的网络结构,也就是图中每个场景对应的灰色部分。每个场景对应的样本经过相应的网络来进行训练,由于每个场景的网络层参数是分开的,这种训练及表征就可以很好地刻画每个场景之间各自分布的差异性。另外在图中左下角部分,我们也引入了一个辅助的 bias 网络。这个 bias 网络的输入包括场景 id 以及某些场景所特有的特征,还有一些上下文的特征。这样可以在共有体系的基础上进一步刻画场景自身上下文之间的差异和 bias 信息。
在具体的训练过程中,每条样本通过统一的特征 embedding 层并进行拼接之后,会进入到全场景共享网络以及这条样本所对应的场景所特有的网络,进行前向传播以及反向传播的网络训练。
同时在整个网络结构当中全场景共享网络每一层的输出都会通过一个场景自适应的门控单元,把全场景的融合信息迁移到单场景上,以此来实现场景信息之间精细化的迁移。具体可以参考图中模型右上角的结构,该迁移结构重点包含一个 adaptive gate 和一个 update gate。其中 adaptive gate 的输出值用来控制全场景的信息中有多少是能够被迁移到单场景上面去的,而 update gate 的输出是控制从全场景网络迁移过来的信息和单场景原有的信息进行加权融合的权重值。这两个 gate 网络的输入包含了全场景网络的信息、单场景网络的信息以及场景自身 bias 的信息。通过这种精细化的、自适应的迁移结构去建模表征场景的迁移方向以及迁移信息量。我们将该迁移结构堆叠多层,最终每条样本都可以得到它在各自对应场景上面的一个向量表征。最后,每个场景各自的输出和对应的场景上 bias 的输出进行融合,得到它在对应的场景上最终的向量表达。
2. 阶段二:微调任务
第二阶段是微调任务。由于我们想将模型落地到推荐链路的召回阶段,因此微调任务和召回任务的目标是对齐的。在样本选择上,我们采用 user 点击的 item 作为正样本,通过随机采样的方式来构造负样本,然后通过构造三元组的方式来进行 pairwise loss 的计算,从而进行训练。
另外,在微调阶段我们会进行模型结构以及参数的复用,即我们会在微调阶段的模型结构上重新采用和预训练阶段相同的表征网络结构,并且会去加载预训练阶段的 embedding 层以及网络参数,相当于将第一阶段场景之间无监督训练的信息保留下来。
在微调阶段的 user 侧和 item 侧的度量匹配任务上面,我们也引入了一个新的辅助任务来帮助训练。前面提到每条样本在通过表征网络进行表征后可以得到两个向量表达,一个是每个单场景网络特有的向量输出,这个向量刻画了它在每个对应场景上面的独立的表达;另外一个是全局共享的向量输出,刻画了 user 特征或者 item 特征在全域上的表达。因此在整个的微调阶段的训练任务中包含了两个 loss,一个是单场景的网络所输出的 user embedding 以及 item embedding 之间训练的 loss;另外一个就是全场景网络对应输出的 user embedding 以及 item embedding 也可以通过这样一种计算方式得到另一个 loss,最后两个 loss 的加权和作为最终的 loss 进行训练。而引入全场景 loss 的辅助任务,相当于刻画同用户和 item 在全域的表达,尽管它的表达可能并不适配于各自场景的独立特征表达,但是如果把它加到一个全局的任务中训练后,对整体效果的收敛是有好处的,后面的实验分析也可以论证这一点。
接下来介绍一下如何去部署召回模型。在模型训练完成后,我们会把微调阶段的模型进行部署上线。在线上预估时,每个场景的信息会通过模型上对应场景的网络得到在该场景下的表征向量。
另外,在辅助任务中全场景网络的输出只在训练阶段使用,因为它是混合样本,可能存在一些噪声,然后在预估的时候,每个场景还是使用各自场景输出的那个特征向量。针对召回任务,在 item 侧我们会针对所有的候选去生成这个向量,之后去构造成相应的索引,再通过模型部署,在线预估的时候生成向量。随后通过向量检索获取到 topk 的结果,最后把结果返回给排序阶段,来进行整个推荐链路后续的一些操作。
03 实验分析和落地应用
接下来介绍一下利用该模型进行的一些实验分析和已经落地的应用。
我们是在两个开源数据集以及自身业务的工业数据集上面与其他方法进行了效果比较。
对比的方法主要分成三类,第一类是传统的单场景模型,因为我们关注的是一个召回任务,因此对比目前业界比较流行的一些召回方法,比如 YoutubeDNN、MIND、BST、DSSM 等。这些单场景模型都是用各自场景各自独立的样本来进行训练。第二类是用多个场景混合的样本进行训练,模型上仍然选用目前业界常用的单场景模型。第三类是业界已有的和我们提出的多场景联合建模的一些方法,其中一些方法是用在排序阶段,而针对在召回阶段的落地实践,为了更好地对比,我们对这些方法稍加改造——即取排序模型网络最后一层的输出作为一个表征向量去适配召回任务。
上表中最后两列是我们提出的模型,其中 SASS-Base 是不加预训练的模型结构,而 SASS 是增加了预训练阶段。由于我们验证的第二个数据集存在特征缺失问题,不能够支撑预训练任务,因此针对这个数据集我们重点比较了 SASS-Base 和其他方法的效果。
从多种类型的方法对比当中,我们得到了几个比较有价值的结论。第一点是采用混合样本训练的单场景模型在大多数情况下的效果反而不如单场景用自己单独的样本进行训练。这和我们前面论证及调研的结论是相符合的,即这种混合样本的方式可能会引入比较多的噪声,而且打破了每个场景原本的数据分布。但是对于一些数据特别稀疏的小场景,混合样本反而达到比较好的效果。因为对于这些场景,用本身稀疏的数据进行训练其实是很难学到有效信息的,采用这种混合样本的方式,虽然数据上面可能是有偏的,但能够通过样本量的增加带来一些收益和效果的提升。
第二个结论是通过多场景联合建模的方式训练得到的模型普遍优于前两类单场景的建模方法,我们提出的模型在不增加预训练任务,即 SASS-Base 模型结构上,在各个场景基本上也优于或者可以和其他多场景联合建模方式取得差不多的效果。而在叠加了预训练任务后,整体的效果有了进一步的提升。
后续我们又进行了一系列的消融实验,主要包括以下几个部分。
第一个是刻画全域场景到单场景上信息迁移的自适应的 gate 结构。我们对模型的 gate 网络上的结构和目前已有的其他类型的 gate 迁移方式进行了对比,包括(1)利用矩阵乘法映射的方式来实现信息迁移;(2)使用类似于 Simnet 这样两个特征进行加法、乘法以及拼接,然后通过 MLP 的方式来进行融合的这种迁移方式;(3)类似 MOE 这样的结构,通过 Sigmoid gate 来进行迁移的网络结构。最后从实际实验效果来看,我们这种自适应的方式能够取得不错的效果。
第二点是针对是否要增加预训练的任务以及不同的预训练任务类型对实验结果影响的对比。对比的预训练方式是通过用户的行为序列来对下一个视频或者下一个 item 预测的训练任务。经结果比较,可以证明增加了预训练的任务,并且通过这种场景和场景之间的对比学习可以提升模型的效果。
第三点是去论证模型结构设计中的辅助网络以及一个辅助任务。其中一个是我们在微调阶段引入了全局共享的网络,利用该网络输出的结果来进行辅助的微调训练,另外一个是在我们的网络结构设计中,针对每个场景的输出,去融合场景相关的 bias 特征的消融实验。实验结果也证明了这两个结构的添加对整体模型效果有一定的提升。
另外,由于我们的表征网络是一个多层的信息迁移结构,因此我们也对比了这种网络层数的增加对我们模型效果的提升。可以看到整体的趋势是随着网络层数的增加,模型效果是先提升然后再下降的。后续网络层数增加所引起的效果变差,我们分析可能是因为网络层数增加后整个参数量随之增加,会存在一些过拟合现象。另外在得到上层表征之后再进行这种大量的信息迁移,可能会使得单场景的表征更容易受到全场景信息的影响。因此这种多层网络结构的层数增加在一定程度上可以提升效果,但是网络层数并不一定越多越好。
下一组实验,我们针对召回任务对比了不同 item 侧的表征向量,因为在召回上每个场景都会生成各自的向量。在一些多场景建模时,user 侧会对应有各自不同的表达,但在 item 侧并没有详细地去刻画,而在我们的召回任务当中 user 侧和 item 侧对应的都是它在每个场景下各自独立的向量表达,因此我们也对比了每个场景对应的 item 表达以及场景共享的同一个 item 侧的 embedding。通过对比发现,在 item 侧同样能够区分开各个场景独立的向量表达。
最后我们将这个模型在一个实际的内容推荐场景上面进行了在线的 A/B 实验。在一些实验指标上取得了不错的效果,尤其在一些相对来说比较小或者数据比较稀疏的场景中,提升幅度更高一些。
目前我们提出的模型方案已经在淘宝的内容推荐场景,包括短视频、图文推荐等场景上完成推广,并且这个模型在各个场景都成为了主要的召回方式之一。
04 总结
最后进行一下总结。整体上,我们想要解决的问题就是推荐领域中的多场景建模的问题,这也是目前在推荐系统当中普遍存在的一个问题。而针对这种多场景建模,我们的核心目标是希望能够通过构建一套统一的框架最大化各个场景之间的信息使用。通过这种联合建模的方式解决数据稀疏问题,同时去提升各个场景的业务指标。并且通过同样的一套方法架构降低模型迭代以及部署的成本。
但是在我们的实际业务应用当中,多场景建模面临着三个核心挑战。第一个是如何实现精细化以及有效场景信息的迁移;另外在多场景建模里面怎样解决数据稀疏的问题,怎样去引入一些无标签数据;然后第三点就是多场景联合建模在召回阶段进行落地。
在我们的实践当中,通过去设计这种自适应的场景信息迁移的网络架构,以及构建场景和场景之间的对比学习的无监督任务,并且包括在模型结构设计、训练方式以及部署上去适配召回阶段的任务来解决上面的挑战。最后,这种场景自适应的无监督模型目前在全场景上较好地落地,并且是作为一个主要的召回方式。