首页 > 解决方案 > 向 Dask 分布式集群提交任务时本地 python 文件导入问题

问题描述

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

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 文件,因此任务失败。

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

标签: pythonpickledaskdask-distributed

解决方案


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

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

两种模糊的可能性:

  • 您可以仅在上传时处于活动状态的相同工作程序 ( ) 上执行计算操作compute(workers=),以及您运行的函数中的 reload 或其他 importlib 钩子。
  • 如果您愿意,您实际上可以将函数源作为文本分发,然后执行定义,或者再次使用 importlib 将其变成工作人员的模块。

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


推荐阅读