论文: DualGR: Generative Retrieval with Long and Short-Term Interests Modeling
会议: WWW 2026
关键词: 生成式召回、短视频推荐、长短期兴趣、语义 ID、DBR、S2D、ENTP-Loss
1. 导读
在工业推荐系统中,用户最终看到的视频通常需要经过“召回—粗排—精排—重排”多级处理。其中,召回阶段负责从数十亿条视频中快速筛选出数百或数千条候选,因此决定了后续排序能够达到的上限。
传统召回多采用 Embedding-Based Retrieval(EBR),即将用户和视频编码为向量,再通过 ANN 近邻搜索完成匹配。它的优势是速度快、索引成熟,但也存在明显局限:多个兴趣容易被压缩成单一用户向量,候选视频与历史行为之间缺少动态交互,长期兴趣和短期兴趣也容易互相稀释。
生成式召回 Generative Retrieval(GR)提供了另一条路线:先把视频量化成层次化语义 ID,再像语言模型生成 Token 一样,自回归生成候选 SID。DualGR 在这一框架上进一步解决三个工业问题:
- 长期稳定兴趣与短期即时兴趣互相干扰;
- 长历史在细粒度 SID 解码中带来噪声和延迟;
- 曝光未点击信号难以被普通 NTP 目标利用。
DualGR 的核心逻辑可以概括为:
先区分长期与短期兴趣
↓
生成粗粒度level-1 SID
↓
只搜索同bucket历史
↓
继续生成level-2与level-3 SID
↓
利用曝光未点击让无效兴趣及时衰退
2. 研究场景:为什么双列短视频召回更难
DualGR 部署在快手双列 Explore Feed 中。与单列沉浸式短视频不同,双列页面一次会展示多个卡片,因此召回目标不再只是“找到一个最相关视频”,而是生成一个同时满足以下要求的候选集合:
- 相关性: 每个候选都应与用户有较高匹配度;
- 多样性: 同屏内容不能全部集中在同一主题;
- 实时性: 需要迅速捕捉用户刚刚出现的新兴趣;
- 稳定性: 短期热点不能完全覆盖长期偏好。
例如,用户长期观看汽车和数码内容,但最近 64 条行为突然集中在篮球视频上。如果只使用一个统一用户向量,长期偏好与短期热点可能被平均化。DualGR 因此显式建立长期与短期两条兴趣分支。
3. 从 EBR 到 GR
3.1 传统 EBR
传统双塔召回的流程是:
用户历史 → 用户塔 → 用户向量u
视频特征 → 视频塔 → 视频向量v
↓
sim(u,v)
↓
ANN搜索
EBR 的优势是可提前建立视频索引,线上检索速度快。但它通常将用户历史压缩成一个固定向量,目标视频与历史行为之间的细粒度交互较弱,多兴趣也容易发生混合。
3.2 生成式召回
生成式召回先将每个视频表示为层次化语义 ID:
<math><semantics><mrow><mi>s</mi><mo>(</mo><mi>v</mi><mo>)</mo><mo>=</mo><mrow><mo fence="true">(</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup><mo separator="true">,</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>2</mn><mo>)</mo></mrow></msup><mo separator="true">,</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>3</mn><mo>)</mo></mrow></msup><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">s(v)=\left(s^{(1)},s^{(2)},s^{(3)}\right) </annotation></semantics></math>s(v)=(s(1),s(2),s(3))
其中:
- <math><semantics><mrow><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">s^{(1)}</annotation></semantics></math>s(1):粗粒度语义方向;
- <math><semantics><mrow><msup><mi>s</mi><mrow><mo>(</mo><mn>2</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">s^{(2)}</annotation></semantics></math>s(2):更细一级子方向;
- <math><semantics><mrow><msup><mi>s</mi><mrow><mo>(</mo><mn>3</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">s^{(3)}</annotation></semantics></math>s(3):细粒度内容。
模型按顺序生成:
BOS → s¹ → s² → s³ → 映射为真实视频
其自回归概率为:
<math><semantics><mrow><msub><mi>p</mi><mi>θ</mi></msub><mrow><mo fence="true">(</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>:</mo><mi>L</mi><mo>)</mo></mrow></msup><mo>∣</mo><msub><mi>x</mi><mi>t</mi></msub><mo fence="true">)</mo></mrow><mo>=</mo><msubsup><mo>∏</mo><mrow><mi mathvariant="normal">ℓ</mi><mo>=</mo><mn>1</mn></mrow><mrow><mi>L</mi></mrow></msubsup><msub><mi>p</mi><mi>θ</mi></msub><mrow><mo fence="true">(</mo><msup><mi>s</mi><mrow><mo>(</mo><mi mathvariant="normal">ℓ</mi><mo>)</mo></mrow></msup><mo>∣</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>:</mo><mi mathvariant="normal">ℓ</mi><mo>−</mo><mn>1</mn><mo>)</mo></mrow></msup><mo separator="true">,</mo><msub><mi>x</mi><mi>t</mi></msub><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">p_\theta\left(s^{(1:L)}\mid x_t\right) = \prod_{\ell=1}^{L} p_\theta\left( s^{(\ell)} \mid s^{(1:\ell-1)},x_t \right) </annotation></semantics></math>pθ(s(1:L)∣xt)=ℓ=1∏Lpθ(s(ℓ)∣s(1:ℓ−1),xt)
Beam Search 可以同时保留多条高概率路径,因此天然适合召回阶段需要“多个候选方向”的目标。
4. DualGR 的三个核心挑战
4.1 长短期兴趣互相干扰
长期偏好和短期热点被放入同一上下文后,注意力与梯度可能互相稀释。DualGR 使用 DBR(Dual-Branch Long/Short-Term Router) 分别建模两种时间尺度。
4.2 长历史噪声与计算压力
生成第二级和第三级 SID 时,完整历史中大量行为与当前粗粒度方向无关。DualGR 使用 S2D(Search-based SID Decoding),只保留与已确定 level-1 SID 相同 Bucket 的历史。
4.3 缺少显式负反馈
普通 NTP 主要学习正样本,难以利用大量曝光未点击日志。DualGR 使用 ENTP-Loss(Exposure-aware NTP Loss),将未点击曝光作为粗粒度负反馈。
5. 整体框架
DualGR 的完整流程如下:
视频向量
↓
RQ-KMeans量化
↓
三级SID:(s¹,s²,s³)
↓
DBR:长期/短期分支预测s¹
↓
S2D:在完整历史中搜索同bucket行为
↓
生成s²、s³
↓
长期与短期候选合并、去重
↓
SID映射为真实视频
三个模块的分工如下:
| 模块 | 解决的问题 | 主要作用阶段 |
|---|---|---|
| DBR | 长短期兴趣相互干扰 | level-1 SID |
| S2D | 长历史噪声与延迟 | level-2/3 SID |
| ENTP-Loss | 曝光未点击无法利用 | 训练目标 |
6. 视频量化与层次化 SID
DualGR 使用 RQ-KMeans 将视频向量量化为三级 SID。
第一层 Codebook 产生粗粒度 Token <math><semantics><mrow><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">s^{(1)}</annotation></semantics></math>s(1);随后对量化残差继续聚类,得到 <math><semantics><mrow><msup><mi>s</mi><mrow><mo>(</mo><mn>2</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">s^{(2)}</annotation></semantics></math>s(2) 和 <math><semantics><mrow><msup><mi>s</mi><mrow><mo>(</mo><mn>3</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">s^{(3)}</annotation></semantics></math>s(3)。直观上可以理解为:
s¹:体育
s²:篮球
s³:NBA比赛集锦
论文设置:
- SID 层数:<math><semantics><mrow><mi>L</mi><mo>=</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">L=3</annotation></semantics></math>L=3;
- 每层 Codebook 大小:8192。
最终系统通过预建映射 Map,将 SID 转换为具体视频 ID。
7. DBR:长短期兴趣双分支路由
7.1 两个历史窗口
DualGR 分别构造:
- 长期历史 <math><semantics><mrow><msubsup><mi>H</mi><mi>t</mi><mrow><mi>l</mi><mi>o</mi><mi>n</mi><mi>g</mi></mrow></msubsup></mrow><annotation encoding="application/x-tex">H_t^{long}</annotation></semantics></math>Htlong:最近 1000 条正向行为;
- 短期历史 <math><semantics><mrow><msubsup><mi>H</mi><mi>t</mi><mrow><mi>s</mi><mi>h</mi><mi>o</mi><mi>r</mi><mi>t</mi></mrow></msubsup></mrow><annotation encoding="application/x-tex">H_t^{short}</annotation></semantics></math>Htshort:最近 64 条正向行为。
模型把历史行为对应的 level-1 SID Embedding 做 Pooling,得到长期与短期兴趣摘要:
<math><semantics><mrow><msub><mi>r</mi><mrow><mi>l</mi><mi>o</mi><mi>n</mi><mi>g</mi></mrow></msub><mo>=</mo><mi>P</mi><mi>o</mi><mi>o</mi><mi>l</mi><mrow><mo fence="true">(</mo><mrow><mo fence="true">{</mo><msubsup><mi>E</mi><mrow><mi>v</mi><mi>o</mi><mi>c</mi><mi>a</mi><mi>b</mi></mrow><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msubsup><mo>[</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup><mo>(</mo><mi>a</mi><mo>)</mo><mo>]</mo><mo>:</mo><mi>a</mi><mo>∈</mo><msubsup><mi>H</mi><mi>t</mi><mrow><mi>l</mi><mi>o</mi><mi>n</mi><mi>g</mi></mrow></msubsup><mo fence="true">}</mo></mrow><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">r_{long}=Pool\left( \left\{ E_{vocab}^{(1)}[s^{(1)}(a)]: a\in H_t^{long} \right\} \right) </annotation></semantics></math>rlong=Pool({Evocab(1)[s(1)(a)]:a∈Htlong})
<math><semantics><mrow><msub><mi>r</mi><mrow><mi>s</mi><mi>h</mi><mi>o</mi><mi>r</mi><mi>t</mi></mrow></msub><mo>=</mo><mi>P</mi><mi>o</mi><mi>o</mi><mi>l</mi><mrow><mo fence="true">(</mo><mrow><mo fence="true">{</mo><msubsup><mi>E</mi><mrow><mi>v</mi><mi>o</mi><mi>c</mi><mi>a</mi><mi>b</mi></mrow><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msubsup><mo>[</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup><mo>(</mo><mi>a</mi><mo>)</mo><mo>]</mo><mo>:</mo><mi>a</mi><mo>∈</mo><msubsup><mi>H</mi><mi>t</mi><mrow><mi>s</mi><mi>h</mi><mi>o</mi><mi>r</mi><mi>t</mi></mrow></msubsup><mo fence="true">}</mo></mrow><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">r_{short}=Pool\left( \left\{ E_{vocab}^{(1)}[s^{(1)}(a)]: a\in H_t^{short} \right\} \right) </annotation></semantics></math>rshort=Pool({Evocab(1)[s(1)(a)]:a∈Htshort})
7.2 训练阶段:Hard Gate 只选一个分支
训练时已知目标视频真实的 level-1 SID <math><semantics><mrow><msubsup><mi>s</mi><mo>⋆</mo><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msubsup></mrow><annotation encoding="application/x-tex">s_\star^{(1)}</annotation></semantics></math>s⋆(1),模型计算目标与两个兴趣摘要的余弦相似度:
<math><semantics><mrow><msub><mi>γ</mi><mrow><mi>l</mi><mi>o</mi><mi>n</mi><mi>g</mi></mrow></msub><mo>=</mo><mi>cos</mi><mo>(</mo><msubsup><mi>e</mi><mo>⋆</mo><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msubsup><mo separator="true">,</mo><msub><mi>r</mi><mrow><mi>l</mi><mi>o</mi><mi>n</mi><mi>g</mi></mrow></msub><mo>)</mo></mrow><annotation encoding="application/x-tex">\gamma_{long}=\cos(e_\star^{(1)},r_{long}) </annotation></semantics></math>γlong=cos(e⋆(1),rlong)
<math><semantics><mrow><msub><mi>γ</mi><mrow><mi>s</mi><mi>h</mi><mi>o</mi><mi>r</mi><mi>t</mi></mrow></msub><mo>=</mo><mi>cos</mi><mo>(</mo><msubsup><mi>e</mi><mo>⋆</mo><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msubsup><mo separator="true">,</mo><msub><mi>r</mi><mrow><mi>s</mi><mi>h</mi><mi>o</mi><mi>r</mi><mi>t</mi></mrow></msub><mo>)</mo></mrow><annotation encoding="application/x-tex">\gamma_{short}=\cos(e_\star^{(1)},r_{short}) </annotation></semantics></math>γshort=cos(e⋆(1),rshort)
随后选择相似度更高的窗口作为 coarse-step 历史:
γlong更大 → 选择长期分支
γshort更大 → 选择短期分支
这样可以避免训练时两个时间尺度继续互相稀释。
7.3 推理阶段:两条分支都解码
推理时没有真实目标 SID,无法提前路由到某一个分支,因此长期和短期分支分别进行 Beam Search:
Long Branch → 稳定偏好候选
Short Branch → 即时兴趣候选
↓
Merge & Dedup
DBR 的关键点是:
- 训练时只激活一个分支;
- 推理时两个分支都运行;
- DBR 主要服务于 level-1 粗粒度 SID;
- 它不是复杂 MoE,而是基于目标相似度的 Hard Gate。
8. S2D:先确定大类,再搜索同类历史
当 level-1 SID 已经确定后,完整历史中的大量行为会成为无关噪声。
例如已经预测:
s¹ = 体育
那么汽车、美食、音乐等历史不应继续干扰“篮球还是足球”的判断。
8.1 训练阶段
训练时使用真实目标 level-1 SID 搜索同 Bucket 历史:
<math><semantics><mrow><msubsup><mi>H</mi><mi>t</mi><mi>b</mi></msubsup><mo>(</mo><msubsup><mi>s</mi><mo>⋆</mo><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msubsup><mo>)</mo><mo>=</mo><mi>S</mi><mi>e</mi><mi>a</mi><mi>r</mi><mi>c</mi><mi>h</mi><mrow><mo fence="true">(</mo><mrow><mo fence="true">{</mo><mi>a</mi><mo>∈</mo><msub><mi>H</mi><mi>t</mi></msub><mo>:</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup><mo>(</mo><mi>a</mi><mo>)</mo><mo>=</mo><msubsup><mi>s</mi><mo>⋆</mo><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msubsup><mo fence="true">}</mo></mrow><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">H_t^b(s_\star^{(1)}) = Search\left( \left\{ a\in H_t: s^{(1)}(a)=s_\star^{(1)} \right\} \right) </annotation></semantics></math>Htb(s⋆(1))=Search({a∈Ht:s(1)(a)=s⋆(1)})
随后在 Teacher Forcing 下预测后续 SID:
p_\theta\left( s_\star^{(\ell)} \mid s_\star^{(1:\ell-1)},x_t^{(>1)} \right), \quad \ell=2,\dots,L8.2 推理阶段
推理时先由 DBR 分支预测 <math><semantics><mrow><msup><mover accent="true"><mrow><mi>s</mi></mrow><mo>^</mo></mover><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\hat{s}^{(1)}</annotation></semantics></math>s^(1),再在完整历史 <math><semantics><mrow><msub><mi>H</mi><mi>t</mi></msub></mrow><annotation encoding="application/x-tex">H_t</annotation></semantics></math>Ht 中搜索:
<math><semantics><mrow><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup><mo>(</mo><mi>a</mi><mo>)</mo><mo>=</mo><msup><mover accent="true"><mrow><mi>s</mi></mrow><mo>^</mo></mover><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">s^{(1)}(a)=\hat{s}^{(1)} </annotation></semantics></math>s(1)(a)=s^(1)
的行为,并继续生成 <math><semantics><mrow><msup><mover accent="true"><mrow><mi>s</mi></mrow><mo>^</mo></mover><mrow><mo>(</mo><mn>2</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\hat{s}^{(2)}</annotation></semantics></math>s^(2) 与 <math><semantics><mrow><msup><mover accent="true"><mrow><mi>s</mi></mrow><mo>^</mo></mover><mrow><mo>(</mo><mn>3</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">\hat{s}^{(3)}</annotation></semantics></math>s^(3)。
预测ŝ¹
↓
搜索完整历史中的同bucket行为
↓
形成目标相关上下文
↓
生成ŝ²、ŝ³
8.3 为什么能提升质量与效率
同 Bucket 历史规模近似为:
<math><semantics><mrow><mrow><mo fence="true">∣</mo><msub><mi>H</mi><mi>t</mi></msub><mo>(</mo><msup><mi>s</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup><mo>)</mo><mo fence="true">∣</mo></mrow><mo>≈</mo><mfrac><mrow><mi mathvariant="normal">∣</mi><msub><mi>H</mi><mi>t</mi></msub><mi mathvariant="normal">∣</mi></mrow><mrow><mi mathvariant="normal">∣</mi><msup><mrow><mi mathvariant="script">V</mi></mrow><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup><mi mathvariant="normal">∣</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">\left|H_t(s^{(1)})\right| \approx \frac{|H_t|}{|\mathcal{V}^{(1)}|} </annotation></semantics></math>∣∣∣Ht(s(1))∣∣∣≈∣V(1)∣∣Ht∣
当 level-1 Codebook 很大时,同 Bucket 历史远小于完整历史,因此 S2D 能够:
- 去除无关类别噪声;
- 缩短 Cross-Attention 序列;
- 在固定延迟下使用更长原始历史;
- 提高细粒度 SID 的语义一致性。
9. ENTP-Loss:让无效兴趣及时衰退
普通 NTP 对正样本提高完整 SID 概率:
<math><semantics><mrow><mo>−</mo><mi>log</mi><msup><mi>p</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msup><mo>−</mo><mi>log</mi><msup><mi>p</mi><mrow><mo>(</mo><mn>2</mn><mo>)</mo></mrow></msup><mo>−</mo><mi>log</mi><msup><mi>p</mi><mrow><mo>(</mo><mn>3</mn><mo>)</mo></mrow></msup></mrow><annotation encoding="application/x-tex">-\log p^{(1)}-\log p^{(2)}-\log p^{(3)} </annotation></semantics></math>−logp(1)−logp(2)−logp(3)
DualGR 进一步组织训练样本:
<math><semantics><mrow><mo>(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><msubsup><mi>s</mi><mi>i</mi><mrow><mo>(</mo><mn>1</mn><mo>:</mo><mi>L</mi><mo>)</mo></mrow></msubsup><mo separator="true">,</mo><msub><mi>c</mi><mi>i</mi></msub><mo>)</mo></mrow><annotation encoding="application/x-tex">(x_i,s_i^{(1:L)},c_i) </annotation></semantics></math>(xi,si(1:L),ci)
其中:
- <math><semantics><mrow><msub><mi>c</mi><mi>i</mi></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">c_i=1</annotation></semantics></math>ci=1:点击或有效观看等正样本;
- <math><semantics><mrow><msub><mi>c</mi><mi>i</mi></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">c_i=0</annotation></semantics></math>ci=0:曝光未点击负样本。
ENTP-Loss 为:
<math><semantics><mrow><msub><mrow><mi mathvariant="script">L</mi></mrow><mrow><mi>E</mi><mi>N</mi><mi>T</mi><mi>P</mi></mrow></msub><mo>=</mo><mfrac><mrow><mn>1</mn></mrow><mrow><mi>N</mi></mrow></mfrac><msub><mo>∑</mo><mrow><mi>i</mi><mo>∈</mo><mrow><mi mathvariant="script">B</mi></mrow></mrow></msub><mrow><mo fence="true">[</mo><msub><mi>c</mi><mi>i</mi></msub><msubsup><mo>∑</mo><mrow><mi mathvariant="normal">ℓ</mi><mo>=</mo><mn>1</mn></mrow><mrow><mi>L</mi></mrow></msubsup><mo>(</mo><mo>−</mo><mi>log</mi><msubsup><mi>p</mi><mi>i</mi><mrow><mo>(</mo><mi mathvariant="normal">ℓ</mi><mo>)</mo></mrow></msubsup><mo>)</mo><mo>+</mo><mo>(</mo><mn>1</mn><mo>−</mo><msub><mi>c</mi><mi>i</mi></msub><mo>)</mo><mrow><mo fence="true">(</mo><mo>−</mo><mi>α</mi><mi>log</mi><mo>(</mo><mn>1</mn><mo>−</mo><msubsup><mi>p</mi><mi>i</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></msubsup><mo>)</mo><mo fence="true">)</mo></mrow><mo fence="true">]</mo></mrow></mrow><annotation encoding="application/x-tex">\mathcal{L}_{ENTP} = \frac{1}{N} \sum_{i\in\mathcal{B}} \left[ c_i \sum_{\ell=1}^{L} (-\log p_i^{(\ell)}) + (1-c_i) \left( -\alpha\log(1-p_i^{(1)}) \right) \right] </annotation></semantics></math>LENTP=N1i∈B∑[ciℓ=1∑L(−logpi(ℓ))+(1−ci)(−αlog(1−pi(1)))]
正样本仍然学习三级 SID;负样本只惩罚 level-1 SID。
为什么只惩罚第一级
曝光未点击不一定表示用户明确不喜欢某个具体视频,可能受到封面、位置和同屏竞争影响。若直接惩罚 level-2/3,容易引入细粒度假负样本。
因此,ENTP 只表达:
某个粗粒度兴趣方向正在减弱。
论文最终设置 <math><semantics><mrow><mi>α</mi><mo>=</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>1</mn></mrow><annotation encoding="application/x-tex">\alpha=0.1</annotation></semantics></math>α=0.1。
10. 完整线上推理流程
用户静态特征u + 完整历史Ht
↓
┌───────┴───────┐
↓ ↓
Long Branch Short Branch
1000条历史 64条历史
↓ ↓
分别Beam Search预测level-1 SID
↓ ↓
S2D在完整历史中搜索同bucket行为
↓ ↓
继续生成level-2和level-3
└───────┬───────┘
↓
Merge & Dedup
↓
SID映射到Videos
11. 实验设置
DualGR 在快手真实双列 Explore Feed 上进行实验,场景规模包括:
- 1 亿以上用户;
- 每日 10 亿次视频观看;
- 每日 100 亿次曝光。
对比方法包括:
- ComiRec;
- PDN;
- KuaiFormer;
- TIGER;
- DualGR。
模型主要配置:
| 配置 | 数值 |
|---|---|
| Transformer Blocks | 4 |
| Model Dimension | 512 |
| Attention Heads | 8 |
| FFN Dimension | 1024 |
| SID 层数 | 3 |
| 每层 Codebook | 8192 |
| 完整历史长度 | 1000 |
| 长期窗口 | 1000 |
| 短期窗口 | 64 |
| ENTP <math><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math>α | 0.1 |
评价指标采用 Online Hit Rate:HR@100、HR@500 和 HR@1000。
12. 总体结果
| Method | HR@100 | HR@500 | HR@1000 |
|---|---|---|---|
| ComiRec | 2.539% | 6.134% | 8.249% |
| PDN | 2.343% | 5.483% | 7.249% |
| KuaiFormer | 4.495% | 7.251% | 12.356% |
| TIGER | 4.936% | 8.184% | 14.442% |
| DualGR | 6.827% | 10.319% | 19.529% |
相对 TIGER,DualGR 的提升约为:
- HR@100:+38.3%;
- HR@500:+26.1%;
- HR@1000:+35.2%。
这说明通用生成式召回仍不足以直接解决工业短视频场景,显式建模时间尺度、搜索目标相关历史和利用曝光负反馈都很重要。
13. 参数敏感性
13.1 短期窗口长度
短期窗口过短时,模型无法充分捕捉近期兴趣;过长时,短期分支会逐渐接近长期分支,互补性下降。
论文最终采用:
<math><semantics><mrow><msub><mi>L</mi><mrow><mi>s</mi><mi>h</mi><mi>o</mi><mi>r</mi><mi>t</mi></mrow></msub><mo>=</mo><mn>6</mn><mn>4</mn></mrow><annotation encoding="application/x-tex">L_{short}=64 </annotation></semantics></math>Lshort=64
13.2 ENTP 权重
<math><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math>α 过大时,会过度惩罚曝光未点击样本,压制真实兴趣;过小时,无效兴趣衰退过慢。
论文最终采用:
<math><semantics><mrow><mi>α</mi><mo>=</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>1</mn></mrow><annotation encoding="application/x-tex">\alpha=0.1 </annotation></semantics></math>α=0.1
14. 在线 A/B 测试
作者在快手双列 Explore Feed 中进行了一周线上 A/B 测试:
- 流量:6%;
- 接入方式:额外召回通道;
- 视频观看次数:+0.527%;
- 用户观看时长:+0.432%;
- 端到端响应延迟:无可测量增加。
召回只是多阶段推荐系统中的一个通道,后续还会经过粗排、精排、重排和业务规则。因此,在亿级用户规模下,约 0.5% 的稳定线上提升已经具有明显业务价值。
15. 消融实验
| Method | HR@100 | HR@500 | HR@1000 |
|---|---|---|---|
| w/o DBR | 5.134% | 8.892% | 15.379% |
| w/o S2D | 6.257% | 9.182% | 16.287% |
| w/o ENTP-Loss | 6.672% | 9.837% | 17.576% |
| DualGR | 6.827% | 10.319% | 19.529% |
去掉 DBR
HR@1000 下降 4.150 个百分点,说明显式区分长期兴趣和短期兴趣最关键。
去掉 S2D
HR@1000 下降 3.242 个百分点,说明同 Bucket 历史搜索不仅提高效率,也显著提升细粒度生成质量。
去掉 ENTP-Loss
HR@1000 下降 1.953 个百分点,说明曝光未点击信号能够促进非兴趣方向及时退出。
三个模块的影响大小为:
DBR > S2D > ENTP
但它们都围绕 level-1 SID 形成协同作用,贡献不能简单相加。
16. DualGR 为什么有效
DualGR 的三个模块分别对应推荐系统中的三个核心问题:
DBR
解决长短期时间尺度冲突
↓
S2D
解决细粒度解码中的长历史噪声
↓
ENTP
解决失效兴趣缺少负反馈的问题
DBR 决定应从哪个时间尺度理解粗粒度兴趣;S2D 在粗粒度方向确定后检索相关历史;ENTP 则让持续曝光但用户不响应的方向及时降低概率。
17. 主要创新点
- 显式区分长期与短期兴趣。 不再只依赖 Beam Search 被动产生多兴趣。
- 训练和推理采用不同路由策略。 训练时 Hard Gate 选一个分支,推理时两个分支都生成候选。
- 将搜索引入层次化 SID 解码。 先生成大类,再检索同类历史完成细粒度生成。
- 把曝光未点击转化为粗粒度负反馈。 避免细粒度假负样本。
- 同时验证离线效果与线上业务收益。 在线提升且没有可测量延迟增长。
18. 局限与思考
18.1 数据不可公开复现
实验基于快手内部工业数据,外部研究者难以完整复现。
18.2 Hard Gate 较为刚性
训练时只选择一个分支,虽然监督更干净,但可能忽略长期和短期共同影响目标的情况。
18.3 负反馈仍然较粗
ENTP 只处理 level-1 SID,细粒度兴趣变化仍有进一步建模空间。
18.4 SID 质量依赖量化
RQ-KMeans 形成的层次结构是否具有稳定语义,会直接影响生成、搜索和最终映射效果。
18.5 多样性指标仍可补充
论文强调双列页面的多样性需求,但核心指标仍是 HR@K,未来可以增加主题覆盖率或候选多样性指标。
19. 总结
DualGR 是一套面向工业短视频场景的生成式召回框架。
它首先将视频量化成三级层次化 SID,再像语言模型一样逐 Token 生成候选。在此基础上:
- DBR 分开建模长期稳定兴趣与短期即时兴趣;
- S2D 根据粗粒度 SID 搜索同 Bucket 历史;
- ENTP-Loss 利用曝光未点击让无效兴趣及时衰退。
其完整逻辑是:
长期分支 + 短期分支
↓
生成粗粒度SID
↓
搜索目标相关历史
↓
生成细粒度SID
↓
合并、去重并映射到视频
DualGR 将 HR@1000 从 TIGER 的 14.442% 提升到 19.529%,并在真实线上 A/B 测试中带来 +0.527% 视频观看次数和 +0.432% 观看时长。
工业生成式召回不仅要会“生成”,还要能够控制兴趣时间尺度、动态筛选历史上下文,并让失效兴趣及时退出候选空间。