Sample Is Feature: Beyond Item-Level, Toward Sample-Level Tokens for Unified Large Recommender Models
Meituan
把历史序列的单位从 item 提升到 sample:每条历史行为不再只是一个 item embedding,而是当时那条完整训练样本(用户画像+物品+上下文+交叉特征,约 600 个特征域)的快照。Sample Tokenizer 用分组自适应残差量化(HGAQ,4 组、B=32 个特征一个子 token、3 层 RVQ×256 码)把每条样本压成 648 bit 的离散码,离线存 KV;SIF-Mixer 在 (L+1)×T 的 token 矩阵上交替做行内(样本内特征交互)和列向(跨样本时序)注意力,美团外卖线上 CTR +2.03%。
核心思路
现有排序模型的行为序列,每个位置基本是一个 item embedding,最多再挂几个侧特征(价格档、类目、CTR 统计)。但训练日志里每条历史曝光本来就有一整条样本:用户画像、物品特征、上下文、预先算好的交叉特征,以及当时的行为结果。SIF(Sample Is Feature)的主张是:历史 token 应该是这一整条样本,而不只是 item。
作者的例子:两个用户都点了同一家餐厅,一个是深夜带券,一个是工作日午高峰。bare item embedding 把两者当成同一回事,但完整请求上下文携带的意图信号完全不同。样本级 token 还能带上 item embedding 根本表达不了的时变信号,比如当时的实时热度、竞争曝光和时段需求。
难点在成本:约 600 个特征域、每个 8 维 float32,一条快照是 600×8×32=153,600 bit,乘以 L=1000 的序列,存储和注意力都扛不住。SIF 用两个组件解决:
- Sample Tokenizer(HGAQ):分组自适应残差量化,把一条 Raw Sample 压成 T×M 个码本索引(27×3×8=648 bit),离线预计算存 KV,线上只查码本。
- SIF-Mixer:在 (L+1)×T 的 token 矩阵上交替做样本内(行)和跨样本(列)注意力。
另一个收益是统一架构中的异构问题:历史 token 和当前请求 token 都变成“同构”的 Token Sample,处在同一码本空间里。
整体实现思路
- 离线:对每条历史曝光的 Raw Sample S=[f_user|f_item|f_ctx|f_cross],用 Tokenizer 得到 Token Sample Q(T×M 个 8 bit 索引),按 PV ID + Item ID 和行为序列 Join,存入 KV。
- 序列化:把行为序列 {i_1,…,i_L} 替换为 {Q_1,…,Q_L},按时间排序。
- 在线:取出历史 Q_l,查码本求和得到每个子 token 向量;当前请求(目标样本)无法预先量化,用逐子 token 的线性投影 W_res 在线映射到码本空间。
- 建模:N=4 个 SIF Block(Token-level Mixer → Sample-level Mixer → FFN),对目标行均值池化后过 MLP 输出 pCTR/pCVR。
- 训练:Tokenizer 与排序模型联合训练,损失 L = L_BCE + 1.0·L_VQ + 0.25·L_align,另加 Tokenizer 侧的 pCTR 辅助损失 L_token。
子模块实现(可复现细节)
Sample Tokenizer:分组与自适应子 token
- 点特征(用户/物品/上下文/交叉)参与量化;用户行为序列这类序列特征不进量化,由 Sample-level Mixer 处理。
- 分为 G=4 个语义组。高基数的关键特征(如 item ID)可以单独成组,保留个体身份,避免和低区分度特征挤在一个码本里。
- 组 g 内的子 token 数 K_g = ceil(|F_g| / B),B 是每个子 token 负责的特征数(默认 32)。组内特征平均切成 K_g 个不重叠子集,每个子集用组与槽位专属线性层投影:f~(g,k) = W_proj(g,k) · f(g,k) ∈ R^{d0},d0=16。
- 总子 token 数 T = Σ K_g,token 总维度 d = T·d0。论文给出 T=27(对应 27×16=432 维);但在 B 扫描一节又写“B=32(T=20)”,并说 B=8 时 T<20,按 T≈600/B 推算约为 19。这几处互相矛盾,复现时需以自家特征数重算。
Sample Tokenizer:残差量化与标签监督
- 每个子 token (g,k) 有独立码本 C_{g,k},M=3 层,每层 V=256 码,维度 d0。
- RVQ:r^(1)=f~,q^(m)=argmin_v ||r^(m) − c_v^(m)||²,r^(m+1)=r^(m) − c_{q}^(m)。
- Token Sample Q = 所有 (g,k,m) 的索引,大小 T×M,按 8 bit 计为 648 bit。
- 标签监督:重建 s^ = concat_{g,k} Σ_m c_{q(g,k,m)},过轻量 MLP 得 y^_token = σ(MLP(s^)),辅助损失 L_token = BCE(y^_token, y),让码本按预测相关性而不只是重建误差组织。由于 Raw Sample 包含原交互的行为结果,主 BCE 也会通过 VQ 回传到码本,作者认为因此不需要额外的对比损失。
目标样本投影与对齐损失
- 目标行 l=0:H0_{0,(g,k)} = W_res(g,k) · f_τ(g,k)。
- L_align = Σ_g Σ_k || W_res(g,k) f_τ(g,k) − sg(e_{g,k}) ||²,其中 e_{g,k} 是当前样本过 Tokenizer 得到的 RVQ 重建,sg 为 stop-gradient。
- 训练时计算 Tokenizer 前向作为对齐目标;服务时跳过 Tokenizer,只做线性投影。
历史行嵌入
z_l(g,k) = Σ_{m=1..M} c(q_l(g,k,m)) ∈ R^{d0};H0_{l,*} = [z_l(1,1) ‖ … ‖ z_l(G,K_G)] + p_{L−l}(recency 位置编码)。
SIF-Mixer Block
把 H^{n−1} 看成 (L+1)×T 的矩阵,行是样本,列是子 token 位置。均为 pre-norm 残差:
- Token-level Mixer(行注意力):H~_l = H_l + MHA(LN(H_l)),对每个样本内部 T 个子 token 做自注意力,捕捉组间(用户-物品-上下文)和组内子概念(如价格与评价)交互。
- Sample-level Mixer(列注意力):H¯{*,p} = H~{,p} + MHA(LN(H~_{,p})),对每个子 token 位置跨 L+1 个样本做自注意力,目标样本可以从所有历史中取信息。
- Token-level FFN:逐位置 FFN,隐层 4×d0。
复杂度 O(T²(L+1)d0 + (L+1)²T d0),T≪L 时以 O(L²T d0) 为主,与同长度标准序列注意力同阶。
预测头与训练配置
- 目标行 T 个子 token 均值池化:h = (1/T) Σ_p H^N_{0,p};y^ = σ(w2ᵀ ReLU(W1 h + b1) + b2)。
- L = L_BCE + β·L_VQ + γ·L_align,β=1.0,γ=0.25,VQ commitment 系数 λ=0.25。
- N=4,8 头,d0=16,FFN 4×d0,L=1000;Tokenizer:G=4,B=32,M=3,V=256。
- Adam(lr=1e-3,β1=0.9,β2=0.999,weight decay 1e-5),batch 4096,8×A100-80G。
实验设置与结果
数据:美团外卖工业数据集,90 天,1B+ 曝光,50M+ 用户,5M+ 物品;每条样本约 600+ 特征域,加 1000 长度的行为序列。所有基线使用相同的当前请求特征,唯一差别是历史序列的表示。结果为 5 次平均,配对 t 检验 p<0.01。
主结果(表 1,第一行为绝对值,其余为相对 DCNv2+DIN 的提升)
| 特征交互 | 序列建模 | CTR AUC | CTR GAUC | CVR AUC | CVR GAUC | 参数(M) | TFLOPs |
|---|---|---|---|---|---|---|---|
| DCNv2 | DIN | 0.7832 | 0.7614 | 0.8103 | 0.7891 | 48 | 0.31 |
| Wukong | SIM | +0.41% | +0.38% | +0.35% | +0.33% | 56 | 0.38 |
| Wukong | LONGER | +0.53% | +0.49% | +0.44% | +0.41% | 62 | 0.42 |
| RankMixer | SIM | +0.67% | +0.61% | +0.58% | +0.54% | 51 | 0.35 |
| RankMixer | LONGER | +0.79% | +0.72% | +0.68% | +0.63% | 53 | 0.40 |
| HyFormer | – | +1.12% | +1.01% | +0.97% | +0.88% | 120 | 0.87 |
| OneTrans | – | +1.08% | +0.96% | +0.91% | +0.83% | 115 | 0.82 |
| SIF | – | +2.03% | +1.89% | +1.74% | +1.61% | 128 | 0.93 |
SIF 相对 HyFormer:CTR AUC +0.91pt、GAUC +0.88pt;CVR AUC +0.77pt、GAUC +0.73pt。参数和算力只多约 7%。
Tokenizer 消融(表 2,ΔGAUC 相对 SIF)
| Token 表示 | ΔCTR-GAUC | ΔCVR-GAUC | 每条存储 | 压缩比 |
|---|---|---|---|---|
| SIF(HGAQ) | – | – | 648 bit | ≈237× |
| 仅 Item ID | −1.00% | −0.86% | 64 bit | ≈2400× |
| Item ID + 约 24 个关键特征 | −0.60% | −0.51% | 832 bit | ≈185× |
| 全量 Raw Sample 稠密投影(d=512,不量化) | −0.27% | −0.23% | 16,384 bit | ≈9× |
稠密版本信息量更多,效果反而差 0.27%。作者给的解释:512 维无结构 token 在 L=1000 上难优化;离散码本带来隐式聚类正则;所有历史位置共享码本,跨时间语义对齐。
注意力策略消融(表 3)
| 策略 | ΔCTR-GAUC | ΔCVR-GAUC | 复杂度 |
|---|---|---|---|
| SIF-Mixer(行+列分解) | – | – | O(L²T + LT²) |
| 展平全注意力 | −0.24% | −0.20% | O((LT)²) |
| 先池化再注意力 | −0.81% | −0.68% | O(L²) |
先池化(现有带侧信息序列模型的常见做法)几乎吃掉了全部收益,只比 HyFormer 略好。
子 token 粒度 B
B ∈ {2,4,8,16,32,64}:B=32 最好(CTR GAUC 0.7758);B=2(T=300)为 0.7750;B=64(T=12)为 0.7735;全部高于 HyFormer 的 0.7691。(注意:这组绝对值和序列长度表的 SIF 0.7803、HyFormer 0.7715 对不上。)
序列长度(表 4,CTR GAUC)
| L | OneTrans | HyFormer | SIF | Δ(SIF−HyFormer) |
|---|---|---|---|---|
| 100 | 0.7674 | 0.7680 | 0.7693 | +0.0013 |
| 200 | 0.7689 | 0.7695 | 0.7745 | +0.0050 |
| 500 | 0.7706 | 0.7712 | 0.7782 | +0.0070 |
| 1000 | 0.7710 | 0.7715 | 0.7803 | +0.0088 |
| 2000 | 0.7713 | 0.7718 | 0.7820 | +0.0102 |
HyFormer、OneTrans 从 L=500 到 2000 只涨 0.0005 和 0.0006,SIF 涨 0.0038。L=500 的 SIF 已超过 L=1000 的 HyFormer。深度方面,N 从 1 到 6,SIF 一直涨到 N=4。
线上 A/B(5% 流量,7 天,对比 HyFormer 生产基线)
| 用户分层(序列长度) | ΔCTR | ΔCVR | ΔGMV/session |
|---|---|---|---|
| L < 10(冷用户) | +0.53% | +0.31% | +0.37% |
| 10 ≤ L < 100 | +1.18% | +0.71% | +0.84% |
| 100 ≤ L < 500 | +2.07% | +1.24% | +1.38% |
| L ≥ 500(重度) | +3.12% | +1.87% | +2.06% |
| 整体 | +2.03% | +1.21% | +1.35% |
冷用户也有收益,作者归因于目标样本被投到同一码本空间、表示更有表达力。
思考与可参考价值
值得借鉴的点
- 历史 token 的“宽度”还有很大空间。多数长序列工作只在加长,SIF 说明把历史位置换成整条样本快照,在相同 L 下收益可能比继续加长更大,而且越长越明显。对电商来说,历史点击时的价格、券、活动、时段、位置、当时的实时 CTR 都是现成的日志字段。
- 分组 RVQ 是一种低成本的存储方案。648 bit 能装下约 600 个特征的快照,比手挑 24 个侧特征(832 bit)还小。做法简单:按语义分组 → 每 32 个特征一个子 token 投影到 16 维 → 3 层 RVQ×256。
- 离散化本身就有正则作用。稠密 512 维同等信息反而更差,这一点对“Q-Former / 连续压缩 vs 离散码”之争是一个有用的数据点(推断:连续压缩在长序列上可能因优化难而塌缩,离散码共享码本带来跨时间对齐)。
- 行列分解注意力适用于任何“每个历史位置是多个 token”的场景,比先池化好很多。
- 标签监督码本(重建过 MLP 预测 CTR 加辅助 BCE)可以直接用到 Semantic ID 训练,让码本按业务信号组织。
和生成式推荐 / SID 的关系
这篇本质是 CTR/CVR 排序模型,不是生成式推荐,放在 gen-rec 主题下是因为它的量化对象是“样本”,属于 SID 思路的扩展。可以设想的组合(推断,论文未做):GR 模型输入侧把历史行为换成 item SID + 样本上下文码,输出仍解码 item SID;或在 SID 前缀之外加一段“交互上下文码”。
采纳前要核对
- 码本版本一致性:Tokenizer 与排序模型联合训练,但历史 Token Sample 是离线预计算存 KV 的。码本更新后旧索引是否失效、多久全量重刷、训练和服务是否用同一版码本,论文都没说,这是最大的工程风险。
- 时间穿越与标签泄漏:Raw Sample 包含原交互的行为结果和交叉统计特征,需确认只用曝光时刻之前可得的值。
- 数字一致性:T=27 / T=20 / T<20@B=8 的矛盾、两套 GAUC 绝对值对不上、“matched FLOPs 0.87”而 SIF 实为 0.93。复现时 T、B 需按自家特征重新定。
- 缺失的消融:没有单独去掉 L_token、L_align,没有单码本 vs 分组、M/V 大小、f_cross 组贡献的实验,也没有与 HSTU、IAT 这类同样把交互实例当 token 的方法比较。
- 线上 vs 离线落差:离线 +0.88pt GAUC,线上 CTR +2.03%,超出作者自己按经验规则估算的 +0.7%,解释较弱;线上实验是否同时引入了其他改动不明。只有一个私有数据集,无代码。
整体判断:思路对工业界很实用,消融里“稠密 vs 离散”和“池化 vs 分解注意力”两组最有信息量;但论文写作上的数字矛盾较多,效果幅度宜打折看,适合作为“历史序列加宽 + 离散压缩”的方向参考,在自家数据上做小规模验证后再投入。