Dud
Dud 是一个轻量级工具,用于在源代码旁对数据进行版本控制并构建数据管道。实际上,Dud 将源代码控制的许多优势扩展到了大型二进制数据。
使用 Dud,你可以通过简单的命令行界面提交、检出、获取和推送大型文件和目录。Dud 将检索数据的配方(也称为阶段)存储在小型 YAML 文件中。这些阶段可以存储在源代码控制中,以将你的数据与代码关联。此外,阶段还可以运行生成数据的命令,有点像 Make。阶段可以链接在一起创建数据管道。请查看入门指南以获取实践性概述。
Dud 的发音是"duhd",而不是"dood"。Dud 不是缩写。
动机
Dud 受到 DVC 的深度启发。DVC 解决了数据版本控制和可重复性的需求,但其实现并非没有问题。我对 DVC 的批评归结为两点:速度和简单性。速度指的是吞吐量和响应速度。简单性指的是做得更少——无论是在项目范围还是抽象程度上。
就速度而言,Dud 通常比 DVC 快得多。就简单性而言,Dud 有一个更小、更专注的范围,并且它以独立可执行文件的形式分发。
总结一下,可以用一个类比来说明:Dud 之于 DVC,就像 Flask 之于 Django。Dud 和 DVC 各有优势。如果你想要一套"包含所有功能"的机器学习项目管理工具套件,DVC 可能适合你。如果数据管理是你的主要需求,而你想要一些轻量级且快速的东西,Dud 可能更适合。
要深入了解细节,请继续阅读。
与 DVC 的具体区别
Dud 不管理实验和/或指标。
Dud 仅专注于在源代码旁对数据进行版本控制和复现。DVC 的范围已经扩大到包含传统机器学习工作流程的大部分内容。虽然集成的工具套件有其优势,但如果 UNIX 的经验可以借鉴的话,小型、更专注的工具的组合通常比它们的单体对应物产生更高的生产力。例如,没有理由你不能在 Dud 旁使用 MLflow 或 Aim 来跟踪你的实验。Dud 不规定任何实验跟踪的解决方案,也不试图进入这个新兴但已经拥挤的工具市场。
其次,在源代码旁对数据进行版本控制本身就是一个非常有用的概念。机器学习和数据科学之外的领域(例如游戏开发和数字设计)可能会从这种数据管理方法中获益匪浅,而不会被特定领域带来的额外负担所困扰。
Dud 的提交必须始终显式调用;它们绝不是副作用。
对于 Dud 和 DVC 来说,将数据提交到缓存都是每个工具执行的最昂贵的操作之一(无论是在运行时间还是 I/O 方面)。因此,Dud 让用户完全控制何时提交数据。在 Dud 中,提交只在你运行 dud commit
时发生。
相比之下,DVC 经常作为其他命令的副作用自动代表你提交(例如,在 dvc add
和 dvc repro
期间)。虽然 DVC 试图提供帮助,但这些隐式提交通常是意外提交。例如,如果你正在快速迭代一个管道,你可能会在开发时反复运行 dvc repro
或 dvc run
。然而,DVC 每次运行 dvc repro
或 dvc run
时都会自动提交结果——即使你只是在调试或调整代码。这种意外提交代价高昂;它们将"快速开发"变成了"开发",并且会使你的缓存膨胀。(你可以使用 --no-commit
标志禁用 DVC 的隐式提交,但你必须每次都记得输入它,而且 DVC 不支持默认启用此标志,例如通过配置文件。)
Dud 默认将文件检出为符号链接。
当 Dud 将缓存的文件检出到工作区时,默认使用符号链接(又称为 symlinks)。符号链接有许多优点,使其成为检出的绝佳选择。首先,创建符号链接需要很少的 I/O,因此 dud checkout
通常几乎瞬间完成。其次,符号链接透明地重定向到缓存的文件本身,所以数据不会在工作区和缓存之间重复,你的存储空间得到有效利用。最后但同样重要的是,符号链接使检查文件是否最新变得非常简单(通过检查链接目标),因此 dud status
也可以非常快速。
默认情况下,DVC 将文件检出为硬拷贝。(从技术上讲,DVC 在使用拷贝之前尝试使用 reflinks,但很少有文件系统支持 reflinks,所以拷贝更可能是默认选项。)使用硬拷贝,上面列出的效率都无法实现,所以默认情况下检出和状态检查效率低下。值得称赞的是,DVC 的缓存可以配置为使用符号链接,但可以说 DVC 的默认缓存配置对于任何规模较大的项目都不太合理。
运行 Dud 管道从不隐式改变阶段的产物。
当你在 DVC 中运行管道时,DVC 会在运行管道的命令之前删除所有管道输出。虽然这有助于确保管道的可重复性,但这是另一个用户必须考虑的隐式行为,它阻止了用户决定何时可以安全地重用阶段输出。 如果你不想让DVC自动为你删除输出,你需要明确告诉它你想保留的每个输出。然而,通过告诉DVC保留一个输出,DVC可能会执行一种新的且不同的自动行为。如果你使用符号链接(或硬链接)进行检出(这通常是个好主意;见上文),DVC会"取消保护"所有输出链接,用缓存中的硬拷贝替换它们。这种行为不仅令人惊讶,而且在运行时间和存储方面都非常昂贵。
DVC这两种行为的结果意味着,在一个合理的配置中,阶段simply无法高效地重用输出;用户几乎别无选择,只能接受DVC的限制。
当你运行Dud管道时,Dud不会对现有文件进行任何隐式修改。Dud将工作空间文件的所有修改推迟给用户。如果你想要特定的行为,你应该将其编码到你的阶段命令中。例如,如果你想在阶段运行之前清除所有输出,你可以在命令脚本的开头删除任何输出。如果你想重用输出,你可以在脚本中检查预先存在的输出,并选择不重新创建它们。Dud的极简方法导致阶段的命令完全掌控其自身的可重复性;这个责任不会尴尬地在阶段和工具之间共享。
Dud将远程缓存管理委托给Rclone。
Rclone是一个非常流行的命令行工具,它将自己描述为"云存储的瑞士军刀"。在撰写本文时,Rclone在Github上拥有超过28,000颗星。Rclone支持几乎所有你可能听说过的云存储提供商。(S3、GCS、Dropbox、Backblaze等等。)这一切都是为了说明:Rclone是在互联网上移动数据的顶级选择。
Dud内部调用Rclone来实现所有的远程缓存功能,比如dud fetch
和dud push
。但Dud并没有完全隐藏Rclone抽象。Dud暴露了它的Rclone配置文件,预期并鼓励用户直接使用Rclone来配置远程存储或与他们的远程数据交互。通过使用Rclone,Dud的远程缓存接口立即获得了多年开源开发和丰富、文档完善的CLI的好处。这是Dud如何拥抱UNIX哲学和单一焦点工具组合的一个例子,如上所述。
相比之下,DVC将各种Python包缝合在一起,以支持适度的云存储选项。在撰写本文时,DVC 2.6支持十一个云存储提供商,而Rclone 1.56支持超过五十个。但云存储选项的数量并不是DVC方法的关键劣势。(Dud和DVC都支持最大的玩家,如S3和GCS。)DVC的关键劣势是他们必须自己开发和维护大部分远程数据管理堆栈。如果Rclone是任何迹象的话,云数据传输是一个非常困难的问题,DVC有很多工作要做。
总之,Dud利用Rclone开发者的深厚知识和努力,提供了一个强大和熟悉的远程缓存体验。DVC自行规划他们的路线,在这样做时产生了巨大的开发成本。
Dud不使用分析。(而且永远不会。)
默认情况下,DVC启用嵌入式分析。我强烈反对这种做法,尤其是在免费和开源软件中。我永远不会在Dud中嵌入分析。
贡献
请参阅CONTRIBUTING.md。
许可证
BSD-3-Clause。请参阅LICENSE。