推荐系统中的双塔模型

Posted 爱好上班摸鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了推荐系统中的双塔模型相关的知识,希望对你有一定的参考价值。

本文纯属乱说,如有雷同纯属巧合。


双塔模型,我相信每一个推荐系统在迭代的长河中都它青睐过。因为它实在很简洁好用。


直截了当,上模型



如上图,不失一般性,考虑只有一个item(即N=1),便是一个双塔结构。简单描述:左边是用户侧的塔,输入用户侧特征;右边是物品侧的塔,输入物品侧特征。各自的塔经过若干fc layer后,进入到最上层,形成两侧k维(比如k=128)向量,两个向量经过内积计算后,再走sigmoid算子进行归一化。若用户点击了物品,label为1,否则label为0。


一、万物皆可embedding


双塔模型第一个可用之处便是可以对物品侧用向量进行表达。每一个item输入到模型右侧,在最上层可以形成一个k维的向量,作为这个物品的embedding。同样在用户侧,每一个用户输入到模型左侧,也可在最上层形成一个k维向量,作为用户的稠密表达。这些embedding可以刻画物品和物品之间,用户和用户之间,用户和物品的相似度。

更进一步,考虑以下现实场景:
一个公司有m个成熟的较大规模的信息流产品,有1个刚孵化的小规模信息流产品,为了扶持这个小产品,可以产生一个上图的多塔模型(N=m+1)。打通多个产品之间的特征体系,当用户a在产品k上进行了资讯的消费,那么这条样本将走用户侧的塔和物品侧第k个塔。最终会训练出一个有多个产品维度知识的模型。对用户a的向量刻画就包含了他在多个产品中的兴趣点。如果我们把该用户向量用到小产品的推荐系统,则用户a在大规模产品的兴趣点也将得以体现。

这些产生的用户向量和物品向量具体怎么使用在推荐系统呢?

  • 在召回层直接用向量做一路召回策略

  • 在排序层把向量间的相似度(cos距离等)作为特征

  • 把具有丰富知识的用户向量作为稠密特征送到模型


二、排序中的双塔模型


我们很多时候也会在粗排使用双塔模型。

为了方便叙述,考虑沉浸式视频场景。如果我们的目标为是否完播,那么完播,label为1,否则label为0。

对于双塔模型:
用户侧会输入一系列特征,比如用户id,用户基础属性(性别,年龄,城市,职业等等),用户历史消费(兴趣点概述,过去消费的视频序列)等等。

物品侧会输入一系列特征,比如视频id,视频标签,视频主题,视频封面信息,标题信息,视频背景音乐,视频的物理时长,视频在过去的平均播放时长,完成率等等。

两侧输入之后经过模型输入一个经过simoid之后的0到1的浮点数,再和label做交叉熵。


这里有两个问题点:
1、双塔模型为什么要在粗排使用,而不在精排使用。
       2、为什么粗排要使用双塔模型,而不使用更复杂的模型


对于问题1:

很大程度上一句话可以回答,双塔模型不够复杂,不太好使用交叉特征。

所谓交叉特征,便是用户和物品之间的交互特征。比如系统给我推荐的有一个候选视频是 “特朗普拒绝邀请拜登夫妇喝咖啡”,在模型判断这个视频要不要推给我时,如果模型有以下特征会更精准:我在过去对带有“特朗普”这个标签的一系列视频的播放时长和播放完成率,我在过去对带有“新闻”,“政治”这类主题的视频的播放时长和播放完成率。很显然这些都是交叉特征,这些特征同时含有我这个用户,和候选视频的交叉信息。

类似这样的特征应该放在哪呢,无论是放在用户侧还是物品侧都会很奇怪,会让双塔失去了纯粹性。

既然双塔无法使用交叉特征,问题2就来了,为什么我们还要在粗排使用双塔模型呢?


对于问题2:

一个字可以回答:快。(双塔的精髓)

这里的快指的是在对候选视频预测的时候,计算很快。前几篇文章我提到过,粗排要计算的候选视频量级是几千级别,我们要在很快的时间内完成计算,如果候选视频太多,模型就不能太复杂。那么双塔为什么计算很快呢。

(以下对新玩家高能)



先从离线说起,粗排一般是小时级更新模型。每个小时会把样本落进hdfs,训练平台会随之拉去数据喂给模型训练,模型训练好该小时数据后会进行一次模型导出。我们会把导出的模型进行上线投入到线上使用。


模型上线后,可以简单理解为模型已经分布式部署到一个服务A中。实际上我们每天可推荐的视频是有限的(在百万到千万级别的量级),所以会部署一个物品特征服务,这个服务会把视频库可推荐的每一个视频拿到对应的特征,去请求已经上线的模型。注意这里自然只对上图的item塔进行请求 (这就是双塔的好处,user和item是隔离的,此时不需要用户信息),然后拿到item塔最上层的128维向量。把这些向量缓存起来。

假设视频库有1kw个视频,我们就会缓存1kw个视频向量,轮循所有的视频假设需要30分钟。即我们会在半个小时完成对视频库所有视频的物品向量获取。

注意到,每个视频的特征都是随时在变的(比如视频a有一个特征是该视频在过去5个小时的平均播放完成率,在时刻1,该值是0.6,过了十分钟,这个视频又可能被很多人播放过,该值就变成0.5),那么每个视频的向量也是随时都在变的。 即同一个视频在此时请求模型获得的向量和在3分钟后请求模型获得的向量是不一样的(因为特征在变)。

基于上述这一点,我们30分钟完成所有视频的向量获取后,会循环进行操作,在下一个30分钟继续获得每一个视频的新的向量,覆盖掉上一轮的向量,缓存起来。这个过程会一天24小时不间断的进行,以保证存储的物品向量都是几乎实时的。

这些向量存起来做什么呢?

当用户a进行一刷后,在粗排层,我们拿到用户特征,然后去请求1次模型 (注意这里仅仅需要1次)获得用户向量,对于召回吐给粗排的候选视频,我们不必再去请求模型,直接根据视频id去查刚刚所述的缓存,拿到向量。然后用户和物品的向量做内积,从而获得打分。

架构图如下:


回看整个过程,当用户进行一刷时,仅仅请求了一次粗排模型(用户侧向量),物品侧每一个物品不必请求模型(请求模型是耗时的),直接拿物品id从缓存dcache中去查表获取(这是几乎不耗时的)。如果模型不是双塔模型,这里有多少个候选视频,就会请求多少次模型。这里双塔架构实际上就是依托了一个一天24小时不断在轮循计算物品向量的模块。


仔细理解了这个过程,就会发现事实上这也损失了一些精度。假设在时刻k,轮循的模块让物品a请求了模型,把物品向量缓存起来。理论上物品a的向量实时都在变,但我们缓存要在k+30min后才会更新向量。如果用户在时刻k到时刻k+30min之间刷一刷视频,此时粗排拿到的物品向量不是完全实时的,而是时刻k的向量,这里会有一小段时间的误差。

三、一些探讨问题

  • 前面提到“把具有丰富知识的用户向量作为稠密特征送到模型”,这里用户的embedding要怎么去和排序模型结合效果最好呢

  • 双塔结构怎么做多任务学习更合适呢







以上是关于推荐系统中的双塔模型的主要内容,如果未能解决你的问题,请参考以下文章

广告行业中那些趣事系列10:推荐系统中不得不说的DSSM双塔模型

推荐系统(十七)双塔模型:微软DSSM模型(Deep Structured Semantic Models)

推荐系统(十七)双塔模型:微软DSSM模型(Deep Structured Semantic Models)

推荐系统(十七)双塔模型:微软DSSM模型(Deep Structured Semantic Models)

推荐系统中不得不说的DSSM双塔模型

LDA主题模型和推荐系统1