正如我们在上一章中确认的,有效管理数据是创建可复现的机器学习工作流程的必要条件。像Git这样的标准版本控制系统擅长追踪基于文本的代码文件的变化,但它们难以应对典型机器学习数据集的规模和特性。那么,团队如何管理不断演变的数据集呢?我们来考察一些常见方法,从简单的手动方式到更复杂的方法,并指出它们的优缺点。手动命名规范和复制也许最基本的方法就是简单地重命名文件或目录来表示不同版本。你可能遇到过类似data_processed_v1、data_processed_v2这样的文件夹,或者features_final.csv、features_final_really_final.csv这样的文件。优点: 无需专用工具;对于很小的项目来说,初期易于理解。缺点: 此方法很快变得难以管理。易出错: 容易犯错,忘记版本之间的具体变化,或不小心覆盖文件。扩展性问题: 为微小改动复制大型数据集会导致磁盘空间占用迅速增加。缺乏来源信息: 难以可靠地将特定版本的数据与其使用的或生成的代码提交或实验运行关联起来。协作变得非常困难。无审计记录: 没有关于更改原因或更改者的系统记录。虽然简单,但手动版本控制缺乏进行认真机器学习开发和复现所需的严谨性。云存储快照或版本控制云存储提供商(AWS S3、Google Cloud Storage、Azure Blob Storage)通常提供自己的版本控制功能。你可以在存储桶上启用版本控制,提供商将在对象被覆盖或删除时保留其旧版本。优点: 利用现有云基础设施;提供备份和回滚功能。缺点:与代码分离: 云存储版本控制独立于你的Git仓库。将特定数据版本与代码提交关联起来需要手动追踪或复杂的脚本操作。粒度: 通常在对象(文件)层面操作。将由多个文件组成的数据集作为一个连贯的单元来管理版本可能会很笨拙。缺少机器学习语境: 这些系统不理解机器学习工作流程、数据处理步骤之间的依赖关系或实验追踪。检出复杂性: 获取与过去项目状态对应的特定、一致的数据文件集可能很麻烦。云存储版本控制对备份和灾难恢复有用,但并未直接解决机器学习中代码、数据和实验之间所需紧密关联的问题。Git 大文件存储 (LFS)Git LFS是一个旨在更高效处理大文件的Git扩展。Git LFS不是将大型二进制文件直接存储在Git仓库历史中(这会迅速使仓库膨胀),而是将指针(小型文本文件)存储在Git中。实际的大文件存储在单独的LFS服务器上(可以是自托管的,或由GitHub、GitLab、Bitbucket等服务提供)。当你检出一个提交时,Git LFS会根据指针下载所需的大文件。优点:Git 集成: 在标准Git工作流程(git add、git commit、git push、git pull)中运行得比较顺畅。改善仓库大小: 保持核心Git仓库小巧快速。缺点:非数据专用: Git LFS将数据视为任何其他大型资产(例如,图形、二进制文件)。它不了解数据集结构、依赖关系或机器学习专用操作。存储管理: 需要管理一个单独的LFS服务器,或在Git托管平台上支付LFS带宽/存储费用。可能进行大文件检出: 如果数据文件发生重大变化,检出分支仍可能触发大量下载。有限的流水线意识: Git LFS无助于定义或管理数据处理流水线,或追踪数据在多步骤中的来源信息。Git LFS无疑是比直接在Git中存储大文件更好的方案,但它是一个处理大文件的通用方案,并非针对机器学习中数据版本控制具体需求的定制方案。专用数据版本控制工具(例如:DVC)认识到上述方法的局限性,出现了专门用于机器学习项目中数据和模型版本控制的专用工具。数据版本控制(DVC),本章的重点,就是一个很好的例子。这些工具通常与Git并行工作,使用Git进行代码版本控制,同时为数据提供专用机制。优点:专为机器学习设计: 在设计时就考虑了机器学习工作流程,理解数据集、模型、流水线和指标等事项。类似Git的体验: 通常提供与Git类似的命令行界面(例如:dvc add、dvc push、dvc pull)。存储无关: 可以与各种存储后端(云、本地、网络驱动器)集成,而无需将数据直接存储在Git中。注重复现性: 能够追踪数据依赖关系并创建可复现的数据流水线。数据来源: 保持代码版本、数据版本和实验结果之间的清晰关联。缺点:学习曲线: 需要学习一个新的工具及其相关事项。增加复杂性: 在项目设置中增加了一层工具。以下是一个简化对比:特点手动复制云版本控制Git LFS专用工具 (DVC)Git 集成无差好优秀(并行)存储本地副本云提供商单独的LFS服务器灵活(云/本地)复现性很低低中等高ML流水线感知否否否是可扩展性差好中等好粒度手动文件级文件级文件/目录/数据集鉴于上述挑战,专用工具提供了在可复现的机器学习环境中管理数据的最全面方案。它们弥补了Git和通用文件存储系统留下的不足。在接下来的部分,我们将了解DVC如何实现这些原则,提供一种实用且有效的方式来对数据和代码进行版本控制。