https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidbEBk9pS52B1udvkMva4Yoj8t6WbMi1i-jVXLvSrAyYnJrlfe32UkDU93HTj2cZyirOaWLGwa_yr12OYwlTfl_Ga9iXKMAejnHmDH-tFQgdLVRzXHuUe18u99PlVURR217QgxpHJFOVc/s1600/1.png
发布者 Robert Crowe、Konstantinos (Gus) Katsiapis 和 Kevin Haas,代表 TFX 团队
当您想到机器学习时,通常只会想到现在可以创建的优秀模型。毕竟,许多研究论文都关注这一点。但是,当您想将这些惊人的模型提供给全世界时,您需要考虑生产解决方案需要的所有内容 - 监控、可靠性、验证等。这就是 Google 创建 TensorFlow Extended (
TFX) 的原因 - 为我们的机器学习 (ML) 管道提供生产级支持。我们与开源社区分享这一点,以便世界各地的开发人员可以在生产级 TFX 管道上创建和部署他们的模型。
Google 创建 TFX 是因为我们需要它,而且没有现成的产品可以满足我们的需求。Google,更一般地说,Alphabet 在我们的大多数产品中广泛使用 ML。实际上,TFX 不是 Google 创建的第一个 ML 管道框架。它从
早期尝试 中演变而来,现在是 Google 大多数 ML 生产解决方案的默认框架。除了 Google 之外,TFX 也对我们的合作伙伴产生了深远的影响,包括 Twitter、Airbnb 和 PayPal。
不仅仅是 ML
当您开始计划将 ML 整合到应用程序中时,您需要考虑所有正常的 ML 事项。这包括获取标记数据(如果您正在进行监督学习),并确保您的数据集很好地涵盖了可能的输入空间。您还需要最小化特征集的维度,同时最大化它包含的预测信息。您还需要考虑公平性,并确保您的应用程序不会
存在不公平的偏见。您还需要考虑罕见情况,特别是在医疗保健等应用中,您可能要对仅在罕见但重要情况下发生的状况进行预测。最后,您需要考虑这是一个会随着时间的推移而发展的动态解决方案,因为新数据会不断流入并且条件会发生变化,并且需要规划数据的生命周期管理。
但除了所有这些之外,您还需要记住,您正在将软件应用程序投入生产。这意味着您仍然拥有任何生产软件应用程序的全部要求,包括可扩展性、一致性、模块化和可测试性,以及安全性和安全性。您远远超出了仅仅训练模型的范围!本身,这些对任何生产软件部署来说都是挑战,您不能因为正在进行 ML 就忘记它们。您将如何满足所有这些需求,并将您惊人的新模型投入生产?
这就是 TFX 的全部意义所在。TFX 允许您创建生产 ML 管道,其中包含生产软件部署的许多要求和最佳实践。它从摄取您的数据开始,并流经数据验证、特征工程、训练、评估和服务。除了
TensorFlow 本身之外,Google 还为 ML 管道的每个主要阶段创建了库 -
TensorFlow 数据验证、
TensorFlow 变换 和
TensorFlow 模型分析。Google 还为各种部署目标创建了框架,包括服务器场 (
TensorFlow Serving)、原生移动应用程序 (
TensorFlow Lite) 和 JavaScript 应用程序 (
TensorFlow JS)。TFX 实施了一系列管道组件,这些组件利用了库,并且允许您创建自己的组件。
为了将所有这些结合在一起,Google 为诸如管道存储、配置和编排之类的方面创建了一些横向层。这些层对于管理和优化您的管道以及在它们上运行的应用程序非常重要。
生产环境中的 ML 存在许多挑战,Google 并不假装拥有所有答案。这是 ML 社区中的一个不断发展的领域,我们欢迎您的贡献。
这篇论文 概述了生产环境中机器学习的挑战。
什么是“管道”和“组件”?
TFX 管道被创建为一系列组件,每个组件执行不同的任务。组件被组织成有向无环图,或“DAG”。但是组件到底是什么?
TFX 组件包含三个主要部分:驱动程序、执行器和发布器。其中两个部分 - 驱动程序和发布器 - 主要是一些您
可以更改的样板代码,但可能永远不需要更改。执行器实际上是您插入代码和进行自定义的地方。
驱动程序检查世界状态并决定需要执行哪些工作,协调作业执行并将元数据提供给执行器。发布器获取执行器的结果并更新元数据存储。但执行器实际上是在每个组件中完成工作的场所。
因此,首先,您需要一个组件的配置,使用 TFX,此配置使用 Python 完成。接下来,您需要一些组件的输入,以及一个用于发送结果的地方。这就是元数据存储的用武之地。我们将在稍后详细介绍元数据存储,但现在您只需要知道,对于大多数组件而言,输入元数据将来自元数据存储,而生成的元数据将被写回元数据存储。
因此,当您的数据通过管道移动时,组件将读取由早期组件生成的元数据,并写入可能由管道中更后面的组件使用的元数据。有一些例外,例如管道开始和结束时,但大多数情况下,数据的流动方式就是这样。
编排 TFX 管道
为了组织所有这些组件并管理这些管道,您需要编排。但是编排到底是什么,它如何帮助您?
为了将 ML 管道整合在一起,定义构成管道的组件序列,并管理它们的执行,您需要一个编排器。编排器提供了一个管理接口,您可以使用它来触发任务并监控我们的组件。
如果您只需要启动管道的下一阶段,那么任务感知架构就足够了。您只需在先前组件完成时启动下一个组件。但是,任务和数据感知架构要强大得多,对于任何生产系统来说几乎都是必需的,因为它存储了来自每个组件在多次执行期间的所有工件。拥有这些元数据会创建一个更强大的管道,并启用许多在没有它的情况下很难实现的功能,因此 TFX 实施了任务和数据感知管道架构。
TFX 可扩展且开放的方式之一是使用编排。Google 提供了对
Apache Airflow 和
Kubeflow 的开箱即用支持,但您也可以编写代码以使用不同的编排器(如果需要)。如果您已经拥有自己喜欢的流程引擎,则可以构建一个运行器以将其与 TFX 一起使用。
为什么要存储元数据?
TFX 使用
ML-Metadata (MLMD) 实施元数据存储,MLMD 是一个开源库,用于定义、存储和查询 ML 管道的元数据。MLMD 将元数据存储在关系型后端中。当前的实现开箱即用地支持 SQLite 和 MySQL,但您可以编写代码来扩展 ML-Metadata 以用于基本上任何与 SQL 兼容的数据库。但是您到底在元数据存储中存储了什么?
首先,我们存储有关您训练的模型、用于训练它们的训练数据及其评估结果的信息。我们将这种类型的元数据称为“工件”,工件具有属性。数据本身存储在数据库外部,但属性和数据的位置保存在元数据存储中。
接下来,我们保留每个组件的执行记录,每次运行时都会记录。请记住,ML 管道通常在很长一段时间内经常运行,因为新数据会不断流入或条件会发生变化,因此保留这些历史记录对于调试、可重复性和审计变得很重要。
最后,我们还包括数据对象在管道中流动时的血统或来源。这使您能够在管道中向前和向后跟踪,以了解运行我们的组件时数据和代码变化的来源和结果。当您需要优化或调试我们的管道时,这一点非常重要,如果没有它,这将非常困难。
元数据驱动的功能
现在您对元数据存储中包含的内容有了一些了解,让我们来看看从元数据存储中获得的一些功能。
首先,拥有所有数据工件的血统或来源使您能够在管道中向前和向后跟踪 - 例如,查看我们的模型是用什么数据训练的,或者一些新的特征工程对您的评估指标有什么影响。在某些用例中,这种跟踪数据来源和结果的能力甚至可能是监管或法律要求。
请记住,这不仅仅是针对今天的模型或今天的结果。您可能还希望了解您的数据和结果随着时间的推移如何变化,因为您会吸收新数据并重新训练您的模型。您通常希望与昨天或上周运行的模型运行进行比较,以了解为什么您的结果变得更好或更差。生产解决方案不是一次性的事情,它们会持续存在,只要您需要它们,这可能需要几个月甚至几年。
您还可以通过仅在必要时重新运行组件并使用热启动继续训练来提高管道的效率。请记住,您通常处理大型数据集,这些数据集可能需要数小时甚至数天才能运行。如果您已经训练了模型一天,并且想要进一步训练,则可以
从中断的地方开始,而不是从头开始。如果您已将有关我们的模型的信息保存在元数据中,这将更容易。
您还可以通过仅在输入或代码发生更改时重新运行它们来使管道中的其他组件更加高效。 您无需再次运行该组件,而只需从缓存中提取先前的结果即可。 例如,如果管道的新运行仅更改了训练器的参数,那么管道可以重用任何数据预处理工件,例如词汇表——这可以节省大量时间,因为大量数据会使数据预处理变得很昂贵。 借助 TFX 和 MLMD,这种重用是开箱即用的,同时您会看到一个更简单的“运行管道”界面,并且无需担心手动选择要运行的组件。 同样,这可以为您节省数小时的处理时间。 如果您已将组件的输入和结果保存在元数据中,那将容易得多。
组件? 什么类型的组件?
既然您有了编排器,让我们谈谈 TFX 附带的标准组件。
但首先,让我们谈谈 Apache Beam
在谈论标准组件之前,让我们先谈谈
Apache Beam。 为了处理大量数据的分布式处理,尤其是像 ML 工作负载这样的计算密集型数据,您确实需要一个分布式处理管道框架,例如
Apache Spark,或
Apache Flink,或
Google Cloud Dataflow。 大多数 TFX 组件都运行在 Apache Beam 之上,Apache Beam 是一种统一的编程模型,可以在多个执行引擎上运行。 Beam 允许您使用已有的分布式处理框架,或选择您喜欢的框架,而不是强迫您使用我们选择的框架。 目前,Beam Python 可以运行在 Flink、Spark 和 Dataflow 运行器上,但正在添加新的运行器。 它还包括一个直接运行器,使您能够在本地系统(如笔记本电脑)上运行开发中的 TFX 管道。
标准组件
TFX 在您首次安装时包含一组相当完整的标准组件,每个组件都设计用于生产 ML 管道中的不同部分。 例如,
Transform 组件使用 Apache Beam 来执行特征工程转换,例如创建词汇表或进行主成分分析 (PCA)。 这些转换可以在您的 Flink 或 Spark 集群上运行,也可以在 Google Cloud 上使用 Dataflow 运行。 由于 Apache Beam 的可移植性,您可以在它们之间迁移而无需更改代码。
实际上,
Trainer 组件只是使用 TensorFlow。 还记得您一直在思考如何训练您的出色模型吗? 这就是您在此处使用的代码。 请注意,目前 TFX 仅支持
tf.estimators。 有关兼容性的其他信息,请
点击此处查看。 一些组件非常简单。 例如,
Pusher 组件只需要 Python 就能完成任务。
当您将所有这些组件组合在一起并使用编排器管理它们时,您就拥有了一个 TFX 管道。 在一端,您要摄取数据,而在另一端,您要将 SavedModels 推送到一个或多个部署目标。 这包括模型存储库,例如
TensorFlow Hub,或使用
TensorFlow JS 的 JavaScript 环境,或使用
TensorFlow Lite 的原生移动应用程序,或使用
TensorFlow Serving 的服务器场,或以上所有内容。
现在,让我们更详细地了解这些组件。
读取数据
首先,您使用
ExampleGen 摄取输入数据。 ExampleGen 是在 Beam 上运行的组件之一。 它从各种受支持的来源和类型中读取数据,将其拆分为训练和评估,并将其格式化为
tf.examples。 ExampleGen 的配置非常简单,只有两行 Python 代码。
接下来,
StatisticsGen 使用 Beam 对数据进行完整的遍历,一个完整的时期,并计算每个特征的描述性统计信息。 为此,它利用了
TensorFlow Data Validation (TFDV) 库,该库包含对您可以在 Jupyter 笔记本中运行的一些可视化工具的支持。 这使您可以探索和理解数据,并查找可能存在的问题。 这是典型的 数据整理工作,是我们所有人准备数据以训练模型时所做的事情。
下一个组件,
SchemaGen,也使用 TensorFlow Data Validation 库。 它查看由 StatisticsGen 生成的统计信息并尝试推断特征的基本属性,包括特征值的 数据类型、值范围和类别。 您应该检查并根据需要调整架构,例如添加您希望看到的 新类别。
下一个组件,
ExampleValidator,获取来自 StatisticsGen 的统计信息和架构(可能是 SchemaGen 的输出或用户整理的结果)并查找问题。 它查找不同类型的异常,包括缺失值或与架构不匹配的值、训练-服务偏差和数据漂移,并生成发现结果的报告。 请记住,您始终在接收 新数据,因此您需要在出现问题时意识到这些问题。
特征工程
Transform 是更复杂的组件之一,需要更多配置以及额外的代码。 Transform 使用 Beam 来进行特征工程,将转换应用于特征以提高模型的性能。 例如,Transform 可以创建词汇表,或将值分桶,或对输入运行 PCA。 您编写的代码取决于模型和数据集需要执行的特征工程。
Transform 将对数据进行完整的遍历,一个完整的时期,并创建两种不同类型的结果。 对于像计算特征的中位数或标准差这样的东西(所有示例的值都相同),Transform 将输出一个常数。 对于像归一化值这样的东西(不同示例的值将不同),Transform 将输出 TensorFlow Ops。
然后,Transform 将输出一个包含这些常数和运算的 TensorFlow 图。 该图是封闭的,因此它包含应用这些转换所需的所有信息,并将构成模型的输入阶段。 这意味着相同的转换在训练和服务之间始终如一地应用,从而消除了训练/服务偏差。 如果您要将模型从训练环境迁移到服务环境或应用程序,并尝试在这两个地方应用相同的特征工程,您希望转换相同,但有时您会发现它们并不相同。 我们称之为训练/服务偏差,Transform 通过在运行模型的任何地方使用完全相同的代码来消除它。
训练您的模型
现在您终于准备好训练模型了,这通常是您在想到机器学习时想到的流程的一部分。
Trainer 获取来自 Transform 的转换图和数据,以及来自 SchemaGen 的架构,并使用您的建模代码训练模型。 这是正常的模型训练,但训练完成后,Trainer 将保存两种不同的
SavedModels。 一个是将部署到生产环境的 SavedModel,另一个是用于分析模型性能的 EvalSavedModel。
Trainer 的配置符合您的预期,例如步骤数量以及是否使用热启动。 您为 Trainer 创建的代码是您的建模代码,因此它可以根据您的需要简单或复杂。
为了监控和分析训练过程,您可以使用
TensorBoard,就像您平时一样。 在这种情况下,您可以查看当前的模型训练运行,或比较多个模型训练运行的结果。 这之所以可能,是因为 ML-Metadata 存储,如上所述。 TFX 使这种比较变得相当容易,而这种比较通常很有启发性。
够好吗?
现在您已经训练了模型,结果如何?
Evaluator 组件将获取 Trainer 创建的 EvalSavedModel 和原始输入数据,并使用 Beam 和
TensorFlow Model Analysis 库进行深入分析。 它不仅查看整个数据集上的顶级结果。 它比这更深入,查看数据集的各个切片。 这很重要,因为您的模型的每个用户的体验将取决于他们的个人数据点。
您的模型可能在整个数据集上表现良好,但如果它在用户提供的数据点上表现不佳,那么该用户的体验将很差。 我们将在以后的文章中详细介绍这一点。
既然您已经查看了模型的性能,您应该将其推送到生产环境吗? 它比您已经在生产环境中的模型更好还是更差? 您可能不想仅仅因为它是新模型就推送一个更差的模型。 因此,
ModelValidator 组件使用 Beam 来进行比较,使用您定义的标准来决定是否将新模型推送到生产环境。
如果 ModelValidator 决定您的新模型已准备好投入生产,那么
Pusher 将负责实际将其推送到您的部署目标。 这些目标可以是 TensorFlow Lite(如果您要进行移动应用程序),也可以是 TensorFlow JS(如果您要部署到 JavaScript 环境),或者 TensorFlow Serving(如果您要部署到服务器场),或者以上所有内容。
下一步做什么?
这篇文章的目的是让您对 TFX 和一般的 ML 管道有一个基本的了解,并介绍主要概念。 在接下来的文章中,我们将更深入地研究 TFX,包括讨论如何扩展 TFX 以使其适合您的需求。 TFX 是开源的,因此 Google 也鼓励软件和 ML 社区
帮助我们改进它。 一个好的起点是尝试
TFX 开发人员教程!
相关主题