精通-Azure-机器学习第二版-五-

66 阅读1小时+

精通 Azure 机器学习第二版(五)

原文:annas-archive.org/md5/4810ad92d2f87002f854999a7a373fce

译者:飞龙

协议:CC BY-NC-SA 4.0

第十五章:第十五章:模型互操作性、硬件优化和集成

在上一章中,我们发现了如何将我们的机器学习评分部署为批量或实时评分器,什么是端点以及我们如何部署它们,最后,我们查看了一下如何监控我们部署的解决方案。在本章中,我们将更深入地探讨 ML 推理的额外部署场景,我们可以利用的其他可能的硬件基础设施,以及我们如何将我们的模型和端点与其他 Azure 服务集成。

在第一部分,我们将探讨如何通过将 ML 模型转换为标准化的模型格式和推理优化的评分框架来提供模型互操作性。开放神经网络交换ONNX)是一种标准化的格式,用于有效地序列化和存储 ML 模型以及循环计算图和操作。我们将学习 ONNX 框架是什么,如何将 ML 模型从流行的 ML 框架转换为 ONNX,以及如何使用 ONNX Runtime 在多个平台上评分 ONNX 模型。

随后,我们将探讨替代硬件目标,例如现场可编程门阵列FPGA)。我们将了解它们内部是如何工作的,以及它们如何与标准硬件甚至 GPU 相比实现更高的性能和更好的效率。

最后,我们将探讨如何将 ML 模型和端点集成到其他服务中。我们将更深入地了解将 ML 部署到边缘设备的过程,并将我们之前设置的一个端点与 Power BI 集成。

在本章中,我们将涵盖以下主题:

  • 与 ONNX 的模型互操作性

  • 使用 FPGA 进行硬件优化

  • 将 ML 模型和端点与 Azure 服务集成

技术要求

在本章中,您需要访问一个 Microsoft Power BI 账户。您可以通过您的工作场所或在此处创建一个试用账户来获取一个账户:app.powerbi.com/signupredirect?pbi_source=web

本章中的所有代码示例都可以在本书的 GitHub 存储库中找到:github.com/PacktPublishing/Masthttps://github.com/PacktPublishing/Mastering-Azure-Machine-Learning-Second-Edition/tree/main/chapter15

与 ONNX 的模型互操作性

在上一章中,我们学习了如何将 ML 模型作为 Web 服务部署以进行在线和批量评分。然而,许多实际用例要求您将训练好的 ML 模型直接嵌入到应用程序中,而不使用单独的评分服务。目标服务可能使用与训练 ML 模型的语言不同的语言编写。一个常见的例子是,使用 scikit-learn 在 Python 中训练的简单模型需要嵌入到 Java 应用程序中。

模型互操作性为您提供了灵活性,您可以使用您选择的语言和框架来训练模型,将其导出为通用格式,然后使用共享格式在不同的语言和平台上对其进行评分。在某些情况下,使用针对目标环境优化的本地运行时甚至可以实现比运行原始模型更好的评分性能。

首先,我们将了解 ONNX 创举,包括规范、运行时和生态系统,以及它是如何帮助实现跨大量支持语言、框架、操作和目标平台的模型互操作性的。

然后,我们将探讨如何将机器学习模型从流行的框架转换为 ONNX(称为 ONNX 前端),并使用 ONNX Runtime(ONNX 的多个后端之一)在本地推理运行时中执行 ONNX 模型。让我们深入了解。

模型互操作性是什么?ONNX 如何帮助?

随着信息技术组织的成长,工具、开发和部署平台以及选择也会增加。在机器学习中,这个问题更为突出,因为存在多个机器学习框架以及模型序列化格式。因此,一旦组织规模扩大,就几乎不可能让每个科学家和工程师都同意使用相同的工具、框架和模型格式,这些格式还需要支持所有目标环境。您的 XGBoost 模型能在 iOS 上运行吗?您的 PyTorch 模型能在 Java 中工作吗?您的 scikit-learn 模型能在基于浏览器的 JavaScript 应用程序中加载吗?解决模型互操作性问题的一种方法确保训练好的机器学习模型可以被移植到可以在所有目标平台上本地执行的标准化格式。这正是 ONNX 的目的。

ONNX 是由微软、Facebook、亚马逊、ARM 和英特尔等主要 IT 公司共同发起的一项联合倡议,旨在促进机器学习模型的互操作性。它允许组织为机器学习训练选择不同的语言、框架和环境,以及为推理选择不同的语言、环境和设备。例如,ONNX 允许组织使用 PyTorch 和 TensorFlow 训练深度学习模型,使用 LightGBM 和 XGBoost 训练传统机器学习模型,并将这些模型部署到基于 Java 的 Web 服务、基于 Objective-C 的 iOS 应用程序和基于浏览器的 JavaScript 应用程序。这种互操作性是通过三个关键要素实现的:

  • ONNX 规范:一种使用协议缓冲区Protobuf)进行模型定义和模型权重高效序列化和反序列化的数据格式。为了表示广泛的机器学习模型,ONNX 规范由可扩展的计算图模型的定义以及标准数据类型和内置算子的定义组成。使用 ONNX 规范,许多由各种支持的架构、构建块、操作和数据类型组成的机器学习模型可以高效地表示在单个文件中,我们称之为ONNX 模型

  • ONNX Runtime: 一个高效的原生推理引擎,支持与多种高级语言绑定,例如 C#、Python、JavaScript、Java/Kotlin(Android)和 Objective-C(iOS)。这意味着,通过这些语言之一的 ONNX Runtime 绑定,我们可以加载、评分,甚至训练 ONNX 模型。它还提供了内置的 GPU 加速,使用 DirectML、TensorRT、深度神经网络库DNNL)、nGraph、CUDA 以及微软线性代数子程序MLAS)库,并支持权重量化和图优化,以便在各种计算目标上高效运行,例如云计算、Jupyter 内核、手机和网页浏览器。

  • ONNX 生态系统:一组库集合,便于在 ONNX 之间进行转换。ONNX 库可以广泛分为 ONNX 前端(转换为 ONNX)和 ONNX 后端(从 ONNX)。虽然ONNX 前端库帮助将任意计算转换为 ONNX 模型(遵循 ONNX 规范的模型),但ONNX 后端库提供执行 ONNX 模型或将其转换为特定框架运行时的支持。ONNX 在微软以及其他大型公司中广泛使用,因此支持广泛的框架和语言。许多流行的库是官方支持的前端,例如传统的机器学习算法、scikit-learn、LightGBM、XGBoost 和 CatBoost,以及现代深度学习框架,如 TensorFlow、Keras、PyTorch、Caffe 2 和 CoreML。

ONNX 是提供模型互操作性以允许组织解耦模型训练、模型序列化和模型推理的绝佳选择。让我们在下一节中了解 ONNX 的流行前端和后端在实际中的应用。

使用 ONNX 前端将模型转换为 ONNX 格式

ONNX 前端是包、工具或库,可以将现有的机器学习模型或数值计算转换为 ONNX 模型。虽然流行的机器学习框架通常自带 ONNX 导出功能(类似于 PyTorch 的torch.onnx模块),但如今大多数框架都通过单独的转换库支持 ONNX。在撰写本文时,最受欢迎的 ONNX 前端如下:

  • skl2onnx:将 scikit-learn 模型转换为 ONNX

  • tf2onnx:将 TensorFlow 模型转换为 ONNX

  • onnxmltools:将 XGBoost、LightGBM、CatBoost、H2O、libsvm 和 CoreML 模型转换为 ONNX

  • torch.onnx:将 PyTorch 模型转换为 ONNX

一旦安装了 ONNX 前端库,将模型转换为 ONNX 规范通常只需运行一个命令。让我们以 TensorFlow 为例看看这个操作:

  1. 首先,我们将使用 TensorFlow 的SaveModel格式保存一个 Keras 模型。我们可以通过调用model.save()并提供将SaveModel模型序列化到磁盘的路径来实现这一点:

train.py

model = create_model()
model.fit(X_train, y_train)
model.save('tf_model')
  1. 然后,我们可以使用tf2onnx库将SaveModel模型转换为 ONNX 模型,如下面的代码片段所示:

convert.sh

python -m tf2onnx.convert \
    --saved-model tf_model \
    --output model.onnx

如前例所示,我们只需要一个命令就可以将 TensorFlow 模型转换为 ONNX 模型。一旦我们有了 ONNX 模型,我们可以使用 ONNX 后端对其进行评分,如下节所述。

使用 ONNX 后端对 ONNX 模型进行原生评分

一旦模型被导出为 ONNX 模型,我们可以使用 ONNX 兼容的后端加载它。ONNX 后端的参考实现被称为ONNX Runtime,它是一个具有许多高级语言绑定的本地实现。

首先,我们可以使用onnx库加载、分析和检查一个 ONNX 模型,如下面的示例所示:

import onnx
model = onnx.load("model.onnx")
onnx.checker.check_model(model)

然而,如果我们想对模型进行评分,我们需要使用onnxruntime后端库。首先,我们需要为推理会话加载模型;这意味着我们可以加载优化后的模型,而无需分配任何用于存储梯度的缓冲区。在下一步中,我们可以通过执行run(output_names, input_feed, run_options=None)来对模型进行评分。output_names参数指向我们希望从模型中返回的命名输出层,而input_feed表示我们想要传递给模型的数据。评分属性,如日志级别,可以通过run_options参数进行配置。以下示例展示了如何对模型进行评分并从 ONNX 模型中返回最后一层的输出:

import onnxruntime as rt
session = rt.InferenceSession("model.onnx")
outputs = session.run(None, {'input': X.values})

在前面的代码中,我们加载了针对推理优化的 ONNX 模型,将数据传递给模型的input参数,并使用 ONNX Runtime Python API 返回最后一层的输出。您可以使用辅助方法session.get_modelmeta()访问层信息以及输入和输出的名称。

在本节中,我们了解了 ONNX,学习了如何使用 ONNX 前端从训练好的机器学习模型创建 ONNX 模型,以及如何使用 ONNX Runtime(ONNX 后端的参考实现)对 ONNX 模型进行评分。虽然我们只看了 ONNX Runtime 的 Python API,但还有许多其他高级绑定可用。

使用 FPGA 进行硬件优化

在前一节中,我们将模型导出为 ONNX 以利用推理优化和硬件加速的运行时来提高评分性能。在本节中,我们将进一步采取这种方法,在甚至更快的推理硬件上部署:FPGA。

但是,在我们讨论如何将模型部署到 FPGA 之前,让我们首先了解 FPGA 是什么,以及为什么我们会选择它作为深度学习推理的目标而不是 GPU。

理解 FPGA

大多数人通常遇到一种特定的集成电路IC),称为专用集成电路ASIC)。ASIC 是专门设计的集成电路,例如笔记本电脑中的处理器、显卡上的 GPU 核心或洗衣机中的微控制器。这些芯片共享的事实是,它们具有固定的硬件足迹,优化以支持特定任务。通常,像任何通用处理器一样,它们使用特定的指令集运行,允许运行某些命令。当你用高级语言,如 Java、C++或 Python 编程时,编译器或解释器将这种高级代码转换为机器代码,这是处理器理解并能运行的命令集。

ASIC 的强大之处在于,其底层芯片架构可以根据特定的工作负载进行优化,从而在所需的面积方面实现最优化设计。ASIC 的弱点在于,它仅适用于执行其设计时指定的特定任务,并且其设计是固定的,因为底层硬件无法更改。

尽管我们可以在标准处理器上运行任何任务,但对于非常具体的事情,例如神经网络中数千个节点的计算和回溯,它们可能不是最优的。因此,现在许多这些计算都是在 GPU 上运行的,因为其芯片架构更倾向于并行运行相同的计算,这更接近神经网络算法的固有结构,而不是标准 CPU。

FPGA 的定义与它们的 ASIC 对应物不同。FPGA 在最优设计方面进行交易,尤其是在芯片上使用的面积方面,以换取可重编程性的自由。这一主要特性允许用户购买 FPGA,然后自己构建自己的处理器、硬件交换机、网络路由器或其他任何东西,并且可以在任何时候更改底层硬件设计。

由于硬件最终是由某种形式的二进制逻辑门、寄存器和电线组成的物理实体,因此 FPGA 的这种能力听起来可能像是魔法。然而,我们每天都在使用可以存储和擦除数据的闪存驱动器。例如,现代NAND 闪存驱动器通过称为场电子发射的过程进行擦除,这允许电荷通过一层薄绝缘层来重置位或,更准确地说,位块。

记住这一点,让我们看看 FPGA 的基本构建块,称为逻辑元素图 15.1显示了这些构建块的一般概念。不同的制造商调整这些构建块的不同方面,但基本概念保持不变:

图 15.1 – FPGA 中逻辑元件的结构

图 15.1 – FPGA 中逻辑元件的结构

逻辑元件通常由以下组件组成:

  • 输入/输出I/O):表示与其他逻辑元件或外部 I/O(例如,考虑以太网和 USB)的互连。

  • 查找表LUT):存储在此逻辑元件中执行的主要逻辑功能。数字电路中的任何逻辑都可以分解为一个布尔函数,该函数将一定数量的二进制输入映射到一定数量的二进制输出。

  • D 触发器(寄存器):存储当前时钟周期的输入值,以便在下一个时钟周期使用,其长度是运行电路频率的倒数。存储东西以供下一轮使用是所有数字硬件的基本原则,也是能够进行硬件流水线操作所必需的。电路中任何相邻寄存器之间的最大处理时间定义了电路可以运行的最大频率。

  • 多路复用器MUX):选择其输入中哪一个被显示为输出。在这种情况下,它要么显示布尔函数的当前结果,要么显示前一个时钟周期的结果。

通过查找表,任何布尔函数(以及通过寄存器,任何多层硬件逻辑)都可以实现。此外,查找表可以被擦除和重置,这使得 FPGA 具有可编程性。

FPGA 的完整示意图结构在图 15.2中显示。只需理解一个正常大小的 FPGA 将拥有超过 500,000 个逻辑元件:

图 15.2 – FPGA 的示意图结构

图 15.2 – FPGA 的示意图结构

除了逻辑元件外,图 15.2还显示了开关矩阵I/O 块。开关矩阵是最后一部分拼图,允许在逻辑元件之间以及它们与 I/O 块之间设置和重置所需的连接。借助它们,可以完全重新编程 FPGA 上的电路结构。

最后,为了便于 FPGA 的编程,使用了一种所谓的硬件描述语言HDL)。用于硬件设计的两种主要语言是SystemVerilogVHDL。当你看到用这些语言编写的代码时,它可能看起来像高级编程语言,但实际上,你并没有在编程任何东西;你是在描述所需的硬件架构。从某种意义上说,你以代码的形式给机器提供了一张电路的图片,它试图将此映射到 FPGA 上的给定元素。这一步称为综合。在此步骤之后,将一个二进制文件发送到 FPGA,该文件用正确的布尔函数填充所需的逻辑元件,并相应地设置所有互连。

除了这种逻辑结构之外,你还会在现代 FPGA 中发现许多其他集成系统,结合了 ASIC 和 FPGA 的优势。你甚至可能会在 IC 上找到像ARM Cortex这样的处理器。其理念是让任何在 FPGA 上从头开始构建将非常耗时的事物都在处理器上运行,同时使用 FPGA 来托管你的定制硬件设计。例如,在 FPGA 上构建以太网协议的低层将花费很多时间,因为 TCP 需要一个高度复杂的硬件电路。因此,将这部分外包给处理器可以极大地加快开发时间。

现在我们已经对 FPGA 是什么以及它是如何工作的有一个大致的了解,让我们讨论为什么它们可能比 GPU 更适合深度学习。

比较 GPU 和 FPGA 在深度神经网络中的应用

正如我们在上一节中讨论的那样,GPU 的底层硬件结构支持深度神经网络的训练和推理。原因在于它们的设计考虑了 3D 图像渲染,因此,在板上有很多逻辑来促进矩阵乘法,这是一个在 CPU 上耗时极多的任务,对于 DNNs 至关重要。通过 GPU,处理时间通常可以从几天降低到仅仅几小时。对于 FPGA 也是如此,因为我们基本上可以构建我们需要的任何专用电路来优化我们想要执行的任务的速度和功耗。

因此,对于 DNNs 来说,这两种选择都比通用 CPU 优越得多。但是,我们应该选择哪一个,为什么?现在让我们通过一个考虑方面的列表来探讨,以及这两个选项在这两种情况下各自的表现如何:

  • 实施复杂性:GPU 通常提供一种软件级语言(例如,CUDA),以使程序员与底层硬件分离。对于 FPGA,程序员必须理解硬件领域以及如何为其设计。因此,为 FPGA 构建正确的电路比在高级编程语言中使用另一个库要复杂得多。但是,正在通过专门的工具和转换器尽可能多地抽象这一层。

  • 功耗:GPU 产生大量热量,需要大量冷却和电力。这是因为为了促进软件可编程性而增加的硬件设计复杂性,从而支持 RAM、CPU 和 GPU 的基础硬件堆栈。另一方面,FPGA 不需要这个堆栈来运行,因此,在大多数情况下,具有低到中等的功耗,这使得它们比 GPU 节能 4 到 10 倍。

  • 硬件堆栈: GPU 依赖于整个标准硬件堆栈的内存管理(CPU 缓存、RAM 和 GPU 内存),并需要一个外部系统来控制它们。这导致 GPU 的硬件设计既低效又必需,以促进连接层到标准硬件堆栈,这使其性能降低。另一方面,FPGA 在其 IC 上拥有所有必需的元素(如高速内存),因此可以完全自主运行,无需从系统内存或其他任何地方拉取数据。

  • 延迟和互连性: 虽然 GPU 连接到标准的硬件堆栈,并且在其后面只有几个实际的硬件端口(HDMI 和 DisplayPort),这些端口通常仅作为输出,但 FPGA 可以连接到任何设备。这意味着它可以同时支持大量不同的输入和输出标准,使其极其灵活且能够适应任何特定情况。此外,它能够以非常低的延迟处理数据,因为不需要通过系统内存、CPU 或 SW 层传输数据,这使得它在实时视频处理等应用中远优于 GPU。

  • 灵活性: 尽管 GPU 具有并行硬件架构,但你可能无法有效地使用它。特定的 DNN 算法必须映射到底层硬件,这可能既不完美也不可行。它属于与在 CPU 核心之间分配进程相同的问题类别。此外,GPU 设计用于处理 32 位或 64 位标准数据类型。如果你使用的是非常专业的数据类型或自定义数据类型,你可能根本无法在 GPU 上运行它。另一方面,FPGA 允许你定义你想要工作的任何数据大小或数据类型,并且在此基础上,甚至在运行时允许所谓的部分重构,它使用此功能在运行时重新编程逻辑的一部分。

  • 行业适应性: 在典型的工业场景中,无论是国防、制造业、智能城市还是其他任何领域,部署的硬件必须紧凑,必须具有较长的使用寿命,应该具有低功耗,应该能够适应其所在的环境(灰尘、高温、湿度),在某些情况下,还需要具备功能性安全,这意味着它必须遵循某些合规标准和协议。GPU 对于这些情况中的任何一种都不是一个好的选择,因为它非常耗电,使用寿命为 2 到 5 年,需要大量的冷却,无法在恶劣环境中生存,并且没有功能性安全。FPGA 的设计初衷就是针对工业环境,因此通常是为了长期使用(10 到 30 年)和安全而构建的,同时功耗和所需空间的影响很小。

  • 成本: 如果你曾经为你的 PC 购买过 GPU,你可能对这种扩展卡的代价有所了解。另一方面,FPGA 可能成本较高,但对于相当的需求配置来说,通常更便宜。

考虑到所有这些因素,FPGAs 在大多数方面在技术上更优越,而且通常更便宜,但它们的主要问题是需要开发者理解硬件设计。这个问题导致了帮助弥合硬件和机器学习开发之间差距的工具包的创建,以下是一些例子:

这些只是支持通过 FPGA 部署和加速机器学习模型的一些选项。

重要提示

FPGAs 是一种非常卓越的技术,但它们需要充分理解硬件设计才能在任何项目中高效且成功地使用,或者需要一个非常复杂的工具集来抽象硬件层。

既然我们知道了为什么我们可能更愿意选择 FPGA 用于 DNN,那么让我们简要地看看如何使用 Azure 机器学习来利用 FPGA 在这方面。

在 Azure 上使用 Intel FPGAs 运行 DNN 推理

如前文所述,为 FPGA 构建硬件设计并非易事。您当然可以从头开始,利用 Azure VM 中配备 FPGA 的选项(docs.microsoft.com/en-us/azure/virtual-machines/np-series),或者使用您自己的 FPGA 开发套件。另一个选择是使用 Azure 机器学习 Python SDK 中可用的硬件加速 Python 包。此包通过支持模型子集和选项的通用硬件设计提供抽象层,特别是用于 DNN 推理的选项。通过这种方式,您可以访问Azure PBS VM 系列,该系列配备有 Intel FPGA,并且仅通过 Azure 机器学习提供。这种机器类型可在东 US、东南亚、西欧和西 US 2 进行部署。

通用方法与 ONNX 非常相似;您将一个训练好的模型转换为可以在 FPGA 上执行的具体格式。在这种情况下,您的模型必须是 ResNet、DenseNet、VGG 或 SSD-VGG,并且必须使用 TensorFlow 编写,以便适应底层硬件设计。此外,我们将使用量化 16 位浮点模型权重转换为 ONNX 模型,这些模型将在 FPGA 上运行。对于这些模型,FPGA 在云中提供了最佳推理性能。

要通过 FPGA 实现硬件加速,与 ONNX 示例相比,我们需要执行一些额外的步骤。以下列表显示了需要执行哪些步骤:

  1. 选择一个受支持的模型特征提取器。

  2. 使用自定义分类器训练受支持的模型。

  3. 将模型特征提取器的权重量化为 16 位精度。

  4. 将模型转换为 ONNX 格式。

  5. (可选) 注册模型。

  6. 创建一个计算目标(最好是 Azure Kubernetes 服务)带有 PBS 节点。

  7. 部署模型。

    重要提示

    由于代码杂乱且难以理解,我们将跳过本节中的代码示例。然而,您可以在 Azure 的 GitHub 仓库中找到有关 FPGA 模型训练、转换和部署的详细示例,链接为github.com/Azure/MachineLearningNotebooks/tree/master/how-to-use-azureml/deployment/accelerated-models

让我们更详细地讨论这些步骤。

从我们讨论的第十章中,在 Azure 上训练深度神经网络,只有特征提取器层(azureml.accel.models包 (docs.microsoft.com/en-us/python/api/azureml-accel-models/azureml.accel.models)。您可以使用 TensorFlow 或 Keras 在顶部附加任何分类或回归头(或两者),但它们将不会进行硬件加速,类似于仅在 GPU 上运行某些操作。设计者在这里选择仅将最耗时的部分部署到 FPGA 上。

在下一步中,您可以使用自己的数据和权重,或者通过微调,例如使用提供的 ImageNet 权重,来训练一个由预定义的特征提取器和自定义分类头组成的模型。这应该在 32 位精度下进行,因为训练期间收敛会更快。

一旦训练完成,您需要使用azureml.accel.models包中提供的量化模型,将特征提取器的权重量化为半精度浮点数。这一步骤需要执行,因为设计者在这里选择了 16 位固定数据大小,以便使硬件设计尽可能通用和可重用。

在下一步中,你将使用来自同一 Azure 包的 AccelOnnxConverter 方法将整个模型转换为 ONNX 模型。此外,AccelContainerImage 类帮助你为基于 FPGA 的计算目标定义 InferenceConfig

最后,你可以使用 Azure Machine Learning 模型注册表注册你的模型,并可以使用 Standard_PB6s 节点创建一个 AKS 集群。一旦集群启动并运行,你就可以使用你的 Webservice.deploy_from_image 方法部署网络服务。

重要提示

你可以在 Azure Machine Learning 文档中找到部署步骤的详细示例:docs.microsoft.com/en-us/azure/machine-learning/how-to-deploy-fpga-web-service

通过 Azure Machine Learning 将模型部署到基于 FPGA 的计算目标的工作流程与简单地部署 ONNX 模型略有不同,因为你从一开始就必须考虑有限支持的模型选择。另一个区别是,当你选择一个预定义的受支持模型进行 FPGA 部署时,你只能加速模型的特征提取部分。这意味着你必须附加一个额外的分类或回归头——这是一个不太明显的一步。一旦你理解了这一点,你就会觉得在训练后只对特征提取进行半精度浮点量化更有意义。

虽然这个过程看起来有点困难且定制化,但在处理图像数据的预测时,性能和延迟的增益是巨大的。但是,只有当你准备好将你的训练过程和管道适应到这个特定环境时,你才应该利用这种优化,正如本节中所示。

现在我们已经很好地理解了 FPGA 是什么以及我们如何通过 Azure Machine Learning 利用它们,让我们在下一节中看看我们可以与我们的模型集成的其他 Azure 服务。

将 ML 模型和端点与 Azure 服务集成

依靠 Azure Machine Learning 服务进行实验、执行端到端训练或简单地注册你的训练模型和环境,都能为你带来巨大的价值。在第十四章,“模型部署、端点和操作”中,我们介绍了两个主要场景,一个是通过自动化部署的实时评分网络服务,另一个是通过部署的管道进行批量评分。虽然这两个用例在需求和部署类型上相当不同,但它们展示了当你有一个存储在 Azure Machine Learning 中的训练模型和打包环境时,你可以做到什么。

在许多场景中,将您的批量评分流程从实际数据处理流程中抽象出来,以分离关注点和责任,是非常有意义的。然而,有时您的评分应该在数据处理或查询时间直接进行,并在同一系统中进行。一旦您的 ML 模型在 Azure Machine Learning 中注册并版本化,您就可以使用 Azure ML SDK 在任何地方提取模型的特定版本,无论是 Python、C#、命令行还是任何可以调用 REST 服务的其他语言。

这使得从桌面应用程序中提取训练和转换后的 ONNX 模型成为可能,无论是在构建时间还是运行时。例如,您可以在 Azure Databricks 或 Azure Synapse 上运行 Spark 作业时加载模型。通过这种方式,您可以避免将 TB 级的数据传输到单独的评分服务。

其他服务,如 Azure Data Explorer,允许您通过 Python 扩展直接从服务中调用模型(docs.microsoft.com/en-us/azure/data-explorer/kusto/query/pythonplugin)。Azure Data Explorer 是一个用于高效存储和查询大量遥测数据的托管服务。它被 Azure 内部使用,为 Azure Log Analytics、Azure Application Insights 和 Time Series Insights 提供动力。它拥有强大的 Python 运行时,提供了许多流行的包,因此提供了执行基于自定义模型的异常检测或时间序列分析的理想服务。此外,它还允许您通过名为Kqlmagic的 Python 扩展在 ML 建模期间访问其时间序列数据(docs.microsoft.com/en-us/azure/data-explorer/kqlmagic)。

重要提示

当使用 Azure Machine Learning 进行模型部署时,您可以利用所有 Azure 生态系统的好处,并可以期待随着时间的推移,模型或端点与越来越多的 Azure 服务进行集成。

在本章结束时,我们将深入探讨即将到来的部分中的两个其他集成选项。我们将查看如何通过Azure IoT Edge将 ML 模型部署到现场网关或设备,以及如何利用 ML 端点在Power BI中进行数据增强。

与 Azure IoT Edge 集成

到目前为止,我们已经讨论了不同的方法来让我们的模型在云中的系统上运行,无论是 CPU、GPU 还是 FPGA 机器,无论是作为批量评分过程还是作为实时端点。现在,让我们讨论另一个有趣的部署场景,将实时评分器部署到现场的一个到数十万个设备上。对这些设备和收集的遥测数据和事件的控制属于所谓的物联网IoT)的范畴,它使我们能够几乎实时地对任何环境中的变化和关键问题做出反应。

在这些场景中,机器学习的集成使我们能够同时将模型分发到多个系统和设备,使这些所谓的边缘设备能够在本地运行时执行模型,以便根据机器处理的结果做出相应反应。这可能是一个执行机器学习图像处理以应对入侵者并发送警报的本地摄像头系统,或者任何你可能想象到的其他场景。

要了解如何利用 Azure 平台实现这一目标的基础知识,让我们首先看看 IoT 场景是如何通过Azure IoT Hub和其他服务的帮助实现的,然后讨论如何将其与 Azure 机器学习和我们的训练模型集成。

理解 Azure 上的 IoT 解决方案

Azure 上任何 IoT 架构的基础是 Azure IoT Hub。它作为云网关与现场中的设备和其他网关进行通信,并能够在一定程度上控制它们。一方面,它运行 Azure Event Hubs 以能够通过分布式结构处理大量传入遥测,这与 Apache Kafka 并无太大不同。另一方面,它作为控制工具,提供以下功能:

  • 设备目录:记录所有注册到 Azure IoT Hub 的设备。任何连接的设备都会获得自己的设备名称和连接配置,定义了设备与中心之间的直接连接如何安全,这可以通过旋转密钥或设备证书来实现。

  • 设备配置:一种允许设备自动注册到 IoT Hub 以获取带有密钥的连接字符串或证书的服务。如果需要注册的设备数量较多,则非常有用。

  • 设备孪生:一个配置文件,定义了设备的重要属性,可以设置或请求。在遥测流之间,设备被要求偶尔发送此文件,更新云网关中设备的状态。因此,设备孪生始终持有设备的最新状态。当在设备上使用Azure IoT 设备 SDK时,此功能会自动实现。

  • 命令与控制:这是通过Azure IoT 服务 SDK实现的。来自控制台或外部应用程序的命令可以用来向单个设备发送新的期望属性,为设备组定义配置,或发送设备需要理解和实施的预定义命令。这可能是一个请求重新启动设备或更新其固件的请求。

  • 监控和诊断:对来自和发送到 IoT Hub 的任何传入和传出消息的诊断视图。它可以用来了解传入遥测的吞吐量,了解交换的任何控制平面信息,并在设备不可达且出现故障时发出警告。

除了这个云网关之外,Azure 还提供了一种边缘设备运行时,称为 Azure IoT Edge,它可以安装在设备或网关上。它由 Moby Docker 运行时(mobyproject.org/)提供支持,允许用户将 Docker 容器部署到现场设备。在此运行时中运行的任何解决方案的设置都由一个部署清单定义,该清单通过 IoT Hub 中的设备孪生配置文件为边缘设备设置。此清单定义以下组件:

  • IoT Edge 代理:验证和实例化模块,在运行时检查它们的状态,并利用设备孪生配置文件报告任何配置或运行时问题。它是运行时的主要模块,是必需的

  • IoT Edge 网关:使 IoT Edge 运行时能够模拟 IoT Hub,以便连接到该本地边缘设备的额外设备。这允许任何形式的复杂层次结构,同时设备可以使用与 IoT Hub 相同的协议与 IoT Edge 设备通信。此模块是必需的

  • 容器模块:定义要复制到边缘运行时的容器镜像。这是通过定义一个链接到存储在 Azure 容器注册表中的源文件来完成的。除了任何可以通过这种方式部署的用户定义容器外,还有许多 Azure 服务的容器化版本可以发送到运行时。这个列表包括 Blob 存储、Azure Function 应用、某些认知服务,甚至还有一个称为SQL Edge的小型、优化的 SQL 服务器版本。

  • 通过路由进行本地通信:通过设置先前定义的各种模块的输入和输出之间的直接连接,定义将模块连接在一起的第一种选项。

  • 通过 MQTT 代理进行本地通信:定义将模块连接在一起的第二种选项。而不是设置直接连接,使用一个代理,模块可以订阅。此代理还提供连接到理解如何与 MQTT 代理通信的外部设备。

定义部署清单时,需要考虑的主要组件和选项。

重要提示

Azure IoT Edge 带来的最大优势是能够在云中定义、管理和版本控制容器,并将它们部署到成千上万的设备上。借助设备配置,我们可以分组设备,并且只为特定组进行新的测试更新,从而在物联网环境中实现 DevOps 的最佳实践。

现在,让我们简要地看一下一个示例。图 15.3显示了通过 Azure IoT Edge 对传入遥测数据进行容器化 ML 模型评分的简单设置及其与 Azure IoT Hub 的连接:

图 15.3 – Azure IoT Hub 连接到边缘运行时

图 15.3 – Azure IoT Hub 连接到边缘运行时

图 15.3中的连接显示了容器之间的内部路由,包括本地执行的操作,而来自机器学习评分的任何见解和任何初始遥测数据都额外发送到云端进行进一步分析。这是任何在边缘运行的机器学习模型的典型场景。

在了解这些知识的基础上,我们现在来看看如何将 Azure 机器学习集成到这样的物联网架构中。

集成 Azure 机器学习

第三章,“准备 Azure 机器学习工作区”,我们了解到每个 Azure 机器学习工作区都自带一个 Azure 容器注册表。我们现在可以使用这个注册表来实现我们的目标。图 15.4展示了边缘机器学习端到端解决方案的示例:

图 15.4 – Azure IoT Edge 端到端机器学习场景

图 15.4 – Azure IoT Edge 端到端机器学习场景

它描述了以下步骤:

  1. 在存储账户中收集遥测数据,无论是通过从 IoT Hub 路由单个消息,还是通过从边缘的 Blob 存储批量上传到云端的存储账户

  2. 在捕获的数据上训练 ML 模型,正如我们之前所学的

  3. 在 Azure 机器学习工作区的现有 Azure 容器注册表中注册包含训练模型和依赖项的容器

  4. 创建一个定义从 Azure 容器注册表源 ML 模块的 IoT Edge 部署清单

  5. 通过 Azure IoT Hub 将创建的配置部署到边缘设备

通过这个设置,我们现在能够部署和控制边缘的 ML 模型,从而在外部设备上运行低延迟的 ML 解决方案。

重要提示

如果你想尝试一下,请随意遵循设置 Azure IoT Edge 上的示例机器学习模型的教程,教程链接如下:docs.microsoft.com/en-us/azure/iot-edge/tutorial-machine-learning-edge-01-intro

最后,如果你对边缘机器学习解决方案的更多选项感兴趣,可以查看 Azure 物联网空间中最新的添加之一,名为Azure Percept (azure.microsoft.com/en-us/services/azure-percept/)。它提供了一个现成的硬件开发套件,用于视频和音频推理,可与 Azure IoT Hub 和 Azure 机器学习协同工作。

现在我们已经对物联网世界和边缘机器学习场景有了初步了解,让我们来看看如何利用 Power BI 实时机器学习端点。

集成 Power BI

从企业角度来看,最有趣的集成之一是 Azure 机器学习与 Power BI 的集成。它允许我们利用我们的 ML 端点,在内置的Power Query 编辑器中应用我们的模型到数据列。想想看,将 ML 模型推广给数据分析师在他们的 BI 工具中使用是多么强大的概念。

让我们通过利用在第十四章“模型部署、端点和操作”中创建的sentiment-analysis-pbi端点来尝试一下,按照以下步骤操作:

  1. 如果您还没有这样做,请将 Power BI 桌面应用程序([powerbi.microsoft.com/en-gb/desktop/](powerbi.microsoft.com/en-gb/deskt…

  2. 从章节存储库下载sentiment_examples.csv文件,然后选择获取数据 | 文本/CSV,将此本地文件的内容加载到 Power BI 的内存数据集中。

  3. Power Query 编辑器将打开,并显示带有名称和大小的文件图标。右键单击该图标,然后选择文本

  4. 您应该会看到一个只有一个列的表格。将列重命名为Phrases,如图 15.5 所示:

图 15.5 – 情感分析样本短语

图 15.5 – 情感分析样本短语

  1. 编辑器为您提供了许多将转换应用于这些数据的方法。查看菜单,您应该在最右侧看到一个名为Azure 机器学习的按钮。点击它。

  2. 如果您登录正确,您应该看到您有权访问的所有 Azure 机器学习工作区中的所有可用端点。选择我们之前创建的端点AzureML.sentiment-analysis-pbi。在Phrases列中。这将是我们的 ML 端点的输入。图 15.6显示了它应该看起来是什么样子:

图 15.6 – 在 Power BI 中选择正确的 ML 端点

图 15.6 – 在 Power BI 中选择正确的 ML 端点

  1. 点击确定。Power BI 现在将开始向端点发送请求。请注意,您可能会在 Power BI 窗口中收到有关数据隐私的警告,因为我们正在将可能涉及隐私的数据发送到另一个服务。请通过选择第一个复选框接受此警告,以便执行此操作。

  2. 结果,您现在应该看到一个名为AzureML.sentiment-analysis-pbi的新列,其中包含许多标记为Record的字段。由于我们的端点发送了多个输出,我们收到了一个记录。您现在可以单独点击每个记录,或者您可以点击列标题旁边显示两个箭头的按钮。这允许您将此Record列展开成多个列。选择所有列名并按确定图 15.7显示了您应该看到的结果:

图 15.7 – Power BI 情感分析结果

图 15.7 – Power BI 情感分析结果

如我们所见,该模型为每个句子给出一个标签(NEGATIVEPOSITIVE)和一个置信度值分数,表示 ML 模型对给定标签的确定性。结果相当准确,也许第四个短语除外。

  1. 现在,您可以点击左上角的关闭并应用,这将导致 Power BI 创建一个增强型 ML 数据集,您现在可以构建报告中的可视化,并最终将报告发布到云中的 Power BI 服务。

如您自己所见,与 Power BI 集成是一种快速简单的方法,使每个人都能利用他们的业务数据使用您部署的 ML 端点,同时不必深入了解 ML 服务的内部工作原理。

随意添加一些你自己的短语来尝试一下。

摘要

在本章中,我们学习了如何使用 ONNX 将 ML 模型转换为便携和可执行格式,什么是 FPGA,以及我们如何通过 Azure Machine Learning 将 DNN 特征提取器部署到 FPGA VM。此外,我们还学习了如何将我们的 ML 模型集成到各种 Azure 服务中,例如 Azure IoT Edge 和 Power BI。

这就结束了我们通过前两章对部署 ML 模型进行批量或实时推理的各种选项的讨论。

在下一章中,我们将把迄今为止所学的一切整合起来,理解和构建一个端到端的 MLOps 流水线,使我们能够为任何需要添加 ML 的过程创建一个企业级和自动化的环境。

第十六章:第十六章:使用 MLOps 将模型投入生产

在上一章中,我们探讨了使用 ONNX 进行模型互操作性、使用 FPGA 进行硬件优化以及将训练模型集成到其他服务和平台中的方法。到目前为止,你已经学习了如何在一个端到端机器学习管道中实现每个步骤,包括数据清洗、预处理、标记、实验、模型训练、优化和部署。在本章中,我们将把之前所有章节中的片段连接起来,在构建和发布管道中集成和自动化它们。我们将重用所有这些概念,在 Azure 中构建一个版本控制的、可重复的、自动化的 ML 训练和部署过程,作为一个 持续集成和持续部署CI/CD)管道。类似于软件开发中的 DevOps 方法论,我们将把这个主题称为 MLOps

首先,我们将看看如何为 ML 项目生成可重复的构建、环境和部署。我们将涵盖代码的版本控制,以及数据和构建工件版本化/快照。

接下来,我们将学习如何自动测试我们的代码,并重点关注 ML 项目来验证代码质量。为此,我们将了解如何将单元测试、集成测试和端到端测试适应以确保训练数据和 ML 模型的良好质量。

最后,你将构建自己的 MLOps 管道。首先,你将学习如何设置 Azure DevOps 作为 MLOps 的编排和协调层,然后你将实现构建(CI)和发布(CD)管道。

在本章中,我们将涵盖以下主题:

  • 确保可重复构建和部署

  • 验证代码、数据和模型

  • 构建端到端 MLOps 管道

技术要求

在本章中,我们将使用以下 Python 库和版本在 Azure DevOps 中创建 MLOps 管道:

  • azureml-core 1.34.0

  • azureml-sdk 1.34.0

  • pandas 1.3.3

  • tensorflow 2.6.0

  • pytest 7.1.1

  • pytest-cov 3.0.0

  • mock 4.0.3

  • tox 3.24.5

本章讨论的大多数脚本和管道需要在 Azure DevOps 中进行调度执行。

本章中所有的代码示例都可以在本书的 GitHub 仓库中找到:github.com/PacktPublishing/Mastering-Azure-Machine-Learning-Second-Edition/tree/main/chapter16.

确保可重复构建和部署

DevOps 有许多不同的含义,但通常是指在源代码更改时实现快速和高品质的部署。实现高质量操作代码的一种方法是通过保证可重复和可预测的构建。虽然对于只有少量配置更改的应用程序开发来说,编译的二进制文件看起来和行为相似似乎是显而易见的,但对于 ML 管道的开发来说,情况并非如此。

机器学习工程师和数据科学家面临着许多问题,这使得构建可重复部署变得非常困难:

  • 开发过程通常在笔记本中执行,因此它不总是线性的。

  • 重构笔记本代码经常会破坏旧的笔记本。

  • 存在库版本和驱动程序不匹配的问题。

  • 源数据可能会被更改或修改。

  • 非确定性优化技术可能导致完全不同的输出。

本书的前几章我们讨论了交互式笔记本(例如 Jupyter、Databricks、Zeppelin 和 Azure 笔记本),你可能在实现机器学习模型和数据管道时已经见过它们。虽然交互式笔记本有执行单元格以迭代验证模型块块的优势,但它们也常常鼓励用户以非线性顺序运行单元格。当尝试将管道投入生产或自动化时,使用笔记本环境的主要好处变成了痛点。

机器学习中的第二个常见问题是确保安装了正确的驱动程序、库和运行时。虽然使用 Python 2 运行基于 scikit-learn 的小型线性模型很容易,但如果部署的 CUDA、cuDNN、libgpu、Open MPI、Horovod、TensorFlow、PyTorch 和类似库与开发版本匹配,对深度学习模型来说就大不相同了。通过 Docker 或类似技术进行容器化有助于构建可重复的环境,但在实验、训练、优化和部署过程中使用它们并不简单。

数据科学家面临的另一个挑战是数据通常会随时间变化。在开发过程中,可能添加了新的数据批次,或者数据被清理、写回存储,并作为其他实验的输入重新使用。由于数据在格式、规模和质量上的可变性,它可能是生产可重复模型时遇到的最大问题之一。与代码版本控制类似,对数据进行版本控制对于可重复构建和审计目的都是必不可少的。

另一个使可重复的机器学习构建变得困难的挑战是,它们通常包含一个优化步骤,如第 第十一章 中讨论的,超参数调整和自动化机器学习。虽然优化是机器学习(例如,用于模型选择、训练、超参数调整或堆叠)的必要步骤,但它可能会给训练过程添加非确定性行为。让我们一步一步地找出如何解决这些问题。

代码版本控制

版本控制源代码是一种最佳实践,不仅适用于软件开发,也适用于数据工程、数据科学和机器学习。作为一个组织,您可以选择建立自己的内部源代码仓库或使用外部服务。GitHubGitLabBitbucketAzure DevOps是管理源代码仓库的流行服务。这些服务的优势在于它们中的一些提供了额外的功能,例如对 CI 工作流的支持。在本章的后面,我们将使用 Azure DevOps 的 CI 运行器集成。

使用版本控制对您的代码来说比您使用的版本控制系统更重要。是的,Git工作得相当好,但MercurialSubversionSVN)也是如此。对于我们的示例 MLOps 管道,我们将使用 Git,因为它是最广泛使用和支持的。您必须熟悉您选择的版本控制系统的基本工作流程。您应该能够创建提交和分支,提交pull requestsPRs),对请求进行评论和审查,以及合并更改。

版本控制源代码的力量在于记录更改。在每个这样的更改上,我们希望触发一个自动的管道来测试您的更改,验证代码质量,并在成功合并后训练模型并自动将其部署到预发布或生产环境。您的提交和 PR 历史记录不仅将成为记录更改的来源,还将触发、运行和记录这些更改是否经过测试并准备好投入生产。

为了有效地使用版本控制,您必须尽快将业务逻辑从您的交互式笔记本中移除。笔记本以自定义数据格式存储每个单元格的代码和输出,例如序列化为 JSON 文件。这使得在序列化的笔记本中审查更改变得非常困难。一种好的折衷方法是采用混合方法,首先在笔记本中测试您的代码实验,然后逐渐将逻辑移动到导入到每个文件中的模块。使用自动重新加载插件,您可以确保在更改逻辑时,这些模块会自动重新加载,而无需重启内核。

将代码从笔记本移动到模块不仅会使您的代码对所有其他实验可重用(无需从笔记本复制实用函数),而且会使您的提交更加易于阅读。当多个人在一个庞大的 JSON 文件(这是您的笔记本环境存储每个单元格的代码和输出的方式)中更改几行代码时,对文件的更改将几乎无法审查和合并。然而,如果这些更改是在模块(仅包含可执行代码的单独文件)中进行的,那么这些更改将更容易阅读、审查、推理和合并。

在我们继续查看训练数据的版本化之前,这是一个复习你的 Git 技能、创建(私有)存储库并实验版本控制功能的好机会。

注册数据快照

你的机器学习模型是训练代码和训练数据的输出。如果我们对训练源代码进行版本控制以创建可重复构建,我们也需要对训练数据进行版本控制。虽然将小型、文本、非二进制和非压缩文件与源代码一起检查到版本控制系统中听起来是合理的,但对于大型二进制或压缩数据源来说,这听起来并不合理。在本节中,我们将讨论如何处理后者的解决方案。

让我们再次强调可重复构建的概念:无论何时执行训练——它可能是今天,也可能是一年后——输出应该是相同的。这意味着对训练数据的任何修改都应该创建数据集的新版本,并且训练应该使用数据集的特定版本。我们区分操作事务数据和历史数据。前者通常是状态性和可变的,而后者通常是不可变的。有时,我们也会看到两者的混合,例如,可变的历史事件数据。

当处理可变数据(例如,存储客户信息的操作数据库)时,我们需要在拉取数据用于训练之前创建快照。对于机器学习,使用完整快照比增量快照更容易,因为每个快照都包含完整的数据集。虽然增量快照通常创建来节省成本,但使用列压缩数据格式和可扩展的 blob 存储系统(如 Azure Blob 存储)也可以高效地存储完整快照,即使你有多个 TB 的数据。

当处理历史数据或不可变数据时,我们通常不需要创建完整快照,因为数据是分区的——也就是说,组织在目录中,目录对应于分区键的值。历史数据通常按处理日期或时间分区,例如数据摄取执行的时间。日期或时间分区使得将训练管道指向特定范围的分区而不是直接指向一组文件变得更容易。

有多种方法可以创建训练数据的快照。然而,当使用 Azure 机器学习工作区时,建议将数据包装在 Azure 机器学习数据集中,如第四章“导入数据和管理数据集”中所述。这使得创建数据快照或版本化数据变得容易。在 Azure 机器学习中处理和修改数据时,你应该养成增加数据集版本的惯例。此外,在训练脚本中获取数据时,你应该传递数据集的特定版本。

每次你向你的训练脚本传递参数时,使用确定性占位符参数化管道是有帮助的。如日期和时间戳之类的参数应在管道调度步骤中创建,而不是在代码本身中创建。这确保了你总是可以用历史参数重新运行失败的管道,并且会创建相同的输出。

因此,确保你的输入数据已注册并版本控制,你的输出数据也已注册并参数化。这需要一点时间来正确设置,但整个项目生命周期都是值得的。

跟踪你的模型元数据和工件

将你的代码移到模块中,将其检查到版本控制中,并对你的数据进行版本控制将有助于创建可重复的模型。如果你正在为企业构建 ML 模型,或者你正在为你的初创公司构建模型,了解哪个模型版本被部署以及它使用的数据集进行训练是至关重要的。这对于审计、调试或解决客户对你服务预测的询问是相关的。

我们在前几章中看到,几个简单的步骤就可以让你在模型注册表中跟踪模型工件和模型版本。对模型工件进行版本化是持续部署的必要步骤。模型由工件组成,这些工件是在训练过程中生成的文件和元数据。模型资产包含模型架构、参数和权重的定义,而模型元数据包含数据集、提交哈希、实验和运行 ID 以及更多训练运行信息。

另一个重要的考虑因素是指定和版本控制你的随机数生成器的种子。在大多数训练和优化步骤中,算法将使用基于随机种子的伪随机数来洗牌数据和参数选择。因此,为了在多次运行代码后产生相同的模型,你需要确保为每个使用随机行为的操作设置一个固定的随机种子。

一旦你了解了源代码版本控制对你应用程序代码和版本化数据集的好处,你就会明白这对你的训练模型来说也是非常有意义的。然而,现在你存储的是每个模型的模型工件(包含模型权重和架构的二进制文件)和元数据,而不是可读的代码。

编写你的环境和部署脚本

自动化你在训练和部署过程中执行的每个操作将增加开发、测试和部署的初始时间,但最终在再次执行这些步骤时将节省大量时间。云服务,如 Azure 机器学习和 Azure DevOps,的好处是它们为你提供了自动化开发部署过程中每一步所需的所有工具。

如果你还没有这样做,你应该开始组织你的 Python 代码到虚拟环境中。流行的选项包括 requirementspyenvPipenvconda 文件,这些文件可以帮助你跟踪开发和测试依赖项。这有助于你将依赖项作为虚拟环境的一部分进行指定,而不是依赖于全局包或开发机器的全局状态。

Azure DevOps 和其他 CI 运行器将帮助你定义依赖关系,因为运行集成测试将在测试过程中自动安装所有定义的依赖项。这通常是 CI 流水线中的第一步。然后,无论何时你将新代码或测试检入到你的版本控制系统,CI 流水线都会执行并自动测试你的环境安装。因此,将集成测试添加到所有模块中是一个好习惯,这样你就不会错过环境中任何包的定义。如果你遗漏了依赖项的声明,CI 构建将失败。

接下来,你还需要编写脚本、配置和自动化所有基础设施。如果你已经阅读了本书的前几章,你现在可能已经明白为什么我们通过 Python 编写环境自动化和部署。如果你之前已经编写了这些步骤的脚本,你可以在 CI 流水线中简单地运行和参数化这些脚本。

如果你运行一个生成模型的 CI 流水线,你很可能希望为这项工作启动一个新的 Azure Machine Learning 集群,这样你就不会干扰到其他发布、构建流水线或实验。虽然这种自动化程度在本地基础设施上非常难以实现,但在云中你可以轻松做到。许多服务,如 Azure Machine Learning 中的 YAML 文件、Azure 中的 ARM 模板或 HashiCorp 的 Terraform,都提供了对你基础设施和配置的完全控制。

最后的部分是在 Azure Machine Learning 中自动化部署。通过代码执行部署并不比通过 UI 花费更多时间,但它提供了可重复和可再现的部署脚本的优点。你经常会面临以多种方式执行相同操作的情况;例如,通过 Azure Machine Learning CLI、Python SDK、YAML、Studio 或 Azure DevOps 中的插件部署 ML 模型。建议选择对你来说最有效的方法,坚持一种做事方式,并以相同的方式进行所有自动化和部署。话虽如此,使用 Python 作为部署的脚本语言并在版本控制中检查你的部署代码是一个好主意,也是流行的选择。

可重复构建和 CI 管道的关键是从一开始就自动化基础设施和环境。在云中,特别是在 Azure 中,这应该非常容易,因为大多数工具和服务都可以通过 SDK 进行自动化。Azure 机器学习团队在 SDK 上投入了大量工作,以便你可以在 Python 内部自动化从摄入到部署的每个步骤。

接下来,让我们来看看代码和资产验证,以确保代码和训练好的模型按预期工作。

验证代码、数据和模型

当实现 CI/CD 管道时,你需要确保你已经设置了所有必要的测试,以便轻松自信地部署你新创建的代码。一旦你运行了 CI 或 CI/CD 管道,自动化测试的力量将立即显现。它不仅可以帮助你检测代码中的故障,还可以帮助你检测整个机器学习过程中的未来问题,包括环境设置、构建依赖项、数据需求、模型初始化、优化、资源需求和部署。

当实现我们机器学习过程的验证管道时,我们可以从传统的软件开发原则中汲取灵感(例如,单元测试、集成测试和端到端测试)。我们可以将这些技术直接转换为机器学习过程中的步骤,例如输入数据、模型和评分服务的应用程序代码。让我们了解如何将这些测试技术适应机器学习项目。

使用单元测试测试数据质量

单元测试对于编写高质量的代码至关重要。单元测试旨在独立于所有其他代码测试代码的最小单元(一个函数)。每个测试应该一次只测试一件事情,并且应该快速运行和完成。许多应用程序开发人员在他们更改代码时运行单元测试,或者至少在将新提交提交到版本控制时运行单元测试。

下面是一个使用 Python 3 标准库中提供的unittest模块编写的单元测试的简单示例:

import unittest
class TestStringMethods(unittest.TestCase):
  def test_upper(self):
    self.assertEqual('foo'.upper(), 'FOO')

如代码片段所示,我们运行一个函数并测试结果是否与预定义的变量匹配。我们可以将更多测试作为额外的方法添加到测试类中。

在 Python 和许多其他语言中,我们区分测试框架和库,这些框架和库帮助我们编写和组织测试,以及执行测试和创建报告的库。pytesttox是执行测试的出色库;unittestmock帮助你以类为单位编写和组织测试,并模拟对其他函数的依赖。

当你为你的机器学习模型编写代码时,你也会发现一些代码单元,这些代码单元可以在每次提交时进行单元测试,并且可能应该进行单元测试。然而,机器学习工程师、数据工程师和数据科学家现在在他们的开发周期中还要处理另一个错误来源:数据。因此,重新思考单元测试在数据质量方面的意义是一个好主意。

一旦你掌握了这个技巧,你将很快理解使用单元测试来衡量数据质量的力量。你可以将输入数据的特征维度视为一个可测试的单个单元,并编写测试来确保每个单元都满足定义的要求。这在随着时间的推移收集新的训练数据并计划未来重新训练模型时尤为重要。在这种情况下,我们总是希望在开始训练过程之前确保数据是干净的并且符合我们的假设。

这里有一些示例,说明你的单元测试可以在训练数据中测试的内容:

  • 唯一/不同值的数量

  • 特征维度的相关性

  • 偏度

  • 最小值和最大值

  • 最常见值

  • 包含零或未定义值的值

让我们将其付诸实践,编写一个单元测试来确保数据集的最小值为 0。这个简单的测试将确保如果数据集中包含意外的值,你的 CI/CD 管道将失败:

import unittest
import pandas as pd
class TestDataFrameStats(unittest.TestCase):
  def setUp(self):
    # initialize and load df
    self.df = pd.DataFrame(data={'data': [0,1,2,3]})
  def test_min(self):
    self.assertEqual(self.df.min().values[0], 0)

在前面的代码中,我们使用 unittest 在同一个类中的多个函数内组织测试。每个类对应一个特定的数据源,在每一个类中,我们可以测试所有特征维度。一旦设置好,我们就可以安装 pytest 并简单地从命令行执行它来运行测试。

在 Azure DevOps 中,我们可以在构建管道中设置 pytesttox 作为简单步骤。对于构建管道步骤,我们只需将以下块添加到 azure-pipelines.yml 文件中:

- displayName: 'Testing data quality'
  script: |
    pip install pytest pytest-cov
    pytest tests --doctest-modules

在前面的代码中,我们首先安装了 pytestpytest-cov 来创建 pytest 覆盖率报告。在下一行,我们执行了测试,现在它将使用数据集并计算所有统计要求。如果测试未满足要求,测试将失败,我们将在构建的 UI 中看到这些错误。这为你的 ML 管道增加了保护,因为你现在可以确保没有未预见的问题的训练数据在没有你注意到的情况下进入发布。

单元测试对于软件开发至关重要,对于数据也是如此。与一般的测试一样,实施它需要一些初始的努力,这不会立即转化为价值。然而,你很快就会看到,有了这些测试,在部署新模型时你会感到更加安心,因为它会在构建时捕捉到训练数据中的错误,而不是当模型已经部署时。

机器学习集成测试

在软件开发中,集成测试验证所谓的单个组件,这些组件通常由多个较小的单元组成。你通常使用测试驱动程序来运行测试套件,并在测试中模拟或存根你不想测试的其他组件。在图形应用程序中,你可以测试一个简单的视觉组件,同时模仿该组件交互的模块。在后端代码中,你测试你的业务逻辑模块,同时模拟所有依赖的持久化、配置和 UI 组件。

因此,集成测试有助于你在组合多个单元时检测关键错误,而无需构建整个应用程序基础设施。它们位于单元测试和端到端测试之间,通常在 CI 运行时按提交、分支或 PR 运行。

在机器学习(ML)中,我们可以使用集成测试的概念来测试机器学习管道的训练过程。这可以帮助你的训练运行在构建阶段发现潜在的错误和错误。集成测试允许你测试你的模型、预训练权重、测试数据片段和优化器是否能够产生成功的输出。然而,不同的算法需要不同的集成测试来测试训练过程中是否存在问题。

当训练一个深度神经网络(DNN)模型时,你可以通过集成测试验证模型的许多方面。以下是一个非详尽的步骤列表,用于验证:

  • 权重初始化

  • 默认损失函数

  • 零输入

  • 单批次拟合

  • 默认激活函数

  • 默认梯度

使用类似的列表,你可以轻松地识别和捕捉到所有激活函数在正向传播中都被限制在最大值,或者在反向传播中所有梯度都是0的情况。理论上,你可以在 CI 运行时连续运行任何实验、测试或检查,就像在处理新的数据集和模型之前手动执行的那样。因此,每次你的模型被重新训练或微调时,这些检查都会在后台自动运行。

一个更一般的假设是,在训练回归模型时,默认的均值应该接近预测值的均值。在训练分类器时,你可以测试输出类别的分布。在这两种情况下,你可以在开始昂贵的训练和优化过程之前,检测到由于建模、数据或初始化错误引起的问题。

在运行者和框架方面,你可以选择与单元测试相同的库,因为在这种情况下,集成测试仅在测试的组件及其组合方式上有所不同。因此,选择unittestmockpytest来构建你的集成测试管道是一种流行的选择。

集成测试对于应用程序开发和运行端到端机器学习(ML)管道至关重要。如果你能够自动检测和避免这些问题,这将节省你大量时间并降低运营成本。

使用 Azure Machine Learning 进行端到端测试

在端到端测试中,我们希望验证所有参与请求已部署和完全功能服务的组件。为此,我们需要一起部署完整的服务。端到端测试对于捕获仅在所有组件组合在一起并在一个没有模拟其他组件的预发布或测试环境中运行服务时触发的错误至关重要。

在机器学习部署中,有许多步骤,如果不进行适当的测试,可能会出现很多问题。让我们先排除那些需要确保环境正确安装和配置的简单问题。在 Azure 机器学习中的部署中,一个更关键的部分是应用程序逻辑本身的代码:评分文件。没有简单的方法可以在没有适当端到端测试的情况下测试评分文件、请求格式和输出。

如你所想,端到端测试通常构建和操作成本很高。首先,你需要编写代码并部署应用程序来测试代码,这需要额外的工作、努力和成本。然而,这是在类似生产环境的端到端环境中真正测试评分端点的唯一方法。

好消息是,通过使用 Azure 机器学习部署,端到端测试变得如此简单,以至于它应该成为每个人的管道的一部分。如果模型允许,我们甚至可以进行无代码部署,我们不需要指定部署目标。如果这不可能,我们可以指定 Azure 容器镜像作为计算目标,并独立部署模型。这意味着将前一章的代码放入 Python 脚本中,并将其作为构建过程中的一个步骤。

端到端测试通常很复杂且成本高昂。然而,使用 Azure 机器学习和自动化部署,模型部署和样本请求可以仅仅是构建管道的一部分。

持续监控你的模型

模型监控是实验和训练阶段的重要步骤。这将帮助你了解当模型作为评分服务使用时所需的资源。这是设计和选择适当规模的推理环境的关键信息。

无论训练和优化过程是否持续进行,模型需求和配置都会随着时间的推移而演变。如果你使用优化进行模型堆叠或自动化机器学习,你的模型可能会变得更大以适应新的数据。因此,密切关注你的模型需求,以考虑与初始资源选择偏差是很重要的。

幸运的是,Azure 机器学习提供了一个模型监控接口,你可以用模型、评分函数和测试数据来填充它。它将为你实例化一个推理环境,启动评分服务,将测试数据通过服务运行,并跟踪资源利用率。让我们将所有这些部分组合起来,并设置一个端到端 MLOps 管道。

构建端到端 MLOps 管道

在本节中,我们希望设置一个端到端的 MLOps 管道。所有必需的训练代码都应该被检查到版本控制中,数据集和模型也将进行版本控制。我们希望在代码或训练数据发生变化时触发 CI 管道以构建代码和重新训练模型。通过单元和集成测试,我们将确保训练和推理代码在隔离状态下工作,并且数据和模型满足所有要求,不偏离我们的初始假设。因此,CI 管道将负责自动的持续代码构建、训练和测试。

接下来,每当一个新的模型版本准备好时,我们将触发 CD 管道。这将部署模型和推理配置到预发布环境,并运行端到端测试。测试成功完成后,我们希望自动将模型部署到生产环境。因此,CD 管道将负责自动部署。

将管道分为 CI 和 CD 部分使得将构建资产的过程与部署资产的过程解耦变得容易。然而,您也可以将这两部分合并为一个单一的 CI/CD 管道,从而使用一个管道进行构建、训练、优化和部署。如何对您的管道的 CI 和 CD 组件进行建模,以及如何设置任何触发器和(手动)批准,取决于您和您的组织。您可以选择将每个提交部署到生产环境,或者在每个工作日或每周在手动批准后部署一定数量的提交。

在本节中,我们将使用 Azure DevOps 来编写和执行 CI/CD 管道,因此设置触发器、运行构建、训练和测试步骤,并处理训练模型的部署。Azure DevOps 具有内置的功能来自动化端到端的 CI/CD 流程。通常,它允许您在您定义的计算基础设施上运行管道中的功能块,称为任务。您可以通过版本控制系统中新提交的提交自动触发管道,或者通过构建工件的新版本或按钮等触发它们,例如,用于半自动部署。前者称为代码管道,指的是 CI,而后者称为发布管道,指的是 CD。

让我们开始设置一个 Azure DevOps 项目。

设置 Azure DevOps

Azure DevOps 将作为编写、配置、触发和执行所有我们的 CI/CD 管道的容器。它提供了与版本控制资源(如代码仓库和与 Azure 及 Azure 机器学习工作区的连接)一起工作的有用抽象,并允许您协作访问运行器、管道和构建工件。

重要提示

Azure DevOps指的是通过dev.azure.com/可访问的托管 Azure DevOps 服务。还存在一个名为Azure DevOps Server(以前称为 Visual Studio Team Foundation ServerTFS))的本地提供方案,它提供了类似的 CI/CD 集成功能。

作为第一步,我们将设置 Azure DevOps 工作区,以便我们可以编写和执行 Azure MLOps 管道。让我们从设置组织和项目开始。

组织和项目

首先,您需要设置您的组织。组织是一个用于管理类似项目并与一组人协作的工作区。您可以通过使用 Microsoft 账户、GitHub 账户或连接到Azure Active DirectoryAAD)来创建组织。要创建组织,您需要登录到 Azure DevOps(dev.azure.com/),提供您组织的 slug 名称,并选择一个区域来托管您组织资产。

以下图显示了创建新的 Azure DevOps 组织的屏幕:

图 16.1 – 创建新的 Azure DevOps 组织

图 16.1 – 创建新的 Azure DevOps 组织

接下来,您可以在组织中设置项目;我们将从一个包含运行 MLOps 管道的配置和代码的项目开始。项目是一个用于逻辑分组特定 ML 项目所有资产的地方。您将能够在 Azure DevOps 项目中管理您的代码仓库、冲刺板、问题、PR、构建工件、测试计划和 CI/CD 管道。

以下图显示了创建新的 Azure DevOps 项目的流程。这将作为我们的管道、测试和部署配置的容器:

图 16.2 – 创建新的 Azure DevOps 项目

图 16.2 – 创建新的 Azure DevOps 项目

一旦我们设置了组织和项目,我们需要通过安装适当的 Azure DevOps 扩展将 Azure 机器学习功能添加到 Azure DevOps 中。

Azure 机器学习扩展

接下来,建议为您的 Azure DevOps 组织安装 Azure 机器学习扩展。这将紧密集成您的 Azure 机器学习工作区到 Azure DevOps 中,以便您可以在 Azure DevOps 内执行以下操作:

  1. 通过 Azure 资源管理器自动分配访问您的 Azure 机器学习工作区资源的自动权限。

  2. 触发新模型修订的发布管道。

  3. 将 Azure 机器学习管道作为任务运行。

  4. 设置模型部署和模型分析预配置任务。

公平地说,所有上述内容也可以通过使用自定义凭据和 Azure ML Python SDK 手动设置,但紧密集成使得设置变得更加容易。

重要提示

你可以从 marketplace.visualstudio.com/items?itemName=ms-air-aiagility.vss-services-azureml 安装 Azure Machine Learning 扩展到 Azure DevOps。

接下来,我们将使用扩展来设置服务连接和你的 Azure 及 Azure Machine Learning 工作区账户的访问权限。

服务连接

你可能还记得从之前的代码示例中,与 Azure 和 Azure Machine Learning 资源交互需要配置适当的权限、租户和订阅。访问这些服务和资源的权限通常通过 服务主体 定义。在 Azure DevOps 中,我们可以设置我们的 Azure DevOps 管道访问 Azure 和 Azure Machine Learning 资源、创建计算资源以及通过 服务连接 提交 ML 实验的权限。

在你的 Azure DevOps 项目中,转到 设置 | 服务连接 并配置一个新的 Azure 服务连接,使用服务主体身份验证你的 Azure Machine Learning 工作区。以下图显示了如何在 Azure DevOps 中设置此连接:

图 16.3 – 创建 Azure DevOps 服务连接

图 16.3 – 创建 Azure DevOps 服务连接

同样,你也可以允许 Azure DevOps 管道以编程方式管理 Azure 资源组中的资源。建议你通过服务主体创建这两种权限,并注意新创建的连接的名称。

密钥

在下一步中,我们希望将所有变量和凭证存储和管理在实际的 CI/CD 管道之外。我们不希望将凭证或配置参数(如订阅 ID、工作区名称和租户 ID)嵌入到管道中,而是将它们作为参数传递给正在运行的管道。

在 Azure DevOps 中,你可以通过使用 变量组安全文件 来实现这一点。你甚至可以将变量组连接到 Azure Key Vault 实例来为你管理密钥。

建议你导航到 管道 | 来设置一个包含你的订阅 ID、租户 ID、服务连接名称等作为变量的变量组,以便它们可以在管道中重复使用。如果你需要,你总是可以稍后回来添加更多变量。以下图显示了可以包含在你的管道中的示例变量组定义:

图 16.4 – 创建 Azure DevOps 变量组

图 16.4 – 创建 Azure DevOps 变量组

接下来,我们将设置一个仓库并编写代码管道。

代理和代理池

你的 CI 和 CD 任务最终将检出项目,构建它,训练模型,运行测试,并部署它。为了完成所有这些(以及更多),你需要一个计算基础设施来运行 CI/CD 作业。在 Azure DevOps 中,这些计算资源被称为 代理

Azure DevOps 服务提供 Microsoft 托管代理,这些代理将在 VM 或 Docker 镜像中执行你的管道作业。这两种计算资源都是临时的,并在每个管道作业后拆除。

当使用 Azure DevOps 与公共项目时,Azure Pipelines 是免费的,并为你的 CI/CD 管道作业提供 Microsoft 托管代理。这允许你运行最多 10 个并行作业,每个作业最多运行 6 小时。对于私有项目,你每月最多只能运行一个并行作业,每个作业最多运行 1 小时。

重要提示

为了防止滥用,所有免费管道资源都需要通过此表单请求组织:aka.ms/azpipelines-parallelism-request

如果需要更多容量,我们可以通过 Azure DevOps Server 和/或 Azure VM 规模集代理运行自托管代理,或者通过 Azure DevOps 服务购买额外的 Microsoft 托管代理。为了本书的目的,你应该能够利用私有仓库上的免费容量舒适地进行实验。

持续集成 – 使用管道构建代码

现在,我们可以开始使用 Azure DevOps 管道设置我们的 ML 模型的自动构建、测试和训练管道。从概念上讲,我们将在 Azure DevOps 中创建或导入一个 Git 仓库,作为我们的 ML 项目的容器,并将包含 CI 管道定义。按照惯例,我们将管道存储在 .pipeline/ 目录中。

下图展示了如何在 Azure DevOps 中设置或导入一个仓库:

图 16.5 – 克隆或导入仓库

图 16.5 – 克隆或导入仓库

接下来,我们打开 Visual Studio Code 并开始编写我们的管道。我们不会从小部件和插件中构建 CI 管道,而是选择 YAML 来编写管道代码。这与 GitHub CI 或 Jenkins 工作流程的编写方式非常相似。

管道包含一系列线性任务,用于构建、测试和训练 ML 模型,这些任务可以通过仓库中的条件触发。在 Azure DevOps 管道中,任务按以下层次结构组织:

  • 阶段 A:

    • 作业 1:

      • 步骤 1.1

      • 步骤 1.2

    • 作业 2:

      • 步骤 2.1

因此,一个管道由阶段组成,其中每个阶段包含多个作业。每个作业可以包含多个称为步骤的任务。除了阶段和作业之外,管道还可以包含以下部分:

  • 管道定义:

    • name:管道的名称
  • 管道触发器:

    • schedules:基于计划的管道触发配置

    • trigger:基于代码的管道触发配置

    • pr:基于 PR 的管道触发配置

  • 管道计算资源:

    • resources: 容器和存储库配置

    • pool: 管道计算资源的代理池配置

  • 管道定制:

    • variables: 管道变量

    • parameters: 管道参数

  • 管道作业定义:

    • stages: 管道作业的分组,如果管道只有一个阶段,则可以跳过

    • jobs: 要执行的管道作业

如前所述的列表所示,Azure DevOps 管道 YAML 方案允许您自定义管道触发器、计算资源、变量和配置,并允许您定义管道中要运行的作业。Azure DevOps 管道还理解模板的概念。您可以使用 template 指令为阶段、管道、作业、步骤、参数和变量引用模板中的文件。

重要提示

您可以在微软文档中找到管道 YAML 方案的文档,网址为 docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/.

让我们使用这些步骤定义来构建一个简单的管道,以测试模型代码并开始模型训练:

ci-pipeline.yaml

trigger:
- main
pool: 
  vmImage: ubuntu-latest
stages:
- stage: CI
  jobs:
  - job: Build
    steps:
    - script: pytest tests --doctest-modules
- stage: Train
  jobs:
  - job: Train
    steps:
    - script: python train.py

在前面的管道中,我们定义了触发器,当 main 分支上有新提交时启动管道。对于执行,我们使用 Ubuntu VM 在微软托管的免费代理池上运行每个作业。然后,我们将任务分为两个阶段:CITrain。前者将构建和测试代码及数据集,而后者将训练机器学习模型并在模型注册表中创建模型的新版本。

现在,我们可以在存储库中添加一个提交并将其合并到 main 分支,CI 管道将被触发并训练一个新的模型版本。您可以使用前面的管道定义作为起点,添加额外的步骤、测试、配置和触发器,以完全定制您的 CI 管道。

重要提示

您可以在微软 GitHub 存储库中找到最新的 MLOps 管道示例,网址为 github.com/microsoft/MLOpsPython

您可以在 Azure MLOps 存储库中找到更多 MLOps 起始点的示例 github.com/Azure/mlops-v2

接下来,我们将查看一个 CD 管道,以将训练好的模型部署到生产环境中。

持续部署 - 使用发布管道部署模型

在模型注册库(例如 Azure 机器学习)中跟踪模型工件(例如,新机器学习模型或版本)的另一个好处是,当工件发生变化时,您可以在 Azure DevOps 中自动触发发布管道。任何工件,如新的机器学习模型或版本,都可以配置为在 Azure DevOps 中触发发布。因此,代码更改触发 CI 构建管道,而工件更改触发 CD 发布管道。在本节中,我们将为我们的模型创建一个 CD 管道,并自动将模型推出到预发布和生产环境。

尽管发布管道的触发机制与构建管道不同,但大多数关于管道执行的概念都非常相似。发布管道也有管道阶段,而每个阶段可以有多个任务。发布管道的一个额外功能是,由于它们处理工件部署,因此每个阶段可以具有额外的触发器,以及部署前部署后条件,例如手动批准门控

触发器将允许您在指定的计划期间继续管道执行。手动批准将使管道暂停,直到被定义的用户或用户组批准,而门控将使管道在执行程序性检查之前暂停预定义的时间。通常将多个阶段、触发器以及部署前和部署后的条件结合起来,以安全地将工件部署到不同的环境。

如果您已安装 Azure Machine Learning 插件,您可以选择专门针对 Azure Machine Learning 的触发器和部署任务,例如基于 ML 模型版本的工件和 Azure Machine Learning 模型部署和性能分析任务。在本节中,我们将选择 ML 模型工件触发器和 ML 模型部署任务。

重要提示

您可以在 Microsoft 文档中找到可用的 Azure DevOps 任务,网址为docs.microsoft.com/en-us/azure/devops/pipelines/tasks/

下图显示了 Azure DevOps 发布管道,其中我们选择一个机器学习模型作为发布管道触发的工件。我们配置了两个阶段,一个是部署到预发布环境,另一个是部署到生产环境。此外,我们还添加了一个手动批准作为预发布部署的部署后条件:

图 16.6 – 定义 Azure DevOps 发布管道

图 16.6 – 定义 Azure DevOps 发布管道

默认情况下,发布管道将要求用户通过在右上角点击创建发布按钮来创建发布。这种模式旨在仅在操作员决定触发部署时创建发布,并有助于我们在配置发布管道时避免任何自动化部署。然而,一旦操作员确信管道和发布过程按预期工作,我们可以通过切换发布管道中资产上的闪光图标来启用自动化部署。这将启用 CD 触发器,因此,每当资产发生变化时,都会触发发布和部署。在本章的最后一个任务中,您可以继续激活 CD 触发器,以完全自动化您的 CD 管道。

摘要

在本章中,我们介绍了 MLOps,这是一种类似于 DevOps 的工作流程,用于开发、部署和操作机器学习服务。DevOps 代表了一种快速且高质量地更改代码并将这些更改部署到生产环境的方法。

我们首先了解到 Azure DevOps 提供了所有功能来运行强大的 CI/CD 流水线。我们可以运行构建流水线,其中步骤用 YAML 编码,或者发布流水线,它们在 UI 中进行配置。发布流水线可以有手动或多个自动触发器(例如,版本控制仓库中的提交或如果模型注册表的工件已更新)并为发布或部署创建输出工件。

版本控制您的代码是必要的,但仅此不足以运行适当的 CI/CD 流水线。为了创建可重复构建,我们需要确保数据集也进行了版本控制,并且伪随机生成器使用指定的参数进行初始化。环境和基础设施也应自动化,部署可以从创作环境进行。

为了保持代码质量高,您需要将测试添加到机器学习流水线中。在应用程序开发中,我们区分单元测试、集成测试和端到端测试,它们测试代码的不同部分,要么独立进行,要么与其他服务一起进行。对于数据流水线,如果数据发生变化或增加,单元测试应测试数据质量以及应用程序中的代码单元。集成测试非常适合独立于其他组件加载模型或执行正向或反向传递。使用 Azure Machine Learning,编写端到端测试变得非常愉快,因为它们可以非常低效和低成本地完全自动化。

现在,您已经学会了如何设置连续流水线,这些流水线可以重新训练和优化您的模型,然后自动构建和重新部署模型到生产环境中。在最后一章中,我们将探讨您、您的公司以及您在 Azure 中的 ML 服务下一步将是什么。

第十七章:第十七章:为成功的 ML 之旅做好准备

恭喜你,你已经成功了——你经历了多么不可思议的旅程!到现在,你应该已经学会了如何在云中预处理数据,实验ML模型,在自动扩展集群上训练深度学习模型和推荐引擎,优化模型,并将它们部署到你想要的地方。你应该知道如何通过MLOps将这些步骤操作化,为蛋糕增添一抹亮色。

在最后一章,我们将回顾我们在这次旅程中学到的一些重要启示。很容易在技术和算法选择中迷失或感到不知所措。你可能会深入研究建模、基础设施或监控,但可能离拥有一个好的预测模型更远。

在第一部分,我们将提醒你,ML 主要关于数据。人工智能可能应该被称为数据清洗和标注,但当然,这听起来没有 AI 那么好。你会明白你的数据是出色性能的关键,所以你最应该关心的是这个。你的数据就是一切!

在接下来的部分,我们将向你展示如何开始你的 ML 项目。我们将通过提供一些指导并强调干净的基础设施和深思熟虑的监控的重要性来实现这一点。

之后,我们将重申自动化的重要性以及新技术将如何带我们进一步进入机器学习即服务MLaaS)的世界。了解技术的发展方向总是很好的,在机器学习的情况下,它是元学习和系统,它们已经自动建议合适的模型并将它们堆叠起来以实现良好的预测性能。当建模完全自动化时,剩下的是什么?正是——你的数据!

在此之后,我们将讨论云服务的持续变化和演变,同时关注 PaaS 服务。我们将探讨为什么 PaaS 解决方案被构建以及它们的基石是什么。这将帮助你了解如何最好地准备应对变化,以及为什么尽管服务不断变化,你仍然在正确的基石上押注。

最后,我们将讨论在这本书中我们主要忽略的一个主题。我们将讨论在开始任何 ML 项目之前你应该思考的一些问题:你应该这样做吗?你模型的成果会对人们的生活产生严重影响吗?你可能已经猜到了:我们将从数据处理的角度讨论伦理。在一个越来越互联的世界中,你不应该滥用他人的个人信息,你不应该构建对某些群体极端有偏见的模型,你不应该通过你的部署解决方案负面地影响人们的生活。

本章将涵盖以下主题:

  • 记住数据的重要性

  • 从一个深思熟虑的基础设施开始

  • 自动化重复性任务

  • 预期持续变化

  • 思考你的责任

记住数据的重要性

许多用于预测和模型拟合的算法问题难以使用经典优化算法或复杂启发式方法进行建模、计算和优化。监督式机器学习提供了一种利用优化和大量标记训练数据解决最复杂问题的强大新方法。

有些人可能认为你只需将大量数据扔给模型。想象一下,你有成千上万张同一只鸟从每个可能角度的照片。基于这些照片训练的模型可能对分类不同的鸟类家族的预测并不具有很高的预测性。

为你的模型选择合适的数据样本

当模型使用高度独特的数据样本和对你模型应预测的上下文有用的数据样本时,其质量会提高。

因此,当你使用机器学习算法工作时,你需要记住,模型是由你提供给它们的训练数据和训练标签驱动的。好的数据是良好性能的关键。

了解这一点,让我们再次强调在处理数据和训练机器学习模型时的关键要点:

  • 大部分时间用于处理数据:正如我们在本书开头讨论的那样,在大多数机器学习项目中,你将花费大约 80%的时间进行数据分析、预处理和特征工程。彻底理解你的数据对于开发成功的预测模型至关重要。这样想:使你与众不同的唯一东西就是你的数据。很可能,你的竞争对手可以访问与你类似的算法、优化和计算基础设施。他们唯一没有的是你的数据和你的技能来分析这些数据(希望如此)。因此,这就是你成功的关键所在:在解释、清理、建模和准备你的数据以进行高质量预测。

  • 强调特征工程:你获得的最大机会是提高任何模型的基础预测性能,这可以通过改进你的基础数据集,通过更好的特征工程或添加更多预测性特征来实现。不要迷失在尝试调整和堆叠模型的过程中。相反,你应该把大部分的时间和资源投入到数据预处理和特征工程中。特征工程是你可以发光和赢得预测游戏的地方。你正在处理日期吗?引入其他数据源,例如当地和全球的节假日以及附近的事件;添加相对日期,例如节假日前的天数,周末前的天数等等。你正在处理位置、城市或国家吗?在这里,你应该引入人口统计数据、政治数据或地理数据。你明白这个意思。

  • 不要被模型调优分散注意力:你的模型能做的事情是有限的。是的,你可以堆叠多个模型,调整和优化它们,针对不同的指标进行优化,等等。然而,你的最大优势是你的数据。任何机器学习模型的好计划都是从一个非常简单的基础模型开始。你是在处理分类数据吗?如果是这样,选择梯度提升树集成,并坚持默认参数。你是在预测连续值吗?如果是这样,选择逻辑回归模型。从小处着手,确保你在开始调整模型之前,你的数据是正确的。

  • 始终从基础模型开始:使用基础模型,并围绕它构建所有自动化、基础设施和指标。值得注意的是,基础模型应该比随机方法表现更好。一旦管道完成,你就可以深入数据,添加新数据,进行更好的特征工程,再次部署,测试,并重新迭代。将你的模型简化为原始的基础模型是一个困难的步骤,但它将帮助你成功管理项目第一阶段的工作重点。为什么基础模型方法如此重要?因为它为迭代项目设定了你的心态,在这个项目中,你不断地测量、添加数据、重新训练并改进你的模型。你的模型将需要重新训练,你需要测量何时需要这样做。为了重新训练,你需要新的训练数据。

  • 持续收集新的、相关的数据样本:在一个完美的设置中,你会安装一个持续的数据收集管道,直接从你的当前产品中收集新的训练数据和训练标签。你的模型预测搜索相关性吗?收集搜索查询和点击结果。你的模型预测欺诈吗?收集新的数据和手动验证的欺诈案例的结果。你的模型预测标签吗?跟踪预测,并让用户在它们不准确时更改它们。在这些所有例子中,我们持续跟踪相关的训练数据,我们可以用这些数据不断重新训练和微调。拥有这种持续的训练数据流可能是你业务的竞争优势,让你为成功做好准备。因此,当你监督一个机器学习项目时,考虑你将如何在未来重新训练模型。

除了遵循这些技术规则来处理机器学习项目外,了解你公司的业务方面至关重要。这样的项目通常需要一个跨学科团队才能成功。因此,获得公司数据策略的 C 级支持至关重要。数据是你的燃料,它通常以大量数据孤岛的形式分散在公司的各个部门。你可能需要访问大量这些来源来实现和改进机器学习模型,因此,拥有访问和使用这些数据的权限至关重要。

这通常需要大多数公司进行思维上的转变,因为来自不同部门的数据需要结合和分析,以便用于预测。因此,数据质量很重要,数据来源很重要,这样你才能了解它来自哪里,及时性很重要,正确性是必不可少的。所以,确保数据在你的公司中得到应有的支持、关爱和照顾。

现在我们已经重申了关于数据处理的重要事实,让我们谈谈你正在工作的环境。

从一个深思熟虑的基础设施开始

成功应用的机器学习项目依赖于迭代的方法来处理数据收集、数据清洗、特征工程和建模。在成功部署和推广后,你应该回到起点,关注你的指标,并收集更多数据。现在应该很清楚,你将在机器学习项目的生命周期中重复一些开发和部署步骤。

从一开始就正确设置你的机器学习项目的基础设施和环境将为你节省很多麻烦。成功基础设施的一个关键在于自动化和版本控制,正如我们在上一章中讨论的那样。因此,我们建议你花几天时间来设置你的基础设施和自动化,并在 Azure 机器学习中注册你的数据集、模型和环境。

这同样适用于监控。为了做出明智的决定,比如你的模型是否按预期工作,训练数据是否仍然准确,或者资源利用率是否足够高,你需要准确的指标。在部署后添加指标相当棘手。因此,你应该事先了解你想要衡量什么,以及你想要提前被提醒什么。在你的项目开始时,花些额外的时间思考你将要跟踪的指标。

最后,在处理数据和模型的同时优先考虑基础设施是困难的。如果你能承担将它们分成单独的团队进行机器学习基础设施、建模和数据工作的奢侈,那么这可能不是你首要考虑的事情。然而,这种情况通常并不存在。为了避免这种优先级问题,我们建议从简单的基线模型开始,并基于这个简单的模型定义你的基础设施自动化。

让我们看看当你开始你的机器学习项目时应该执行哪些步骤:

  1. 选择一个基线模型:为你的用例选择具有默认参数的最简单模型,一小部分训练数据以及最重要的工程特征。

  2. 构建一个简单的流水线:将这些模型训练步骤放入一个流水线中,自动构建你的模型并将其部署到预发布环境中。这种方法的优点在于你自动优先考虑基础设施,并且始终输出一个已部署的评分服务。这将为你成功奠定基础。

  3. 深入数据:确保你理解数据及其质量,如何填充缺失值,以及如何预处理特征。你可以添加额外的数据,并从事特征工程,将你的原始输入数据转换为可解释的数据。如果你选择了一个好的基线模型,这项工作应该会极大地提高基线模型的性能,并给你的同事提供一个评分服务 API,以便与新的服务一起使用。

  4. 实验更复杂的模型:一旦你确信你已经建立了一个稳固的数据管道,你就可以着手建模,包括模型选择、训练、验证、优化和堆叠。再次强调,你应该能够看到可以衡量并持续部署到任何 QA 环境中的渐进式改进。一旦你的性能足够好,就可以将服务推广给你的客户,并开始收集指标和更多训练数据。

  5. 监控云使用:当你使用云中的计算基础设施进行开发时,很容易迅速花费几千美元用于一些未使用或利用率低的虚拟机。我们建议你定期检查机器的数量及其利用率。如果某些东西不再被使用,就进行扩展或关闭。请记住,云的最大好处是可扩展的基础设施。所以,请充分利用它。

遵循这些指导原则将帮助你建立一个干净且可监控的基础设施,你可以在这个过程中不断演进。

现在我们已经讨论了你应该设置的基础设施,让我们再次谈谈自动化。

自动化重复性任务

训练机器学习模型是一个复杂且迭代的流程,包括数据准备、特征工程、模型选择、优化和部署。最重要的是,一个企业级的端到端机器学习管道需要是可重复的、可解释的、安全的和自动化的,这对大多数公司来说在知识、成本和基础设施要求方面都提出了额外的挑战。

在前面的章节中,我们学习了这个过程的方方面面,因此我们可以确认它没有什么是简单或容易的。调整特征工程方法会影响模型训练;数据清洗过程中的缺失值策略将影响优化过程。

首先,你的模型所捕获的信息很少是恒定的,因此大多数机器学习模型都需要频繁的重训练和部署。这导致了对 MLOps 的新要求:一个用于机器学习的 DevOps 管道,以确保数据的持续集成和持续部署。

自动化机器学习通过自动化许多这些挑战来简化这个复杂且迭代的流程。而不是手动调整输入数据,然后手动选择、优化和部署机器学习模型,自动化服务只需要输入数据,以及一些与业务相关的配置,例如要训练的预测类型。

因此,使用 Azure DevOps 和 Azure 机器学习管道等工具可以大大减少错误和系统停机时间,并使用户从执行大量手动任务中解放出来。此外,Azure 自动机器学习等服务允许用户优化机器学习训练,甚至堆叠多个模型以提高预测性能。最大的好处是用户可以专注于机器学习过程最重要的部分:理解、获取和清理数据。

在许多情况下,自动机器学习服务将优于手动训练的模型,同时显著降低训练和运营成本。原因在于许多任务,如选择正确的分类嵌入、处理不平衡数据、选择最佳模型、找到最佳参数以及结合多个模型以提高性能,可以系统地优化,而不是手动选择。

每个主要的云服务提供商都提供成熟的服务,以便您可以在云中执行自动机器学习,并方便地部署这些模型。自动机器学习是一种节省时间和成本的同时,为现有员工提供训练复杂端到端机器学习管道所需工具的绝佳方式。这使得自动机器学习成为一种真正的服务——机器学习即服务(MLaaS)。

谈到工具,让我们谈谈当您使用现代云系统时需要跟上的一些变化。

期待持续变化

一切都处于持续变化的状态。15 年前,只有少数人听说过神经网络和机器学习。今天,您可以访问大量的机器学习库、程序和云服务。每天,都在取得新的进展,以自动化机器学习任务并改进机器学习建模。只需想想您可能使用的语音助手以及自动驾驶汽车正在发生的事情。

由于这个原因,您将面临对机器学习库及其工具进行的大量持续变化。这在云环境中尤其如此,与许可软件相比,更新可以快速推送到用户群体。正如我们之前所学的,查看大型云服务提供商,他们的服务通常可以分为以下几类:

  • 基础设施即服务IaaS):IaaS 服务是所有基础设施抽象,如虚拟机(计算)、磁盘(存储)和网络。

  • 平台即服务PaaS):PaaS 服务是在这些组件之上构建的平台,具有额外的功能,可以暴露服务同时隐藏底层基础设施和操作系统。

  • 软件即服务SaaS):与 PaaS 服务相反,SaaS 服务通过用户界面暴露,不提供对底层软件和硬件堆栈的任何访问。

Azure 机器学习是一个很好的 PaaS 服务的例子,因为它结合了不同的基础设施服务、UI 和 SDK,为你提供了全新的功能,并提供了对底层服务的完全访问,例如 blob 存储、训练集群和容器注册表,而在大多数情况下,操作系统则被置于幕后。在你的每月 Azure 账单上,你会发现当你使用 PaaS 解决方案时,你大部分的钱都花在了基础设施服务上。

虽然底层基础设施为所有云服务奠定了基础,但它们在接下来的几年内不太可能发生剧烈变化。新的改进将进入市场,通常集中在吞吐量水平和网络安全上。尽管如此,你不应该期望对现有 API 进行重大更改。此外,这些服务不太可能被终止,因为它们是许多服务的基石。

对于 PaaS 服务来说,情况并非如此。它们被设计用来回答客户关于抽象解决方案的需求,这样他们就可以免于编写大量的样板代码和处理解决方案的低级基础设施细节。你有多少次看到 Azure 机器学习的一个功能,心想,“嘿,我完全可以自己实现这个功能”?这当然是对的,但你可能希望有人帮你解决这个简单的问题,这样你就可以专注于你试图解决的复杂问题。这就是 PaaS 最初存在的原因。

然而,客户驱动的需求带来的不利之处在于,这些需求和用法模式始终在不断发展。新的用例(如 MLOps)不断出现,需要支持新的服务或对现有服务的扩展。因此,你应该始终期待 PaaS 会随着时间的推移而变化。

如果你查看这本书的第一版,你会发现其中近一半的代码和功能要么已经弃用,要么被新的东西所取代,或者与 Azure 机器学习服务的其他部分合并。根据你阅读这本书的时间,你可能已经发现我们在这里描述的功能或 API 与 Azure 当前 API 和功能之间存在差异。

如果你感到困惑是可以理解的,并问自己这本书怎么会已经过时了,我们想向你保证,我们展示的是正确的技术,值得下注。PaaS 服务总体上,以及 MLaaS 服务具体来说,总是在经历巨大的变化和改进。期待变化!

让我们看看你可能随着时间的推移会遇到的一些可能的变更:

  • 预期名称会发生变化:这可能是最常见的变更。公司通常在命名产品方面做得不好,Azure 和其他所有云服务提供商也不例外。这可能看起来像是一个很大的变化或不便,但实际上只是更改服务或组件的名称,或者将其隐藏在云平台的其他地方。在过去的几年里,针对 Azure 的机器学习(ML)进行了许多变更。曾经有一个名为Azure Machine Learning Studio (classic)的服务,它主要作为 Azure 机器学习中的Designer存在。曾经有,现在仍然有名为Azure BatchAzure BatchAIAML Compute的服务,它们提供了与您现在在 Azure 机器学习中找到的批推理计算集群大致相同的功能。简单来说,不要让自己被这些变化分散注意力。预期会出现一些有趣的新名称,用于您所熟悉和喜爱的功能。

  • 预期 UI 会发生变化:这是最明显的变化,在最近的云服务中相当常见。许多服务都得到了全新的 UI,一些被整合到 Azure UI 中,还有一些被放置在单独的应用程序中。预期某些功能可能只在一个 UI 中暴露,而在另一个 UI 中则不暴露。然而,通常情况下,新的 UI 意味着相同或类似的功能可以通过新的界面访问。这也是我们为什么训练你更多地使用 Python API 或 Azure CLI 而不是图形界面工作的原因之一。

  • 预期 SDK 中的类和包会发生变化:大多数云服务提供商的机器学习解决方案的 API 都在不断演变。Azure 在它的机器学习服务上投入了大量的资金,因此变化是不可避免的。为应对这种变化,一个很好的做法是将代码抽象成特定的实现,这样就可以轻松地用新功能替换。另一个好的做法是对库更新保持谨慎,但也不要落后于最新版本太久。

你是否同意,在这些情况下,变化是唯一的不变因素?请记住,所有 PaaS 解决方案最终都是建立在底层基础设施之上的,这为你的计算、存储和网络提供了坚实的基础。

因此,请记住:尽管变化不断,你是在正确的基石上构建!

在讨论了在使用云平台进行机器学习时应考虑的大部分内容之后,让我们谈谈一个更加重要的话题:数据伦理。

考虑到你的责任

在本书的最后一节,我们想要从模型、部署和优化中退一步,来谈谈一个更加重要的主题:处理数据时的伦理,或者今天所知的负责任的 AI/ML

第一章《理解端到端机器学习过程》中,我们讨论了数据中的偏差,它如何有意或无意地被引入数据集中,以及你需要注意什么。这只是反映你如何收集数据以及你的训练模型如何对他人生活产生负面影响的一个小小拼图。

想象一下,你正在训练一个机器学习模型,建议银行柜员允许面前的客户获得贷款,以及客户可以获得的贷款利率。使用自动化系统做出这个决定可能是一种祝福或诅咒。如果公司的大多数银行柜员存在固有的偏差,而你构建了一个公平的模型,那么这可能会是一种祝福。然而,如果你的模型基于那些银行柜员的先前决策,你必须密切关注你的数据中的大量偏差。如果不这样做,你可能会创造一个更加不公平的世界,因为现在,你的机器学习系统负责。一个公平的柜员发放贷款,即使他们可能了解你的机器学习系统中存在偏差,现在可能也不允许他们推翻它。

虽然有比这更糟糕的例子,但这应该能给你一个很好的概念,了解我们想要讨论的内容。

一般而言,我们可以将你的责任分为以下几类:

  • 可解释性:你如何解释你的模型及其生成的结果?

  • 公平性:你如何通过消除数据中的偏差来确保公平性?

  • 隐私:在你的基础数据和模型中,个人的可识别信息PII)得到了多好的保护?谁可以访问它?

  • 合规性:你所使用和可以访问的每一件事物都有多好的文档记录?你是如何追踪谁在使用你的数据或模型的?

让我们更详细地看看你需要注意的事项,以及 Azure 机器学习提供的哪些工具可以帮助你在进行这项工作时得到支持。

解释模型

任何部署的机器学习模型都是一个黑盒。我们通过模型发送输入并接收以预测或分类形式呈现的输出。因此,利益相关者很难理解为什么系统会做出某些决策以及为什么不会。为了缓解这种情况,你可以应用新的工具来解释你的模型。

但在我们讨论解释机器学习模型的工具和方法之前,让我们将模型分为两类:

  • 黑盒模型:计算如此复杂,以至于我们不知道决策是如何形成的。

  • 玻璃箱模型:结果可以相对容易地解释和计算的模型。例如,考虑线性回归模型。

玻璃盒模型通常更简单,所以权衡似乎是在可解释性和复杂性(因此,可能是准确性)之间。但如果您的模型处理大量个人信息,您将想知道模型是如何得出结论的。

因此,出现了对黑盒模型进行解释的需求,这种解释器被称为黑盒解释器。以下是最为知名的两种解释器:

  • Shapley 增量解释SHAP):这是一种将博弈论应用于机器学习模型的方法,主要用于可解释性。这个方法族假设模型中的每个特征都是一个游戏中的玩家。基于这个假设,您可以使用所谓的Shapley 值来计算特征值对预测的平均贡献。简单来说,这是通过向联盟中添加和删除特征来完成的,在博弈论中,联盟是合作的一组玩家。SHAP 可以用于任何类型的模型,但它对线性回归、树、集成树以及使用 TensorFlow 或 Keras 的深度学习有很好的定义。此外,它还可以解释单个预测,而不仅仅是全局层面的解释。您可以在其开源版本中了解更多关于 SHAP 的信息(github.com/slundberg/shap)。

  • 局部可解释模型无关解释LIME):这是一种创建所谓的代理玻璃盒模型的方法,基于任何黑盒分类器模型。代理模型试图模仿底层模型的行为,同时降低其复杂性。这是通过在特定实例附近训练一个线性模型来实现的。用户可以查看这个新创建的玻璃盒模型,以了解黑盒模型对这个邻域或预测子集的输出。因此,LIME 可以解释黑盒模型的单个预测。您可以在其开源版本中了解更多关于 LIME 的信息(github.com/marcotcr/lime)。

这些是您可以用来解释黑盒模型的技术。为了稍微缓解玻璃盒模型的情况,微软研究院正在开发一个名为可解释提升机EBM)的机器学习模型,它在准确度上与梯度提升相当,同时仍然完全可解释。他们的原始论文可以在arxiv.org/abs/2106.09680找到。

要尝试这些解释器,您可以直接在项目中使用这些包,或者您可以使用来自 Azure ML SDK 的azureml-interpret包(docs.microsoft.com/en-us/python/api/azureml-interpret)。这个包为您提供了访问Interpret Community SDK(github.com/interpretml/interpret-community)的权限。您可以阅读该包上可用的解释器。

如果你想尝试一下,可以查看以下指南:docs.microsoft.com/en-us/azure/machine-learning/how-to-machine-learning-interpretability-aml。当你在这本书的所有动手练习中查看 Azure Machine Learning 工作室页面时,你可能已经注意到训练运行和模型中有一个名为解释的标签。当你使用这个包时,你可以将解释器的结果添加到训练运行中,并在之后在线查看视觉效果。

想要进一步阅读,可以查看InterpretML项目(interpret.ml/docs/intro.html),该项目提供了不同类型解释器的概述。

现在我们已经了解了如何解释我们模型的结果,让我们来看看公平性。

模型训练中的公平性

分析模型公平性的主要工具之一称为Fairlearn(fairlearn.org/)。为了定义模型是否公平,Fairlearn 包中的算法和指标寻找两种可能造成的损害,如下所示:

  • 分配损害:一个保留机会、资源或信息的模型或系统。这符合我们之前的例子,其中我们讨论了一个 ML 系统向个人发放贷款。

  • 服务质量损害:一个不保留任何东西但对待不同群体行为不同的模型或系统。

为了评估给定模型的公平性,使用了两种结构,评估指标和缓解算法。这些可以按以下方式分类:

  • 评估指标:可以通过比较多个模型为单个模型计算指标,也可以为通过缓解算法创建的模型计算指标。它们包括从计算模型召回率等简单指标到添加分组信息以分析模型结果。更多信息请参阅fairlearn.org/main/user_guide/assessment.html

  • 减少算法:这些算法在评估后从重新加权的训练数据集中构建一个新的标准黑盒模型。用户可以通过不同的模型运行来调整,以找到准确性和公平性之间的最佳权衡。更多信息请参阅fairlearn.org/main/user_guide/mitigation.html#reductions

  • 后处理算法:这些算法将原始模型和敏感特征结合起来计算应用于模型预测的转换。通过这个过程,我们避免了重新训练原始模型。

请注意,像 Fairlearn 这样的包仍在开发中。由于决定公平性不是一个简单的话题,不要仅依赖于这样的工具。当你思考可以引入的类型偏见时,要反思你所做的事情,并使用这些工具来获得更多见解。Fairlearn 的开发者指出了以下几点:

“公平性本质上是一个社会技术挑战。许多关于公平性的方面,如正义和正当程序,都无法通过定量公平指标来捕捉。此外,还有许多定量公平指标无法同时满足。我们的目标是使人类能够评估不同的缓解策略,并根据他们的场景做出适当的权衡。”

有关如何使用 Fairlearn 包与 Azure 机器学习结合使用以及如何上传您的结果的指南,请访问docs.microsoft.com/en-us/azure/machine-learning/how-to-machine-learning-fairness-aml

最后,让我们学习如何使用 Azure 机器学习处理隐私和合规性。

处理 PII 数据和合规要求

随着欧洲的通用数据保护条例GDPR)和加州的加州消费者隐私法案CCPA)等立法的出台,企业现在处于困境。除了有明确的指导说明如何利用 PII 数据外,他们通常还要求存储涉及此数据的任何行动的审计跟踪,从用户到访问此数据的公司员工。

因此,拥有支持这一努力的工具非常重要。大多数 Azure 服务都设有安全措施来应对外部入侵者并构建多租户应用程序,帮助客户避免看到他人的 PII 数据。然而,在大多数组织中,系统管理员通常可以访问这些明文数据。对于构建机器学习模型的人来说也是如此。此外,Azure 上的数据库通常可以记录任何访问并建立审计跟踪以供审查。但机器学习建模管道或部署管道又如何呢?谁能在什么形式和什么时间点看到数据?

所有这些问题都需要得到解答。让我们看看一些可用的工具和在这个领域正在进行的研究:

请密切关注这些主题的发展,因为未能遵守这些法规可能会产生严重的后果。

正如你所见,我们在这个章节中讨论的所有包都还处于 alpha 或 beta 阶段,因为可解释性、公平性和隐私性在机器学习背景下相对较新。在过去十年中,机器学习更多的是一个研究课题,而不是实际的生产环境。如今,基于机器学习的解决方案已经融入了我们的日常生活。因此,我们需要退一步,开始思考我们是否可以不质疑其有效性就让机器为我们做决定。

因此,当你运行下一个注定要投入生产的 ML 项目时,将这些话题带入讨论,因为它们需要从一开始就得到处理。

摘要

在这一章中,我们通过涵盖数据、基础设施、监控、自动化、变更管理和伦理等方面,从更高的层次审视了一些内容。我们希望你在阅读这本书后,对这些话题的理解是合理的。

重要的是要理解,你的数据将控制和影响一切,因此,将数据作为你公司的一等公民是第一步重要的举措。雇佣一个数据副总裁并定义数据质量、血缘和可发现性的标准只是你可以采取的一些措施。

在自动化方面,我们看到自动化机器学习将在几年内统治世界。这个想法很简单:一个训练好的元模型在提出、训练、优化和堆叠模型以实现更高的预测性能方面将始终优于人类。这完全说得通。这只是另一个参数优化步骤,也包括模型架构。另一个有趣的思考是,自动化机器学习将为不熟悉机器学习的人提供真正的 MLaaS。也许 Excel 中会提供一个预测列,或者在 Power BI 中有一个机器学习转换步骤,这意味着普通的 Office 用户可以通过电子表格应用程序突然利用机器学习的力量。

我们还提到,在云中使用 PaaS 时,变化是不可避免的。这是因为 PaaS 解决方案旨在实施典型的客户解决方案,并推动你消费更多的基础设施服务。随着客户需求的变化,这些 PaaS 提供的产品也会随之变化。因此,一个很好的经验法则是不要过于依赖产品名称、UI 或 SDK 包。

最后,我们理解了在数据处理中伦理的重要性。我们讨论了构建可解释的模型、评估我们模型公平性以及如何保护个人数据不受我们自己和其他人侵害的话题。

我们希望你喜欢这本书,并学会了如何掌握机器学习和 Azure 机器学习。然而,这个兔子洞比这本书深得多。所以,继续学习吧,我们也会这样做。在社交媒体上联系我们,告诉我们你学到了什么,你喜欢什么,以及这本书中可以改进的地方。我们非常乐意听到你的反馈。

在那时之前,祝大家机器学习愉快!