管理依赖关系
一个 Metaflow 流程在一个单一的 Python 文件中定义。除了流程代码本身,一个典型的流程有许多 软件依赖,即其他 模块,包,以及像 pandas 或 pytorch 的第三方库,流程由这些组成。
虽然依赖管理的问题看起来相当平凡,但对于生产质量项目来说,这是一个至关重要的部分,原因有很多:
流程需要一个稳定的执行环境。你不希望因为某个包在后台突然发生变化而得到意外结果。每个项目可能都有自己的依赖集,这些依赖需要与其他项目隔离。
应该能够使流程可重现。任何人都应该能够检索一个流程,重新运行它,并获得类似的结果。为了实现这一点,流程不能依赖于仅在你的笔记本电脑上可用的库。
任务的远程执行 要求所有依赖项可以在远程环境中即时重建。如果流程依赖于仅在您的笔记本电脑上可用的库,这将不可能。
Metaflow 包含强大但灵活的机制来管理依赖关系。您可以轻松开始,并逐步完善项目,以为其提供稳定、可重复的执行环境。
在幕后,Metaflow 做的远不止于 pip install 流动安装包。如果你想了解更多内容及原因,请查看 打包内部细节 和 @pypi 公告博客文章。
解压一个 Metaflow 项目
让我们考虑构成Metaflow项目的层:

一个流程文件,例如
flow.py定义了流程的有向无环图(DAG)。该文件可以包含任意用户定义的代码,使得仅用一个文件就能轻松入门。随着项目的发展,将项目结构化为多个模块和包是很方便的,而不是将数百行代码包含在一个文件中。Metaflow会自动打包本地Python依赖项。
至关重要的是,Metaflow 为远程执行打包了 Metaflow 本身,因此您在使用
@batch和@kubernetes时无需手动安装它。同时,这保证了所有任务始终使用相同版本的 Metaflow。外部库可以通过
@pypi和@conda装饰器 包含。在幕后,这些装饰器自动处理依赖关系解析、虚拟环境创建和包快照。最终,所有代码都在一个操作系统上执行,该操作系统定义了低级驱动程序和安全功能。如果需要,这其中的许多内容可以通过自定义Docker镜像进行配置。
请注意,您可以开始本地开发而无需担心这些。Metaflow 使用您本地安装的库,就像其他Python项目一样。 当您想要扩展到云端或想要 在生产中部署流程时,依赖管理变得立即相关。
为远程执行打包项目
为了在您的本地环境之外执行任务,Metaflow 会自动快照层 1-3(深蓝色)并将其存储在 代码包 中。您可以 通过客户端 API 检查该包 以查看运行时执行的确切代码。
如果您感兴趣,可以通过执行来检查将包含在代码包中的文件
python myflow.py package list
默认情况下,包只包括本地 Python 文件,而不包括你手动安装的库,例如通过 pip install。要包括外部库,你需要将它们包含在 自定义 Docker 镜像 中,或者 在 @pypi 或 @conda 装饰器中指定它们。此图说明了这个概念:

使用哪种方法?
假设你的团队有一个公共模块 special_module.py,该模块被许多流程使用。你可以将它包含在这三层中的任何一层。你可以
- 将其与
flow.py一起包含作为本地依赖项,Metaflow会自动打包。 - 将其发布为一个Python包,并使用
@pypi包含它。 - 将其包含在自定义Docker镜像中。
应选择哪种方法?可能有内部原因使得选择某种方法而不是其他方法,但如果你不确定,这里有一个简单的经验法则:优先使用本地文件用于任何需要快速更改的依赖项。
如果您需要每天多次更改 special_module.py,那么每次更改都需要构建新的包或Docker文件的开销可能会让人感到不堪重负。相比之下,如果文件很少更改,所有方法效果都一样好。
下一页的重点是使用本地文件进行快速开发。