← 论文沉淀 / 🗂 Semantic ID · ·RecSys 2026

RankGraph-2: Lifecycle Co-Design for Billion-Node Graph Learning in Recommendation

Renzhi Wu, Zikun Cui, Junjie Yang, Tai Guo, Hong Li et al. (13 人)

Meta MRS × Meta Training Data Infra × FB Monetization

提出“生命周期协同设计”:把十亿节点图召回的建图、训练、在线服务三段看成互相传递需求的整体,而不是各自优化。服务端用与图模型联合训练的两层残差量化簇索引(5000×50=25 万簇)替代在线 KNN,U2U2I 变成读簇内最近活跃用户的物品队列;训练端用离线 PPR 预计算邻居 + 自包含边中心数据,彻底去掉在线图存储/采样引擎;建图端用流行度纠偏 + 截断把数百万亿边压到数千亿并 1 小时内重建。

Co-learned RQ Cluster IndexBillion-Node GNNU2U2I RetrievalCodebook BalancingOffline PPR Neighbors
📝 我的备注
加载中…

核心思路

RankGraph-2 是 Meta 在十亿节点规模上做图召回的系统论文,它的核心论点是生命周期协同设计:建图、训练、在线服务三段互相约束,下游的需求应当反推上游的设计,而不是各段分别优化。

需求链是这样传递的:

  • 服务 → 训练:U2U2I 召回发现“只看最近 15 分钟活跃的相似用户”效果最好,但对这样持续变化的候选池做在线 KNN 需要数千台机器,静态 KNN 映射又跟不上。于是改成簇召回:每个用户分到一个簇,簇里维护最近活跃成员的物品队列,服务时直接读队列。簇索引必须与嵌入联合训练,否则质量掉。
  • 训练 → 建图:相似度类召回(U2U、I2I)依赖的结构信号变化慢,可以把邻居计算挪到离线。这样就不需要在线图存储和分布式采样引擎,训练跑在普通 ML 基础设施上;而且离线还能做在线做不了的多跳 PPR 和流行度纠偏。这要求建图产出自包含的边中心数据。
  • 服务 → 建图:新物品覆盖需要小时级刷新,所以整条建图流水线要在 1 小时内跑完,每 3 小时全量重建一次。

和 SID 方向的关联:本文的簇索引就是与主任务联合训练的两层残差量化码(5000×50=25 万簇),并给出了持续训练下防码本坍缩的两种做法。RQ 码在这里不是拿去做生成式解码,而是直接当成簇 ID 来做 U2Cluster2I 召回。

整体实现思路

  1. 建图(24 小时互动数据,每 3 小时全量重建一次,单次约 1 小时):建三类共互动边 U-I / U-U / I-I,对 I-I 边做流行度纠偏,再做两步子采样,把数百万亿条边压到数千亿条;然后在主干图上用蒙特卡洛 PPR 为每个节点预计算 50 个重要的用户邻居和物品邻居,输出按边类型分区的边中心样本。
  2. 训练(持续训练):类型专属的多头编码器加异构聚合器,在边上做对比式链接预测(margin + InfoNCE),同时联合训练 RQ 簇索引(重建损失、重建嵌入上的对比损失、码本均衡正则)。
  3. 服务:U2I2I 离线预算 I2I KNN;U2U2I 按用户簇码读簇内实时物品队列,不做近邻搜索。从互动到嵌入刷新端到端约 2 小时。

子模块实现(可复现细节)

1. 异构共互动图

所有边都来自互动数据(点击、点赞、分享、购买),不用社交关系或知识图谱。

  • U-I 边:过去 T 小时内用户和物品有过互动就连边,权重按互动类型取业务预设值,方向为用户指向物品。
  • U-U 边:两用户共同互动过的物品集合为 I(ni,nj),当 |I| >= CU 时连边,权重 w = ln( Σ_{e∈I} w_{ni,e} · w_{nj,e} )。取对数是为了把高频用户和低频用户的权重拉到同一量级。
  • I-I 边:两物品的共同用户集合为 U(ni,nj),当 |U| >= CI 时连边,权重 w = ln( Σ_{e∈U} w_{e,ni} · w_{e,nj} )。

作者说明,每个节点类型对只用一种共互动关系、再配合子采样,效果好于多种细粒度关系类型;后者会让图变大,但质量没有相应提升。

2. 流行度纠偏(仅 I-I)

w'_{ni,nj} = w_{ni,nj} · ( w_{nj,ni} / Σ_k w_{nj,nk} )^α,其中 α = 0.3。

nj 越热门,分母越大,这条边被压得越低。纠偏后 (ni,nj) 与 (nj,ni) 的权重不再相等,两条都保留。

3. 边子采样

  1. U-U 边只保留按业务价值挑出的约 0.1B 个用户节点(每日刷新);U-I 边保留全部节点。
  2. 每个节点只保留权重最高的 KCAP 条边。

经过这两步,边数从数百万亿降到数千亿,结果称为扩展图。有同类型邻居的节点为 Group 1,它们和它们的边构成主干图;没有同类型邻居的节点为 Group 2。

4. PPR 邻居预计算

  • 在主干图上用蒙特卡洛随机游走近似 PPR:R 条长度为 L 的游走,重启概率 0.15,可以在十亿节点上做到完全并行。边类型权重先归一化,避免某一类边主导 PPR 结果。
  • 每个节点取 KIMP = 50 个用户邻居和 50 个物品邻居。这些 PPR 邻居不作为新边加进图,只作为固定长度的预计算邻接表供训练使用。
  • Group 2 节点用上一轮训练得到的 Group 1 嵌入做 KNN(每日更新)来补同类型邻居;物品邻居取权重最高的 U-I 边。
  • 训练时,每条边从 50 个预计算邻居中随机采 K’IMP = 10 个。
  • 输出为边中心格式:每条记录包含 (ni, nj, w)、两端节点的特征及其采样邻居,按边类型分区。

5. 图模型

归纳式设置:节点有实值特征,用共享编码器,因此能泛化到未见过的节点。

M(ni) = AGG_t( f_t(X(ni)), {f_U(X(e)) | e∈N_U(ni)}, {f_I(X(e)) | e∈N_I(ni)} )

  • 每个节点恰好有 K 个用户邻居和 K 个物品邻居。
  • f_t 和 AGG_t 都是多头结构:训练时,不同头输出的嵌入互作额外负例;推理时对多头取平均。
  • 用户特征包括人口属性和最近互动的物品序列;物品特征包括内容类型和 id 类特征。嵌入维度为 256。

6. 负采样与损失

  • 负例来自三路:in-batch、跨 batch 的滚动负例池、多头增广。每条正边采 100 个与 nj 同类型的负例。
  • L_margin = Σ_k max(0, s_neg,k − s_pos + 0.1),相似度用余弦。
  • L_infoNCE = −log( e^{s_pos/τ} / (e^{s_pos/τ} + Σ_k e^{s_neg,k/τ}) ),τ = 0.06。
  • L_ij = λ·L_margin + (1−λ)·L_infoNCE。
  • 每个 batch 混合所有边类型:L = β1·L_UU + β2·L_UI + β3·L_IU + (1−β1−β2−β3)·L_II。λ 和 β 用 Kendall 不确定性加权学习。
  • 优化器:稀疏参数用 AdaGrad(lr 0.02),稠密参数用 AdamW(lr 0.004),batch 大小 32,768,持续训练。取数、预处理和负采样放在 CPU 上,与 GPU 训练重叠执行。不依赖图引擎带来的 batch 大小是确定的,MFU 更高。

7. 联合训练的 RQ 簇索引

两层残差量化:

k_i = argmin_j || h_{i-1} − C_{i,j} ||²
h_i = h_{i-1} − C_{i,k_i}
h'  = Σ_i C_{i,k_i}

码本大小为 |C1| × |C2| = 5000 × 50 = 250,000 个簇。

损失由四项组成:主损失 L;重建嵌入 h’ 上的同一对比损失 L’;L_recon = ||h − h'||²(对正边两端和负例取平均);码本均衡正则 L_reg。四项同样用不确定性加权组合。

8. 持续训练下的防码本坍缩

  • 均衡正则:维护最近 1000 个 batch 的选码队列,得到第一层的经验分布 p̂。当前 batch 做软分配 p(h,C)[j] = exp(ζ1/(ζ2+d_j)) / Σ_k exp(ζ1/(ζ2+d_k)),其中 ζ1 = 10、ζ2 = 0.01、d 为到各码字的距离。对 batch 内所有 h 求和并归一化,得到 p(C)_batch。L_reg = p̂ · p(C)_batch,对所有层取平均。直觉是:当前 batch 越往已经常用的码字上堆,惩罚越大。
  • 有偏选码:k_i = argmax_j p(h_{i-1}, C_i)[j] / p̂[j],偏向使用较少的码字。作者认为由此带来的轻微分散在发现型场景里相当于一种探索。

9. 簇召回服务

  • 每个用户有簇码 c = (k1, k2),每个簇维护其最近活跃成员(例如过去 15 分钟)互动物品的实时队列。U2U2I 由此变成 U2Cluster2I,即读取目标用户所在簇队列里的最新物品。
  • 簇需要足够大,保证经过时间过滤后仍有足够多的活跃用户;又需要足够小,保证簇内用户相似。这个平衡靠调整码本大小来找。
  • 每次重建图后立即重算嵌入,按节点 ID 聚合过去一周的结果,每个节点保留最新一份。

实验设置与结果

评测在 Meta 的两个推荐面(Surface 1 和 Surface 2)上进行,各服务数十亿用户。图包含数十亿节点和数千亿条边。作者没有跑公开基准,理由是公开数据集的规模小几个数量级。

用户嵌入(随机 10 万用户,top-100 KNN 邻居,用次日互动计算召回)

MethodR@5R@10R@50R@100
GAT-DGI0.0380.0660.1800.251
HSTU0.0130.0240.0850.135
RankGraph-20.1430.2090.3990.482

物品嵌入(用第 N 天的嵌入预测第 N+1 天的 I-I 共互动,抽样 1000 条边)

MethodR@5R@10R@50R@100
PBG0.0170.0300.2440.374
HSTU0.1320.1770.3490.434
RankGraph-20.1470.1960.5090.775

簇索引质量(Hitrate@K:正边的相似度在负例中排进前 K)

MethodHR@1HR@5HR@10
原始嵌入0.8710.9810.997
重建嵌入0.8460.9730.994
重建嵌入,去掉正则0.7170.8770.931

带正则时码本利用率为 100%;去掉正则后利用率“显著下降”,论文没有给出具体数值。

消融(用户嵌入协议)

边类型R@5R@10R@50R@100
仅 U-I0.0520.0810.2100.285
U-I + I-I0.0890.1340.2850.352
U-I + U-U0.1150.1700.3310.410
U-I + U-U + I-I0.1430.2090.3990.482
邻居策略R@5R@10R@50R@100
随机0.0450.0720.1900.260
权重 Top0.0980.1450.2950.370
PPR0.1430.2090.3990.482
流行度纠偏(物品协议)R@5R@10R@50R@100
无纠偏0.1120.1510.4150.620
有纠偏0.1470.1960.5090.775

在线 A/B(14 天,p < 0.05,在现有链路上新增一路召回源)

召回SurfaceCTRCVR
U2I2ISurface 1+0.96%+2.75%
U2I2ISurface 2+0.33%+0.76%
U2U2ISurface 1+0.40%+1.01%
U2U2ISurface 2+0.20%+0.17%

在 U2U2I 上,簇索引与在线近似 KNN 的 CTR、CVR 相当,服务资源则从数千台机器减少了 83%。截至论文发表,RankGraph-2 已支撑 20 多次召回上线。

思考与可参考价值

  • RQ 码作为簇 ID 使用。SID 通常用来做生成式解码,本文展示了另一种用法:把联合训练出的两层 RQ 码直接当作用户簇,每个簇挂一个实时物品队列,相似用户召回由此变成查表。在电商里,这对应“和你相似的人最近在买什么”,可以替代对活跃用户池的在线 ANN。需要注意,这里的码完全基于协同信号,不含内容语义;如果把它当 SID 用,冷启动物品和新用户从中得不到好处。
  • 持续训练下的码本均衡可以直接复用:用最近 1000 个 batch 的选码队列估计 p̂,正则项为 p̂ 与软分配分布的点积,选码时按 p / p̂ 取 argmax。实现成本很低,表中 HR@1 从 0.717 提到 0.846。对天级或小时级增量更新的 SID 码本有参考价值。
  • 在重建嵌入上再算一遍主任务损失 L’,让量化误差直接作用到检索目标上。这比先训好嵌入、再单独训 RQ-VAE 更贴近下游任务。
  • 流行度纠偏 (w_ji/Σw_j·)^0.3 对电商爆品主导共现的问题有直接意义,可以用在构建 I-I 图上,也可以用在为 SID 构造共现监督信号上。
  • 离线 PPR 加边中心样本,可以在不引入图引擎的情况下把多跳协同信号接进现有的双塔或序列训练流水线。

论文的不足:

  • 基线偏弱。GAT-DGI 只在二部图上训练;HSTU 是序列模型,被直接拿来做 U2U KNN;PBG 是平移嵌入方法。缺少同图、同邻居条件下只更换模型的对照,所以 3.8 倍的提升更多反映图和邻居构造的质量。
  • 缺少关键对比实验。“预计算邻居与在线采样质量相当”这一论断没有与在线采样直接比较;簇索引对 KNN 只说了“相当”,没有给出具体数字,也没有码本大小的扫描结果。
  • KCAP、CU、CI、T、R、L 等关键超参没有公开,也没有代码。

落地前需要确认的问题(推断):

  • 电商的活跃密度远低于 Meta 的内容流。25 万个簇配 15 分钟的时间窗口,可能导致很多簇在窗口内是空的,簇大小和时间窗口都要重新调。
  • 有偏选码会让用户被分到并非最近的码字,需要评估这对簇纯度的影响。
  • 3 小时一次的刷新在大促等强时效场景下可能不够快。