使用Git分支进行机器学习项目版本控制的实用方法,简化工作流程并组织数据和模型
TL;DR
使用Git分支进行机器学习项目版本控制的简单方法,简化工作流程,组织数据和模型,并将项目的相关部分联系在一起。
介绍
在管理机器学习解决方案时,解决方案的各个方面通常分布在多个平台和位置上,如GitHub上的代码、HuggingFace上的模型、Weights and Biases上的跟踪、S3上的备份等。
在数据方面,我们有训练数据、处理数据、训练跟踪数据和模型监控数据。我们保存用于推理的模型,包括旧版本和用于在线测试的实验模型。我们还有用于预处理、训练、推理、实验、数据科学分析和监控警报的代码。
这很容易失控。
使用各种工具、环境和资源地址跟踪ML生命周期的不同部分可能导致分散和协调不一致的状态。这可能导致数据丢失、安全漏洞和需要谨慎管理的配置错误。
在以前的一个项目中,我们使用SageMaker在内部部署的解决方案中进行每日训练。这要求客户每天下载一个模型,并使用各种客户数据集的组合进行训练。
我们必须管理哪个二进制模型是用哪个训练代码以哪个客户的哪个数据训练的,哪个模型在哪个客户处使用了哪个推理代码等等。
在本文中,我们将展示如何利用数据版本控制工具来解决这些问题,使用Git。
数据版本控制工具允许您将数据和模型文件与代码一起提交,而不考虑它们的大小。通过以这种方式对所有文件进行版本控制,您可以避免管理数据和模型资产时的不便。
在理想世界中,您只需拥有当前任务所需的相关代码、数据和模型。无论您是开发还是运行ML训练、跟踪实验、在生产中监控模型,还是进行在线实验。
与手动(甚至自动)连接正确的部分-在正确的代码中加载正确的数据,在HuggingFace中连接它们到正确的模型,在正确的环境中-相比,想象一下每次切换分支时,所有的部分都在那里。
在本文中,我将展示一个框架,用Git替代了繁琐的工具复杂性,Git是几乎所有ML团队已经在使用的系统。
目标是通过将所有内容放在一个地方,由Git管理,简化和消除开始ML工作流程的障碍。
我们的要求
- 简单的工作流程,易于暂停、恢复,并适应不断变化的业务和开发需求。它还应支持可重现性,并支持后事实查询,比如“我的模型是基于哪些数据进行训练的?”
- 高效地使用数据和代码,注重协作、治理和审计。- 尽可能多地重用数据和代码,并利用git功能如commits、issues和tags。
- 整合ML解决方案的所有不同方面非常重要。通常情况下,实验跟踪、在生产中进行模型监控以及在线和离线实验被分开管理。在这里,我们的目标是将它们统一在一个框架下,使其在它们之间容易转换。
- 遵循Git和ML的最佳实践,包括早期可共享的数据拆分、测试和简单的协作,适用于不同的ML工程师。
关键概念
每次更改都是一个Git提交:这包括数据上传、特征工程、模型覆盖、合并实验指标结果、模型监控,以及自然的代码更改。
活动分支:通常使用不同的分支进行开发和生产。但是,在这里我们可以更进一步。这意味着您可以切换到一个分支,并将所有必要的数据、代码、模型、文档、readme和带有度量的模型卡片都集中在一个地方。
🤯 您的存储库就是您的 blob 存储!您的分支类似于 blob 存储中的存储桶,可以用于上传、下载和存储数据和模型。
这使您可以针对不同的开发、实验和生产需求使用不同的分支,而无需依赖不同的平台和工具。
合并作为工作流: 用于合并分支。代码通常以正常方式合并,而模型通常会覆盖现有模型。当数据合并时,通常是追加的方式。要接收新数据,可以通过复制从另一个分支中“拉取”数据。
合并数据可以简单到文件的复制或追加到 JSON 列表中。在更复杂的情况下,可以合并 SQLite 数据库。
去重是数据版本控制工具中常用的功能,它可以防止创建多个相同文件的副本,即使有多个包含相同文件的分支。
分支类型
主分支
首先,我们使用项目的主分支来存储问题定义、文档、数据描述和项目结构。这是用于协作和讨论的空间。
提示:从明确定义业务问题、确定期望的结果、识别目标值或标签及其获取方式以及建立评估指标和要求开始,我们可以确保项目成功启动,并为入职和协作提供一个地方。
我们还可以将其用于跟踪实验,其中合并您实验的结果。例如,MLflow 的 mlruns 文件夹可以合并到此处以此目的。任何合作者都可以检出此分支并运行 UI。
或者,跟踪可以在另一个分支中进行。
以这种方式开始非常简单,随着时间的推移需要发生变化,可以最小程度地更改为 MLflow 服务器或像 Weights and Biases 这样的跟踪平台。
数据分支
这些是项目的分支,主要包括数据文件、文档和转换脚本,并且它们保持活动状态。您可以将它们视为 S3 存储桶,但不是上传和下载,而是检出一个分支,您的文件就在那里。
建议始终提交(上传)到原始分支。这将创建一个真实性来源,一个从未编辑或删除的位置,以便我们始终可以追踪数据的来源和经过的路径。它还便于轻松创建新的流程,审计和管理。
💡 如果在提交消息中添加数据的来源,可以更加详细地观察数据。
您可以使用另一个干净的分支,其中只包含干净的数据。例如,在原始分支中上传的损坏的图像或空的文本文件不会出现在干净的分支中。
拆分分支用于按照训练、验证和测试进行数据划分,以确保所有团队和合作者在相同的基础上工作。
这种方法有助于防止数据泄露,并实现更强大的特征工程和协作。减少测试集中的示例包括在训练阶段中的机会,降低引入偏差的风险。此外,让所有合作者在相同的拆分上工作,可以确保实验结果的一致性和无偏性。
在以前的分类项目中,我是一个个人贡献者团队的一员,每个人都从头开始运行整个流程;我们每个人使用了不同的数据拆分百分比和种子,导致在基于错误和数据偏差的生产中使用了较弱的模型。
💡 ML 提示:三阶段的模型开发最佳实践我们使用“训练”和“验证”数据集来训练和优化模型的超参数。然后,我们使用训练加验证的数据作为训练集,训练我们调整过的模型,并使用测试数据集进行评估,仅一次。最后,我们对所有数据进行训练并将其保存为我们的模型。
稳定分支
这些分支是用于训练和推理的活跃分支。在这里,您可以运行训练,保存模型、检查点和模型卡片,运行测试,构建和测试Docker镜像,在训练周期结束时提交全部内容,然后进行标记。它们应该能够处理新数据的检索和重新训练。这就是自动化发生的地方。
⚠️ 这些分支不写任何代码。
这确保了模型与其训练的数据、用于生产的训练和运行时使用的代码(包括特征工程)以及结果指标的耦合。所有这些组件都合并到一个统一的“快照”中。每当您签出一个标记,该模型所需的所有必要组件都会存在。
💡 提示:通过提前选择标记名称,您可以将其作为参数添加到训练过程中的跟踪信息中。这样,您可以始终使用任何跟踪工具根据跟踪数据检索模型-数据-代码的“快照”。
训练后,只有跟踪数据被合并(复制)到您的主分支进行跟踪。
在最简单的情况下,它可以是一个包含超参数和评估结果的JSON文本文件。然后,将此文件附加到主分支中的列表中。对于MLflow而言,它涉及将实验从mlruns文件夹复制到主分支。
编码分支
这些分支用于代码开发和数据探索,在样本数据或小数据上进行训练,直到您有一个可运行的程序。在开发过程中,欢迎使用所有的Git最佳实践。然而,只有在不需要对代码做进一步更改的情况下,即使有额外的数据被引入,也只能分支出一个稳定分支。这些分支应该包括推理代码、服务器、Docker文件和测试。
始终至少保留一个活动的开发分支,该分支用于合并所有新功能、错误修复和其他更改。
💡 ML和MLOps工程师可以在训练和推理方面进行合作。
例如,您可以创建一个dev/model分支,用于开发一个基准模型。这可以是分类任务中最受欢迎的类别,或者回归任务中的均值/中位数。重点在于设置代码,同时充分理解数据。
当稳定且测试通过时,我们分支出stable/model,在那里我们训练并提交模型、代码和数据到远程,并进行标记。这样做快速而简单,方便共享,并使开发运维、后端和前端团队能够启动开发并交流反馈。它还将有助于尽早在实际环境中验证新发现的需求。
接下来,我们将dev/model分支中的模型开发成一个简单模型,如线性回归。当它准备好并且测试通过时,我们可以将其合并到stable/model中,进行训练、提交和标记一个发布到生产环境的版本。
这种方法使您能够逐步改进模型,同时保留稳定分支中以前模型的全部上下文。
从这点开始,我们有三个选择:
- 当有更多数据到达时,我们可以通过将数据拉到稳定分支进行重新训练。
- 我们可以在dev/linear-regression分支上使用特征工程来进行实验。
- 我们可以创建一个新的dev/new-approach分支,用于更复杂的模型。
监控分支
在模型监控中,我们关注数据分布、异常值和预测分布。
在监控分支中,我们将来自生产环境的查询数据、提交的标记和模型预测保存为文件。
💡 您可以为每个环境(开发环境、稳定环境和生产环境)使用多个监控分支。
我们可以在数据提交时设置警报,以测试任何特征分布中的偏移、异常值、校准的合理性测试以及保存警报代码;这样可以实现更高级的解决方案,例如异常值检测模型,因为我们也可以在这个分支中保存模型。
这个分支通常属于另一个与创建监控日志的代码、生成数据和模型的代码无关的项目。
分析分支
数据科学和分析是项目中另一个常常分离成不同项目的方面。在这个项目中,汇集了分析代码和数据科学家的非训练数据。
数据科学家可以从监控分支中检出并提取数据,用于运行分析、A/B测试和其他在线和离线实验。他们还可以使用原始分支的数据进行这些目的。
在线示例较为简单,因为每个实验组对应一个分支。
💡 提示:常见的在线实验:
前向测试 – 比较当前模型的99%与候选模型的1%。
回测 – 合并新模型后,将原模型保留1%以验证预期效果的逆向影响。
将模型标签作为监控数据的参数可帮助您确定度量指标变化的潜在原因。
摘要
本文介绍了使用Git分支版本技术构建机器学习项目的框架。该框架简化了工作流程,组织了数据和模型,并将项目的相关部分耦合在一起。它强调使用分支作为环境,其中每个分支都包含特定任务所需的数据、代码、模型和文档。本文还讨论了使用不同的活动分支类别等关键概念。总体而言,该框架旨在提高机器学习项目的工作流效率、治理和协作。
如果您想聊天或详细了解,请加入我们的Discord或关注我们的博客。
结语
关于我的本地挑战,我们为每个相关的训练代码和数据集组合维护了一个“稳定”分支。在完成训练后,我们会用适当的标签(-<增量版本>)对提交进行标记。客户可以拉取最新的标签,就像拉取任何其他发布一样。
当“调试”一个客户时,我们会参考特定时刻的标签来检查代码和相应的数据。我们还可以使用相同的标签来匹配监控数据,该标签已添加到监控数据中。分析笔记本可以在我们的ds/client-id分支上找到。