向 Dask 分布式集群提交任务时本地 python 文件导入问题

Local python files import issue when submitting a task to Dask distributed cluster

我有以下问题。如果我的代码被分成不同的文件,我不能简单地将函数导入并提交到集群,因为我的本地文件不存在于工作机器上。为了解决这个问题,我需要手动将文件合并为一个。对于小示例,它可以相对简单地完成,但是对于一个分成几个文件夹的大项目来说,这非常耗时。示例:

localfile.py 文件:

def custom():
  print("Remote run")
  return

现在让我们尝试将导入的函数提交到集群,cluster.py 文件:

import localfile

x = client.submit(localfile.custom)

x.result()
# Import error here, details below

-

# The protocol we write by default.  May be less than HIGHEST_PROTOCOL.
  File "/usr/local/lib/python3.6/site-packages/cloudpickle/cloudpickle.py", line 944, in subimport
ModuleNotFoundError: No module named 'localfile'

如您所见,工作人员无法找到本地 python 文件,因此任务失败。

有什么方法可以将我的 pickled 代码与导入的本地文件一起发送吗?我知道可能的解决方案只是将本地文件上传给工作人员,但是当代码经常修改并且您的集群是动态的时,这不是一个优雅的解决方案。如果能够自动将您的 'client.py' 代码与 'localfile.py' 合并,将其腌制并发送到调度程序,那就太好了。这有可能吗?你有任何其他想法如何解决这个问题吗?谢谢!

我想你会知道,客户端 API 提供了 upload_file,它可以处理将你的模块发送到工作人员可以导入的地方。

在工人来来去去的情况下,您将无法确保新工人将文件放在正确的位置。但是,pickle 就其本质而言,将 objects/functions 引用到源文件,大概是为了减少数据大小。

两种模糊的可能性:

  • 您可以仅对上传时处于活动状态的相同工作人员 (compute(workers=)) 执行计算操作,连同重新加载或您 运行 函数中的其他 importlib 挂钩.
  • 如果您愿意,您实际上可以将函数源作为文本分发,并执行定义,或者再次使用 importlib 将其放入工作模块中。

在任何一种情况下,您都需要修改或包装您的函数以处理额外的步骤。