多任务排序实验加速与长尾重排:推荐系统工程实践
1. 先说这两个信息在推荐系统里各自落在哪个环节
1.1 YouTube 多任务排序:排序模型在哪个链路位置
经常维护大型推荐系统的朋友,看到“YouTube 把多任务排序实验压到 11 天”这句话,第一反应大概率不是兴奋,而是条件反射地算一笔账:一个模型从加参训练到在线实验得出结论,以前怎么也得两到三周,凭什么能压到 11 天?结论是不是拿代理指标糊弄出来的?
这里要先对齐一下“多任务排序”到底指的是什么。在 YouTube 这种体量的推荐场景里,排序链路通常被拆成召回、粗排、精排、重排四层,多任务排序模型一般就是指精排阶段那个同时预测多个目标的模型,典型任务包括点击率、观看时长、互动率、完播率,甚至还包括“不喜欢”这类体验负向信号。它和单任务模型最大的差异是,模型输出不是一个分数,而是多个头的预测结果,最终再通过一个融合层或规则把这些分数加权合并成最终排序分。
这类模型做实验之所以难,不只是难在训练阶段,更难在评估阶段。因为一个模型同时影响多个目标,实验上线后往往会出现“点击涨了、时长没动”“时长涨了、次日留存掉了”这类错位现象。多个指标的置信区间要同时达到显著,比单指标实验严格得多,样本量需求成倍上涨。在过去的基础设施下,这类实验跑满三周甚至一个月都很正常,所以当论文里宣称压缩到 11 天时,背后真正被压缩的不只是实验天数,而是一整套从数据管道到决策规则的工程能力。
1.2 Spotify 重排:链路最后一公里在做什么
Spotify 这条信息的关键词是“重排”和“长尾”。如果把推荐链路理解成一条流水线,召回负责把候选集从百万级缩到几千条,精排负责给每条内容打一个相对精准的分数,那重排就是在最后一道工序里,精排已经算好的列表做整体调整。为什么要做整体调整,而不是直接把精排分数最高的若干条端出去?因为用户看的是一个列表,不是一盘散沙的单点结果。列表里如果全是相似的头部热门歌曲,第一两条可能很合口味,但整体体验会迅速疲劳,翻牌率、跳过率都会变差。
Spotify 的“兼顾长尾”在这里就非常典型了。音乐平台和电商、短视频有一点不同,它的供给生态高度依赖大量中腰部创作者的持续投入。如果重排完全按照用户个体偏好最大化来做,结果会迅速收敛到头部热门内容,长尾歌曲的曝光会越来越少,越少就越难被标签数据学习到,进一步加剧马太效应。所以论文里提到的重排,本质上是在最后一公里重新定义“什么是一个好结果”:不只是用户当下满意度高,还要在搜索结果里保持足够的新鲜感、探索空间和生态多样性。
这两件事放在一起看很有意思,一个在谈“结论怎么更快”,一个在谈“目标怎么更全”,但它们其实都指向同一个底层问题:模型从离线指标到在线收益之间的转化路径,到底要损耗多少、延迟多久,以及最终我们愿意为谁优化。
2. 11 天实验要解决的,是“多任务排序没法快速得出结论”的老问题
2.1 多任务模型哪里难?
多任务排序模型的训练难点,业内已经讨论得很多了,不外乎任务之间梯度冲突、样本量纲不一致、不同任务的信号强度差异大。但我这几年实际做下来,觉得最磨人的不是训练,而是评估。单任务模型做实验,看一个主指标变化就能拍板,多任务模型不行。比如我手里一个短视频推荐模型,同时预测点击、播完、点赞和负反馈,离线指标都涨了,上线后点击显著提升,但播完率掉了一个不显著的点,这时候到底要不要上线?不同团队会给出完全不同的答案,而为了把这个问题回答清楚,实验就得继续跑,跑的时间越长,结论越稳定,迭代速度就越慢。
另一个被低估的问题是“任务权重”在线上实验里很难直接观测。很多多任务模型最终排序分是各任务预估值的加权和,权重调了 0.1,点击和时长的平衡会发生多大变化?离线很难精确回答,只能靠线上实验。可线上实验又有自身的动态性:模型上线后会影响用户行为分布,用户行为分布又会影响后续训练数据,整个闭环需要时间才能收敛到稳态。这就是为什么很多团队默认多任务实验至少跑 14 天以上,低于一周的数据很难让人放心。
2.2 数学上怎么从 14 天压到 11 天
先把公式摆出来,A/B 实验单个指标的所需样本量可以简化为:
n = (z(1-α/2) + z(1-β))^2 * σ^2 / δ^2其中 α 是显著性水平,β 是检验功效,σ 是指标标准差,δ 是最小可检测效应。这个公式说明三件事:想把样本量降下来,要么窄置信区间,要么降方差,要么放宽最小可检测效应。
举例算一下。假设 σ=1.0,δ=0.1,α=0.05,β=0.2,那么 z 值分别是 1.96 和 0.84,样本量大约是每组 784。如果 σ 从 1.0 降到 0.8,样本量会变成约 502,压缩了 36%。如果再把最小可检测效应从 0.1 放宽到 0.2,甚至能把样本量压到 125。同时,如果采用序贯检验设计,允许在提前到达显著性边界时停止实验,那 14 天压到 11 天,从数学上看是可行的。
但这里要特别提醒一句:这不是“免费午餐”。降方差靠的是 CUPED、分层抽样、预实验协变量调整这些方法,它们需要高质量的用户级历史数据和稳定的指标口径。放宽最小可检测效应则意味着你可能放弃捕捉 0.1% 级别的小幅提升,只追求 0.2% 以上的确定性收益。对 YouTube 这种流量规模来说这是合理的取舍,但对中小团队来说,不能一概而论。
2.3 一个不能让步的前提:护栏指标
话又说回来,我可以接受主指标用更短的时间决策,但护栏指标绝对不能跟着一起压缩。所谓护栏指标,就是那些“不能因为本次实验而变差”的底线指标,比如长期留存、单用户日均使用时长、负反馈率、低质量内容消费占比。多任务实验经常会出现一个现象:短期代理指标涨得很好,长期质量指标悄悄跌了。
举个例子,我们把某个多任务模型里的“观看时长”权重调高,结果人均播放时长快速提升,但新的推荐策略开始偏向长视频,短视频和互动内容的消费量下降,次日留存刚开始看不出来,等到第 14 天、第 28 天可能才显出来。如果实验在第 11 天就拍板上线,这个尾巴就很难再接住。因此,我理解论文里的“11 天”并不是所有指标都只观察 11 天,而是主决策指标走快速通道,长期护栏指标继续保留延后监控,一旦发现异常需要立刻有回滚预案。这部分工程细节,往往是论文里一笔带过、恰恰是最值钱的部分。
3. 多任务排序实验压到 11 天的实操推演
3.1 离线阶段先过滤:不值得上在线的实验
先把一个现实说清楚:不是所有实验都配得上 11 天,更不是所有实验都配得上 10% 的线上流量。很多团队的问题不是实验太慢,而是实验太多,且大量实验在线下已经能看出“铁定不会赢”,还是要花两周上线验证一遍,白白浪费流量和时间。
所以压缩实验周期的第一步,应该是把离线评估的过滤作用发挥到极致。对多任务模型,我会要求离线至少同时看三类指标:各任务本身的指标变化、排序分融合后的 Top K 命中率变化、以及关键人群的切片变化。离线评估可以做到“把一个模型的收益区间缩到很小”,虽然不能替代在线实验,但可以把明显差的模型提前杀掉。比如新模型离线点击率预估的 AUC 掉了 0.002,观看时长预估掉了 0.003,这种模型根本不用占流量。
另外,如果团队的数据管道支持回放式评估,我强烈建议做“离线 replay”。简单说,就是把线上某段时间的真实请求日志重新跑一遍,把模型打出来的分数和线上实际曝光比较,模拟“如果当时用的是新模型,用户会看到什么”。这个方法的局限是不能完整模拟用户行为反馈,但对过滤掉那些排序质量明显下降的模型已经足够有用了。
3.2 在线实验设计的四板斧
到了在线阶段,真正能把实验周期压下来的,我总结为四件事。
第一件是方差缩减。最常用的是 CUPED,利用实验前一段时间的用户行为指标作为协变量,对实验期的指标做回归调整。比如用户实验前 7 天的消费时长,和实验期的消费时长相关性很高,用这个协变量能把个体差异解释掉一大块,指标方差能降 30% 到 50%,样本量需求随之显著下降。这相当于给每个用户去掉了“本来就是高活跃用户”的背景差异。
第二件是分层和分流复用。好的实验平台应该支持在同一层内做动态分层,让高、中、低活跃用户在各实验组里分布均衡,避免某组偶然分到更多重度用户。如果平台支持多实验共享流量池,还可以通过正交实验设计提升流量利用率,让多个实验并行不互相污染。
第三件是序贯检验。传统 A/B 是“固定样本量、到期一次性看结果”,序贯检验则允许在多个预设检查点计算边界,一旦效应足够明显就提前停止。Alpha 是逐步分配的,不会因为反复查看而膨胀。这套机制做得好,实验周期确实可以从“最坏情况”变成“平均情况”,很多显著实验在第 7 天到第 9 天就能停下。
第四件是代理指标的分层。多任务模型不是所有任务都能瞬间观测到稳定结果的,点击率可以分钟级观测,观看时长最好等 24 到 48 小时,留存类指标要等更久。合理的做法是把指标拆成快、中、慢三层,快层主决策,中层做纠偏,慢层做护栏,而不是把所有任务都盯着同一个窗口。
3.3 上线之后盯着什么
即使实验在第 11 天给出了“通过”的结论,上线也不是结束。我的习惯是把“实验通过”和“发布后观察”分成两件事。实验通过只代表模型在随机分组、有限时间段内没有出现显著负向,不代表它在全量流量上不会出问题。全量发布会带来更复杂的效果叠加、数据分布漂移、以及部分用户的适应期反馈。
所以上线后我会至少再盯 7 到 14 天,重点看三样东西:核心指标是否回落到实验期的水平、负反馈类指标有没有异常爬升、分层用户里的尾部群体有没有被明显牺牲。一旦发现异常,触发的是预置的回滚开关,而不是临时讨论要不要下线。这套“快速决策、慢速观察”的机制,比单纯把实验周期改成 11 天可靠得多。
4. Spotify 重排“兼顾长尾”:不是调参,是重定义目标
4.1 把“长尾生态价值”写进目标函数
Spotify 这种音乐推荐场景,长尾不是一个抽象概念,它直接对应一小批独立音乐人、刚上传半个月的新歌、以及某些小众流派的忠实听众。如果排序目标里完全没有长尾相关内容,模型学到的规律就是“热门内容更容易得到用户反馈,所以更值得推荐”,这是统计学上的自我实现,但长期看对平台生态是一种消耗。
和我以前见过的很多“后处理调参”不同,真正有效的长尾策略,是把“生态价值”直接写成重排阶段目标函数的一部分。简单表示:
final_score(i) = (1 - λ) * user_utility(i) + λ * ecosystem_value(i)其中 user_utility 是用户侧效用,比如点击和播放时长;ecosystem_value 是内容侧生态价值,比如新歌冷启动潜力、小众流派代表性、创作者历史流量欠公平程度。λ 不一定是固定常数,可以根据用户当前的探索意愿动态调整。比如用户已经连续听了很多首热门歌曲,下一轮的 λ 就可以临时调高,把更长尾的结果排上来。
这一写进目标函数,和单纯的“每页固定插一条冷门歌曲”有本质区别。后处理是规则,规则不懂用户,只追求指标表象;目标函数里的生态价值,会让模型学习到“在什么条件下长尾结果可能被用户接受”,推荐的是条件反射式的合理长尾,而不是机械地平均分配。
4.2 列表级重排的三个具体实现手法
具体到重排算法,业界常用的有三个层次:逐点评分、贪心序列生成、全局列表优化。长尾目标最好是放在后两个层次里实现。
第一个是经典的 MMR 思路,中文一般叫最大边际相关度。每次从候选列表里选下一个结果时,不仅看它自己的分数,还要看它和已选结果的相似度,如果相似度太高就减分。公式可以写成:
score(i) - λ * max(similarity(i, j)) (j ∈ 已选集合)这个办法实现简单,效果也稳定,适合作为长尾重排的第一版方案。缺点是它每次只考虑“下一个选谁”,是一个贪心过程,理论上不一定能拿到全局最优列表。
第二个是 DPP,行列式点过程。它通过一个半正定矩阵来度量候选集合内部的多样性,从中选择一个子集的概率与这个子集对应子矩阵的行列式成正比。它的优势是能在数学上同时考虑整组结果的多样性和相关度,避免贪心算法容易出现的“局部最优”问题。DPP 在工业界已经被不少团队验证过,主要瓶颈是矩阵分解的计算开销,但现在候选集控制在几百条的量级下,性能基本可以接受。
第三个是直接做列表级损失训练。重排模型不再给每条候选单独打分,而是把一个候选集合整体作为输入,输出一个最优排列的概率。训练时可以用 ListMLE 这类方法,用整个列表的排序损失来更新模型。这个方法最接近“全局最优”,但对训练数据和模型结构的要求也最高,适合已经有精排多任务模型沉淀的团队去试。
4.3 候选池和延迟怎么平衡
动手做长尾重排的人,很快会撞到一个现实约束:长尾内容在最开始召回阶段可能就被过滤掉了。重排只是在精排给它的几百条候选里做文章,如果这些候选全是头部热门内容,再怎么调重排目标也救不回来长尾。所以重排的“兼顾长尾”,必须和召回策略联动。
我的建议是,召回阶段就为长尾内容设置一个最低配额。比如每次召回的 1000 条里,强制要求来自新歌池和小众流派的结果至少占 10%,给重排留出可以操作的余地。这也意味着召回评估指标不能只看整体召回率,还要分长尾类目看召回率,否则上游一个“为了提整体精度而牺牲长尾”的改动,会把下游重排的努力全部清零。
至于延迟,重排阶段一般只处理几百条候选,即使使用 DPP 或列表级模型,也远没有精排那么大计算压力。但要注意别把重排模型设计得过度复杂。常见做法是给重排模型只输入已经算好的精排分数、内容类型、来源标签、用户近期交互历史这些紧凑特征,而不再重新过一遍大模型。重排本质上是做“最后的序列决策”,不是重新理解内容。
4.4 长尾效果怎么衡量
长尾重排上线后,建议建一套单独的评估维度。如果只看整体点击率,长尾的贡献很难体现,甚至可能因为被长尾挤掉了一些头部曝光而轻微下跌,这时候要区分“整体下跌”和“生态多样性提升”。
核心要看四类指标:长尾曝光占比,即长尾内容获得的曝光量在总曝光里的比例;长尾消费效率,即长尾内容的点击和播放转化是否达到可接受底线;推荐列表多样性,比如风格相似度、创作者重片区占比;以及用户体验满意度有没有因为长尾增加而下降。把这个放进表格就是:
| 维度 | 指标举例 | 重点关注 |
|---|---|---|
| 长尾供给 | 长尾曝光占比、新歌覆盖数 | 不能只看总量,要看是否有持续“上新” |
| 长尾消费 | 长尾点击率、播放完成度 | 曝光了但不消费,说明推荐匹配度不够 |
| 列表多样性 | 风格熵、创作者重片区占比 | 避免“伪长尾”:小众类别重复推一个 |
| 用户满意度 | 跳过率、负反馈率、次日留存 | 这是护栏,长尾不得以牺牲满意度为代价 |
我自己在项目里会特别留意一个现象:长尾曝光占比提升很轻松,难的是同时保住长尾消费效率。如果平台出现大量“长尾曝光,但用户只看两秒就划走”,那就说明长尾匹配做得太粗糙,不是在建立生态多样性,而是在制造用户对推荐的不信任。
5. 落地中我踩过的坑,以及一张排查表
5.1 短实验周期最容易翻车的三件事
第一件事,是没有预注册就过早看结果。有些同事拿到 11 天快速实验方案后,每天盯着实验看板,第三天看到“点击率显著提升”就想截单跑路。这完全是把序贯检验用成了 “看到显著就停”,alpha 膨胀会很严重,假阳性概率被放大。正确做法是,实验开始前就定好检查点和停止边界,中途查看只是为了监控异常,不是为了做决策。
第二件事,是为了追求速度把主指标换成高波动代理指标。比如用“首屏曝光点击率”替代“完整会话消费时长”,前者确实快,但噪音很大,且容易被列表首图质量干扰,不能反映真实消费价值。我见过一个项目用快速点击率作为决策依据,实验通过后全量上线,结果用户时长明显下降,最后不得不回滚。快速和准确之间的平衡点,是靠指标相关性分析算出来的,不能拍脑袋。
第三件事,是低估了多任务模型的“自举效应”。在线实验期间,模型推荐会影响用户行为,用户行为又会影响训练数据。如果实验只跑 11 天,行为数据还没在模型训练循环里充分起作用,最终的结论可能只代表“模型在旧数据分布上的表现”。这个偏差不会因为实验时间缩短而消失,只能通过提前准备好训练数据延迟更新,或者做发布后持续监测来兜底。
5.2 长尾重排最容易误读的两件事
第一件误读,是把“长尾曝光占比上升”直接等同于“长尾策略成功”。我用真实的例子说话:某次重排实验上线后,长尾覆盖率很漂亮地从 8% 涨到了 14%,但长尾内容的点击率只有对照组的 40%,反而让整体满意度下滑。问题出在,我们把长尾配额放在一个过于粗糙的层级上,模型为了完成配额,把小众歌曲强行塞给了对新风格没有接受意愿的用户。后来改成“长尾曝光必须匹配用户历史探索行为”的条件式策略之后,覆盖率保持在了 11%,消费效率才追上来。
第二件误读,是把长尾问题完全归咎于排序模型。实际上,很多长尾内容的候选在召回阶段就被淘汰了,重排无论怎么做都是无米之炊。所以每次排查长尾推荐问题时,我都会让团队先把各阶段的长尾留存率列出来看看:100 条长尾候选里,召回阶段剩多少、粗排剩多少、精排剩多少、重排又剩多少。数据会告诉你,真正需要动手的环节往往不在最后一层。
5.3 快速排查表
| 现象 | 可能原因 | 排查顺序 |
|---|---|---|
| 实验提前显著,全量后指标回落 | 停止规则不严格 / 小样本偶然 | 先查实验设计是否预注册,再看是否有多天重复查看 |
| 点击率涨、时长跌 | 多任务权重失衡 / 只看快层指标 | 切快中慢指标分层,复核各任务梯度贡献 |
| 长尾曝光提升但消费率低 | 召回阶段无长尾候选 / 配额过于粗放 | 先看召回长尾剩余率,再看重排配额条件 |
| 整体满意度跌但长尾指标在涨 | 用户体验护栏失守 | 立刻看负反馈率、跳过率,需要先降配额 |
| 实验 11 天结论和 21 天结论不同 | 动态分布未稳态 / 模型自举 | 延长护栏观察期,必要时做一次全量回查 |
这张表不是标准答案,但每一条都是我实际踩过或者见团队踩过的坑。排错的时候最忌讳只看最终指标,把链路各层的留存率拆开看,问题往往一目了然。
6. 这两件事对我的实际冲击
6.1 实验周期是能力下限,不是炫技
YouTube 把多任务排序实验压到 11 天,我最开始以为这是个算法技巧,后来才意识到这更多是系统工程能力的外显。实验结论快,意味着决策更快,模型迭代更快,团队的认知积累也更快。它要求数据管道按小时甚至分钟级产出指标,要求实验平台支持复杂的方差缩减和序贯检验,要求算法工程师有能力在实验开始前定义清楚决策规则,而不是跑完才想怎么看数据。
反过来说,如果团队这三层基础都不到位,单纯把实验天数从 21 天改成 11 天,只会收获一堆不靠谱的结论。所以,与其问“我们能不能也把实验压到 11 天”,不如先问“我们的指标基础设施和实验方法论,能不能支撑一个 11 天的快速决策”。前者是个时间数字,后者才是真正值得投入的方向。
6.2 长尾是结构问题,不是道德问题
Spotify 重排兼顾长尾,本质上是在试图修正推荐系统里一个结构性偏差。不是“我们有义务推冷门歌曲”,而是“如果内容生态的尾部供给萎缩,平台长期的生命力一定受损”。这件事难就难在它不是短期指标能体现的,但也不是虚无缥缈的情怀落地。它需要被量化、被写进目标函数、被分配预算,并且用护栏指标防止它反过来伤害用户体验。
我个人在做类似调整时最深的一个体会是:长尾策略必须是一套系统,而不是一个活动。召回阶段有配额,排序阶段有权重,重排阶段有列表约束,评估阶段有独立指标,四个环节缺一不可。如果只在一个环节发力,要么效果不明显,要么会牺牲另一头的收益,最后一算总账,往往不如不做。
最后再说一个比较实用的小建议:如果你所在团队准备尝试这一类优化,别从大改目标函数开始,先从补齐评估能力开始。先把“长尾曝光占比”“长尾消费效率”“列表多样性熵”这几个指标稳定地建起来,跑一段时间看清楚真实基线,再决定下一步怎么动。评估都看不清的时候做的任何加速或重排调优,都只是在给未来的自己挖坑。