关于ml:机器学习的持续交付CD4ML

38次阅读

共计 14887 个字符,预计需要花费 38 分钟才能阅读完成。

机器学习的继续交付 -CD4ML

端到端自动化构建部署机器学习利用

原文:Continuous Delivery for Machine Learning – CD4ML
关键字:继续部署、继续交付、机器学习、CD4ML
作者:Danilo Sato, Arif Wider, Christoph Windheuser
译者:周冠龙 Guanlong Zhou

写在后面

ThoughtWorks 在最新一期的技术雷达中,将 CD4ML 举荐为“试验”评级,我所在的 team 恰好在给客户做一套与 ML 相干的零碎,用到很多 CD4ML 中的概念和实际。因为文章较新,网上还没有适合的译文,故本人翻译以便与大家独特学习。第一次翻译此类文章,如有不当,敬请斧正,不胜感激。

现在,机器学习(ML)在各行各业中变得越来越遍及,与传统软件(例如 Web 服务或挪动利用)相比,ML 的开发、部署和继续优化会更加简单。复杂性源于三个维度的可变性:代码自身、机器学习的模型和数据。它们的变动通常很简单又难以预测,而且不容易测试,难以解释并且难以改良。机器学习的继续交付(CD4ML)将继续交付的原理和实际引入到机器学习利用(程序),给咱们提供一些能够遵循的基本准则。

简介和定义

2015 年,Sculley 等人在 Google 发表驰名论文“Hidden Technical Debt in Machine Learning Systems“,其中强调指出,在事实世界里的机器学习零碎中,真正的机器学习代码只占整个工程的一小部分。零碎中存在大量围绕 ML 相干的基础设施架构和流程用于反对 ML 零碎演进。在论文中,他们还探讨了许多此类零碎中积攒的技术债,比方和数据依赖性、模型复杂性、可再现性、测试、监控以及应对外部世界的变动相干的问题。
许多传统软件系统中也存在相似的问题,所以继续交付引入一个基于自动化流程、质量保证和标准,牢靠并可复用地将软件部署到生产环境的办法。
杰兹和戴夫曾在他们的开创性著述《继续交付》中指出:
“继续交付是一种可能以可继续的形式平安疾速地将所有的变更 – 包含性能增加、配置更改、谬误修复和试验 — 投入生产或交付用户的能力。”
- 杰兹·汉布尔(Jez Humble)和戴夫·法利(Dave Farley)
除了代码之外,ML 模型和训练数据的变动是另一种类型的变更,咱们须要对它们进行治理并将其纳入软件交付过程中(图 1)。

图 1: 在机器学习利用中 3 个维度的变更 – 数据、模型和代码 – 和一些变更的起因

思考到这些方面,咱们能够扩大“继续交付”的定义,以纳入事实世界机器学习零碎中存在的新元素和挑战,咱们将这种办法成为“机器学习的继续交付(CD4ML)”。
CD4ML 是一种软件工程方法论,应用此办法,跨性能团队可基于代码、数据和模型小步且平安地增量训练机器学习利用,并且这个机器学习利用能够在任何的工夫点更加牢靠地被疾速重现和部署。

上面对定义中的关键字进行逐个解释
软件工程办法 :它使团队可能无效地产出高质量的软件。
跨性能团队 :一群来自数据工程、数据迷信、机器学习工程、开发、运维和其余常识畛域,具备不同技能和工作形式的专家合作在一起,充分发挥每个团队成员的技能和劣势。
基于代码、数据和机器学习模型开发的利用(软件):ML 软件生产过程的所有产物都须要通过不同的工具和工作流程,进行相应的版本治理。
小而平安的增量(部署):一个软件应用程序的公布被分为了多个小步增量迭代公布,这将使每次公布所产生的变动具备可见性和可控制性,从而减少了部署过程的安全性。
可重现和牢靠的软件公布 :尽管模型的输入后果具备不确定性并且难以重现,但将 ML 软件公布到生产中的过程是牢靠且可重现的,在此过程中,该当尽可能进步自动化水平。
不受限于工夫 :能够随时将 ML 利用公布到生产环境至关重要。即便组织不想始终交付软件,它也应始终处于可公布状态。何时公布应该是由业务决策决定,而不是技术决策。
适应周期短:短周期意味着开发周期只有数天,甚至几小时,而不是几周,也不是几个月甚至几年。牢靠的自动化流程是实现这一指标的要害。通过应用生产环境中取得的后果来调整 ML 模型能够造成一个疾速的反馈循环。

在本文中,咱们将实现 CD4ML,并展现一系列机器学习应用程序里的重要技术组件,同时解释如何将不同的工具联合应用以实现残缺的端到端过程。在适当的时候,咱们将介绍一些咱们选用的其余工具。随着在咱们行业中的实际,咱们还将探讨更多的开发和钻研畛域。

一个预测销售数据的机器学习利用

自 2016 年以来,咱们就开始思考如何将继续交付使用到机器学习零碎中,咱们公布了一个用于展现 ML 的案例钻研,这是咱们与 AutoScout 单干构建的一个我的项目,用于预测在其平台上发售的汽车价格。
然而,咱们没有被容许应用实在的代码作为示例,所以咱们决定应用面向公众公开的问题和数据集构建一个 ML 示例利用,以论述 CD4ML 的实现过程。这个机器学习应用程序解决了许多零售商面临的一个常见预测问题:尝试依据历史数据预测给定产品在将来的销售量。咱们为厄瓜多尔大型杂货零售商 Corporación Favorita 公布在 Kaggle 上的问题构建了简化的解决方案。出于咱们的目标,咱们组合并简化了它们的数据集,因为咱们的指标不是找到最佳预测后果(您的数据科学家能做得更好),而是演示如何实现 CD4ML。
基于监督学习算法和风行的 Scikit-learn Python 库,咱们应用具备标签的输出数据训练失去预测模型。将这个模型集成到简略的 Web 应用程序中,而后将其部署到云生产环境中。图 2 简略展现了此流程。


图 2:训练 ML 模型,将其与 Web 应用程序集成并部署到生产中的初始流程
部署实现后,用户能够在 Web 应用程序(图 3)中抉择产品种类和预测日期,而后预测模型将输入对该日选定产品销量的预测后果。


图 3:Web UI 演示模型

独特的挑战

后面的探讨给咱们开了个好头,然而在发展施行端到端部署的实际过程时,咱们遇到了两个挑战。第一个挑战源于组织构造:不同的团队可能参加流程中不同的局部,并且存在交接(通常是“甩锅”)的问题,而对如何逾越这些边界却没有明确的冀望(图 4)。数据工程师可能正在构建使数据可被拜访的流水线,而数据科学家正在为如何构建和晋升 ML 模型性能发愁。而后,机器学习工程师或开发人员将不得不为如何集成该模型并公布到生产环境而担心。


图 4:大型组织中的常见职能孤岛可能会制作屏障
扼杀了将机器学习应用程序部署到生产环境 - 端到端流程自动化的能力

这将导致我的项目的提早交付以及团队之间产生摩擦。一个常见的问题是模型只能停留在实验室,而永远不会来到概念验证阶段。还有一种状况,如果他们以手工形式将其投入生产环境,ML 模型在之后将会过期且很难被更新。
第二个挑战是技术层面的:如何确保此流程是可反复和可被审核的。因为这些团队应用的工具不尽相同并遵循不同的工作流程,端到端的自动化很难实现。除代码外,还须要治理许多其余组件,对其进行版本控制并不容易。在这些组件中,有些体积很大,须要用到更加简单的工具能力对他们进行无效的存取。
只管解决组织挑战不在本文探讨范畴之内,然而咱们能够借鉴 Agile 和 DevOps 的教训,建设以后果为导向的且囊括不同学科的领域专家的跨职能团队,从而结构一个端到端的 ML 零碎。如果您的组织无奈做到这一点,则至多激励突破团队间的阻碍,并在整个过程中尽早进行合作。
本文的其余部分将探讨咱们针对技术挑战得出的解决方案。咱们将深刻探索每个技术组件,并逐渐改良和扩大端到端流程以使其更加欠缺。

CD4ML 的技术组件

当咱们思考如何应用机器学习解决预测问题时,第一步是理解数据集。在这种状况下,数据存储在一系列 CSV 文件里,其中蕴含以下信息:

  • 产品,例如它们的分类以及是否易腐
  • 商店,例如它们的地位以及它们如何汇集在一起
  • 非凡事件,例如公共假期,季节性事件或 2016 年厄瓜多尔产生的 7.8 级地震
  • 销售交易记录,包含给定产品的销售数量、日期和地位

在这个阶段,数据分析师和数据科学家通常将执行某种探索性数据分析(EDA),以理解数据的“形态”,并确定粗粒度模式和异样值。例如,咱们发现某些产品的销售单位数为负,咱们将其解释为退货。而咱们仅打算摸索销售数据,因而退货数据将从训练数据集中删除。
在许多组织中,训练 ML 模型所需的数据可能不会齐全依照数据科学家所需的形式来结构。因而,它着重强调了咱们的第一个技术组件:可被发现和可被拜访的数据。

可被发现和可被拜访的数据

最常见的数据源是你的外围交易系统。然而,从组织内部引入其余数据源的价值也不容疏忽。咱们找到了一些用于数据收集和使数据可用的常见模式,例如 Data Lake 架构、更传统的数据仓库体系、实时数据流汇合,和最近咱们正在尝试构建的去中心化的 Data Mesh 架构。
无论你应用哪种体系和架构,都须要保障你的数据是可被发现和可被拜访的。对数据科学家而言,寻找所需数据破费的精力越多,他们建设有用的模型所破费的工夫就越长。除此以外,他们会心愿在现有输出数据之上产生新的特色数据,这可能有助于改善其模型的性能。
在咱们的示例里,进行初始探索性​​数据分析(EDA)之后,咱们决定将多个文件合并成为单个 CSV 文件,并清理无关数据点和可能在模型中引入无害噪声的数据点(例如负销售)。而后,咱们将输入的文件放云存储系统中。
应用此文件作为输出训练数据的快照,基于文件夹构造和文件命名约定,咱们可能设计出一种简略的办法来对数据集进行版本控制。数据版本控制是一个绝对较大的话题,源于它能够在两个不同维度上进行扭转:数据结构的变动和随时间推移理论采样数据内容的变动·。咱们的数据科学家 Emily Gorcenski 在其博客文章中更具体地介绍了此主题。不过在本文的前面,咱们将探讨随着工夫的推移对数据集进行版本控制的其余办法。
值得注意的是,在事实世界中,你可能会搭建更简单的 data pipelines(数据流水线),便于数据科学家能够轻松的从多个数据源获取数据并应用。

可反复训练的模型

当数据筹备好之后,上面咱们将开始迭代数据迷信的工作流程以构建模型。咱们通常将数据分为训练集和验证集,尝试组合应用不同的算法以及调整其参数和超参数。这样就产生了一个能够被验证集评估的模型,以评估模型预测的品质。一步一步迭代训练模型的过程,咱们称之为机器学习 (ML) 流水线。
在图 5 展现的是针对销售预测问题构建的 ML 流水线,其中蕴含了不同的代码、数据和模型组件。输出数据、两头训练后果和验证数据集以及输入模型文件可能很大,咱们不心愿将他们存储在代码仓库中。而且,流水线的各个阶段会常常须要被批改,这使得其很难在数据科学家的本地环境之外被复制。


图 5:针对咱们的销售预测问题的机器学习流水线,以及应用 DVC 使其自动化的 3 个步骤

为了使模拟训练过程可能代码化,咱们应用了一个叫做 DVC(Data Science Version Control)的开源工具。它提供了与 Git 相似的语义,同时它还解决了一些 ML 特有的问题:

  1. 它具备多个后端插件,可在源代码管制存储库之外的内部存储中获取并存储大文件;
  2. 它能够跟踪存储文件的版本,从而容许咱们在数据更改时从新训练咱们的模型;
  3. 它能够保留用于执行 ML 流水线的依赖关系图和命令,从而使该过程能够在其余环境中重现;
  4. 它能够与 Git 分支集成,以容许多个试验共存;

例如,咱们能够应用三个 dvc run 命令来配置图 5 中的初始 ML 流水线(- d 指定依赖项,- o 指定输入,- f 是记录该步骤的文件名,而 - M 是后果度量):
dvc run -f input.dvc \ ➊
-d src/download_data.py -o data/raw/store47-2016.csv python src/download_data.py
dvc run -f split.dvc \ ➋
-d data/raw/store47-2016.csv -d src/splitter.py \
-o data/splitter/train.csv -o data/splitter/validation.csv python src/splitter.py
dvc run ➌
-d data/splitter/train.csv -d data/splitter/validation.csv -d src/decision_tree.py \
-o data/decision_tree/model.pkl -M results/metrics.json python src/decision_tree.py
每次执行完指令会创立一个相应的文件,该文件能够提交到版本控制器中,并容许其他人通过 DVC repo 来重现整个 ML 流水线。
一旦找到适合的模型,咱们会将其视为须要版本化的工件 (artifact),并将它部署至生产环境。在此,咱们应用 dvc push 和 dvc pull 命令来公布和获取它。
有一些其余开源工具能够解决这些问题:Pachyderm 应用容器技术执行流水线中的各个步骤,并通过追踪数据提交,解决了数据版本控制和记录数据出处问题,优化了流水线的执行。MLflow 我的项目定义了一种新的文件格式,用于配置环境和流水线各个步骤,并提供了 API 和 CLI 工具,能够在本地或近程运行我的项目。咱们之所以抉择 DVC,是因为它是一个非常简单的 CLI 工具,能够更好地解决这上述问题。

模型的供应

当确定了适合的模型,咱们须要决定如何在生产环境中应用。咱们曾经发现了一些实现它的办法:

  • 嵌入式模型:这是略简略的办法,您能够将模型视为在生产应用程序中构建和打包的依赖。从当初开始,您能够将利用程序代码和所选模型的打包组合成为一个整体利用。
  • 将模型部署为独自的服务:在这种办法中,模型被包装在能够独立部署的应用服务中。这样能够对模型独立公布更新,然而因为每次预测都须要进行近程调用,这会引入一些提早。
  • 以数据模式公布模型:应用这种办法,模型也被独立公布,不同的是运行中的其它利用会将其作为数据摄取。咱们曾经在流解决 / 实时处理计划中看到了这种用法。在这种计划中,应用程序能够订阅模型公布事件,在读取新模型到内存中的之前,持续应用旧版本的模型。蓝绿部署或金丝雀部署之类的软件部署模式也能够在这种状况下应用。

在咱们的示例中,鉴于咱们应用的应用程序也是由 Python 编写的,因而咱们决定应用绝对简略的嵌入模型办法。咱们的模型将导出为序列化对象 (pickle 文件),并由 DVC 推送到存储。在构建应用程序时,咱们将其拉出并嵌入到 Docker 容器中。从此,Docker 镜像将蕴含咱们的应用程序 + 模型,该镜像会被版本化并部署到生产中。
除了应用 pickle 序列化模型对象,还有其余工具可用于实现嵌入式模型模式。MLeap 为导出导入 Spark、scikit-learn 和 Tensorflow 模型提供了一种通用的序列化格局。还有与语言无关的替换格局能够用于模型共享,例如 PMML、PFA 和 ONNX。其中的一些序列化办法也实用于实现“model as data”。
此外,还能够应用例如 H2O 之类的工具将模型作为 POJO 导出至 Jar 库中,而后能够将它作为我的项目依赖增加到应用程序中。应用这种办法的益处是,你能够应用数据科学家相熟的语言 (Python 或 R) 训练模型,并将模型导出为在不同指标环境(JVM)中运行的已编译二进制文件,这样能够缩小工夫干预。
为了实现“model as data”模式,许多云服务供应商都提供了工具和 SDK 用于将你的模型包装并部署至他们的 MLaaS(Machine Learning as a Service)平台中,如 Azure Machine Learning、AWS Sagemaker 和 Google AI Platform。另一个抉择是应用像 Kubeflow 这种工具,旨在 Kubernetes 上部署机器学习工作流,只管它想尝试解决的不仅仅是模型供应局部的问题。
MLflow Models 尝试提供一种规范来打包不同“口味”的模型,以供被上游的各种工具所应用,一些把模型作为独立的服务,另一些将模型嵌入在应用程序中。能够说,这是以后开发畛域、各种工具和厂商正在致力简化的重点工作,换句话说,这意味着当初还没有 (公开或私下) 明确的规范被证实是最佳实际,因而你须要依据你本人的条件去评估,从而抉择满足你需要的实际。
值得注意的是,无论你决定应用哪种模式,训练出的模型和它的消费者之间始终存在隐式契约。此模型期待输出数据合乎指定状态,如果数据科学家扭转了契约,那么就须要从新输出数据或特征值,则可能呈现集成问题,导致应用该模型的应用程序损坏。因而,测试是咱们必须思考的。

机器学习中的品质测试

ML 工作流程中能够应用到的测试品种繁多。只管机器学习零碎在某些方面天生具备不确定性且难以自动化,然而减少不同类型的自动化测试依然具备价值并且能够进步机器学习零碎的整体品质:

  • 验证数据:咱们能够增加用于验证输出数据的测试来验证数据格式和构造,或验证咱们对有效值的假如。例如,他们在某特定范畴内或不为空值。对于工程特征值,咱们能够编写单元测试来测验他们是否计算正确。例如,对数字特色进行缩放或归一化,”one-hot”编码的后果包涵全 0 和一个 1,或应用失当值替换缺失值。
  • 验证组建间集成:咱们能够应用相似的办法测试不同服务间的集成。这里应用“契约测试”来验证预期的模型接口与应用中的应用程序的兼容性。同时还存在另一种测试,用于确保将模型以不同格局导出公布后,依然能够产出雷同的后果。这能够通过针对雷同的验证数据集,运行原始模型和生产模型,并比照他们的后果来实现。
  • 验证模型品质:尽管机器学习的模型性能具备不确定性,但数据科学家通常会收集和监控一系列指标对模型进行评估,例如错误率、准确率、准确率、召回率、混同矩阵、AUC、ROC 等。他们在调参优化过程中也很有用。作为简略的品质管制,咱们在流水线引入阈值测试和棘轮。
  • 验证模型偏差和公平性:尽管咱们会在总体测试和验证数据集上取得不错的后果,然而查看模型在特定数据集上的基准体现也尤其重要。举个例子,在训练数据中可能存在固有的偏差,比照该数据集和真实世界中数据的理论散布,会发现在某些给定特征值(例如:种族、性别和地区)上存在更多的数据点,因而对跨不同域数据的查看工作也变得尤其重要。像 Facets 之类的工具能够帮忙你对数据进行切片可视化,从而帮忙发现数据集中不同特色的值散布。

在咱们的示例应用程序里,Favorita 定义的评估指标应用一个归一化的错误率。咱们编写了一个简略的 PyUnit 阈值测试,如果错误率超过 80%,测试就会中断,并且测试被安置在公布新版本的模型之前,以演示如何阻止不良模型的部署。
尽管咱们给出的测试示例绝对简略,然而要全面的对模型品质进行评估,并不容易。随着工夫流逝,如果咱们始终基于雷同的数据集计算指标,那么将开始遇到适度拟合的问题。同时,当其余模型已被公布,你须要保障新版本的模型不会对不可见数据进行降级。因而,对测试数据的治理和整顿变得尤其重要。
当你在散发模型和导出模型以供其余程序应用时,你会发现在训练时和服务时,特征向量的计算结果不同。解决此问题的一种办法是将保留数据集和模型打包件一起散发,并容许上游的利用开发团队在集成了保留数据集之后,依据保留数据集从新评估模型的性能。这相当于传统软件开发中宽泛被应用的集成测试。
除了下面提到的,还有一些其余类型的自动化测试能够思考,然而咱们认为有必要在流水线中退出一些(人为)手工的阶段,以展现无关模型的具体参数和信息,并让人们决定是否对它进行降级部署。这个过程,实现了你对机器学习流程的监管,也引入了对模型偏误和模型公平性的人为查看,同时为人们了解以后模型体现的优劣提供了可被解释的信息。
通过退出更多类型的测试,将使你从新思考测试金字塔的形成:如图 6 所示,你能够为每种产出(代码、模型和数据)设计独自的金字塔,并思考如何组合他们。相对而言,机器学习零碎的测试和品质管制更加简单,能够作为一个主题另写一篇文章深入探讨。

图 6:如何将不同的测试金字塔联合用于 CD4ML

试验追踪

为了撑持起这个治理过程,对各个试验信息的捕捉和追踪变得尤其重要,人们将用它决定该将哪种模型部署推广到生产环境当中。而数据科学家的工作重心次要在钻研上,常常会存在多个试验共存的状况,而其中许多试验可能从未投入到生产环境。
在钻研阶段,这种试验办法不同于传统的软件开发流程,因为咱们预期这些试验中的许多代码都将被抛弃,只有其中局部代码被认为值得投入生产。因而,须要定义一种追踪他们的办法。
在示例中,咱们决定遵循 DVC 倡议的办法,即应用不同的 Git 分支来追踪源代码中的不同试验。只管这违反了咱们在单个骨干上实际继续集成的偏好。DVC 能够从不同分支和标签的试验中调取和显示指标,从而能够轻松地在它们之间切换。
在传统的软件开发中,应用 git 分支作为性能分支存在一个毛病,如果分支的寿命过长,那么可能导致分支合并艰难。因为对代码的变更会产生较宽泛的影响,所以这会组织开发团队尽可能的对代码进行重构。同时,这种做法迫使对每条分支别离设置作业工作,直到分支代码被合并到骨干后,能力适当地进行和其它零碎的集成,这种做法有违继续集成实际。
对于机器学习的试验,咱们冀望绝大部分的分支代码都不会被用于集成,并且各个试验之间的代码差别通常很小。从自动化继续集成的角度上看,咱们实际上心愿为每个试验训练多个模型,并收集指标,以告知咱们哪种模型能够被用于下一阶段部署。
除了 DVC 之外,MLflow Tracking 是另一个能够帮忙咱们进行试验跟踪的工具。它能够作为托管服务进行部署,同时提供了 API 和 Web 界面用于追踪不同试验的运行以及他们的参数和性能指标,如图 7 所示。


图 7:MLflow Tracking Web 界面显示试验的运行、参数和指标
为了更好地反对试验过程,你可能须要多种 (有时须要制订的硬件) 环境。用于培训,应用具备弹性的基础设施的益处变得非常明显。基于云的基础架构非常适合这种场景,许多云服务供应商都在构建服务和解决方案以反对这个流程。

模型部署

在咱们提供的简略示例里,咱们只尝试构建一个模型,将该模型嵌入到应用程序中一起部署。而在事实世界中,简单的场景会应用多种部署形式:

  • 多组模型:有时你可能有多个模型用于执行同样的工作。例如,咱们能够对每一种产品训练一个模型。在这种状况下,能够将模型部署为独自的服务,使应用程序通过独立的 API 调用获取预测后果。而后,你能够在之后决定哪些模型在公布的接口中被应用。
  • 影子模型:在生产环境中替换模型时,会用到此模式。你能够将新的模型与以后模型独特编排部署,把新的模型为影子模型。发送雷同的生产数据到这两个模型,收集并察看他们的体现,并以此决定是否应用新的模型。
  • 竞争模型:这种模型实用略微简单一点的场景,当你尝试在生产环境中应用模型的多个版本(如 A / B 测试)时,试图找出哪个版本更好。这里的难点在于如何确保流量被从新定向到正确的模型,同时你还需破费一些工夫,以确保收集足够的数据来保障作出的决策具备统计学意义。
  • 在线学习模型:与咱们后面探讨的模型不同,在线学习模型是通过离线训练产生,而用于在线预测。在线学习模型应用的算法和技术能够随着新数据的到来而一直进步其本身性能,所以能够在生产环境中一直学习。这带来了额定的复杂性,因为如果不向模型提供雷同的数据,本地版本化的动态模型工件将会产生不同的预测后果。你不仅须要对训练数据进行版本控制,还要对将影响模型性能的生产数据进行版本控制。

在此,我想重申一次,为了反对更简单的部署计划,应用基于弹性基础设施的架构将使你受益匪浅。除了能够在生产环境中同时运行上述多种模型以外,弹性基础设施能够让你按需进行横向扩大和纵向伸缩,从而进步零碎整体的可靠性和可扩展性。

继续交付的编排

在所有次要构件模块都装置配置到位之后,有必要将他们串到一起,这就就要用到继续交付的编排工具。在这个畛域中,有很多工具可供选择,他们中的大部分都提供了一些办法,用于配置和执行部署流水线以构建软件并将其公布到生产环境。在 CD4ML 中,咱们还有一些其余需要:配置搭建基础设施,执行 ML 流水线,训练并捕捉来自不同模型试验的指标;data-pipeline 的构建、测试和部署;不同模型的测试、验证和比照,以确定将要采纳的模型;基础架构的配置搭建以及将模型部署至生产环境。
咱们抉择应用 GoCD 作为咱们的继续交付工具,因为它设计之初,就确定了将流水线概念作为首要设计指标。不仅如此,GoCD 提供了多种触发器和提级机制,容许咱们将不同流水线组合编排,从而实现更加简单的工作流程。
在咱们的简化示例中,咱们还没有构建任何简单的 data-pipeline 或配置基础设施,咱们仅演示了如何组合应用两条 GoCD 流水线,如图 8 所示:

  • 机器学习流水线:应用 GoCD 代理执行模型训练和评估,以及执行根本的阈值测试用于决定是否推广模型。
  • 应用程序部署流水线:用于构建和测试利用程序代码,用于应用 dvc pull 从上游流水线取得适合的模型,将模型和应用程序打包为 Docker 镜像,并将它公布到 Kubernetes 生产集群。

    图 8:在 GoCD 中联合机器学习流水线和应用程序部署流水线

随着我的项目的推动,咱们能够扩大 ML 流水线以并行执行多个试验(此性能依赖于 GoCD 的 fan-out/fan-in 模式),同时咱们须要定义模型监管流程,用于查看模型的偏差性、正确性和公正性。还有一些其它品种的步骤,用于决定哪些模型能够被推广和部署到生产环境中。
最初,继续集成的调度还蕴含另一个方面,就是为了避免将体现不佳的模型部署到生产环境后,可能及时撤销的回滚机制。它在整个流程中起到安全网的作用。

模型的监控与察看

既然咱们的模型曾经部署上线,咱们就须要理解它在理论生产环境中的体现,并买通数据反馈流程,形成残缺的循环。在此,咱们能够复用现有应用程序和服务中已有的监控和观察所需的基础设施。
实时零碎通常会应用日志聚合和指标收集工具来捕捉零碎中重要的数据,例如业务 KPIs、软件可靠性、性能指标、故障信息和异常情况下触发报警的其余指标。咱们同样能够应用这些工具来捕获数据,用于了解咱们模型的体现。数据蕴含:

  • 模型的输出:通过剖析采集到模型的数据,查看模型训练是否存在偏斜。模型的输入:分析模型从输出中失去的预测和倡议,以理解模型在实在数据上的体现。
  • 模型的可解释性输入:例如模型的各项系数、ELI5 或 LIME 输入之类的度量规范,容许进一步的钻研以理解模型如何进行预测,用来辨认训练期间未发现的潜在适度拟合或偏差。
  • 模型的输入与决策:基于生产环境的输出数据,察看咱们的模型将进行哪些预测,以及应用这些预测进行哪些决策。有时,应用程序可能会抉择疏忽模型并间接依据预约义的规定做出决定(或防止未来呈现偏差)。
  • 用户的行为与处分:基于进一步对用户行为的追踪,咱们能够捕捉“处分指标”以理解模型是否达到了预期的成果。例如,如果咱们显示产品举荐,能够跟踪用户何时决定购买举荐产品作为处分指标。
  • 模型的公平性:针对可能存在偏颇的已知特色(例如种族,性别,年龄,支出群体等)剖析输出数据和输入预测。

在咱们的示例中,咱们应用 EFK Stack 做监督和察看,它次要由 3 个工具组成:

  • Elasticsearch:开源搜索引擎。
  • FluentD:用于对立日志记录的开源数据收集器。
  • Kibana:可轻松浏览和可视化 Elasticsearch 索引的数据摸索工具。

首先,应用咱们的应用程序中的代码来记录模型的输出和预测,用于生成 FluentD 事件:
predict_with_logging.py…
df = pd.DataFrame(data=data, index=[‘row1’])
df = decision_tree.encode_categorical_columns(df)
pred = model.predict(df)
logger = sender.FluentSender(TENANT, host=FLUENTD_HOST, port=int(FLUENTD_PORT))
log_payload = {‘prediction’: pred[0], data}**
logger.emit(‘prediction’, log_payload)
而后,该事件在 ElasticSearch 中转发并建设索引,能够登陆 Kibana 的网页界面对其进行查问和剖析,如图 9 所示,

图 9:Kibana 中分析模型的预测
还有很多其它用于监控和察看的常用工具,例如 ELK Stack(应用 Logstash 而非 FluentD 进行日志提取和转发)、Splunk 等等。
当你在生产环境中部署了多个模型后,对数据的收集、监控和察看变得尤为重要。例如,你可能须要评估一个影子模型,或是正在进行拆分测试,亦或是应用多组模型进行多臂赌博机试验 (multi-armed bandit)。
这同样实用于以下场景,如果你须要进行终端试验,例如在用户的挪动设施上训练模型或进行模型交融,或者部署多组在线学习模型,这些模型会一直学习生产环境中的新数据,而随工夫产生扭转。
通过捕捉此数据,能够造成一个残缺的数据反馈环。这能够通过收集更多的实在数据(例如在定价引擎或举荐引擎)实现,也能够通过增加剖析人员,让他们剖析从生产环境中捕捉的新数据,创立用于制作新模型或改良模型的新训练数据集而实现。数据反馈的闭环是 CD4ML 的一大劣势,因为它使得咱们可能依据从理论生产数据中取得的教训来调整模型,从而实现继续改良的目标。

端到端的 CD4ML 流程

通过逐渐攻克各项技术难题,并应用一系列的工具和新技术,咱们设法搭建端到端的 CD4ML 流程如图 10 所示,该流程治理三个维度的工件 (代码、模型和数据)。

图 10:机器学习端到端流程的继续交付
实际上,咱们须要一种简略的办法来治理、发现、拜访和版本化咱们的数据。而后,咱们能够自动化模型的构建和训练工作,使这部分的流程可被重用。从而,咱们能够进行多组模型的试验和训练。

接下来怎么办?

咱们将本文中应用示例应用程序和代码上传到了的 Github 仓库,用于在各种会议和咱们给客户做的 workshop。咱们将一直摸索对于如何实现 CD4ML。在本大节中,咱们将重点介绍一些 workshop 中未波及的畛域,以及一些开放性畛域以待在未来能够进一步摸索。

数据版本控制

在继续交付中,咱们将每次代码提交作为一个 release 的候选,这将触发部署流水线的执行一次构建部署。如果它通过了流水线的所有阶段,就能够被部署到生产环境中。在议论 CD4ML 时,咱们常常遇到的一个问题是“当数据变动时,如何触发流水线?”
在咱们的例子中,机器学习流水线起始于 download_data.py 脚本如图 5 所示,它负责从共享区下载训练数据集。如果咱们更改了共享区数据集的内容,这并不会立刻登程流水线,因为程序的代码没有发生变化,并且 DVC 也检测不到它。为了可能将数据版本化,咱们必须创立一个新的文件或更改文件名,这反过来须要咱们更新 download_data.py 代码应用新的数据门路,并为此提交一次代码。
有一种更好的方法,容许 DVC 对文件内容进行追踪,并替换咱们之前写的代码:
dvc add data/raw/store47-2016.csv ➊
这将对咱们的机器学习流水线稍作批改,如图 11 所示

图 11:批改第 1 步以容许 DVC 跟踪数据版本并简化 ML 流水线

这会创立一个元数据文件,用于追踪和校验咱们提交到 Git 的文件。当文件内容变动时,DVC 会更新元数据文件,这个变更将会触发一次流水线。
尽管这容许咱们在数据更改时从新训练模型,但这并不能解决无关数据版本控制的全副问题。一方面是数据历史:现实状况,你须要保留数据变更的残缺历史记录,然而这并不总是可行的,取决于数据发生变化的频率。另一方面是数据出处:理解数据处理中的哪局部引起数据产生了变动,和该变动在不同数据集间是如何流传的。还有一个问题,随着工夫的推移,数据的构造和类型可能发生变化,这些变动是否能够向前和向后兼容。
在流媒体畛域,数据的版本化管制将会变得更加简单,因而咱们心愿在这个畛域中有更多的实际、工具和技术可能失去倒退。

Data-Pipeline

目前为止,咱们还未波及的另一个方面,是对于如何对 data-pipeline 自身进行版本化、测试、部署和监督。在事实世界中,在某一些工具选型中应用 CD4ML 会比另一些好。举个例子,许多 ETL 工具须要你在图形界面里定义转换和解决数据的步骤,这样的工具通常会在版本控制、测试于公布至混合环境时带来麻烦。其中有一部分工具能够生成代码,并作为工件搁置在部署流水线中。
咱们更偏向于应用容许咱们应用代码定义 data-pipeline 的开源工具,因为它在版本控制、测试与公布过程中带来了很大的便当。比如说,如果应用了 Spark,则你的 data-pipeline 能够应用 Scala 编写,配合 ScalaTest 或 spark-testing-base 进行测试,把 job 打包成一个版本化的 JAR 工件,并通过 GoCD 的部署流水线进行部署。
通常状况,data-pipeline 的入口会应用一个批处理作业或长时间运行的流解决利用,咱们没有将它们蕴含在图 10 的端到端 CD4ML 流程图中,然而因为他们的输入可能发生变化,而上游用于接管的模型和程序没有做相应的批改,于是这可能带来一个潜在的集成问题。因而,将集成和数据的契约测试作为咱们部署流水线中的一部分,能够无效的捕捉到这部分的谬误。
与 data-pipeline 无关的另一种测试类型是数据质量检查,但这个主题设计的内容较广,能够独自作为另一篇文章探讨。

平台化思维

你可能留神到了,咱们应用了多种不同的工具和技术以实现 CD4ML。如果你有多个团队尝试发展这个实际,那么他们最终可能会去做大量反复的工作。这里,平台化思维能够帮忙咱们。并不是说一个独立的团队专门去做这件事会成为拖慢速度,而是说将注意力集中在搭建一个与畛域无关的工具,它来解决潜在简单的实现,从而能更快更容易地被其余团队尝试和应用。咱们的共事 Zhamak Dehghani 在她的 Data Mesh 文章里对此进行了更具体的介绍。

演进中的无偏差智能零碎

当你的第一个机器学习零碎部署到生产环境时,他将开始预测并被用于于看不见的数据,它甚至能够替换你之前应用的基于规定的零碎。为此所需的训练数据集和模型验证是基于一系列之前零碎产生的历史数据,而这些历史数据可能被先前零碎存在的固有偏差所影响。此外,机器学习系统对你用户产生的影响,也会影响到你未来的训练数据。
为了能更好的了解,让咱们思考两种状况。第一种,是咱们本文中探讨的需求预测解决方案。假如有一个应用程序能够预测需要,以确定须要订购和提供给客户产品的确切数量。如果预测的数量低于理论的需要,你将没有足够的物品用于发售,因而该产品的销量会缩小。如果仅应用这些新交易的数据作为改良模型的训练数据集,那么随着工夫的推移,需求预测的后果将一直缩小。
第二种状况,试想你正在搭建一个异样检测模型,用来确定客户的信用卡交易是否为欺诈行为。如果应用程序驳回了模型的决策阻止了交易,随着时间推移,欺诈行为越来越少,被容许的交易越来越多。因为训练数据变得偏差“良好”交易,此模型的性能也会降落。
想解决这个问题并不容易。在第一种状况中,零售商有时还思考了缺货的状况,并订购了比预期更多的商品以补救潜在的短缺。对于欺诈监测计划,有时能够应用一些概率分布来疏忽或笼罩模型的本来输入。同时,咱们还需识到很多数据集都是工夫数据集,即他们的散布会随工夫发生变化。许多验证办法应用了随机数据宰割,这都基于了他们合乎 i.i.d.(独立均匀分布)的假如,然而一旦将工夫因素思考在内,这个假如将不再成立。
因而,咱们不仅要器重捕获模型的输出和输入,还须要重视应用程序是否应用模型的决策而作出的最终判断。这里你能够对数据进行标注,从而防止在之后的训练数据中产生这种偏差。当你遇到这些问题的时候,容许人员通过管理系统对数据进行治理,是必不可少的。
随着工夫的推移,智能零碎的倒退和机器学习模型性能的晋升将被视为“元学习”问题。该畛域很多最新的钻研都集中在这类问题上。例如,强化学习的利用,或生产环境中的在线学习。咱们冀望咱们在如何最好的构建、部署和监控这类机器学习零碎方面的常识和教训也能够一直的演进。

结语

随着机器学习技术一直的提高,咱们对治理和交付此类利用的常识也在一直倒退。通过引入和延长继续交付中的原理和实际,咱们能够更好地管制更新公布引入的危险,从而安全可靠地部署机器学习应用程序。
通过解读销售预测示例应用程序,咱们展现了一系列 CD4ML 的技术组件,并探讨了一些实现它们的办法。咱们置信,随着 ML 这项技术持续倒退,新工具将会一直呈现和隐没,然而继续交付的外围原理,将为你在当前搭建本人的机器学习应用程序中提供重要领导。

正文完
 0