Stories by Pinterest Engineeri... 笔记

Stories by Pinterest Engineering | Medium 中文

Medium 上的 Pinterest 工程展示了推动流行视觉发现平台的技术创新。通过深入的文章,工程师们分享了他们在可扩展性、机器学习、数据基础设施等方面的工作见解。该出版物强调了 Pinterest 的工程文化,强调协作、实验和解决复杂问题的热情。读者可以探索诸如构建推荐系统、优化搜索功能和开发数据分析工具等主题。内容为工程师和技术爱好者提供了宝贵的视角,了解像 Pinterest 这样的大型平台的技术细节。无论是深入研究图像识别的挑战还是他们基础设施的演变,Medium 上的 Pinterest 工程都为人们提供了一个迷人的技术视角。

笔记线程

现代推荐系统因其大规模和分布式特性,在测试与调试方面面临重大挑战。传统的“模型优先(Model-First)”方法导致硬件瓶颈、输入数据依赖以及迭代反馈循环缓慢。ModuleLens 引入了一种“模块优先(Module-First)”范式,使工程师能够本地隔离、重构和剖析各个模块。这显著加速了开发工作流,并促进了自主 AI 代理的优化。ModuleLens 架构由 ModuleTracer、ModuleRepo 和消费层(Consumption Layer)组成。ModuleTracer 通过 PyTorch 前向钩子(forward hooks)以无侵入方式捕获关键的运行时数据,包括张量、参数和初始化参数,高效处理大张量并在内存中追踪模块初始化。ModuleRepo 将提取的模块状态集中存储于 Weights & Biases(WandB)注册表中,通过集合索引进行组织,并以包含元数据和二进制负载的版本化制品形式进行管理。消费层为人类工程师提供交互式 Jupyter 扩展和 IPython 命令行接口,并为大语言模型(LLM)代理提供 Agent Skills。这使得调试、探索以及自主模块分析与优化成为可能。ModuleLens 已被应用于多种内部工具,包括用于瓶颈识别的训练分析器(Training Analyzer)、用于 GPU 内核生成与验证的 KernelAgent,以及用于评估基础设施成本的扩展定律投资回报率工具(Scaling Law ROI Tools)。未来计划包括稳定核心系统、增强 Agent Skills 以支持高级优化(如 Triton/CUDA 内核合成),并实现自主训练与服务优化。ModuleLens 旨在提升人类工程效率,并为模型自动研究和递归自我改进提供执行基础。通过提供对隔离模块和性能信号的可靠访问,ModuleLens 赋能代理进行实验、修改组件、基准测试并保留成功的变更。本项目感谢来自产品机器学习基础设施(Product ML Infra)、ATG、HomeFeed 和广告排序团队的众多贡献者,他们在领导、设计洞察、测试、采用及代码开发方面提供了关键支持。
CdXz5zHNQW_NEug4e7mVW.png
Pinterest 服务着 6.4 亿用户,与 Intel 合作,通过性能分析(profiling)提升基础设施效率。初期,他们面临分析工具碎片化以及需要统一可扩展解决方案的挑战。他们选择增强开源工具 gProfiler,该工具最初由 Granulate 开发,而 Granulate 曾是 Intel 的子公司。此次合作旨在为大规模云环境构建一个稳健的性能分析系统。Pinterest 和 Intel 扩展了 gProfiler,增加了动态性能分析功能,支持按需启动分析会话。他们集成了 Intel PerfSpect 以获取硬件遥测数据,捕获诸如缓存行为和 CPU 停顿等细节。同时引入了墙钟时间(wall-time)性能分析,以检测 I/O 或锁竞争导致的延迟,这些是 CPU 火焰图(flame graphs)所遗漏的。此外,他们还添加了 PMC 火焰图,将函数与硬件事件关联起来,并贡献了生产环境加固修复,以确保大规模部署下的效率。该合作聚焦于开源方法,以避免供应商锁定并促进协作。gProfiler 编排多种语言特定的性能分析器,生成统一的火焰图,提供系统活动的全面视图。Pinterest 决定合作,是出于认识到从头构建如此复杂的工具将极其艰巨,而 Intel 的硬件专业知识对于深入分析瓶颈至关重要。gProfiler 及其后端 gProfiler Performance Studio 的开源,为 Pinterest 提供了可在此基础上构建的基础。随后,Pinterest 在其整个机队中部署了 gProfiler 代理,解决了与资源消耗和数据摄入相关的可靠性问题。他们的重大贡献包括动态性能分析功能,实现了全机队范围内的按需分析。这些贡献还解锁了额外能力,如墙钟时间性能分析和基于硬件事件的火焰图。gProfiler 的架构由每个节点上的数据收集代理和负责聚合与可视化的后端组成。代理协调各种语言性能分析器,生成合并的堆栈跟踪,从而在不修改应用代码的情况下提供统一视图。后端微服务负责处理性能数据摄入、存储至 S3、索引至 ClickHouse,并通过 React 前端进行可视化。
CdXz5zHNQW_4O814w3FCn.png
Pinterest 旨在理解用户的长期目标,即“旅程”(journeys),这是一系列与特定兴趣和意图相关的交互序列。这超越了仅基于单次点击推荐下一个物品的简单做法。识别这些旅程能够提供更相关的推荐和通知,帮助用户完成项目。最初,Pinterest 采用多阶段流水线通过聚类关键词并附加属性来推断旅程。该遗留系统提升了参与度指标,但存在碎片化、通用分桶以及来自无关点击的偶然噪声等问题。为解决这些问题,Pinterest 将旅程推断重构为生成任务,使用经过微调的 40 亿参数大语言模型(LLM)。该 LLM 直接读取用户的按时间顺序排列的活动日志,并以用户所在地区的语言输出排序后的旅程名称列表。该 LLM 的提示工程至关重要,它定义了操作重要性、事件分组,并处理诸如“不喜欢”等负向信号。前沿模型被用作教师,为微调更小、可投入生产的“学生”模型生成合成训练数据。选择 40 亿参数模型,是因为其在输出质量与服务效率之间取得了良好平衡。在大规模部署这些模型时,采用了诸如 PagedAttention 和连续批处理等复杂优化技术,以高效服务数亿用户。新的生成式系统成功整合了碎片化的旅程,提供了具体的名称,并重新引入了丢失的意图。这种方法为个性化提供了一套通用方案,不仅适用于 Pinterest,也适用于具有顺序用户活动和结构化意图目标的其他平台。
CdXz5zHNQW_wEiKzVPwD3.png
Pinterest 在所有决策制定中均依赖可信指标,涵盖业务表现到功能实验。数百名数据生产者从海量数据湖中生成数千个指标。为管理这一复杂性,Pinterest 构建了 Metrics Board,一个端到端平台。该平台自动化指标创建、强制执行质量规范,并支持由智能体驱动的统计分析。指标对于理解用户与广告商价值、推动产品决策及预测公司战略至关重要。同时,指标也支撑 Pinterest 的大规模产品实验实践,确保结果公平且具有统计显著性。此前,指标定义于定制的数据管道中,导致效率低下与信任流失。Metrics Board 旨在统一指标、提供透明定义、自动化管道创建,并确保指标验证与监控。其目标是使指标对所有用户、应用程序及不断演进的 AI 智能体而言易于使用。Metrics Board 充当语义层,其定义在 Git 仓库中管理,如同生产代码。系统生成 YAML 规范并发起拉取请求,与更广泛的数据栈集成。Metrics Board 通过调度 Airflow DAG 编排指标计算,将每个指标隔离以实现更优控制。它将 SQL 编译为 SparkSQL 或 PrestoSQL,并自动生成依赖任务与数据质量检查。回填操作由 Airflow 管理,平台还处理自动化运维任务,如检测上游数据延迟。此举将指标创建时间从数天或数周缩短至数小时。指标质量至关重要,每个定义均包含验证规则。这些验证采用基于规则的检查以明确预期,并结合基于机器学习的异常检测。当检查失败时,警报会实时通知相关人员;质量报告可通过 API 获取并导出为 PDF。发布机制确保指标能够到达用户实际使用的产品中,集成支持 PinCat、Helium、Superset 和 StarRocks。元数据集成在提交时发布,而数据集成则在计算完成后发布。Metrics Board 通过集中定义与元数据促进发现与治理,提升可发现性。指标自动流入 PinCat 数据目录。认证等级体系从“未知”到"A+",帮助使用者识别可信指标。仪表板也被划分为不同层级,影响留存率、查询性能及关键公司级仪表板所需的文档要求。一级仪表板代表最关键的一组,享有强保障并需经过正式认证。
CdXz5zHNQW_G7lgncluYP.png
CdXz5zHNQW_u1wkB0MUto.png
Pinterest 开发了一种名为 Nexus 的新型轻量级排序模型,该模型超越了传统的双塔架构。Nexus 模型联合预测点击率(pCTR)、优质点击率(pGCTR30)和外链点击率(pOCTR)。为高效支持这些预测,针对每个任务对嵌入向量进行分段处理。Nexus 系统支持更复杂的模型架构,如交叉注意力机制和序列建模。然而,每次请求需对数十万候选项进行打分,带来了显著的延迟与成本挑战。为此,设计了一种三塔协同训练模型,将快速的双塔预测与更丰富的三塔预测相结合。该架构保留了原有的查询塔(query tower)和 Pin 塔,以实现高效的缓存与点积预测。同时引入第三个交叉塔(cross tower),利用用户序列与候选特征之间的注意力机制,并通过交互模块(inter module)融合这些嵌入向量。模型采用协同训练方式,既能为所有候选项生成快速分数,又能为子集生成更准确的分数。该方法通过将计算资源分配至影响最大的位置,实现了性能与延迟的平衡:交叉塔捕捉高阶交互,交互模块则为所有任务生成共享表示。训练过程采用多任务损失函数,对主要的三塔损失赋予更高权重,而辅助的双塔协同训练损失权重较低。这确保了三塔预测成为主要优化目标,同时保持快速双塔预测的质量。实施了一系列显著的推理优化以控制计算成本,包括在 Pin 塔中对 Pin 特征进行预处理以避免每次请求的计算开销,以及采用 BF16 低精度推理。这些优化大幅降低了 P99 模型推理时间,使得三塔方法在大规模场景下具备可行性。综合改进带来了显著的离线损失下降,并推动了线上业务指标的积极提升。
CdXz5zHNQW_1jHfrOQVr3.png
CdXz5zHNQW_ydHVPNTidy.png
Pinterest 的主页信息流旨在通过改进推荐系统,为用户检索相关的 Pins。最初采用双塔模型,分别对用户和物品进行编码,但难以应对用户的多重兴趣。为此,提出了条件化学习检索(Conditional Learned Retrieval, CLR),通过显式检索上下文对用户嵌入进行条件化以解决该问题。 prior 工作已探索将 CLR 用于通知的引导式训练,并将其集成到主页信息流的多嵌入框架中。本文详细介绍了 CLR 如何演变为 Pinterest 主页信息流的更广泛检索系统。CLR 通过引入兴趣(Interests)、Pins 和 Boards 等新条件类型,扩展以支持多样化的检索候选项。兴趣条件最初从用户信号中引导式训练,随后利用大语言模型(LLM)生成的兴趣进行增强。Pin 条件通过对已互动的 Pins 进行聚类,并使用嵌入表示,使 CLR 能够替代遗留的生成器。Board 条件则通过在 Pin-Board 图上执行随机游走构建,并使用嵌入表示 Boards。模型基础通过序列建模和增强的条件表示进行了扩展。引入了条件化用户序列 Transformer(Conditioned User Sequence Transformer),使 CLR 具备序列感知能力,通过同时编码用户行为和条件 token 来实现。该架构进一步演化为基于基础模型(Foundation Model)的 CLR 架构,整合了在大规模全局用户序列上训练的大型 Transformer。该基础模型对用户塔和物品塔共享 Pin 嵌入,并采用对比对齐损失(contrastive alignment loss)。条件表示被统一,以便在单个模型内处理异构条件,减少重复工作。统一 CLR 将不同条件类型整合到一个模型中,支持多种条件输入并补全缺失特征。路由简化涉及将路由逻辑重构为与条件无关的槽位架构(Slot Architecture),为不同类型的嵌入预定义槽位。CLR 的训练效率通过无损的基础设施优化得到提升,训练吞吐量翻倍。请求级训练(request-level training)在批次内去重相同的用户特征,进一步优化工作正在进行中。该系统现已能在生产规模下高效处理多条件检索,通过提供更多样且相关的内容提升用户参与度。
CdXz5zHNQW_6wtn6E8XMD.png
Pinterest 旨在通过其推荐系统帮助用户发现通往更美好生活的灵感。主页信息流作为关键发现平台,采用多阶段管道进行推荐。此前,优化工作侧重于点击和收藏等参与度指标。然而,参与度与留存率截然不同,仅优化参与度可能导致用户流失。本文介绍了"Pinner Progression"计划,该计划通过理解用户不断演变的需求,将用户留存置于优先地位。其核心理念是将顺序用户理解与持久用例表示相结合。这种方法有助于预判用户行为,并提供能够促进意外发现的推荐。引入的关键信号是用户兴趣簇(User Interest Clusters, UICs),它们代表了用户参与的各类不同用例。可持续增长依赖于建立用户与特定用例之间的长期关系,而不仅仅是短期参与度。分析表明,用例的采用与持续参与度和留存率呈正相关。现代推荐系统擅长理解用户当前的偏好,但在建模这些偏好的生命周期方面存在困难。区分用户处于活跃的“公寓装饰”阶段还是衰退的“酸面团”阶段,对于长期留存至关重要。UIC 表示建立在 PinnerSage 和 OmniSage 等过往工作基础之上,其创新之处在于仅针对已参与的内容进行个性化聚类,从而允许每个用户拥有动态数量的簇。关键的是,每个 UIC 均包含有状态的生命周期元数据,提供时序和行为洞察。这些元数据有助于推断用户兴趣的成熟度,区分转瞬即逝的好奇心与新兴的习惯。UIC 由 OmniSage 嵌入空间中的中心点(medoids)和地标图钉(landmark Pins)定义,其中接近度表示功能效用。信号构建涉及对用户近期参与嵌入进行层次聚类。完全连接算法基于其最不相似对的相似度合并簇,并设定相似度阈值。该过程在剩余任何一对的相似度未超过阈值或达到最大簇数量时停止。系统级集成涉及将 UIC 作为推荐管道检索、排序和混合阶段的共享抽象。这使得系统不同组件能够推理用户兴趣的成熟度。UIC 被外部化到共享特征存储中以提升效率,减少了多次信号获取带来的延迟。未来工作包括扩展 UIC,加入能够保留时序动态的长序列表示。检索是首个集成点,在此阶段,条件学习检索(Conditional Learned Retrieval)利用用户信息和条件生成候选项,以确保语义相关性。
CdXz5zHNQW_3eUbsaOfmV.png
在 Pinterest 这样的大型分布式组织中管理基础设施即代码(IaC)面临着显著的安全与后勤挑战。为此,Pinterest 开发了资源供应管道(Resource Provisioner Pipeline, RPP),一种专有的 Terraform 执行引擎。RPP 能够在多仓库架构下安全地管理关键与非关键的基础设施变更。该系统通过双重控制、集中化的 GitHub Actions 以及安全的角色链式调用,为全球 AWS 运营提供合规性与强健的安全保障。RPP 管理着数百个 Terraform 工作区,管控着数万个 AWS 资源,涵盖安全策略、网络及计算资源。RPP 的 GitHub 工作流采用集中执行模型,由拉取请求(PR)事件触发。该流程使用组合式 GitHub Actions,并通过为每个工作区独立执行计划来隔离工作区的影响。双重控制增加了必要的人工审查层,需经代码审查员批准。为贯彻最小权限原则,RPP 实施了严格的工作区 - 路径 - 角色映射,利用安全的角色链式调用。流程始于通过 GitHub OIDC 认证并假设集中化的 RPPActionsRole,随后确定工作区属性,将其映射到允许的仓库、路径及执行角色。关键的后端验证确保代码路径严格引用指定工作区对应的 S3 状态后端及 KMS 密钥。若验证通过,RPPActionsRole 将假设一个作用域受限的团队 IAM 角色,从而确保权限最小化。部署流程包括代码检查、在 PR 上输出计划结果,以及通过特定评论触发的审慎应用。该方法带来的优势包括统一审计、即时系统性补丁以及集中化的资源指标。
CdXz5zHNQW_ggFzV94AMK.png
Pinterest 为其基于 Kafka 的 CDC 摄入平台开发了一套稳健、自动化的模式演进框架。模式变更是跨系统的关键契约,若缺乏管控的演进可能导致管道故障和数据不一致。其解决方案旨在通过将其视为多阶段收敛过程,使模式演进具备安全性、可重复性和可扩展性。该架构涉及 CDC 源、Kafka、用于转换的 Flink 以及用于向 Iceberg 表执行 upsert 操作的 Spark。核心组件是一个可靠的接入模型,该模型以包含稳定数字标识符的模式定义文件作为单一事实来源。更新通过基于 PR 的发布流程(包含版本控制和审计)自动传播至 Kafka、Flink、Spark 和 Iceberg。该系统主要支持增量式模式变更,以维持向后兼容性并最小化复杂性。类型变更严格限制为保留语义含义的变更,例如数值精度扩展。模式演进通过三阶段收敛模型进行管理,以维持管道可用性。第一阶段更新 Iceberg 模式,第二阶段部署更新后的 Flink 和 Spark 代码,第三阶段确保数据收敛。这种分阶段方法将模式传播与数据正确性解耦,允许在定义的 SLA 范围内存在临时差异。Pinterest 采用基于 SLA 的模式演进模型,优先保证可预测性和运营安全性。部署策略经过精心管理,尤其是针对 Flink,以防止数据丢失。对于不支持或存在歧义的情况(如默认值或主键变更),设有特定的手动恢复路径。针对 CREATE TABLE 差异的歧义问题,通过对比数据库的实际 DDL 历史记录来解决,而非从文本变更中推断意图。并发模式变更按顺序处理,以防止竞态条件,确保串行收敛。列转换通过为模式添加所需转换注解进行管理,这些注解随后被注入摄入管道。错误处理与恢复机制(特别是针对 Spark 故障)确保处理能够从最后一个成功的水印处恢复。
CdXz5zHNQW_srAU1TSiiq.png
Pinterest 的在线机器学习(ML)服务系统采用根 - 叶架构,客户端服务通过该架构请求 Pin 的预测分数。根组件负责特征检索与预处理,而叶节点执行模型推理,通常利用 GPU。该设计简化了新模型的接入流程,并通过分离 CPU 与 GPU 工作负载优化资源利用率。然而,由于传递大量特征,根与叶分区之间出现了网络瓶颈。最初,系统实施了 lz4 压缩以减少网络用量,虽显著节省了带宽,但导致 CPU 使用率和延迟略有上升。这虽是一个良好的开端,但核心问题——传输不必要的特征——依然存在。随后,团队开发了“按需发送”(Send What You Use)方案,仅发送特定模型所需的特征,以解决这一问题。模型签名(model signature)定义了模型的输入与输出,是特征需求的权威来源。模型在训练并导出时,其签名会一同保存。Leaf 节点加载这些签名,构建特征转换器,仅处理必要特征。为同步根与叶之间的特征需求,模型签名被发布为轻量级工件(artifacts)。这些签名被聚合为包级映射(bundle-level mappings),随后与现有配置一同部署至根节点。该部署流程遵循与模型发布相同的分阶段交付机制,确保一致性并支持优雅回滚。此集成使得 Feature Trimmer 能够动态更新根节点上的特征白名单,确保仅传输必要特征。系统通过版本化查找和降级机制,处理频繁模型更新与渐进式发布,确保根节点对所需特征的视图与实际部署在叶节点上的模型保持同步。通过剪枝不必要的特征,Pinterest 显著降低了网络流量并提升了基础设施效率。
CdXz5zHNQW_Pr67hugpQp.png
CdXz5zHNQW_iZkUUBsGZ2.png
Pinterest 利用内容理解来驱动内容分发与用户互动,这需要深入理解图像和出站链接。核心问题在于 URL 规范化:由于跟踪参数的存在,相同的产品页面可能以多种不同的 URL 形式出现。这种冗余会导致重复抓取和处理,从而浪费计算资源。项目规范化旨在将不同 URL 所代表的相同项目统一起来,这对于购物目录至关重要。当项目 ID 缺失时,高级 URL 规范化对于去重尤为关键。最小重要查询参数集(MIQPS)算法能够自动学习哪些 URL 参数会影响内容身份。该算法能够区分中性参数(不影响页面内容)和非中性参数(会影响页面内容)。虽然静态规则适用于知名平台,但 Pinterest 拥有庞大的域名集合,因此需要一种动态的、数据驱动的方法。MIQPS 算法分为三个步骤。首先,从 Pinterest 的摄入管道中收集每个域名的观测 URL 语料库。其次,根据查询参数模式对 URL 进行分组,确保参数在其特定上下文中进行分析,避免因 URL 类型不同而错误分类参数。最后,对于模式中的每个参数,算法通过实证测试其重要性。它会采样具有不同参数值的 URL,并计算原始 URL 和修改后(移除该参数)URL 的内容 ID。如果在一定比例的样本中,移除该参数会导致内容 ID 发生显著变化,则该参数被归类为非中性参数并予以保留;否则,该参数被视为中性参数,可在规范化过程中安全移除。每个商家域名都会获得专属的 MIQPS 映射表,以反映该域名下参数的特定含义。
CdXz5zHNQW_WVip85jMBw.png
Pinterest 搜索是用户可以发现与他们的信息需求相符的启发性内容的关键入口,搜索相关性衡量搜索结果与搜索查询的匹配程度。为了改进搜索相关性模型,我们使用一个 5 级准则来衡量查询和 Pins 之间的相关性。我们使用交叉编码器语言模型来预测 Pin 与查询的相关性,同时结合 Pin 文本,并将任务表述为多类别分类问题。该模型使用人工标注的数据进行微调,最小化交叉熵损失。为了表示每个 Pin,我们使用了一系列不同的文本特征,包括 Pin 的标题和描述、合成的图像标题、高参与度的查询词、用户策划的板块标题以及链接标题和描述。然而,基于交叉编码器 LLM 的分类器由于实时延迟和成本的考虑,难以在 Pinterest 搜索中进行扩展。因此,我们使用知识蒸馏将基于 LLM 的教师模型蒸馏成一个轻量级的学生相关性模型。学生模型使用查询级特征、Pin 级特征和查询-Pin 交互特征来预测 5 级相关性分数。我们采用知识蒸馏和半监督学习来训练学生模型,这有效地利用了大量最初未标记的数据,并将数据扩展到世界范围内的多种语言。离线实验证明了每个建模决策的有效性,包括语言模型的比较、丰富文本特征的重要性以及通过蒸馏扩大训练标签规模。在线结果显示,搜索 feed 相关性提高了 +2.18%(通过 nDCG@20 衡量),并且在全球范围内搜索完成率显着提高。所提出的相关性建模流程有效地推广到训练期间未遇到的语言,而基于多语言 LLM 的相关性教师模型则推广到未见的语言。未来的工作将探索整合可服务的 LLM、视觉与语言多模态模型以及主动学习策略,以动态扩展和提高训练数据的质量。
CdXz5zHNQW_lGLj8VappE.png