0%

读论文-OneRec生成式推荐系统

Deng J, Wang S, Cai K, et al. Onerec: Unifying retrieve and rank with generative recommender and iterative preference alignment[J]. arXiv preprint arXiv:2502.18965, 2025.

方法介绍

本文提出 OneRec,一个端到端的单阶段生成式推荐框架,其目标是直接根据用户历史行为生成目标 session,而不再采用传统的多阶段级联排序流程。设用户历史行为序列为

$$ H_u={v_1^h,v_2^h,\dots,v_n^h} $$

其中,$v_i^h$ 表示用户产生过有效正反馈的视频,$n$ 表示历史行为长度。模型输出为一个 session 级推荐列表

$$ S={v_1,v_2,\dots,v_m} $$

其中,$m$ 表示该 session 中的视频个数。

从整体上看,OneRec 可以表示为一个从用户历史序列到目标 session 的映射函数:

$$ S := M(H_u) $$

OneRec 的方法主要由三部分构成:语义表示构建、session 级生成建模,以及基于奖励模型的迭代偏好对齐。

1. 语义表示构建

对于每个视频 $v_i$,首先利用多模态表示学习得到其连续向量表示

$$ e_i \in \mathbb{R}^d $$

为了让生成模型能够像生成文本 token 一样生成推荐结果,OneRec 不直接生成原始 item id,而是将每个视频 embedding 离散化为多层语义 ID。具体地,采用多层 residual quantization。第 1 层的初始残差定义为

$$ r_i^1 = e_i $$

在第 $l$ 层,设码本为

$$ C_l={c_1^l,c_2^l,\dots,c_K^l} $$

其中,$K$ 为该层 codebook 大小。则第 $l$ 层所选取的语义 token 索引为

$$ s_i^l=\arg\min_k \lVert r_i^l-c_k^l \rVert_2^2 $$

随后,将该层选中的聚类中心从残差中扣除,得到下一层残差:

$$ r_i^{l+1}=r_i^l-c_{s_i^l}^l $$

因此,多层语义 ID 的生成过程可以写为

$$ s_i^1 = \arg\min_k \lVert r_i^1-c_k^1 \rVert_2^2,\qquad r_i^2 = r_i^1-c_{s_i^1}^1 $$

$$ s_i^2 = \arg\min_k \lVert r_i^2-c_k^2 \rVert_2^2,\qquad r_i^3 = r_i^2-c_{s_i^2}^2 $$

$$ \cdots $$

$$ s_i^L = \arg\min_k \lVert r_i^L-c_k^L \rVert_2^2 $$

最终,每个视频被表示为一个由 $L$ 层 token 构成的语义 ID:

$$ v_i \longrightarrow (s_i^1,s_i^2,\dots,s_i^L) $$

为了避免语义 token 分布极不均衡,OneRec 采用 Balanced K-Means 构造更平衡的码本。给定物品集合 $V$ 和簇数 $K$,每个簇分配的样本数为

$$ w=\frac{\lvert V \rvert}{K} $$

Balanced K-Means 的核心约束是:每个 cluster 都尽量包含相同数量的 item,从而缓解语义编码中的分布偏斜问题。

2. Session 级列表生成

不同于传统 point-wise 推荐方法只预测下一个 item,OneRec 直接建模整个 session 的生成。用户历史序列和目标 session 都用语义 ID 序列表示:

$$ H_u={(s_1^1,s_1^2,\dots,s_1^L),(s_2^1,s_2^2,\dots,s_2^L),\dots,(s_n^1,s_n^2,\dots,s_n^L)} $$

$$ S={(s_1^1,s_1^2,\dots,s_1^L),(s_2^1,s_2^2,\dots,s_2^L),\dots,(s_m^1,s_m^2,\dots,s_m^L)} $$

模型结构采用 Encoder-Decoder Transformer。首先,Encoder 对用户历史行为进行编码,得到用户兴趣表示:

$$ H = Encoder(H_u) $$

然后,Decoder 基于编码后的用户兴趣表示,以自回归方式生成目标 session 的语义 token 序列。

为了增强模型容量,OneRec 在 Decoder 的前馈层中引入了 **Mixture of Experts (MoE)**。对于第 $l$ 层 decoder 表示 $H_t^l$,MoE 输出为

$$ H_t^{l+1} = \sum_{i=1}^{N_{\mathrm{MoE}}} g_{i,t},FFN_i(H_t^l) + H_t^l $$

其中,$N_{\mathrm{MoE}}$ 表示 expert 总数,$FFN_i(\cdot)$ 表示第 $i$ 个 expert。门控值 $g_{i,t}$ 定义为

$$ g_{i,t} = s_{i,t},\mathbb{I}!\left[s_{i,t}\in \mathrm{Topk}\big({s_{j,t}\mid 1\le j\le N},K_{\mathrm{MoE}}\big)\right] $$

并且

$$ s_{i,t}=\mathrm{Softmax}_i\big((H_t^l)^\top e_i^l\big) $$

这意味着每个 token 只会被路由到少数几个 expert 上,从而实现“参数规模大但计算稀疏”。

在训练时,在每个 item 的语义 token 前加入起始符号 $s^{[\mathrm{BOS}]}$,得到 decoder 输入序列

$$ \bar S={s^{[\mathrm{BOS}]},s_1^1,s_1^2,\dots,s_1^L,s^{[\mathrm{BOS}]},s_2^1,s_2^2,\dots,s_2^L,\dots,s^{[\mathrm{BOS}]},s_m^1,s_m^2,\dots,s_m^L} $$

模型采用 next-token prediction 训练目标,对目标 session 的语义 token 使用交叉熵损失:

$$ L_{\mathrm{NTP}} = -\sum_{i=1}^{m}\sum_{j=1}^{L} \log P\Big(s_i^{j+1}\mid[s^{[\mathrm{BOS}]},s_1^1,\dots,s_1^L,\dots,s^{[\mathrm{BOS}]},s_i^1,\dots,s_i^j];\Theta\Big) $$

经过这一阶段训练后,可以得到初始生成模型 $M_t$。

3. 奖励模型

为了进一步刻画用户对整个 session 的偏好,OneRec 引入奖励模型 $R(u,S)$。其中,$u$ 表示用户,$S$ 表示一个候选 session,奖励模型输出

$$ r = R(u,S) $$

表示该用户对该 session 的偏好程度。

对于 session 中的每个 item $v_i$,首先构造其面向用户的 target-aware 表示:

$$ e_i = v_i \odot u $$

其中,$\odot$ 表示目标感知操作。于是,整个 session 的表示可以写为

$$ h={e_1,e_2,\dots,e_m} $$

为了建模 session 内部 item 之间的关系,采用 self-attention 融合上下文信息:

$$ h_f=\mathrm{SelfAttention}(hW_s^Q,hW_s^K,hW_s^V) $$

接着,使用多个 tower 对不同目标进行预测:

$$ \hat r_{\mathrm{swt}} = Tower_{\mathrm{swt}}(Sum(h_f)) $$

$$ \hat r_{\mathrm{vtr}} = Tower_{\mathrm{vtr}}(Sum(h_f)) $$

$$ \hat r_{\mathrm{wtr}} = Tower_{\mathrm{wtr}}(Sum(h_f)) $$

$$ \hat r_{\mathrm{ltr}} = Tower_{\mathrm{ltr}}(Sum(h_f)) $$

其中

$$ Tower(\cdot)=\mathrm{Sigmoid}(\mathrm{MLP}(\cdot)) $$

奖励模型采用多目标二元交叉熵进行训练:

$$ L_{\mathrm{RM}} = -\sum_{xtr}\left[y_{xtr}\log(\hat r_{xtr}) + (1-y_{xtr})\log(1-\hat r_{xtr})\right] $$

4. 迭代偏好对齐(IPA)

在得到初始生成模型 $M_t$ 和奖励模型 $R(u,S)$ 后,OneRec 进一步采用 Direct Preference Optimization (DPO) 做偏好对齐。

对于每个用户,当前模型通过 beam search 生成 $N$ 个候选 session:

$$ S_u^n \sim M_t(H_u),\qquad \forall u\in U,; n\in[N] $$

随后,利用奖励模型为每个候选 session 打分:

$$ r_u^n = R(u,S_u^n) $$

根据得分,选出奖励最高的候选作为 winner,奖励最低的候选作为 loser:

$$ S_u^w = S_u^{\arg\max_i r_u^i},\qquad S_u^l = S_u^{\arg\min_i r_u^i} $$

从而构造偏好对

$$ D_t^{\mathrm{pairs}}=(S_u^w,S_u^l,H_u) $$

给定偏好对后,训练下一个模型 $M_{t+1}$,其 DPO 损失定义为

$$ L_{\mathrm{DPO}} = -\log \sigma\left(\beta \log \frac{M_{t+1}(S_u^w\mid H_u)}{M_t(S_u^w\mid H_u)} - \beta \log \frac{M_{t+1}(S_u^l\mid H_u)}{M_t(S_u^l\mid H_u)}\right) $$

因此,OneRec 的总训练目标可以写为

$$ L = L_{\mathrm{NTP}} + \lambda L_{\mathrm{DPO}} $$

也就是说,模型一方面通过 $L_{\mathrm{NTP}}$ 学习基本的 session 生成能力,另一方面通过 $L_{\mathrm{DPO}}$ 将生成分布进一步推向更高奖励的候选结果。

由于偏好对构造需要 beam search,计算代价较高,论文仅对一小部分样本执行 DPO 对齐。设采样比例为 $r_{\mathrm{DPO}}$,则训练时仅在

$$ \mathrm{rand()} < r_{\mathrm{DPO}} $$

时执行偏好对齐,否则仅使用 $L_{\mathrm{NTP}}$ 更新参数。

5. 方法总结

总体而言,OneRec 的建模流程可以概括为:

  1. 利用多模态 embedding 和多层残差量化,将 item 表示为语义 ID;
  2. 使用 Encoder-Decoder Transformer 对整个 session 进行自回归生成;
  3. 借助 MoE 扩展模型容量;
  4. 使用奖励模型估计 session 质量;
  5. 通过 IPA + DPO,在迭代训练中不断提升模型对高价值 session 的偏好。

因此,OneRec 可以视为一个统一了 检索、列表生成和偏好对齐 的端到端生成式推荐框架。