2021 年 2 月 15 日 — Larry Price 的客座文章,OpenX由 Robert Crowe 和 Anusha Ramesh 编辑 - TensorFlow 概述 广告技术是一个建立在规模化延迟基础上的行业。在 OpenX,这意味着在高峰流量期间,我们的交易所每秒处理 **超过一百万个广告请求**,其中大多数需要在 300 毫秒内做出响应。在如此高容量和严格的时间预算下,优先处理流量至关重要,以确保我们同时帮助发布商从其库存中获得最高收益,并确保买方实现其广告系列目标。
Larry Price 的客座文章,OpenX
由 Robert Crowe 和 Anusha Ramesh 编辑 - TensorFlow
广告技术是一个建立在规模化延迟基础上的行业。在 OpenX,这意味着在高峰流量期间,我们的交易所每秒处理 **超过一百万个广告请求**,其中大多数需要在 300 毫秒内做出响应。在如此高容量和严格的时间预算下,优先处理流量至关重要,以确保我们同时帮助发布商从其库存中获得最高收益,并确保买方实现其广告系列目标。
为了实现这一点,我们利用了 TensorFlow 生态系统和 Google Cloud 中的多个产品,包括 TensorFlow Extended (TFX)、TF Serving 和 Kubeflow Pipelines - 来构建一项服务,该服务将流量优先分配给我们的买方(需求方平台,或广告技术术语中的 DSP),更具体地说,是分配给那些 DSP 中的品牌和代理商。
OpenX 运营着全球最大的独立广告交易所。从基本层面上讲,交易所是一个市场,它将数万个顶级品牌连接到访问量最大的网站和移动应用程序上的消费者。
交易的基本方式是拍卖,其中代表品牌的买方竞标发布商的库存,这些库存是网站和移动应用程序上的广告展示。拍卖本身相当简单,但有两个事实使该系统异常复杂
这种对低延迟的需求以及高吞吐量要求对于机器学习系统来说相当不寻常。在我们深入了解如何构建能够处理这两个要求的机器学习基础设施的细节之前,我们将更深入地研究我们是如何走到这一步的以及我们试图解决什么问题。
在 2019 年,OpenX 承担了一项雄心勃勃的任务,即 从本地计算资源迁移到 Google Cloud Platform (GCP)。我们在七个月内完成了这一过程。作为一家公司,我们被授权利用托管服务并在过渡过程中修改我们的堆栈,因此它不仅仅是一个简单的“提升和迁移”。我们真的在数据科学团队中践行了这一点。
在迁移到 GCP 之前,我们的传统机器学习基础设施遵循一种模式,即科学家训练的模型必须由工程师在需要执行模型的组件中重新实现。这种情况满足了规模和延迟要求,但带来了一系列其他问题
由于这些以及其他几个原因,我们决定从头开始。同时,我们正在研究一个新问题,并决定将这两项工作结合起来,作为新项目的一部分开发一个新的框架。
OpenX 市场与股票市场或证券交易所并不完全不同。与高容量的金融市场一样,为了确保买方实现其广告系列目标并同时帮助发布商适当地将库存货币化,需要优先处理流量。从根本上讲,这意味着我们需要一个模型,能够准确评估并因此对到达交易所的每个请求进行排名。
当我们为下一代平台寻找解决方案时,我们心中有几个目标。我们主要希望大幅减少将模型投入生产的时间和精力,并且在实现这一目标的过程中,尽可能使用托管服务。TensorFlow 已经在 OpenX 中使用了一段时间,早于我们迁移到 GCP,但我们的传统基础设施涉及许多用于数据转换和管道化的自定义脚本。在我们研究选择方案的同时,TensorFlow Extended (TFX) 和 Kubeflow Pipelines (KFP) 都达到了成熟度,使它们对我们的目的很有吸引力。将这些技术采用到我们的堆栈中是理所当然的。
我们的管道看起来像这样。
花一些时间分解管道拓扑结构很有用
总的来说,开箱即用的 TFX 组件提供了我们所需的大部分功能。我们必须解决的最大需求是,我们的市场不断变化,这需要频繁更新模型。如前所述,TFX 的设计使这些增强易于实现。
但是,这实际上只解决了我们问题的模型训练部分。每秒处理一百万次查询,每次都在 15 毫秒内完成,是一个重大挑战。为此,我们求助于 TensorFlow Serving。
TensorFlow Serving 使我们能够快速提取我们的 TensorFlow 模型并在生产中以高性能和可扩展的方式提供服务。使用 TensorFlow Serving 为我们带来了许多好处。首先,因为它原生支持 Google Cloud Storage 作为模型仓库,我们只需上传到 GCS 存储桶即可自动更新我们在服务中使用的模型。这使我们能够快速刷新使用最新数据的模型,并立即在生产中提供服务。其次,TensorFlow Serving 支持批处理模式,该模式通过将多个请求排队并在单个图运行中同时处理它们来大幅提高吞吐量。这是一个基本功能,它通过设置单个选项极大地帮助我们实现了吞吐量目标。最后,TensorFlow Serving 开箱即用地提供指标,使我们能够监控请求的吞吐量和延迟,并观察任何扩展瓶颈和低效率。
TensorFlow Serving 中的所有这些开箱即用的功能对我们来说都是巨大的胜利,并帮助我们实现了目标,但将其扩展到每秒处理数百万个请求并非没有挑战。通过使用具有大量 CPU 的大型虚拟机,我们能够达到 15 毫秒预测的目标,但它的成本效益并不高,我们知道我们可以做得更好。幸运的是,TensorFlow Serving 有一些旋钮和参数,我们可以使用它们来调整我们的生产 VM 以提高效率和可扩展性。通过设置批处理线程数、跨操作和操作内并行度以及批处理超时等内容,我们能够在自定义大小的 VM 上高效地自动扩展,同时仍然保持我们的吞吐量和延迟目标。
最终结果是在 Google Kubernetes Engine 上运行的 TensorFlow Serving 部署,每秒处理 250 万个预测请求,每个请求在 15 毫秒内完成。该部署跨越了 10 个不同 GCP 区域的 25 个以上 Kubernetes 集群,并且能够无缝扩展以应对流量高峰,并在流量较低时缩减规模以节省成本。在高峰时段,全球约有 500 个 TensorFlow Serving 实例运行,每个 8 核部署能够处理每秒 5000 个请求。
自从实施以来,我们已经对模型进行了数十项改进,从改变原始模型的架构到改变处理某些特征的方式,所有这些都无需任何其他工程团队的支持。在我们的旧架构中,这种速度的变更几乎是不可能的。此外,这些改进为我们的客户(我们的市场中的买家和卖家)带来了新的价值,速度比以往更快。
自从我们最初实施此参考架构以来,我们已将其用作新项目的模板以及现有模型的迁移模板。令人惊奇的是,我们现有的许多 TFX 组件可以移植到新项目中,更重要的是,我们大幅缩短了将模型投入生产所需的时间。因此,数据科学家能够将更多时间花在优化模型参数和架构、了解模型对业务的影响以及最终为客户创造更多价值上。
如果没有 Michal Brys、Andy Gooden、Junbo Park 和 Paul Selden 的辛勤工作,以及 OpenX 数据科学与工程团队的其余成员以及 Paul Ryan 的支持,这一切都是不可能的。我们也感谢战略云工程师 Will Beebe 和 Leonid Kuligin 以及来自 GCP 账户管理团队的 Dillon Do、Iman Kafarah 和 Kyle Winn 的支持。衷心感谢 TensorFlow (TFX、TF Serving) 和 Kubeflow 团队,特别是 Robert Crowe 和 Anusha Ramesh 为帮助完成本案例研究。