实现高效MLOps的六个关键原则(上)
在本文中,我们将探讨独立于任何工具的核心 MLOps 原则。这些原则旨在帮助我们设计出健壮且可扩展的生产级机器学习系统和架构。
- 自动化或操作化
- 版本控制
- 实验跟踪
- 测试
- 监控
- 可复现性
如果你想了解更多关于大语言模型的相关内容,可以阅读以下这些文章:
大型语言模型景观
利用大型语言模型进行因果推理:为什么知识和算法至关重要?
如何为你的业务选择合适的大型语言模型(LLM)
语言模型在虚假信息活动中存在误用——如何降低风险?
首先,我们来研究自动化(操作化)的基本要素。
1 自动化或操作化
为了实施 MLOps,大多数应用系统会经历三个核心层次的逐步演进,从手动操作到完全自动化:
- 手动流程:在开发机器学习应用的早期,流程通常是实验性和迭代性的。数据科学家手动执行每个管道的步骤,如数据准备和验证、模型训练和测试。在这个阶段,他们常常使用 Jupyter Notebooks 来训练模型。此阶段的产出是用于准备数据和训练模型的代码。
- 持续训练 (CT):下一阶段涉及模型训练的自动化,这就是所谓的持续训练 (CT)。当需要时,它会自动触发模型的再训练。在这一阶段,数据和模型验证步骤通常已经自动化。这个步骤通常由编排工具完成,例如 ZenML,它将所有代码整合在一起,并在特定触发器上执行。最常见的触发器是基于时间计划(例如每天一次),或某些事件发生时(如新数据上传或监控系统检测到性能下降),从而提供灵活的触发条件。
- CI/CD:最后一个阶段是实现 CI/CD 管道,确保将 ML 代码快速且可靠地部署到生产环境中。该阶段的关键进展是自动化数据、模型和训练管道组件的构建、测试和部署。CI/CD 用于将新代码迅速推送到不同环境(例如测试环境或生产环境),确保高效、可靠的部署流程。
在构建 LLM 系统时,我们可以利用 FTI 架构,快速从手动流程过渡到 CI/CD 和 CT。在图 1 中,我们可以看到,CT 流程可以由多种事件触发,例如监控管道检测到的性能下降,或是新一批数据的到达。
此外,图1分为两大部分。上半部分展示了自动化流程,而下半部分展示了数据科学团队在实验各种数据处理方法和模型时进行的手动操作流程。
一旦团队通过调整数据处理方式或模型架构改进了模型,他们会将代码推送到代码库中,随之触发 CI/CD 管道。这将自动构建、测试、打包,并将新更改部署到 FTI 管道中。
综上所述,CT 实现了 FTI 管道的自动化,而 CI/CD 则负责构建、测试并将 FTI 管道的新版代码推送到生产环境。
2 版本控制
到目前为止,我们知道代码、模型或数据中的任何更改都会导致整个机器学习系统发生变化。因此,分别对这三者进行跟踪和版本控制至关重要。那么,我们该如何分别跟踪代码、模型和数据呢?
代码 是通过Git进行版本控制的,Git帮助我们在每次向代码库添加更改时创建一个新的提交(代码的快照)。此外,基于Git的工具通常允许我们发布版本,版本通常包含多个新功能和错误修复。
尽管每次提交会生成一个人类难以解读的唯一标识符,但版本发布遵循更常见的命名约定,通常包括主版本、次版本和补丁版本。
例如,在版本号为 “v1.2.3″ 的版本中,”1″ 表示主版本,”2” 表示次版本,而 “3” 表示补丁版本。常见的工具包括 GitHub 和 GitLab。
模型 的版本控制可以通过模型注册表实现,它允许存储和共享系统中使用的所有模型,并对其进行版本化。模型版本控制通常采用与代码类似的语义版本控制(Semantic Versioning)方案,使用主版本、次版本和补丁版本,同时也支持 alpha 和 beta 版本,用于向应用程序发出信号。
此外,你还可以通过 ML 元数据存储将一些附加信息关联到模型上,比如模型是在哪些数据上训练的、模型架构、性能指标、延迟,以及任何对您特定用例有意义的信息。这么做可以创建一个清晰的模型目录,使团队和公司能够轻松浏览和使用这些模型。
数据的版本控制比代码和模型要复杂得多,因为它取决于数据的类型(结构化或非结构化)以及数据量的大小(小数据集或大数据集)。
例如,对于结构化数据,你可以使用带有版本列的 SQL 数据库来帮助跟踪数据集中的更改。然而,还有一些其他流行的解决方案,如基于 Git 的系统 DVC,可以用于跟踪数据集的每次更改。
另一种流行的解决方案是基于工件(artifact),类似于模型注册表,它允许你为数据集添加虚拟层,跟踪每次数据更改并创建新版本。Comet ML、W&B 和 ZenML 都提供了强大的工件功能。无论选择哪种解决方案,数据通常需要存储在本地或云对象存储解决方案中(如 AWS S3)。这些工具提供了构建、版本化、跟踪和访问数据集的能力。
3 实验跟踪
训练机器学习模型是一个完全迭代且实验性的过程。与传统的软件开发不同,机器学习涉及运行多个并行实验,基于一组预定义的指标对它们进行比较,并决定哪一个实验应推进到生产环境中。
实验跟踪工具可以帮助您记录所有必要的信息,例如模型预测的指标和可视化结果,以便比较各个实验并轻松选择最佳模型。常用的工具包括Comet ML、W&B、MLFlow和Neptune。
4 测试
在测试机器学习系统时,我们也会遇到与传统软件类似的挑战。因此,我们必须从三个方面测试我们的应用程序:数据、模型 和 代码。此外,还必须确保特征、训练管道和推理管道能与外部服务(如特征存储)良好集成,并能够作为一个完整的系统协同工作。
在 Python 环境中,最常用的测试框架是 pytest,我们也推荐使用它来编写测试。
测试类型
在开发周期的不同阶段,通常会采用以下五种主要类型的测试:
- 单元测试:这些测试关注具有单一职责的单个组件。例如,测试一个用于将两个张量相加的函数或在列表中查找特定元素的函数。
- 集成测试:这些测试评估系统中多个集成组件或单元之间的交互。例如,测试数据处理管道或特征工程管道,以及它们与数据仓库和特征存储的集成情况。
- 系统测试:系统测试在开发周期中起着关键作用,它们检查整个系统的完整性,涵盖了完整的集成应用程序。这类测试严格评估系统的端到端功能,包括性能、安全性和整体用户体验。例如,测试整个机器学习管道,从数据摄取到模型训练和推理,确保系统能针对特定输入产生正确的输出。
- 验收测试:这些测试通常称为用户验收测试(UAT),它们用于验证系统是否满足规定的需求,确保系统已准备好部署。
- 回归测试:回归测试的目标是检查先前修复的错误,以确保新代码的更改不会重新引入已解决的问题。
- 压力测试:压力测试用于评估系统在高负载或极端条件下的表现,确保它能在峰值流量或数据量增加的情况下依然稳定运行。
我们测试什么?
在编写大多数测试时,通常将组件视为一个黑盒。因此,您可以控制的主要是输入和输出。测试的目标是检查对于给定的输入,是否能够得到预期的输出。这里有一些应该经常考虑测试的内容:
- 输入:数据类型、格式、长度,以及边界情况(如最小值/最大值,小规模/大规模等)。
- 输出:数据类型、格式、异常、中间结果以及最终输出。
测试的例子
在测试代码时,可以利用经典的软件工程标准。以下是一些在编写单元测试时的代码测试示例,有助于更好地理解我们希望测试的内容。
例如,您可能想检查一个句子是否按照预期方式进行了清理。此外,您也可以测试分块算法,断言它在处理不同句子和块大小时是否正常工作。
当我们谈到数据验证时,主要指的是数据的有效性。数据有效性测试代码通常在从数据仓库中摄取原始数据或计算特征之后运行,成为特征管道的一部分。因此,通过为您的特征管道编写集成或系统测试,您可以检查系统是否对有效和无效数据做出正确的响应。
数据有效性的测试方式在很大程度上取决于应用场景和数据类型。例如,处理表格数据时,可以检查是否存在非空值、分类变量是否仅包含预期的类别,或浮点值是否始终为正数。而在处理非结构化数据(如文本)时,可能会检查数据的长度、字符编码、语言、特殊字符及语法错误。
模型测试
模型测试是最具挑战性的,因为模型训练过程是机器学习系统中最不确定的部分。与传统软件不同,机器学习系统即使没有抛出任何错误,也可能产生不正确的结果,而这些错误通常只能在评估或测试阶段被发现。
一些常见的模型测试技术包括:
- 输入张量和模型输出张量的形状:
- 经过一批(或多批)训练后,损失减少:
- 小批量训练时,损失逐渐趋近于 0:
- 你的训练管道可以在所有支持的设备上运行,如 CPU 和 GPU:
- 早停和检查点逻辑功能正常:
所有测试都会在 CI(持续集成)管道中自动触发。如果某些测试的成本较高,例如模型测试,可以设置为在特定条件下执行,比如当修改模型代码时才触发。
另一方面,您还可以对模型进行行为测试。行为测试借鉴了代码测试的方法,将模型视为一个黑盒,只关注输入和期望输出。这使得行为测试与模型的具体实现无关,具有模型不可知的特点。
这一领域的重要研究之一是《超越准确性:使用清单进行 NLP 模型的行为测试》一文。如果您想更深入了解这个主题,建议阅读该论文。作为快速概述,该论文建议对模型进行三种类型的测试。以下我们用一个从句子中提取主语的模型作为例子来说明:
- 不变性测试:输入的某些变化不应影响输出。例如,基于同义词替换的测试
model(text="The advancements in AI are changing the world rapidly.")
# output: ai
model(text="The progress in AI is changing the world rapidly.")
# output: ai
- 方向性测试:输入的变化应当影响输出。例如,以下是一个示例:我们知道输出应该根据提供的输入而变化
model(text="Deep learning used for sentiment analysis.")
# output: deep-learning
model(text="Deep learning used for object detection.")
# output: deep-learning
model(text="RNNs for sentiment analysis.")
# output: rnn
- 最小功能:输入和预期输出的最简单组合。例如,下面是我们期望模型始终正确的一组简单示例的示例
model(text="NLP is the next big wave in machine learning.")
# output: nlp
model(text="MLOps is the next big wave in machine learning.")
# output: mlops
model(text="This is about graph neural networks.")
# output: gnn
感谢阅读!你还可以订阅我们的YouTube频道,观看大量大数据行业相关公开课:https://www.youtube.com/channel/UCa8NLpvi70mHVsW4J_x9OeQ;在LinkedIn上关注我们,扩展你的人际网络!https://www.linkedin.com/company/dataapplab/。
原文作者:Paul Iusztin
翻译作者:过儿
美工编辑:过儿
校对审稿:Jason
原文链接:https://medium.com/decodingml/the-6-mlops-foundational-principles-ac8518506dee