我正在开发需要使用相当大的训练模型文件才能运行的机器学习仓库。这些文件不在Git远程库中,而是由DVC跟踪并保存在一个单独的远程存储中。当我在CI管道中尝试运行需要这些模型文件进行预测的函数的单元测试时,我遇到了问题。由于我在Git远程中无法访问这些文件,我无法测试它们。
在这种情况下,人们通常会采取什么最佳做法?我能想到几个选项 –
- 在CI管道中从DVC远程拉取模型。我不想这样做,因为每次想推送一些代码时都需要下载模型,这会迅速消耗我的CI使用时间,并且是一个昂贵的选项。
- 使用
unittest.mock
模拟模型预测的输出,并测试代码的其他部分。这是我目前在做的事情,但使用unittest的mock功能有点麻烦。从我所见,这个模块并不是专门为机器学习设计的。它缺少(或难以找到)一些我非常希望有的功能。有没有专门针对机器学习的工具来做这个? - 对函数定义进行奇怪的重新格式化,实际上可以实现选项2,但不需要mock模块。也就是说,只测试周围的逻辑,不关心模型输出。
- 直接将模型文件放入Git远程库,结束这件事。只使用DVC来跟踪数据。
在这种情况下,人们通常会怎么做?
回答:
如果我们谈论的是单元测试,我认为确实最好使用mock。单元测试最好保持小巧,测试单元的实际逻辑等。不过,最好还有其他测试,这些测试会拉取模型并在其上运行一些逻辑——我会称它们为集成测试。
不过,这并不是非黑即白。如果你出于某种原因发现使用实际模型更容易(例如,模型变化频繁,使用它比维护和更新存根/固定数据更容易),你可以考虑缓存它。
我想,要帮助你使用mock,你需要分享一些技术细节——函数的外观,你尝试过什么,什么地方出了问题等。
因为每次想推送一些代码时都需要下载模型,这会迅速消耗我的CI使用时间,并且是一个昂贵的选项。
我认为你可以利用CI系统的缓存功能来避免反复下载。这是GitHub Actions相关的仓库,这是CircleCI。所有常见的CI提供商的理念都是相同的。你考虑使用哪一个,顺便问一下?
直接将模型文件放入Git远程库,结束这件事。只使用DVC来跟踪数据。
这可以是一种方法,但如果模型足够大,你会显著污染Git历史。在某些CI系统上,这可能会变得更慢,因为它们会使用常规的git clone
来获取这些文件。实际上,还是在下载模型。
顺便说一下,无论你是否使用DVC,请看另一个专门为机器学习的CI/CD设计的开源项目 – CML。