因此,您的公司决定投资机器学习 (ML)。您拥有一支才华横溢的数据科学家团队,他们精心设计模型来解决几年前还无法解决的重要问题。所有性能指标看起来都很棒,演示让人惊叹不已,高管们会问多久才能将模型投入生产。
你想,这应该很快。毕竟,您已经解决了所有高级科学、数学问题,所以剩下的就是日常 IT 工作。它能有多难?
事实证明,相当困难。 Deeplearning.ai 报告称,“只有 22% 使用机器学习的公司成功部署了模型。”是什么让它如此困难?我们需要做什么来改善这种情况?
让我们从根本原因开始。
MLOps 挑战
在传统软件开发领域,一系列称为 DevOps 的实践使得在几分钟内将软件交付到生产环境并保持其可靠运行成为可能。 DevOps 依靠工具、自动化和工作流程来抽象出意外的复杂性,让开发人员专注于需要解决的实际问题。这种方法非常成功,许多公司都已经熟练掌握了,那么为什么我们不能继续为机器学习做同样的事情呢?
虽然代码是在受控的开发环境中精心编写的,但数据来自被称为“现实世界”的永无休止的熵源。
根本原因是机器学习与传统软件之间存在根本区别:机器学习不仅仅是代码,而是代码加数据。您可以通过将算法应用于大量训练数据来创建 ML 模型,即最终投入生产的工件,这将影响模型在生产中的行为。至关重要的是,模型的行为还取决于我们在预测时提供的输入数据,而这是您无法提前知道的。
虽然代码是在受控的开发环境中精心编写的,但数据来自被称为“现实世界”的永无休止的熵源。它永远不会停止变化,而你无法控制 如何 它会改变。考虑代码和数据之间关系的一种有用方法是,就好像它们生活在共享时间维度但在所有其他方面独立的不同平面上。机器学习过程的挑战是以受控方式在这两个平面之间建立一座桥梁。
这种根本性的脱节导致了一些重要的挑战,任何试图将机器学习模型成功投入生产的人都需要解决这些挑战,例如:
部署缓慢、脆弱且不一致
缺乏再现性
绩效降低(训练-服务偏差)
由于我已经多次使用“数据”这个词,您可能会想到另一个可以拯救我们的学科:数据工程。你是对的!数据工程确实提供了解决生产中机器学习难题所不可或缺的重要工具和概念。为了破解这个难题,我们需要结合 DevOps 和数据工程的实践,并添加一些 ML 特有的内容。
因此,MLOps 可以通过这个交集来定义:
现在让我们通过检查可用于实现 MLOps 目标的各个实践来更详细地了解这实际上意味着什么。
MLOps 实践
混合团队
我们已经确定,生产 ML 模型需要一套我们之前认为彼此独立的技能。为了取得成功,我们需要一个涵盖各种技能的混合团队。当然,一个人可能足以胜任所有这些任务,在这种情况下,我们可以称这个人为完整的 MLOps 工程师。但目前最有可能的情况是,一个成功的团队将包括一名数据科学家或机器学习工程师、一名 DevOps 工程师和一名数据工程师。
让模型在凌乱的笔记本中正常工作是不够的。
团队的具体组成、组织和头衔可能会有所不同,但最重要的部分是认识到仅靠数据科学家无法实现 MLOps 的目标。即使一个组织具备所有必要的技能,如果他们不紧密合作,它也不会成功。
另一个重要的变化是数据科学家必须精通基本的软件工程技能,如代码模块化、重用、测试和版本控制;让模型在凌乱的笔记本中正常工作是不够的。这就是为什么许多公司都采用机器学习工程师的头衔,它强调这些技能。在许多情况下,ML 工程师实际上正在执行 MLOps 所需的许多活动。
机器学习管道
数据工程的核心概念之一是数据管道。数据管道是我们应用于源和目标之间的数据的一系列转换。它们通常被定义为一个图,其中每个节点都是一个转换,边代表依赖关系或执行顺序。有许多专门的工具可以帮助创建、管理和运行这些管道。数据管道也可以称为 ETL(提取、转换和加载)管道。
机器学习模型总是需要某种类型的数据转换,这通常是通过脚本甚至笔记本中的单元来实现的,这使得它们难以可靠地管理和运行。切换到正确的数据管道在代码重用、运行时可见性、管理和可扩展性方面提供了许多优势。
由于我们也可以将 ML 训练视为数据转换,因此很自然地将特定的 ML 步骤包含在数据管道本身中,将其转变为 ML 管道。大多数模型需要两种版本的管道:一种用于训练,一种用于服务。这是因为,通常情况下,数据格式以及访问它们的方式在每个时刻都非常不同,特别是对于我们在实时请求中提供的模型(而不是批量预测运行)。
ML 管道是纯代码工件,独立于特定的数据实例。这意味着可以在源代码管理中跟踪其版本,并使用常规 CI/CD 管道(DevOps 的核心实践)自动部署。这让我们能够以结构化、自动化的方式连接代码和数据平面:
请注意,有两个不同的 ML 管道:训练管道和服务管道。它们的共同点是它们执行的数据转换需要生成相同格式的数据,但它们的实现可能非常不同。例如,训练管道通常在包含所有功能的批处理文件上运行,而服务管道通常在线运行并仅接收请求中的部分功能,并从数据库检索其余部分。
然而,确保这两个管道的一致性非常重要,因此应尽可能重用代码和数据。有些工具可以帮助实现这一目标,例如:
TensorFlow Transform 等转换框架可以确保基于训练集统计数据(例如标准化的平均值和标准差)的计算保持一致。
特征存储是存储不属于预测请求的值的数据库,例如使用数据流转换根据用户历史记录计算的特征。
模型和数据版本控制
为了具有可重复性,一致的版本跟踪至关重要。在传统的软件世界中,版本控制代码就足够了,因为所有行为都是由它定义的。在机器学习中,我们还需要跟踪模型版本、用于训练模型的数据以及一些元信息(例如训练超参数)。
我们可以在像 Git 这样的标准版本控制系统中跟踪模型和元数据,但数据通常太大且可变,以至于无法高效和实用。避免将模型生命周期与代码生命周期联系起来也很重要,因为模型训练通常按照不同的时间表进行。
还需要对数据进行版本控制,并将每个经过训练的模型与我们使用的代码、数据和超参数的确切版本联系起来。理想的解决方案是专门构建的工具,但到目前为止,市场上还没有明确的共识,并且从业者使用许多不同的方案,主要基于文件/对象存储约定和元数据数据库。
模型验证
另一个标准的 DevOps 实践是测试自动化,通常采用单元测试和集成测试的形式。通过这些测试是部署新版本的先决条件。拥有全面的自动化测试可以给团队带来极大的信心,从而大大加快生产部署的速度。
ML 模型更难测试,因为没有模型能够给出 100% 正确的结果。这意味着模型验证测试本质上必须是统计性的,而不是具有二进制的通过/失败状态。为了确定模型是否足以部署,需要确定要跟踪的正确指标及其可接受值的阈值,通常是根据经验,并且通常是通过与以前的模型或基准进行比较。
这是一门令人兴奋的新学科,其工具和实践可能会不断快速发展。
跟踪整个验证集的单个指标也是不够的。正如好的单元测试必须测试多种情况一样,我们需要针对数据的相关部分(称为切片)单独验证模型。例如,如果性别可以直接或间接地成为模型的相关特征,那么我们应该跟踪男性、女性和其他性别的单独指标。否则,该模型可能会出现股权问题或在重要领域表现不佳。
如果您设法以自动化且可靠的方式验证模型以及机器学习管道的其余部分,您甚至可以关闭循环并实施在线模型训练(如果这对用例有意义)。
数据验证
良好的数据管道通常从验证输入数据开始。常见验证包括文件格式和大小、列类型、null 或空值以及无效值。这些都是机器学习训练和预测所必需的,否则你可能会得到一个行为不当的模型,并最终绞尽脑汁寻找原因。数据验证类似于代码域中的单元测试。
除了任何数据管道执行的基本验证之外,机器学习管道还应该验证输入的更高级别的统计属性。例如,如果某个特征的平均值或标准差从一个训练数据集到另一个训练数据集发生很大变化,则可能会影响训练模型及其预测。
这可能反映了数据的实际变化,也可能是由数据处理方式引起的异常,因此排除系统错误作为可能污染模型的原因并根据需要进行修复非常重要。
监控
监控生产系统以保持其良好运行至关重要。对于机器学习系统来说,监控变得更加重要,因为它们的性能不仅取决于我们可以控制的因素,例如基础设施和我们自己的软件,还取决于我们无法控制的数据。
除了监控延迟、流量、错误和饱和度等标准指标外,我们还需要监控模型预测性能。
监控模型性能的一个明显挑战是,我们通常没有经过验证的标签来比较模型的预测,因为模型适用于新数据。在某些情况下,我们可能有一种间接的方法来评估模型的有效性,例如通过测量推荐模型的点击率。在其他情况下,我们可能必须依赖时间段之间的比较,例如,通过每小时计算正分类的百分比,并在模型偏离该时间平均值的百分之几以上时设置警报。
就像我们验证模型时一样,跨切片(而不仅仅是全局)监控指标也很重要,以便能够检测影响特定细分的问题。
MLOps 的未来
随着机器学习从研究到应用商业解决方案的成熟,我们也需要提高其操作流程的成熟度。幸运的是,我们可以从机器学习之前的学科中扩展许多实践。
下表总结了 MLOps 的主要实践以及它们与 DevOps 和数据工程实践的关系:
这是一门令人兴奋的新学科,其工具和实践可能会不断快速发展。当然有很多机会来开发生产技术并将其应用于机器学习。