数据中心/云端

生成式推荐系统如何大规模重新定义 RecSys

推荐系统 (RecSys) 是消费互联网行业最常见的机器学习问题之一,但众所周知,很难进行大规模训练和服务。LLM 的出现激发了从传统的基于嵌入 – 相似性的目标向生成式目标的转变,即根据一系列用户历史记录来预测大型目录中的下一个行动或项目。本文将介绍向生成式推荐系统 (GR) 的架构转变、它引入的生产挑战,以及 NVIDIA recsys-examplesnv-embedding-cache 如何解决

为什么传统的 RecSys 无法大规模运行

数据类型和数量

用户历史记录是 RecSys 的主要数据类型,用于记录用户与目录中商品的交互方式。与文本或图像等模态不同,用户历史记录涉及随着时间的推移经常变化的分类特征和连续特征的混合。在行业规模上,这些数据每天可能达到 TB 或 PB 的数量级。即使在高端硬件加速器上,这种规模的数据也无法适应 GPU 高带宽内存 (HBM) ,从而在训练和推理过程中引入许多瓶颈。

稀疏性和长尾问题

推荐系统中的长尾问题是指目录中的少量热门商品在交互中占据大多数的现象。出现此问题的原因是,商品目录可能远远超过用户数量,从而导致用户 – 商品交互数据非常稀疏。由于与物品交互的概率分布严重偏向于该物品的受欢迎程度,因此训练数据对绝大多数表示用户偏好事实的特定物品几乎没有提供任何信号。

冷启动问题

当新用户或物品加入 RecSys 平台时,没有交互历史记录可以立即生成高质量的嵌入。相反,它必须从较小的特征集推断出来,这可能会对推荐系统的运行轨迹产生负面影响。通过关联类似项目和语义描述,可以部分解决此问题,但存在初始推荐效果不佳并降低用户体验的风险。

严格的延迟要求

在生产环境中,RecSys 模型通常根据严格的服务水平协议 (SLA) 在线提供给数百万用户,其中延迟的小幅增加会影响用户体验。与可能容忍自回归解码延迟的 LLM 工作负载不同,RecSys 模型必须在几毫秒内频繁检索数千个候选项并对其进行排序。

生成式推荐系统

与传统的基于嵌入的推荐系统以几何相似度模拟用户商品偏好不同,GR 将推荐系统重构为类似于 LLM 的序列建模问题。

目标是根据一系列用户历史对下一个行动或物品的概率分布进行建模:

P(next_item | user_history)

向更均质、类似 Transformer 的架构的转变可以更好地利用扩展定律,有可能在单个模型中统一检索和排名,并更自然地与快速发展的 LLM 生态系统集成。

在推荐系统中实现此目标的两种常用方法是分层顺序转导单元 (HSTU) 和语义 ID:

HSTU

Meta 于 2024 年推出的 HSTU 是一种基础 GR 模型架构,它在生成目标下重新定义了 RecSys,并引入了关键创新,以实现生产规模的高效训练和服务。

HSTU 将输入数据表示为交错项目和操作 (如、单击等) 的每个用户序列按时间排序。它还消除了对显式特征工程的依赖 (传统 RecSys 模型中的常见做法) ,转而采用从注意力中学习到的顺序表示,而不是用户 – 商品交互。这种表述使用户历史记录类似于 LLM 中的下一个 token 预测,在训练中,您可以在序列内和批量中获得有意义的学习信号。

与标准 Transformer 注意力不同,HSTU 通过将 softmax 归一化替换为基于 SiLU 的权重来修改注意力聚合机制,加入相对注意力偏差,并在输出投影之前应用元素级门控。这些修改可在长序列中保留更强的信息量,同时实现更高效的内核融合和更低延迟的推理。

语义 ID

对具有稀疏用户 – 商品交互集的大型商品语料库进行下一个商品预测建模可能会带来许多挑战:全 softmax 计算的瓶颈、长尾商品的训练信号较弱,以及语义相似商品的泛化能力差。

Google 推出的语义 ID (SID) 可根据商品嵌入的层次聚类生成一组较小的新词汇量标记,从而缓解这些问题。TIGER、PLUM、OneRec v1/v2 等架构以及许多现代 GR 架构都使用语义 ID 作为可扩展自回归推荐的基础。

与传统的 RecSys 不同,语义 ID 的自回归解码直接生成推荐,而不是在嵌入空间中进行搜索,并自然地通过输出 logits 提供排名。这使得束搜索等搜索方法能够在一次正向传递中生成多个语义 ID,从而提高吞吐量,并允许选择集群中的特定项目。

recsys-examples 存储库

The recsys-examples 存储库是一个示例集合,展示了使用 PyTorchNVIDIA GPU 上训练和部署生成式推荐系统的最佳实践。它包括 HSTU语义 ID 模型的优化实施,涵盖训练和推理工作流。该库还整合了三个模块化组件:用于嵌入层的 DynamicEmb、为推荐系统定制的 KV 缓存存储管理器,以及用于 HSTU语义 ID 束搜索解码的高效 CUDA 运算

动态嵌入

RecSys 中的传统嵌入表采用固定的静态词汇表。但是,在生产环境中,新用户和商品会不断出现,而且商品目录的长尾增长速度远快于任何单个 GPU 的 HBM。过度配置静态表会浪费永远不会触碰的行上的内存,而不足配置会导致副本成本高昂,进而降低模型性能和质量。

DynamicEmb 使用 GPU 优化的评分哈希表替换静态表,该哈希表可按需将任意特征 ID 映射到嵌入行。系统仅会为模型实际看到的 ID 分配行,且表位于 HBM 和固定主机内存中,因此其容量会远远超出单个 GPU 的容量。该实现基于 HierarchicalKV 哈希表设计中的算法。准入控制和基于分数的驱逐相结合,可将容量用于对模型训练至关重要的 ID,并使长尾问题可以大规模解决。

它作为 TorchRec 后端提供,并使用 EmbeddingBagCollectionEmbeddingCollection API 跨秩对表进行行分片。融合后的 CUDA 内核可处理 SUMMEAN 和序列池化模式的查找和梯度归约。预取技术会将经常访问的嵌入保留在 HBM 中,以实现高效访问。

HSTU 支持

Recsys-examples 为 HSTU 提供了生产式训练和推理堆栈。物品、用户、动作和上下文嵌入表通过 TorchRec 进行管理,DynamicEmb 为高基数表提供动态容量和缓存。对于密集层,HSTU 主干使用 Megatron-Core,因此一次训练可以利用数据、张量、序列和工作流并行。该库在整个堆栈中采用模块化设计,因此组件可以使用自定义架构即插即用。

在训练期间,TorchRec/DynamicEmbMegatron-Core 可无缝集成,以协调嵌入和密集模块之间的分片和并行处理。该训练流程采用动态混洗技术来平衡 rank 之间的工作负载,将嵌入通信和预取与密集计算重叠,并包含具有融合运算的 HSTU 层以及针对 NVIDIA Ampere、Hopper 和 Blackwell GPU 优化的 FBGEMM 注意力内核。这些优化将端到端模型浮点运算利用率 (MFU) 从两个 DGX H100 节点上的 7.65% 提高到 31.40%,显著提高了训练效率

在推理方面,recsys-examples 旨在满足严格的低延迟要求,支持 PyTorch AOTInductor 在 Torch C++ 运行时中执行模型,同时保持与 NVIDIA Triton 推理服务器兼容。

使用 nv-embedding-cache 将经常访问的嵌入保持在靠近 GPU 的位置,并通过自定义的启用 FlexKV 的 KV 缓存 (在多个内存层之间分配缓存条目) 进一步减少计算。

与 Triton 推理服务器一起部署时,使用 Pytorch AOTI 后端和无 KV 缓存的推理速度比 Python 后端快 1.14 倍~1.28 倍,使用 Pytorch AOTI 后端和 KV 缓存的推理速度在理想的全 GPU 缓存场景中快 2.20 倍~2.38 倍。

语义 ID-GR

基于语义 ID 的 GR 引入了一种与基于聊天的 LLM 推理截然不同的服务模式:长用户上下文、简短的自回归解码,以及在受限的商品标记空间上的大波束宽度。在实际语义 ID 工作负载中,请求可能包含数千个历史令牌,仅解码 2 – 3 个语义 ID 令牌,并使用波束宽度 (例如 128 或 256) 来改进推荐多样性。

vLLM、SGLang 和 TensorRT LLM 等现有 LLM 服务系统主要针对具有分页 KV 缓存、动态批处理和长解码的多用户聊天式服务进行了优化。它们是功能强大的通用框架,但并不会自然而然地展示语义 ID-GR 所需的核心抽象概念:共享请求级上下文 KV、每束短解码 KV、波束路径跟踪、动态波束宽度和项目约束生成。

为解决此问题,recsys-examples 为基于 Qwen 的语义 ID 模型提供了 示例。该框架将 KV 缓存分离开来,以隔离与波束相关的组件和独立组件:长共享上下文转换为 ContextKV,短解码历史记录转换为 BeamKV,逻辑束起源转换为 BeamPath。这避免了将每个光束视为单独的长序列。运行时还包括 GR 原生连续批处理、直接池视图 CUDA 图形回放、项目受限的 topK,以及直接在 GR KV 布局上运行的专用 gr-decode_atten 后端。

在搭载 Qwen3-1.7 B 的单个 NVIDIA H100 80GB GPU 上,上下文长度为 1000 和 5000 个令牌,束宽为 256,输出令牌为 3,在测量的离线和在线基准测试中,GR 专用路径的表现始终优于 SGLang 束搜索。

指标 工作负载 GR 结果 基准 改进
离线延迟 ctx=1000, batch=4, beam=256, output=3 47.736 毫秒 102.318 毫秒 速度比之前快 2.14 倍
离线延迟 ctx=5000, batch=4, beam=256, output=3 164.224 毫秒 349.857 毫秒 速度提高 2.27 倍
离线延迟 ctx=5000, batch=8, beam=256, output=3 107.917 毫秒 685.354 毫秒 速度提高 2.23 倍
在线服务吞吐量 ctx=5000, concurrency=4, beam=256, output=3 = 19.7 req/ s = 10.7 req/ s 增加+ 1.85 倍
在线中值延迟 ctx=5000, concurrency=4, beam=256, output=3 约 199 毫秒 约 370 毫秒 + 降低 46%
离线正确性 ctx=1000/5000, batch=1/2/4/8, beam=256 Top1 exact 1000 SGLang 比较 TopK 重叠均值 0.960

表 2. recsys-examples 的服务结果语义 ID-GR 推理框架

这使得语义 ID-GR 在 recsys 示例中成为对 HSTU 和嵌入组件的自然补充:HSTU 和 DynamicEmb 可处理生产级训练和嵌入密集型推理,而语义 ID-GR 推理路径则针对具有长上下文、大束搜索和严格推荐系统延迟要求的自回归语义 ID 生成。

nv-embedding-cache

nv-embedding-cache (NVE) 是一个 SDK,用于加速推荐系统推理中的大规模嵌入表查找和操作。它提供模块化组件,包括优化的内核、软件缓存基元和与 PyTorch 兼容的绑定,从而实现对嵌入表的低延迟访问,其容量超过单个 GPU 的 HBM。

产品级推荐嵌入表通常会超出单个 GPU 的 HBM 容量,迫使推理系统跨多个内存层暂存嵌入。此外,推荐系统通常表现出非常有利于缓存的访问模式。

NVE 通过分层查找流对此进行管理,该流程由 HBM 中的 GPU 缓存 (热层) 、DRAM 中的 CPU 缓存 (热层) 和远程参数存储 (通常为 Redis 或 RocksDB 支持) 组成。热键升级到 GPU 缓存是可定制的,并且无锁的 invalidate-and-commit 协议允许在 GPU 上同时运行查找和缓存修改,而不会导致查找流停止。跨设备的分片通过 CUDA 虚拟内存处理,因此单个逻辑表可以跨多个 GPU 或节点。

NVE 提供 NVEmbeddingNVEmbeddingBag 作为 torch.nn.Embeddingtorch.nn.EmbeddingBag 的直接替代品,以便轻松与 PyTorch 生态系统集成。这些模块会公开熟悉的参数,同时添加特定于缓存的配置标志。由于这些层的行为类似于标准 nn.Module 组件,因此它们可以集成到现有的推荐系统模型中,并且只需对图形进行极少的更改。为便于部署,NVE 将其查找运算符注册为 LibTorch Stable ABI,从而在 C++ 运行时中提供 AOTInductor 支持。

NVE 支持 Recsys-examples DynamicEmb 表,允许在训练和推理之间轻松过渡。在 DLRM v3 上,基于 HSTU 的 MLPerf 生成式推荐系统基准测试、recsys-examples 和 NVE 能够在在线服务器场景中实现 99997 条查询/ 秒的推理吞吐量。此处提供了如何使用这两个库执行推理的示例。

开始使用

请查看以下资源库,获取快速入门指南和更多详细信息:

标签