使用导入函数时,使用joblib出现错误。

7

我正在使用joblib来并行化我的Python 3.5代码。
如果我执行以下操作:

from modules import f
from joblib  import Parallel, delayed

if __name__ == '__main__':
    Parallel( n_jobs  =  n_jobs,backend = "multiprocessing")(delayed(f)(i) for i in range( 10 ))

代码无法运行。相反应该这样处理:

from joblib import Parallel, delayed

def f( i ):
    # my func ...

if __name__ == '__main__':
    Parallel( n_jobs  =  n_jobs, backend = "multiprocessing")(delayed(f)(i) for i in range(10))

这个有效!

有人能解释一下为什么我必须把所有的函数都放在同一个脚本中吗?

这真的很不实用,因为在模块中有许多我编写的函数,我不想将它们复制/粘贴到主脚本中。


1
欢迎。请问您是否可以标记您的代码,以便使其更易读。 - rocksteady
2
请您能否提供更多信息,说明您的代码为什么无法正常工作?例如错误信息、观察到的行为等。 - Nils Werner
我没有错误,代码开始运行,但当它到达“parallel”时,它停止工作,就像进入了一个无限循环。我认为它可能正在寻找“modules”中定义的函数,但是“modules”与主脚本在同一个文件夹中。因此,它应该能够找到它们。另外,非并行版本运行良好。 - Grg
这与此处报告的问题 https://github.com/joblib/joblib/issues/911 类似,但我自己无法重现它。如果有人能够在使用joblib 0.14.0或更高版本时重现此问题,请提供完整的traceback信息。 - ogrisel
2个回答

3

我遇到了类似的问题。当我从导入中调用函数时,它会冻结,但当我调用本地函数时,它可以正常工作。通过使用多线程而不是多进程来解决该问题。

Parallel( n_jobs  =  n_jobs, backend='threading')(delayed(f)(i) for i in range(10))

1
请注意,对于不释放GIL的CPU绑定工作,这不是一个好的解决方案,因为所有线程共享同一实例的GIL。 - kabla002

1
我找到了一个解决方法,可以让你将辅助函数保留在单独的模块中。对于每个想要并行化的导入函数,在您的主模块中定义一个代理函数,例如:
def f_proxy(*args, **kwargs):
    return f(*args, **kwargs)

只需使用delayed(f_proxy)即可。虽然还有些不尽人意,但比将所有辅助函数移动到主模块更加简洁。


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