OneRec 是首个在工业场景完全替代三级级联推荐 pipeline 的端到端生成式推荐模型:1B 参数 Encoder-Decoder + MoE 架构,一次性生成整个 session(5 个视频的 SID),Balanced K-Means 解决 codebook 不均衡问题,IPA 策略用 Reward Model 自动构造 DPO 偏好对进行迭代对齐;快手主页 A/B:总观看时长 +1.68%,人均单次观看时长 +6.56%。
📄 原文:https://arxiv.org/abs/2502.18965
🔗 前驱工作:TIGER(NeurIPS 2023)、LETTER(arXiv 2403.06361)
当前页面聚焦 2502 原论文:核心方法主线是 Balanced K-Means + Session-wise 生成 + IPA 对齐,重点回答“OneRec 为什么成立、为什么能替代三级漏斗”。
如果你想继续看“它在快手到底怎么工程化落地”,建议再读:OneRec Technical Report 解读。技术报告重点补了四类信息:
① Tokenizer 前置多模态管线:caption / OCR / ASR / 图像帧 + QFormer + RQ-Kmeans;
② 更完整的用户建模:静态特征、短期行为、正反馈行为、终身行为四路 Encoder;
③ 更工程化的对齐体系:P-Score、Format Reward、Industrial Reward、ECPO / RL;
④ 更完整的工业指标:MFU、OPEX、QPS 承接比例、硬件规模等。
可以把两页配合理解为:这页讲“方法为什么成立”,技术报告页讲“系统怎样真正落地、扩展并降成本”。
① 单阶段替代三级漏斗:Encoder-Decoder + MoE,一个模型统一召回与精排,彻底消除多阶段信息损失;
② Session-wise 生成:一次输出 5 个视频的完整 session,而非逐 item 生成,捕获 session 内 item 间关联性;
③ IPA 迭代偏好对齐:Reward Model 打分 → Beam Search 采样 → DPO 构造偏好对 → 迭代优化,闭环提升推荐质量。
快手的视频推荐系统日活用户超过 3 亿,传统架构采用三阶段级联排序:召回(Retrieval)→ 粗排(Pre-ranking)→ 精排(Ranking)。每个阶段独立训练、优化目标不同,上游的天花板限制了下游的性能上限。
传统级联 vs OneRec 统一架构
传统三阶段级联
- 召回:从 $10^{10}$ 个视频筛到 $10^5$(MIPS/ANN)
- 粗排:从 $10^5$ 筛到 $10^3$(轻量排序模型)
- 精排:从 $10^3$ 筛到 $10^2$(复杂重排模型)
- 各阶段独立优化,目标不一致,信息损失累积
OneRec 端到端生成
- Encoder 处理用户历史(最长 256 个视频)
- Decoder 直接生成 session(5 个目标视频的 SID)
- 一个模型 = 召回 + 精排,目标统一
- 在线 A/B:总观看时长 +1.68%,人均视频时长 +6.56%
OneRec 是快手首个在大规模工业场景中显著超越多阶段 pipeline 的端到端生成式推荐模型,具有重要的工业落地意义。
2.1 均衡 K-Means 语义 ID(Balanced Identifier Quantization)
传统 RQ-VAE 存在"沙漏现象"(hourglass phenomenon):少数 codebook 码字被频繁使用(高频 item 全都量化到几个热门码字),而大量码字闲置,导致 ID 分布极不均匀,Decoder 难以学习。OneRec 使用平衡 K-Means(Balanced K-Means) 解决这一问题。
SID 生成全流程:残差量化 + 均衡约束
OneRec 的 SID 生成分两步:①残差量化(RQ) 决定每层的 token 是什么;②均衡 K-Means 决定每层的 codebook 如何训练。两者结合生成最终的分层 SID。
第一步:残差量化生成 SID(与 RQ-VAE 相同)
给定视频 $i$ 的多模态 embedding $\mathbf{e}_i$,依次在每一层 codebook 中找最近邻 cluster,用"残差"迭代量化:
重复 $L$ 层后,视频 $i$ 的 SID 为 $(s_i^1, s_i^2, \ldots, s_i^L)$,即一个 $L$ 维的 token 序列。
第二步:均衡 K-Means 训练 codebook(OneRec 的创新)
普通 K-Means 允许各 cluster 大小不一,导致沙漏现象。均衡 K-Means 对每层 codebook 训练加入强制等分约束:
每轮迭代的分配过程:初始化 $K$ 个 cluster 中心 → 将所有视频按到各 cluster 的距离排序 → 每个 cluster 按距离从近到远依次认领最近的 $w$ 个未被认领的视频 → 用分配到的视频均值更新 cluster 中心 → 重复直到收敛。
设定:总视频数 $|\mathcal{V}|=6$,每层 codebook 大小 $K=3$,层数 $L=2$,则 $w = 6/3 = 2$(每个 cluster 精确包含 2 个视频)。
假设 6 个视频的 embedding(1 维,便于可视化):
- 视频 A: 0.1 | 视频 B: 0.15 | 视频 C: 0.5 | 视频 D: 0.55 | 视频 E: 0.9 | 视频 F: 0.95
第一层均衡 K-Means($K=3$,$w=2$):
初始化 3 个 cluster 中心,假设收敛后:
Cluster 0 中心 ≈ 0.125,Cluster 1 中心 ≈ 0.525,Cluster 2 中心 ≈ 0.925
按均衡约束分配(每个 cluster 精确 2 个视频):
- Cluster 0 ← {视频 A(0.1), 视频 B(0.15)}(最近 0.125,且恰好 2 个)
- Cluster 1 ← {视频 C(0.5), 视频 D(0.55)}(最近 0.525)
- Cluster 2 ← {视频 E(0.9), 视频 F(0.95)}(最近 0.925)
→ 第一层 SID token($s_i^1$):A→0, B→0, C→1, D→1, E→2, F→2
计算第一层残差($\mathbf{r}_i^2 = \mathbf{r}_i^1 - \mathbf{c}_{s_i^1}^1$):
- 视频 A 残差:0.1 − 0.125 = −0.025
- 视频 B 残差:0.15 − 0.125 = +0.025
- 视频 C 残差:0.5 − 0.525 = −0.025
- 视频 D 残差:0.55 − 0.525 = +0.025
- 视频 E 残差:0.9 − 0.925 = −0.025
- 视频 F 残差:0.95 − 0.925 = +0.025
第二层均衡 K-Means 作用在残差上($K=3$,$w=2$):
残差只有 ±0.025 两种,cluster 大小均衡后:
- Cluster 0(负残差)← {视频 A, 视频 C, 视频 E},但 $w=2$,所以只能取 2 个!
- 这里体现均衡约束的关键:普通 K-Means 会把 A/C/E 都分到同一个 cluster,而均衡 K-Means 强制每个 cluster ≤ 2 个,会把第 3 个负残差视频分到其他 cluster
- 假设最终:Cluster 0 ← {A, C},Cluster 1 ← {E, B},Cluster 2 ← {D, F}
→ 第二层 SID token($s_i^2$):A→0, C→0, E→1, B→1, D→2, F→2
最终 2 层 SID:
- 视频 A:(0, 0) | 视频 B:(0, 1) | 视频 C:(1, 0)
- 视频 D:(1, 2) | 视频 E:(2, 1) | 视频 F:(2, 2)
对比普通 RQ-VAE 沙漏现象:如果不加均衡约束,极端情况下所有视频第一层都分到同一个大 cluster(比如都在 embedding 空间中某个高密度区域),导致 $s_i^1$ 对所有视频都是同一个数字,失去区分能力。均衡约束强制每个 cluster 只有 $w$ 个视频,保证 ID 空间被充分利用。
2.2 Session-wise 列表生成(Session-wise List Generation)
传统生成式推荐(如 TIGER)每次只预测"下一个 item"(Next-Item Prediction),然后再以该 item 为条件预测下下一个……这种逐点生成方式存在两个问题:
- 每次生成只看到单个 item,无法考虑 session 内视频之间的多样性和连贯性
- 需要人工设计规则来合并多次生成结果(如去重、强制多样性),非端到端优化
OneRec 定义 session 为一次刷新返回给用户的视频列表,通常包含 5-10 个视频。训练时直接以高质量 session 为学习目标(整体 session 而非单个视频),让模型自主学习 session 内的最优结构。
高质量 Session 筛选标准
- 用户在该 session 内实际观看的视频数 ≥ 5
- 用户观看总时长超过一定阈值
- 用户有明确的交互行为(点赞、收藏、分享等)
Session-wise 生成目标的形式化定义:
- $H_u$:用户历史行为序列(最近 256 个有效互动视频的 SID 序列)
- $S = \{v_1, v_2, \ldots, v_m\}$:目标 session($m=5$ 个视频)
- $s_i^j$:session 中第 $i$ 个视频第 $j$ 层的 SID token($j$ 从 1 到 $L=3$)
- $\text{BOS}$:视频分隔符 token,每个视频前插入一个 BOS
- $m$:session 中的视频数量(默认 5)
有意义,但要理解 NTP 和 DPO 在这里各自的角色:
原因一:NTP 是"地基",不是终点
OneRec 的目标是用一个生成模型替代整个三阶段系统。第一步要做的,就是让这个生成模型至少能达到旧系统的水平——否则连基线都达不到,谈什么超越。
NTP 学旧系统的高质量 session,是在告诉模型:"历史上用户真正喜欢的是这类 session,你先学会生成这个水平的东西。"这是知识迁移,不是无意义的复制。
原因二:DPO(IPA)才是超越旧系统的关键
NTP 只能让模型复现旧系统的上限,而 DPO 的作用是让模型超越旧系统。DPO 的训练数据来自 Beam Search 生成的合成 session,Beam Search 可以探索出旧系统从来没推过的组合,RM 给这些组合打分,选出比旧系统更好的 session 作为 chosen,再用 DPO 拉高这类 session 的概率。
整体逻辑:
NTP → 学会旧系统水平(地基) → DPO → 探索并强化旧系统未发现的更优解(超越)原因三:99% NTP 在混合训练里起正则作用
IPA 阶段 99% 的数据仍然是 NTP,目的是防止模型在 DPO 优化偏好方向时灾难性遗忘——如果只做 DPO,模型可能过度拟合 RM 的偏好打分,忘掉"如何生成语义合法的 session token 序列"。NTP 持续提供正则,保持模型的生成能力稳定。
两者训练代码对比(Encoder-Decoder 架构):
# ── Next-Item 训练 ─────────────────────────────────────────
# target: 下一个视频的 SID,shape [3],例如 [9, 3, 1]
enc_out = encoder(H_u) # 用户历史,只跑一次
decoder_input = [BOS, 9, 3] # 长度 3,去掉最后一个 token
decoder_target = [9, 3, 1] # 长度 3,去掉开头 BOS
logits = decoder(decoder_input, enc_out) # shape [3, vocab_size]
loss = cross_entropy(logits, decoder_target)
# ↑ loss 只覆盖 3 个 token(1 个视频)
# ── Session-wise 训练 ──────────────────────────────────────
# target: 完整 5 个视频 session,形式化为带 BOS 分隔的序列
enc_out = encoder(H_u) # 完全一样,只跑一次
target_seq = [BOS,9,3,1, BOS,4,5,4, BOS,6,1,5, BOS,2,7,2, BOS,9,1,3] # 长度 20
decoder_input = target_seq[:-1] # 长度 19
decoder_target = target_seq[1:] # 长度 19
logits = decoder(decoder_input, enc_out) # shape [19, vocab_size]
loss = cross_entropy(logits, decoder_target)
# ↑ loss 覆盖 19 个 token(5 个视频)
结论一:训练方式完全相同,encoder 调用一模一样,decoder 内部也是标准 causal mask teacher forcing,唯一区别是 decoder_input 的长度(3 vs 19),即 loss 覆盖的 token 数不同。
结论二:为什么 Session-wise 能感知完整 session?
不是因为 Encoder,而是因为 5 个视频的所有 token 都在同一个 decoder_input 序列里。Decoder 的 causal self-attention 在生成视频3的 token 时,天然能"看到"视频1和视频2已经生成了什么——这是 Transformer 自回归的固有能力,与 Encoder 无关。Encoder 只负责处理用户历史 $H_u$,对 session 内部的感知没有贡献。
结论三:Next-Item 推理时的额外问题(Encoder-Decoder 架构下被放大)
推理时 Next-Item 需要循环 5 次:每次生成 1 个视频 → 把它加入 $H_u$ 重新跑 Encoder → 再生成下一个。这导致两个问题:
- Exposure Bias:训练时 decoder_input 始终是真实视频 SID,推理时却要把模型自己生成的视频加入历史——这个模式训练中从未出现过,误差逐步累积
- 推理代价高:需要调用 5 次 Encoder forward,而 Session-wise 只需 1 次
如果把两者都改成纯 Decoder(GPT 风格,把历史和目标拼成一条序列),则 Next-Item 推理时也不需要反馈进 Encoder,两者推理行为等价,唯一区别只剩"训练时 loss 覆盖多少个 token"。 这说明 Next-Item 的额外劣势本质上是 Encoder-Decoder 架构下"训练时序列短、推理时要迭代循环 Encoder"这一不一致带来的。
2.3 Encoder-Decoder + Sparse MoE 架构
OneRec 采用 T5 风格的 Encoder-Decoder 架构,Decoder 中的 FFN 层全部替换为 Sparse Mixture-of-Experts(MoE)层:
- $N_\text{MoE} = 24$:总 expert 数量(每层 24 个 FFN expert)
- $K_\text{MoE} = 2$:每次前向只激活 2 个 expert(FFN 层稀疏性 = $2/24 \approx 8.3\%$)
- $g_{i,t}$:第 $i$ 个 expert 对第 $t$ 个 token 的 gate 权重(仅 top-2 非零)
- $s_{i,t} = \text{Softmax}_i(H_t^l \cdot e_i^l)$:token $t$ 对 expert $i$ 的路由分数
2.4 奖励模型设计(Reward Model)
原因一:日志给不了"对比对"(反事实问题)
DPO 需要的是:同一用户、同一历史状态 $H_u$ 下,一个 chosen session 和一个 rejected session 的对比。但历史日志中,每次刷新只有一条真实曝光记录——系统当时推了什么,就只有这一条,没有"如果推了另一个 session 用户会怎么反应"的记录。这是反事实问题,在现实中不存在。
Beam Search 的作用正是:用当前模型为同一个 $H_u$ 生成 $N$ 条不同路径,人工制造出可对比的候选集,再由 RM 从中挑出最好和最差,构成合法的 DPO pair。
原因二:直接用旧系统日志做 DPO 数据,log-ratio 会不稳定
标准 DPO 理论上可以用 off-policy 数据(提前收集好的固定数据集),但有一个实践问题:DPO loss 需要计算当前模型对 chosen/rejected session 的 log 概率。如果偏好对来自旧系统(比如一个月前的推荐系统生成的 session),当前模型对这些序列的概率可能极低甚至接近 0——当前模型根本不会生成这些 token 组合,导致 log 概率趋向 $-\infty$,log-ratio 数值爆炸,梯度噪声极大。
Beam Search 生成的候选 session 来自当前模型本身,模型对它们的概率在合理范围内,log-ratio 稳定,训练收敛正常。这是 IPA 每轮重新采样的工程动机之一。
原因三:RM 的训练数据和 DPO 的数据需求是两件不同的事
RM 用真实日志(
历史session + 真实swt/ltr标签)训练,学会了"给任意 session 打分的能力"。IPA 利用这个打分能力,给 Beam Search 产生的合成 session 评分,再选出 chosen/rejected。
不能反过来——直接把真实日志当 DPO 数据,因为真实日志根本给不了对比对(原因一),且旧 session 会导致 log-ratio 不稳定(原因二),合成 session 也没有真实用户行为标签。
类比:厨师(RM)从 10 万道顾客真实点评的菜里学会了"什么好吃"。比赛中他给自己新发明的菜(Beam Search 合成 session)打分,选最好和最差的配方来改进。真实日志给了 RM 的知识来源,但比较对象是模型自己生成的合成 session——两件事的数据需求完全不同。
| RM 训练数据 | IPA DPO 数据 | |
|---|---|---|
| 数据来源 | 历史真实曝光 session | Beam Search 生成的合成 session |
| 标签 | 真实 swt/ltr(用户行为日志) | RM 预测分数(无真实标签) |
| 用途 | 让 RM 学会打分 | 构造 (chosen, rejected) 偏好对 |
| 为什么不能互换 | 真实 session 没有可比对的"另一条路径" | 合成 session 没有真实用户行为标签 |
DPO 训练需要 preference pairs(好的 session vs 差的 session)。推荐系统中用户不会明确表示"我更喜欢这个 session",且 Beam Search 生成的合成 session 没有真实用户行为标签,因此 OneRec 训练一个多目标奖励模型(session 级别打分,非 point-wise)来模拟用户偏好。
我们用 $R(\bm{u}, \mathcal{S})$ 表示奖励模型,它负责为不同用户选择偏好数据。其中,输出 $r$ 表示用户 $u$(通常由用户行为表示)对 session $\mathcal{S}=\{\bm{v}_1, \bm{v}_2, \ldots, \bm{v}_m\}$ 的偏好奖励值。
为了使 RM 具备对 session 进行排序的能力,我们首先对 session $\mathcal{S}$ 中每个 item $\bm{v}_i$ 提取 target-aware 表示 $\bm{e}_i = \bm{v}_i \odot \bm{u}$,其中 $\odot$ 表示 target-aware 操作(例如对用户行为做 target attention)。由此得到 session $\mathcal{S}$ 的 target-aware 表示序列 $\bm{h} = \{\bm{e}_1, \bm{e}_2, \cdots, \bm{e}_m\}$。
接着,session 内各 item 通过 self-attention 层相互交互,融合不同 item 之间的必要信息:
然后,我们使用不同的 tower 对多目标奖励进行预测,RM 使用大量推荐数据进行预训练:
在得到每个 session 的所有预测奖励 $\hat{r}^{swt}, \ldots$ 以及真实标签(ground-truth labels)$y^{swt}, \ldots$ 之后,我们直接最小化二值交叉熵损失来训练 RM:
补充说明:论文未具体说明 ground-truth label 的构造方式(如 swt 是绝对时长还是归一化比例),仅说"使用大量推荐数据预训练 + binary cross-entropy loss"。RM 是 session 级别打分,而非 point-wise 对单个视频打分——通过 self-attention 让 session 内 5 个视频互相感知后 Sum 池化得到整体表示,能捕捉单视频排序做不到的多样性/连贯性信息。
OneRec 用 Beam Search 为某个用户生成了 3 个不同的候选 session:
Session A:[搞笑段子①, 搞笑段子②, 搞笑段子③, 搞笑段子④, 搞笑段子⑤] → 主题重复,用户可能看了前 2 个就滑走。Reward Model 预测:swt=0.12, ltr=0.05 → 综合分低。
Session B:[搞笑段子①, 科技评测①, 美食探店①, 搞笑段子②, 健身教程①] → 多样但用户兴趣匹配度参差不齐。Reward Model 预测:swt=0.19, ltr=0.09 → 综合分中等。
Session C:[搞笑段子①, 搞笑段子②, 科技评测①, 美食探店①, 搞笑段子③] → 主题连贯 + 适度多样。Reward Model 预测:swt=0.22, ltr=0.12 → 综合分最高。
IPA 选择 Session C 为 chosen,Session A 为 rejected,构成 DPO 训练的偏好对。
2.5 迭代偏好对齐(Iterative Preference Alignment, IPA)
标准 DPO 只用一次,IPA 通过迭代自我改进的方式持续提升质量:
- 1用当前模型 $\mathcal{M}_t$ 通过 Beam Search(beam size=128)为每个用户生成 $N$ 个不同 session
- 2用 Reward Model $R(u, S)$ 对每个 session 打分
- 3选分数最高的 session 为 chosen $S^w_u$,分数最低的为 rejected $S^l_u$
- 4对每个训练样本,以概率 $r_\text{DPO}=1\%$ 进入 DPO 分支:若进入,则在线构造偏好对并计算 $\mathcal{L}_\text{NTP}+\lambda\mathcal{L}_\text{DPO}$;否则只计算 $\mathcal{L}_\text{NTP}$
- 5得到新模型 $\mathcal{M}_{t+1}$,用新模型重新生成候选 session,回到步骤 1
- $\mathcal{M}_{t+1}$:当前更新中的模型
- $\mathcal{M}_t$:reference 模型(固定,用于计算 KL 惩罚基准)
- $S^w_u$:用户 $u$ 的 chosen session(RM 分最高)
- $S^l_u$:用户 $u$ 的 rejected session(RM 分最低)
- $\beta$:KL 惩罚系数,防止过度偏离参考模型
总训练 loss 为:
按论文 Algorithm 2 的写法:对每个训练 sample,先按概率 $r_\text{DPO}=1\%$ 判断本次是否进入 DPO 分支。
若进入 DPO 分支:当前模型先在线生成候选 session,RM 选出 best / worst,再计算总损失 $\mathcal{L}=\mathcal{L}_\text{NTP}+\lambda\mathcal{L}_\text{DPO}$;若不进入 DPO 分支:只计算 $\mathcal{L}_\text{NTP}$。
因此,可以确定的是:
① IPA 阶段不是“先完全做完 NTP 再切到 DPO”的两阶段;
② DPO 所需的偏好对不是固定离线数据,而是由当前模型在线生成;
③ 论文明确保留了 $\mathcal{L}_\text{NTP}$,用于在偏好对齐时继续稳定生成能力。
但要注意:论文没有明确展开说明 DPO 分支中的 $\mathcal{L}_\text{NTP}$ 具体是对哪条序列计算,因此这里不能擅自写成“对 chosen 做 teacher forcing”之类超出原文的信息。
这里的“DPO 样本”不是像传统监督学习那样,提前放在离线数据集里的固定样本,而是 IPA 训练过程中由当前模型在线生成 的偏好对:
- 先给定一个用户历史 $H_u$
- 当前模型 $\mathcal{M}_t$ 用 Beam Search 生成 $N$ 个候选 session
- RM 给这 $N$ 个候选打分
- 最高分作为 chosen $S^w_u$,最低分作为 rejected $S^l_u$
于是得到一个在线构造的偏好对 $(H_u, S^w_u, S^l_u)$,再用于计算 $\mathcal{L}_{\text{DPO}}$。因此,DPO 数据不是“事先标好的训练集”,而是“训练过程中当前模型自己生成、RM 再筛出来的 pair”。
注意:论文确认了进入 DPO 分支时总损失写作 $\mathcal{L}_{\text{NTP}} + \lambda \mathcal{L}_{\text{DPO}}$,但没有展开说明这个分支里 $\mathcal{L}_{\text{NTP}}$ 的监督对象具体是哪条序列,因此这里不再额外假设实现细节。
第 1 轮:模型质量较弱,Beam Search 生成的最优 session 也只能打 0.22 分(勉强好),rejected 打 0.08 分(明显差)。DPO 能学到一些偏好信号,但 chosen session 本身不够好。
第 2 轮(用第 1 轮模型):模型稍强,现在 Beam Search 的最优 session 能打 0.28 分,rejected 还是 0.09 分。DPO 能从更高质量的 chosen 学习更强的偏好信号。
第 3 轮:最优 session 打 0.31 分……如此迭代,每轮的"自我生成的 hard negative"都是当前模型能力边界上的挑战性样本,比一次性用固定负样本训练效果好得多——这就是"自我改进"的本质。
2.6 在线部署架构
OneRec 的在线服务由三个核心组件构成:
- 离线训练系统:1B 参数模型,使用 XLA + bfloat16 混合精度,支持大规模分布式训练
- 在线推理服务:KV Cache 加速 + float16 量化减少内存,Beam Search beam_size=128(平衡质量与延迟)
- DPO Sample Server:仅对 1% 请求进行 DPO 采样(用 Reward Model 打分生成偏好对),供持续在线学习使用
论文给出的核心思路很明确:OneRec 在线上不是当“召回器”或“打分器”用,而是直接充当完整的推荐生成器。也就是说,它一次性完成传统系统里“召回 + 排序 + 列表组织”三件事。
在线请求到来时,大致流程是:
① 取用户最近的行为历史,编码成语义 ID 序列,送入 Encoder;
② Decoder 以自回归方式生成目标 session 的语义 ID 序列(例如 5 个视频,每个视频 3 个 SID token,中间用 BOS 分隔);
③ 在线服务使用 Beam Search 在 SID 空间搜索多个候选序列,beam size = 128;
④ 得到最终的 SID 序列后,再映射回真实视频 ID,作为这一屏的推荐结果返回给用户。
所以从线上 serving 角度看,它不是“先召回一堆候选视频,再用模型逐个打分重排”,而是直接生成最终的推荐列表。
假设某用户最近看过的历史是:[搞笑A, 搞笑B, 科技C, 美食D, 搞笑E, 健身F, ...]。
- Step 1:Encoder 读历史
系统先把这些历史视频转成语义 ID token 序列,Encoder 对整段历史做编码,得到用户当前兴趣状态的表示。 - Step 2:Decoder 生成 session
Decoder 从[BOS]开始,自回归生成一整屏推荐的 SID 序列,比如:
[BOS, a9, b3, c1, BOS, a4, b5, c4, BOS, a6, b1, c5, BOS, a2, b7, c2, BOS, a9, b1, c3] - Step 3:Beam Search 选最优序列
在线推理不是只保留一条贪心路径,而是保留 beam size = 128 条候选路径,在 SID 空间中比较哪条完整 session 概率最高。 - Step 4:SID → 视频
最终把生成出的 5 组 SID 映射回真实视频,得到这一屏真正展示给用户的 5 个视频。
这就是 OneRec 在线 serving 的本质:用户历史 → 生成语义 ID 列表 → 映射回视频 → 直接展示。
论文明确写了:
- 在线推理用 KV Cache 加速自回归解码
- 使用 float16 量化 降低显存/内存开销
- 在线搜索使用 Beam Search,beam size = 128
- 单独有一个 DPO Sample Server,只采样 1% 在线流量,用于构造偏好对回流训练
离线对比(vs 传统方法 + TIGER)
| 模型 | swt↑ (mean) | swt↑ (max) | ltr↑ (mean) | ltr↑ (max) |
|---|---|---|---|---|
| SASRec(传统判别式) | 0.0375 | 0.0803 | 0.0314 | 0.0604 |
| TIGER-1B(逐点生成) | 0.0873 | 0.1368 | 0.0323 | 0.0579 |
| OneRec-1B(session 生成) | 0.0991 | 0.1529 | 0.0360 | 0.0660 |
| OneRec-1B+IPA(+偏好对齐) | 0.1025 | 0.1933 | 0.0397 | 0.1203 |
OneRec-1B 在 session watch time 的 max 指标上比 TIGER-1B 提升 +41.3%,加上 IPA 后 ltr (max) 提升 +107.8%(0.0579 → 0.1203),说明 IPA 对交互类指标的提升尤其显著。
模型规模消融(Scaling Law)
从 0.05B 到 1B 持续提升性能,具有稳定的 scaling 特性:
- 0.05B → 0.1B:max swt 提升 +14.45%
- 0.1B → 0.2B:+5.09%;→ 0.5B:+5.70%;→ 1B:+5.69%
DPO 采样比例消融
在 1% 到 5% 的 DPO 采样比例范围内,1% 比例已能获得约 95% 的最优性能,而 5% 需要 5 倍 GPU 资源。论文选择 1% 作为在线部署的工程平衡点。
在线 A/B 测试(快手主页信息流,1% 流量,1 个月)
| 模型 | 总观看时长 | 人均视频时长 |
|---|---|---|
| OneRec-0.1B | +0.57% | +4.26% |
| OneRec-1B | +1.21% | +5.01% |
| OneRec-1B+IPA | +1.68% | +6.56% |
在快手这样的超大规模平台上,1.68% 的观看时长提升代表着极大的商业价值(对应数亿用户每天数百万小时的增量观看时长)。
最重要的贡献
- Session-wise 生成是核心创新:不是"生成单个推荐"而是"生成推荐列表",让模型能感知多视频之间的关系,这是 OneRec 超越 TIGER 的关键。
- IPA = 自我博弈式提升:用当前模型的 beam search 结果构造 hard negative,再 DPO 训练,形成正向循环。这是 AlphaGo 自对弈思想在推荐系统的应用。
- 1% DPO 是工程智慧:论文中仔细分析了计算资源与性能的权衡,最终选择 1% 而非更大比例,这种工程意识在工业论文中非常难得。
潜在不足
- Session-wise 生成要求训练数据中有高质量 session 标注,数据集构建成本高(需要满足 3 个以上筛选条件的真实 session)。
- Reward Model 本身的质量直接影响 IPA 的上限——如果 RM 不准,chosen/rejected 的区分就会有噪声,DPO 效果打折。
- MoE 推理需要 All-to-All 通信,分布式部署时可能成为延迟瓶颈(尤其是 expert 跨卡分布时)。
对我的启发
OneRec 给了我一个重要信号:生成式推荐的潜力不仅在于"好的 item tokenization",更在于"好的生成目标"。Session-wise 生成让模型优化的目标更接近线上真实场景(用户不是孤立地接受每个推荐,而是整体评价这一屏内容的质量),这种"任务定义的优化"往往比"模型架构的优化"带来更大的收益。
论文链接:arXiv 2502.18965
关键词:生成式推荐 · Session-wise 生成 · MoE · DPO · 偏好对齐 · 端到端推荐
对比基线:SASRec, BERT4Rec, TIGER, DPO/IPO/cDPO 等多种变体