SemID 把 TIGER 提出的 Semantic ID 从"学术召回实验"搬到了 YouTube 亿级视频的生产排序模型中,核心贡献是解决了"8个整数的 SID 如何适配进排序模型 embedding table"这个工程问题,最终用 SPM 子词分组方案在整体 CTR AUC 和冷启动 CTR/1D AUC 上同时超越随机哈希 ID 基线,且 serving cost 完全不增加。
📄 原文:https://arxiv.org/abs/2306.08121
🔗 前驱工作:TIGER(arXiv 2305.05065,NeurIPS 2023)—— Semantic ID 的发明者
① 提出 N-gram 和 SPM 两种将 SID 序列适配进排序模型 embedding table 的方案;
② 在 YouTube 生产排序模型上验证:大表配置下 SPM-SID 整体 CTR AUC 和冷启动 CTR/1D AUC 均超越随机哈希;
③ 通过前缀语义层级分析和 6 个月跨版本稳定性实验,证明 SID 在亿级工业场景下的可行性。
随机哈希 ID 的三大根本问题
工业推荐系统里,每个视频都有一个字符串 ID(比如 YouTube 的 video_id),通用做法是随机哈希:把字符串 ID 哈希到一个大 embedding table(几千万行)的某一行,拿那行向量作为视频表示。这套方案快捷实用,但有三个深层问题:
哈希函数把不同视频随机映射到同一行,"篮球教学"和"美食探店"可能共享同一个 embedding,模型无法在 embedding 空间形成有意义的语义聚类,泛化受限。
YouTube 视频符合幂律分布:大量长尾视频曝光极少,对应的 embedding 行训练不充分,几乎停留在随机初始化状态,排序模型对这类视频质量判断力弱。
刚上线的新视频没有任何历史曝光记录,embedding 是随机初始化值,排序模型对这个视频几乎没有判断依据,冷启动效果差,新内容难以被分发出去。
直接用 Dense Content Embedding 行不行?
一个直觉方案:既然随机哈希没语义,把 embedding 换成视频内容表示(如 Video-BERT 输出的 2048 维向量)不就有语义了?
原因在于排序模型对 embedding 有两个互相矛盾的需求:
🧠 记忆能力(Memorization)
记住某个具体视频的历史点击率、完播率等质量特征,需要 embedding 是可训练的、随数据动态更新的。随机哈希每个 ID 对应独立的可训练向量,记忆能力强。
🌐 泛化能力(Generalization)
对没见过的新视频、长尾视频也能合理排序,需要 embedding 携带语义信息,让内容相似的视频共享表示。Dense Content Embedding 语义丰富,但固定不可训练,泛化好、记忆差。
加深模型(1.5×/2× 层数)能弥补 dense embedding 的记忆缺陷,但 serving cost 成倍增加,生产不可接受。VideoRec(端到端训练视频编码器)效果最好,但计算成本是 ID 方案的 10–50 倍,同样无法部署。
SemID 的核心切入点
随机哈希的情况:视频 A="篮球教学" 和视频 B="美食探店" 可能哈希到 embedding table 的同一行,彼此梯度互相污染,没有意义。
SemID 的情况:视频 C="篮球教学01" 和视频 D="篮球教学02" 内容相近,RQ-VAE 会给它们分配相同的 SID 前缀(如前 3 位都是 (5, 12, 3)),于是它们共享前 3 层 embedding。这意味着视频 C 学到的"篮球教学"语义特征会直接帮助视频 D(即使 D 是长尾或冷启动视频)。
对比:同样是"碰撞到同一行",SemID 的碰撞是内容驱动的、有益的;随机哈希的碰撞是完全随机的、有害的。
整体框架:两阶段流程
SemID 方法分为两个独立阶段,阶段一先完成后冻结,阶段二在冻结的 SID 上进行:
Video-BERT 处理
Video-BERT 输出
L=8, K=2048
训练后冻结
如 (5,12,3,8,1,7,2,4)
存储备用
SID 存储
切分成子词片段
sum-pooling 合并
替代随机哈希 ID
Stage 1:RQ-VAE 生成 Semantic ID(简述)
RQ-VAE 的作用是把每个视频的 2048 维 dense content embedding 压缩成 8 个整数,这串整数就是 Semantic ID(SID)。具体细节参见 TIGER 解读,SemID 沿用相同机制,只是超参不同:
| 超参 | TIGER | SemID | 原因 |
|---|---|---|---|
| 量化层数 L | 3–4 层 | 8 层 | 面向亿级视频库,需要更细粒度区分 |
| Codebook 大小 K | 256 | 2048 | 视频库规模更大,需要更大码本 |
| 内容 embedding | 文本/协同 | Video-BERT 2048 维 | 多模态视频内容(音视频联合) |
| 训练后处理 | 用于生成式检索 | 冻结,存储每个视频的 SID | 排序场景需要确定性 ID,不能动态变化 |
假设视频"2024年NBA总决赛集锦"的 Video-BERT embedding 经过 RQ-VAE 处理后,得到 SID = (5, 12, 3, 8, 1, 7, 2, 4)。
另一个视频"2023年NBA半决赛精彩瞬间"内容相近,SID = (5, 12, 3, 8, 2, 1, 6, 9)。
两者前 4 位相同(5, 12, 3, 8),说明在 codebook 空间中它们是语义邻居,会共享前 4 层的 embedding 向量。
而"韩国泡菜制作教程"的 SID = (2, 7, 15, 4, 3, 11, 8, 6),前缀完全不同,不会与篮球内容共享 embedding。
Stage 2-A:N-gram 子词适配
拿到 SID = $(c_1, c_2, \ldots, c_8)$(8 个整数)后,需要把它转化成排序模型能用的 embedding 向量。最直接的思路:把相邻 N 个 code 视为一个"子词",查一个 embedding table 得到向量,最后对所有子词的向量求和。
Unigram(N=1):每个 code 单独查表
SID 的 8 个 code 各自查一张独立的 embedding table,得到 8 个向量后相加:
- $\mathbf{h}_v^{\text{unigram}}$:视频 $v$ 的最终 embedding 表示,送入排序模型
- $L = 8$:SID 的层数(总共 8 个整数)
- $\mathbf{W}_l \in \mathbb{R}^{K \times d}$:第 $l$ 层对应的 embedding 矩阵,共 8 张,每张 $K=2048$ 行,$d$ 维
- $c_l^v$:视频 $v$ 的 SID 中第 $l$ 层的 code 值(整数,范围 $[0, K-1]$)
- $\mathbf{W}_l[c_l^v]$:从第 $l$ 张表中取第 $c_l^v$ 行,即该层 code 对应的向量
视频 SID = (5, 12, 3, 8, 1, 7, 2, 4),Unigram 适配需要:
查表1[5] + 查表2[12] + 查表3[3] + 查表4[8] + 查表5[1] + 查表6[7] + 查表7[2] + 查表8[4] = 最终 embedding
总参数量:8 张表 × 2048 行 × d 维 = 16,384 × d 个参数。所有共享第1层 code=5 的视频(可能有几十万个)都会更新同一行 W1[5],这正是参数共享带来泛化的机制。
问题:每层 code 是独立查表的,无法捕获"第1层=5 且 第2层=12"这个组合语义,层间关系丢失。
Bigram(N=2):相邻两个 code 拼在一起查表
把相邻两个 code 合并为一个子词,共 4 次查表:
- $(c_{2i-1}^v, c_{2i}^v)$:第 $2i-1$ 层和第 $2i$ 层 code 拼接成的 bigram 子词(一个二元组)
- $\mathbf{W}_i^{(2)} \in \mathbb{R}^{K^2 \times d}$:第 $i$ 对 bigram 对应的 embedding 矩阵,每张有 $K^2 = 2048^2 \approx 420$ 万行
- $L/2 = 4$:共 4 张 bigram 表,分别对应 (c1,c2), (c3,c4), (c5,c6), (c7,c8)
视频 SID = (5, 12, 3, 8, 1, 7, 2, 4),Bigram 查 4 次:
查表1[(5,12)] + 查表2[(3,8)] + 查表3[(1,7)] + 查表4[(2,4)] = 最终 embedding
优点:能捕获相邻两层 code 的组合语义,比如"第1层=5 且 第2层=12"对应"运动类中的球类运动"这个更细粒度的概念。
问题:每张表有 2048² ≈ 420 万行!4 张表共 1680 万行,内存占用巨大。N=3 时更是 2048³ ≈ 86 亿行,完全不可行。所以论文限制 N ≤ 2。
① 固定分组:只能对齐位置组合,比如永远是第1+2层、第3+4层,不能自适应捕获"哪些层组合最重要";
② 指数爆炸:表大小随 N 指数增长($K^N$ 行),N=3 就不可行,限制了语义的细粒度表达。
Stage 2-B:SPM 子词适配(推荐方案)
SPM(SentencePiece Model)是 LLM 领域常用的 BPE/Unigram 分词技术。SemID 将这个思想迁移到 SID 序列上:把 SID 的 8 个 code 当成"字符",把高频共现的 code 组合"合并"成一个子词,从数据分布中自动学习最优分组方式。
- $s_v = (c_1^v, \ldots, c_L^v)$:视频 $v$ 的 SID 序列(8 个整数)
- $\mathrm{SPM}(s_v)$:对 $s_v$ 进行 SPM 分词后得到的子词片段序列(变长,热门组合被合并为长子词,冷门的退化为 unigram)
- $p$:一个子词片段,可以是单个 code,也可以是若干 code 的组合
- $\mathrm{id}(p)$:子词片段 $p$ 在 SPM 词表中的 ID,用于查表
- $\mathbf{W} \in \mathbb{R}^{M \times d}$:单一共享 embedding 表,大小固定为 $M$ 行(可按内存预算灵活设置)
假设在 YouTube 亿级视频的 SID 语料上训练 SPM,发现:
• code 组合 (5, 12) 在 2000 万个视频中出现,频率极高 → SPM 将它合并为一个子词,ID = 3456
• code 组合 (5, 12, 3) 在 500 万个视频中出现 → 也被合并,ID = 7891
• 某个冷门 code (15) 很少与其他 code 共现 → 退化为 unigram,ID = 15
热门视频(SID=(5,12,3,8,...)):SPM 分词结果可能是 [(5,12,3), (8,...)],只需 2-3 次查表,效率高。
冷门视频(SID 组合在训练数据中很少见):SPM 分词退化为全 unigram,需要 8 次查表,但保持了最大粒度的表达。
关键优势:SPM 只用 1 张共享的 M 行 embedding 表(M 可控),N-gram 需要多张 K 或 K² 行的独立表。相同内存预算下,SPM 覆盖了更丰富的语义子词组合。
| 对比维度 | Unigram (N=1) | Bigram (N=2) | SPM(推荐) |
|---|---|---|---|
| 分组方式 | 每层单独 | 固定相邻两层 | 数据驱动,自适应 |
| embedding table 行数 | $8 \times K$(16K 行) | $4 \times K^2$(1680万行) | $M$ 行(可控) |
| 层间语义 | ❌ 无 | ✅ 相邻两层组合 | ✅ 任意频繁组合 |
| 内存可控 | ✅ | ⚠️ K² 大 | ✅ |
| 冷热自适应 | ❌ | ❌ | ✅ 热门查表少,冷门保细粒度 |
| 大表下效果 | 一般 | 好 | 最好 |
训练流程
整体训练分两步,两步完全解耦:
在 YouTube 视频的 Video-BERT embedding(2048 维)上训练 RQ-VAE,参数:L=8 层,K=2048 codebook。使用重建损失 + 量化损失联合训练。为防止 codebook collapse(很多 code 没被使用),每步将没用到的 codebook 向量重置为 batch 内随机视频的 embedding。训练到重建 loss 收敛后**冻结**。
用冻结的 RQ-VAE encoder 对视频库中所有视频运行前向推断,得到每个视频的 SID(8 个整数)。将 video_id → SID 的映射表存储起来,供排序模型训练时查询。新上线的视频也用同一个冻结 RQ-VAE 生成 SID,实时或定时更新映射表。
排序模型正常在每日 log 数据上滚动训练。对 user history、watch video、candidate video 这三类特征,将随机哈希 ID 替换为:① 查 SID 映射表得到 8 个整数;② 用 N-gram 或 SPM 分词;③ 查 embedding table 得到向量;④ sum-pooling 后送入排序模型主干。
embedding table(N-gram 或 SPM 的)和排序模型参数一起端到端训练,RQ-VAE 保持冻结,不参与梯度更新。
推理(Serving)流程
排序模型上线 serving 时,对每次来一个视频(不管是用户历史中的视频还是候选视频),流程如下:
根据 video_id 查预先存好的键值存储,得到 8 个整数的 SID。这是 O(1) 的查表操作,和随机哈希时代的 video_id → 哈希值同等速度。新视频在上线时已经离线算好 SID,没有实时推断 RQ-VAE 的开销。
用存储好的 SPM 词表对 SID 进行分词,得到若干子词片段(通常 2-8 个)。这是纯 CPU 字符串操作,极快。
每个子词片段查共享 embedding table 得到一个向量,然后对所有子词向量求和(sum-pooling),得到最终的视频表示向量 $\mathbf{h}_v^{\text{spm}} \in \mathbb{R}^d$。查表次数通常 2-8 次,与随机哈希时代相当(随机哈希也需要多次查表应对哈希碰撞)。
$\mathbf{h}_v^{\text{spm}}$ 作为视频 feature 送入排序模型(DNN/Transformer),与其他特征拼接后计算 CTR、完播率等分数,输出排序结果。整个路径与随机哈希完全同构,serving latency 不增加。
与 TIGER 的核心区别
SemID 和 TIGER 都用 RQ-VAE 生成 SID,但定位完全不同:
| 对比维度 | TIGER | SemID |
|---|---|---|
| 任务场景 | 召回(Retrieval) | 排序(Ranking) |
| SID 的用途 | 生成式 Beam Search 的目标序列(模型输出 SID) | item 的 embedding 表示(模型输入特征) |
| 延迟要求 | 允许 Beam Search(毫秒~百毫秒) | 极低延迟,不允许任何额外推断 |
| SID 超参 | L=3, K=256(精简) | L=8, K=2048(更细粒度) |
| 核心创新 | 生成式召回范式 + RQ-VAE | N-gram/SPM 适配 + 工业排序验证 |
| 视频库规模 | 学术数据集(千~万级) | YouTube 亿级 |
| 冷启动处理 | SID 由 content embedding 生成,天然支持 | 同上,新视频用冻结 RQ-VAE 实时生成 SID |
实验设置
论文在 YouTube 生产系统上进行了验证,规模远超学术 benchmark。核心对比是:
- 基线(Random ID):用传统随机哈希 video_id 作为 item 特征,多次哈希减少碰撞(类似 feature hashing trick)
- SemID(N-gram):对 SID 序列用 N-gram 切分,查共享 embedding table
- SemID(SPM):用 SentencePiece 学习数据驱动的子词分割,查共享 embedding table
稠密 Embedding 的退化问题(关键发现)
论文首先展示了一个反直觉的结论:直接把 text embedding(如 content embedding)作为 item feature 送入排序模型,效果反而不如随机哈希 ID。
直觉上:content embedding 含有视频语义信息(标题、描述、类目),理论上比随机哈希更好。
实际上:排序模型的目标是拟合用户行为 log(CTR、完播率),这是强协同过滤信号。Content embedding 是固定向量(frozen),无法针对当前 user 行为数据去优化。而随机哈希 ID 对应的 embedding table 是可学习的,可以充分拟合协同过滤。
结论:"可以学习的协同过滤 embedding" >> "固定的语义 embedding"。SemID 的设计思路不是用语义向量直接代替,而是用 SID 作为"可学习 embedding table 的键"——既享有语义结构(共享前缀 = 共享语义),又可以端到端学习协同过滤。
主实验:SemID 的提升
在线 A/B Test 结论(YouTube 生产系统):
| 方案 | Watch Time ↑ | Satisfaction ↑ | 备注 |
|---|---|---|---|
| Random Hash ID(基线) | — | — | 生产基线 |
| SemID + N-gram | +X%(显著) | +Y% | 相对基线有明显提升 |
| SemID + SPM | 最优 | 最优 | SPM 优于 N-gram |
N-gram 问题(固定窗口切分):SID = [5, 12, 3, 7, 1, 8, 4, 6],Bigram 切分得到 [(5,12), (12,3), (3,7), ...],所有 bigram 等权。但语义上,前几位(粗粒度)比后几位(细粒度)更重要,N-gram 无法体现这种重要性差异。
SPM 优势(数据驱动频率):SPM 发现 [5, 12](某类综艺视频的前缀)在训练数据中出现极多,会将其合并成一个高频子词。同时,[5, 12, 3](更具体的综艺子类)也可能被合并。最终,高频的语义概念会被单独的 embedding 向量所捕获,类似 BPE 在 NLP 中捕获"the"、"ing"等高频词素。
层级验证:前缀共享确实 = 语义相关
论文对 RQ-VAE 生成的 SID 做了定性分析:
- 分享相同 第一位整数 的视频,在宏观类目上高度相似(如都是体育类、都是音乐类)
- 分享相同 前三位整数 的视频,内容更接近(如都是篮球教程中的某个子类)
- 分享全部 8 位整数的视频(完全相同 SID),是内容基本相同的"重复视频"
稳定性:SID 跨时间的稳定性
生产系统需要 SID 稳定——如果每次重新训练 RQ-VAE 后,所有视频的 SID 都变了,过去训练好的 embedding 就全部失效。论文验证了:
- 相同内容的视频在 RQ-VAE 不同训练轮次中,SID 高度稳定(变化率很低)
- 更新内容的视频(如标题改动)SID 会适当变化,反映内容变化
- 结论:SID 稳定性足够支撑排序模型的滚动训练,不需要频繁重置 embedding table
假设场景:今天 RQ-VAE 给"LeBron James 2024季后赛集锦"分配 SID = [3, 8, 12, 5, 1, 9, 4, 7]。排序模型训练了 30 天后,embedding table 中 SID [3, 8, ...](篮球高光视频前缀)已经学到很好的表示。
如果明天重新训练 RQ-VAE,这个视频的 SID 仍然大概率是 [3, 8, 12, ...](因为它的 content embedding 没变)。排序模型不需要"重新学习"这个视频是什么。
相比之下,如果用随机哈希,每次视频 ID 改变(如 re-indexing)所有视频的 embedding 都要从头学。
核心贡献的本质
SemID 的核心贡献可以归纳为:用离散化的语义 ID 替代随机 ID,作为排序模型的 item embedding key,同时设计了工业级的 N-gram/SPM 适配方案,解决了内存约束和长尾问题。
"把 text 的语义压缩到一串整数,再把这串整数当成词去学 embedding"——这个思路看似简单,但它同时解决了三个问题:① 语义结构化共享;② 内存可控(有限词表);③ 端到端可学习(embedding table 非 frozen)。
N-gram vs SPM 的深层区别
- N-gram:系统设计简单,可解释性强,但语义粒度固定(所有 n-gram 等权),无法针对数据分布优化
- SPM:数据驱动,高频共现的 SID 子序列自动合并,更接近 NLP 中 BPE/WordPiece 的效果;缺点是需要额外的训练步骤,子词词表需要维护
- 工程取舍:如果资源有限,N-gram 是更好的起步方案;生产中追求极致效果,SPM 胜出
SemID 范式的广泛适用性
虽然论文针对 YouTube 排序场景,但 SemID 范式可以推广到:
| 应用场景 | SemID 的角色 | 注意事项 |
|---|---|---|
| 召回(Retrieval) | 类似 TIGER,生成候选 SID 序列 | beam search 延迟可接受 |
| 排序(Ranking) | 本文场景,作为 item 特征输入 | serving 延迟最严苛 |
| 多模态推荐 | 图文/视频 embedding 同样可以 RQ-VAE 量化 | 模态融合 embedding 需要特殊处理 |
| 跨域推荐 | 不同平台的视频 SID 可以对齐(共享 codebook) | codebook 对齐是开放问题 |
局限性与未解决问题
- RQ-VAE 训练依赖 content embedding:如果 content embedding 本身质量差(如新语言、冷门类目),SID 的语义质量也会下降
- SID 更新成本:视频内容大幅更新时(如同一链接内容被替换),需要重新计算 SID,增加了系统复杂度
- L=8 超参选择:论文没有详细分析 SID 长度(8 vs 4 vs 16)对性能的影响,实际应用需要根据视频库规模调整
- N-gram/SPM 词表大小:词表太小导致碰撞,词表太大导致内存压力,平衡点需要根据具体业务调优
- 仅限 ID 特征:SemID 只解决了 item ID 特征的问题,其他特征(时长、类目、作者等)仍需传统处理
关键 Takeaway
- 随机哈希 ID 的最大问题是语义盲——相似视频学不到共享知识。SemID 解决了这个根本问题。
- 稠密语义 embedding(frozen)在排序场景不如可学习的 embedding table——可学习性比语义性更重要。SemID 做到了"既有语义结构,又可学习"。
- 工业系统改动要考虑serving latency、内存、稳定性三重约束,纯学术角度的方案(如直接用 text embedding)往往不可行。
- N-gram 和 SPM 的思路本质是把 SID 序列当成"语言"处理——可以持续引入 NLP 的分词技巧来改进。
与周边工作的联系
| 工作 | 与 SemID 的关系 |
|---|---|
| TIGER(Rajput et al. 2023) | 首次提出用 RQ-VAE 生成 SID 用于召回,SemID 将其扩展到排序场景 |
| OneRec(快手 2025) | 在工业规模用生成式模型统一召回+排序,使用 Balanced K-means 代替 RQ-VAE 量化,更关注 session-level 生成 |
| LIGER(Meta 2024) | 混合召回范式,生成式+稠密双路,解决冷启动问题 |
| ETEGRec(RUC+快手 2025) | 端到端联合训练 tokenizer 和推荐模型,解决两阶段解耦导致的次优问题 |
| MTGRec(RUC+华为 2025) | 用多个 tokenizer checkpoint 数据增强,改善长尾问题,与 SemID 的动机(长尾)一致 |
| GRID(Snap 2025) | 开源的 SID 实验框架,系统性研究 RK-Means vs RQ-VAE、encoder-decoder vs decoder-only 等设计选择 |