如何克服joblib的“TypeError:无法pickle instancemethod对象” on class method?

10

给定一个类和其中的两个方法A、B。

当我在A类中尝试执行以下命令时,会出现“TypeError: can't pickle instancemethod objects”的错误:

joblib.Parallel(n_jobs=-1)(joblib.delayed(self.B)(arg1, arg2, arg3) for arg1 in arg1_values_list)

我在Stackoverflow上发现了几个有关 instancemethod 的帖子,其中一些甚至涉及到 joblib,但我仍然没有成功地克服这个错误。

编辑:

以下是代码:

from sklearn.externals.joblib import Parallel, delayed
def a(self, x):
    print x
    return x*10

class c(object):
    def b(self):
        Parallel(n_jobs=-1)(
            delayed(a)(self, i) 
            for i in range(10))

test_c = c()

test_c.b()

正常运行时可正常运行。

但在尝试使用 "python -m cProfile" 进行分析时会失败。

2个回答

3

只向joblib.Parallel传递Python无状态函数可能更安全。您可以尝试import dill来注册实例方法的pickling支持:https://pypi.python.org/pypi/dill(不过,效果因人而异)。


我尝试将B移出类并像https://github.com/scikit-learn/scikit-learn/blob/8ad2f5ea8a01a1f33b0acf78bbe7b95c53a6afa4/sklearn/ensemble/forest.py中所做的那样将“self”传递给它,但现在我得到了“TypeError:无法pickle函数对象”...可能是什么原因导致了这个问题? - user2808117
奇怪,我从来没有在纯函数上使用joblib.Parallel时遇到过任何问题。你是否在某个地方使用了lambda函数?请编辑你的问题,包括一个最小化的复制脚本,不依赖于外部代码或数据。 - ogrisel
12
这太难以置信了!调试了4个小时,问题的原因竟然是cProfile!一旦使用它,joblib的并行就会失败。 - user2808117
2
有人能发一下关于cProfiles的解决方案吗? - Nacho
1
“关于cProfile的解决方案”是什么意思?当使用n_jobs>1的joblib时,只需不进行分析。cProfile无法分析子进程中发生的情况,因此尝试也是无用的。 - ogrisel
显示剩余2条评论

2
尝试将backend="threading"添加,因为多进程是默认的,但似乎会崩溃。这对我解决了问题。

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