Dask“no module named xxxx”错误

13
使用dask distributed,我尝试提交一个位于另一个名为worker.py的文件中的函数。 在workers中,我遇到了以下错误:

No module named 'worker'

然而,我无法弄清楚我在这里做错了什么...

这是我的代码样例:

import worker

def run(self):
    dask_queue = queue.Queue()
    remote_queue = self.executor.scatter(dask_queue)
    map_queue = self.executor.map(worker.run, remote_queue)
    result = self.executor.gather(map_queue)

    # Load data into the queue
    for option in self.input.get_next_option():
        remote_queue.put([self.server, self.arg, option])

以下是在工作端获得的完整回溯信息:

distributed.core - INFO - 失败无法反序列化 b'\x80\x04\x95\x19\x00\x00\x00\x00\x00\x00\x00\x8c\x06worker\x94\x8c\nrun\x94\x93\x94.' Traceback (most recent call last): File "/usr/local/lib/python3.5/dist-packages/distributed/core.py", line 74, in loads return pickle.loads(x) ImportError: No module named 'worker' distributed.worker - WARNING - 无法反序列化任务 追溯信息如下: (most recent call last): File "/usr/local/lib/python3.5/dist-packages/distributed/worker.py", line 496, in compute_one task) File "/usr/local/lib/python3.5/dist-packages/distributed/worker.py", line 284, in deserialize function = loads(function) File "/usr/local/lib/python3.5/dist-packages/distributed/core.py", line 74, in loads return pickle.loads(x) ImportError: No module named 'worker'

4个回答

5

这个问题可能有两种情况:主代码中调用dask-distributed函数的导入未找到,或者在dask-distributed函数内部的导入未找到。无论哪种情况,解决方案都是更新sys.path以指向那些模块的位置。

在我的情况下,我两种都更新了。

例如,假设您的主脚本中有模块xxx,在您想要分发的dask函数中有模块yyy。 代码应该像这样:

from dask.distributed import Client
import sys

def update_syspath():
  sys.path.insert(0, 'module_xxx_location')

# you have to update sys.path first before import the xxx module
import xxx

def dask_function():
  sys.path.insert(0, 'module_yyy_location')
  import yyy

client.submit(dask_function, params)

你是我的救星!! - Cupitor

4
我遇到了类似的问题。在创建dask图时使用了来自Python模块的函数。然而,工作进程无法找到Python模块。
下面是工作进程控制台中出现的错误。这里,tasks.py包含了在dask图中使用的工作进程函数。
[ worker 10.0.2.4 ] : ModuleNotFoundError: No module named 'tasks'
[ worker 10.0.2.4 ] : distributed.protocol.pickle - INFO - Failed to deserialize b'\x80\x04\x95\x14\x00\x00\x00\x00\x00\x00\x00\x8c\x05tasks\x94\x8c\x06ogs_mk\x94\x93\x94.'

当使用Client.upload_file将本地Python模块发送到工作节点时,问题得到了解决。

client.upload_file('tasks.py')     ## Send local package to workers
results = client.get(dsk, 'root')  ## get the results

1
一个文件夹作为模块怎么样? - wakandan
@wakandan 请查看 UploadDirectory 插件:https://distributed.dask.org/en/latest/plugins.html#distributed.diagnostics.plugin.UploadDirectory - Anatoly Alekseev

3

编辑:请参考MRocklin的评论以获得更干净的解决方案

实际上,如果要在dask worker中执行的代码位于外部模块中,则必须从dask worker路径(不是从客户端序列化到worker)了解该模块。

更改我的PYTHONPATH以确保worker知道该模块可以解决该问题。 类似的问题已经发布在dask issues:

https://github.com/dask/distributed/issues/344


3
您可能还想查看Client.upload_file方法:http://distributed.readthedocs.io/en/latest/api.html#distributed.client.Client.upload_file - MRocklin
它看起来确实比我的解决方案好 :) 谢谢 - Bertrand
3
我明白这是一篇旧帖子,但我不理解你所说的“更改PYTHONPATH”的意思。我已经尝试将我的项目文件夹添加到PYTHONPATH中,但这没有解决我的问题。我使用的是venv。你认为这可能与venv有关吗?你是如何“更改PYTHONPATH”的? - MehmedB
是的,它们是。但我意识到了一些事情。缺失的不是一个实际的模块,而是项目内部的一个脚本。我已经将该脚本打包并使用pip模块进行安装。这解决了问题。 - MehmedB
我发现有些问题在使用Dask时总是没有解决方案,而其他问题则总能找到相关线程。 - wakandan

0

当Dask工作进程在我的当前工作目录中找不到模块时,我通过稍微调整启动命令来解决了这个问题:

PYTHONPATH=$(pwd) dask-worker 127.0.0.1:8786

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接