LinkedIn 的信息流触达超过 13 亿用户,但其底层架构多年来未能与时俱进。系统积累了五个独立的检索管道,每个都有独立的基础设施和优化逻辑。去年,LinkedIn 工程团队决定彻底推翻这一架构,用单一的 LLM 系统取而代之。
从五个管道到一个模型
LinkedIn 过去的 Feed 系统是一个异构架构的集合体:
- 按时间排序的网络索引:展示用户关注的人的最新动态
- 地理热点话题:基于位置的热门内容
- 兴趣过滤:根据用户偏好推送内容
- 行业内容:特定领域的专业信息
- 嵌入向量系统:基于语义相似度的推荐
每套系统都需要独立维护,优化策略互不兼容,运维成本居高不下。新架构的目标是用一个统一的 LLM 来理解内容,并根据用户的专业背景进行个性化匹配。
让 LLM 理解数字信号
重构的第一步是将数据转换为 LLM 可以处理的文本格式。LinkedIn 构建了一个提示词模板库:
- 帖子维度:格式、作者信息、互动计数、文章元数据、正文文本
- 用户维度:个人资料、技能、工作经历、教育背景,以及用户历史互动的时间序列
一个关键发现是:LLM 处理数字的方式会影响模型性能。当帖子有 12,345 次浏览时,如果直接写成”views:12345″,模型会将其视为普通文本 token,失去了”热度”的含义。解决方案是将互动计数转换为百分位桶,并用特殊 token 包裹,让模型能够区分结构性数字和普通文本。
将职业历史视为序列
传统推荐模型假设用户与内容的互动是独立的、随机的。但 LinkedIn 团队意识到:用户的职业发展是一个连续的故事。
LinkedIn 构建了专有的生成式推荐(Generative Recommender,GR)模型,将互动历史视为序列。模型处理用户超过 1000 次历史互动,理解时间模式和长期兴趣。与传统方法相比,GR 模型不是对每篇帖子独立打分,而是基于用户的”职业故事”进行整体推荐。
GPU 成本的平衡之道
引入 LLM 后,LinkedIn 面临一个新的挑战:GPU 成本。团队采取了几项优化措施:
- 计算分离:将 CPU 绑定的特征处理与 GPU 密集的模型推理解耦,避免 GPU 被非核心任务阻塞
- 自定义数据加载器:用 C++ 重写数据加载器,消除 Python 多进程带来的开销
- Flash Attention 优化:构建自定义的 Flash Attention 变体,优化推理时的注意力计算
- 并行检查点:将检查点操作并行化而非串行化,提升 GPU 内存利用率
给工程师的启示
LinkedIn 的重构案例为构建大规模推荐系统提供了具体参考:
- 数字信号在提示词中需要特殊编码
- CPU 和 GPU 工作负载应该显式分离
- 用户历史应该被视为序列,而非独立事件集合
教训不是 LLM 解决了所有问题——而是部署 LLM 会迫使你解决与出发点完全不同的问题类别。这不是降低成本的灵丹妙药,而是一次需要深思熟虑的架构变革。
发表回复