DLRM 的根本瓶颈
工业推荐系统长期由 DLRM(深度学习推荐模型) 主导,其核心特征:
- 异构特征:上千个数值特征(CTR、比例等)+ 类别特征(商品 ID、创作者 ID 等),特征空间高基数(十亿级 vocabulary)
- 手工特征工程:特征大量依赖人工设计,维护成本极高
- 扩展瓶颈:DLRM 在增大计算量时质量不再提升(Zhao et al., 2023),无法享受 scaling law 红利
- 训练效率:传统 impression-level 训练中,attention 的复杂度为 $O(N^3 d + N^2 d^2)$,代价极高
GR 的核心洞察
论文的核心主张是:用户行为是一种新的模态(modality),可以类比语言进行生成式建模:
关键洞察三条:
- 召回和排序都可以被重新表述为序列转换任务(Sequential Transduction Task)
- 序列化的特征空间允许以生成式方式训练,摊销 encoder 成本,减少数量级的计算量
- 生成式训练使模型质量随计算量呈幂律增长(Scaling Law),DLRMs 则饱和
2.1 统一特征空间:把异构特征序列化
工业 DLRM 的特征体系极其庞大——一个典型的大规模推荐系统往往依赖数万个人工设计的特征,可分为两大类:类别/稀疏特征(Categorical / Sparse)和数值/稠密特征(Numerical / Dense)。GR 的核心目标是把这两类特征统一整合为一条时间序列,彻底消除手工特征工程。
① 类别特征(Categorical / Sparse):序列化步骤拆解
类别特征的典型例子包括:用户点赞的视频、关注的创作者(分类别,如户外/美食)、用户语言、加入的社区、发起请求的城市……这些都是高基数的 ID 类特征。GR 通过以下三步将其序列化:
选取最长的时间序列作为主干,通常是"用户直接交互过的 item 序列"——即把用户历史上看过、点赞、分享的所有内容按时间排成一列,记作: $$(\Phi_0, a_0, \Phi_1, a_1, \ldots, \Phi_{n_c-1}, a_{n_c-1})$$ 其中 $\Phi_i$ 是系统推送给用户的第 $i$ 个内容(视频、帖子等),$a_i$ 是用户对它的行为(点赞 / 跳过 / 完整观看+分享 等)。
其余类别特征(如关注的创作者列表、加入的社区、所在城市)都是随时间缓慢变化的序列。如果原样拼接,序列长度会爆炸。GR 的处理方式是:
对每段连续相同值,只保留该段的最早一条(Keep the earliest entry per consecutive segment),再把压缩后的结果按时间戳插入主时间序列中对应的位置。
由于这些特征变化极慢,压缩后每个特征增加的 token 数极少,对总序列长度的影响可忽略不计。
把主时间序列与所有压缩后的辅助序列,按时间戳排序,合并成一条统一序列——这就是 GR 模型的输入。论文 Figure 2 中用 $\Phi_i$ 统一表示合并后的主时间序列第 $i$ 个 token,$\Psi_k(t_j)$ 表示在时刻 $t_j$ emit 的第 $k$ 个训练样本。
场景:用户 Alice 在 Meta 短视频平台的 30 天历史记录(简化版)
DLRM 视角的原始特征集(每次请求都要准备这些):
| 特征类型 | 内容示例 | 基数 |
|---|---|---|
| 用户交互视频序列 | [v_0012, v_0089, v_3301, v_2204, v_0077, ...](过去 30 天 1200 个) | 10亿级 |
| 关注的创作者(美食类) | [creator_A, creator_B, creator_C](2 周前关注,之后未变) | 1亿级 |
| 关注的创作者(户外类) | [creator_X](1 个月前关注,之后未变) | 同上 |
| 加入的社区 | [community_hiking, community_cooking](1 个月前加入,未变) | 千万级 |
| 用户语言 | en-US(从未变化) | 千级 |
| 城市 | Seattle(偶尔变化) | 百万级 |
GR 序列化后的统一时间序列(按时间戳排列):
t=30天前 → [community_hiking] ← 加入社区(辅助特征,只保留段首) t=30天前 → [creator_X] ← 关注户外创作者(辅助特征,段首) t=28天前 → [v_0001 → 点赞] ← 主序列 t=28天前 → [community_cooking] ← 加入美食社区(段首) t=25天前 → [v_0002 → 跳过] ← 主序列 t=20天前 → [creator_A] ← 关注美食创作者 A(段首) t=18天前 → [creator_B] ← 关注美食创作者 B(段首) t=15天前 → [v_0089 → 完整观看+分享] ← 主序列 ...(后续 1200 个视频 token)... t=今天 → [v_3301 → 点赞] ← 最近的交互
效果对比:
- DLRM:需要对每个
(user, item)impression 构造包含数万个特征的样本,且"关注的创作者"等需要用 attention pooling 或 MLP 处理,逻辑分散在多个子模块 - GR:所有信息合并为一条约 1200+ token 的时间序列,输入统一,模型用 HSTU 一次性处理
② 数值特征(Numerical / Dense):为什么可以"删掉"?
数值特征的典型例子:过去 7 天对"户外"话题视频的 CTR(点击率)、过去 24 小时的视频完成率、用户历史平均观看时长比例……这类特征有两个问题导致序列化代价极高:
- 变化频率极高:每次用户与一个 item 交互,相关计数器都会更新。例如 CTR 在每次 impression 后都会变化,完全随时间序列化意味着每个 token 都要附带几十个随时变化的数值,存储和计算成本爆炸。
- 衍生性强:CTR 本质上是"用户对某类话题视频的点击次数 / 曝光次数"的聚合。而这个分子、分母都可以从原始的交互序列中推算出来——如果模型表达能力足够强,它完全可以从序列中自己推算出 CTR。
数值特征:Alice 过去 30 天对"户外"话题视频的 CTR = 0.42(比全体用户均值 0.08 高很多)
这个数值背后对应的是什么?Alice 过去 30 天的序列中:
- 共出现了 50 个户外话题视频,其中 21 个
a_i = 点赞/完整观看,29 个a_i = 跳过 - CTR = 21/50 = 0.42
模型如何隐式得到这个信息?HSTU 在对候选"户外视频 $\Phi_{new}$"打分时,会对序列中所有历史 token 做 attention。它"看到"了 21 个正面行为 + 29 个跳过,这些信息通过 pointwise aggregated attention 积累到候选 token 对应的表示中。模型不需要 0.42 这个数字,它看到的原始交互比这个数字更细粒度、更信息丰富。
前提条件:序列要足够长(包含足够多的历史)+ 模型要 target-aware(即目标 item 的话题标签需要在序列中可见,以便 attention 能区分"户外"和"美食"视频)。这也是为什么 GR 强调 target-aware 排序公式的原因。
① GR(完整版,只用交互序列,无数值特征)
② GR (interactions only)(仅考虑用户交互的 item,不含 action 类型等)
③ GR (content-based)(只用内容特征,不用行为序列)
结果显示"GR (interactions only)"比完整 GR 差 2.6% NE,"GR (content-based)"则与 DLRM 有显著差距。这验证了两点:行为动作(action 类型)很重要;内容特征(文本语义)远不如行为序列。
③ 统一序列的完整形式:符号约定
整合后,GR 的输入序列可以写成:
- $\Phi_i \in \mathbb{X}_c$:系统推送给用户的第 $i$ 个内容(item),$\mathbb{X}_c$ 是 item 空间(非稳态,每分钟新增内容)
- $a_i \in \mathbb{X}$:用户对 $\Phi_i$ 的行为(点赞 / 跳过 / 完整观看 / 分享等),每种行为是独立 token
- $n_c$:用户历史交互过的内容总数
- $E, F, G, H$:论文 Figure 2 中标注的辅助类别特征(创作者 ID、社区 ID、语言、城市等),压缩后按时间插入
- 整条序列统一用 $\Phi_i$ 标记合并结果,$\Psi_k(t_j)$ 表示时刻 $t_j$ emit 的第 $k$ 个训练样本
④ 近似保证:GR ≈ DLRM 当序列无限长
论文给出了一个关键理论声明:GR 的统一序列特征空间是 DLRM 完整特征空间的近似,且近似质量随序列长度趋近无穷而收敛(原文:"the new approach approximating the full DLRM feature space as sequence length tends to infinity")。
直觉理解:越长的序列包含越完整的用户历史,模型就越能从行为序列中推算出那些数值聚合特征(CTR、比例等)。这为 GR "删掉数值特征" 提供了理论依据,也解释了为什么 Scaling Law 中序列长度比参数量更重要——它直接决定了 GR 与完整 DLRM 特征空间的近似精度。
GR = Generative Recommenders(生成式推荐系统),是本论文提出的新范式的名字。
传统推荐系统叫 DLRM(Deep Learning Recommendation Model)——用大量人工设计特征 + 各种神经网络做 CTR/CVR 预测。
GR 的核心思想是:把推荐问题从"特征预测"重新表述为"序列生成"——像语言模型生成下一个 token 一样,让模型生成用户下一个感兴趣的 item 或预测用户的下一个行为。GR 的 encoder 就是本文设计的 HSTU 架构,所以 "GR" 和 "HSTU" 经常一起出现:HSTU 是架构,GR 是用 HSTU 实现的推荐系统范式。
2.2 排序与召回重新表述为序列换能任务
GR 的关键技术动作是:把推荐系统最核心的两个任务——排序(Ranking)和召回(Retrieval),统一成一种叫做序列换能(Sequential Transduction)的形式,然后用 HSTU encoder 一次性解决。
① 什么是"序列换能"
"换能(Transduction)"来自 NLP 领域,指的是输入序列 → 输出序列的映射,和语言翻译(seq2seq)或语音识别本质一样。在推荐场景里,定义如下:
- $x_i \in \mathbb{X}$:输入序列的第 $i$ 个 token(可以是 item $\Phi_i$、行为 $a_i$、辅助类别特征等)
- $t_i$:第 $i$ 个 token 被观测到的时间戳,序列按时间升序排列
- $y_i \in \mathbb{X} \cup \{\emptyset\}$:输出序列的第 $i$ 个 token;$y_i = \emptyset$ 表示该位置没有监督信号(不需要预测)
- $\mathbb{X}_c \subseteq \mathbb{X}$:item 子空间(视频、帖子等),$\mathbb{X}$ 还包括 action token 等
- $n_c$:用户历史交互 item 总数
这个框架的精妙之处在于:输入和输出是等长的——每个输入 token 对应一个输出 slot,不需要的位置填 $\emptyset$。这使得排序和召回可以在同一个 causal(因果/自回归)encoder 框架下表达,无需 decoder。
② 召回任务(Retrieval)
召回的目标:给定用户历史,找出用户下一个最可能感兴趣的 item。
标准召回被建模为:学习分布 $p(\Phi_{i+1} \mid u_i)$,其中 $u_i$ 是用户在第 $i$ 步的表示,目标是找到 $\arg\max_{\Phi \in \mathbb{X}_c} p(\Phi \mid u_i)$。
在序列换能框架下,召回的输入和输出定义为:
| 位置 $i$ | 输入 $x_i$ | 输出 $y_i$ | 含义 |
|---|---|---|---|
| $0$ | $(\Phi_0, a_0)$ | $\Phi_1$(下一个正样本 item) | 看过 $\Phi_0$ 并做了行为 $a_0$ 后,预测下一个 item |
| $1$ | $(\Phi_1, a_1)$ | $\Phi_2$ | 类似 |
| $i$ | $(\Phi_i, a_i)$ | $\Phi_{i+1}$ | 类似 |
| 辅助特征位置 | 城市/语言等 | $\emptyset$ | 不需要预测,跳过 |
1. 监督信号不一定是下一个 token:用户可能对推给他的 $\Phi_{i+1}$ 反应是负面的(跳过),此时 $y_i$ 不用 $\Phi_{i+1}$,而要用能反映"真正感兴趣"的正样本(如该时间窗口内主动搜索的 item)。
2. 辅助特征位置输出为 $\emptyset$:当 $x_{i+1}$ 是城市、语言这类非 engagement 特征时,$y_i$ 设为 $\emptyset$,该位置不参与损失计算。
用户序列(简化版 5 步):
位置0: x0 = (Φ_篮球视频, a=完整观看) → y0 = Φ_足球视频(下一个正样本) 位置1: x1 = (Φ_足球视频, a=点赞) → y1 = Φ_羽毛球视频 位置2: x2 = 城市=Seattle → y2 = ∅(不预测) 位置3: x3 = (Φ_羽毛球视频, a=跳过) → y3 = Φ_网球视频 位置4: x4 = (Φ_网球视频, a=分享) → y4 = Φ_?(推理时:预测下一个)
训练时:位置0/1/3/4 各 emit 一个训练样本(正负样本对),位置2 跳过。一次 forward pass,4 个训练样本同时得到监督,这就是"生成式训练"的效率来源(§2.3 详述)。
③ 排序任务(Ranking)—— target-aware 的关键设计
排序比召回难得多,工业上的核心挑战是:target-aware。
什么叫 target-aware?简单说,给用户推荐候选视频 $\Phi_D$ 时,打分必须考虑"用户历史与 $\Phi_D$ 的交互",而不是一个与目标无关的通用用户表示。
DLRM 是怎么处理的?DIN(Zhou et al., 2018)等经典方法:先算一个用户表示 $u$(对历史 pooling),再和候选 $\Phi_D$ embedding 做 attention/MLP。历史与目标的"交叉"发生在最后几层,时机很晚,信息利用不充分。
GR 排序的做法:直接把候选 $\Phi_{i+1}$ 插入输入序列,让它作为序列的一部分参与 self-attention,历史的每个 token 从一开始就能"看到"目标并与之交互。形式化为:
序列换能的输入输出定义为:
| 位置 $i$ | 输入 $x_i$ | 输出 $y_i$ | 含义 |
|---|---|---|---|
| $0$(item) | $\Phi_0$ | $a_0$(用户行为) | 预测用户对 $\Phi_0$ 的行为(CTR/CVR 等) |
| $1$(action) | $a_0$ | $\emptyset$ | action token 不预测 |
| $2$(item) | $\Phi_1$ | $a_1$ | 类似位置0 |
| $2k$(item) | $\Phi_k$ | $a_k$ | … |
| $2k+1$(action) | $a_k$ | $\emptyset$ | … |
注意:输入序列是item 与 action 交错排列的($\Phi_0, a_0, \Phi_1, a_1, \ldots$),候选 $\Phi_{i+1}$ 作为序列末尾的 item token 插入。输出只在 item 位置有监督(预测对应 action),action 位置输出 $\emptyset$。
排序预测结果不直接就是 $a_{i+1}$ 的 embedding;实践中会在 $\Phi_{i+1}$ 位置的 HSTU 输出上接一个小 MLP,将输出变换为多任务预测(点赞率 / 完成率 / 分享率 等)。
causal self-attention 中,$\Phi_{i+1}$(候选)被插入序列后,历史所有 token $\Phi_0, a_0, \ldots, \Phi_i, a_i$ 都能在 attention 时"看到"候选。等价于:用候选作为 query,对所有历史 token 做 cross-attention,而且这个交互在每一层都发生(多层 HSTU),比 DIN 那种"最后一层交叉"深得多。
更重要的是:一次 forward pass 可以对 $n_c$ 个历史位置同时 emit 训练样本(M-FALCON 在推理时利用了同样的思路并行处理多个候选)。
场景:用户历史 [篮球→完整观看, 足球→点赞, 羽毛球→跳过],候选 item = 网球视频。
GR 排序输入序列(交错 + 候选插入末尾):
x = [Φ_篮球, a=完整观看, Φ_足球, a=点赞, Φ_羽毛球, a=跳过, Φ_网球(候选)]
↑
候选插入这里,参与 attention
HSTU causal attention mask(上三角因果掩码):
Φ_篮球 → 只能看自己 a=完整观看 → 能看 Φ_篮球 + 自己 Φ_足球 → 能看 Φ_篮球, a=完整观看, 自己 ... Φ_网球 → 能看所有历史 token(篮球/足球/羽毛球及对应 action)
输出(只关心 item 位置):
- $y_0 = $ 预测用户对篮球视频的行为(训练用,label = 完整观看)
- $y_2 = $ 预测用户对足球视频的行为(label = 点赞)
- $y_4 = $ 预测用户对羽毛球视频的行为(label = 跳过)
- $y_6 = $ 预测用户对网球视频的行为(推理目标,无 label)→ 接小 MLP 得到点赞率/完成率/等
对比 DLRM(DIN):DLRM 只有 $y_6$ 这一个预测,历史与候选的交互在最后的 attention/MLP 层才发生。GR 一次 forward pass 得到 4 个位置的预测,且候选从第一层 HSTU 起就与历史充分交互。
④ 统一视角:一张表对比两个任务
| 维度 | 召回(Retrieval) | 排序(Ranking) |
|---|---|---|
| 目标 | 预测下一个正样本 item $\Phi_{i+1}$ | 预测用户对候选 item 的行为 $a_{i+1}$ |
| 输入序列结构 | $(\Phi_0, a_0), (\Phi_1, a_1), \ldots$(pair 为一个 token) | $\Phi_0, a_0, \Phi_1, a_1, \ldots, \Phi_{n_c}$(item 与 action 交错,候选插末尾) |
| 输出 $y_i$ 的含义 | $\Phi_{i+1}$(下一个 item 的 ID) | $a_i$(对第 $i$ 个 item 的行为类型) |
| 类比 NLP 任务 | 语言模型下一个 token 预测 | 序列标注(每个 item 位置打一个标签) |
| target-aware? | 否(不需要,目标就是预测下一个) | 是(候选必须插入序列参与 attention) |
| 推理时 | Beam Search / MIPS 检索最高分 item | M-FALCON 并行对多个候选打分 |
| 训练时每次 emit 几个样本 | $n_c$ 个(每个 item 位置各一个) | $n_c$ 个(每个 item 位置各一个) |
2.3 生成式训练:降低 $O(N)$ 复杂度
传统 impression-level 训练:每个用户每次 impression 单独构造训练样本,总复杂度为 $O(N^3 d + N^2 d^2)$($N = \max_i n_i$)。
生成式训练的做法是:在一次 forward pass 内,沿序列每个位置 emit 一个训练样本,encoder 成本被所有 targets 摊销。以 $s_u(n_i) = 1/n_i$ 的频率对第 $i$ 个用户采样,总训练成本变为:
- $n_i$:第 $i$ 个用户的序列长度
- $s_u(n_i) = 1/n_i$:对用户的采样率(序列越长,采样越稀疏)
- $N = \max_i n_i$:最长序列长度
- $d$:embedding 维度
- 复杂度从 $O(N^3)$ 降至 $O(N^2)$,节省了一个 $O(N)$ 因子
工业实现上,通常在用户一次 session 结束时批量 emit 当次 session 的所有训练样本($\hat{s}_u(n_i) \propto 1/n_i$)。
2.4 HSTU 架构:专为推荐设计的序列转换器
HSTU(Hierarchical Sequential Transduction Unit) 是本文的核心架构创新,每层包含三个子层:
子层 1:Pointwise Projection(逐位投影)
- $X$:层输入(序列 token 矩阵)
- $f_1(X) = W_1 X + b_1$:单线性层(节省计算)
- $\varphi_1$:SiLU 激活
- Split:把投影结果分成 $U$(门控权重)、$V$(值)、$Q$(查询)、$K$(键)四部分
- 所有投影融合为单个 fused kernel,避免中间结果反复读写显存
子层 2:Spatial Aggregation(空间聚合,逐位归一化 Attention)
- $Q(X)K(X)^T$:注意力权重矩阵(不做 softmax 归一化)
- $r_{ab}^{p,t}$:相对注意力偏置(Relative Attention Bias),同时融合位置信息($p$)和时间信息($t$)
- $\varphi_2$:SiLU(逐位激活,不做序列级 softmax)
- 关键差异:传统 Transformer 用 softmax 对整个序列归一化(非稳态 vocabulary 下不稳定);HSTU 用逐位聚合(pointwise aggregated attention),更适合推荐系统的非稳态分布
子层 3:Pointwise Transformation(逐位变换)
- $\text{Norm}$:Layer Norm(对 pooled features 稳定训练不可缺少)
- $\odot U(X)$:门控操作,$U$ 由 SiLU 激活,等价于 SwiGLU 变体;同时模拟 MoE 的 conditional computation
- $f_2$:单线性层输出变换
- 整层激活内存仅 $14d$(bfloat16),Transformer 同等条件需 $33d$,HSTU 可构建 $>2\times$ 更深网络
推荐场景中,历史中与目标相关的 token 数量本身就是用户偏好强度的信号(相关 token 越多 → 兴趣越强)。Softmax 归一化后这个绝对计数信息会被消除。此外,推荐 vocabulary 是非稳态的(新内容不断加入),softmax 对非稳态分布不鲁棒。逐位聚合注意力保留了这两个特性。
输入:用户序列 $X \in \mathbb{R}^{n \times d}$,$n=2048$,$d=512$
- Projection:$f_1(X)$ 一次线性变换,输出 $4d$ 维,split 为 $Q,K,V,U$(各 $d$ 维),用 fused kernel 完成
- Aggregation:计算 $\varphi_2(QK^T + r_{ab}^{p,t}) V$,逐位聚合(不 softmax),加入时间/位置偏置
- Transformation:$\text{Norm}(\cdot) \odot U$(门控)→ $f_2$(线性输出),层内 LN + dropout + MLP 全部 fused
与 Transformer 对比(同等 $d=512$):
- 激活内存:HSTU $14d = 7168$ vs Transformer $33d = 16896$(节省 57%)
- 线性层数:HSTU 2 个($f_1, f_2$)vs Transformer 6 个(QKV投影 + O投影 + FFN两层)
2.5 Stochastic Length (SL):算法性稀疏化降序列长度
用户序列长度分布极度不均,长尾用户序列极长,直接计算 attention 代价极高。SL 对超过阈值的序列做随机下采样:
- $N_c = \max_j n_{c,j}$:最长序列长度
- $\alpha \in (1, 2]$:控制稀疏化程度的超参数,$\alpha=2$ 等价于不稀疏化
- 以 $1 - N_c^\alpha/n_c^2$ 的概率对长序列做长度为 $N_c^{\alpha/2}$ 的下采样
- attention 相关复杂度降至 $O(N_c^\alpha d)$
实验(Table 3)显示,$\alpha=1.6$、序列长度 4096 时,稀疏率达 80.5%,主要指标 NE 退化不超过 0.2%。SL 相比现有的 length extrapolation 方法效果更好。
2.6 M-FALCON:成本摊销的大规模推理算法
排序阶段需要对数万个候选 item 逐一打分,每次调用 encoder 的成本极高。M-FALCON(Microbatched-Fast Attention Leveraging Cacheable OperatioNs)通过修改 attention mask 和 $r_{ab}^{p,t}$ 偏置,使 $b_m$ 个候选在同一次 forward pass 内并行处理:
传统方式:对 16384 个候选逐一过 encoder,每次都重新计算历史序列的 attention,QPS 极低,延迟极高。
M-FALCON 方式:
- 历史序列过一次 HSTU,encoder KV 缓存
- 设 $b_m = 64$,把 16384 个候选分成 $16384/64 = 256$ 个 microbatch
- 每个 microbatch:64 个候选与缓存的 KV 做 cross-attention,修改 mask 使互相不干扰
- 总成本:encoder 算 1 次 + 256 次轻量 cross-attention
结果:在相同推理预算下,模型复杂度提升 285×,QPS 提升 1.50x~2.99x。
3.1 公开数据集:MovieLens & Amazon Reviews
对比方法:SASRec(2023 版)。数据集:ML-1M、ML-20M、Amazon Books。HSTU-large 是 4× 层数 + 2× 头数的大版本。
| 数据集 | 方法 | HR@10 | NDCG@10 | NDCG@200 |
|---|---|---|---|---|
| ML-1M | SASRec (2023) | 0.2853 | 0.1603 | 0.2498 |
| HSTU | 0.3097 (+8.6%) | 0.1720 (+7.3%) | 0.2606 (+4.3%) | |
| HSTU-large | 0.3294 (+15.5%) | 0.1893 (+18.1%) | 0.2771 (+10.9%) | |
| ML-20M | SASRec (2023) | 0.2906 | 0.1621 | 0.2521 |
| HSTU | 0.3252 (+11.9%) | 0.1878 (+15.9%) | 0.2774 (+10.0%) | |
| HSTU-large | 0.3567 (+22.8%) | 0.2106 (+30.0%) | 0.2971 (+17.9%) | |
| Books | SASRec (2023) | 0.0292 | 0.0156 | 0.0350 |
| HSTU | 0.0404 (+38.4%) | 0.0219 (+40.6%) | 0.0450 (+28.6%) | |
| HSTU-large | 0.0469 (+60.6%) | 0.0257 (+65.8%) | 0.0508 (+45.1%) |
HSTU-large 在 Books 数据集的 NDCG@10 提升高达 +65.8%,长尾 item 下的优势更明显(受益于更长序列建模)。
3.2 工业场景:GR vs DLRM 在大规模流式设置
在百亿级训练样本、工业 streaming 设置下,GR 在召回和排序任务上均超越 DLRM 基线:
| 任务 | 方法 | 离线指标 | 在线 E-Task | 在线 C-Task |
|---|---|---|---|---|
| 召回 | DLRM | HR@100=29.0%, HR@500=55.5% | +0% | +0% |
| GR(新增来源) | HR@100=36.9%, HR@500=62.4% | +6.2% | +5.0% | |
| 排序 | DLRM | E-NE=0.4982, C-NE=0.7842 | +0% | +0% |
| GR | E-NE=0.4845, C-NE=0.7645 | +12.4% | +4.4% |
消融实验验证:仅使用 interactions 的 GR 显著好于仅使用 content features 的 GR,确认了用户行为(actions)才是核心信号(论文题目"Actions Speak Louder than Words"的出处)。
3.3 Scaling Law:推荐系统的 ChatGPT 时刻
最具影响力的结论:GR 的模型质量随训练计算量呈幂律增长,跨越三个数量级,直至 GPT-3/LLaMA-2 量级,且没有出现饱和:
- $L$:评估指标(HR@100 或 NE)
- $C$:训练 PetaFLOPs/day
- $a, b$:拟合常数
- HR@100: $L = 0.15 + 0.0195 \ln C$;NE: $L = 0.549 - 0.0053 \ln C$
- DLRM 在约 200B 参数时质量饱和,GR 持续增长至 1.5 万亿参数
核心亮点
- 统一范式:用序列转换统一了推荐系统的召回和排序,消除了多阶段系统的割裂优化,一套框架搞定两个任务
- Pointwise Attention 的直觉:不用 softmax,而是逐位聚合,保留了"相关 token 数量 = 兴趣强度"这个重要信号,且对非稳态 vocabulary 更鲁棒
- M-FALCON 的工程价值:解决了"大模型 + 大规模候选集"的推理效率矛盾,使 285× 更复杂的模型能以 更低 的推理成本上线,是非常有价值的工程贡献
- Actions > Words:内容特征(GR content-based)大幅逊色于行为特征(GR interactions),验证了"行为胜于语言描述"的核心主张,与直觉一致
- Scaling Law:推荐系统首次被证明遵循幂律 scaling,且序列长度比参数量更关键,为未来模型发展提供明确方向
局限与思考
- 无语义理解:GR 的特征完全来自行为序列,缺乏 item 的内容语义(文本、多模态)。对冷启动 item(没有交互数据)效果有限,而 OneRec 通过 RQ-VAE 语义 ID 弥补了这一点
- 实现复杂度:Raggified attention、Fused kernel、M-FALCON 等工程优化依赖大量底层 CUDA 实现,复现门槛极高(Meta 规模专属技术)
- 序列长度的矛盾:scaling 需要极长序列,但训练/推理成本随序列长度快速增长,SL 只是缓解而非根本解决
- 排序任务的 target-aware:需要把候选 item 插入序列,每个候选都要一次完整 forward pass(M-FALCON 解决了这个问题),但设计上仍有约束
对后续工作的启发
以下问答均对照论文原文逐条核实,引用原句标注于各条末尾。
Q1 训练样本是按 user 粒度还是 impression 粒度组织的?
按 user 粒度组织。
传统 DLRM 是 impression-level 训练:每个曝光单独作为一条样本,forward 一次只处理一个 impression,每个 impression 都要完整跑一遍序列编码,总复杂度 $O(N^3 d + N^2 d^2)$。
HSTU 采用 generative training:把整个用户历史序列 $x_0, x_1, \ldots, x_{n-1}$ 做一次 forward,序列上每个位置都 emit 一个 training signal,encoder 成本被均摊到多个目标上,复杂度降低 $O(N)$ 因子,变为 $O(N^2 d + N d^2)$。
Q2 工业流式训练中,样本具体什么时候 emit?
在工业实现中,在一次用户 request 或 session 结束时 emit 训练样本。
例如:用户今天刷了 10 个 item,这 10 个 item 连同历史序列构成输入,等这次 request 结束后,把整条序列打包 emit 出训练样本(对应序列上多个位置的监督信号)。这样采样率 $\hat{s_u}(n_i) \propto 1/n_i$,序列越长的用户采样频率越低,实现了对用户级的归一化。
Q3 item vocab 有十亿级,训练 retrieval 时怎么处理 softmax?
论文没有使用全量 softmax,而是采用负采样方式训练 retrieval。论文给出了两处线索:
- 训练目标:类似语言建模的 next-token prediction,评估指标为 log perplexity(§4.1.2)
- 负样本数量:"We additionally adjust the number of negatives for retrieval."(§4.3.1),说明 negatives 数量是可调超参数
Q4 Retrieval 和 Ranking 各自预测什么?
| 任务 | 预测目标 | 输入序列 |
|---|---|---|
| Retrieval | $p(\Phi_{i+1} \mid u_i)$,找下一个最优 item | $\Phi_0, a_0, \Phi_1, a_1, \ldots, \Phi_i, a_i$(不含候选) |
| Ranking | $p(a_{i+1} \mid \Phi_0, a_0, \ldots, \Phi_{i+1})$,预测用户对候选的 action | 历史 + 候选 item $\Phi_{i+1}$ 插入序列末尾 |
Ranking 在 $\Phi_{i+1}$ 位置的输出上接一个小 MLP,做多任务预测(同时预测点赞、完播、分享等多种 action)。
论文原句(§2.2):"the supervision for $x_i$, $y_i$, is not necessarily $\Phi_{i+1}$, as users could respond negatively to $\Phi_{i+1}$."
Q5 GR 是否替代了整个召回 + 排序漏斗?
并非替代整个多阶段漏斗,需要区分两种部署方式:
| 阶段 | 部署方式 | 说明 |
|---|---|---|
| 召回 | add source 或 replace source | 可新增为一路召回源,或替换原主 DLRM 召回源(多路召回中的一路) |
| 排序 | 直接替换 DLRM ranker | 对比 production DLRM,GR ranker 直接替代 |
Q6 为什么 impression-level 训练复杂度是 $O(N^3 d + N^2 d^2)$?
对于用户 $i$,序列长度 $n_i$,训练时对序列上每个 impression $j$($j = 1, 2, \ldots, n_i$)单独 forward,处理长度为 $j$ 的前缀序列:
- self-attention:$O(j^2 d)$
- MLP 层($d_{ff} = O(d)$):$O(j \cdot d_{ff} \cdot d) = O(j d^2)$
对用户 $i$ 求和:
$\displaystyle\sum_{j=1}^{n_i}(j^2 d + j d^2) = O(n_i^3 d + n_i^2 d^2)$
取所有用户最大序列长度 $N = \max_i n_i$,总复杂度:
$O(N^3 d + N^2 d^2)$
Q7 Target-aware 就是把候选 item 插到序列末尾做 causal self-attention?前面的历史 token 还参与 attention 吗?
对,target-aware 就是这个构造技巧。前面的历史 token 同样参与完整的 causal self-attention,不是只更新最后一个 token。
整个 forward 流程:
输入:[Φ₀, a₀, Φ₁, a₁, ..., Φᵢ, aᵢ, 🎯Φᵢ₊₁(候选)]
↓ 所有 token 都参与 HSTU 每一层 causal self-attention ↓
输出:[ h₀, h₁, h₂, h₃, ..., hᵢ, hᵢ₊₁ ]
↑
只取这个位置接 MLP 算 action 概率
历史 token 的输出 $h_0 \ldots h_i$ 是中间计算结果(用于后续层 attention 的 K/V),但 ranking 任务只在 $\Phi_{i+1}$ 位置算 loss,其他位置的输出不参与 loss 计算。
• 历史 token $\Phi_j$($j < i+1$):看不到候选(候选在右边被 mask)
• 候选 token $\Phi_{i+1}$:可以 attend 到左边所有历史(序列最后一个,没有右侧 token)
因此 $h_{i+1}$ 是整合了全部历史信息后的融合表示,而历史 token 的计算不受候选影响(保证因果性)。
笔记里"target-aware 前提是目标 item 的话题标签需要在序列中可见"的意思是:候选 $\Phi_{i+1}$ 的 item embedding(含话题标签)在序列里,当它做 attention 时,能从历史中检索出与自己话题相关的记录(比如候选是户外视频,历史中户外相关 token 的 attention 权重会更高)。这是 target-aware 的核心机制。
Q8 M-FALCON 就是把所有候选拼在后面,用 mask 让候选只看历史、互相隔离,这样共用历史的 QKV?
理解完全正确。 M-FALCON 把 $b_m$ 个候选同时展开,通过 attention mask 设计让每个候选只能 attend 到历史 + 自己,候选之间互不可见,历史部分的 K/V 只计算一次被所有候选共用。
Attention mask 示意(n 个历史 token + $b_m$ 个候选):
Φ₀ a₀ ··· Φᵢ aᵢ │ C₁ C₂ C₃ Φ₀ [ ✓ ✗ ✗ ✗ ✗ │ ✗ ✗ ✗ ] aᵢ [ ✓ ✓ ··· ✓ ✗ │ ✗ ✗ ✗ ] ← 历史 token 看不到候选 ────────────────────────────┼────────────── C₁ [ ✓ ✓ ··· ✓ ✓ │ ✓ ✗ ✗ ] ← 看历史 + 只看自己 C₂ [ ✓ ✓ ··· ✓ ✓ │ ✗ ✓ ✗ ] ← 看历史 + 只看自己 C₃ [ ✓ ✓ ··· ✓ ✓ │ ✗ ✗ ✓ ] ← 看历史 + 只看自己
复杂度变化:
- 朴素做法(每个候选单独 forward):$O(b_m \cdot n^2 d)$
- M-FALCON($b_m$ 个候选共享历史 KV):$O((n + b_m)^2 d) \approx O(n^2 d)$($b_m \ll n$ 时)