MLFlow-机器学习工程-全-
MLFlow 机器学习工程(全)
原文:
annas-archive.org/md5/e98213c48352ec428afb655035096e6f译者:飞龙
前言
基于机器学习的产品实施可能是一项费力的任务。普遍需要减少机器学习开发生命周期不同步骤之间的摩擦,以及参与过程中的数据科学家和工程师团队之间的摩擦。
机器学习从业者,如数据科学家和机器学习工程师,使用不同的系统、标准和工具。虽然数据科学家大部分时间在 Jupyter Notebook 等工具中开发模型,但在生产运行时,模型是在一个对规模和可靠性要求更高的软件应用环境中部署的。
在本书中,您将了解 MLflow 以及有助于您机器学习生命周期的机器学习工程实践,包括数据获取、准备、训练和部署。本书的内容基于开放接口设计,将与任何语言或平台兼容。在可扩展性和可重复性方面,您也将从中受益。
在本书结束时,您将能够轻松地使用 MLflow 设置模型开发环境,构建您的机器学习问题,并使用标准化框架来设置您自己的机器学习系统。如果您正在实施您的第一个生产级机器学习项目,本书也将特别有用。
本书面向对象
本书面向软件、机器学习以及数据科学专业人士或爱好者,他们希望探索生产中机器学习系统的工程方面。机器学习从业者将能够通过这本实用的 MLflow 指南将他们的知识付诸实践。本书采用动手实践的方法来实施相关方法,让您能够迅速上手 MLflow。本书的基本要求是具备 Python 编程经验以及了解 Bash 终端和命令。
本书涵盖内容
第一章,介绍 MLflow,将概述 MLflow 的不同功能,指导您安装和探索平台的核心功能。阅读本章后,您将能够在本地上安装和操作您的 MLflow 环境。
第二章,您的机器学习项目,将介绍本书的重点。本书的方法是通过一个实际业务案例,即股票市场预测,来探索 MLflow 的所有不同功能。将使用问题框架框架让您深入了解书中使用的示例。本书的其余部分将创建一个示例管道供使用。
第三章, 您的数据科学工作台,帮助您了解如何使用 MLflow 创建本地环境,以便您可以在本地使用 MLflow 提供的一切不同功能来开发机器学习项目。
第四章, MLflow 中的实验管理,您将通过创建不同的模型并在 MLflow 中比较不同运行的指标来获得股票预测的实际经验。您将得到指导,了解如何部署跟踪服务器,以便许多机器学习从业者可以共享指标并改进模型。
第五章, 使用 MLflow 管理模型,探讨了 MLflow 中模型创建的不同功能。将涵盖内置模型,如 PyTorch 和 TensorFlow 模型,以及 MLflow 中不可用的自定义模型。将介绍模型生命周期,以及 MLflow 的模型注册功能。
第六章, 介绍 ML 系统架构,讨论了正确架构机器学习系统的必要性以及 MLflow 如何融入端到端机器学习系统的画面中。
第七章, 数据和特征管理,介绍了数据和特征管理。将阐明特征生成的重要性,以及如何使用特征流通过 MLflow 记录模型结果。
第八章, 使用 MLflow 训练模型,将描述并开发针对当前问题的完整训练管道基础设施,并使用 MLflow 特定的功能。
第九章, 使用 MLflow 进行部署和推理,将使用 MLflow 的 API 和批量功能暴露我们的机器学习系统的端到端部署基础设施,包括推理组件。还将描述 MLflow 的云启用功能。
第十章, 扩展您的机器学习工作流程,涵盖了与高性能/大数据库的集成,这些库允许 MLflow 系统扩展以处理大量数据。
第十一章, 性能监控,探讨了机器学习操作的重要领域以及如何使用最佳实践和操作模式确保书中开发的生成系统平稳运行。
第十二章, MLFlow 的高级主题,展示了包含完整 MLflow 管道的高级案例研究。这些案例研究使用了与本书其他部分所讨论的不同类型的模型,以确保对 MLflow 的特征覆盖范围广泛。
为了充分利用本书
理想情况下,在开始阅读本书之前,您应该对 Python 编程语言有很好的掌握,并且已经创建了基本的机器学习模型。一门机器学习入门课程将有助于将本书中讨论的概念置于上下文中。

如果您正在使用本书的数字版,我们建议您亲自输入代码或从本书的 GitHub 仓库(下一节中有一个链接)获取代码。这样做将帮助您避免与代码复制和粘贴相关的任何潜在错误。
下载示例代码文件
您可以从 GitHub 下载本书的示例代码文件github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow。如果代码有更新,它将在 GitHub 仓库中更新。
我们还有其他来自我们丰富的图书和视频目录的代码包可供选择,请访问github.com/PacktPublishing/。查看它们!
下载彩色图像
我们还提供了一份包含本书中使用的截图和图表彩色图像的 PDF 文件。您可以从这里下载:static.packt-cdn.com/downloads/9781800560796_ColorImages.pdf
使用的约定
本书使用了多种文本约定。
文本中的代码:表示文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称。以下是一个示例:“model.pkl文件包含模型的序列化版本”
代码块按以下方式设置:
import mlflow
from sklearn.linear_model import LogisticRegression
mlflow.sklearn.autolog()
with mlflow.start_run():
clf = LogisticRegression()
clf.fit(X_train, y_train)
任何命令行输入或输出都按以下方式编写:
docker build -t stockpred -f dockerfile
粗体: 表示新术语、重要单词或您在屏幕上看到的单词。例如,菜单或对话框中的单词以粗体显示。以下是一个示例:“MLflow是一个开源平台,用于机器学习(ML)生命周期”
小贴士或重要提示
看起来像这样。
联系我们
读者的反馈总是受欢迎的。
一般反馈: 如果您对本书的任何方面有疑问,请通过 customercare@packtpub.com 给我们发邮件,并在邮件主题中提及书名。
勘误表: 尽管我们已经尽最大努力确保内容的准确性,但错误仍然可能发生。如果您在这本书中发现了错误,如果您能向我们报告,我们将不胜感激。请访问www.packtpub.com/support/errata并填写表格。
盗版: 如果您在互联网上以任何形式发现我们作品的非法副本,如果您能向我们提供位置地址或网站名称,我们将不胜感激。请通过版权@packt.com 与我们联系,并提供材料的链接。
如果您有兴趣成为作者: 如果您在某个领域有专业知识,并且您有兴趣撰写或为书籍做出贡献,请访问authors.packtpub.com。
分享您的想法
一旦您阅读了《使用 MLflow 的机器学习工程》,我们非常期待听到您的想法!扫描下面的二维码直接进入此书的亚马逊评论页面并分享您的反馈。

您的评论对我们和科技社区都非常重要,它将帮助我们确保我们提供的是高质量的内容。
第一部分:问题界定与介绍
本节将向您介绍使用 MLflow 以简洁明了的方式陈述机器学习问题的框架。
本节涵盖了以下章节:
-
第一章, 介绍 MLflow
-
第二章, 您的机器学习项目
第一章:介绍 MLflow
MLflow是一个专注于机器学习(ML)生命周期、可重复性、训练和部署的开源平台。它基于开放的接口设计,能够与任何语言或平台协同工作,拥有 Python 和 Java 客户端,并通过 REST API 提供访问。可扩展性也是 ML 开发者可以利用的 MLflow 的一个重要优势。
在本书的这一章中,我们将通过示例和示例代码来查看 MLflow 的工作原理。这将建立使用该概念来构建端到端 ML 项目的必要基础。
具体来说,我们将在本章中查看以下部分:
-
什么是 MLflow?
-
开始使用 MLflow
-
探索 MLflow 模块
技术要求
对于本章,你需要以下先决条件:
-
在您的机器上安装了最新版本的 Docker。如果您没有最新版本,请按照以下 URL 的说明操作:
docs.docker.com/get-docker/。 -
访问 bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
已安装 Python 3.5+。
-
已安装 PIP。
什么是 MLflow?
基于 ML 的产品实施可能是一项费力的任务。普遍需要减少 ML 开发生命周期不同步骤之间的摩擦,以及参与过程的数据科学家和工程师团队之间的摩擦。
机器学习从业者,如数据科学家和机器学习工程师,使用不同的系统、标准和工具进行操作。虽然数据科学家大部分时间在 Jupyter Notebooks 等工具中开发模型,但在生产环境中运行时,模型是在一个对规模和可靠性要求更高的软件应用环境中部署的。
在 ML 项目中,一个常见的情况是工程团队重新实现模型,创建一个定制的系统来提供特定的模型。对于遵循定制方法的模型开发团队,以下是一些常见的挑战:
-
由于需要创建定制的软件基础设施来开发和提供模型,导致超出预算的 ML 项目
-
在重新实现数据科学家产生的模型时出现的翻译错误
-
在提供预测时遇到的可扩展性问题
-
由于缺乏标准环境,数据科学家在重现训练过程中出现的摩擦
利用机器学习的公司往往创建自己的(通常是极其费力的)内部系统,以确保机器学习开发过程的顺畅和结构化。广泛记录的机器学习平台包括来自 Uber 和 Facebook 的 Michelangelo 和 FBLearner 等系统。
在机器学习(ML)日益普及的背景下,MLflow 最初在 Databricks 创建,并作为一个平台开源,旨在帮助实现机器学习系统的实施。
MLflow 允许一个日常实践者在单一平台上管理机器学习生命周期,从模型开发的迭代到在兼容现代软件系统要求的可靠和可扩展环境中部署。
开始使用 MLflow
接下来,我们将在您的机器上安装 MLflow 并为其在本章中使用做准备。安装 MLflow 时,您有两个选择。第一个选择是通过书中提供的基于 Docker 容器的配方在存储库中:github.com/PacktPublishing/Machine-Learning-Engineering-with-Mlflow.git。
要安装它,请按照以下说明操作:
-
使用以下命令安装软件:
$ git clone https://github.com/PacktPublishing/Machine-Learning-Engineering-with-Mlflow.git $ cd Machine-Learning-Engineering-with-Mlflow $ cd Chapter01 -
在这个阶段,Docker 镜像非常简单:它仅包含 MLflow 和 sklearn,这是本书这一章节中要使用的主要工具。为了说明目的,您可以查看
Dockerfile的内容:FROM jupyter/scipy-notebook RUN pip install mlflow RUN pip install sklearn -
要构建镜像,您现在应该运行以下命令:
docker build -t chapter_1_homlflow -
在构建镜像后,您可以运行
./run.sh命令:./run.sh重要提示
确保您的机器上安装了最新版本的 Docker 非常重要。
-
打开您的浏览器,访问
localhost:888,您应该能够导航到Chapter01文件夹。
在接下来的部分,我们将使用之前步骤中创建的 Jupyter 环境使用 MLflow 开发我们的第一个模型。
使用 MLflow 开发您的第一个模型
从简单性的角度来看,在本节中,我们将使用 sklearn 内置的样本数据集,这是我们最初用来探索 MLflow 功能的机器学习库。对于本节,我们将选择著名的 Iris 数据集,使用 MLflow 训练一个多类分类器。
Iris 数据集(sklearn 内置数据集之一,可通过 scikit-learn.org/stable/datasets/toy_dataset.html 获取)包含以下作为特征的元素:花瓣长度、花瓣宽度、花萼长度和花萼宽度。目标变量是鸢尾花的类别:Iris Setosa、Iris Versicolor 或 Iris Virginica:
-
加载样本数据集:
from sklearn import datasets from sklearn.model_selection import train_test_split dataset = datasets.load_iris() X_train, X_test, y_train, y_test = train_test_split(dataset.data, dataset.target, test_size=0.4) -
接下来,让我们训练您的模型。
使用 scikit-learn 等框架训练简单的机器学习模型涉及实例化一个估算器,如
LogisticRegression,并调用fit命令在 scikit-learn 内置的Iris数据集上执行训练:from sklearn.linear_model import LogisticRegression clf = LogisticRegression() clf.fit(X_train, y_train)上述代码行只是 ML 工程 流程的一小部分。正如将要展示的,为了将前面的训练代码投入生产并确保其可用性和可靠性,需要创建大量的代码。MLflow 的一个主要目标就是帮助设置 ML 系统和项目的过程。在接下来的章节中,我们将展示如何使用 MLflow 使您的解决方案更加健壮和可靠。
-
然后,我们将添加 MLflow。
通过几行额外的代码,你应该能够开始你的第一个 MLflow 交互。在以下代码列表中,我们首先导入
mlflow模块,然后是 scikit-learn 中的LogisticRegression类。你可以使用附带的 Jupyter 笔记本来运行下一部分:import mlflow from sklearn.linear_model import LogisticRegression mlflow.sklearn.autolog() with mlflow.start_run(): clf = LogisticRegression() clf.fit(X_train, y_train)mlflow.sklearn.autolog()指令允许您在本地目录中自动记录实验。它捕获了使用的底层机器学习库产生的指标。MLflow Tracking 是负责处理指标和日志的模块。默认情况下,MLflow 运行的元数据存储在本地文件系统中。 -
如果你在一个附带的笔记本的根文档上运行以下摘录,你应该现在在你的主目录中有以下文件,这是运行以下命令的结果:
$ ls -l total 24 -rw-r--r-- 1 jovyan users 12970 Oct 14 16:30 chapther_01_introducing_ml_flow.ipynb -rw-r--r-- 1 jovyan users 53 Sep 30 20:41 Dockerfile drwxr-xr-x 4 jovyan users 128 Oct 14 16:32 mlruns -rwxr-xr-x 1 jovyan users 97 Oct 14 13:20 run.shmlruns文件夹与你的笔记本文件夹同时生成,包含当前上下文中由你的代码执行的所有实验。mlruns文件夹将包含一个带有顺序编号的文件夹来标识你的实验。文件夹的结构如下所示:├── 46dc6db17fb5471a9a23d45407da680f │ ├── artifacts │ │ └── model │ │ ├── MLmodel │ │ ├── conda.yaml │ │ ├── input_example.json │ │ └── model.pkl │ ├── meta.yaml │ ├── metrics │ │ └── training_score │ ├── params │ │ ├── C │ │ ….. │ └── tags │ ├── mlflow.source.type │ └── mlflow.user └── meta.yaml因此,我们几乎不需要付出太多努力,就有很多可追溯性可用,并且有一个很好的基础来改进。
你的实验在先前的样本中被识别为 UUID,由 46dc6db17fb5471a9a23d45407da680f。在目录的根目录下,有一个名为 meta.yaml 的 yaml 文件,其中包含以下内容:
artifact_uri: file:///home/jovyan/mlruns/0/518d3162be7347298abe4c88567ca3e7/artifacts
end_time: 1602693152677
entry_point_name: ''
experiment_id: '0'
lifecycle_stage: active
name: ''
run_id: 518d3162be7347298abe4c88567ca3e7
run_uuid: 518d3162be7347298abe4c88567ca3e7
source_name: ''
source_type: 4
source_version: ''
start_time: 1602693152313
status: 3
tags: []
user_id: jovyan
这是你实验的基本元数据,包括开始时间、结束时间、运行识别(run_id 和 run_uuid)、生命周期阶段的假设以及执行实验的用户。设置基本上基于默认运行,但提供了关于你实验的有价值和可读的信息:
├── 46dc6db17fb5471a9a23d45407da680f
│ ├── artifacts
│ │ └── model
│ │ ├── MLmodel
│ │ ^ ├── conda.yaml
│ │ ├── input_example.json
│ │ └── model.pkl
model.pkl 文件包含模型的序列化版本。对于 scikit-learn 模型,有一个模型的 Python 代码的二进制版本。在自动记录时,利用了底层机器库的指标。默认的打包策略基于一个 conda.yaml 文件,其中包含正确的依赖关系,以便能够序列化模型。
MLmodel 文件是从 MLflow 项目中关于如何运行当前模型进行推理的主要定义。
metrics 文件夹包含训练过程的这次特定运行的训练分数值,可以用来与后续模型改进进行基准测试。
在文件夹列表的第一项中,params 文件夹包含了逻辑回归模型的默认参数,不同的默认可能性被透明地列出并自动存储。
探索 MLflow 模块
MLflow 模块是软件组件,它们提供了辅助不同机器生命周期阶段的核心理念。MLflow 功能通过模块提供,这些模块是可扩展的组件,它们在平台上组织相关的功能。
以下是在 MLflow 中内置的模块:
-
MLflow 跟踪:提供了一种机制和用户界面来处理由 ML 执行(训练和推理)生成的指标和工件
-
MLflow 项目:一种用于标准化 ML 项目的包格式
-
MLflow 模型:一种机制,可以部署到不同类型的本地和云环境
-
MLflow 模型注册表:一个模块,用于管理 MLflow 中的模型及其生命周期,包括状态
为了探索不同的模块,我们将使用以下命令在您的本地环境中安装 MLflow:
pip install mlflow
重要提示
确保在您的本地机器上正确安装了技术要求,以便您能够跟随操作。您也可以使用具有所需权限的pip命令。
探索 MLflow 项目
MLflow 项目代表 ML 项目的组织基本单位。MLflow 项目支持三种不同的环境:Conda 环境、Docker 和本地系统。
重要提示
可以在官方文档中查看 MLProject 文件上可用的不同参数的模型详细信息,该文档可在www.mlflow.org/docs/latest/projects.html#running-projects找到。
以下是一个conda环境MLproject文件的示例:
name: condapred
conda_env:
image: conda.yaml
entry_points:
main:
command: "python mljob.py"
在conda选项中,假设存在一个包含所需依赖项的conda.yaml文件。当 MLflow 被要求运行项目时,它将使用指定的依赖项启动环境。
基于系统的环境将如下所示;实际上相当简单:
name: syspred
entry_points:
main:
command: "python mljob.py"
上述系统变体将基本上依赖于本地环境依赖项,假设底层操作系统包含所有依赖项。这种方法特别容易与底层操作系统发生库冲突;在已经存在适合项目的操作系统环境的情况下,这可能是有价值的。
以下是基于 Docker 环境的MLproject文件:
name: syspred
docker_env:
image: stockpred-docker
entry_points:
main:
command: "python mljob.py"
一旦您有了环境,定义您的项目外观的主要文件是MLProject文件。此文件由 MLflow 用于了解它应该如何运行您的项目。
在 MLflow 中开发您的第一个端到端管道
我们将在本节中使用 MLflow 和本地安装的 Docker 原型化一个简单的股票预测项目,并将记录解决方案的不同文件和阶段。您将使用本地系统上安装的 MLflow 和 Docker 来开发它。
重要提示
在本节中,我们假设 MLflow 和 Docker 已在本地安装,因为本节中的步骤将在您的本地环境中执行。
在本示例项目中,任务是创建一个基本的 MLflow 项目,并生成一个可工作的基线 ML 模型,根据一定数量的市场信号预测股市是上涨还是下跌。
在本节中,我们将使用 Yahoo Finance 提供的 BTC-USD 对 3 个月期间的报价数据集。我们将训练一个模型来预测在给定的一天内报价是否会上涨。将通过 MLflow 提供一个 REST API 进行预测。
我们将逐步说明创建一个 MLflow 项目,用于在股票数据上训练分类器,使用 Yahoo API 通过包的 pandas 数据读取器检索金融信息:
-
添加你的
MLProject文件:name: stockpred docker_env: image: stockpred-docker entry_points: main: command: "python train.py"前面的
MLProject文件指定依赖项将使用特定的镜像名称在 Docker 中管理。MLflow 将尝试使用您系统上安装的 Docker 版本来拉取镜像。如果找不到,它将尝试从 Docker Hub 获取。对于本章的目标,MLflow 在您的本地机器上运行是完全可行的。我们添加到项目中的第二个配置是主入口点命令。要执行的命令将在 Docker 环境中调用我们的项目代码的
train.pyPython 文件。 -
将 Docker 文件添加到项目中。
此外,您还可以指定您镜像的 Docker 注册表 URL。运行 Docker 的优势是您的项目不受 Python 语言的限制,正如我们将在本书的高级部分中看到的那样。MLflow API 在 Rest 接口以及官方客户端(Python、Java 和 R)中可用:
FROM continuumio/miniconda:4.5.4 RUN pip install mlflow==1.11.0 \ && pip install numpy==1.14.3 \ && pip install scipy \ && pip install pandas==0.22.0 \ && pip install scikit-learn==0.20.4 \ && pip install cloudpickle \ && pip install pandas_datareader>=0.8.0前面的 Docker 镜像文件基于开源软件包 Miniconda,这是一个免费的、包含数据科学所需的最小包集的最小安装程序,它允许我们控制环境中所需包的详细信息。
我们将指定 MLflow(我们的 ML 平台)的版本、
numpy和scipy用于数值计算。Cloudpickle允许我们轻松序列化对象。我们将使用pandas来管理数据框,并使用pandas_datareader来允许我们轻松从公共来源检索数据。 -
导入项目所需的所有包。
在下面的列表中,我们明确导入了在执行训练脚本期间将使用的所有库:读取数据的库,以及与所选初始 ML 模型相关的不同
sklearn模块:import numpy as np import datetime import pandas_datareader.data as web from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report from sklearn.metrics import precision_score from sklearn.metrics import recall_score from sklearn.metrics import f1_score import mlflow.sklearn我们明确选择了
RandomForestClassifier作为股票市场运动检测问题的模型,因为它是一个非常灵活且广泛接受的分类问题基线模型。 -
获取您的训练数据。
代码中获取 Yahoo Finance 股票数据集的部分故意很小,因此我们选择一个 3 个月的特定间隔来训练我们的分类器。
acquire_training_data方法返回一个包含相关数据集的pandas数据框:def acquire_training_data(): start = datetime.datetime(2019, 7, 1) end = datetime.datetime(2019, 9, 30) df = web.DataReader("BTC-USD", 'yahoo', start, end) return df获取数据的格式是交易所 API 中金融证券的经典格式。对于期间每一天,我们检索以下数据:股票的最高价、最低价、开盘价和收盘价,以及成交量。最后一列代表调整后的收盘价,即除息和拆股后的价值:
![图 1.1 – 获取数据的摘录
![img/image001.jpg]()
图 1.1 – 获取数据的摘录
图 1.2 说明了我们希望通过当前数据准备过程实现的目标变量:
![图 1.2 – 带有预测列的获取数据摘录
![img/image002.jpg]()
图 1.2 – 获取数据中带有预测列的摘录
-
使数据可由 scikit-learn 使用。
在先前的步骤中获取的数据显然不能直接由
RandomForestAlgorithm使用,因为它依赖于分类特征。为了便于执行此操作,我们将使用滚动窗口技术将原始数据转换为特征向量。基本上,每一天的特征向量成为当前窗口日和前一个窗口日之间的差值。在这种情况下,我们使用前一天的股市走势(股票上涨为 1,否则为 0):
def digitize(n): if n > 0: return 1 return 0 def rolling_window(a, window): """ Takes np.array 'a' and size 'window' as parameters Outputs an np.array with all the ordered sequences of values of 'a' of size 'window' e.g. Input: ( np.array([1, 2, 3, 4, 5, 6]), 4 ) Output: array([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]) """ shape = a.shape[:-1] + (a.shape[-1] - window + 1, window) strides = a.strides + (a.strides[-1],) return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides) def prepare_training_data(data): data['Delta'] = data['Close'] - data['Open'] data['to_predict'] = data['Delta'].apply(lambda d: digitize(d)) return data以下示例说明了使用前一天的二值化涨跌产生的数据框输出:
![图 1.3 – 二值化市场涨跌的特征向量
![img/image003.jpg]()
图 1.3 – 二值化市场涨跌的特征向量
-
在 MLflow 中训练和存储您的模型。
以下代码列表的这一部分调用了先前声明的数据准备方法并执行了预测过程。
主要执行还明确地将当前执行中在 MLflow 环境中训练的 ML 模型记录下来。
if __name__ == "__main__": with mlflow.start_run(): training_data = acquire_training_data() prepared_training_data_df = prepare_training_data(training_data) btc_mat = prepared_training_data_df.as_matrix() WINDOW_SIZE = 14 X = rolling_window(btc_mat[:, 7], WINDOW_SIZE)[:-1, :] Y = prepared_training_data_df['to_predict'].as_matrix()[WINDOW_SIZE:] X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.25, random_state=4284, stratify=Y) clf = RandomForestClassifier(bootstrap=True, criterion='gini', min_samples_split=2, min_weight_fraction_leaf=0.0, n_estimators=50, random_state=4284, verbose=0) clf.fit(X_train, y_train) predicted = clf.predict(X_test) mlflow.sklearn.log_model(clf, "model_random_forest") mlflow.log_metric("precision_label_0", precision_score(y_test, predicted, pos_label=0)) mlflow.log_metric("recall_label_0", recall_score(y_test, predicted, pos_label=0)) mlflow.log_metric("f1score_label_0", f1_score(y_test, predicted, pos_label=0)) mlflow.log_metric("precision_label_1", precision_score(y_test, predicted, pos_label=1)) mlflow.log_metric("recall_label_1", recall_score(y_test, predicted, pos_label=1)) mlflow.log_metric("f1score_label_1", f1_score(y_test, predicted, pos_label=1))mlflow.sklearn.log_model(clf, "model_random_forest")方法负责在训练后持久化模型。与先前的示例相比,我们明确要求 MLflow 记录我们认为相关的模型和指标。这种对记录项的灵活性允许一个程序将多个模型记录到 MLflow 中。最后,根据先前创建的文件,您的项目布局应如下所示:
├── Dockerfile ├── MLproject ├── README.md └── train.py -
构建您项目的 Docker 镜像。
为了构建您的 Docker 镜像,您应该运行以下命令:
stockpred tag. This image will be usable in MLflow in the subsequent steps as the model is now logged into your local registry. Following execution of this command, you should expect a successful Docker build:---> 268cb080fed2
成功构建 268cb080fed2
成功标记 stockpred:latest
-
运行您的项目。
为了运行您的项目,您现在可以运行 MLflow 项目:
mlflow run .您的输出应类似于此处提供的摘录:
MLFLOW_EXPERIMENT_ID=0 stockpred:3451a1f python train.py' in run with ID '442275f18d354564b6259a0188a12575' === precision recall f1-score support 0 0.61 1.00 0.76 11 1 1.00 0.22 0.36 9 accuracy 0.65 20 macro avg 0.81 0.61 0.56 20 weighted avg 0.79 0.65 0.58 20 2020/10/15 19:19:39 INFO mlflow.projects: === Run (ID '442275f18d354564b6259a0188a12575') succeeded ===这包含了对您的模型的打印输出、实验 ID 以及当前运行期间捕获的指标。
在这个阶段,您有一个使用 MLflow 的简单、可复制的股票预测管道的基线,您可以在此基础上进行改进并轻松与他人分享。
重新运行实验
MLflow 的另一个极其有用的功能是能够以与最初运行时相同的参数重新运行特定的实验。
例如,您应该能够通过指定项目的 GitHub URL 来运行您之前的项目:
mlflow run https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter01/stockpred
基本上,上一个命令执行的操作是 MLflow 将仓库克隆到临时目录,并按照 MLProject 上的配方执行它。
实验的 ID(或名称)允许您使用原始参数运行项目,从而实现项目的完全可重复性。
MLflow 项目功能允许您的项目在高级云环境中运行,如 Kubernetes 和 Databricks。无缝扩展您的机器学习作业是像 MLflow 这样的平台的主要卖点之一。
如您从当前章节所见,MLflow 项目模块允许执行一个可重复的机器学习作业,该作业被视为一个自包含的项目。
探索 MLflow 跟踪
MLflow 跟踪组件负责可观察性。此模块的主要功能是记录 MLflow 执行的指标、工件和参数。它提供可视化和工件管理功能。
在生产环境中,它被用作一个用 Python 实现的集中式跟踪服务器,可以由组织中的一组机器学习从业者共享。这使得组织内部可以共享机器学习模型的改进。
在图 1.4中,您可以看到一个记录了您模型所有运行的界面,并允许您记录您实验的可观察量(指标、文件、模型和工件)。对于每次运行,您都可以查看和比较您模块的不同指标和参数。
它解决了模型开发者比较不同参数和设置下模型不同迭代时的常见痛点。
以下截图展示了我们上一个模型最后一次运行的指标:

图 1.4 – MLFlow 界面/UI 的示例
MLflow 允许检查与每个模型及其相关元数据相关的任意工件,允许比较不同运行的指标。您可以看到 RUN ID 和生成特定实验运行的代码的 Git 哈希:

Figure 1.5 – 检查记录的模型工件
在您的stockpred当前目录中,您可以运行以下命令以访问您运行的结果:
mlflow ui
在本地运行 MLflow UI 将使其在以下 URL 下可用:127.0.0.1:5000/。
在以下截图所示的特定情况下,我们有一个命名实验,其中调整了前一个示例中窗口大小的参数。在 F1 分数方面,可以清楚地看到算法性能的差异:

图 1.6 – MLflow 运行的列表
MLFlow 跟踪的另一个非常有用的功能是能够在不同作业运行之间进行比较:

图 1.7 – 任务运行 F1 指标的对比
此前的可视化允许从业者决定在生产中使用哪种模型,或者是否进一步迭代。
探索 MLflow 模型
MLflow 模型是处理 MLflow 中支持的不同模型风味以及将部署到不同执行环境的中介的核心组件。
我们现在将深入探讨 MLflow 最新版本中支持的不同模型。
如MLflow 入门部分所示,MLflow 模型在模型以内部格式持久化时具有特定的序列化方法。例如,stockpred项目上实现的模型的序列化文件夹看起来如下:
├── MLmodel
├── conda.yaml
└── model.pkl
内部,MLflow sklearn 模型在运行时使用conda文件及其依赖项持久化,并使用源代码记录的 pickle 模型:
artifact_path: model_random_forest
flavors:
python_function:
env: conda.yaml
loader_module: mlflow.sklearn
model_path: model.pkl
python_version: 3.7.6
sklearn:
pickled_model: model.pkl
serialization_format: cloudpickle
sklearn_version: 0.23.2
run_id: 22c91480dc2641b88131c50209073113
utc_time_created: '2020-10-15 20:16:26.619071'
~
默认情况下,MLflow 支持以两种风味提供模型服务,即作为python_function或sklearn格式。这些风味基本上是用于工具或环境的模型格式。
使用前面的一个很好的例子是能够通过执行以下命令来提供服务而无需任何额外代码:
mlflow models serve -m ./mlruns/0/b9ee36e80a934cef9cac3a0513db515c/artifacts/model_random_forest/
您可以访问一个非常简单的 Web 服务器,可以运行您的模型。您可以通过运行以下命令来执行模型预测接口:
curl http://127.0.0.1:5000/invocations -H 'Content-Type: application/json' -d '{"data":[[1,1,1,1,0,1,1,1,0,1,1,1,0,0]]}' [1]%
对我们模型 API 调用的响应是1;根据我们的预测变量定义,这意味着在下次读取时,股票将上涨。
最后几个步骤概述了 MLflow 作为端到端模型开发工具的强大之处,包括为 ML 服务原型设计基于 REST 的 API。
MLflow 模型组件允许创建具有与内置模型相同优势的自定义 Python 模块,只要遵循预测接口即可。
在接下来的章节中,我们将探讨一些值得注意的模型类型,包括以下内容:
-
XGBoost 模型格式
-
R 函数
-
H2O 模型
-
Keras
-
PyTorch
-
Sklearn
-
Spark MLib
-
TensorFlow
-
Fastai
支持最普遍的 ML 模型类型,结合其内置的本地和云部署能力,是 MLflow 模型的最强功能之一。我们将在与部署相关的章节中更详细地探讨这一点。
探索 MLflow 模型注册
MLflow 中的模型注册组件为 ML 开发者提供了模型生命周期管理的抽象。它是一个集中存储库,允许组织或功能中的模型可以协作地共享、创建和归档。
可以使用 MLflow 的不同 API 和 UI 来管理模型。图 1.7 展示了跟踪服务器中的 Artifacts UI,可用于注册模型:

图 1.8 – 将模型注册为工件
在注册模型后,您可以使用相关元数据注释已注册的模型,并管理其生命周期。一个例子是将模型放在预生产环境中的测试阶段,并通过将模型发送到生产来管理生命周期:

图 1.9 – 管理不同的模型版本和阶段
本书将进一步探讨模型注册模块,详细介绍了如何设置集中式服务器以及管理机器学习模型的生命周期,从构思到逐步淘汰模型的过程。
摘要
在本章中,我们介绍了 MLflow,并探讨了采用机器学习平台以减少机器学习开发中从模型开发到生产的时间的动机。通过本章获得的知识和经验,您可以开始改进并使您的机器学习开发工作流程可重复和可追踪。
我们深入探讨了平台中的每个重要模块:项目、模型、跟踪器和模型注册。特别强调了实际示例,以说明每个核心功能,让您能够以动手的方式接触平台。MLflow 提供了多种开箱即用的功能,这些功能将最小化代码和配置,以减少机器学习开发生命周期的摩擦。MLflow 提供了开箱即用的指标管理、模型管理和可重复性。
我们将在本章节的入门知识基础上,扩展我们在构建实际机器学习平台方面的技能和知识。
在本章中,我们简要介绍了股票市场预测的用例,该用例将在本书的其余部分中使用。在下一章中,我们将专注于严格定义股票市场预测的机器学习问题。
进一步阅读
为了增强您的知识,您可以查阅以下链接中提供的文档:
-
MLflow 的参考信息可在以下链接找到:
www.mlflow.org/docs/latest/ -
机器学习平台复习笔记:
medium.com/nlauchande/review-notes-of-ml-platforms-uber-michelangelo-e133eb6031da -
MLflow 技术论文:
www-cs.stanford.edu/people/matei/papers/2018/ieee_mlflow.pdf
第二章:您的机器学习项目
本书的方法是通过迭代一个实际商业项目——即股票市场预测——并利用这个用例,通过不同的章节探索 MLflow 的不同功能。我们将使用结构化方法来构建机器学习问题和项目。本书剩余部分将创建并使用一个示例管道来迭代和演进项目。
使用结构化框架描述机器学习问题有助于从业者更有效地推理机器学习管道的不同需求。我们将展示一个使用在构建阶段收集到的需求的实际管道。
具体来说,在本章中,我们将涵盖以下内容:
-
探索机器学习过程
-
构建机器学习问题
-
介绍股票市场预测问题
-
开发您的机器学习基线管道
技术要求
对于本章,您需要以下先决条件:
-
在您的机器上安装了最新版本的 Docker。如果您还没有安装,请按照
docs.docker.com/get-docker/上的说明进行操作。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
已安装 Python 3.5 以上版本。
-
如第一章,“介绍 MLflow”中所述,在本地安装 MLflow。
探索机器学习过程
在本章中,我们将首先描述我们将贯穿整本书解决的问题。我们的目标是关注股票交易背景下的机器学习。
机器学习可以被定义为训练一个软件实体的过程——在本例中,是一个模型,用于在问题中做出相关预测。预测被用于驱动业务决策,例如,应该购买或出售哪只股票,或者图片中是否包含猫。
对于一个成功的项目来说,拥有标准的机器学习项目方法是至关重要的。机器学习生命周期的典型迭代在图 2.1中展示:

图 2.1 – 获取数据的摘录及预测列
让我们详细检查每个阶段:
-
构思:这一阶段涉及识别一个使用机器学习的机会并制定问题。
-
原型设计:这涉及到验证现有数据集的可行性和适用性,以实现计划中的想法。
-
试点:这涉及到评估和迭代机器学习算法,以便决定是否进入下一阶段。
-
生产部署:在成功试点后,我们应该能够在生产中运行机器学习项目,并允许它开始接收生产流量。
在图 2.1中定义的这些高级阶段肯定不是静态的,通常是迭代的,各阶段之间有动态移动以精炼和改进。
应该注意的是,机器学习并不是解决所有问题的方案。在决定使用机器学习之前,需要对当前的问题或项目进行深入评估,以决定是否应用机器学习。
有一些简单场景,机器学习解决方案是一个很好的候选者,例如以下情况:
-
当简单的规则和启发式方法不足以解决当前的问题时。
-
使用当前最先进的方法解决问题非常昂贵。
-
当解决问题的规则和代码非常复杂且难以维护时。
机器学习的出现给各个领域带来了变化;其中之一是金融领域。在计算机出现之前,金融是基于小办公室中的交易纸张,交易数量较少。有了计算机,情况发生了变化;现在每天有数百万笔交易。数百万人相互交易,无需亲自见面或进行任何其他形式的物理接触。
在金融和股票交易领域,机器学习可以在以下环境中使用:
-
数据挖掘:使用高级预测分析来识别数据集中的模式。高级数据分析师通常将机器学习模型作为其分析过程的一部分,并用于驱动业务决策。
-
对冲交易:一种使用两对市场方向相反的股票的技术。基本上,这是通过在每只股票与其正常行为不同步时卖出或买入来实现的,因为市场在一段时间后会趋于收敛。
-
股票预测:基于当前时间序列对特定股票在未来的某个时间点将被交易的简单预测。
-
异常检测:在市场中检测异常情况,发现对防止自动交易系统在市场异常的日子里运行非常重要。
-
情感分析:众所周知,股市主要是由公司和企业参与者的情绪驱动的。这种技术使用社交媒体或其它媒介上的消息,利用自然语言处理技术来衡量情绪(例如,正面、负面或中性)。
接下来,我们将探讨为机器学习构建问题框架。
构建机器学习问题框架
本节中定义的机器学习问题框架是一种技术和方法,旨在帮助明确和具体化机器学习问题,以便可以实施工程解决方案。如果没有一个稳固的方法来处理机器学习问题,提取这项工作的真正价值可能会变得非常困难。
我们将借鉴亚马逊和谷歌等公司的方法,这些公司已经成功应用了机器学习问题框架的技术。
机器学习开发过程高度基于科学方法。我们经过不同的阶段,包括陈述目标、数据收集、假设检验和结论。预期我们将循环通过工作流程的不同阶段,直到确定一个好的模型或明显无法开发模型。
以下小节描述了本书其余部分将使用的框架,以激发机器学习问题解决框架。
问题陈述
在尝试其他任何事情之前,理解我们正在解决的问题非常重要。为当前问题定义问题陈述是定义问题的明确方式。以下是一些合理的机器学习问题陈述示例:
-
预测特定股票的股票市场明天是否会上涨。
-
预测图片中是否有猫。
在这个流程的部分,我们指定我们旨在解决的特定类型的学习问题。以下是一些常见的问题类型:
-
分类:这类问题要求你预测模型的输出标签或类别,例如,分类电子邮件文本是否为垃圾邮件。它可以是二分类或多分类。一个多分类变体的好例子是根据手写数字进行分类。
-
回归:这指的是你需要,例如,从训练数据集中预测一个数值。好的例子包括根据大气特征预测温度和预测给定股票的美元价值。
-
聚类:当你没有标签来训练模型时,它包括发现数据的自然分组。它使用距离度量将相似数据点分组到同一组中。聚类可以用来识别欺诈交易,因为它们不会属于现有的分组。
-
生成模型:这是一种新型的机器学习,它根据现有数据生成新的数据,并且与输入数据在统计上相似。它在现代语言模型中广泛使用,例如 OpenAI 的 GPT-3。
-
强化学习:这是一种机器学习类型,其中代理/模型与环境交互以学习最优行为以最大化奖励。一个著名的应用是谷歌 DeepMind 的 AlphaGo 代理,它能够在围棋棋盘游戏中击败最佳人类玩家。一个非常重要的应用是使用盈利作为奖励来训练自动交易股票代理。
重要提示
机器学习问题有多种分类法;本节中的列表绝对不是详尽的。此列表与书中的示例相关。
成功与失败的定义
从业务中获得成功定义对于将您的问题置于正确的视角非常重要。例如,对于股市案例,以下可以概述为一个期望的结果:“使用本项目的模型,我们希望将我们目前 50%的日常交易盈利的盈利能力提高至 56%。”
因此,如果我们只有 30%的交易是成功的,那么这个模型显然是失败的。它通常将依赖于业务标准。
将业务指标作为成功定义,而不是像准确性、精确度或召回率这样的技术指标,有助于使解决方案与组织的具体目标保持一致。
模型输出
在机器学习问题框架的背景下,模型输出取决于您要解决的问题类型。例如,回归模型输出将是一个特定的数字(例如,作为股票预测的 10.5)和分类将返回一个标签(例如,检测到猫时返回true)以及一个概率阈值。
您的模型输出应该肯定与您的结果定义相关。
输出用途
说明您的预测将如何被使用有助于揭示模型开发的理由,帮助开发者了解问题和拥有感,例如,决定您是否将预测直接用于用户界面或用于喂养上游系统。
启发式方法
使用机器学习解决的问题可以通过规则和启发式方法来近似。将启发式方法作为机器学习管道的起点通常是一个推荐的项目启动方法。
例如,对于股票交易预测问题的一个有效启发式方法是使用最后一天的预测作为第一个基线生产启发式。模型开发者的目标就是通过更好的模型来超越基线。
数据层定义
在您的模型背景下精确定义输入和输出有助于澄清并指导您的机器学习问题开发。
数据源
本节关于问题框架的内容包括在问题框架过程中识别原始数据源并对其进行记录。原始数据源的例子包括公共或专有数据集及其定义和数据字典。
在这个阶段,识别数据是否已标记以及标记数据所需付出的努力是很重要的。
模型输入/输出
模型开发涉及定义模型中要使用的精确输入。考虑到所有可用的数据源,指定模型输入或特征集对于执行您的管道变得至关重要。与您的输入一起,应定义期望的目标。
模型输入/输出最好以表格形式呈现,如图 2.2所示,以便于推理和模型实现。为了清晰起见,增加了一行示例数据:

图 2.2 – 模型输入/输出的文档示例
接下来,我们将探讨在本书中我们将要工作的股票交易场景中,使用机器学习问题界定技术。
介绍股票市场预测问题
本书剩余章节将涵盖假设公司PsyStock LLC的情景,该公司为业余交易者提供平台,提供 API 和 UI 以解决股票预测背景下的不同预测问题。
作为机器学习实践者和开发者,我们应该能够构建一个平台,使数据科学家团队能够快速开发、测试并将机器学习项目投入生产。
我们将首先应用和界定问题,以便我们可以在问题的定义基础上构建我们的平台。需要注意的是,随着我们对问题的了解更多,问题界定将不断发展:初始界定将为我们提供解决问题空间的指导。
以下是我们将在本书的其余部分作为机器学习开发在 MLflow 中参考的核心项目。
股票走势预测器
这是公司 PsyStock LLC 将为客户提供的第一个 API 项目。如果给定的股票代码在股市中上涨,则该 API 将返回true,如果不上涨,则返回false。
问题陈述
问题陈述是通过机器学习分类器预测市场在单日是否会上涨。
成功与失败定义
在这种情况下,成功定义为系统中预测市场方向正确的天数占一个月天数的百分比。成功基本上是指系统在市场方向上准确率超过 60% – 基本上,是优于随机基线的期望值。
模型输出
模型输出为1表示股票代码价值增加,为0表示未增加。
输出用途
模型的输出将用于向 Rest API 提供基于分类准确度定义阈值的true或false值。
此问题的预期延迟低于 1,000 毫秒。
启发式方法
解决此问题的最简单启发式方法是使用随机预测器对每个输入进行预测,市场上涨或下跌的概率相等。
数据层定义
让我们定义我们数据层的每个部分。
数据源
由 Yahoo Finance 公共 API 提供的历史股票市场数据集。
模型输入/输出
让我们看看输入和输出,接下来:
-
输入:过去 10 天给定股票代码的每日收盘价。
-
1表示下一期增加,0表示不增加。
下表显示了模型的输入/输出数据:


图 2.3 – 记录模型输入/输出的示例
市场影响者的情绪分析
情绪机器学习管道将预测社交媒体上股票代码的情绪是正面还是负面,并将其作为 API 提供给我们在本书中开发的机器学习平台的用户。
问题陈述
为了预测 PsyStock LLC 选定的相关市场影响者在 Twitter 上对给定股票代码在当天是否具有正面情绪。
成功与失败的定义
在这种情况下,成功定义起来有点困难,因为情绪是正面的这一事实不能精确地追踪到市场指标。对于这个特定的预测问题,成功的定义应该是用户重复使用 API 次数的代理。
模型输出
模型输出基本上是一个数字,匹配股票代码的推文的极性——正面、负面或中性情绪。
输出用途
该系统的输出将用于一个 Rest API,该 API 将在请求时提供,包括给定股票代码的正面、中性和负面极性的数量。
启发式方法
作为此问题的基线,一个非常简单的启发式方法是计算单词up和down出现的次数。对于股票代码,哪个单词更频繁,就使用哪个单词的值作为极性。如果两个单词之间的频率百分比小于 10%,我们将假设该股票代码的情绪是中性的。
数据层定义
对于这个问题,最 readily available 的原始数据是社交媒体。Twitter 提供了一个易于消费和搜索的 API,我们可以通过股票代码和影响者用户名进行搜索。
数据来源
源数据将通过 Twitter API 获取,以搜索给定可更新市场影响者列表的股票代码。
模型输入/输出
将为模型提供服务的系统将接收一条推文并返回分类的情绪(正面、负面或中性):

图 2.4 – 记录模型输入/输出的示例
在本节中,我们仅定义了我们将从头到尾在整个书中解决的问题。我们将根据需要改进问题框架的定义,并在必要时对其进行更新。
在下一节中,我们将探讨在问题框架中定义启发式方法,以创建我们将要改进的第一个基础管道。
开发您的机器学习基线管道
对于我们的机器学习平台,我们将从一个非常简单、基于启发式方法的管道开始,以确保您的端到端系统的基础设施运行正确,并为机器学习模型提供一个可以迭代的 环境。
重要提示
确保在本地机器上正确安装技术要求对于跟随教程至关重要。本节假设您已按照技术要求部分安装了 MLflow 和 Docker。
到本节结束时,您将能够创建我们的基线流程。基线流程的价值在于能够快速迭代模型开发。因此,基本上,一个端到端的基础设施将提供给开发团队,其中包含用于训练和模型服务的占位符。由于所有这些都实现在了 MLflow 中,因此可以轻松实现不同类型团队在机器学习项目中的专业化和专注。工程团队将专注于改进流程,而数据科学导向的团队将有一种快速测试和评估其模型的方法:
-
在 MLflow 中实现启发式模型。
在以下代码块中,我们创建了
RandomPredictor类,这是一个从mlflow.pyfunc.PythonModel类派生的定制预测器。主要的predict方法返回 0 到 1 之间的随机数:import mlflow class RandomPredictor(mlflow.pyfunc.PythonModel): def __init__(self): pass def predict(self, context, model_input): return model_input.apply(lambda column: random.randint(0,1))我们使用 MLflow 中创建自定义模型的特定功能;有关自定义模型的更多详细信息,请参阅
mlflow.org/docs/latest/python_api/mlflow.pyfunc.html#pyfunc-create-custom。 -
在 MLflow 中保存模型。
以下代码块以
random_model的名称保存模型,以便以后检索。它在本地文件系统中的 MLflow 注册表中注册:model_path = "random_model" baseline_model = RandomPredictor() mlflow.pyfunc.save_model(path=model_path, python_model=random_model)在这个阶段,我们基本上实例化了模型,并按照本地环境配置将其存储在模型注册表中。
-
运行您的
mlflow作业:mlflow run . -
启动服务 API:
mlflow models serve -m ./mlruns/0/b9ee36e80a934cef9cac3a0513db515c/artifacts/random_model/ -
测试您模型的 API。
您可以访问一个非常简单的 Flask 服务器,可以运行您的模型。您可以通过在服务器上运行
curl命令来测试执行:curl http://127.0.0.1:5000/invocations -H 'Content-Type: application/json' -d '{"data":[[1,1,1,1,0,1,1,1,0,1,1,1,0,0]]}' [1]%
在这个阶段,我们有一个基线虚拟模型,模型开发团队的目标现在是要改进这个模型。这个相同的流程将在下一章中用于构建一个数据科学开发环境,该平台在本书中构建的初始算法。
摘要
在本章中,我们介绍了机器学习问题框架方法,并探讨了采用此框架的一些动机。
我们介绍了股票市场预测机器学习平台以及我们使用 ML 问题框架方法定义的初始预测问题集。
在本章中,我们简要介绍了将在本书其余部分使用的股票市场预测基本流程的用例。
在下一章中,我们将专注于使用本章中定义的问题创建一个数据科学开发环境,使用 MLflow。
进一步阅读
为了进一步扩展您的知识,您可以查阅以下链接中的文档:
-
关于谷歌机器学习问题框架的参考信息:
developers.google.com/machine-learning/problem-framing -
关于亚马逊机器学习框架的参考信息:
docs.aws.amazon.com/wellarchitected/latest/machine-learning-lens/ml-problem-framing.html
第二部分:模型开发和实验
本节涵盖了使用 MLflow 进行端到端模型开发的过程,包括通过 MLflow 进行实验管理,针对机器学习中的算法开发阶段。您将学习如何使用 MLflow 逐步开发您的机器学习模型,并使用 MLflow 进行管理。
本节包含以下章节:
-
第三章, 您的数据科学工作台
-
第四章, MLflow 中的实验管理
-
第五章, 使用 MLflow 管理模型
第三章:您的数据科学工作台
在本章中,您将了解在创建本地环境的情况下 MLflow 的应用,以便您可以使用 MLflow 提供的不同功能在本地开发机器学习项目。本章专注于机器学习工程,机器学习工程师最重要的角色之一是建立一个环境,让模型开发者和从业者可以高效工作。我们还将演示如何使用工作台完成特定任务的动手示例。
特别地,在本章中,我们将探讨以下主题:
-
理解数据科学工作台的价值
-
创建您自己的数据科学工作台
-
使用工作台进行股票预测
技术要求
对于本章,您需要以下先决条件:
-
在您的机器上安装的 Docker 最新版本。如果您尚未安装,请按照
docs.docker.com/get-docker/上的说明进行操作。已安装 Docker Compose 的最新版本。如果您尚未安装,请按照 https://docs.docker.com/compose/install/ 上的说明进行操作。
-
命令行中访问 Git,并按照本 统一资源定位符 (URL)
git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明进行安装。 -
访问
bash终端(Linux 或 Windows)。 -
访问浏览器。
-
已安装 Python 3.5+。
-
如在 第一章 中所述,本地安装 MLflow。
理解数据科学工作台的价值
数据科学工作台是一个环境,用于标准化组织的机器学习工具和实践,允许快速上线和开发模型和分析。机器学习工程的一个关键功能是支持数据科学从业者使用能够赋予他们力量并加速他们日常活动的工具。
在数据科学团队中,快速测试多种方法和技术的能力至关重要。每天都有新的库和开源工具被创建。一个项目可能需要超过十个库来测试一种新的模型。这些众多的库,如果未能正确整理,可能会在模型中引起错误或不兼容。
数据是数据科学工作流程的核心。拥有干净的数据集用于开发和评估模型至关重要。随着大量大型数据集的出现,需要专门的大数据工具来处理数据。数据可以以多种格式和速度进行分析或实验,并且可以以多种格式和介质提供。它可以通过文件、云或 REpresentational State Transfer (REST) 应用程序编程接口 (API)提供。
数据科学主要是一种协作工艺;它是团队成员之间共享模型和流程的工作流程的一部分。不可避免地,从这个活动中出现的一个痛点是模型开发作业在从业者之间的跨可重复性。数据科学家 A 分享了一个假设库版本 2.6 的模型训练脚本,但数据科学家 B 使用的是版本 2.8 的环境。在某些情况下,追踪和修复这个问题可能需要数小时。如果这个问题出现在生产环境中,它可能会对公司造成极大的成本。
在迭代——例如——模型时,每次运行都包含多个可以调整以改进模型的参数。如果我们不以结构化的方式存储实验的详细信息,那么维护哪个参数产生了特定的性能指标(例如准确性)的可追溯性可能会成为问题。如果在模型开发阶段只保留最新设置,那么回到产生更好模型的特定批次设置可能是不可能的。
迭代速度的需求在将原型代码翻译到可靠执行的生产环境时,可能会引起许多挫败感。例如,如果你在一个可以轻松访问图形处理单元(GPUs)进行推理的 Windows 机器上开发新的交易模型,你的工程团队成员可能会决定重用现有的无 GPU 访问的 Linux 基础设施。这导致你的生产算法最终需要 5 小时才能完成,而在本地运行只需 30 秒,影响了项目的最终结果。
很明显,如果不对环境和工具相关的问题进行前期处理,数据科学部门会面临系统性的技术痛点。总结来说,我们可以列出本节中描述的以下主要点:
-
可重复性摩擦
-
处理大型和多样化数据集的复杂性
-
实验设置管理不善
-
本地和生产环境之间的漂移
数据科学工作台通过创建一个结构化环境来解决本节中描述的痛点,在这个环境中,机器学习从业者可以授权可靠地开发和部署他们的模型,减少摩擦。无摩擦的环境将允许高度昂贵的模型开发时间专注于开发和迭代模型,而不是解决工具和数据技术问题。
在深入研究为机器学习团队构建数据科学工作台的动机之后,我们接下来将根据已知的痛点开始设计数据科学工作台。
创建自己的数据科学工作台
为了解决前述章节中描述的数据科学模型开发中的常见摩擦,我们需要为数据科学家和从业者提供一个标准化的环境,让他们可以在其中开发和管理工作。数据科学工作台应允许您快速启动项目,并且一套起始工具和框架的可用性允许数据科学家快速启动项目。
数据科学家和机器学习从业者处于工作台的中心:他们应该有一个可靠的平台,允许他们开发并为其组织增加价值,同时他们的模型触手可及。
以下图表展示了数据科学工作台的核心功能:
![Figure 3.1 – 数据科学工作台的核心功能
![img/B16783_03_001.jpg]
图 3.1 – 数据科学工作台的核心功能
为了思考我们数据科学工作台的设计,并基于图 3.1中的图表,我们需要在我们的数据科学工作台中具备以下核心功能:
-
依赖管理:在本地环境中集成依赖管理有助于处理可重复性问题,并防止不同环境之间的库冲突。这通常是通过使用环境管理器,如 Docker,或者在您的编程语言中提供环境管理框架来实现的。MLflow 通过支持基于 Docker 或 Conda 的环境来提供这一功能。
-
数据管理:如果您必须处理大量数据集,则在本地环境中管理数据可能会变得复杂且令人畏惧。在您的本地项目中有一个标准化的数据处理定义,允许他人自由协作并理解可用的结构。
-
模型管理:将不同的模型组织并妥善存储提供了一个易于工作的结构,能够同时处理许多想法并持久化那些有潜力的想法。MLflow 通过模型格式抽象和模型注册组件来支持这一点,以管理模型。
-
部署:在本地环境中与模型将提供服务的生产环境保持一致需要深思熟虑。生产环境需要准备好接收模型开发者的模型,以尽可能少的摩擦。这种平稳的部署工作流程只有在本地环境正确设计的情况下才可能实现。
-
实验管理:调整参数是机器学习从业者最常见的事情。能够跟上不同版本和特定参数可能会迅速变得繁琐,对模型开发者来说。
重要提示
在本节中,我们将从头开始使用 MLflow 实现数据科学工作台的基础,主要支持本地开发。云提供商如亚马逊网络服务(AWS)Sagemaker、谷歌 AI和Azure 机器学习(Azure ML)提供了一些非常具有意见和功能丰富的选项。
机器学习工程团队在所服务的团队使用的用例和技术方面有自由度。
以下步骤展示了使用数据科学工作台进行开发的良好工作流程:
-
模型开发者通过安装程序或克隆仓库来安装公司工作台包。
-
模型开发者运行一个命令以启动项目。
-
模型开发者根据配置或提示选择一组选项。
-
基本框架生成时,会为以下项目创建特定文件夹:
a)
Data:这将包含当前项目的所有数据资产b)
Notebooks:用于存放所有迭代开发笔记本,包括生成模型所需的所有步骤c)
Model:包含二进制模型或模型引用的文件夹,可能以二进制格式d)
Source Code:用于存储代码的结构化组件和可重用库e)
Output:用于存放项目特定输出的文件夹——例如,可视化、报告或预测 -
使用标准化的包、依赖管理和工具组织创建项目文件夹。
-
模型开发者可以自由迭代并使用组织级别的支持工具创建模型。
建立数据科学工作台为组织中的机器学习加速和民主化提供了一个工具,这是由于标准化和高效采用机器学习最佳实践的结果。
我们将在本章中开始我们的工作台实现,使用业界广泛使用的合理组件。
构建我们的工作台
我们将在开发环境架构中拥有以下组件:
-
Docker/Docker Compose:将使用 Docker 来处理架构中每个主要组件的依赖关系,Docker Compose 将用作不同软件组件容器之间的协调器。工作台架构的每个组件都在 Docker 中,其优势是元素库之间不会相互冲突。
-
JupyterLab:在机器学习环境中开发数据科学代码和进行数据分析的事实上环境。
-
MLflow:MLflow 是工作台的核心,提供实验跟踪、模型管理、注册和部署接口的功能。
-
PostgreSQL 数据库:PostgreSQL 数据库作为 MLflow 后端元数据的存储层,是当前架构的一部分。其他关系型数据库也可以用作 MLflow 后端元数据,但我们将使用 PostgreSQL。
我们的数据科学工作台设计可以在以下图表中看到:

图 3.2 – 我们的数据科学工作台设计
图 3.2 展示了我们将支持的数据科学工作台组件布局。
一旦环境启动并运行,实践者的常规工作流程是在 Jupyter 中开发他们的代码,并使用 MLflow 支持运行他们的实验。环境将自动路由到正确配置到正确后端的 MLflow 安装,如图 3.2 所示。
重要提示
根据本章定义,我们的数据科学工作台是一个完整的地方环境。随着本书的进展,我们将介绍基于云的环境,并将我们的工作台与共享资源链接。
以下 GitHub 文件夹中提供了一个项目布局的示例:
您可以在此处看到工作台文件布局的一般表示:
├── Makefile
├── README.md
├── data
├── docker
├── docker-compose.yml
├── docs
├── notebooks
├── requirements.txt
├── setup.py
├── src
├── tests
└── tox.ini
此文件夹结构的主要元素在此概述:
-
Makefile:这允许您控制工作台。通过发出命令,您可以要求工作台设置一个新的环境笔记本以以不同格式启动 MLflow。 -
README.md:一个包含项目示例描述及其如何运行的文件。 -
data文件夹:一个文件夹,用于存储开发期间使用的数据集,并在本地运行时挂载数据库的数据目录。 -
docker:一个包含我们环境所包含的不同子系统 Docker 镜像的文件夹。 -
docker-compose.yml:一个包含我们工作台环境中的不同服务编排的文件——即:Jupyter 笔记本、MLflow 和用于支持 MLflow 的 PostgreSQL。 -
docs:包含我们希望持久化的相关项目文档。 -
notebooks:一个包含笔记本信息的文件夹。 -
requirements.txt:一个要求文件,用于向项目添加库。 -
src:一个包含项目源代码的文件夹,将在项目的后续阶段进行更新。 -
tests:一个包含项目代码端到端测试的文件夹。 -
tox.ini:一个模板文件,用于控制单元测试的执行。
现在,我们将继续使用我们自己的开发环境来解决股票预测问题,基于我们刚刚构建的框架。
使用工作台进行股票预测
在本节中,我们将逐步使用工作台来设置新项目。按照步骤说明启动您的环境并使用工作台进行股票预测项目。
重要提示
在“技术要求”部分列出的所有软件包/库都必须正确安装在您的本地机器上,这对于您跟随教程至关重要。
启动你的环境
我们将接着探索您自己的开发环境,基于本节中所示的开发环境。请执行以下步骤:
-
复制位于 https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter03/gradflow 的项目内容。
-
通过运行以下命令启动您的本地环境:
make -
检查创建的环境,如下所示:
$ docker ps以下截图展示了三个 Docker 镜像:第一个用于 Jupyter,第二个用于 MLflow,第三个用于 PostgreSQL 数据库。状态应显示为
Up x minutes:

图 3.3 – 运行 Docker 镜像
您工作台通常使用的端口如下所示:Jupyter 在端口 8888 上运行,MLflow 在端口 5000 上运行,PostgreSQL 在端口 5432 上运行。
如果任何容器失败,您可能需要检查端口是否被不同的服务使用。如果是这种情况,您将需要关闭所有其他服务。
检查您的 Jupyter Notebooks 环境 localhost:8888,如下面的截图所示:

图 3.4 – 运行 Jupyter 环境
您应该有一个可用的环境,允许您在指定的文件夹中创建新的 notebooks 文件。
在 http://localhost:5000 上检查您的 MLflow 环境,如下面的截图所示:

图 3.5 – 运行 MLflow 环境
图 3.5 展示了您将在 MLflow 中使用的实验跟踪环境。
通过运行 /notebooks/mlflow_sample.ipynb 中的 notebook 文件在 MLflow 中运行一个示例实验,如下面的截图所示:

图 3.6 – mlflow_sample 代码摘录
图 3.6 中的代码导入 MLflow 并手动创建一个实验,在第二行使用 mlflow.set_experiment('mlflow_experiment')。
with mlflow.start_run() 行负责在 MLflow 中启动和拆除实验。
在接下来的三行中,我们使用 mlflow.log_param 函数记录几个字符串类型的测试参数。要记录数值,我们将使用 mlflow.log_metric 函数。
最后,我们还将使用 mlflow.log_artifact("mlflow_example.ipynb") 函数记录执行函数的整个文件,以确保模型及其源代码的可追溯性。
检查示例运行情况,以确认环境是否正常工作。您应该回到位于 http://localhost:5000 的 MLflow 用户界面(UI)并检查是否创建了新的实验,如下面的截图所示:

图 3.7 – MLflow 测试实验
图 3.7 显示了我们特定实验中使用的附加参数以及 指标 列中可见的特定指标 i。
接下来,您应该点击创建的实验以访问我们迄今为止执行的运行的详细信息。以下是一个截图示例:

图 3.8 – MLflow 实验细节
除了指标细节之外,您还可以访问特定时间点的 mlflow_example 笔记本文件。
在此阶段,您已经拥有一个按预期运行和工作的环境。接下来,我们将使用我们自己的算法来更新它;我们将使用我们在 第二章,您的机器学习项目 中创建的算法。
使用您自己的算法进行更新
让我们更新我们在 第二章,ML 问题框架 中创建的笔记本文件,并将其添加到您本地工作台上的笔记本文件夹中。代码摘录如下:
import mlflow
class RandomPredictor(mlflow.pyfunc.PythonModel):
def __init__(self):
pass
def predict(self, context, model_input):
return model_input.apply(lambda column: random.randint(0,1))
在 notebooks/stockpred_randomizer.ipynb 文件中的 notebook 文件夹下,您可以跟随我们最近创建的数据科学工作台中前面代码摘录的集成。我们将按以下步骤进行:
-
我们将首先导入所有需要的依赖项并运行笔记本的第一个单元,如下所示:
![图 3.9 – MLflow 实验细节]()
图 3.9 – MLflow 实验细节
-
让我们声明并执行 图 3.9 中概述的类,该类在笔记本的第二单元中表示,如下所示:
![图 3.10 – 包含 RandomPredictor 类声明的笔记本单元]()
图 3.10 – 包含 RandomPredictor 类声明的笔记本单元
-
我们现在可以在 MLflow 基础设施中保存我们的模型,以便我们可以测试模型的加载。
model_path包含模型将保存的文件夹名称。您需要在r变量中实例化模型,并使用mlflow.pyfunc.save_model将模型本地保存,如下面的代码片段所示:![图 3.11 – 展示保存模型的笔记本]()
图 3.11 – 展示保存模型的笔记本
您可以在笔记本环境左侧的窗格中看到,在您的文件旁边创建了一个新文件夹来存储您的模型。此文件夹将存储 Conda 环境以及您的模型的可 pickled/binarized Python 函数,如下面的截图所示:
![图 3.12 – 展示保存模型文件夹的笔记本]()
图 3.12 – 展示保存模型文件夹的笔记本
-
接下来,我们可以加载并使用模型来检查保存的模型是否可用,如下所示:

图 3.13 – 展示保存模型文件夹的笔记本
图 3.14 展示了创建一个随机输入 loaded_model 来预测输入向量的过程。我们将以 stockpred_experiment_days_up 为名运行实验,将每个模型在市场上涨的天数作为指标进行记录,如下所示:

图 3.14 – 展示加载模型使用的笔记本单元格
要检查实验的最后运行,你可以查看 http://localhost:5000 并确认新实验已被创建,如下面的屏幕截图所示:

图 3.15 – 我们 stockpred 实验的 MLflow 初始用户界面
你现在可以比较我们算法的多次运行,并查看天数上升指标的变化,如下面的屏幕截图所示。你可以相应地选择深入了解你想要更多详细信息的运行:

图 3.16 – 保存的工件日志细节
在图 3.16中,你可以清楚地看到我们运行的日志细节——即,工件模型和天数上升指标。
为了正确地拆除环境,你必须在同一文件夹中运行以下命令:
make down
摘要
在本章中,我们介绍了数据科学工作台的概念,并探讨了采用此工具作为加速我们的机器学习工程实践的一些动机。
我们根据需求设计了一个数据科学工作台,使用 MLflow 和基于相邻技术的技术。我们详细说明了使用 MLflow 设置你的开发环境的步骤,并说明了如何使用现有代码。在后面的章节中,我们探讨了工作台,并添加了我们上一章开发的股票交易算法。
在下一章中,我们将专注于使用 MLflow 进行实验,以改进我们的模型,使用本章开发的工作台。
进一步阅读
为了进一步扩展你的知识,你可以查阅以下链接中的文档:
-
Cookiecutter 文档页面:
cookiecutter.readthedocs.io/en/1.7.2/ -
关于 cookie cutters 的参考信息:
drivendata.github.io/cookiecutter-data-science/ -
数据科学工作台背后的动机:
dzone.com/articles/what-is-a-data-science-workbench-and-why-do-data-s#
第四章:MLflow 中的实验管理
在本章中,我们将通过创建不同的模型并比较 MLflow 中不同运行的指标来为您提供股票预测的实际经验。您将指导如何使用 MLflow 实验方法,以便不同的机器学习从业者可以共享指标并改进同一模型。
在本章中,我们将具体探讨以下主题:
-
开始使用实验模块
-
定义实验
-
添加实验
-
比较不同的模型
-
使用超参数优化调整您的模型
在这个阶段,我们目前有一个基于朴素启发式的基线管道。在本章中,我们将通过 MLflow 添加我们的技能集,以便能够对多个模型进行实验,并调整一个特定模型。
我们将深入研究第二章中介绍的“您的机器学习项目”中的Psystock公司案例,这是一个股票交易机器学习平台。在本章中,我们将向我们的平台添加比较多个模型和运行基准实验的功能,以便能够为特定的股票和股票代码创建预测器。
在数据科学函数中,一种常见的方法是为特定模型开发一个模型,涉及以下三个步骤:创建不同模型类型的基线模型,确定表现最佳的模型,并使用最佳模型进行预测。
技术要求
对于本章,您需要以下先决条件:
-
在您的机器上安装了最新版本的 Docker。如果您还没有安装,请按照
docs.docker.com/get-docker/中的说明进行操作。 -
安装了最新版本的 Docker Compose。请按照
docs.docker.com/compose/install/中的说明进行操作。 -
在命令行中访问 Git,并按照
git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明安装。 -
访问 bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
安装了 Python 3.5+。
-
您本地安装的最新机器学习版本,并在第三章,“您的数据科学工作台”中描述。
开始使用实验模块
要开始使用技术模块,您需要开始使用以下文件夹中为本章准备的环境:github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter04
在这个阶段,您应该能够执行 make 命令来构建工作台,以便跟随本章的内容。接下来,您需要输入以下命令以移动到正确的目录:
$ cd Chapter04/gradflow/
要启动环境,您需要运行以下命令:
$ make
开始管理 MLflow 中的实验的入口是 图 4.1 中所示的实验界面:
2
1
![图片 4.1 – MLflow 中的实验界面
![图片 B16783_04_01.jpg]
图 4.1 – MLflow 中的实验界面
在左侧面板(1)中,您可以管理和创建实验,在右侧(2)中,您可以查询特定实验的详细信息。
要创建一个新实验,您需要在左侧面板上点击 + 按钮,并添加您实验的详细信息,如图 图 4.2 所示:
![图片 4.2 – 创建新实验
![图片 B16783_04_02.jpg]
图 4.2 – 创建新实验
在简要介绍了跟踪服务器和实验管理功能之后,我们现在将使用工作台上的功能来应对本章的挑战。
定义实验
使用机器学习问题框架方法,我们现在将定义本章中股票价格预测问题的主要组件:
![图片 B16783_04_Table_(1).jpg]![表 4.1 – 机器学习问题框架回顾
![图片 B16783_04_Table_(2).jpg]
表 4.1 – 机器学习问题框架回顾
机器学习中的 F-score 指标是二元分类器的准确度度量,提供了在误分类(假阳性或假阴性)之间的良好平衡和权衡。更多详细信息可以在维基百科页面找到:en.wikipedia.org/wiki/F-score。
探索数据集
根据我们的机器学习问题框架,我们将使用 2020 年 1 月至 12 月的市场观察数据作为输入数据,这些数据由 Yahoo 数据 API 提供。
以下代码片段,使用了我们工作台中的 pandas_datareader 模块,使我们能够轻松检索我们想要的数据。完整的笔记本可以在github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/blob/master/Chapter04/gradflow/notebooks/retrieve_training_data.ipynb找到:
import pandas as pd
import numpy as np
import datetime
import pandas_datareader.data as web
from pandas import Series, DataFrame
start = datetime.datetime(2014, 1, 1)
end = datetime.datetime(2020, 12, 31)
btc_df = web.DataReader("BTC-USD", 'yahoo', start, end)
对于这个特定问题,我们将从 2014 年检索数据,直到 2020 年底,如图 图 4.3 中提供的表格所示。该表格提供了交易部分 BTC 股票的高、低、开盘价和收盘价的价值信息。这些数据将用于本章中模型的训练:
![图片 B16783_04_03.jpg]
图 4.3 – 列出从源(Yahoo Finance)检索的数据
可以通过绘制其中一个变量来轻松绘制这些数据,以说明数据的连续性:
btc_df['Open'].plot()
为了更详细地说明数据的性质,我们可以绘制数据的摘录:
![图 4.4 – 从源(雅虎财经)检索到的 BTC Open 变量的绘图]
![img/B16783_04_04.jpg]
图 4.4 – 从源(雅虎财经)检索到的 BTC Open 变量的绘图
在本节中明确定义我们将要实验的内容后,我们将添加新的模型,以便我们能够运行实验并在它们之间进行比较。
所需范围的数据方便地保存在 Chapter04/gradflow/notebooks/training_data.csv 文件中,时间范围从 2014 年到 2020 年(含),因此可以在建模阶段轻松检索。
添加实验
因此,在本节中,我们将使用 MLflow 的实验模块来跟踪不同模型的运行,并将它们发布到我们的工作台数据库中,以便可以并排比较性能结果。
实验实际上可以由不同的模型开发者进行,只要他们都指向共享的 MLflow 基础设施。
为了创建我们的第一个模型,我们将选择一组模型家族,并在每个案例上评估我们的问题。从更广泛的角度来看,分类的主要家族可以是基于树的模型、线性模型和神经网络。通过查看在每个案例上表现更好的指标,我们然后可以将调整引导到最佳模型,并将其用作我们的初始生产模型。
我们在本节中的选择包括以下内容:
-
逻辑分类器:线性模型家族的一部分,并且是常用的基线。
-
Xgboost:这属于树提升算法家族,其中许多弱树分类器被组装成一个更强的模型。
-
Keras:这类模型属于神经网络家族,通常用于数据量很大且特征之间关系非线性的情况。
设置新模型的步骤相当常见,每个模型都会有重叠和重复的代码。接下来,我们将从基于逻辑回归的分类器开始。
设置基于逻辑分类器的步骤
在本子节中,我们将使用 scikit-learn 实现逻辑回归分类器,并使用我们的输入数据训练模型。
该模型的完整笔记本可在本书的存储库中找到,并可用于在 Chapter04/gradflow/notebooks/mlflow_run_logistic_regression.ipynb 文件中跟随:
-
SKLearn模型、LogisticRegression和f1_score指标功能,这将使我们能够计算性能:import pandas import numpy as np import mlflow import tensorflow from tensorflow import keras import mlflow.keras from sklearn.metrics import f1_score,confusion_matrix from sklearn.model_selection import train_test_split -
training_data.csv文件:pandas_df = pandas.read_csv("training_data.csv") X=pandas_df.iloc[:,:-1] Y=pandas_df.iloc[:,-1] X_train, X_test, y_train, y_test = \ train_test_split(X, Y, test_size=0.33, random_state=4284, stratify=Y)使用
train_test_split函数将数据分为训练集和测试集,其中三分之一的用于测试,其余用于训练。 -
mlflow.set_experiment方法。这将创建一个实验(如果不存在)或将当前运行与一个实验关联。我们使用mlflow.sklearn.autolog()启用 MLflow 的自动功能来捕获实验的指标:mlflow.set_experiment("Baseline_Predictions") mlflow.sklearn.autolog() -
with。mlflow.start_run函数用于处理将运行与特定的run_name注册,以便它可以被识别,并包含fit模型,以及用于计算f1_score实验性能指标的评估代码:with mlflow.start_run(run_name='logistic_regression_model_baseline') as run: model = LogisticRegression() model.fit(X_train, y_train) preds = model.predict(X_test) y_pred = np.where(preds>0.5,1,0) f1 = f1_score(y_test, y_pred) mlflow.log_metric(key="f1_experiment_score", value=f1)此外,我们需要使用
mlflow.log_metric函数记录我们特定的指标f1_experiment_score。添加我们特定方法的主要原因是为每个模型,MLflow 中的自动记录功能使用每个底层框架默认的指标,通常这些指标并不匹配。
执行所有与模型开发相关的步骤后,我们现在可以导航到我们的运行并可视化实验的日志。在 图 4.5 中,你可以看到与逻辑回归、持续时间以及你在运行中使用的所有参数相关的特定参数:

图 4.5 – 逻辑回归模型细节
对于 SKLearn 模型,MLflow 自动记录混淆矩阵和精确率和召回率曲线,这对于检测模型在训练数据上的表现非常有用。例如,图 4.6 报告将存储在运行的艺术品中:

图 4.6 – 混淆矩阵指标
MLflow 为 Sklearn 提供了内置的指标,这为训练过程中产生的模型提供了更好的可见性,而无需开发者编写额外的代码。
设置基于 XGBoost 的分类器的步骤
我们现在将使用 XGBoost 库实现基于梯度树的算法。
该模型的完整笔记本可在本书的存储库中找到,并可用于在 Chapter04/gradflow/notebooks/mlflow_run_xgboost.ipynb 文件中跟随:
导入依赖项:XGBoost 库与指标函数一起导入:
import pandas
import mlflow
import xgboost as xgb
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
-
training_data.csv文件。 -
Baseline_Predictions,我们需要给 MLflow 指示通过mlflow.xgboost.autolog自动记录模型:mlflow.set_experiment("Baseline_Predictions") mlflow.xgboost.autolog() -
f1_score:with mlflow.start_run( run_name='xgboost_model_baseline') as run: model=xgb.train(dtrain=dtrain,params={}) preds = model.predict(dtest) y_bin = [1\. if y_cont > threshold else 0\. for y_cont in preds] f1= f1_score(y_test,y_bin) mlflow.log_metric(key="f1_experiment_score", value=f1)
执行所有与模型开发相关的步骤后,我们现在可以导航到我们的运行并可视化实验的日志。在 图 4.7 中,你可以看到与 xgboost_model_baseline、持续时间以及你在运行中使用的所有参数相关的特定参数:

图 4.7 – MLflow 中的 XGBoost 分类器细节
对于 XGBoost 模型,MLflow 自动记录特征信息和重要性。我们可以在 图 4.8 中看到模型存储在工作台 艺术品 部分的特征排名:

图 4.8 – XGBoost 在 MLflow 上的特征重要性
图 4.8 中的特征重要性图允许开发者从数据中了解模型的内部结构。在这种情况下,似乎输入向量的第 14 天的第 2 天和第 7 天是前两个有意义的特征。接下来,我们将实现一个基于深度学习的模型。
基于深度学习的分类器设置步骤
在本节中,我们将实现一个神经网络算法来解决我们的分类问题。
该模型的完整笔记本位于本书的仓库中,可以在 Chapter04/gradflow/notebooks/mlflow_run_keras.ipynb 文件中找到以进行跟随:
-
tensorflow,因为我们将其用作keras的后端:import pandas import numpy as np import mlflow import tensorflow from tensorflow import keras import mlflow.keras from sklearn.metrics import f1_score,confusion_matrix from sklearn.model_selection import train_test_split -
获取数据:请参考 设置基于 XGBoost 的分类器步骤 部分的第 2 步。
-
Baseline_Predictions,我们需要给 MLflow 指令,通过mlflow.tensorflow.autolog自动记录模型:mlflow.set_experiment("Baseline_Predictions") mlflow.tensorflow.autolog()Sklearn或 XGBoost 分类器,因此我们需要定义网络的层和架构。在这种情况下,需要按照 Tensorflow 的要求编译Sequential架构和模型:model = keras.Sequential([ keras.layers.Dense( units=36, activation='relu', input_shape=(X_train.shape[-1],) ), keras.layers.BatchNormalization(), keras.layers.Dense(units=1, activation='sigmoid'), ]) model.compile( optimizer=keras.optimizers.Adam(lr=0.001), loss="binary_crossentropy", metrics="Accuracy" ) -
run_name、拟合模型以及计算f1_score指标:with mlflow.start_run( run_name='keras_model_baseline') as run: model.fit( X_train, y_train, epochs=20, validation_split=0.05, shuffle=True, verbose=0 ) preds = model.predict(X_test) y_pred = np.where(preds>0.5,1,0) f1 = f1_score(y_test, y_pred) mlflow.log_metric(key="f1_experiment_score", value=f1)对于
keras模型,MLflow 会自动记录大量的神经网络相关数据,包括优化器、epoch 和批大小,以及其他在 图 4.9 中可以看到的相关信息:

图 4.9 – Keras 分类器模型细节
此外,TensorFlow 日志可以连接到 TensorBoard。这是一个 TensorFlow 内置工具,用于提供机器学习工作流程的可视化和指标。创建了接口,以便模型开发者可以利用本地的 TensorFlow 仪器和专业的可视化工具。
在我们的平台上设置好分类器后,在下一节中,我们将准备好比较使用 MLflow 开发的不同分类器的性能。
比较不同模型
我们在本节中为每个覆盖的模型运行了实验,并验证了所有不同的工件。只需查看我们的基线实验表,并选择共同的定制指标 f1_experiment_score,我们就可以看到表现最好的模型是基于逻辑回归的模型,F 分数为 0.66:

图 4.10 – 从目标指标的角度比较不同模型性能
指标也可以并排比较,如图 图 4.11 所示。在左侧,我们有 SKlearn 模型,在右侧是 XGBoost 模型,带有自定义的 f1_experiment_score 指标。我们可以看到,两者提供的指标是不同的,因此当我们有不同模型时,自定义指标的原因:

图 4.11 – Sklearn 模型的指标
比较指标后,很明显最佳模型是逻辑回归。为了改进模型,在下一节中,我们将使用最先进的技术来优化其参数,并使用 MLflow 实验功能来实现这一点。
使用超参数优化调整模型
机器学习模型有许多参数,允许开发者提高性能并控制他们所使用的模型,提供更好的数据拟合和生产用例的杠杆。超参数优化是系统地、自动地识别机器学习模型最佳参数的过程,对于此类系统的成功部署至关重要。
在上一节中,我们确定了针对我们问题的最佳模型族(换句话说,LogisticRegression),因此现在我们需要使用 MLflow 来确定我们模型的正确参数。您可以在项目仓库中的以下笔记本中跟随操作,位于 Chapter04/gradflow/notebooks/hyperopt_optimization_logistic_regression_mlflow.ipynb:
-
hyperopt库,其中包含多个算法帮助我们进行模型调优:from hyperopt import tpe from hyperopt import STATUS_OK from hyperopt import Trials from hyperopt import hp from hyperopt import fmin from sklearn.linear_model import LogisticRegression from sklearn.model_selection import cross_val_score from sklearn.model_selection import train_test_split -
我们模型中的
f1_score指标。在hyperopt中,优化是通过最小化来实现的,但在这个案例中,我们希望得到最大的f1_score指标。因此,我们定义损失(最小化的函数)的方式是f1_score指标的倒数,即loss = 1-fscore,这样这个函数的最小化将代表最佳的f1_score指标。对于模型参数的每一次运行,我们将它包裹在mlflow.start_run(nested=True)中,这样每次优化迭代都会作为主任务的子运行被记录,从而在比较运行间的指标时提供多项优势:N_FOLDS = 3 MAX_EVALS = 10 def objective(params, n_folds = N_FOLDS): # Perform n_fold cross validation with #hyperparameters # Use early stopping and evaluate based on ROC AUC mlflow.sklearn.autolog() with mlflow.start_run(nested=True): clf = LogisticRegression(**params, random_state=0, verbose =0) scores = cross_val_score(clf, X_train, y_train, cv=5, scoring='f1_macro') # Extract the best score best_score = max(scores) # Loss must be minimized loss = 1 - best_score # Dictionary with information for evaluation return {'loss': loss, 'params': params, 'status': STATUS_OK} -
best变量。核心功能是最小化,由fmin(fn = objective, space = space, algo = tpe.suggest, max_evals = MAX_EVALS, trials = bayes_trials)表示,其中我们提供了之前定义的参数空间和目标函数:# Algorithm tpe_algorithm = tpe.suggest # Trials object to track progress bayes_trials = Trials() mlflow.set_experiment("Bayesian_param_tuning") with mlflow.start_run(): best = fmin(fn = objective, space = space, algo = tpe.suggest, max_evals = MAX_EVALS, trials = bayes_trials) -
运行实验几分钟之后,我们现在可以回顾
Hyperopt_Optimization实验中的实验:![图 4.12 – 列出超参数调优的所有嵌套运行![图片]()
图 4.12 – 列出超参数调优的所有嵌套运行
-
通过点击
training_f1_score和求解器:![图片]()
图 4.13 – 列出超参数调优的所有嵌套运行
-
我们可以轻松地在同一界面中比较不同的求解器和对我们性能指标的影响,从而进一步了解我们的建模阶段:

图 4.14 – 列出超参数调优的所有嵌套运行
我们通过优化当前问题的最有效模型的参数来结束本节。在本书的下一章中,我们将使用最佳模型提供的信息,深入探讨MLflow中模型管理的生命周期。
摘要
在本章中,我们介绍了 MLflow 的实验组件。我们了解了 MLflow 中的日志指标和工件。我们详细说明了在 MLflow 中跟踪实验的步骤。
在最后几节中,我们探讨了使用本章学到的概念进行超参数优化的用例。
在下一章中,我们将专注于使用本章开发的模型,利用 MLflow 来管理模型。
进一步阅读
为了进一步巩固你的知识,你可以查阅以下链接中的文档:
第五章:使用 MLflow 管理模型
在本章中,您将了解 MLflow 中模型管理的不同功能。您将了解 MLflow 中的模型生命周期,我们将解释如何将其与您的常规开发工作流程集成以及如何创建 MLflow 中不可用的自定义模型。模型生命周期将与 MLflow 的模型注册表功能一起介绍。
具体来说,在本章中,我们将查看以下部分:
-
理解 MLflow 中的模型
-
探索 MLflow 中的模型风味
-
管理模型和签名模式
-
使用模型注册表管理生命周期
从工作台的角度来看,我们希望使用 MLflow 来管理我们的模型并实施一个清晰的模型生命周期。通过将管理模型功能添加到我们的基准测试中,利用 MLflow 将提高我们机器学习工程解决方案的质量和运营。
技术要求
对于本章,您需要以下内容:
-
在您的机器上安装了最新版本的 Docker。如果您还没有安装,请按照
docs.docker.com/get-docker/中的说明进行操作。 -
最新版本的
docker-compose已安装。请按照 https://docs.docker.com/compose/install/ 中的说明进行操作。 -
在命令行中访问 Git 并按照
git-scm.com/book/en/v2/Getting-Started-Installing-Git中描述的方式进行安装。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
安装了 Python 3.5+。
-
本地安装了您机器学习工作台的最新版本,如第三章中所述,您的数据科学工作台。
理解 MLflow 中的模型
在 MLflow 平台上,您有两个主要组件可用于管理模型:
-
模型:此模块管理平台上的格式、库和标准执行模块。它支持最常用的多种机器学习模型:sklearn、XGBoost、TensorFlow、H20、fastai 等。它具有管理模型输出和输入模式的功能,并便于部署。
-
模型注册表:此模块处理模型生命周期,从注册和标记模型元数据以便相关系统检索。它支持不同状态的模型,例如,实时开发、测试和生产。
MLflow 模型在本质上是一种模型打包格式。MLflow 模型打包的主要目标是使模型类型与其执行环境解耦。MLflow 模型的类比有点像模型的 Dockerfile,其中您描述模型的元数据,并且上游的部署工具能够根据规范与模型交互。
如图 5.1 中的图所示,在一侧您有您的模型库,例如 TensorFlow 或 sklearn。在 MLflow 的核心,您有 MLflow 模型格式,它能够以多种风味(模型格式)提供,以满足本地和云上不同类型的推理工具:

图 5.1 – MLflow 模型图
图 5.1是从 URL www.infoq.com/presentations/mlflow-databricks/# 提取的。
MLflow 模型定义的核心部分是 MLflow 模型文件,如图中下一个屏幕截图所示:

图 5.2 – MLmodel 文件的示例
一个 MLmodel 示例可以在图 5.2 中看到,并提供以下信息:
-
运行 ID:这是对项目模型运行的引用,该运行允许创建模型。
-
创建时间:模型创建的时间戳。
-
MLflow 提供的
pyfunc模型。 -
签名:这是 MLmodel 中定义模型签名并允许您以某种方式类型化模型推理过程的组件。它允许验证需要与模型签名匹配的输入数据。
pyfunc。此函数在支持 Python 的任何环境中都受支持,为模型的部署者提供了在 MLflow 中记录模型后如何最佳运行模型的灵活性:
-
在项目的 GitHub 仓库中,请转到
Gradflow文件夹,并按照以下命令启动本章的环境:make -
您可以运行包括图 5.3 中显示的模型单元格在内的所有单元格:
![图片]()
图 5.3 – MLmodel 文件的示例
图 5.3 中的模型应该与第四章中使用的模型非常相似,即 MLflow 中的实验管理。使用
mlflow.start_run,您可以在 MLflow 中开始记录模型,并利用平台固有的功能来捕获正在开发的模型的相关细节。 -
您现在可以探索 MLflow 中的
MLmodel文件!![图片]()
图 5.4 – MLmodel 文件的示例
-
在 MLflow 中探索
conda文件!![图片]()
图 5.5 – MLmodel 文件的示例
-
将模型以
MLflow Pyfunc格式加载进行预测:import mlflow logged_model = ‘/data/artifacts/1/132e6fa332f2412d85f3cb9e6d6bc933/artifacts/model’ # Load model as a PyFuncModel. loaded_model = mlflow.pyfunc.load_model(logged_model) # Predict on a Pandas DataFrame. import pandas as pd loaded_model.predict(pd.DataFrame(X_test))或者,模型可以以原生 H5 Keras 格式加载,并加载到完全不同的应用程序中,如图 5.4 所示,使用
/data/model/model.h5文件。
在本节介绍了 MLflow 中的模型概念之后,我们将进一步深入探讨 MLflow 中不同类型的模型。
探索 MLflow 中的模型风味
MLflow 中的模型风味基本上是 MLflow 支持的不同库的不同模型。此功能允许 MLflow 使用每个特定模型的本地库处理模型类型,并支持一些模型的本地功能。以下列表展示了代表模型的选取,以描述和说明 MLflow 中可用的支持:
-
mlflow.tensorflow: TensorFlow 是迄今为止最常用的库之一,特别适合深度学习。MLflow 通过以 TensorBoard 格式保存日志,与模型格式和监控能力进行原生集成。MLflow 支持 TensorFlow 模型的自动记录。 -
mlflow.h2o: H2O 是一个面向模型自动化的完整机器学习平台,与 MLflow 有一些重叠的功能。MLflow 提供了在 H2O 原生格式中加载(load_model)和记录模型(log_model)的能力,允许工具之间的互操作性。不幸的是,截至当前 MLflow 版本,你无法在h2o模型上使用自动记录:mlflow.h2o.load_model(...) mlflow.h2o.log_model(...) -
mlflow.spark: MLflow 通过两个主要接口与 Apache Spark 库进行原生集成:Spark MLlib 用于机器学习,以及 MLeap 平台(https://combust.github.io/mleap-docs/)。Mleap 更像是一个部署平台,而 MLlib 则更像是一个你可以添加到项目中的库。
MLflow 支持非常全面的口味/格式列表,它们的用法和支持可以在这里阅读:www.mlflow.org/docs/latest/python_api/index.html.
)
自定义模型
我们可以深入探讨下一段代码和自定义的RandomPredictor模型。只要提供一个具有fit和predict方法接口的类,你就可以拥有自己的自定义 MLflow 模型:
class RandomPredictor(mlflow.pyfunc.PythonModel):
def __init__(self):
pass
def fit(self):
pass
def predict(self, context, model_input):
return model_input.apply(
lambda column: random.randint(0,1))
在前面的class中,我们基本上使用随机概率,它可以作为一个样本模型,用于确保你的模型比随机模型更好。
在本节中,我们介绍了不同类型的模型风味和自定义模式的创建。接下来,我们将探讨 MLflow 的一些模式和签名特征。
管理模型签名和模式
MLflow 的一个重要特性是提供模型输入和输出模式的抽象,以及在预测和训练期间验证模型数据的能力。
如果你的输入在预测期间不匹配模型的模式和签名,MLflow 会抛出一个错误:
-
接下来,我们将查看一个简单的数字分类模型(数据集的详细信息可在以下链接找到:
archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits)的代码示例。以下代码将图像展平为 pandas DataFrame,并将模型拟合到数据集:from sklearn import datasets, svm, metrics from sklearn.model_selection import train_test_split import mlflow digits = datasets.load_digits() n_samples = len(digits.images) data = digits.images.reshape((n_samples, -1)) clf = svm.SVC(gamma=0.001) X_train, X_test, y_train, y_test = train_test_split( data, digits.target, test_size=0.5, shuffle=False) mlflow.sklearn.autolog() with mlflow.start_run(): clf.fit(X_train, y_train) -
我们将查看之前的代码列表,您可以在新的笔记本中运行它,并通过 MLflow UI 深入调查 图 5.6 中生成的 MLmodel:
![]()
图 5.6 – MLmodel 文件示例
-
MLmodel 文件包含输入和输出文件的 JSON 签名。对于一些自动记录的变体,我们可能无法自动推断签名,因此您可以在记录模型时提供签名:
# flatten the images from mlflow.models.signature import infer_signature with mlflow.start_run(run_name=’untuned_random_forest’): … signature = infer_signature(X_train, wrappedModel.predict(None, X_train)) mlflow.pyfunc.log_model(“random_forest_model”, python_model=wrappedModel, signature=signature)
在之前的代码块中,模型的签名由 infer_signature 方法提供。当模型通过 log_model 记录时,签名被提供。签名与模型一起记录的一个重要优点是它们可以作为模型的文档和元数据。第三方系统可以消费元数据并通过验证数据或为模型生成文档与模型交互。
在本节中,我们介绍了 MLflow 模型的模式化和签名功能。现在我们将继续探讨这个空间中的另一个关键模块,即模型注册表。
介绍模型注册表
MLflow 模型注册表是 MLflow 中的一个模块,它包含一个用于存储模型的集中存储库,一个允许在注册表中管理模型生命周期的 API。
对于机器学习模型开发者来说,一个典型的流程是获取训练数据;清理、处理和训练模型;然后将其交给负责部署模型的人员或系统。在非常小的环境中,如果您有一个人负责这个功能,这相当简单。当团队中模型的种类和数量开始扩展时,挑战和摩擦开始出现。以下是一些机器学习开发者提出的关于存储和检索模型的常见摩擦点:
-
在大型团队中的协作
-
生产中淘汰过时的模型
-
模型的来源
-
模型缺乏文档
-
识别模型的正确版本
-
如何将模型与部署工具集成
MLflow 模型注册表背后的主要思想是在组织中提供一个中央存储模型的地方,所有相关模型都存储在此,并且可以被人类和系统访问。一个很好的类比就是具有相关元数据和模型集中状态管理的模型 Git 仓库。
在 MLflow UI(可在您的本地环境中使用)中,您应单击 实验 标签右侧带有 模型 标签的选项卡,如箭头所示:
-
通过此模块,您能够列出所有已注册的模型,按名称搜索或按名称创建。对于每个模型,您可以看到最新版本的标签以及处于预发布或生产中的特定版本!
图 5.7 – 模型注册表 UI
-
可以通过点击 创建模型 按钮创建一个新模型,并为特定模型指定一个相关名称,如图 5.8 所示:
![]()
图 5.8 – 模型注册库 UI – 创建模型
-
你也可以通过进入 实验 模型并选择你的一个模型来在 MLflow 中创建模型,然后,具体决定注册该模型。你将必须将你的运行与现有模型关联或创建一个新模型名称,以关联此特定类型的模型:

图 5.9 – 模型跟踪 UI – 创建新模型
当你添加一个新模型时,MLflow 会自动增加版本号,并将此版本标记为最新版本,组织中的每个人都可以查询给定问题的模型的最新版本。
将你的最佳模型添加到模型注册库
在 MLflow 的 UI 中可以执行的所有操作也可以通过 MLflow API 实现。
我们可以快速回到我们的股票市场预测用例,并将我们的第一个基线模型添加到模型注册库,并运行本章仓库中可用的 hyperopt_optimization_logistic_regression_mlflow.ipynb 笔记本,并根据图 5.10 所示的 F1 分数指标按降序排序运行:

图 5.10 – 选择最佳模型
从那里,你应该能够注册名为 BTC StockPrediction 的最佳模型,如图 5.11 所示:

图 5.11 – 命名你的模型
通过返回模型模块,你将注意到,如图 5.12 所示,你的新创建的模型位于 版本 1 下:

图 5.12 – 已注册模型
在介绍了模型注册库的功能后,在下一节中,我们将描述一个模型开发生命周期,以帮助组织你的模型管理。
管理模型开发生命周期
在一个由多个模型开发者组成的团队中工作,管理模型生命周期非常重要。在同一个项目中尝试不同模型是相当常见的,让审阅者决定最终进入生产的模型非常重要:

图 5.13 – 模型开发生命周期的示例
如果使用与图 5.13 所示类似的生命周期,模型在其生命周期中可以经历以下阶段:
-
开发:模型开发者仍在探索和尝试不同的方法,仍在尝试找到解决他们的机器学习问题的合理解决方案。
-
预发布:模型可以与生产类型流量自动测试的状态。
-
生产:当模型准备好处理现实生活中的生产流量时。
-
存档:当模型不再服务于其最初开发时的业务目的时,它将被存档,其元数据将存储以供将来参考或合规性使用。
例如,如图 5.14所示,审稿人或主管可以将模型从开发状态移动到预发布状态,以便在测试环境中进一步部署,如果经审稿人批准,模型可以过渡到生产状态:

图 5.14 – 模型开发生命周期的示例
在从 MLflow 中的状态转换时,你有选择将处于现有状态的模型发送到下一个状态:

图 5.15 – MLflow 中的阶段转换
在成熟环境中,从预发布阶段到生产阶段的转换旨在自动进行,正如我们将在本书的后续章节中展示的那样。
通过本节,我们完成了与 MLflow 中模型相关特性的描述。
摘要
在本章中,我们首先介绍了 MLflow 中的模型模块及其对不同算法的支持,从基于树的到线性的再到神经网络的。我们了解了模型日志和指标的支持以及自定义指标的创作。
在前两节中,我们介绍了模型注册模型及其如何使用它来实现模型生命周期来管理我们的模型。
在本书的下一章和章节中,我们将专注于将到目前为止学到的概念应用于现实系统,并将为生产环境设计一个机器学习系统。
进一步阅读
为了巩固你的知识并深入了解本章中介绍的概念,你应该查看以下链接:
第三部分:生产环境中的机器学习
本节将介绍 MLflow 中可用于将模型从开发阶段无缝过渡到生产环境的各种功能。
本节涵盖了以下章节:
-
第六章, 介绍机器学习系统架构
-
第七章**, 数据和特征管理
-
第八章**, 使用 MLflow 训练模型
-
第九章**, 使用 MLflow 进行部署和推理
第六章:介绍机器学习系统架构
在本章中,你将了解在更广泛的软件工程(SWE)背景下机器学习(ML)系统架构的一般原则,以及以可靠方式在生产中部署模型时常见的常见问题。你还将有机会跟随我们构建我们的机器学习系统。我们将简要探讨如何使用 MLflow 以及其他相关工具构建可靠和可扩展的机器学习平台。
具体来说,在本章中,我们将探讨以下部分:
-
理解机器学习系统和项目中的挑战
-
调查最先进的机器学习平台
-
构建 PsyStock 机器学习平台
你将遵循一个理解问题、研究行业领先公司提供的不同解决方案,然后开发你自己的相关架构的过程。这种三步法可以转移到你想要开发的任何未来的机器学习系统中。
技术要求
对于本章,你需要满足以下先决条件:
-
在你的机器上安装了最新版本的 Docker。如果你还没有安装,请按照
docs.docker.com/get-docker/中的说明操作。 -
已安装
docker-compose的最新版本。请按照docs.docker.com/compose/install/中的说明操作。 -
在命令行中访问 Git,并按照
git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明进行安装。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
已安装 Python 3.5+。
-
如第三章中所述,在本地安装了与你的机器学习平台最新版本兼容的版本,你的数据科学工作台。
理解机器学习系统和项目中的挑战
利用机器学习实现产品可能是一项费力的任务,因为需要在书中介绍一些关于机器学习系统架构最佳实践的新概念。
到目前为止,在这本书中,我们已经展示了 MLflow 如何使日常模型开发者拥有一个平台来管理从模型开发迭代到在模型注册表中存储模型整个机器学习生命周期。
总结来说,到目前为止,我们已经为模型开发者创建了一个平台,让他们可以构建模型并在中央仓库中发布模型。这是开始挖掘创建的模型商业价值理想阶段。在机器学习系统中,要从模型开发跃迁到生产中的模型,需要转变思维方式和采取不同的方法。在解锁价值和构建模型之后,利用阶段开始,这时拥有机器学习系统架构可以为你的模型部署和运营定下基调。
机器学习系统是传统软件开发(SWE)领域的专业化分支,因此我们可以也应该利用 SWE 领域的知识体系来构建我们的系统。与我们相关联的 SWE 概念如下:
-
关注点分离:一个完整的系统应该被分割成不同的组件。系统的每个组件都应该是独立的,并且专注于做好一件事。例如,一个训练组件应该专注于训练,而不是同时进行评分。
-
自主性:系统的每个组件都应该作为一个独立的自主单元存在,并且可以独立部署。例如,您的 API 系统的部署应该独立于训练系统的部署。
-
弹性:关注点分离和模块化的一个后果是我们必须确保如果更广泛系统的一个组件出现故障,这不会影响独立组件。如果一个机器平台的批量评分机制出现故障,它不应该影响实时系统。
-
可扩展性:我们应该能够独立并根据其工作负载独立扩展系统的不同组件。
-
可测试性:这代表系统被测试的能力以及其功能与一组代表性输入进行验证的能力。在机器学习系统中,由于模型的非确定性,这一点尤其困难。
-
持续部署/交付:这代表在几乎没有任何摩擦的情况下,在代码、配置、模型或数据发生变化时部署系统的能力,在机器学习的情况下,以便有新版本的系统。
-
可组合性:我们应该能够将系统的组件在未来项目中重复使用,以提高投资回报率。因此,机器学习工程师需要确保正在开发的代码和组件易于重复使用和/或与其他系统互操作。
-
可维护性:这是系统被修改、修复和改进以适应不断变化的环境需求的容易程度。
在这个阶段,我们可以简要介绍并细化我们的用例,即股票预测,以在 PsyStock 公司开发我们的机器学习平台。
基于迄今为止在原型设计模型以预测比特币价格方面所做的工作,公司的业务发展部门决定将其第一个产品作为加密货币预测 API来启动,因为它们正在成为企业界的一种流行技术。一个团队被组建起来,决定调查挑战和最先进的平台,然后构建公司的自有平台。
一个机器学习项目通常涉及公司中的许多部门。以 PsyStock 为例,一个典型的机器学习项目团队包括以下利益相关者:
-
数据科学团队:负责构建和发展模型,目标是实现最高准确率,预测加密货币价格和市场走势。
-
机器学习/数据工程团队:负责工程组件,包括数据采集、准备、训练和部署,并关注系统在生产中正确部署并按规格运行。
-
基础设施团队:负责提供计算和基础设施资源。期望系统不会给团队带来运营负担。
-
产品团队:提供与公司网络平台和整体软件的集成,推动功能创建,确保快速推理速度。
-
业务发展/市场营销团队:打包和营销产品,并监控产品的业务表现。
在下一节中,我们将了解机器学习系统和项目的一般挑战。
机器学习(ML)是技术的一个重要应用,旨在帮助组织利用数据释放价值。在商业世界中应用机器学习时,尚未定义标准实践,许多组织都难以将基于机器学习的产品投入生产。
在现实世界中,将模型投入生产的简单方法可能包括以下步骤:
-
数据科学家在笔记本环境中创建模型,并在 R 语言中实现代码。
-
数据科学家与工程团队分享笔记本,表示他们已准备好将他们的模型投入生产。
-
工程团队使用他们能理解的语言重新实现了训练过程,在这种情况下,是 Python 语言。
-
经过长时间的试错过程,直到数据科学团队和工程团队达成一致,认为定制化训练系统产生的模型与原始模型产生等效的输出。
-
创建并开发了一个新的系统来评分系统,工程团队注意到高延迟。由于当前状态无法重新开发,模型被发送回重新开发。
上一段描述的情况比你想象的更常见。这在 D. Sculley 等人于 2015 年发表的论文《机器学习系统中隐藏的技术债务》中有详细描述。谷歌的一个团队识别了以下与天真地实施机器学习平台相关的风险因素和技术债务:
-
边界侵蚀:由于机器学习系统的本质是混合不同逻辑域的信号,因此在 SWE 中尽可能保持业务域的清晰逻辑具有挑战性。另一个自然问题是将模型输出作为第三个模型A的输入的诱惑,这可能会在模型B中产生意外的效果。
-
昂贵的依赖数据:新鲜、准确和可靠的数据是机器学习系统最重要的组成部分。例如,在加密货币案例中,为了能够预测,可能会结合使用外部 API 和社会网络情绪信号。在某个时刻,其中一个数据信号可能不可用,使得其中一个组件不可用。现实世界中的数据分布可能会改变,导致模型在现实世界中的推理变得不相关。
-
反馈循环:在某些情况下,模型会影响用于训练的数据选择。信用评分就是一个很好的例子。决定谁将获得模型下一次重新训练的信用的人将选择受模型影响的人群中的训练数据。在开发模型时,分析模型对地面数据的影响是很重要的。
-
系统级反模式:机器学习系统因其包含不同包和缺乏适当抽象的粘合代码而臭名昭著。在某些情况下,由于在笔记本中编写代码的迭代性质,可能会使用多种语言来实现库。
-
配置管理:通常在机器学习系统中被忽视,但特定结果产生的配置信息对于模型的后分析和部署至关重要。不使用既定的配置管理实践可能会在机器学习管道中引入错误。
-
监控和测试:集成测试和单元测试是 SWE 项目中的常见模式,但由于机器学习项目的随机性质,它们更难实施。
解决机器学习系统挑战的一个重要实践是在模型训练期间以及系统运行时,对过程的临界部分、代码进行广泛的测试,如图 6.1 所示:

图 6.1 – 从 https://research.google/pubs/pub46555/提取的机器学习系统测试
图 6.1 所展示的是通过标准软件实践测试系统的不同部分,并添加专门的数据预测监控来应对技术债务的一种方法。重要的新增加是数据测试和模型测试,因此测试传入数据和训练数据,同时能够监控这些测试并决定系统是否通过相关标准是至关重要的。
作为平台,MLflow 解决了本节中提到的机器学习系统的一些问题。MLflow 专注于机器学习技术债务的特定维度,是创建机器学习平台的一个很好的支柱组件。
在下一节中,我们将探讨一些最先进的鲁棒机器学习工程系统的例子,以指导我们的开发。
调查最先进的机器学习平台
从高层次来看,一个成熟的机器学习系统具有图 6.2中概述的组件。这些组件理想上是独立的,并负责系统的特定功能:

图 6.2 – 机器学习平台组件
遵循 SWE 模块化的先例,这些通用组件使我们能够比较不同的机器学习平台,并指定我们对 PsyStock 每个组件的要求。我们选择用作架构比较参考的组件如下:
-
数据和特征管理:数据和特征管理组件负责数据采集、特征生成、存储以及向上游模块提供服务。
-
训练基础设施:处理模型训练过程、调度、消耗特征以及生成最终模型的组件。
-
部署和推理:该单元的职责是模型的部署推理和批处理评分。它是系统的外部面孔,对外部系统是可访问的。
-
性能和监控:一个处理可观察性、不同系统发布的指标以及生产中的监控系统的组件。
-
模型管理:管理模型工件版本和模型的生命周期。
-
工作流管理:负责编排批处理工作流和处理管道的组件。
在描述了机器学习平台的不同组件之后,我们将查看一些示例,从 Uber 的 Michelangelo 开始。
了解 Michelangelo
Uber 是首批广泛记录其认识到机器学习平台对于释放数据价值至关重要的公司之一。
Uber 构建平台内部动机如下:
-
由于将本地模型转换为生产所需的大量资源,机器学习的影响有限。
-
不可靠的机器学习和数据管道。
-
工程团队必须为现有系统创建定制的服务容器和系统。
-
无法扩展机器学习项目。
以下图 6.3(来自eng.uber.com/michelangelo-machine-learning-platform)展示了 Michelangelo 的不同组件。一个显著组件是 Uber 基础设施中的数据组件,它将实时数据基础设施与流系统(如 Kafka)解耦,以从外部获取数据,这些数据流向训练过程,然后到实时和离线模式下的评分。独特的特征包括批处理世界和实时世界的分离,以及为 API 和批处理系统提供通用预测服务:

图.6.3 – Michelangelo 架构
我们选择用作架构比较参考的组件如下:
-
数据和特征管理:它包含一个集中式数据存储,其中包含为服务模型和训练模型所需的所有特征。特征数据存储可以实时和批量访问。对于批量场景,他们使用名为 Hive 的数据库系统,对于实时,他们使用 Cassandra。
-
训练基础设施:使用名为Horovod(
github.com/horovod/horovod)的工具提供的分布式训练基础设施,具有专门和定制的组件以及增强的报告功能。它为每种类型的模型(深度学习、模型、特征重要性等)提供自定义指标。训练作业的输出是使用 Cassandra 数据库作为后端的模型存储库。 -
部署和推理:通过标准的 SWE 实践(CI/CD、基于指标监控的回滚等)部署的系统,通常作为工件在 Uber 数据中心提供。一个预测服务接收请求,并根据头部信息预先加载正确的模型,并使用内部 DSL 在特征存储的服务层查询进一步的数据增强,从而提供预测向量。
-
性能和监控:它利用公司通用的集中式日志系统。对于监控预测,会生成预测和现实世界值的相关指标,并将差异记录下来。通过这种方式,可以分析和监控模型的错误。
-
模型管理:模型作为工件编译并存储在 Cassandra 数据存储中。
-
工作流管理:提供用于连接管道的 API。它包含一个管理平面,其中包含一个 UI,允许管理模型和部署。工作流管理是 API 驱动的,可以从外部使用 Python 或 Java 进行管理。
对于像 Uber 这样的公司来说,建立自己的系统的一个明显优势是灵活性和满足他们非常具体用例的能力。
了解 Kubeflow
Kubeflow 在某种程度上是一个针对Kubernetes环境的开源平台,用于机器学习生命周期。它基本上是一个工具生态系统,这些工具协同工作以提供机器学习平台的主要组件。Kubeflow 最初是在谷歌开发的,目前是一个非常活跃的开源项目。
Kubernetes是领先的开放源代码计算环境之一,它允许在容器化工作负载中灵活分配计算和存储资源。它最初是在谷歌创建的。为了理解 Kubeflow,需要基本了解 Kubernetes。以下官方文档链接包含了理解基础所需的前提条件:kubernetes.io/docs/concepts/overview/。
如 图 6.4 所示,它使用 Kubernetes 的基础,提供了一套机器学习工作流的应用程序,其中可以聚合与 Kubeflow 标准兼容的不同工具,以提供一套连贯的服务:

图 6.4 – 来自 https://www.kubeflow.org/docs/started/kubeflow-overview/
我们选择用作架构比较参考的组件如下:
-
数据和特征管理:Kubeflow 提供与 Spark 等大数据工具的集成。用于数据和特征管理的一个生态系统组件称为 Feast,是一个开源的机器学习特征。
-
训练基础设施:Kubeflow 为常见的模型如 TensorFlow、PyTorch 和定制模型提供特定的 Kubeflow 运算符。训练作业基本上是特定的 Kubernetes 作业。
-
部署和推理:Kubeflow 提供与 TensorFlow Serving、Seldon Core 和 KFServing 等第三方工具的多个集成,具有不同的权衡和成熟度水平。
-
性能和监控:Prometheus 是一种在 Kubernetes 环境中使用的通用监控工具,可以在此环境中利用。
-
模型管理:不是专门用于管理模型的工具,但可以添加如 MLflow 这样的工具来覆盖模型管理生命周期。
-
工作流管理:通过一个名为 Kubeflow Pipelines 的特定工具进行工作流管理,该工具建立在 Kubernetes 上的通用管道工具 Argo Workflows 之上。它允许通过代码构建多步骤管道。
在查看参考架构后,我们现在将花时间构建自己的架构,凭借行业中最先进的知识。
架构 PsyStock 机器学习平台
我们可以根据对最佳实践和示例参考架构的研究提炼出的原则,为我们的机器学习平台定义一组期望的原则。我们希望在平台中保持的主要原则如下:
-
利用 开放系统和标准:使用如 MLflow 提供的开放系统允许长期性和灵活性,以利用开源社区的进步和力量,以较低的成本扩展公司的机器学习平台。
-
优先考虑 可扩展的解决方案:公司需要为未来增长激增做好准备;尽管这是第一个版本,但根据需求和视角进行激增的能力需要到位。
-
集成 可靠的数据生命周期:数据是机器学习平台的重心,应该以可靠和可追踪的方式在规模上进行管理。
-
遵循 软件开发最佳实践:例如,关注点分离、可测试性、CI/CD、可观察性和模块化。
-
维护 供应商和云独立性:PsyStock 作为一个初创公司,在一个非常动态的环境中运营,在不同的地理区域,可以访问不同的云,在某些情况下,还需要遵守不将数据从给定地理区域移动的要求。因此,保持云无关性并能够在不同的环境中拥有工作负载是一个竞争优势。
这些原则将使我们能够在公司内部构建一个开放且成本低的系统架构,并允许在不同的系统上运行,无论是在本地、云中还是本地。
我们之前已经定义了预测用例的业务需求,即加密货币运动的检测和价值预测。为了利用这一点和其他用例,创建一个机器学习平台对公司来说至关重要。
现在,凭借对最先进系统的研究和描述的知识,我们将接下来定义激发我们机器学习平台特性的方法。
描述机器学习平台的功能
制定特性规范对于保持开发工作专注于一小套能够为平台用户解锁价值的特性至关重要。在本节中,我们将激发能够实现机器学习平台最佳价值的特性。
在我们的系统中,我们希望能够具备以下功能:
-
特性:安排训练作业:数据科学家需要能够使用配置或等效代码为他们的模型安排训练作业。
-
特性:无缝部署从数据科学工作台开发的不同模型:公司在第三章“你的数据科学工作台”中已经开发了一个数据科学工作台。我们希望能够利用之前所做的所有工作,以便在平台上开发的模型可以部署到生产环境中。
-
特性:允许在出现新数据的情况下重新校准模型:当特定位置出现新数据时,需要自动生成一个新模型并将其存储在平台系统和人类可访问的模型注册表中。
-
特性:提交和配置批量评分作业:平台应允许相关用户在出现新数据的情况下配置和安排批量作业。
-
特性:基于高效推理 API 的以下 API 评分:给定一个模型,平台应该具有使用模型模式创建匹配 API 的功能。
在讨论了机器学习系统的理想特性之后,我们将在下一节中开始从高层次构建系统。
高层次系统架构
我们现在将专注于定义我们架构的构建块以及不同组件之间的不同数据流。
根据上一节中指定的特性和原则,我们的机器学习平台和解决方案应包含以下组件,如图 6.5中的架构图所述。

图 6.5 – ML 平台架构图
此图对技术选择具有特定的不确定性,因为这将在即将到来的章节中完成,届时将全面探索每个组件的工程。
-
数据和特征管理:这是通过特征/数据层执行的,该层从工作台接收特征注册,并允许从工作台注册数据集。数据层为训练环境提供数据。
-
训练基础设施:训练基础设施组件允许根据数据科学工作台的请求安排作业的训练。
-
部署和推理:部署环境消耗模型以执行批量或实时操作,由数据层中的数据或通过生产系统发出的请求触发。
-
性能和监控:这是通过监控和指标的中心组件来实现的,所有围绕该组件的系统都会将指标发布到其中。
-
模型管理:由模型注册表组件封装,其中包含存储和相关生命周期项目。输入主要来自训练作业和数据科学工作台。
-
工作流管理:这是一个允许协调不同系统的组件。例如,它允许安排作业和依赖关系管理,强制执行执行顺序。例如,推理批处理作业只能在训练作业之后执行。这可以通过操作系统使用 Cron 系统或通过更复杂的流程工具(如 Airflow)来实现。
我们接下来将简要介绍我们将如何使用MLflow实现本节概述的想法。
MLflow 和其他生态系统工具
MLflow 是由开源社区创建的一个工具,旨在解决开放系统中 ML 系统的一个空白,专注于可重复性、模型管理和部署。MLflow 绝对不是一个完整的工具;它需要其他组件,当其优势得到利用时,它是 ML 解决方案的一个核心部分。
近年来,在 Kubernetes 世界中出现了如Kubeflow之类的系统,旨在帮助管理 ML 系统的基础设施方面,并作为实际的部署环境。
Minio是 Kubeflow 附带的一个存储系统,它将用作元数据和数据集的无差别存储机制,并为云和本地环境上的存储提供抽象。
在确定了关于 ML 平台行业的最佳实践、概述了我们的需求,并在本节中设计了我们的 ML 平台架构后,我们将用本书的接下来的四章来构建我们平台的所有组件。
摘要
在本章中,我们介绍了构建机器学习系统所涉及的概念,映射了利益相关者,确定了常见问题和最佳实践,并概述了初始架构。我们在数据层和建模与推理层上确定了机器学习系统架构的关键构建块。强调了组件之间的互连,并概述了功能规格。
我们还讨论了如何在您的机器学习平台上利用 MLflow 以及其他参考工具可以补充的不足之处。
在本书的下一章节和部分中,我们将专注于将到目前为止学到的概念应用于实际系统,并通过实现 PsyStock 机器学习平台的架构来实践。我们将为每个组件设立一个章节,从规格说明开始,直到包含实际示例的组件实现。
进一步阅读
为了进一步扩展您的知识,您可以查阅以下链接中的文档:
-
技术债务的高度关注 –
papers.nips.cc/paper/2015/file/86df7dcfd896fcaf2674f757a2463eba-Paper.pdf -
CS 329S: 机器学习系统设计,奇普·黄 –
cs329s.stanford.edu,2021
第七章:数据和特征管理
在本章中,我们将向正在构建的机器学习平台添加一个特征管理数据层。我们将利用 MLflow Projects 模块的功能来结构化我们的数据管道。
具体来说,在本章中,我们将查看以下部分:
-
结构化您的数据管道项目
-
获取股票数据
-
检查数据质量
-
管理特征
在本章中,我们将获取相关数据以提供用于训练的数据集。我们的主要资源将是雅虎财经数据集 BTC。除了这些数据,我们还将获取以下额外数据集。
利用在第六章中介绍的引入 ML 系统架构的生产化架构,如图 7.1 所示,特征和数据组件负责从源获取数据,并使数据以平台不同组件可消费的格式可用:
![图 7.1 – 带数据层引用的高级架构]
![img/image0013.jpg]
图 7.1 – 带数据层引用的高级架构
让我们深入本章,看看我们将如何结构化和填充数据层,以包含用于训练模型和生成特征的相关数据。
技术要求
对于本章,您需要以下先决条件:
-
在您的机器上安装了最新版本的 Docker。如果您还没有安装,请按照
docs.docker.com/get-docker/中的说明操作。 -
已安装最新版本的 docker-compose。请按照
docs.docker.com/compose/install/中的说明操作。 -
在命令行上访问 Git,并按照
git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明进行安装。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
Python 3.5+ 已安装。
-
如第三章中所述,您本地安装了机器学习的最新版本,您的数据科学工作台。
在下一节中,我们将描述我们的数据管道结构、数据源以及我们将执行的不同步骤来实现我们的实际示例,利用 MLflow 项目功能来打包项目。
注意
直接从代码片段复制粘贴可能会导致您的编辑器出现问题。请参阅本章在 https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter07 上的 GitHub 仓库。
结构化您的数据管道项目
从高层次来看,我们的数据管道将每周运行一次,收集前 7 天的数据,并以机器学习作业可运行的方式存储。我们将我们的数据文件夹结构化为三种类型的数据:
-
原始数据:通过从 Yahoo Finance API 获取过去 90 天的数据生成的数据集。我们将以 CSV 格式存储数据——与从 API 收到的格式相同。我们将在 MLflow 中记录运行并提取收集到的行数。
-
阶段数据:在原始数据上,我们将运行质量检查、模式验证,并确认数据可用于生产。有关数据质量的信息将记录在 MLflow 跟踪中。
-
训练数据:训练数据是数据管道的最终产品。它必须在被认为是干净且适合执行模型的数据上执行。数据包含已处理成可以直接用于训练过程的功能数据。
这种文件夹结构最初将在文件系统中实现,并在部署期间转换为相关环境(例如:AWS S3、Kubernetes PersistentVolume 等)。
为了执行我们的数据管道项目,我们将使用 MLflow 项目 模块以与执行环境无关的格式打包数据管道。我们将使用 Docker 格式打包 MLflow 项目。Docker 格式为我们提供了不同的选项,根据可用的基础设施,我们可以将项目部署在云端或本地:

图 7.2 – 具有数据层引用的高级架构
我们的工作流程将执行以下步骤,如图 图 7.2 所示:
-
data/raw/data.csv 文件夹. -
data/staged/data.csv 文件. -
data/training/data.csv 位置.
通过这三个不同的阶段,我们确保了训练数据生成过程的可重复性、可见性和过程不同步骤的清晰分离。
我们将首先将我们的 MLflow 项目组织成步骤,并为管道的每个组件创建占位符:
-
在您的本地机器上创建一个名为
psytock-data-features的新文件夹。 -
添加
MLProject 文件:name: pystock_data_features conda: file: conda.yaml entry_points: data_acquisition: command: "python data_acquisition.py" clean_validate_data: command: "python clean_validate_data.py " feature_set_generation: command: "python feature_set_generation.py" main: command: "python main.py" -
添加以下
conda.yaml文件:name: pystock-data-features channels: - defaults dependencies: - python=3.8 - numpy - scipy - pandas - cloudpickle - pip: - git+git://github.com/mlflow/mlflow - pandas_datareader - great-expectations==0.13.15 -
您现在可以向文件夹中添加一个示例
main.py文件,以确保项目的基本结构正在工作:import mlflow import click def _run(entrypoint, parameters={}, source_version=None, use_cache=True): #existing_run = _already_ran(entrypoint, parameters, source_version) #if use_cache and existing_run: # print("Found existing run for entrypoint=%s and parameters=%s" % (entrypoint, parameters)) # return existing_run print("Launching new run for entrypoint=%s and parameters=%s" % (entrypoint, parameters)) submitted_run = mlflow.run(".", entrypoint, parameters=parameters) return submitted_run @click.command() def workflow(): with mlflow.start_run(run_name ="pystock-data-pipeline") as active_run: mlflow.set_tag("mlflow.runName", "pystock-data-pipeline") _run("load_raw_data") _run("clean_validate_data") _run("feature_set_generation") if __name__=="__main__": workflow() -
通过运行以下命令测试基本结构:
mlflow run .此命令将根据您的
conda.yaml文件创建的环境构建您的项目,并运行您刚刚创建的基本项目。它应该会出错,因为我们需要添加缺失的文件。文件未找到 错误将如下所示:python: can't open file 'check_verify_data.py': [Errno 2] No such file or directory
在这个阶段,我们有了将在本章中构建的数据管道 MLflow 项目的基石。我们将在下一节中填写获取数据的 Python 脚本。
获取股票数据
我们获取数据的脚本将基于pandas-datareader Python 包。它提供了一个简单的抽象,我们可以利用它来在管道中利用远程金融 API。这个抽象非常简单。给定一个数据源,例如 Yahoo Finance,您提供股票代码/对和日期范围,数据将以 DataFrame 的形式提供。
我们现在将创建load_raw_data.py文件,该文件将负责加载数据并将其保存到raw文件夹中。您可以在以下存储库中查看文件的详细内容:https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/blob/master/Chapter07/psystock-data-features-main/load_raw_data.py。执行以下步骤以实现该文件:
-
我们将首先导入相关包:
import mlflow from datetime import date from dateutil.relativedelta import relativedelta import pprint import pandas import pandas_datareader.data as web -
接下来,您应该添加一个函数来检索数据:
if __name__ == "__main__": with mlflow.start_run(run_name="load_raw_data") as run: mlflow.set_tag("mlflow.runName", "load_raw_data") end = date.today() start = end + relativedelta(months=-3) df = web.DataReader("BTC-USD", 'yahoo', start, end) df.to_csv("./data/raw/data.csv")
现在我们已经获取了数据,我们需要应用下一节中将要讨论的最佳实践——检查获取的数据质量的方法。
检查数据质量
将数据质量检查作为您机器学习系统的一部分,对于确保模型训练和推理的完整性和正确性至关重要。应借鉴并使用软件测试和质量原则于机器学习平台的数据层。
从数据质量的角度来看,在数据集中有几个关键的维度可以用来评估和配置我们的数据,即:
-
模式合规性:确保数据来自预期的类型;确保数值不包含其他类型的数据
-
有效数据:从数据角度评估数据是否从业务角度有效
-
缺失数据:评估是否所有运行分析和算法所需的数据都可用
对于数据验证,我们将使用Great Expectations Python 包(可在github.com/great-expectations/great_expectations找到)。它允许使用许多数据兼容的包(如 pandas、Spark 和云环境)对数据进行断言。它提供了一个 JSON DSL,我们可以用它来声明我们希望数据遵守的规则。
对于我们的当前项目,我们希望以下规则/约束是可验证的:
-
日期值应该是有效的日期,且不能缺失。
-
检查数值和长值是否正确类型。
-
数据集中的所有列都存在。
现在我们将创建check_verify_data.py文件,该文件将负责加载数据并将其保存到staging文件夹中,所有数据都有效且准备好用于机器学习训练。您可以在以下存储库中查看文件的详细内容:https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/blob/master/Chapter07/psystock-data-features-main/check_verify_data.py。
-
为了使前面的规则能够被我们的系统依赖,我们需要导入以下依赖项:
import mlflow from datetime import date from dateutil.relativedelta import relativedelta import pprint import pandas_datareader import pandas from pandas_profiling import ProfileReport import great_expectations as ge from great_expectations.profile.basic_dataset_profiler import BasicDatasetProfiler -
接下来,我们将实现脚本:
if __name__ == "__main__": with mlflow.start_run(run_name="check_verify_data") as run: mlflow.set_tag("mlflow.runName", "check_verify_data") df = pandas.read_csv("./data/raw/data.csv") describe_to_dict=df.describe().to_dict() mlflow.log_dict(describe_to_dict,"describe_data.json") pd_df_ge = ge.from_pandas(df) assert pd_df_ge.expect_column_values_to_match_ strftime_format("Date", "%Y-%m-%d").success == True assert pd_df_ge.expect_column_values_to_be_of_ type("High", "float").success == True assert pd_df_ge.expect_column_values_to_be_of_type("Low", "float").success == True assert pd_df_ge.expect_column_values_to_be_of_type("Open", "float").success == True assert pd_df_ge.expect_column_values_to_be_of_type("Close", "float").success == True assert pd_df_ge.expect_column_values_to_be_of_type("Volume", "long").success == True assert pd_df_ge.expect_column_values_to_be_of_type("Adj Close", "float").success == True -
现在我们可以进行一些清理工作:
#we can do some basic cleaning by dropping the null values df.dropna(inplace=True) #if data_passes_quality_can_go_to_features: df.to_csv("data/staging/data.csv")
在验证了数据的质量和暂存用于后,现在可以以高度的信心用于特征生成。
生成特征集和训练数据
我们将重构在本地环境中先前开发的代码,以生成用于训练的特征,并将我们的 MLflow 项目中的数据管道添加到我们的 MLflow 项目中。
我们现在将创建feature_set_generation.py文件,该文件将负责生成我们的特征并将它们保存在training文件夹中,所有数据都是有效的,并且准备好用于机器学习训练。你可以在仓库 https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/blob/master/Chapter07/psystock-data-features-main/feature_set_generation.py 中查看文件内容:
-
我们需要导入以下依赖项:
import mlflow from datetime import date from dateutil.relativedelta import relativedelta import pprint import pandas as pd import pandas_datareader import pandas_datareader.data as web import numpy as np -
在深入研究代码的主要组件之前,我们现在将实现一个关键函数,通过基本上将每个n个前一天的差异转换为特征,我们将使用这个特征来预测下一天,这与我们在本书的前几章中用于我们的运行用例的方法非常相似:
def rolling_window(a, window): """ Takes np.array 'a' and size 'window' as parameters Outputs an np.array with all the ordered sequences of values of 'a' of size 'window' e.g. Input: ( np.array([1, 2, 3, 4, 5, 6]), 4 ) Output: array([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]) """ shape = a.shape[:-1] + (a.shape[-1] - window + 1, window) strides = a.strides + (a.strides[-1],) return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides) -
接下来,我们将继续读取被认为是清洁且准备好由上游流程使用的暂存文件:
with mlflow.start_run() as run: mlflow.set_tag("mlflow.runName", "feature_set_ generation") btc_df = pd.read_csv("data/staging/data.csv") btc_df['delta_pct'] = (btc_df['Close'] - btc_df['Open'])/btc_df['Open'] btc_df['going_up'] = btc_df['delta_pct'].apply(lambda d: 1 if d>0.00001 else 0).to_numpy() element=btc_df['going_up'].to_numpy() WINDOW_SIZE=15 training_data = rolling_window(element, WINDOW_SIZE) pd.DataFrame(training_data).to_csv("data/training/data.csv", index=False)
我们生成特征集和特征。我们现在能够从数据采集到特征生成运行整个端到端管道。
运行你的端到端管道
在本节中,我们将运行完整的示例,你可以从以下地址获取该示例,地址为书的 GitHub 仓库中的/Chapter07/psytock-data-features-main 文件夹。图 7.3展示了你可以在 GitHub 中检查的项目完整文件夹结构,并与你的本地版本进行比较:

图 7.3 – 文件夹结构
要运行端到端管道,你应该在包含代码的目录中执行以下命令:
mlflow run . --experiment-name=psystock_data_pipelines
它将基本执行端到端管道,你可以在 MLflow UI 中直接检查它,按顺序运行管道的每个步骤:
mlflow ui
你可以在 MLflow 中运行和探索跟踪信息,网址为localhost:5000。
在图 7.4中,你可以看到管道阶段的主项目和子项目的不同运行,以嵌套工作流程格式呈现,你可以浏览以检查细节:

图 7.4 – 带数据层引用的高级架构
在图 7.5中,你可以看到数据管道的load_raw_data阶段的引用,并检查它何时开始和停止以及使用的参数:

图 7.5 – 包含数据层引用的高级架构
在图 7.6中,您可以看到数据管道中check_verify_data阶段的引用,我们记录了数据集的一些基本统计信息:

图 7.6 – 包含数据层引用的高级架构
如果检测到任何数据质量问题,工作流将失败,并明确指出哪个部分失败了,如图 7.7所示:

图 7.7 – 检查错误
通过本节,我们已完成了使用 MLflow 中的MLProjects模块实现的数据管道中数据管理和特征生成过程的描述。我们现在将探讨如何管理特征存储中的数据。
使用特征存储
特征存储是在您的数据之上的一层软件层,通过为推理系统提供一个接口来检索可用于推理或训练的特征集,从而抽象化所有数据的生成和管理过程。
在本节中,我们将通过使用 Feast(一个特征存储),一个用于管理和为生产中的模型提供机器学习特征的操作性数据系统,来阐述特征存储的概念:

图 7.8 – Feast 架构(来自 https://docs.feast.dev/)
为了了解 Feast 是如何工作的以及它如何适合您的数据层组件(代码可在 https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter07/psystock_feature_store 找到,执行以下步骤:
-
安装
feast:pip install feast==0.10 -
初始化特征存储库:
feast init -
通过替换自动生成的
yaml文件来创建您的特征定义:project: psystock_feature_store registry: data/registry.db provider: local online_store: path: data/online_store.db -
我们现在将导入特征定义的依赖项:
from google.protobuf.duration_pb2 import Duration from feast import Entity, Feature, FeatureView, ValueType from feast.data_source import FileSource -
我们现在可以加载特征文件:
token_features = FileSource( path="/data/features.csv", event_timestamp_column="create_date", created_timestamp_column="event_date", ) token= Entity(name="token", value_type=ValueType.STRING, description="token id",) -
我们现在可以添加一个特征视图:
hourly_view_features_token = FeatureView( name="token_hourly_features", entities=["token"], ttl=Duration(seconds=3600 * 1), features=[ Feature(name="prev_10days", dtype=ValueType.INT64), Feature(name="prev_11days", dtype=ValueType.INT64), Feature(name="prev_12days", dtype=ValueType.INT64), Feature(name="prev_13days", dtype=ValueType.INT64) ], online=True, input=token_features, tags={}, ) -
要部署带有迄今为止添加的配置的特征存储,我们需要运行以下命令:
feast apply在这个阶段,特征存储已部署到您的环境中(在本例中为本地),并且特征存储可供您的 MLflow 作业使用。
-
现在所有特征都已存储在特征存储中,我们可以进行特征检索:
import pandas as pd from datetime import datetime from feast import FeatureStore # entity_df generally comes from upstream systems event_data_point = pd.DataFrame.from_dict({ "token": ["btc","btc"], "event_date": [ datetime(2021, 4, 12, 10, 59, 42), datetime(2021, 4, 12, 8, 12, 10), ] }) store = FeatureStore(repo_path=".") feature_loading_df = store.get_historical_features( entity_df=entity_df, feature_refs = [ 'token_hourly_features:prev_3days', 'token_hourly_features:prev_4days', 'token_hourly_features:prev_5days' ], ).to_df()
您现在可以将您的特征存储库集成到您的 MLflow 工作负载中。
通过本节,我们已完成了使用 MLflow 中的MLProjects 模块实现的数据管道中数据管理和特征生成过程的描述。我们现在准备好在后续章节中处理生产环境部署。
摘要
在本章中,我们介绍了 MLflow 及其与参考架构中特征管理数据层的集成。我们利用 MLflow 项目模块的功能来构建我们的数据管道。
介绍了数据与特征管理的重要层级,并明确了特征生成的需求,同时阐述了数据质量、验证和数据准备的概念。
我们将数据管道生产的各个阶段应用于我们的项目。然后我们正式化了数据获取和质量检查。在最后一节,我们介绍了特征存储的概念以及如何创建和使用它。
在本书的下一章节和后续部分,我们将专注于将数据管道和特征应用于生产环境中数据管道的训练和部署过程。
进一步阅读
为了进一步扩展您的知识,您可以参考以下链接中的文档:
github.com/mlflow/mlflow/blob/master/examples/multistep_workflow/MLproject
第八章:使用 MLflow 训练模型
在本章中,您将学习如何使用 MLflow 创建生产就绪的训练作业。在更广泛的范围内,我们将关注如何将我们在早期章节中查看的笔记本环境中的训练作业转换为标准格式和蓝图以创建训练作业。
在本章中,我们将具体查看以下部分:
-
使用 MLflow 创建您的训练项目。
-
实现训练作业。
-
评估模型
-
在模型注册表中部署模型。
-
为您的训练作业创建 Docker 镜像。
是时候向 pyStock 机器学习(ML)平台训练基础设施添加内容,将第三章中开发的工坊中创建的概念验证模型转移到生产环境。
在本章中,您将开发一个定期运行或由数据集到达触发的训练项目。训练项目的主要输出是一个新模型,作为输出生成并在模型注册表中注册,具有不同的详细信息。
这里是训练工作流程的概述:

图 8.1 – 训练工作流程
图 8.1从高层次描述了一般过程,即训练数据集到达并启动训练作业。训练作业生成一个模型,最终在模型注册表中评估和部署。上游系统现在能够使用新部署的模型部署推理应用程序编程接口(API)或批量作业。
技术要求
对于本章,您需要以下先决条件:
-
在您的机器上安装了最新的 Docker 版本。如果您还没有安装,请按照
docs.docker.com/get-docker/中的说明操作。 -
已安装最新的 Docker Compose 版本——请按照
docs.docker.com/compose/install/中的说明操作。 -
在命令行中访问 Git,并按照
git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明进行安装。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器的权限。
-
安装了 Python 3.5+。
-
如第四章中所述,您已在本地上安装了最新的 ML 库,MLflow 中的实验管理。
使用 MLflow 创建您的训练项目。
您从数据科学家那里收到一份基于XGBoost模型准备从概念验证阶段过渡到生产阶段的规范。
我们可以回顾数据科学家最初注册模型的原版 Jupyter 笔记本,这是开始创建 ML 工程管道的起点。在笔记本中进行初步原型设计和训练后,他们就可以准备将模型投入生产了。
一些公司直接将笔记本自身投入生产,这当然是一种可能性,但以下原因使其变得不可能:
-
版本控制笔记本很困难。
-
单元测试代码很困难。
-
对于长时间运行的测试来说,它不可靠。
通过这三个不同的阶段,我们确保了训练数据生成过程的可重复性,以及过程不同步骤的可见性和清晰的分离。
我们将首先将我们的 MLflow 项目组织成步骤,并为管道的每个组件创建占位符,如下所示:
-
在您的本地机器上创建一个新的文件夹,并将其命名为
pystock-training。添加MLProject文件,如下所示:name: pystock_training conda_env: conda.yaml entry_points: main: data_file: path command: "python main.py" train_model: command: "python train_model.py" evaluate_model: command: "python evaluate_model.py " register_model: command: "python register_model.py" -
添加以下
conda.yaml文件:name: pystock-training channels: - defaults dependencies: - python=3.8 - numpy - scipy - pandas - cloudpickle - pip: - git+git://github.com/mlflow/mlflow - sklearn - pandas_datareader - great-expectations==0.13.15 - pandas-profiling - xgboost -
您现在可以向文件夹中添加一个示例
main.py文件,以确保项目的基本结构正常工作,如下所示:import mlflow import click import os def _run(entrypoint, parameters={}, source_version=None, use_cache=True): print("Launching new run for entrypoint=%s and parameters=%s" % (entrypoint, parameters)) submitted_run = mlflow.run(".", entrypoint, parameters=parameters) return mlflow.tracking.MlflowClient().get_run(submitted_run.run_id) @click.command() def workflow(): with mlflow.start_run(run_name ="pystock-training") as active_run: mlflow.set_tag("mlflow.runName", "pystock-training") _run("train_model") _run("evaluate_model") _run("register_model") if __name__=="__main__": workflow() -
通过运行以下命令测试基本结构:
mlflow run.此命令将根据您的
conda.yaml文件创建的环境构建您的项目,并运行您刚刚创建的基本项目。它应该出错,因为我们需要添加缺失的文件。
在这个阶段,我们已经有了本章将要构建的数据管道 MLflow 项目的基本块。接下来,您将填写用于训练数据的 Python 文件。
实现训练作业
我们将使用上一章生成的训练数据。这里的假设是独立的工作在特定文件夹中填充数据管道。在本书的 GitHub 仓库中,您可以在 https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/blob/master/Chapter08/psystock-training/data/training/data.csv 查看数据。
现在我们将创建一个train_model.py文件,该文件将负责加载数据以拟合并生成模型。测试预测将被生成并持久化在环境中,以便工作流程的其他步骤可以使用这些数据来评估模型。
本节生成的文件可在以下链接找到:
-
我们将首先导入相关的包。在这种情况下,我们需要
pandas来处理数据,xgboost来运行训练算法,显然还需要mlflow来跟踪和记录数据运行。以下是您需要执行的代码:import pandas as pd import mlflow import xgboost as xgb import mlflow.xgboost from sklearn.model_selection import train_test_split -
接下来,您应该添加一个函数来执行数据的分割,该函数依赖于
sklearn中的train_test_split。我们选择的分割比例是测试数据和训练数据分别为 33/67%。我们指定random_state参数以确保过程可重复,如下所示:def train_test_split_pandas(pandas_df,t_size=0.33,r_state=42): X=pandas_df.iloc[:,:-1] Y=pandas_df.iloc[:,-1] X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=t_size, random_state=r_state) return X_train, X_test, y_train, y_test -
此函数返回训练和测试数据集以及每个数据集的目标。我们依赖于
xgboost矩阵xgb.Dmatrix数据格式来有效地加载训练和测试数据,并馈送给xgboost.train方法。代码如下所示:if __name__ == "__main__": THRESHOLD = 0.5 mlflow.xgboost.autolog() with mlflow.start_run(run_name="train_model") as run: mlflow.set_tag("mlflow.runName", "train_model") pandas_df=pd.read_csv("data/training/data.csv") pandas_df.reset_index(inplace=True) X_train, X_test, y_train, y_test = train_test_split_pandas(pandas_df) train_data = xgb.DMatrix(X_train, label=y_train) test_data = xgb.DMatrix(X_test) model = xgb.train(dtrain=train_data,params={}) -
我们也利用这个时刻使用
model.predict方法生成测试预测。一些数据转换被执行以将股票上涨或下跌的概率离散化,并将其转换为0(不会上涨)或1(上涨),如下所示:y_probas=model.predict(test_data) y_preds = [1 if y_proba > THRESHOLD else 0\. for y_proba in y_probas] -
作为最后一步,我们将持久化测试预测到
result变量中。我们删除索引,以便在运行result.to_csv命令时,保存的pandasDataFrame 不包含索引,如下所示:test_prediction_results = pd.DataFrame(data={'y_pred':y_preds,'y_test':y_test}) result = test_prediction_results.reset_index(drop=True) result.to_csv("data/predictions/test_predictions.csv") -
您可以通过运行以下命令查看您的 MLflow 用户界面(UI)以查看记录的指标:
mlflow ui
您应该能够查看您的 MLflow UI,如下面的截图所示,您可以在其中看到持久化的模型和刚刚训练的模型的不同模型信息:
![Figure 8.2 – 训练模型
![img/image0025.jpg]
图 8.2 – 训练模型
在这个阶段,我们已经将我们的模型保存并持久化到我们的 MLflow 安装的工件中。接下来,我们将添加一个新的步骤到我们的工作流程中,以生成刚刚生成的模型的指标。
评估模型
我们现在将收集模型的评估指标,以添加到模型的元数据中。
我们将处理evaluate_model.py文件。您可以通过在一个空文件中工作或访问 https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/blob/master/Chapter08/psystock-training/evaluate_model.py 来跟随操作。按照以下步骤进行:
-
导入相关的包—
pandas和mlflow—分别用于读取和运行步骤。我们将依赖于导入sklearn中可用的模型评估指标,用于分类算法,如下所示:import pandas as pd import mlflow from sklearn.model_selection import train_test_split from sklearn.metrics import \ classification_report, \ confusion_matrix, \ accuracy_score, \ auc, \ average_precision_score, \ balanced_accuracy_score, \ f1_score, \ fbeta_score, \ hamming_loss, \ jaccard_score, \ log_loss, \ matthews_corrcoef, \ precision_score, \ recall_score, \ zero_one_loss在这个阶段,我们已经导入了我们需要的所有函数,以便在下一节中提取所需的指标。
-
接下来,您应该添加一个
classification_metrics函数来根据df参数生成指标。假设 DataFrame 有两个列:y_pred,这是训练模型预测的目标,以及y_test,这是训练数据文件中存在的目标。以下是您需要的代码:def classification_metrics(df:None): metrics={} metrics["accuracy_score"]=accuracy_score(df["y_pred"], df["y_test"] ) metrics["average_precision_score"]=average_precision_score( df["y_pred"], df["y_test"] ) metrics["f1_score"]=f1_score( df["y_pred"], df["y_test"] ) metrics["jaccard_score"]=jaccard_score( df["y_pred"], df["y_test"] ) metrics["log_loss"]=log_loss( df["y_pred"], df["y_test"] ) metrics["matthews_corrcoef"]=matthews_corrcoef( df["y_pred"], df["y_test"] ) metrics["precision_score"]=precision_score( df["y_pred"], df["y_test"] ) metrics["recall_score"]=recall_score( df["y_pred"], df["y_test"] ) metrics["zero_one_loss"]=zero_one_loss( df["y_pred"], df["y_test"] ) return metrics前面的函数基于预测值和测试预测值生成一个
metrics字典。 -
在创建了这个生成指标的函数之后,我们需要使用
start_run,基本上是读取预测测试文件并运行指标。我们将所有指标通过mlflow.log_metrics方法以日志字典的形式同时记录。代码在下面的代码片段中展示:if __name__ == "__main__": with mlflow.start_run(run_name="evaluate_model") as run: mlflow.set_tag("mlflow.runName", "evaluate_model") df=pd.read_csv("data/predictions/test_predictions.csv") metrics = classification_metrics(df) mlflow.log_metrics(metrics) -
我们可以再次查看 MLflow UI,在那里我们可以看到刚刚持久化的不同指标。您可以在以下位置查看输出:

图 8.3 – 持久化的训练模型指标
在这个阶段,我们对训练作业进行了模型评估,为模型实现者/部署者提供了指标和信息。现在我们将继续到训练过程的最后一步,即在 MLflow 模型注册表中注册模型,以便它可以部署到生产环境中。
在模型注册表中部署模型
接下来,您应该将register_model.py函数添加到模型注册表中以注册模型。
这就像执行mlflow.register_model方法,传入模型的统一资源标识符(URI)和模型名称。基本上,如果模型不存在,将会创建一个模型。如果它已经在注册表中,将添加一个新的版本,使得部署工具可以查看模型并追踪训练作业和指标。它还允许做出决定,是否将模型推广到生产环境中。所需的代码在下面的代码片段中展示:
import mlflow
if __name__ == "__main__":
with mlflow.start_run(run_name="register_model") as run:
mlflow.set_tag("mlflow.runName", "register_model")
model_uri = "runs:/{}/sklearn-model".format(run.info.run_id)
result = mlflow.register_model(model_uri, "training-model-psystock")
在以下屏幕截图中,展示了已注册的模型,我们可以根据我们的工作流程更改状态并进入预发布或生产状态:

图 8.4 – 已注册模型
在注册了我们的模型之后,我们现在将转向准备一个用于公共云环境或 Kubernetes 集群的训练作业 Docker 镜像。
为您的训练作业创建 Docker 镜像
在许多情况下,Docker 镜像是模型开发者向生产中的更专业系统基础设施团队交付的最关键的成果之一。项目包含在以下存储库的文件夹中:https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter08/psystock-training-docker。在以下步骤中,我们将生成一个可部署的 Docker 镜像:
-
您需要在项目的根目录下设置一个 Docker 文件,如下面的代码片段所示:
FROM continuumio/miniconda3:4.9.2 RUN apt-get update && apt-get install build-essential -y RUN pip install \ mlflow==1.18.0 \ pymysql==1.0.2 \ boto3 COPY ./training_project /src WORKDIR /src -
我们将首先通过运行以下命令来构建和训练镜像:
docker build -t psystock_docker_training_image . -
您可以运行您的镜像,指定您的跟踪服务器
$TRACKING_SERVER_URI值以到达host.docker.internal:5000,如下面的代码片段所示:docker run -e MLflow_TRACKING_SERVER=$TRACKING_SERVER_URI psystock_docker_training_image
在这个阶段,我们已经完成了完整训练工作流程的所有步骤。在下一章中,我们将继续在生产环境中部署平台的各个组件,利用迄今为止创建的所有 MLflow 项目。
摘要
在本章中,我们介绍了使用 MLflow 创建生产训练过程的概念和不同功能。
我们首先设置了 MLflow 训练项目的基本模块,并在本章中依次进行了训练模型、评估训练好的模型和注册训练好的模型。我们还深入探讨了为您的训练任务创建一个现成的图像。
这是我们架构的一个重要组成部分,它将使我们能够为我们的生产 ML 系统构建一个端到端的生产系统。在下一章中,我们将部署不同的组件,并说明模型的部署过程。
进一步阅读
为了进一步扩展您的知识,您可以参考以下链接的官方文档:
www.mlflow.org/docs/latest/projects.html
第九章:使用 MLflow 进行部署和推理
在本章中,您将了解我们机器学习(ML)系统的端到端部署基础设施,包括使用 MLflow 的推理组件。然后我们将转向在云原生 ML 系统(AWS SageMaker)和混合环境中部署我们的模型。接触这些不同环境的主要目标是让您具备在不同项目环境(云原生和本地)约束下部署 ML 模型的能力。
本章的核心是将 PsyStock 模型部署以预测基于您在本书中迄今为止所做的前 14 天市场行为的比特币(BTC/USD)价格。我们将借助工作流在多个环境中部署此模型。
具体来说,我们将在本章中查看以下部分:
-
启动本地模型注册库
-
设置批量推理作业
-
创建推理的 API 流程
-
在 Kubernetes 中部署模型进行批量评分
-
使用 AWS SageMaker 进行云部署
技术要求
对于本章,您需要以下先决条件:
-
在您的机器上安装了最新版本的 Docker。如果您尚未安装,请按照
docs.docker.com/get-docker/上的说明进行操作。 -
安装了最新版本的
docker-compose。请按照docs.docker.com/compose/install/上的说明进行操作。 -
在命令行中访问 Git,其安装方法可参考
git-scm.com/book/en/v2/Getting-Started-Installing-Git。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
安装了 Python 3.5+。
-
按照第三章**,您的数据科学工作台中所述,在本地安装了最新版本的 ML 平台。
-
一个配置好的 AWS 账户,用于运行 MLflow 模型。
启动本地模型注册库
在执行本章的以下部分之前,您需要设置一个集中的模型注册库和跟踪服务器。我们不需要整个数据科学工作台,因此可以直接使用内置在以下章节中将要部署的模型中的较轻量级的工作台变体。您应该在代码的根目录中,该目录可在github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter09找到。
接下来,切换到gradflow目录,并启动环境的一个轻量级版本以服务于您的模型,操作如下:
$ cd gradflow
$ export MLFLOW_TRACKING_URI=http://localhost:5000
$ make gradflow-light
在使用 MLflow 从 ML 注册表中检索模型并设置我们的 API 部署基础设施之后,我们将继续处理需要评分的批量输入数据的情况。我们将使用 MLflow 为当前的预测问题准备一个批量推理作业。
设置批量推理作业
本节所需的代码位于 pystock-inference-api 文件夹中。MLflow 基础设施由代码附带的 Docker 镜像提供,如图下所示:
![Figure 9.1 – 批量评分部署布局
![img/image0015.jpg]
图 9.1 – 批量评分部署布局
如果你直接访问到这些工件,你可以执行以下操作。代码位于 pystock-inference-batch 目录下。为了设置一个批量推理作业,我们将遵循以下步骤:
-
导入你的批量作业的依赖项;在相关的依赖项中,我们包括
pandas、mlflow和xgboost:import pandas as pd import mlflow import xgboost as xgb import mlflow.xgboost import mlflow.pyfunc -
我们接下来将通过调用
mlflow.start_run来加载start_run并从input.csv评分输入文件加载数据:if __name__ == "__main__": with mlflow.start_run(run_name="batch_scoring") as run: data=pd.read_csv("data/input.csv",header=None) -
接下来,我们通过指定
model_uri值从注册表中加载模型,基于模型的详细信息:model_name = "training-model-psystock" stage = 'Production' model = mlflow.pyfunc.load_model( model_uri=f"models:/{model_name}/{stage}" ) -
我们现在可以通过运行
model.predict来预测我们刚刚读取的数据集:y_probas=model.predict(data) -
保存批量预测。这基本上涉及到将
y_preds变量中的市场上涨的概率目标映射到 0 到 1 的值:y_preds = [1 if y_proba > 0.5 else 0 for y_proba in y_probas] data[len(data.columns)] =y_preds result = data result.to_csv("data/output.csv") -
我们现在需要将作业打包成一个 Docker 镜像,这样我们就可以轻松地在生产环境中运行它:
FROM continuumio/miniconda3 WORKDIR /batch-scoring/ RUN pip install mlflow==1.16.0 RUN pip install pandas==1.2.4 COPY batch_scoring.py /batch-scoring/ COPY MLproject /batch-scoring/ ENV MLFLOW_TRACKING_URI=http://localhost:5000 ENTRYPOINT ["mlflow run . --no-conda"] -
构建你的 Docker 镜像并对其进行标记,以便你可以引用它:
docker build . -t pystock-inference-batch -
通过执行以下命令来运行你的 Docker 镜像:
docker run -i pystock-inference-batch
在这种情况下,一个 Docker 镜像为你提供了一个机制,可以在支持 Docker 镜像的任何云或本地计算环境中运行你的批量评分作业。
我们现在将展示如何为 MLflow 生成一个 Docker 化的 API 推理环境。
创建用于推理的 API 进程
本节所需的代码位于 pystock-inference-api 文件夹中。MLflow 基础设施由代码附带的 Docker 镜像提供,如图下所示:
![Figure 9.2 – API 作业的结构
![img/image0026.jpg]
图 9.2 – API 作业的结构
通过依赖 MLflow 内置的 REST API 环境,设置一个 API 系统相当简单。我们将依赖本地文件系统上的工件存储来测试 API。
通过以下命令集,其核心是使用 CLI 中的 models serve 命令,我们可以提供我们的模型服务:
cd /gradflow/
export MLFLOW_TRACKING_URI=http://localhost:5000
mlflow models serve -m "models:/training-model-psystock/Production" -p 6000
我们接下来将前面的命令打包到一个 Docker 镜像中,以便在任何环境中进行部署。实现这一目标的步骤如下:
-
生成一个 Docker 镜像,指定工作目录和需要启动的命令作为
entry point:FROM continuumio/miniconda3 WORKDIR /batch-scoring/ RUN pip install mlflow==1.16.0 ENV MLFLOW_TRACKING_URI=http://localhost:5000 ENTRYPOINT ["mlflow models serve -m "models:/training-model-psystock/Production" -p 6000"] -
构建你的 Docker 镜像:
docker build . -t pystock-inference-api -
运行你的 Docker 镜像:
docker run -i pystock-inference-api -p 6000:6000
在这个阶段,你已经将 API 基础设施 Docker 化,并且可以在你方便的计算环境中部署它。
在深入研究了 MLflow 与 AWS 平台上的云原生部署的交互之后,我们现在将关注一个不依赖于任何提供商的部署。
在 Kubernetes 中部署你的模型进行批量评分
我们将使用 Kubernetes 来部署我们的批量评分作业。我们需要进行一些修改,使其符合 Docker 格式,以便通过 Kubernetes 进行生产中的 MLflow 部署。本节的前提条件是你有权访问 Kubernetes 集群或可以设置一个本地集群。有关指南,请参阅 kind.sigs.k8s.io/docs/user/quick-start/ 或 minikube.sigs.k8s.io/docs/start/。
你现在需要执行以下步骤,从 Kubernetes 中的注册表中部署你的模型:
-
前提条件:部署和配置
kubectl(kubernetes.io/docs/reference/kubectl/overview/) 并将其链接到你的 Kubernetes 集群。 -
创建 Kubernetes 后端配置文件:
{ "kube-context": "docker-for-desktop", "repository-uri": "username/mlflow-kubernetes-example", "kube-job-template-path": "/Users/username/path/to/kubernetes_job_template.yaml" } -
加载输入文件并运行模型:
mlflow run . --backend kubernetes --backend-config kubernetes_config.json
在查看在 Kubernetes 中部署模型之后,我们现在将专注于在云原生 ML 平台上部署我们的模型。
使用 AWS SageMaker 进行云部署
在过去几年中,像 AWS SageMaker 这样的服务作为运行 ML 工作负载的引擎已经逐渐占据了一席之地。MLflow 提供了集成和易于使用的命令,可以将你的模型部署到 SageMaker 基础设施中。由于需要构建大型 Docker 镜像并将其推送到 Docker 仓库,本节的执行将需要几分钟(5 到 10 分钟,具体取决于你的连接速度)。
以下是你需要遵循的一些关键前提条件列表:
-
本地配置的 AWS CLI 使用默认配置文件(更多详情,请参阅
docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)。 -
AWS 账户中用于 SageMaker 及其依赖项的访问权限。
-
AWS 账户中用于推送至 Amazon 弹性容器注册(ECR)服务的访问权限。
-
你的 MLflow 服务器需要按照第一部分“启动本地模型注册”中所述运行。
要将你的本地注册表中的模型部署到 AWS SageMaker,请执行以下步骤:
-
构建
mlflow-pyfunc镜像。这是与 SageMaker 兼容的基本镜像。 -
构建并推送一个带有
mlflow pyfunc消息的容器:mlflow sagemaker build-and-push-container此命令将构建 MLflow 默认镜像并将其部署到 Amazon ECR 容器。
为了确认此命令成功执行,你可以在控制台上检查你的 ECR 实例:
![图 9.3 – SageMaker 部署的镜像]()
图 9.3 – SageMaker 部署的镜像
-
在本地运行你的模型以测试 SageMaker Docker 镜像并导出跟踪 URI:
7777.The output should look like the following excerpt and you should be able to test your model locally:安装收集的包:mlflow
尝试卸载:mlflow
已找到现有安装:mlflow 1.16.0
卸载 mlflow-1.16.0:
成功卸载 mlflow-1.16.0
成功安装 mlflow-1.15.0
pip 20.2.4 来自 /miniconda/lib/python3.8/site-packages/pip(python 3.8)
Python 3.8.5
1.15.0
[2021-05-08 14:01:43 +0000] [354] [INFO] Starting gunicorn 20.1.0
[2021-05-08 14:01:43 +0000] [354] [INFO] Listening at: http://127.0.0.1:8000 (354)
This will basically confirm that the image is working as expected and you should be able to run your API in SageMaker. -
通过 AWS
cli双重检查你的镜像:aws ecr describe-images --repository-name mlflow-pyfunc你应该在图像列表中看到你的已部署镜像,并且肯定可以运行。
-
你需要在 AWS 中配置一个角色,该角色允许 SageMaker 代表你创建资源(你可以在 https://docs.databricks.com/administration-guide/cloud-configurations/aws/sagemaker.html#step-1-create-an-aws-iam-role-and-attach-sagemaker-permission-policy 找到更多详细信息)。
-
接下来,你需要使用以下命令将你的区域和角色导出到
$REGION和$ROLE环境变量中,指定你环境的实际值:export $REGION=your-aws-region export $ROLE=your sagemaker-enabled-role -
要将你的模型部署到 SageMaker,请运行以下命令:
mlflow sagemaker deploy -a pystock-api -m models:/training-model-psystock/Production –region-name $REGION -- $ROLE此命令将从你的本地注册表中加载你的模型到 SageMaker 作为内部表示,并使用生成的 Docker 镜像在 AWS SageMaker 基础设施引擎中提供模型。设置所有基础设施将需要几分钟。成功后,你应该会看到以下消息:
2021/05/08 21:09:12 INFO mlflow.sagemaker: The deployment operation completed successfully with message: "The SageMaker endpoint was created successfully." -
验证你的 SageMaker 端点:
aws sagemaker list-endpoints你可以查看以下内容,以了解输出消息类型的示例:
{ "Endpoints": [ { "EndpointName": "pystock-api", "EndpointArn": "arn:aws:sagemaker:eu-west-1:123456789:endpoint/pystock-api", "CreationTime": "2021-05-08T21:01:13.130000+02:00", "LastModifiedTime": "2021-05-08T21:09:08.947000+02:00", "EndpointStatus": "InService" } ] } -
接下来,我们需要使用一个简单的脚本来消费我们的 API,该脚本基本上列出功能,使用 Amazon Boto3 客户端调用 SageMaker 端点,并打印出基于特征向量的市场价格的概率:
import pandas import boto3 features = pd.DataFrame([[1,0,1,1,0,1,0,1,0,1,0,1,0,1]]) payload = features.to_json(orient="split") result = runtime.invoke_endpoint( EndpointName='pystock-api', Body=payload, ContentType='application/json') preds = result['Body'].read().decode("ascii") print(preds)运行此之前的脚本后,你应该会看到以下输出:
'[0.04279635474085808] -
探索 SageMaker 端点接口。在其监控组件中,你可以查看与你的部署环境和模型相关的不同指标,如图图 9.4所示:![图 9.4 – SageMaker 推理实例指标
![img/image0046.jpg]()
图 9.4 – SageMaker 推理实例指标
-
现在,你可以轻松地拆除已部署的模型,当需要部署模型或逐步淘汰时。所有相关资源都将被拆除:
mlflow sagemaker delete -a pystock-api --region-name $REGION删除后,你应该会看到类似于以下摘录中的消息:
2021/05/08 23:49:46 INFO mlflow.sagemaker: The deletion operation completed successfully with message: "The SageMaker endpoint was deleted successfully." 2021/05/08 23:49:46 INFO mlflow.sagemaker: Cleaning up unused resources... 2021/05/08 23:49:47 INFO mlflow.sagemaker: Deleted associated endpoint configuration with arn: arn:aws:sagemaker:eu-west-1:123456789:endpoint-config/pystock-api-config-v-hznm3ttxwx-g8uavbzia 2021/05/08 23:49:48 INFO mlflow.sagemaker: Deleted associated model with arn: arn:aws:sagemaker:eu-west-1:123456789:model/pystock-api-model-4nly3634reqomejx1owtdg
通过本节,我们完成了在不同环境中使用 MLflow 在生产环境中部署 ML 模型的相关功能描述,包括从本地机器到 Docker 和docker-compose、公共云,以及使用 AWS SageMaker 的非常灵活的方法。
摘要
在本章中,我们专注于 ML 模型的部署,其背后的概念,以及 MLflow 在多个环境中部署时提供的不同功能。
我们解释了如何准备 Docker 镜像以便部署。我们还阐明了如何与 Kubernetes 和 AWS SageMaker 交互以部署模型。
在本书的下一章和接下来的几节中,我们将专注于使用工具来帮助我们扩展 MLflow 工作负载,以提高我们模型基础设施的性能。
进一步阅读
为了进一步扩展您的知识,您可以查阅以下链接中的文档:
第四部分:高级主题
本节涵盖了关于 MLflow 高级使用的各种主题,使您了解如何在大数据环境中扩展 MLflow 以及满足高计算需求。我们将涵盖高级用例,以确保广泛覆盖将要讨论的模型类型和用例,同时也会介绍 MLflow 的内部结构和如何为其做出贡献。
本节包含以下章节:
-
第十章**, 扩展您的机器学习工作流程
-
第十一章**, 性能监控
-
第十二章**, 使用 MLFlow 的高级主题
第十章:扩展您的机器学习工作流程
在本章中,您将了解各种技术和模式,以在不同的可扩展性维度上扩展您的 机器学习(ML)工作流程。我们将探讨使用 Databricks 管理环境来扩展您的 MLflow 开发能力,在您有更大的数据集的情况下添加 Apache Spark。我们将探索 NVIDIA RAPIDS 和 图形处理单元(GPU)支持,以及 Ray 分布式框架来加速您的 ML 工作负载。本章的格式是一个小的 概念验证,包含一个定义良好的规范数据集,以展示一种技术和工具链。
特别是,在本章中,我们将查看以下部分:
-
在 Databricks 社区版环境中开发模型
-
将 MLflow 与 Apache Spark 集成
-
将 MLflow 与 NVIDIA RAPIDS (GPU) 集成
-
将 MLflow 与 Ray 平台集成
本章将需要研究每个框架的适当设置,基于每个案例的标准官方文档。
技术要求
对于本章,您需要以下先决条件:
-
在您的机器上安装的最新版本的 Docker。如果您尚未安装,请按照
docs.docker.com/get-docker/中的说明进行操作。 -
安装了最新版本的 Docker Compose—请按照
docs.docker.com/compose/install/中的说明进行操作。 -
命令行中访问 Git,并按照
git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明进行安装。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
安装了 Python 3.5+。
-
如第三章中所述,本地安装的您机器学习库的最新版本,您的数据科学工作台。
-
配置为运行 MLflow 模型的 Amazon Web Services(AWS)账户。
在 Databricks 社区版环境中开发模型
在许多小型团队和公司的场景中,启动一个集中的 ML 环境可能是一个成本高昂、资源密集的前期投资。一个能够快速扩展并使团队快速掌握技能的团队对于解锁组织内 ML 的价值至关重要。在这些情况下,使用托管服务非常相关,以开始原型设计和开始了解以较低成本使用 ML 的可行性。
一个非常流行的托管 ML 和数据平台是 Databricks 平台,由开发 MLflow 的同一家公司开发。在本节中,我们将使用针对学生和个人使用的 Databricks 社区版版本和许可证。
为了探索 Databricks 平台以开发和共享模型,您需要执行以下步骤:
-
在
community.cloud.databricks.com/上注册 Databricks 社区版,并创建一个账户。 -
使用您刚刚创建的凭据登录您的账户。
-
将训练数据上传到 Databricks。您可以从上传位于
Chapter10/databricks_notebooks/training_data.csv文件夹中的训练数据开始。在以下屏幕截图中,您可以看到左侧的数据标签页,并且应该看到您的文件已上传到平台:![Figure 10.1 – Uploading training data to Databricks]()
Figure 10.1 – Uploading training data to Databricks
-
将训练数据上传到 Databricks。您可以从上传位于
Chapter10/databricks_notebooks/input_prediction.csv文件夹中的训练数据开始。 -
创建一个用于您工作负载的集群。您可以为您的负载拥有集群,限制为 15 GB(GB)的随机存取内存(RAM),并且使用期限为定义的时间段。
您可以在以下屏幕截图中查看集群创建过程的概述:
![img/image0027.jpg]()
Figure 10.2 – Creating a cluster in Databricks Community Edition
-
通过点击页面右上角的创建空白笔记本按钮,在您的着陆工作空间页面上创建一个新的笔记本,如图所示:
![Figure 10.3 – Creating a new notebook in Databricks Community Edition]()
Figure 10.3 – Creating a new notebook in Databricks Community Edition
-
我们现在已准备好在这个托管环境中启动一个笔记本以执行基本的训练作业。您可以从点击创建笔记本开始,如图所示:
![Figure 10.4 – Creating your new notebook]()
Figure 10.4 – Creating your new notebook
-
将训练数据上传到 Databricks。您可以从上传位于
Chapter10/databricks_notebooks/input_prediction.csv文件夹中的训练数据开始。 -
导入所需的库。我们将适配一个用于分类我们正在运行的
btc-usd标的价格的业务案例的LogicRegression模型,如下所示:import pandas import numpy as np import mlflow from sklearn.linear_model import LogisticRegression from sklearn.metrics import f1_score, confusion_matrix from sklearn.model_selection import train_test_split -
由于平台中使用了 Databricks 文件系统,为了读取数据,更方便的是在 Spark 中读取数据,然后将 DataFrame 转换为
pandas。我们通常将数据分为训练集和测试集。以下是您需要的代码:df = (spark.read.option("header","true").csv("/FileStore/tables/training_data.csv")) pandas_df = df.toPandas() X=pandas_df.iloc[:,:-1] Y=pandas_df.iloc[:,-1] X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=4284, stratify=Y) -
我们的下一步将是快速训练我们的分类器,如下所示:
mlflow.sklearn.autolog() model = LogisticRegression() with mlflow.start_run(run_name='logistic_regression_model_baseline') as run: model.fit(X_train, y_train) preds = model.predict(X_test) -
在页面右上角,您可以点击实验按钮查看关于您运行的更多详细信息,并且可以进一步点击查看您的模型实验,如图所示,以下屏幕截图所示:
![Figure 10.5 – Experiment button]()
Figure 10.5 – Experiment button
-
一个有趣的功能是可以扩展并加速你与他人协作的能力,即能够发布公开可访问的模型笔记本,供与你分享链接的每个人使用,如下面的截图所示:

图 10.6 – 发布笔记本
您还可以将笔记本导出为 dbc 文件,以便您可以在 Databricks 环境中快速启动它,您还可以在存储库中共享它,如章节文件夹中所示,在 /databricks-notebooks/bitpred_poc.dbc。
在处理了使用 Databricks 环境扩展运行、开发和分发模型的方法之后,我们将接下来探讨将 Apache Spark 流集成到我们的推理工作流程中,以处理我们有访问权的大型数据集的场景。
集成 MLflow 与 Apache Spark
Apache Spark 是一个非常可扩展且流行的大数据框架,它允许在大规模上进行数据处理。有关更多详细信息和支持文档,请访问 spark.apache.org/。作为一个大数据工具,它可以用来加速您的机器学习推理的部分,因为它可以在训练或推理级别进行设置。
在这个特定案例中,我们将说明如何实现它,以便使用上一节在 Databricks 环境中开发的模型来扩展批量推理作业到更大的数据量。
为了探索 Spark 与 MLflow 的集成,我们将执行以下步骤:
-
在 Python 中创建一个名为
inference_job_spark的新笔记本,并将其链接到刚刚创建bitpred_poc.ipynb笔记本的运行集群。 -
将您的数据上传到环境中的文件/上传数据链接的
dbfs上。 -
在笔记本的一个单元中执行以下脚本,将
logged_model和df文件名更改为您环境中的文件名:import mlflow logged_model = 'runs:/6815b44128e14df2b356c9db23b7f936/model' df = spark.read.format("csv").load("dbfs:/FileStore/shared_uploads/ input.csv") # Load model as a Spark UDF. loaded_model = mlflow.pyfunc.spark_udf(spark, model_uri=logged_model) # Predict on a Spark DataFrame. df.withColumn('predictions', loaded_model()).collect()
这个示例摘录可以在 Databricks 或您自己的 Spark 集群上运行,并可以扩展到大型数据集,利用 Spark 的分布式计算能力。
从使用 Apache Spark 扩展推理开始,我们现在将探讨在 MLflow 的支持下使用 GPU 来扩展超参数优化作业。
集成 MLflow 与 NVIDIA RAPIDS(GPU)
训练和调整机器学习模型是一个漫长且计算成本高昂的操作,并且是能够从并行处理中受益最大的操作之一。在本节中,我们将探讨将您的 MLflow 训练作业(包括超参数优化)与 NVIDIA RAPIDS 框架集成。
要集成 NVIDIA RAPIDS 库,请按照以下步骤操作:
-
根据您的环境,以以下方式安装 RAPIDS:
a.
rapids.ai/start.html包含有关部署选项的详细信息。b.
developer.nvidia.com/blog/run-rapids-on-google-colab/详细说明了如何在 Google Colaboratory(Google Colab)上运行 RAPIDS。 -
在你的环境中安装 MLflow。
-
按照以下方式导入所需的库:
import argparse from functools import partial import mlflow import mlflow.sklearn from cuml.metrics.accuracy import accuracy_score from cuml.preprocessing.model_selection import train_test_split from cuml.ensemble import RandomForestClassifier from hyperopt import fmin, tpe, hp, Trials, STATUS_OK -
实现
load_data函数,这是一个辅助函数,用于将数据加载到将被cudfDataFrame(一个用于加载、连接、聚合和过滤的 DataFrame 库,无需了解 计算统一设备架构(CUDA)编程的细节)使用。以下是所需的代码:def load_data(fpath): import cudf df = cudf.read_parquet(fpath) X = df.drop(["ArrDelayBinary"], axis=1) y = df["ArrDelayBinary"].astype("int32") return train_test_split(X, y, test_size=0.2)Start the ray server ray.init() client = serve.start() -
按照以下方式定义训练循环:
def _train(params, fpath): max_depth, max_features, n_estimators = params max_depth, max_features, n_estimators = (int(max_ depth), float(max_features), int(n_estimators)) X_train, X_test, y_train, y_test = load_data(fpath) mod = RandomForestClassifier( max_depth=max_depth, max_features=max_features, n_estimators=n_estimators ) mod.fit(X_train, y_train) preds = mod.predict(X_test) acc = accuracy_score(y_test, preds) mlparams = { "max_depth": str(max_depth), "max_features": str(max_features), "n_estimators": str(n_estimators), } mlflow.log_params(mlparams) mlflow.log_metric("accuracy", acc) mlflow.sklearn.log_model(mod, "saved_models") return {"loss": acc, "status": STATUS_OK} -
调用内部训练循环,如下所示:
def train(params, fpath, hyperopt=False): with mlflow.start_run(nested=True): return _train(params, fpath, hyperopt) -
如果你在 Docker 中部署了版本,通过读取参数设置你的主要流程。以下代码片段展示了如何执行此操作:
if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--algo", default="tpe", choices=["tpe"], type=str) parser.add_argument("--conda-env", required=True, type=str) parser.add_argument("--fpath", required=True, type=str) args = parser.parse_args() -
按照以下方式定义你的试验和要优化的参数:
search_space = [ hp.uniform("max_depth", 5, 20), hp.uniform("max_features", 0.1, 1.0), hp.uniform("n_estimators", 150, 1000), ] trials = Trials() algorithm = tpe.suggest if args.algo == "tpe" else None fn = partial(train, fpath=args.fpath, hyperopt=True) experid = 0 -
按照以下方式运行你的主要循环:
artifact_path = "Airline-Demo" artifact_uri = None with mlflow.start_run(run_name="RAPIDS-Hyperopt"): argmin = fmin(fn=fn, space=search_space, algo=algorithm, max_evals=2, trials=trials) print("===========") fn = partial(train, fpath=args.fpath, hyperopt=False) final_model = fn(tuple(argmin.values())) mlflow.sklearn.log_model( final_model, artifact_path=artifact_path, registered_model_name="rapids_mlflow_cli", conda_env="envs/conda.yaml", )
在处理了使用高度可扩展的计算环境在 Ray 平台上提供模型之后,我们现在将考虑一个不同的问题,我们将探讨从本地机器在集中式云位置跟踪多个运行的选择。
将 MLflow 与 Ray 平台集成
Ray 框架([docs.ray.io/en/master/](https://docs.ray.io/en/master/))是一个分布式平台,它允许你快速扩展部署基础设施。
使用 Ray,你可以在运行需要以与模型服务相同方式扩展的 ML 平台时添加任意逻辑。它基本上是一个网络框架。
我们预先加载了模型和内容,并将它们放入以下存储库文件夹中:https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter10/mlflow-ray-serve-integration。
为了将你的模型服务执行到 Ray 中,执行以下步骤:
-
通过运行以下命令安装 Ray 包:
pip install -U ray -
在你的环境中安装 MLflow。
-
按照以下方式导入所需的库:
import ray from ray import serve import mlflow.pyfunc -
实现模型后端,这基本上意味着将模型服务函数包装到你的 Ray 服务环境中。以下是所需的代码:
class MLflowBackend: def __init__(self, model_uri): self.model = mlflow.pyfunc.load_model(model_ uri=model_uri) async def __call__(self, request): return self.model.predict(request.data) -
按照以下方式启动 Ray 服务器:
ray.init() client = serve.start() -
按照以下方式加载模型并创建后端:
model_uri = "./tmp/0/31fc9974587243d181fdbebfd4d2b6ad/artifacts/model" client.create_backend("mlflow_backend", MLflowBackend, model_uri) -
通过运行以下命令测试服务平台:
ray start --head # Start local Ray cluster. serve start # Start Serve on the local Ray cluster.
在处理了使用高度可扩展的计算环境在 Ray 平台上提供模型之后,我们将在下一章中查看性能和监控组件。
摘要
在本章中,我们专注于使用 Databricks 环境扩展你运行、开发和分发模型的能力。我们还探讨了将 Apache Spark 流集成到我们的批量推理工作流程中,以处理我们有访问大型数据集的场景。
我们使用 NVIDIA RAPIDS 框架和 Ray 分布式框架,以可扩展性的方式总结了两种扩展超参数优化和 应用程序编程接口(API)服务的方法。
在下一章和本书的后续部分,我们将专注于 ML 模型的可观察性和性能监控。
进一步阅读
为了进一步扩展您的知识,您可以查阅以下链接中的文档:
第十一章:性能监控
在本章中,你将了解机器学习(ML)操作的重要和相关性领域,以及如何使用该领域的最佳实践和已知的操作模式来确保到目前为止在此书中开发的系统在生产中的平稳运行。我们将了解机器学习中的操作概念,并查看用于监控机器学习系统中数据质量的指标。
具体来说,我们将在本章中查看以下部分:
-
机器学习模型性能监控概述
-
监控数据漂移和模型性能
-
监控目标漂移
-
基础设施监控和警报
我们将介绍一些用于监控机器学习系统性能和可靠性的实用参考工具。
技术要求
对于本章,你需要以下先决条件:
-
在您的机器上安装了最新版本的 Docker。如果您还没有安装,请按照
docs.docker.com/get-docker/上的说明操作。 -
安装了最新版本的
docker-compose。为此,请按照docs.docker.com/compose/install/上的说明操作。 -
在命令行中访问 Git,可以按照
git-scm.com/book/en/v2/Getting-Started-Installing-Git中的说明进行安装。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
Python 3.8+已安装。
-
按照第三章**,您的数据科学工作台*中描述的,在本地安装了您机器学习的最新版本。
-
配置了 AWS 账户以运行 MLflow 模型。
机器学习模型性能监控概述
监控是可靠机器学习系统的基石,能够持续释放数据的价值并提供改进的关键反馈。
在机器学习模型的监控方面,有多个利益相关者,我们应该从涉及的不同利益相关者那里获取监控要求。以下是一个典型的利益相关者集的一个例子:
-
数据科学家:他们在监控方面的重点是评估可能对性能产生负面影响的模型性能和数据漂移。
-
软件工程师:这些利益相关者希望确保他们有衡量指标,以评估他们的产品是否能够可靠且正确地访问为模型提供服务的 API。
-
数据工程师:他们希望确保数据管道是可靠的,并且能够可靠地推送数据,以适当的速度,并且符合正确的模式。
-
业务/产品利益相关者:这些利益相关者对其客户群整体解决方案的核心影响感兴趣。例如,在一个交易平台中,他们可能最关心整体解决方案为公司带来的盈利与风险比率。如果市场在一天内非常波动或处于非典型情况,可能会向算法中添加断路器。
在机器学习行业中,最广泛使用的监控维度如下:
-
数据漂移:这对应于用于模型训练或推理的输入数据发生的重大变化。这可能表明现实世界中模型假设的变化,这将需要重新训练、重新开发模型,甚至如果不再适用,则存档。这可以通过监控用于训练模型的数据与用于评分或推理的数据随时间变化的分布来轻松检测。
-
目标漂移:随着输入数据中方案的变化,我们在一段时间内经常看到模型输出分布的相同变化。常见的周期是几个月、几周或几天,可能表明环境发生了重大变化,这将需要模型重新开发和调整。
-
性能漂移:这涉及到查看性能指标,如分类问题的准确度或均方根误差,是否随着时间的推移逐渐恶化。这是模型存在问题的迹象,需要模型开发人员或维护人员进行调查和采取行动。
-
平台和基础设施指标:此类指标与建模无直接关系,而是与包围模型的系统基础设施有关。它意味着异常的 CPU、内存、网络或磁盘使用,这肯定会影响模型向业务提供价值的能力。
-
业务指标:非常关键的业务指标,如模型的盈利能力,在某些情况下应添加到模型运营中,以确保负责模型的团队能够监控模型实现其业务假设的能力。
在下一节中,我们将探讨使用一个可以与MLflow集成的工具来监控数据漂移并检查模型的性能。
监控数据漂移和模型性能
在本节中,我们将通过一个示例,您可以在GitHub仓库(https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter11/model_performance_drifts)中找到的笔记本中的代码进行演示。我们将通过计算不同类型的漂移并探索其与 MLflow 的集成来运行整个过程。
监控模型性能领域的一个新兴开源工具被称为 pandas、JSON 和 CSV。它允许我们监控机器学习模型中的多个漂移及其性能。Evidently 的 GitHub 仓库可在 github.com/evidentlyai/evidently/ 找到。
在本节中,我们将探索 Evidently 与 MLflow 的组合,以便在下一节中监控数据漂移和模型性能。
监控数据漂移
在本小节中,我们将在我们的环境中设置 Evidently 并了解如何将其集成。请按照 GitHub 仓库中的这些步骤操作(更多详细信息请参阅 技术要求 部分):
-
安装
evidently:pip install evidently==0.1.17.dev0 -
导入相关库:
import pandas as pd import numpy as np from sklearn import datasets from sklearn.model_selection import train_test_split from evidently.dashboard import Dashboard from evidently.tabs import DataDriftTab, NumTargetDriftTab,CatTargetDriftTab -
获取一个参考数据集,基本上是一个训练数据集。我们将向
pandasDataFrame 添加一组特征,以便evidently能够在漂移报告中使用特征名称:reference_data = \ pd.read_csv("training_data.csv", header=None, names=[ "day{}".format(i) for i in \ range(0,14) ]+["target"] )以下 图 11.1 代表我们将用作参考数据集的训练数据的数据结构:
![图 11.1 – 要使用的数据集样本]()
图 11.1 – 要使用的数据集样本
-
在此步骤中,我们加载
to_score_input_data.csv文件。这是要评分的文件。我们在此练习中的目的是计算参考训练集中的数据与要评分的数据之间的分布差异:latest_input_data = \ pd.read_csv("to_score_input_data.csv", header=None, names=[ "day{}".format(i) for i in \ range(0,14) ] ) -
执行数据漂移报告生成并记录到 MLflow 运行中。基本上,以下代码片段所发生的是生成一个包含参考数据和最新输入数据的 Evidently 仪表板。计算漂移报告并将其加载到 MLflow 运行中,以便在后续步骤中采取行动和审查:
EXPERIMENT_NAME="./reports_data_drift" mlflow.set_experiment(EXPERIMENT_NAME) with mlflow.start_run(): drift_dashboard = Dashboard(tabs=[DataDriftTab]) drift_dashboard.calculate(reference_data, latest_input_data) drift_dashboard.save(EXPERIMENT_NAME+"/input_data_drift.html") drift_dashboard._save_to_json(EXPERIMENT_NAME+"/input_data_drift.json") mlflow.log_artifacts(EXPERIMENT_NAME) -
您现在可以运行前几行中的笔记本代码(在
monitoring_data_drift_performance.ipynb文件中),并在 MLflow 运行的“工件”组件中探索您的数据漂移报告。图 11.2 显示,该工具在 14 个特征中没有检测到任何漂移,并相应地展示了分布:

图 11.2 – 要使用的数据集样本
与数据漂移类似,我们现在将在下一小节中查看目标漂移,以揭示模型中可能的其他问题。
监控目标漂移
我们现在将比较评分输出与参考训练输出,以寻找可能的目标漂移:
-
获取最近评分的数据集:
production_scored_data = \ pd.read_csv("scored_data.csv", header=None, names=[ "day{}".format(i) for i in \ range(0,14) ]+["target"] ) bcancer_data_and_target_drift = \ Dashboard(reference_data, production_scored_data, tabs=[ CatTargetDriftTab]) bcancer_data_and_target_drift.save('reports/target_drift.html') -
执行数据漂移报告生成并将结果记录在 MLflow 中:
EXPERIMENT_NAME="./reports_target_drift" mlflow.set_experiment(EXPERIMENT_NAME) with mlflow.start_run(): model_target_drift = \ Dashboard(reference_data, production_scored_data, tabs=[CatTargetDriftTab]) model_target_drift.save(EXPERIMENT_NAME+"/target_drift.html") drift_dashboard._save_to_json(EXPERIMENT_NAME+"/target_drift.json") mlflow.log_artifacts(EXPERIMENT_NAME) -
探索您的目标漂移报告。如图 11.3所示,在此次运行中未发现对目标漂移有统计学意义的数值。在检测漂移时,Evidently 使用数据来自不同分布的概率(由p 值表示)进行统计测试(更多详情请见
en.wikipedia.org/wiki/P-value)。它比较了参考数据和当前数据的结果!![图 11.3 – 目标数据漂移]()
-
如图 11.4所示,您可以进一步深入到特定特征的目标漂移;在这种情况下,预测股票价格的特定前8 天:

图 11.4 – 我们目标的数据漂移
在学习了如何检测输入数据中的漂移之后,我们现在将探讨如何使用 Evidently 来监控模型中的漂移。
监控模型漂移
监控模型漂移对于确保您的模型仍然以最佳性能水平运行至关重要。通过这次分析,您可以决定是否重新训练您的模型,甚至从头开始开发一个新模型。
我们现在将监控模型漂移。为此,您需要执行以下步骤:
-
导入相关库:
import xgboost as xgb import mlflow from evidently.tabs import ClassificationPerformanceTab -
获取参考数据集:
X=reference_data.iloc[:,:-1] Y=reference_data.iloc[:,-1] reference, production, y_train, y_test = \ train_test_split(X, Y, test_size=0.33, random_state=4284, stratify=Y) reference_train = xgb.DMatrix(reference,label=y_train) dproduction= xgb.DMatrix(production) dreference=xgb.DMatrix(reference) -
训练您的模型:
mlflow.xgboost.autolog() EXPERIMENT_NAME="reports_model_performance" mlflow.set_experiment(EXPERIMENT_NAME) with mlflow.start_run() as run: model=xgb.train(dtrain=reference_train,params={}) -
创建参考预测和训练预测:
train_proba_predict = model.predict(dreference) test_proba_predict = model.predict(dproduction) test_predictions = [1\. if y_cont > threshold else 0\. for y_cont in test_proba_predict] train_predictions = [1\. if y_cont > threshold else 0\. for y_cont in train_proba_predict] reference['target'] = y_train reference['prediction'] = train_predictions production['target'] = y_test production['prediction'] = test_predictions -
生成并附加性能报告到您的执行中:
classification_performance = Dashboard( tabs=[ClassificationPerformanceTab]) classification_performance.calculate(reference, production) classification_performance.save('.reports/'+EXPERIMENT_NAME+'.html') mlflow.log_artifact('.reports/'+EXPERIMENT_NAME+'.html') -
探索您的 MLflow 性能指标报告。通过查看生成的报告,您可以检查参考指标,包括准确率、精确度、召回率和F1 指标,这些是基于训练数据的参考指标,其最大值为1。当我们测试测试数据集的子集时,下面一行当前状态肯定已经退化。这可以帮助您判断是否在当前的F1值下,模型仍然在生产中运行是有意义的:


在深入了解数据漂移、目标漂移和模型性能监控的细节,以及如何将这些功能与 MLflow 集成之后,我们现在将探讨监控基础设施的基本原则,包括监控和警报。
基础设施监控和警报
从基础设施的角度来看,ML 系统监控的主要维度与传统软件系统没有区别。
为了说明这个问题,我们将利用 AWS CloudWatch 和 SageMaker 中可用的监控和警报工具来展示设置监控和警报基础设施的示例。这个相同的机制可以使用 Grafana/Prometheus 等工具在本地和云部署中设置。这些监控工具实现类似的目标,并提供类似的功能,因此您应该根据您的环境和云提供商选择最合适的工具。
AWS CloudWatch 提供了一种监控和可观察性解决方案。它允许您监控您的应用程序,响应系统级性能变化,优化资源使用,并获得操作健康性的单一视图。
在更高层次上,我们可以将基础设施监控和警报组件分为以下三个部分:
-
资源指标:这指的是系统部署的硬件基础设施的指标。在这种情况下,主要的指标包括以下内容:
a. CPU 利用率:这基本上是处理器利用率的百分比单位。这是一个通用的指标,应该被监控。
b. 内存利用率:您的计算系统当前使用的内存百分比。
c. 网络数据传输:网络数据传输是指特定计算节点进出流量的大小。它通常以 Mb/s 为单位。异常可能意味着您需要向系统中添加更多节点或增加容量。
d. 磁盘 I/O:这是通过磁盘的读写吞吐量来衡量的;它可能表明系统处于压力之下,需要扩展或调查其性能:


图 11.6 – SageMaker 基础设施指标示例
-
系统指标:基础设施监控和警报组件的第二支柱是指系统基础设施的指标,系统部署在其中。在这种情况下,主要的指标包括以下内容:
a. 请求吞吐量:每秒处理的预测数量
b. 错误率:每个预测的错误数量
c. 请求延迟:服务预测的端到端时间
d. 验证指标:请求输入数据的错误指标
一个生产系统,如 SageMaker,会将系统指标推送到 AWS CloudWatch 以提供实时系统指标监控。AWS CloudWatch 拥有一套完整的特性集,用于管理、存储和监控指标和仪表板:

图 11.7 – 在 AWS CloudWatch 中指定警报
- 警报:对于警报,我们使用上一节计算出的任何指标,并设置一个我们认为可接受的阈值。AWS CloudWatch 界面允许您轻松设置默认服务指标和自定义指标的警报。负责可靠性的团队将通过 CloudWatch 发送消息到公司聊天/Slack、电子邮件地址或手机来接收警报,以便团队处理或减轻事件:

图 11.8 – 在 AWS CloudWatch 中指定一个警报
您可以使用相同的监控工具记录和监控与您的 ML 系统相关联的所有其他指标。例如,为 ML 模型的周利润设置警报是一个应该与系统核心系统指标一起部署的业务指标。
在本书的最后一章,我们将探讨 MLflow 的高级概念,作为对 AWS CloudWatch 作为实现生产中 ML 系统指标监控和警报工具的概述。
摘要
在本章中,我们介绍了数据漂移和目标漂移的概念,并探讨了 ML 系统中性能监控的不同方法。
我们首先介绍了性能和监控领域的重要概念,不同类型的漂移和需要监控的业务指标,以及使用 AWS CloudWatch 作为实时系统中实现监控和警报的工具。
性能和监控是我们架构的重要组成部分,它将使我们能够完成我们 ML 系统架构的重要一层。现在让我们深入了解 MLflow 的高级主题。
进一步阅读
为了进一步扩展您的知识,您可以查阅以下链接中的文档:
第十二章:MLflow 的高级主题
在本章中,我们将涵盖高级主题,以解决常见的情境和用例,通过使用本书其他部分未公开的不同类型的模型,利用你的 MLflow 知识,确保广泛的功能覆盖和接触各种主题。
具体来说,在本章中,我们将查看以下部分:
-
使用 AutoML 探索 MLflow 用例
-
将 MLflow 与其他语言集成
-
理解 MLflow 插件
我们将以模式格式(即问题背景和解决方案方法)简要描述每个案例的问题和解决方案。
本章的不同部分不呈现连续性,因为它们解决不同的问题。
技术要求
对于本章,您需要以下先决条件:
-
在您的机器上安装 Docker 的最新版本。如果您还没有安装,请按照
docs.docker.com/get-docker/中的说明进行操作。 -
请安装 Docker Compose 的最新版本——请按照
docs.docker.com/compose/install/中的说明进行操作。 -
在命令行中访问 Git,并按照
git-scm.com/book/en/v2/Getting-Started-Installing-Git中描述的方式进行安装。 -
访问 Bash 终端(Linux 或 Windows)。
-
访问浏览器。
-
安装 Python 3.5+。
-
按照第 4 章 中描述的,在本地安装你 ML 库的最新版本,MLflow 中的实验管理。
使用 AutoML 探索 MLflow 用例
执行 ML 项目需要多个领域的广泛知识,并且在很多情况下,需要深入的技术专业知识。一种缓解采用并加速项目上市时间(TTM)的突发技术是使用自动化机器学习(AutoML),其中模型开发者的某些活动被自动化。它基本上包括通过以下两种方式在 ML 中自动化步骤:
-
特征选择:使用优化技术(例如,贝叶斯技术)选择最佳特征作为模型的输入
-
建模:通过使用超参数优化技术测试多个算法,自动识别要使用的模型集
我们将探索将 MLflow 与一个名为 PyCaret 的 ML 库(pycaret.org/)集成,该库允许我们利用其 AutoML 技术并在 MLflow 中记录过程,以便您可以自动获得您问题的最佳性能。
我们将接下来查看本书中 pyStock 的用例,并基于我们的训练数据自动建模。
AutoML pyStock 分类用例
对于本节,我们将解决一个你可以跟随的解决方案(https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter12/automl_pycaret)与笔记本和我们的项目数据集。我们将按照以下步骤执行,以实现我们的用例的 AutoML:
-
让我们从安装 PyCaret 的完整版本开始,如下所示:
pip install pycaret==2.3.1 -
首先,我们应该导入必要的库,如下所示:
import pandas import pycaret -
然后,我们读取所有训练数据,如下所示:
data=pandas.read_csv("training_data.csv",header='infer') -
接下来,我们设置项目数据和加载输入数据,如下所示:
from pycaret.classification import * s = setup(data, target = 'target', log_experiment = True, experiment_name = 'psystock')这里是输出:
![图 12.1 – 自动特征推断
![img/image0018.jpg]
图 12.1 – 自动特征推断
-
然后,我们执行
compare_models(),如下所示:best = compare_models()这里是输出:
![图 12.2 – 不同类型的模型
![img/image0029.jpg]
图 12.2 – 不同类型的模型
-
通过以下命令选择您最好的模型:
best = compare_models() -
运行 MLflow 来检查所有模型(在以下统一资源定位符(URL):http://127.0.0.1:5000/#/experiments/1),然后你应该会看到一个像这样的屏幕:
![img/image0038.jpg]
图 12.3 – 已记录在 MLflow 中的模型
我们将探讨在没有目标的情况下实现 AutoML 的场景。我们需要使用异常检测,这是一种无监督的机器学习技术。
自动机器学习 – 欺诈异常检测
对于本节,我们将解决一个你可以跟随的解决方案(https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter12/automl_pycaret_fraud)与笔记本和我们的项目数据集。我们将按照以下步骤执行,以实现我们的用例的 AutoML:
-
首先,我们应该导入库,如下所示:
import pandas import pycaret -
然后,我们读取所有训练数据,如下所示:
data=pandas.read_csv("credit_card.csv",header='infer')这里是输出:
![图 12.4 – MLflow 中自动可用的模型
![img/image0049.jpg]
图 12.4 – MLflow 中自动可用的模型
-
接下来,我们设置项目数据和加载输入数据,如下所示:
from pycaret.anomaly import * s = setup(df, log_experiment = True, experiment_name = 'psystock_anomaly')) -
然后,我们执行
compare_models(),如下所示:models()这里是输出:
![图 12.5 – 不同类型的模型
![img/image0057.jpg]
图 12.5 – 不同类型的模型
-
然后,执行你选择的异常检测模型,如下所示:
iforest = create_model('iforest', fraction = 0.1) iforest_results = assign_model(iforest) iforest_results.head() -
接下来,运行 MLflow 来检查所有模型(在以下网址:http://127.0.0.1:5000/#/experiments/1),你应该会看到一个像这样的屏幕:
![图 12.6 – MLflow 中自动可用的模型
![img/image0066.jpg]
图 12.6 – MLflow 中自动可用的模型
在这个阶段,你应该能够利用你在整本书中学到的知识来使用本书中识别的生产模型。接下来,我们将探讨如何将 MLflow 与其他语言集成——在这种情况下,是 Java。
将 MLflow 与其他语言集成
MLflow 主要是在机器学习领域的 Python 生态系统中根植的工具。在其核心,MLflow 组件提供了一个 表示状态传输(REST)接口。只要创建了 应用程序编程接口(API)包装器,底层代码就可以从任何支持 REST 的语言中访问。REST 接口在 www.mlflow.org/docs/latest/rest-api.html 中有广泛的文档;与其他语言的集成大部分是提供访问 API 的简洁、特定语言的库层。
MLflow Java 示例
在机器学习领域,多个团队在多种语言的环境中工作。在大型分布式系统中,最重要的平台之一是 Java 虚拟机(JVM)。能够实现可以与基于 Java 的系统交互的系统对于 MLflow 与更广泛的 信息技术(IT)基础设施的顺利集成至关重要。
我们将展示如何在 Java 中使用 MLflow 的示例(你可以在以下链接获取代码:https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter12/psystock-java-example)。为了在 Java 中使用 MLflow,你必须执行以下步骤:
-
按照指示安装 Java 和 Java 构建工具
Maven,链接为maven.apache.org/install.html。 -
创建一个包含 MLflow 客户端依赖项的
pom.xml文件,如下所示:<project> … <dependencies> <dependency> <groupId>org.mlflow</groupId> <artifactId>mlflow-client</artifactId> <version>1.17.0</version>.. </dependency> … </project> -
实现你的主类,如下所示:
package ai.psystock.jclient; import org.mlflow.tracking.MlflowClient; import org.mlflow.tracking.MlflowContext; import java.io.File; import java.io.PrintWriter; public class Main { public static void main(String[] args) { MlflowClient mlflowClient=new MlflowClient(); String runId="test"; RunStatus = RunStatus.FINISHED; MlflowContext = new MlflowContext(); MlflowClient client = mlflowContext.getClient(); client.logParam("test","alpha", "0.5"); client.logMetric("test","rmse", 0.786); client.setTag("test","origin","HelloWorldFluent Java Example"); mlflowClient.setTerminated(runId, runStatus, System.currentTimeMillis()); } } -
使用以下方式使用 Maven 构建你的项目:
mvn clean package -
执行以下代码以运行你的 Java 项目:
java -jar ./target/java-maven-command-line-1.0-SNAPSHOT.jar
在这个阶段,MLflow 本地集成到 Python 生态系统中。它提供了与其他生态系统类似的链接,就像我们在本章中用 JVM 语言演示的那样。接下来,我们将探索 R 语言的示例。
MLflow R 示例
我们将展示如何在 Databricks 环境中使用 MLflow 的示例(你可以在以下链接获取代码:github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter12/mlflow-example-r)。你可以从 Databricks 社区版环境中导入笔记本,并从那里探索代码。
在本节中,我们将在 R 语言的标准数据集上运行随机森林分类器,该数据集作为 R 包 Pima.tf 提供(rdrr.io/cran/MASS/man/Pima.tr.html)。这是一个简单的数据集,包含一组生物医学特征,用于检测特定患者是否患有糖尿病。
为了创建你的 R 示例代码的笔记本,你需要执行以下步骤:
-
在
community.cloud.databricks.com/上注册 Databricks 社区版,并创建一个账户。 -
使用您刚刚创建的凭证登录您的账户。
-
创建一个用于您工作负载的集群。您可以为您的负载拥有集群,每个集群的随机存取内存(RAM)限制为 15 GB(GB),并且使用期限为定义的时间段。
您可以在以下屏幕截图中查看集群创建过程的概述:
![图 12.7 – 在 Databricks 社区版中创建集群]()
图 12.7 – 在 Databricks 社区版中创建集群
-
在您的 Databricks 平台的登录工作空间页面上,通过点击页面右上角的创建空白笔记本按钮来创建一个新的笔记本,如图所示:
![图 12.8 – 在 Databricks 社区版中创建新的笔记本]()
图 12.8 – 在 Databricks 社区版中创建新的笔记本
-
我们现在已准备好在这个托管环境中启动一个笔记本来执行基本的训练作业。您可以通过点击工作空间中的新建笔记本来开始。您需要将默认语言设置为R,并将笔记本附加到上一章中创建的集群。
您可以在以下屏幕截图中查看笔记本创建过程的概述:
![图 12.9 – 添加您的新的 R 笔记本详情]()
图 12.9 – 添加您的新的 R 笔记本详情
-
您可以从导入 MLflow 依赖项开始您的笔记本,使用
install.packages并实例化库,如下所示:install.packages("mlflow") library(mlflow) install_mlflow() -
我们现在将使用所需的数据安装额外的包,以便能够执行我们的示例。在这个特定的例子中,我们将使用
carrier包来简化远程函数的操作并记录有关它们的信息。我们还将包括MASS包,其中包含我们将在此示例中使用的数据集。el071包和randomforest将用于统计函数和运行预测分类器。以下是您需要的代码:install.packages("carrier") install.packages("e1071") library(MASS) library(caret) library(e1071) library(randomForest) library(SparkR) library(carrier) -
接下来,我们将通过以下代码行
with(mlflow_start_run(), {)开始一个代码块来启动实验:这将基本上允许我们通过mlflow_log_param函数开始记录模型参数。在以下情况下,我们将在 MLflow 中记录算法每次分割的树的数量(ntree)和随机采样的特征数量(mtry)。代码如下所示:with(mlflow_start_run(), { # Set the model parameters ntree <- 100 mtry <- 3 # Log the model parameters used for this run mlflow_log_param("ntree", ntree) mlflow_log_param("mtry", mtry) -
在接下来的两行中,我们通过指定
Pima.tr训练数据集并添加算法参数来实例化随机森林算法。然后我们使用Pima.te测试数据进行预测。代码如下所示:rf <- randomForest(type ~ ., data=Pima.tr, ntree=ntree, mtry=mtry) pred <- predict(rf, newdata=Pima.te[,1:7]) -
我们现在可以专注于通过
caret包中可用的confusionMatrix方法计算模型性能周围的指标——在这种情况下,特异性和敏感性——如下所示:# Define metrics to evaluate the model cm <- confusionMatrix(pred, reference = Pima.te[,8]) sensitivity <- cm[["byClass"]]["Sensitivity"] specificity <- cm[["byClass"]]["Specificity"] # Log the value of the metrics mlflow_log_metric("sensitivity", sensitivity) mlflow_log_metric("specificity", specificity) -
我们现在可以专注于上传基于先前度量的混淆矩阵图。在 R 中,记录模型的方法是
mlflow_log_artifact。以下是你需要使用的代码:# Log the value of the metrics # Create and plot confusion matrix png(filename="confusion_matrix_plot.png") barplot(as.matrix(cm), main="Results", xlab="Observed", ylim=c(0,200), col=c("green","blue"), legend=rownames(cm), beside=TRUE) dev.off() # Save the plot and log it as an artifact mlflow_log_artifact("confusion_matrix_plot.png") -
最后,我们可以使用
carrier包上可用的crate方法将模型函数序列化并记录到 MLflow 中,以便可以从另一个 R 笔记本中重用。我们最终使用mlflow_log_model记录模型,并在最后一行代码后关闭括号,如下面的代码片段所示:predictor <- crate(function(x) predict(rf,.x)) mlflow_log_model(predictor, "model") }) -
现在,你可以自由地探索你环境中的 实验 选项卡,你应该能够访问你的模型日志并探索运行的指标和细节,如下面的屏幕截图所示:
![图 12.10 – MLflow 中自动可用的模型
![img/Image0102.jpg]
图 12.10 – MLflow 中自动可用的模型
在本节中,我们探讨了 Java 和 R 的示例,这两种语言在机器学习生态系统中对工程师和数据科学家都极为相关。现在,我们将深入了解通过插件扩展 MLflow 功能。
理解 MLflow 插件
作为一名机器学习工程师,在你的项目中,你可能会多次达到框架的限制。MLflow 通过其插件功能提供扩展系统。插件架构允许软件系统的可扩展性和适应性。
MLflow 允许创建以下类型的插件:
-
跟踪存储插件:此类插件控制并调整你用于在特定类型的数据存储中记录实验度量值的存储。
-
log_artifact和download_artifacts。 -
git_tags和repo_uri,以及你系统环境中的其他相关元素。 -
模型注册存储:此功能允许你自定义模型存储的位置;例如,如果你只能通过 安全文件传输协议(SFTP)系统存储生产基础设施中的模型,你可以使用此功能。在需要适应有限服务集和你的模型注册存储的监管环境中,此功能可能具有优势。
-
MLflow 项目部署:此类插件控制并调整你的部署方式。在部署环境不支持 MLflow 的情况下,你可以使用此功能来专门化你的部署方式。
-
请求头提供者:使你能够控制并向 MLflow 发出的 REST 请求添加额外值。一个例子是,如果所有 超文本传输协议(HTTP)请求都需要一个与你的网络中集成公司 单点登录(SSO)的安全令牌相关的头键。
-
项目后端:这为在不同的执行环境中运行 MLflow 提供了可扩展性。例如,Kubernetes 和 Sagemaker 都是后端,因此 MLflow 和模型将部署的环境之间的集成需要为每种情况编写特定的代码。
要创建一个插件,您必须创建一个 Python 包,该包覆盖 MLflow 中的特定模块。我们将根据官方文档逐步开发一个示例 MLflow 插件。您可以按照以下仓库 URL 跟随:https://github.com/PacktPublishing/Machine-Learning-Engineering-with-MLflow/tree/master/Chapter12/mlflow-psystock-plugin。要完成这个过程,请按照以下步骤进行:
-
在
setup.py文件中定义您的插件。install_requires=["mlflow"]这行代码将 MLflow 与您的包捆绑在一起,足以安装您的新插件包,并且它将创建一个更改后的 MLflow 实例。代码如下所示:setup( name="mflow-psystock-deployment-plugin", # Require MLflow as a dependency of the plugin, so that plugin users can simply install # the plugin and then immediately use it with MLflow install_requires=["mlflow"], entry_points={ "mlflow.deployments": " psystock target= psystock. deployment_plugin" } ) -
在名为
mlflow-psystock-deployment/_init_.py的文件夹中创建一个空的包命名空间文件,以表示包的创建。 -
下一步涉及通过我们想要在插件中覆盖以覆盖 MLflow 默认行为的方法来覆盖文件的创建。
在我们的特定情况下,我们将查看覆盖 MLflow 中的
BaseDeploymentClient类,这基本上意味着我们需要实现所有方法。我们将实现一系列虚拟方法来展示这个过程,从create_deployment和update_deployment方法开始,如下所示:import os from mlflow.deployments import BaseDeploymentClient p_deployment_name = "pystock" class PluginDeploymentClient(BaseDeploymentClient): def create_deployment(self, name, model_uri, flavor=None, config=None): if config and config.get("raiseError") == "True": raise RuntimeError("Error requested") return {"name": f_deployment_name, "flavor": flavor} def delete_deployment(self, name): return None def update_deployment(self, name, model_uri=None, flavor=None, config=None): return {"flavor": flavor} -
我们接着实现了
list_deployments和get_deployments方法,如下所示:def list_deployments(self): if os.environ.get("raiseError") == "True": raise RuntimeError("Error requested") return [f_deployment_name] def get_deployment(self, name): return {"key1": "val1", "key2": "val2"} def predict(self, deployment_name, df): return "1" def run_local(name, model_uri, flavor=None, config=None): print( "Deployed locally at the key {} using the model from {}. ".format(name, model_uri) + "It's flavor is {} and config is {}".format(flavor, config) )run_local(name, model_uri, flavor=None, config=None)方法是当实例化此插件时将被执行的主要方法。 -
您现在可以通过运行以下命令在 MLflow 上安装您的插件:
pip install-e .
我们通过本节关于通过新功能扩展 MLflow 的内容来结束本书,这允许您作为机器学习工程师在合理的时候扩展 MLflow。
摘要
在本章中,我们讨论了一些用例,并提供了示例 MLflow 管道。我们探讨了在两种不同场景下实现 AutoML,当我们没有目标时,我们需要使用异常检测作为无监督机器学习技术。我们讨论了非 Python 基础平台的使用,并以如何通过插件扩展 MLflow 作为结论。
在这个阶段,我们已经使用 MLflow 在机器学习工程领域解决了广泛和深入的话题。您的下一步肯定是进一步探索,并在您的项目中利用本书中学到的技术。
进一步阅读
为了进一步扩展您的知识,您可以查阅以下链接中的文档:



























浙公网安备 33010602011771号