【问题标题】:SystemError: NULL result Multiprocessing PythonSystemError:NULL结果多处理Python
【发布时间】:2017-11-27 19:13:10
【问题描述】:

我正在使用多处理池来训练机器学习者。

每个 LearnerRun 对象都有一个学习者、一个超参数字典、一个名称、另一个选项字典中的更多选项、要写入结果的目录的名称、一组要训练的示例 ID(切片或numpy 数组),以及一组要测试的示例 ID(也是切片或 numpy 数组)。重要的是,尚未读取训练和测试数据:ID 集相对较小,并指导后续函数的数据库读取行为。

我打电话给self.pool.apply_async(learner_run.run),以前可以正常工作。现在池似乎已加载完毕,但 run() 函数顶部的打印语句从未打印,因此进程实际上并未运行。

我已经跟踪了一些其他的线程,发现我可以通过handler = self.pool.apply_async(learner_run.run)handler.get() 更详细地查看问题。这将打印“SystemError: NULL result without error in PyObject_Call”。

太好了,我可以用谷歌搜索。但是我在 Multiprocessing 的这个问题上所能找到的只是它可能是在将太大而无法腌制的参数传递给子进程时引起的。 但是,我显然没有向我的子进程传递任何参数。那么是什么给了?

除了超过分配的内存大小的参数(我有理由确信这不是这里的问题)之外,还有什么可能导致 apply_async 给出空结果?

再一次,这在我去度假之前有效并且没有改变。 对其他代码进行哪些类型的更改可能会导致此功能停止工作?

如果我不尝试从处理程序中 get() 以便执行不会因错误而停止,那么内存使用将遵循这种奇怪的模式。

【问题讨论】:

    标签: python multiprocessing system-error pyobject


    【解决方案1】:

    好的,我发现了问题。事实上,我的 LearnerRun 太大,Multiprocessing 无法处理。但是它的方式非常微妙,所以我会描述一下。

    显然,需要腌制的不仅仅是论据;该函数也被腌制,包括其执行将依赖的LearnerRun 对象(self)。

    LearnerRun 的构造函数获取传递给它的选项字典中的所有内容,并使用 setattr 将所有键和值转换为具有值的成员变量。仅此一项就可以了,但我的同事意识到这会留下一些需要作为数据库引用的字符串并设置 self.trainDatabase = LarData(self.trainDatabase)self.coverageDatabase = LarData(self.coverageDatabase),这通常会很好。

    除了这意味着要腌制类,您必须腌制整个数据库!我在进行健全性检查时发现了这一点,其中只是对 LearnerRun 本身进行了序列化,以查看pickle.dumps(learner_run) 会发生什么。我的内存被淹没了,swap 开始以惊人的速度填满,直到 stackoverflow

    那么酸洗到磁盘呢? pickle.dump(learner_run, filename) 也炸了。在我终止之前它达到了 14.3 GiB!

    如果需要删除这些引用并稍后调用 LarData 构造函数呢?巴姆。固定的。一切正常。多处理不再给出神秘的 SystemError。

    这是second time泡菜最近让我很痛苦。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      • 2023-04-07
      • 2021-09-30
      • 2017-10-16
      • 1970-01-01
      • 2022-08-23
      相关资源
      最近更新 更多