推荐系统里的“七伤拳”:那些高ROI但长期有损的优化
2025-7-20
| 2026-11-11
字数 3956阅读时长≈ 10 分钟
所谓七伤拳,“伤人七分、损己三分”,是易伤内息的邪门武学。我这里指的,是推荐系统里的那些高ROI,但是有着长期潜在危害的优化策略。这篇内容,可以用不同视角来看。推荐系统的贡献者,可以拿走冲一波业绩,但推荐系统的管理者,要充分权衡短期收益和长期潜在危害。
笛卡尔积特征。是把系统里原本的两个ID特征,组合成一个新的ID,创建独立的embedding,放进网络里。它来源于,基于大规模稀疏LR的特征工程,比如用户的年龄交叉物品的类别,有一个独立的ID组,代表某个年龄在类别上的偏好,到这里还算“正修”,后来呢,发现大规模稀疏化的LR有能力给这样的组合特征继续扩大规模,可以在本来已经稀疏的ID继续组合,如用户的TOP-N类目偏好交叉物品ID,甚至两个稀疏的ID交叉,比如最近点击过的N个商品和物品ID交叉。
这个做法,从LR时代被带到了NN里。大规模的稀疏化LR可以通过调节正则项,控制特征规模,NN可以依靠大规模的PS集群来硬抗。他的效果是一如既往的好,大家挑战说这个泛化能力弱,但是AB一做一个不吱声,几乎是百试百灵。有一段时间,我看任何业务里没有这个,加一下就能拿到一个大的AB收益。在 NN 阶段同样适用:即便基线已引入诸如 DCN 的特征交叉模块,继续对原始特征进行维度组合仍能带来增益。CAN的那篇论文,就是想出来一个dynamic的结构来替代掉笛卡尔积特征,但是ablation study显示,即便参数量已经很大了,在这个基础上再加笛卡尔积特征,依旧有增益。
他的缺点是,你的Embedding参数量会变得极大,占满了PS集群。会影响迭代效率,本来可能计算资源是瓶颈,现在存储也是瓶颈了。更长期的问题是它是一个GPU不友好的特征,对于GPU有一个概念叫计算强度,即每字节内存传输所能执行的算术操作数,就是你的GPU计算处以GPU的访存。Embedding Lookup 的算术强度极低,无论是通过CPU offload到内存还是SSD,或是通过PS网络IO。如果说GPU的Dense GEMM (矩阵乘法) 算术强度是10-50,Embedding lookup的算术强度只有 0.25,Cross‑ID Embedding的只有0.1,并且特征数量远超原始ID。它会直接把一个GPU的计算密集训练,变成访存密集型训练,导致GPU的利用率低下。
笛卡尔积特征在LR时代或CPU/小GPU的NN时代能带来准确率提升,但在 GPU 驱动的深度推荐系统中,却因 embedding 表规模爆炸、随机访问严重、批内异构、跨节点通信重、算存失衡等多重因素,极大削弱了 GPU 的计算优势。顺便说一句,我们最新的系统已经通过GPU上的模型优化,干掉了有笛卡尔积特征的强基线。
下面讲一个他的孪生兄弟,大规模的UID embedding。
早期曾在一个基于 MLP 的 NN 模型中加入 128 维的 UID embedding,但并未带来明显提升。但是却一直听到某司说UID有效,直到我亲眼看到它是怎么加的。一段上千维度的embedding,分成多段slice,分别和物品侧的各类ID进行隐式交叉。它和笛卡尔积特征一样,就是几行代码就完成,高ROI(效果/研发成本),但也是属于邪修,带来了所谓的万亿参数,几十TB的模型。
为啥讲它是笛卡尔积特征的孪生兄弟?在NN时代前,推荐系统排序模型有两个流派,一个是依赖手工特征的大规模稀疏化LR,一个是依赖大规模embedding的隐式交叉的FFM。他们各自把自己的“邪修”带到了NN时代。很多经历过16-18年艰难切NN的阶段,一段时间里切到MLP-base的NN模型是没有收益的,多半是因为基线里做满了特征工程,加上有笛卡尔积和大规模UID的FFM。
它的问题,和笛卡尔积一样。大规模的PS占用,拉低研发效率,且在未来基于GPU的推荐系统竞争中,会拖慢节奏,落于下风。
推荐系统里有一种邪门的做法,叫cascade(级联)模型,指的是在推荐系统多阶段中,学习后阶段打分或排序的模型。它用精排的排序top做正例,构建一路召回或粗排。可以说你AB的时候是非常有效的,如果你基线里有这种东西,用以用户反馈为GroundTruth的模型来替换它,何其艰难。
推荐系统里有两个常见的问题,一个叫链路一致性,一个叫data-loop(说严重点叫信息茧房)。Cascade模型,极致地解决了前者,收益很大程度来自这里。链路不一致有什么问题?你的召回模型认为好的,粗排认为很差,丢掉了,你粗排认为好的,精排认为很差,丢掉了,浪费了很多计算quota。现在让召回和粗排以精排马首是瞻,就解决了问题。
但是会产生严重的data-loop。原本你的系统的每一个模块,都在学习用户的反馈,现在两个模块学习精排的输出。先做一个比喻,一个面向用户的公司,它的基层中层应该从用户反馈中迭代APP呢,还是完全学习CEO的精神和指示,让CEO去理解用户。Cascade模型选择了后者,在推荐系统的局部构建了一个“一言堂”。原本系统是多源的,我们常常讲,召回要尽可能用更多的正例,一般来讲,排序模型样本基于场景的曝光样本,占整个用户行为的一部分比例,但是召回可以用100%的用户反馈。所以,召回认为好的,精排认为不好,是一种多源设计,只要精排让他有一定漏出的机会,精排就会从反馈中学习到,原来这样推荐是更好的。但是Cascade模型,损伤了精排模型的更新机会,它让被低估的永远被低估。
在实际系统中,若不加以限制,Cascade 召回会逐渐吞噬大部分配额。举个例子,上线时系统设置的召回权重也是10%,它占了10%的曝光,但是日复一日,你会发现设置没有变化,它的占比能涨到70-80%。即便你把它的权重设置为1%,依旧有50%的曝光占比。这是我真实经历的案例。
所以,我们的同学尝试Cascade的时候,拿到了很大的AB收益,即便如此,我们也开了一个长期大流量反转。长期反转表明,效果会逐步劣化。而无法AB的是,当你真的改变了基线,改变了你的曝光样本集合,为精排设置了一个天花板。反转并不能观察出这样的长期危害。
最后要讲的,会有一些争议,就是流式训练及它所强化的记忆性ID。它的有效在于你用一些极简的ID特征,通过隐式交叉,和流式持续学习,就能拿到很大的收益。机器学习有一个特征的完备性假设,未知的样本集合是可以泛化的,流式学习没有依赖这样的假设。批式训练也是天级或小时级增量的,流式训练的假设是在这一天之内会产生很多不曾发生过的模式,需要及时捕捉。
很多宣称流式训练及其有效的场景,忽略了特征完备性假设,通俗讲就是因为ID可以实时学习,就忽略了特征的构造和实时性优化。特征完备和流式并不矛盾,阿里的系统,默认是batch,很多系统是后面接入流式的,但是AB收益并不大,甚至普遍没有收益;某司的系统,默认是流式的,宣称流式是非常有效的。这里面有两个原因,阿里的系统是从LR演化来的,做了非常多的特征工程,比如大量秒级实时统计特征,来到NN后,也做了秒级实时行为序列,超长行为序列,它切流式就没有太大效果。某司的系统,从FFM演化来的,特征工程即模型里的手工隐式交叉,依赖训练产生新的模式捕捉,来到NN之后,一段时间也没有手工统计特征和非常实时的序列架构,那流式自然就非常有效。
除了基线特征完备性的原因外,场景的特性会影响流式的有效性。比如内容场景有大量的新增物品,流式就会更加有效,但依然不能在思维上对ID记忆性学习有盲目的依赖,通过秒级实时统计特征,秒级的用户行为序列和多模态特征,构建起特征的泛化性。流式虽然反馈快速,但是在不考虑额外处理delayed feedback的前提下,一般要从曝光后设置一个窗口,根据不同的行为收集比率,这个窗口从15分钟到1小时不等,比如电商等待转化label,直播等待关注label。流式的label并不足够实时,这也是实时特征永远能带来增益的原因。构建泛化特征,能避免对流式学习的过度依赖,避免long term的潜在损失。
举一个例子,某司的系统喜欢用一种“号称LTR”的模型,实际就是Cascade模型,这个Cascade模型大量依赖ID特征和隐式交叉,它的效果极其依赖流式,别说是断更,一点样本lag都会极大影响效果。我怎么知道的?当时给直播的粗排做优化,线上两个实验,一个是cascade模型的升级,一个是粗排MTL模型去ensemble基线的Cascade模型,我负责后者,实验日常是4-5个点的收益,突然有一天变成20个点,是系统故障了,模型样本堆积严重,Cascade基线崩跪了。到后面推全的时候,我发现收益跌到了2-3个点,仔细看才发现,他们这个推全的Cascade把资源从200多core开到了1200 core,做到了几乎0 lag。我想说的:流式有没有效果,有多大的效果,不只是挑场景,更是挑系统的设计。有的时候设计出了问题,某个特性才会特别有效;并且,不完备的系统设计,鲁棒性很差,需要非常好的工程架构来弥补。甚至很多时候lag产生的损失,完全无法监控。为什么系统故障都发生了lag,Cascade粗排崩溃了,我的MTL粗排模型没有问题,因为我做了大量的统计特征和实时行为序列,对lag不敏感。
之所以会觉得有争议,我经常听到一个说法,就是以流式为基线的同学,看到Batch系统会觉得,架构不够好,是上一代系统。我每次遇到这样的看法,会反驳一句,你觉得ChatGPT增加在线的流式训练,它的性能还会更好么?流量分发系统外,大多数的机器学习是批式训练,固化模型,依赖泛化性的。
我们的业务第一天就是流式系统。我们做了实时的统计特征和秒级的行为序列,以及多模态特征,最终把流式切到了Batch,效果无损。这么做有几个原因:1,批+流的系统需要两次排队,排批,排流,过于繁琐,远没有训练到最近一天,直接上线迭代效率高。2,我们对特征完备性有坚定的信仰,长期能带来潜在的鲁棒性收益。3,未来的系统设计要针对GPU大卡做算力优化,流式系统不利于长期的算力提升。
关于流和批在GPU未来算力上的设计,展开聊聊。第一,流式训练无法给 GPU 构建起充足的训练数据 pipeline,对GPU的高吞吐的利用带来障碍。第二,为了做到超长序列,避免和曝光产生大量平方级的重复存储,样本需要重新组织,做到list-wise,极致时甚至到天级user-wise,减少GPU的访问存带宽,提升算术强度,发挥出GPU的核心算力。由于流式依旧要做label的窗口等待,通过小时级Batch加Request-wise特征构造,是一个替代流式的高性价比的方案,它不会比流式慢多久,批式能发挥出GPU的算力,通过小时级构造User-Wise样本,提升GPU在长序列上的算力。
始终要坚持第一性原理,理解推荐系统和机器学习的本质,不盲从过去和外部的经验。那些从发展中长出来的“邪修”分支,需要被长期审视和修剪。公司笛卡尔积的潘多拉魔盒是我打开的,现在已经把它剔除了;大规模的UID我们想办法消灭掉;Cascade模型我们极力克制和拒绝;流式训练已经切回来Batch。前行不易,共勉,也欢迎加入。
  • 推荐系统
  • 思考
  • 时隔一年,贴一下当时的生成式推荐精读笔记记19年的生成式重排工作,才知道这个强化方法叫GRPO
    Loading...
    目录