本文约6500字,建议阅读13分钟
本文将介绍近年来推荐大模型的演进,以及其中一些重要的技术点。
[ 导读 ] 本文将介绍近年来推荐大模型的演进,以及其中一些重要的技术点(本文基于2022年底在DataFun的分享成文,仅代表当时的技术和业务情况)。
主要内容包括四大部分:
1. 微博推荐技术路线回顾
2. 推荐大模型技术近期迭代
3. 以增强链路表达一致性为目标
4. 其他技术点
01、技术路线回顾
1. 业务场景与特点
本团队在微博 APP 中负责的推荐业务主要包括:
① 首页推荐下的所有 tab 栏的内容,信息流产品一般都是第一个 tab 流量占比较高;
② 热搜向下滑进入的一个信息流,这也是我们的业务场景,也包括这个页面上的其他信息流 tab,比如视频频道等;
③ 在整个 APP 当中搜索或者点击推荐视频,进入的沉浸视频场景。
我们的业务具有如下一些特点:
(1)首先,从推荐实现的视角来看:
① 业务场景多;
② 微博 UI 上用户对操作和反馈多样,内容既可以点击进入正文页观看,也可以在流内消费,流内反馈多样如点进博主个人页、点进正文页、点图片、点视频、转评赞等;
③ 可分发的物料类型多,如首页推荐可分发长图、图片(一图或多图)、视频(横版或竖版视频)、 文章等。
(2)从产品定位角度来看:
① 服务热点:微博在热点爆发前后,流量变化特别大,用户能在推荐里面顺畅消费热点内容,是公司对推荐产品的要求;
② 构建关系:希望在推荐的微博里沉淀一些社交关系。
2. 技术选型
下图展示了我们这几年的技术进步脉络。
当前的推荐框架来讲千亿特征、万亿参数是标配。与 NLP 和 CV 不同,这两个方向太大的模型是网络本身复杂度高,推荐场景有较好的稀疏性,模型尺寸比较大,训练往往使用数据并行的方式,每个用户 serving 并不需要全部模型参数。
本团队从 2018 年至 2022 年的技术演进,主要是大规模和实时性两个方面。在此基础上再做复杂结构,来达到事半功倍的效果。
这里简要介绍一下我们的 Weidl 在线学习平台。
主要流程为:用户行为拼接样本,给模型来进行学习,再推荐给用户反馈回来,整体采用数据流优先的设计原则来达到更好的灵活性。无论使用什么方式训练 KERNEL,离线的模型存储和在线的 PS 之间的实时更新部分还是在的。不管是用手写的 LR 或 FM,或者 Tensorflow,或者 DeepRec 训练模型都是可以的,对应的模型存储都是我们自己搭建的一套数据流,模型格式也是我们自己做的,从而保证多 Backend 下从模型训练到线上更新能够在分钟级以下,下次用户调用时能用到新的参数。在这种设计原则下,可以很方便的切换 Backend。
Weidl 是微博自研机器学习平台,其中 Bridge 模式可以调用各个深度学习框架的算子,也可以不用 Bridge 模式,替换成自研算子也很方便。比如我们之前使用 Tensorflow,会对 tf 进行一些内存分配和算子的优化,2022 年下半年切换到 DeepRec,对 DeepRec 多一些了解之后,会发现之前基于 tf 的一些性能上的优化点和 DeepRec 是殊途同归的。
下图中列出了本团队这些年做的一些版本,方便大家理解我们业务中各个技术点的贡献度,首先是用基于 FM 的模型解决大规模实时推荐问题,后面依次做了基于深度的复杂结构。从结果来看,前面使用非深度模型解决在线实时问题带来的收益也很大。
信息流推荐与商品的推荐不同,信息流推荐基本都是大规模实时深度结构。这块也有一些难点和分歧点,比如:特征实时并不是模型实时的替代方案,对推荐系统来讲,模型学到的才是比较重要的;另外在线学习确实会带来一些迭代上的问题,但在绝对收益前,都是可以花时间克服的。
02、大模型近期技术迭代
这一章节会从目标、结构和特征几方面来介绍业务的迭代模型。
1. 多目标融合
微博场景用户操作很多,用户表达对 Item 的喜欢会有很多种行为,比如点击互动、时长、下拉等,每个目标都是要去建模预估,最后整体融合排序,这块对推荐业务来讲是很重要的。最开始做的时候,是通过静态融合加离线搜参来做,后来通过强化学习的方法,变成动态搜参,之后又做了一些融合公式优化,后面还改进成通过模型来输出一些融合分等。
强化调参的核心做法是,把线上流量分成一些小的流量池,通过一些线上当前的参数,去生成一些新的参数,去看用户对这些参数的反应,收集反馈进行迭代。其中比较核心的部分是 reward 的计算,其中用了 CEM、ES。后边用了自研的算法,以适应自身业务需求。因为在线学习变化是非常快的,参数要不能随之变化的话就会出现比较大的问题,比如大家对于视频类内容的偏好从周五晚上到周六早上和周日晚上到周一早上,偏好的变化是非常快的,整个融合参数的变化要反映出用户对一些东西的偏好的变化。
下面是模型优化中的一些小 trick,用户每天使用是带周期性的,每天定时 init 校正是比较好的,不然可能会走到比较偏的分支;参数初始化的时候要服从先验分布,先进行先验化分析,再去进行差异化融合;加入异常检测机制,保证融合参数能一致迭代更新。
融合公式一开始选用加法融合,当时业务目标还没有那么多,后来随着目标增多,发现加法融合不方便支持加更多的目标,会弱化各子目标的重要性影响,后边使用了乘法融合公式。效果如 ppt 所示:
在全量版本升级为多任务之后,在此版本上优化成,通过模型进行目标融合。通过模型融合,能更好地捕捉很多非线性的东西,具有更好的表达力,这样也能做到个性化融合,每个用户融出来的东西是不一样的。
2. 多任务
多任务是从 2019 年、2020 年开始火起来的一个概念,推荐系统往往需要同时关注多个目标,比如我们的业务场景里有七个目标:点击、时长、互动、完播、负反馈、进主页、下拉刷新等。对每个目标各训练一个模型会消耗较多的资源且繁琐。并且,有些目标是稀疏的,有些则相对稠密一些,如果分开单独做模型,那些比较稀疏的目标一般不容易学好,放在一起学习能解决稀疏目标学习的问题。
推荐多任务建模入门一般是从 MMOE 开始,到 SNR,再到 DMT,最后到全量的 MM,其实就是在 SNR 上做了融合网络等优化。
在做多任务之前,重点要解决的问题包括:多目标之间各个 loss 是否有冲突,彼此是否会有跷跷板效应;样本空间不一致的问题;loss 平衡问题等。在实际经验中,无论是 PCGrad,UWL 的方法在测试数据都会体现出其作用,但如果放大到生产环境中,去在线学习不断训练的话,这些方法的作用就会衰减的比较快,反而根据经验去设定一些值在整个在线实习环境中也不是不可行,这块也不太确定是不是跟在线学习相关,还是与样本量有关。单独做 MMOE 的效果也是比较好的,左边是业务上实际的一些收益点。
下面是从 MMOE 开始的一些技术演进。开始做多任务一般是做简单的硬连接,后面到 MMOE,再到 SNR 或者 PLE,这些都是近年来业界比较成熟的方法。本团队使用的是SNR,并且进行了两个优化。下图下半部分,最左边是 SNR 标准 paper 的做法,我们把 expert 内部的 transformation 进行了简化。同时会有独享的专家和共享的专家,这里会根据一些实际业务中反馈的数据结论的实际值与估计偏差进行一些分析,做一些单独的专家。
3. 多场景技术
我们所负责的推荐场景比较多,很自然想到使用一些多场景的技术。多任务是有些目标比较稀疏,多场景是因为场景有大有小,小场景收敛的没那么好,因为数据量不足,而大场景的收敛比较好,即使两个场景都差不多大,中间也会有一些涉及到知识迁移会对业务有收益,这也是最近比较热的方向,和多任务在技术上有很多相通的点。
基于每个多任务模型,都可以做多场景模型,相比于多任务结构,多加的是下图中的 Slot-gate 层,相同的 Embedding 通过 Slot-gate 针对不同的场景表达不同的作用。通过 Slot-gate 的输出可以分为三部分:连专家网络、连进目标任务,或者连特征。
主模型主要是用 SNR 替换 CGC,跟多任务的迭代是一脉相成的。下面是当前多任务和多场景混合在一起,在热点和热门两个内部业务场景下的应用。其中首页推荐为热门流,发现页推荐为热点流。
整体结构类似 SNR,上面为点击、互动和时长三个目标塔。其中这三个目标塔针对热门和热点两个场景,细分为六个目标。除外,增加了 Embeding transform layer,和 Slot-gate 不同的是,Slot-gate 是去找特征的重要性,而 Embeding transform layer 是考虑不同场景下 embedding 空间差异,去进行 embedding 映射。有些特征在两个场景中维度不同,通过 Embedding transform layer 进行转换。
4. 兴趣表征
兴趣表征是这些年提的比较多的技术,从阿里的 DIN 到 SIM、DMT,已经成为业界用户行为序列建模的主流。
一开始使用的 DIN,对不同行为,构建多个行为序列。引入 attention 机制给行为中不同物料予以不同权重,使用 local activation unit 来学习用户序列与当前候选排序物料的权重分布,实现了热门精排方案,并取得了一定的业务收益。
DMT 的核心是把 Transformer 用在 multitask 上,本团队使用了简化的 DMT 模型,移除了 bias 模块,替换 MMoE 为 SNR,上线后也取得一定的业务效果。
Multi-DIN 是将多个序列展开,将候选物料的 mid,tag,authorid 等作为 query,分别对每个序列单独做 attention 得到兴趣表征后,拼接其他特征进入多任务排序模型。
同时我们也做了实验发现,把序列拉的更长,比如将点击、时长、互动序列等,每个序列从 20 扩到 50,效果更好,与 paper 中结论一致,不过序列更长需要更多的算力成本。
用户生命周期超长序列建模和前面的长序列建模不同,不是通过请求特征就能拉到数据,而是离线构造用户的长行为序列特征;或者是通过一些搜索的方式,找到对应的特征再去生成 embedding;或者是将主模型和超长序列模型分开建模,最终形成 embedding 送入主模型中。
在微博业务中,超长序列的价值没有那么大,因为互联网上大家的关注点变化较快,比如热搜的东西,一两天就逐渐淡忘了,信息流中七天前的东西,分发就比较少了。因此太长的用户行为序列,对于预估用户对 item 的偏好价值会有一定程度的减弱。但对于低频或者说回流用户来说,这个结论一定程度上是不同的。
5. 特征
使用超大规模的模型,在特征层面也会有一些困扰。比如有的特征理论上觉得会对模型有帮助,但加入后的效果并不能达到预期,这也是推荐业务面临的现实情况。因为模型规模非常大,模型中加了特别多 id 类的信息,已经对一些用户偏好有了不错的表达,这时再加一些统计上的特征,可能就没那么好用,下面讲下本团队实践中比较好用的特征。
首先匹配特征效果都是比较不错的,用户对于单个物料、单个内容类型、单个发博者建立一些比较详细的统计数据,都能带来一些收益。
另外,多模态的特征也是比较有价值的,因为整个推荐模型是基于用户行为的,有一些低频、冷门的 Item 在整个系统中用户行为都是不足的,这时引入更多的先验知识能带来更多收益。多模态通过引入 NLP 等技术引入一批语义进来,对于低频和冷启动都是有帮助的。
本团队做了两种类型引入多模态特征的做法:第一种类型是把多模态 embedding 融合进推荐模型中,对底层这些 embedding 的梯度冻结,往上层的 MLP 再进行更新;另一种方法是利用多模态在进推荐模型之前先做聚类,把聚类的 id 扔进推荐的模型进行训练,这对于推荐模型来讲是更容易引进信息的方式,但也会丢失一些多模态具体的语义信息。
上面两种方式,在我们的业务中都做了较多尝试,第一种方法会带来模型复杂度的提升,需要做很多空间变换,找特征重要性等,但能带来不错的收益;第二种方法使用聚类 id 去学习,复杂度都在模型之外,线上服务也比较简单,效果也能达到 90% 左右,而且还可以对聚类 id 做一些统计性的特征,结合起来效果很好。
加入多模态特征后,收益比较大的是高质量的低曝光物料,能解决冷启动问题。推荐那些曝光比较少的物料,模型无法充分学习的,会很依赖多模态体带来更多信息,对业务生态也是有正向价值的。
Co-action 的动机是:尝试 deepfm、wide deep 等多种特征交叉方式无果, 怀疑是交叉特征与 DNN 部分共享 embedding 冲突导致。Co-action 相当于加了存储,单独开辟存储空间去做交叉,这里增加了表达空间,在业务中也拿到了不错的收益。
03、链路表达一致性
这部分是关于粗排和召回的内容。对于推荐业务来讲,虽然因为算力支持不了将几百万的候选集都用精排来排,而分成召回、粗排、精排几部分,但逻辑上是在讲同个问题。如下图举例,粗排是会做截断的,最终给到精排的内容只有 1000 左右,如果粗排和精排的表达差异较大,在截断的过程中很可能会把将来精排分比较高的内容截断掉。精排和粗排的特征、模型结构都不一样,粗排一般和召回的框架比较类似,是向量检索的近似结构,特征会交叉比较晚,出现和精排模型表达差异是很自然的情况。如果能提升一致性,也会促进业务指标上涨,因为两边能抓住同样的变化趋势。
下图展示了粗排一致性迭代过程中的技术脉络,上面是双塔的技术线,下面是 DNN 的技术线。由于双塔的特征交互较晚,所以加了很多双塔特征交叉的方式。但向量检索的方式天花板有点太低了,所以从 2022 年开始,会有 DNN 分支来做粗排,这对于工程架构的压力比较大,比如要做特征筛选,网络剪枝,性能优化等,而且一次性打分的条数也会较之前有减少,但打的分更好了,因此条数变少也是可以接受的。
DSSM-autowide 是基于双塔做了类似 Deep-FM 的交叉,带来了业务指标上的增幅,但下一个项目,换新的交叉方式,提升就没有那么显著了。
因此,我们觉得基于双塔能做出的收益是比较有限的。我们还尝试了基于双塔做的多任务粗排模型,但还是绕不过双塔问题。
基于上述问题,本团队对粗排模型进行优化,使用 DNN 和级联模型做 Stacking 架构。
级联模型可以用双塔先做一层筛选,筛选之后再过滤截断给粗排的 DNN 模型,相当于在粗排这里内部做了粗排和精排。换成 DNN 模型后,能支持更复杂的结构,更快拟合用户兴趣变化等。
级联在框架中起了比较重要的作用,如果没有级联模型的话,不太能从比较大的候选集中选出小候选集去给粗排的 DNN 来使用。级联中比较重要的是怎么构造样本,可以看下图。从百万级的物料库,召回几千粗排,给精排 1000 内的物料,最后曝光的是 20 条左右,用户有行为的是个位数条数,整体是从更大的库走到用户有行为的漏斗过程。在做级联的时候,核心点是每个部分都要进行一些采样,组成一些比较难的 pair 和比较简单的 pair,来给级联模型学习。
下图是级联优化和全局负采样带来的收益,这里不做详细介绍。
接下来介绍近期比较火热的因果推断。
我们使用因果推断的动机是,给用户推的东西,如果推所有人都喜欢的东西,用户点击效果也不错,但用户自己也有一些比较小众的兴趣,给用户推这些小众的物料,用户也比较喜欢。这两种东西对于用户来讲是一样的,但对平台来讲,能推出来更小众的东西是更个性化的,而模型更容易推出来的是第一种,因果推断就是来解决这种问题的。
具体的做法是去组 pairwise 样本对,对用户点击且流行度低的物料,和流行度高但用户未点击的物料,用贝叶斯的方法做 loss 训练模型。
在我们的实践中,因果推断在粗排和召回阶段来做比在精排做更容易获得收益。原因是精排模型比较复杂,精排已经有不错的个性化能力,但粗排和召回即使用了 DNN,也是裁剪的 DNN,整个模型的个性化能力还是有差距的,在个性化能力比较差的地方使用因果推断效果肯定比在个性化能力强的地方使用效果更明显。
04、其他技术点
1. 序列重排
重排是采用 beam-search 方法,设计结合 NEXT 下拉模型的 reward 函数,生成多种候选序列,选取最大收益的序列,扩量后效果不稳定,细节进一步优化中。
2. 图技术
图技术主要包括两部分:图数据库和图 embedding。对于推荐来讲,如果用图数据库,会更方便一些,成本更低。图 embedding 指的是游走类的节点随机游走,将图数据(通常为高维稠密的矩阵)映射为低维稠密向量的过程。图嵌入需要捕捉到图的拓扑结构,顶点与顶点的关系,以及其他的信息(如子图,连边等),在此不展开介绍。
推荐中可以用基于随机游走、图结构、图对比学习等算法,做用户与博文、用户与作者的互动/关注等召回。主流的方式还是把图文、用户等做成 embedding,给模型加特征,也有一些比较前沿的尝试方式,如直接做端到端网络,用 GNN 来做推荐。
下图是目前端到端的模型,目前我们还在尝试中,不是线上的主流量版本。
下图是基于图网络生成 embedding,右边的图是根据账号的领域算出的相似度。对于微博来讲, 根据关注关系算出 embedding 是有收益的。
05、问答环节
Q1:对推荐信息流很多 Item 只浏览不点击,是怎么区分是否感兴趣的呢?通过列表页上 Item 的停留时间吗?
A1:对的,信息流业务来讲话,时长是比较重要的优化指标。做时长的优化指标,不太方便直接优化用户今天整体在 APP 上停留多久,优化比较多的还是在 item 停留多久。不把时长当作优化目标来做,就比较容易推很多浅消费的内容。
Q2:训练发生 fail over 模型实时更新会有一致性问题吗?模型的一致性问题如何处理?
A2: 当前对于推荐的学习训练来讲,如果是 cpu 的话异步式的比较多,大家不太做成那种全局有个轮次,等轮次结束之后统一收集完,更新到 ps 上,再发起下轮次,因为性能问题,大家基本不会这样做。无论是不是实时、在线学习,都达不到强一致性。
如果你训练发生 fail over 的话,如果流式训练的话,是记录在数据流上,比如 kafka 或者是 flink 上,去记载你当前方案训练到哪的位置的,你的 ps 上也有你上次训练完的记录,也就跟全局的差异是差不多的。
Q3:请问召回使用精排的序会不会降低召回模型迭代上限?
A3:迭代上限姑且理解为召回的天花板,那我理解召回的天花板肯定不是要超越精排,举例来说,如果算力现在是无穷的话,那用精排打 500 万物料的分是不是对业务最好的处理方式。那召回在投入不那么大的情况下,尽量把精排觉得最好的部分给他找出来,比如说让他从召回里面那 6000 里面选出的 top15 和在 500 万的 top15 是比较接近的,召回模块做的就比较好了。如果大家这么理解的话,那召回使用精排的序不会降低迭代上线,反而是向着上限前进。不过这也是我们一家之言,大家根据自己的业务导向,可能结论不一定是放之四海而皆准的。
编辑:于腾凯
校对:王欣