8 级可重复性:让你的 Python 项目面向未来

下一个可能就是你!点击此处提交创客博客系列摘要。


恭喜!你已经编写了一些有用的 Python 代码。接下来呢?你明天、一年后或十年后还能运行这段代码吗?如果你把它交给别人,他们能运行吗?你能设置它在没有你在场的情况下定期运行,或者在不需要仅存储在你脑海中的特殊信息的情况下将其部署到服务器上吗?

如果你不计划可重复性,那么所有这些问题的答案几乎肯定是“否”。Python 程序通常建立在来自各种独立安装的库的代码之上,即使其中一个库不可用,或者版本比你使用的版本旧或新,你的代码也很容易停止工作。幸运的是,Python 具有捕获所有这些依赖项的工具,因此你可以实现几乎任何你想要的可重复性级别,尽管每个新级别都需要更多的工作,并且需要更多的磁盘空间或其他资源。

作为有用的指南,以下是可重复性不断提高的级别列表;只需选择你需要的级别并按照说明进行操作即可实现!我们将假设你想重现的代码表示为 Jupyter notebook 代码单元中的 Python 行,或表示为 .py Python 文本文件。我们还将假设如果你的代码需要数据,则数据是静态的并且足够小,可以与你的代码一起存档(但我们稍后会回到这个假设!)。

  • 级别 -1(不可重复):你的代码曾经运行并正常工作,命令以某种顺序,在某个先前编辑的版本中运行,但如果你执行python file.py或在你的 notebook 中“重启并全部运行”,它会因某种原因失败——即使你没有更改环境的任何内容。如果你一直在 Jupyter 或命令行中输入命令,而没有仔细考虑执行顺序,那么这很可能是你开始的地方!

  • 级别 0(仅限你今天可重复):你的代码目前在你的初始环境中重复运行。仅限你可重复,并且仅当你的环境任何其他外部代码和数据都可用不更改如果你知道在该环境中运行哪些命令以及使用哪个环境(其中“命令”类似于jupyter notebook file.ipynb(+ 重启并全部运行)或 python file.py arg1)。

  • 级别 1(在指导下其他人可重复):你已将你的环境的重要部分捕获在 requirements.txtenvironment.yml 文件中,其中你的直接依赖项按版本固定(例如,pandas=1.4.1),并且你保存或分发包含你的命令、环境规范、你需要的任何数据文件以及关于如何重现结果的明确且人类可读的说明的存档(例如,myproject.zip)或存储库(例如,在 github.com 上)。你可以重现,并且任何你将存档传达给的人都可以重现,只要他们可以在该环境中找到要运行的正确命令,他们可以正确解释你的说明,他们可以访问引用的 pip 或 conda 包,并且没有未固定的包已被其他人以不兼容的方式更新。

  • 级别 2(今天可重复,任何有互联网访问权限的人都可重复):你已使用 anaconda-project 或等效工具以机器可读形式捕获命令、任何外部代码和环境,其中直接依赖项按版本固定。今天任何有权访问引用的 pip 或 conda 包的人都可以重现,只要没有发布具有不兼容更新的未固定包。由于 anaconda-project 明确捕获了命令,因此只要你在本地测试过项目,你的说明中就不会有歧义或遗漏步骤的危险,但当互联网上可用的包更新时,它仍然可能失败,即使是你可能从未听说过的包(如果它们是你正在使用的包的依赖项)。

  • 级别 3(无限期可重复,任何有互联网访问权限的人都可重复):你已将命令和环境都捕获到完全锁定的项目中(使用 anaconda-project lockconda-lock 或等效工具),将每个递归依赖项固定到单独的构建(不仅是 pandas=1.4.1,还有每个已安装的依赖项,如 pytz=2020.1,即使你从未使用过 pytz 本身)。任何有权访问引用的 conda 或 pip 包的人都可以重现,只要没有锁定的包变得不可用(这种情况很少见,但可能由于稍后发现的安全风险或其他问题而发生)。

  • 级别 4(无限期可重复,无需依赖互联网):你已使用 anaconda-project –pack-envs 将命令和环境都捕获到完全锁定的 anaconda 项目中,其中所有 pip 或 conda 包都已解包并包含在内。即使没有可用的 conda 存储库,或者包已从存储库中删除,也可以重现,只要没有任何内容依赖于系统库,但会生成包含二进制文件的大得多的存档。请注意,只有单个平台的包可以以这种方式打包;在其他平台上构建仍然需要互联网访问(或构建单独的 Windows、Linux 和 Mac 存档)。

  • 级别 5(使用 Docker 可重复):与级别 4 相同,但创建包含你的项目的 Docker 镜像(可以使用 anaconda-project dockerize 轻松完成)。任何有权访问你的操作系统 (OS) 的人都可以重现甚至部署,即使系统库发生更改且没有可用的包存储库,只要 Docker 本身可用(今天这种情况很普遍)。生成更大的存档,这些存档不太容易被人类直接访问,因为它们将配置与二进制工件混合在一起,但比级别 4 更隔离于底层计算系统。

  • 级别 6(使用虚拟机可重复):与级别 5 相同,但将 Docker 和 Docker 镜像放到虚拟机 (VM) 镜像上。任何可以在任何 OS 上运行 VM 的人都可以重现——即使你不再有权访问原始类型的硬件或 OS——只要你可以运行 VM 镜像,但由于包含更多底层计算系统,因此生成的存档比 Docker 镜像更大。

  • 级别 7(在未触及的硬件上可重复):与级别 6 相同,但 VM 镜像也安装在为安全起见而锁定的 air-gap 物理硬件上。即使当前的硬件或 OS 无法再运行 VM 镜像,也可以重现,但可能只有具有物理访问权限的人员才能重现,并且只要硬件保持运行状态即可。

除非你明确使你的项目可供其他人重现,否则你很可能停留在级别 -1 或级别 0。达到级别 1 需要用于管理与底层系统分离的 Python 环境的工具,例如 pip+venvpoetryconda,这些工具通常可用,但对于可重复性而言并非真正足够,因为它们不捕获所需的命令或数据文件。在实践中,我的目标是制作级别 3 存档,这是第一个让我有信心分享我的代码并期望它在几个月后对我或其他人有效的级别,同时生成一个紧凑的文件存档,其中仅包含严格要求重现项目的内容。达到级别 3 确实需要安装 anaconda-project,但这很容易通过开源下载实现,并且生成的项目存档并不比任何其他可以包含你的项目的存档大得多。(也有计划最终将 anaconda-project 合并到 conda 本身中,从而进一步降低可重复性的门槛。)Anaconda Nucleus 包含一个 简单指南,介绍如何使用 anaconda-project 开始使用级别 3 及更高级别。

级别 4 通常也很有用,但它需要文件大小大幅增加,因为你的存档保存了特定平台上每个依赖项的副本,因此你不会想每天都创建级别 4 存档。不过,在里程碑或项目结束时绝对有用!级别 5 再次增加了所需的文件大小,并且还需要安装 Docker 来测试结果,但它提供了很好的保证,即你的项目将保持可用性,并且对于部署特别有用,考虑到部署系统中对 Docker 的广泛支持。级别 6 和 7 适用于真正偏执的人,或者适用于你真的非常担心以后无法运行该代码的情况(例如,出于监管、法律或产品安全原因)。

请注意,以上级别都假设如果你的代码需要任何数据或其他非代码文件,则这些文件足够小,可以包含在存档中,这对于 .zip 存档来说很容易,并且 anaconda-project 也很好地支持。如果你使用大型远程数据文件,你还需要一种方法来确保这些文件保持可用并被明确引用,这可能本身就很令人头疼(以及一个单独的主题)。如果你确实引用了任何外部数据文件,那么最好将数据的一个小子集直接包含在存档中,以便至少可以证明代码本身仍然可以可重复地运行,即使完整的数据稍后不再可用。当你想要在新数据上运行相同的代码,并且甚至不关心原始数据,但没有原始数据就无法使代码工作,或者如果你无法弄清楚代码将接受哪种类型的数据时,你以后会感谢自己的。

对于依赖于特殊硬件的代码(例如特定图形处理单元 (GPU) 型号、某种类型的计算集群或其他系统基础设施)也是如此。即使你的完整结果取决于这些专用系统,重要的是包含某些版本的代码,这些代码将在“通用”硬件上运行,以便你项目的未来用户能够验证基本代码在专用计算系统不再可用时仍然按预期工作。anaconda-project 支持多个命令,因此添加一个用于小型测试数据和/或有限计算平台的命令很简单。

这些级别还假设你的代码是运行然后完成并输出结果的东西。相反,如果你的代码是适合部署的东西,例如仪表板或 REST API,你应该争取级别 3 或更高级别,然后实际部署并监控结果,理想情况下使用持续集成系统进行测试,以确保新重启的部署将继续工作。部署带来了所有自身的难题,但如果你持续部署你的项目,你不仅可以确定它仍在工作,而且你将立即允许每个人使用你的工作。

无论你的情况如何,只需选择你对所涉及的工作和风险感到舒适的级别,但如果你的代码有任何价值,那么肯定至少选择级别 3!


关于作者

Jim Bednar 是 Anaconda, Inc. 的定制服务总监。Bednar 博士拥有德克萨斯大学计算机科学博士学位,以及电气工程和哲学学位。他发表了 50 多篇关于视觉系统、软件开发和可重复科学的论文和书籍。Bednar 博士管理 HoloViz 项目,这是一个开源 Python 工具集合,其中包括 Panel、hvPlot、Datashader、HoloViews、GeoViews、Param、Lumen 和 Colorcet。Bednar 博士于 2004 年至 2015 年在爱丁堡大学担任计算神经科学讲师和阅读器,此前曾在 National Instruments 从事硬件工程和数据采集工作。

关于创客博客系列

Anaconda 正在 每月博客系列 中放大其一些最活跃和最受珍视的社区成员的声音。如果你是一位创客,一直在寻找机会讲述你的故事、详细阐述你最喜欢的项目、教育你的同行并建立你的个人品牌,请考虑提交摘要。有关更多详细信息以及访问丰富的教育数据科学资源和讨论主题,请访问 Anaconda Nucleus

与专家交流

与我们的专家之一交流,为你的 AI 之旅寻找解决方案。

与专家交流