1813 字
9 分钟
TIGER复现笔记

简介#

TIGER是Google提出的一种生成式召回推荐系统。其核心思想是将推荐任务转化为自回归生成任务。 TIGER的工作流程分为三步:

  1. 语义嵌入:使用预训练模型(如BERT)将商品文本描述转化为高维稠密向量(例如768维)。

  2. 量化编码:通过RQ-VAE,将上述稠密向量压缩为一串简短、离散的语义ID(Semantic IDs)。

  3. 序列生成:在召回阶段,训练一个自回归模型(如T5),以用户历史行为序列为输入,直接生成下一个推荐商品的语义ID,从而实现端到端的推荐。

Semantic IDs#

在传统的深度推荐模型(如DLRM)中,物品通常由一个简单的Item ID表示。这个ID经由哈希函数生成,主要用于在庞大的嵌入表中查找物品的Embedding 。然而,这种表示方法存在固有局限:

  1. 哈希碰撞:不同的物品可能映射到同一个ID,造成信息损失。

  2. 词汇表膨胀:每个新物品都需要一个新ID,导致模型参数剧烈增长。

  3. 冷启动困难:全新物品的ID缺乏历史交互数据,其嵌入难以训练。

  4. 语义缺失:DLRM依赖于User和Item的交互,模型无法利用物品本身的语义信息。

为解决这些问题,语义ID 应运而生。与单一ID不同,一个物品由一串有序的离散编码来表示,每个编码捕捉物品不同层级的语义信息(由粗到细)。这不仅极大地压缩了词汇表规模,还使模型能够理解物品之间的内在关联,增强泛化性。

RQ-VAE#

介绍RQ-VAE之前,我们首先简要介绍VAE(自分编码器)。VAE是一种生成模型,它通过学习将输入数据编码到一个低维的、连续的“潜空间”,再从中解码重建数据,本质上是一个有损压缩过程。 RQ-VAE是VAE的一个变种,其核心创新在于引入了残差量化 和 离散码本

  • 离散码本:它是一个包含固定数量向量的“字典”。RQ-VAE的目标不是生成一个连续的潜变量,而是用码本中的一系列向量来组合表示原始输入。

  • 残差量化:这个过程是迭代进行的。首先,用码本中一个最接近的向量来近似原始嵌入(产生第一个语义ID)。然后,计算近似后的残差,再用码本对残差进行量化(产生第二个语义ID)。如此重复,直到用一串ID(如[42, 15, 7])来精确表示原物体。 最终,一个商品的高维稠密嵌入,就被转化为了一串简短、可解释的语义ID。 RQ-VAE的生成过程契合由粗到细的规律,因此带来了一个关键优势:语义的层次化编码。最终得到的语义ID序列,其每个位置的token天然地对应着不同粒度的语义信息。(如:第一个token代表鞋,第二个token代表运动鞋,第三个token代表篮球鞋…),这极大地增强了系统的泛化性,因为语义相似的物品(如“篮球鞋”和“足球鞋”),其语义ID的前缀必然相同或高度相似。 同时,由于RQ-VAE利用的是Item的语义信息,冷启动问题被极大地缓解(新物品也有语义信息)。 alt text

RQ-VAE具体实现#

RQ-VAE架构#

alt text

K-Means Init#

对于每一层VectorQuantizer,在第一次forward时,对来自上一级的输入进行K-Means聚类,然后用聚类簇的中心初始化码表

Loss函数#

  • RQ-VAE使用三种Loss函数:

  • commitment_losscodebook_loss在VectorQuantizer中使用。两者皆为输入embedding与距之最近的码表向量的“距离”,但是codebook_loss不对输入embedding进行反向传播,从而只优化码表;而commitment_loss不对码表向量进行反向传播,从而只优化编码器,使编码器输出向已选码本靠拢。

commitment_loss = F.mse_loss(x_q.detach(), x)
codebook_loss = F.mse_loss(x_q, x.detach())
  • reconstruction_loss:重建损失。

Sinkhorn-Knopp#

问题:富者越富 (Rich get richer)#

  1. 初始化时,某些码本向量可能离数据稍微近一点点。
  2. 这些“幸运”的码本会被大量样本选中,并在训练中不断更新,变得离数据更近。
  3. 其他码本因为从未被选中(或选中概率极低),永远得不到梯度更新,变成 “死码” (Dead Code)。
  4. 结果:虽然设定了 256 个码本,实际可能有 200 个都是空的,模型容量被浪费了

数学解释#

给定一个非负矩阵 Q,我们要找到两个对角缩放矩阵 D1​ 和 D2​,使得变换后的矩阵P=D1​QD2​ 满足两个约束:

  1. 行和约束:每一行的和固定。
  2. 列和约束:每一列的和固定。
迭代公式#

假设输入是相似度矩阵Q(0),迭代过程如下:

Step 1: 行归一化 (Row Normalization)

使得每一行的和符合约束

Qij(t+0.5)Qij(t)kQik(t)Q_{ij}^{(t+0.5)} \leftarrow \frac{Q_{ij}^{(t)}}{\sum_{k} Q_{ik}^{(t)}}

Step 2: 列归一化 (Column Normalization)

使得每一列的和符合约束。

Qij(t+1)Qij(t+0.5)lQlj(t+0.5)Q_{ij}^{(t+1)} \leftarrow \frac{Q_{ij}^{(t+0.5)}}{\sum_{l} Q_{lj}^{(t+0.5)}}

重复这两个步骤直到收敛。

效果#

Sinkhorn 通过迭代归一化,强制要求每个码本在一个 Batch 中被分配到的总概率权重相等。这迫使模型去激活那些冷门的码本,最大化离散编码的熵。

  • 实际上,我还没有太理解这个算法😂(2026.01.20)

sentence-t5模型训练#

TIGER系统的最后一步,是利用编码好的语义ID训练一个Encoder-Decoder架构生成模型(如 sentence-T5)。这一过程的本质,是将推荐任务重构为一个Seq2Seq任务

  • 输入序列:用户近期交互过的物品(已转化为语义ID序列)。

  • 输出序列:模型生成的、推荐给用户的下一个物品的语义ID。 在推理(实际推荐)阶段,模型需要根据用户历史,生成最可能的下一个语义ID序列。这里,直接选择概率最高的单个输出(贪心搜索)容易陷入局部最优,导致推荐结果单一。为此,TIGER在推理时采用了Beam Search。

总结#

作为早期的生成式推荐模型,TIGER的主要贡献在于:一方面,创新性地使用RQ-VAE为物品构建语义ID;另一方面,成功将自回归模型应用于召回阶段。 与后来OneRec等端到端推荐模型不同,TIGER的价值恰恰在于其结构简洁、复杂度低,,非常适合作为初学者入门该领域的首选模型。

后记#

这是我的第一篇技术文章(应该勉强算是吧😂),下笔时往往感觉词不达意,内容空洞,此时才感到语文没学好的痛苦😭。无奈之下,只能求助于DeepSeek重写(重写的效果其实也不尽如人意)。慢慢来,希望以后我能写出更好的文章🤤

参考:

TIGER复现笔记
https://xikus.github.io/posts/tiger复现笔记/
作者
xikus
发布于
2026-01-20
许可协议
CC BY-NC-SA 4.0