rabbit-obsidian/Clippings/推荐算法介绍.md

23 KiB
Raw Permalink Blame History

关于这个分享

第一次AI分享交流会的时候大家建议首次的分享可以先从经典开始。所以我先制个经典把过去十余年推荐技术发展脉络跟大家梳理下介绍下主要工作、技术发展思想和规律。本次抛砖引玉以思想的穿针引线为主。后续算法团队会分享一些具体方向方法的更多细节。

       排序整体架构上分为:召回、粗排、精排/排序、重排几个阶段。本次分享聚焦在排序和召回两个方向。

业内推荐系统发展阶段

从大的技术变革的角度看,目前主要分成三个大阶段:

•        **传统机器学习技术(Before 2013年):**算法上采取LR和GBDT为主要算法交叉信息主要通过特征交叉实现工程框架较为简单模型训练依赖自定义的分布式训练框架。

•        **大规模离散DNN技术(20142025年?):**精彩的十年自从14年业界突破了大规模离散DNN的训练如何稳定收敛离散DNN以百分位AUC巨大提升很快成为业界主流技术框架。特征交叉方面人工交叉和模型交叉技术层出不穷自定义训练框架出现了homura、mio、abucus并在2016年到19年影响了一众互联网公司各家或多或少能看到上述框架的影子从16年阿里开始研究XDL开始以tensorflow+自定义的parameter server逐步成为主流解决方案各大公司纷纷拥有内部自定义的解决方案。携程在20年开始建设分布式大规模离散DNN训练和serving框架也属于tensorflow+自定义ps的技术路线。

•        **生成式推荐技术(2025年~?):**受大模型技术思想的影响,开始出现的技术趋势。得益于硬件发展和推理效率的提升,可以依赖模型强大的交叉能力来做模型交叉;并以端到端的解决方案,在挑战传统的级联式推荐架构。发展中的技术,方案还存在探索和发展。

为啥DNNLRGBDT在推荐里面有发展前途?

在本小节中,我们详细介绍对比下这三种模型设计。分类模型在推荐场景下最常见(比如点击率、转化率模型),分类模型要做的是找到决策边界来区分正负样本,如下图所示:

Figure 1: LRGBDT和DNN的决策边界

LRLogistic Regression逻辑回归

在LR里决策边界函数是线性的线性也决定了LR的白盒属性。在Figure 1公式中权重矩阵w和w(0)定义了决策边界的线性函数。模型的优点是我们可以通过模型的权重大小解释特征的重要性同时LR也支持离散特征和增量更新。模型的缺点是线性决策边界这个假设太强会让模型的精度变小另外模型的可扩展性程度低。

GBDTGradient Boosting Decision Tree梯度提升决策树

在GBDT中决策边界是非线性的模型通过将样本空间分而治之的方式来提高模型精度。在Figure 1的GBDT图中tree_i(∙)表示其中一棵树,α(i)是树的权重。这个模型的优点是树模型可以计算每个特征的重要性程度来获得一些可解释性同时模型比LR有更高的精度。模型的缺点是不支持大规模的离散模型不支持增量更新模型可扩展性程度低。

DNNDeep Neural Network深度神经网络

在DNN中决策边界是高度非线性的。在Figure 1的DNN图中g(i)表示模型的其中一层非线性层。我们知道计算机通过与或非这种简单的逻辑可以表达各种复杂的对象音频视频网页等。而DNN每一层网络比与或非逻辑更加复杂DNN通过多层神经元叠加成为一个万能函数逼近器在理想情况下只要有足够的数据量不论我们实际的决策边界如何复杂我们都可以通过DNN来表达。同时DNN支持大规模离散DNN支持增量更新支持根据业务场景进行灵活定制各种网络结构。这个模型的缺点是1特征经过不同层交叉交互耦合关系过于复杂而导致可解释性不好且MLP的交叉效率不高2在样本量比较稀疏的小场景存在过拟合的风险模型过于复杂反而导致此时不通用这时一般需要加入规则来进行约束和矫正3工程复杂度在我们用不同结构的时候所有不同。我们真实物理世界很多问题的决策边界应该是高度非线性的所以采取更符合物理世界的模型理论上限更高;再加上互联网世界海量的用户行为数据促成了DNN模型在业界的地位。

如下表格简单总结了各类酒店排序模型的特点:白盒模型虽然具有高可解释性,但精度较低,且精度到达一定程度时进一步提升的空间较小;黑盒模型精度提升明显,但可解释性难度也高。

点击图片可查看完整电子表格

推荐系统解决方案

虽然GBDT后来在xgboost、lightgbm这些经典算法出来后在很多中小推荐场景成为涨点的好帮手但在业内大规模推荐场景好景不长好不容易做上线很快就被连续DNN以及后续的离散DNN10年经典解决方案颠覆。但在这之前大规模离散LR在业内属于主流解决方案比如百度的ctr、阿里妈妈的广告模型。但不可否认gbdt是个好模型。

经典方法**-大规模离散LR**

特征分为连续特征和离散特征。连续特征属于统计特征典型例子身高、用户过去30天的点击率等。离散特征的例子userid、点击序列(itemid list、itemid。这两个特征各有特点

•        **连续特征:**可以直接作为模型输入使用,具备良好的泛化性。

•        **离散特征:**要通过embedding映射embedding size可以是1早期离散LR的weight可以看作embedding size=1才能给模型使用。离散特征命中就有没命中就没有具备良好的记忆型用户点击了酒店A、B和C在统计特征里面是点击3次在离散特征里面是记住了哪3次对连续特征用户点击【A、B、C】和点击【B、C、D】是一样的但是对离散特征而言用户点不同酒店列表结果是不一样的。

通过连续模型的泛化性叠加离散特征的记忆型是业界推荐算法常见设计在2014年的离散DNN落地的时候就有了。所以很难说google 2016年的wide & deep model创造了泛化性+记忆性模型范式。

正则和模型训练

LR模型容易过拟合在离散LR的场景下L1正则是常规手段。这样做有两个好处模型不过拟合了L1正则导致的稀疏性大幅度节省线上的存储和计算成本。但L1是不可导的只有subgradient这对依赖梯度下降法的算法是个问题。为了提升L1约束下的离散LR快速收敛业界主要采取的方法包括OWL-QN和Coordinate descent李沐老师在2012年百度的工作取名Darlin。该方法上线也是经过了一番折腾AUC提升2个千分点委实不容易后来李沐去CMU读PhD开启了开挂人生

线性模型的非线性努力

线性模型交叉能力为0线性决策边界的假定影响了模型精度上限。所以业界也出现了一些增加线性模型非线性能力的解决方案比如百度的Pegasus无paper、阿里的LS-PMLLarge-Scale Picece-wise Linear Model又称为Mixed LRFacebook的LR+GBDT广义线性模型Factorization Machine。前三个方法本质上都可以看作通过聚类的方法来对模型引入非线性而FM通过模型显式交叉的方式来引入非线性。

        这些方法都在努力突破线性模型的局限性,然而线性模型表达能力毕竟有限,况且他们一些方法是分为两阶段的,不是**端到端(算法发展追求端到端设计来减少信息折损,后面还有很多例子)**的学习方案。

大规模离散****DNN

连续DNN在业内存在时间也非常短我们直接进入2014年开启的全新解决方案。既然离散特征有很好的记忆型表达精准非线性DNN模型表达能力强那为啥不上来就整大规模离散DNN呢原因简单而复杂下面两个方面都未准备好

•        算法层面在2014年前业界LR还没有玩明白呢训练模式还是batch模式online learning这种streaming训练方法还在孕育。说到非线性模型连续版本的ANN、DNN也在摸索还在为落地实践踩坑好不容易模型收敛了取得了离线效果结果放到线上又被A/B效果怼回来分析原因。回头看坑真的非常多从参数初始化、学习方法、数据处理任何细节不到位都会导致最终失败。

•        工程层面大规模离散DNN这套技术栈回头看对工程要求也更高。首先工程需要提升线上线下一致性的工艺不然离散DNN会放大不一致让线上效果变差然后相比LR和GBDTDNN结构可改动的地方非常多所以在模型训练框架层面既要能支持万亿离散特征的扩展性又要能支持各类DNN结构的灵活性。Tensorflow是2015年开源pytorch是2017年才出稳定版即使到了18年这两个最大的开源训练框架对大规模离散DNN也支持的不好。

百度重视AI技术其实早在2012年的时候内部就有了paddle一个可扩展性的DNN训练框架并在13年开始逐步承接了凤巢广告模型的model inference。Paddle一直到16年才宣布开源不过这个闭源系统在14年的时候,代码保密工作做的相当不错,哪怕是对核心的凤巢算法团队也是一视同仁:丝毫没有主动接入当时国内最大的业务场景(只有少部分同学可以用Paddle调研连续DNN),做大做强的打算。推荐团队不能使用Paddle定制训练框架商业价值驱动下业务探索到了这个地步又有相关诉求又当如何呢

工欲善其事必先利其器

没办法的情况下一开始离散DNN训练框架在之前离散LR的框架上改了改先做个POC。不过这种显然不是长久之策离散LR框架要硬编码的地方比较多DNN网络结构变来变去又灵活总不能每次调个模型结构要动代码吧。于是有同学开始思考把不同类型的神经网络layer抽象出来把网络结构定义给配置化。

        适度内卷是有价值的从结果看当时一个凤巢团队2年内搓出来好几个DNN训练框架算法同学开发了homura、mio、elf三个框架后来工程团队在算法的mio的基础上改出来abacus。同一时间能配置驱动的DNN训练框架Caffe在2014年发布让大佬Yangqing Jia一战封神当然caffe不是为推荐场景设计的不支持当时还非常冷门的大规模离散DNN模型。

        目前说到的几个训练框架都是c++写的要定制化得动c++不是太灵活。Tensorflow在2015年已经开源了于是在2016年就有人想是不是可以把目前c++框架里面的Parameter Server单独拆出来集成到Tensorflow里面去这样不就又有了parameter server支持万亿离散特征的能力又有tensorflow的灵活性么。于是诞生了XDL项目。关于parameter server的核心思想大家可以参考下沐神的成名作Scaling distributed machine learning with the parameter server。后面业界基本上各大公司都采取了定制化的tensorflow方案。Pytorch没有抢到这个风头是因为tensorflow稳定、可靠的tf serving更适合做线上服务。

        我司技术栈主要是java的所以在2020年的时候我基于miniconda+cmake搭建了c++ toolchain经历过一番踩坑和折腾后在这个基础上构建了离散DNN训练框架并陆续开发了tensorflow 1.14和tensorflow 2.0定制版并和董锐团队一起构建了eagle推荐系统。目前线上公司全量的版本是tensorflow 1.14版本,不过动态图是未来趋势实际使用也会更加方便后续技术中心会推进tensorflow 2.0+版本的适配和落地。算法这边酒店排序是在21年后逐步切换到大规模离散DNN技术栈上去的第一个版本相对当时核心技术栈XGBOOST大幅度提升3个百分点

        简单说下大规模离散DNN训练框架的设计想法。其实简单说来就要解决一个问题推荐里面离散ID特征很大且不断自增和tensorflow looking up table是静态的设计之间的矛盾

•        量大:那就做分布式存储。

•        自增那就做分布式查询然后把每次batch用到的所有ID特征查询出来把结果包装成静态的looking up table给tensorflow用。

在这种思想下tensorflow本质上就是一个定义计算图和计算梯度的工具parameter server本质上是一个带梯度更新策略的“redis”。如果能把开发中_跟模型收敛碰到的各种坑给解决掉_就可以做出离散DNN模型训练框架了。如下面的简图

推荐算法的发展

经典的开端

经典的paper都在这个图上有兴趣的可以读下

基本上大家核心都要解决一个问题信息交叉的问题。我们上面提到MLP网络的交叉效率不是很高所以比较依赖显式的交叉设计来提升效果。当然在交叉这块业界主要是两个大的流派特征交叉模型交叉:

•        特征交叉依赖人工经验和设计可解释性强拿业务指标直接。缺点是过细的人工交叉会让系统特征数目爆炸比如item跟item的交叉提升了线上存储的代价。

•        模型交叉依赖模型结构设计写paper容易上面的经典paper都是模型方面的能够让交叉存储代价很低但会提升线上计算代价。好在现在算力越来越便宜了。

目前酒店推荐特征交叉模型交叉在提升模型精度上面的贡献大概是7:3开。PDD这种业务指标PK环境下也比较注重业务理解和特征设计。现在随着算法技术的发展类似transformer这种信息交叉结构也普遍应用在推荐系统中我们在酒店V8模型中就用到transformer来提升行为序列编码效果。在解决清楚信息交叉之后就可以针对具体业务场景的目标定义损失函数来训练模型了。

算法持续优化**-**案例一

用户行为序列包含用户所有的个性化信息,如何更好的做序列建模,是推荐算法重点研究方向。我们也可以通过这个案例看到算法迭代的一些规律:

•        DIN2018年是模型交叉方案的经典之作。用户历史上会有很多行为不是每个行为对当前物品推荐具备相同的权重。比如“鼠标”这个历史商品对预测“键盘”这个商品点击率的作用肯定大于T-shirt或者洗面奶。从模型角度来说在建模过程中给不同历史行为应该给予不同的“注意力”权重跟当前物品相似大的物品权重更大。

•        DIEN2019年当然上述建模忽略了行为的时间信息原则上离当前时间越近的历史行为应该更能表达出用户的兴趣迁移。用户行为兴趣迁移太常见了可能上周还想买衣服但是本周就想买电子产品了。所以DIEN在DIN的基础上引入了GRU这种网络来学习用户的行为偏好迁移。

•        SIM2020年上面的方法解决了部分问题实际上因为线上Serving性能的考虑我们的行为序列是做了长度截断的。然而离线调研会发现如果完全不考虑Serving性能尽可能多的用到用户行为序列对线上指标提升会有好处。但是历史行为又不是所有的行为都同等重要那么是不是就可以先根据当前商品来快速的找到相关的历史行为称为GSU-General Search Unit比如可以根据商品品类来快速筛选然后再在更小的集合上做DIEN的建模称为ESU-Exact Search Unit。是不是像极了现在的RAG-通过找到相关的信息,来减少算法的代价。

•        ETA2021年和SDIM2022年虽然前面的方法解决了部分问题但是GSU和ESU比毕竟是个两阶段的方法不是end-2-end的难以保障两个阶段的一致性所以研究更加端到端的方案就成了继续涨点的思路。如果能解决GSU阶段的性能问题不就可以让GSU和ESU保持端到端学习了么。所以快速根据向量计算相似度选Top-K的方法就可以考虑进来。于是在GSU阶段引入了LSH这种快速索引方法。

•        TWIN-12023年和TWIN-22024年虽然ETA和SDIM是end-2-end的但是GSU阶段采取了LSH毕竟跟ESU阶段要的attention还是不太一样。所以索性想办法让GSU采取跟ESU一样的结构并提升attention的计算效率。TWIN-2等后面分享召回的时候会看到一些思想端倪先别急。

从上面例子可以看到,端到端建模一直是算法提升效果的一个思路。之所以拆成多个阶段,受限于线上性能约束和技术发展阶段限制。

        既然一个小小的序列建模都要端到端那整个推荐系统分成召回、粗排、精排和重排是不是也可以端到端这就有了目前生成式推荐的一些尝试OneRec2025年、UniROM2025年、EGA-V2 2025年。当然end-2-end取代传统推荐架构代价比较高生成式推荐也不都是一上来就以这个为目标的有些设计是为了减少人工特征工程负担和利用最新的Transformer架构的强大交叉能力比如HSTU2024年、MTGR 2025年、RankGPT2025年

浅谈个性化召回**-**案例二

跟大家分享其中一个召回技术分支的发展历程给相关方向算法研究思路提供参考。Embedding目前已经为大家熟知了基于embedding的ANNApproximate Nearest Neighborhood检索算法LSH、Annoy、HNSW等也是家喻户晓。业界这块发展也是几经折腾

•        Word2Vec2013年这是NLP里面从语言序列里面学习每个word的经典方法。该方法可以把每个离散的词表达成Dense embedding向量使得相似语义的向量欧式距离更近。于是有人想用户行为序列其实也是一个序列丢进去是不是也可以得到每个行为Item的embedding表达线上通过embedding索引的方式来进行召回呢于是Item2Vec2016年有了Word2Vec在推荐场景的应用。KDD 2018年还有一篇airbnb的best paper基于这个传统方法做了细致的业务定制化Real-time Personalization using Embeddings for Search Ranking at Airbnb

•        DeepWalk2014年Word2vec这种方法是建立在序列样本上的互联网的用户和物品之间的关系其实是图结构。采取一个更符合物理规律的模型会有更好的效果于是有了DeepWalk在推荐领域的应用。可以参考Billion-scale Commodity Embedding for E-coimmerce Recommender in Alibaba这片文章。

•        Node2Vec2016年虽然DeepWalk解决图结构数据适配的问题但是不够灵活。图的遍历有两种方法DFS深度优先搜索和BFS广度优先搜索。通过DFS我们可以有机会游走到更远的节点让Embedding学习更加具备探索性专业术语是结构性通过BFS我们更多的在当前节点邻居进行游走可以让附近节点的embedding更加近似让推荐更准专业术语同质性。推荐系统对embedding的两个能力都想要最好有一个办法可以来取这个tradeoff于是有了Node2Vec。

•        EGES2018年当然前面的方法还是存在缺陷的在推荐场景下每个商品是有很多side information的。比如酒店有距离、星级、点评分数等等信息。如何DeepWalk的基础上引入这些side information就诞生了Enhanced Graph Embedding with Side Information这篇文章。

•        DSSM双塔模型2016年Word2vec这些方法虽然好用但是模型结构还是过于简单。Word2vec模型主要做法是以CBOW为例是把上下文序列Embedding求和计算跟当前Item的Embedding计算cosine相似度。如果把上下文Embedding和Item Embedding分别经过一个DNN网络然后再做cosine相似度不就可以增加模型的表达能力了么于是就有了DSSM。这个召回方法在2016年百度凤巢就上线并取得效果了。当然这里我们还要解决一个问题就是如何减少热门Item对embedding学习造成干扰不然每个item都会跟热门的item有相似的embedding表达Word2vec里面发明的针对hot word打压的采样策略都可以借鉴本质上是一样的。Facebook还有一篇文章专门来研究召回模型里面的负例采样问题。

•        TDM2018年双塔模型的用户侧和item测信息交叉只在最后一次层进行交叉的太晚了效果有折损且跟排序产生不一致了。但是召回模型为了提升线上服务效率又不能让用户侧和item侧在DNN底层交叉这样就没办法单独对Item的建立索引。于是有人思考能否想办法把索引的学习和主网络学习不是双塔结构了是一个DIN attention结构DNN底层做了模型交叉来一个co-training这便有了Tree-based Deep Model。线上Serving的时候通过索引树采取beam search的方法找到最相关的top-K个节点遍历到最后的叶子节点的Item即为召回集合。相关工作还包括字节的Deep Retrieval2020年和美团的Dual Augmented Two-tower2021年都可以值得研究下。

当然TDM复现的难度和线上落地的复杂度会比较高通常可以建议把DSSM双塔改成三塔增加一个浅层网络把重要的交叉特征放进来以提升效果。这是个比较实际的思路。

算法小结

当然实际业务会比上面经典方法面临的情况要复杂:我们的问题通常是多任务和多场景的,不同场景数据放在一起如何更高效的学习和表达;在推荐里面,很难避免长尾问题和冷启动问题,这部分数据不充分,很容易混在整体分布中让主流的偏好数据带偏,除了特征个性化之外,我们如何让模型本身具备一定的个性化;我们现在的学习方法是否已经足够稳定,在数值优化层面,有没有更多的技术细节突破,以带来更多效果的提升。上面的这些问题,业界都有同学在持续不断的探索。

       从业务应用层面讲,我们会面临不同的业务场景:广告推荐、游戏推荐、短视频推荐、社区内容推荐、电商推荐。因为不存在万能****“银弹,不同业务场景需要我们算法同学根据实际业务特点,因地制宜的制定模型方案,并设计合适的产品机制,让算法发挥更大作用。