Utility-Aware Generative Recommendation: Utility-Enriched Semantic Codes and Utility-Guided Decoding

Yang Hu, Duo Wang, Ning Li, Kang Li, Junda She, Chengcheng Guo, Kuo Cai, Bin Liu, Youhua Liu, Xiaoshuang Chen · arXiv 2611.02981 · 发表 2026-11-02
14 分钟阅读时长 5253字 4.50综合分 第 2 名11-04 Generative 日报
目录 · 8 节1它到底在解决什么问题?2UAGR 怎么做:先看全景3解码时怎么算价值分?4编码时怎么把价值放进 SID?5实验:价值真的帮到推荐了吗?6我认为它的局限7一个推荐团队可以怎么试8结论
相关 5新颖 4实用 4证据 5时效 5

做生成式推荐的团队值得读。UAGR(快手这篇论文提出的方法)在两个以前只看内容和概率的地方加入了视频的价值:SID 最后一个 token 里留出 3 个比特存价值档位;束搜索每一步把预测出的价值分加进剪枝分数。这样改有两个原因。常见的生成式推荐只按内容给视频编 SID,常被看完的视频和很少有人看完的视频,只要内容相近,就拿到几乎一样的编码。束搜索又只按生成概率剪枝,价值高的候选可能在中间某个 token 就被剪掉,后面的重排救不回来。价值分来自模型解码时对观看时长、长播放、点赞、转发的预测,按权重加起来;SID 长度和词表大小都不变。

它已在快手短视频推荐全量上线,一周 A/B 里视频观看时长提升 0.206%。离线在 KuaiRand 上,只加解码这一项,Recall@3 就从 2.111% 提到 2.578%,高于生成后重排的 2.307%,也高于用同样价值分做 GRPO 训练的 2.418%。这意味着,价值信号放在剪枝这一步用,比只在生成完之后重排更有效。

它到底在解决什么问题?

生成式推荐把每个视频编成一个 SID,比如由 3 个 token 组成,每个 token 从 8192 个编号里选一个。模型看着用户历史,一个 token 一个 token 地生成 SID,生成出的 SID 对应的视频就是推荐结果。生成用束搜索,束宽记为 K。

问题出在两处。第一,SID 是按视频内容的 embedding 聚类得到的,内容相近的视频编码也相近,甚至完全相同。两个都讲「家常红烧肉」的视频,一个完播率很高,一个大多数人划走,编码上分不出来。第二,生成概率学的是「用户历史里出现过什么」,不直接反映曝光之后用户会不会看完、点赞、转发。束搜索在中间某一步按概率剪掉一个前缀,这个前缀下面的所有视频就都没机会了。

论文图 2 用一个四条前缀的例子说明第二个问题(数字是论文图中的示意值),束宽 K 取 2:

前缀累计生成概率(对数)价值分只按概率概率加价值
A-1.00.6-1.0,保留-0.4,保留
B-1.20.1-1.2,保留-1.1,剪掉
C-1.50.2-1.5,剪掉-1.3,剪掉
D(用户会喜欢的视频在这里)-1.40.7-1.4,剪掉-0.7,保留

只按概率时 D 排第三,被剪掉,它下面那个用户会喜欢的视频再也生成不出来。把价值分加上以后,D 的总分从 -1.4 变成 -0.7,排到第二,留了下来。事后重排做不到这一点,因为重排只能在已经生成出来的候选里调顺序。

标准束搜索和价值引导束搜索的对比:左边只按概率,D 被剪掉;右边加上价值分后,D 被保留,B 被剪掉
标准束搜索和价值引导束搜索的对比:左边只按概率,D 被剪掉;右边加上价值分后,D 被保留,B 被剪掉

UAGR 怎么做:先看全景

UAGR 总览:左边 (a) 是新的 SID 编码,前两个 token 照旧按内容聚类,最后一个 token 一部分比特存内容、一部分比特存价值档位;中间 (b) 是价值预测模块,从解码器的隐状态里读出各项行为的预测;右边 (c) 是束搜索时把生成概率和价值分加在一起剪枝
UAGR 总览:左边 (a) 是新的 SID 编码,前两个 token 照旧按内容聚类,最后一个 token 一部分比特存内容、一部分比特存价值档位;中间 (b) 是价值预测模块,从解码器的隐状态里读出各项行为的预测;右边 (c) 是束搜索时把生成概率和价值分加在一起剪枝

整个方法分两块,各管一件事:

部件什么时候起作用做什么
UGD训练时加一个小预测模块;推理时每一步剪枝都用预测每个候选 token 对应的曝光后行为,加权成价值分,和生成概率一起排序
UE-SID建 SID 时在最后一个 token 里留 3 个比特存价值档位,让内容相近、价值不同的视频编码不同

两块的分工是:编码让价值不同的视频在 SID 上可以分开,解码让价值在剪枝时真正起作用。下面拆开讲。

解码时怎么算价值分?

这一块论文叫 UGD(Utility-Guided Decoding 的缩写)。为什么需要它:束搜索每一步都要决定留谁,而概率只代表相关性。要在剪枝时考虑价值,就得在每一步、对每个候选 token 都有一个价值估计。

价值预测模块直接复用生成模型的计算。解码第 个 token 时,解码器已经根据用户历史和已生成的前缀算出一个隐状态。模块先用一个小 MLP 把这个隐状态压成一个低维向量,四种行为共用这个向量。然后每种行为对每个候选 token 各有一个可学的向量和偏置(每个 token 位置各一套),和这个低维向量做内积,得到「接上这个 token 后,这种行为的预测分」。四种行为是观看时长、长播放、点赞、转发。

剪枝时每个候选的总分是:

第一项是到目前为止的累计生成对数概率。 是第 种行为在候选 token 上的预测分。 把各种行为的预测放到同一量级:点赞这类二分类预测过 sigmoid;观看时长这类回归预测,先在当前这一步的所有候选里做标准化,再过 sigmoid。 是各行为的权重,论文用观看时长 0.6、长播放 0.2、点赞 0.1、转发 0.1, 取 1。

有一个细节容易忽略:概率是逐个 token 累加的,价值分却不累加。排序分等于累计对数概率,加上当前这一步候选 token 的价值分;前面几步的价值分不带进来。 Hoot 说

Hoot 说解码一步走一遍:价值分从哪来、加到哪、带不带到下一步收起 ✕
往下一步传的只有累计对数概率,价值分每一步按当前候选 token 重新算。它和下一个 token 的概率出自同一次前向,推理时不看任何真实反馈。
六个方框:解码器隐状态同时给出下一个 token 的概率和价值头的预测;价值头经小 MLP 和每个候选 token 的向量得到四种行为的预测,加权成价值分;累计对数概率加价值分得到排序分,取前 K 个;进入下一步的只有累计对数概率。解码器隐状态用户历史 + 已生成的前缀,一次前向累计对数概率前缀的 + 这个候选 token 的价值头(stop-gradient)四种行为预测,加权成价值分只用当前一步排序分 = 累计对数概率 + λ × 价值分所有候选里取前 K 个下一步只带上累计对数概率,价值分重算真实曝光反馈只在训练时当价值头的标签推理时没有
六个方框:解码器隐状态同时给出下一个 token 的概率和价值头的预测;价值头经小 MLP 和每个候选 token 的向量得到四种行为的预测,加权成价值分;累计对数概率加价值分得到排序分,取前 K 个;进入下一步的只有累计对数概率。解码器隐状态用户历史 + 已生成的前缀,一次前向累计对数概率前缀的 + 这个候选 token 的价值头(stop-gradient)四种行为预测,加权成价值分只用当前一步排序分 = 累计对数概率 + λ × 价值分所有候选里取前 K 个下一步只带上累计对数概率,价值分重算真实曝光反馈只在训练时当价值头的标签推理时没有
  1. 价值分(示意):0.6 × 0.9 + 0.2 × 0.5 + 0.1 × 0.2 + 0.1 × 0 = 0.66
  2. 排序分(示意):累计对数概率 −1.4 加上 1 × 0.66,等于 −0.74;只用这个分决定留不留
  3. 进入下一步的仍是 −1.4 加上下一个 token 的对数概率,这一步的 0.66 不带过去,所以长前缀不会把价值分重复加好几遍。

示意:一条前缀在某一步的一个候选 token。左列是这一步算出的两样东西,右列是剪枝和下一步。四种行为的归一化预测是编的,权重 0.6、0.2、0.1、0.1 和 λ 取 1 是论文的设置。 出处: 论文 §3.2 排序分公式(累计对数概率 + λ·加权归一化预测,价值分只用当前一步)、价值头读取 stop-gradient 后的解码器隐状态;附录 B.2 权重和 λ

推理时模块只看隐状态,不看任何真实反馈。真实反馈只在训练时出现:每条训练样本是用户历史加一个目标视频,目标视频曝光后有没有长播放、看了多久、点没点赞、转没转发,这些记录作为标签,监督模块在目标 SID 每个 token 上的预测。离线实验里,这些标签取自训练期的全部曝光记录,包括没有长播放的曝光,不用验证集和测试集的数据。总的训练目标是原来的下一个 token 预测损失,加上一个权重 0.001 的价值损失。

这个模块读入解码器隐状态的地方加了 stop-gradient。生成模型仍然用下一个 token 预测损失照常训练(论文里是 LoRA 微调),只是不受这些带噪声的行为标签干扰。以后要加一种新行为,也只需要加一个预测头。推理时这些预测头和下一个 token 的预测用同一次前向计算,不需要额外跑一遍模型。

编码时怎么把价值放进 SID?

为什么需要这一步:如果两个视频的 SID 完全一样,解码时就无法区分它们,价值分再准也没用。论文把这种情况叫 SID 冲突。在 KuaiRand 上用常规的三层残差 K-means 编码,有 4.29% 的视频和别的视频共用同一个 SID。

论文的编码方案叫 UE-SID(Utility-Enriched SID 的缩写),它只改最后一个 token,前两个 token 照旧用残差 K-means。最后一个 token 的 8192 个编号正好是 13 个比特。做法分三步:

  1. 把最后一个 token 拆成 13 个独立的 0/1 比特。 用一个可学的线性投影把前两层剩下的残差变成 13 个数,每个数大于 0 记 1,否则记 0。这种做法叫 LFQ(lookup-free quantization,不查码本、直接按正负号取比特)。投影的训练目标有两项。一项让这 13 个数各自靠近它取到的 +1 或 −1,这样取比特时丢的信息少。另一项是熵正则,让各种编号都被用到,避免大量视频挤在少数编号上。论文没有加重建损失,比特里的内容信息来自输入本身:它就是前两层没分完的内容残差。
  2. 挑出 3 个最没用的比特让出来。 13 个比特里选 3 个,一共 286 种组合,作者全部试一遍,选去掉后冲突增加最少的那 3 个。
  3. 让出的 3 个比特存价值档位。 3 个比特正好能表示 8 个档,所以用 7 个从小到大的边界值把价值统计量切成 8 档,编号 0 到 7。统计量越过了几个边界,就落在几号档,档位编号写进这 3 个比特。离线实验里,价值统计量用的是视频的历史点击率。

举个例子(示意):两个红烧肉视频的 10 个内容比特完全一样,都是 1011001110;一个点击率落在 6 号档,写成 110,一个落在 1 号档,写成 001。拼起来是两个不同的编号,模型能分开生成它们。编号总数还是 8192,词表没变。

实验:价值真的帮到推荐了吗?

离线实验用 KuaiRand-27K,这是快手公开的短视频数据,带多种曝光后反馈。每个用户只保留长播放的视频作为正样本序列,最后一个用于测试。生成模型是 OneRec-1.7B,用 LoRA 微调,束宽 200。下表各行都在同一个基础模型上比较。

方法(KuaiRand)Recall@3NDCG@3Recall@5NDCG@5
基础模型2.1111.6433.1492.046
加生成后重排2.3071.6753.2752.083
加 GRPO 训练2.4181.9533.6022.450
只加 UE-SID2.4091.9673.5852.436
只加 UGD2.5782.0473.7122.499
完整 UAGR2.7742.2743.9632.776

(单位 %,来自论文表 3)

先看解码这一项该和谁比。重排和 GRPO 用的是同一个价值分、同样的四项权重,只是用的位置不同:重排在生成完以后调顺序,GRPO 在训练时把价值分当奖励。只加 UGD 的 Recall@3 比重排高 0.27 个点,比 GRPO 高 0.16 个点。这说明同样的价值信号,放在剪枝时用比放在事后或训练时用更有效。GRPO 优化的是完整 SID 的奖励,它会改变生成概率,所以也间接影响剪枝,但不能保证高价值前缀在中间剪枝时留下来;UGD 直接改了每一步的剪枝分数。

和其他类型的方法比,完整 UAGR 在论文表 1 的所有方法里最好,Recall@3 比最强的基线高 7.74%。单独的部件则大致和已有的强基线相当:只加 UGD 的 2.578 与 RecForest 的 2.575 几乎一样。所以单个部件的提升不宜高估,两块合起来才拉开差距。

再看编码。单独加 UE-SID,Recall@3 从 2.111 提到 2.409。附录的拆解说明了各步的作用:只换成 13 比特的 LFQ,视频之间更好区分,推荐效果也变好;去掉 3 个最弱的比特,推荐效果反而略好;再加上 3 个价值比特,各项推荐指标都明显提升。作者还试了直接学一个 10 比特的 LFQ 再加 3 个价值比特,编码容量完全一样,Recall@3 却只有 2.168。作者的解释是,一开始只学 10 个比特压得太狠,丢掉了对推荐有用的内容区分;先学 13 个再去掉最弱的 3 个,能保留更多。这只是一个数据集上的一组对比。

最直接的证据是论文图 3。作者把有长播放反馈的视频算作高价值视频,以解码开始前这批视频为分母,统计每解码一个 token 后,它们的前缀还剩多少在束里。这是评测时的统计:长播放标签只用来挑出这批视频,解码时模型用的只是自己的预测。同样束宽下,加了 UGD 以后,第一个 token 后多保留 10.9 个百分点,第二个 token 后差距最大,为 16.3 个百分点,第三个 token 后保持在 16.2 个百分点(数字读自图中标注)。价值分从第一次剪枝起就有作用,到中间的 token 差距最大。

高价值视频的前缀保留率:横轴是解码到第几个 token,纵轴是还在束里的比例,蓝线是基础模型,橙线加了 UGD
高价值视频的前缀保留率:横轴是解码到第几个 token,纵轴是还在束里的比例,蓝线是基础模型,橙线加了 UGD

线上在快手短视频推荐场景替换原来的生成模型,做了一周 A/B:App 使用时长提升 0.074%,视频观看时长提升 0.206%,视频播放量提升 0.164%,三项都通过了 p<0.05 的显著性检验;QPS 只降 0.03%。这说明每步多算几个预测头的开销在线上几乎可以忽略。UAGR 从 2026 年 9 月起已在快手全量。

我认为它的局限

第一,离线指标的绝对值很低,基数也小。Recall@3 只有 2% 左右,完整 UAGR 比基础模型高 0.66 个点。数据集只有一个 KuaiRand-27K,没有在其他数据或其他基础模型上复现。

第二,线上只报了整体效果。0.206% 的观看时长提升是 UGD 和 UE-SID 一起上的结果,没有分开的线上实验,看不出线上收益主要来自哪一块。

第三,价值分的四项权重和 都是手工定的一组值:观看时长 0.6、长播放 0.2、点赞 0.1、转发 0.1, 取 1。实验只报告了这一组设置下的结果。换一个业务目标,权重要重新调,而这组值对结果有多敏感,现在的实验看不出来。

一个推荐团队可以怎么试

  1. 先只加解码时的价值分。论文是让行为预测头和生成模型一起训练,靠 stop-gradient 隔开;想更省事,可以先冻结现有生成模型,只在它的隐状态上训练几个预测头,这是我的简化。剪枝时把加权价值分加到累计概率上。对照组用同样价值分做生成后重排,看提升是不是来自剪枝这一步。
  2. 同时统计高价值目标的前缀保留率,像论文图 3 那样逐个 token 看。如果各个 token 上的保留率都没有明显提高,说明价值分没起作用,调法见第 4 步。
  3. 再看现有 SID 的冲突比例。如果超过几个百分点,再试把最后一个 token 换成按比特编码、让出几个比特存价值档位。
  4. 把四项权重和 当作要调的超参数:先在离线数据上扫几组,再挑一两组上线做 A/B,因为论文只给了一组设置。

结论

生成式推荐的价值信号,最该用在束搜索剪枝的那一刻;编码层面再给价值留几个比特,让内容相近的视频能被分开。

维度评价
问题重要性高。中间前缀被剪掉的候选,事后重排救不回来,序列级奖励也只能间接影响
方法创新性中。每步加价值分和在编码里留比特都不复杂,但两者配合、价值分只算当前一步的设计很清楚
实验证据中。有和重排、GRPO 的同条件对比和逐个 token 的保留率分析,但离线只有一个数据集,线上没拆开各部件
工程成本低到中。加几个轻量预测头,推理不多跑前向;编码要重建最后一个 token
是否值得尝试值得。已经上线生成式召回、又有多种曝光后反馈的团队,可以先试解码时加价值分

读完这篇,你觉得

点一下即可,无需登录;再点一次撤回。只统计匿名次数,不记录你是谁。

讨论

欢迎补充实验细节、复现经验或不同看法。需 GitHub 登录。

正在加载讨论…