2017-11-27 22 views
0

私はマルチプロセッシングプールを使用して機械学習者を訓練しています。SystemError:NULL resultマルチプロセッシングPython

各LearnerRunオブジェクトは、学習者、ハイパーパラメータの辞書、名前、他のオプション辞書のいくつかのオプション、結果を書き込むディレクトリの名前、トレーニングするサンプルのIDのセット(スライスまたはnumpy配列)、およびテストするサンプルのIDのセット(スライスまたはnumpy配列)重要なことは、トレーニングとテストのデータはまだ読み込まれていないことです。IDのセットは比較的小さく、後の関数のデータベース読取り動作を指示します。

私はself.pool.apply_async(learner_run.run)を呼び出しましたが、これまでは問題なく機能していました。今度はプールがロードされているように見えますが、run()関数の先頭のprint文は決して出力されないので、プロセスは実際には実行されません。

私はこれについて、いくつかの他のスレッドを突き止め、私はhandler.get()続いhandler = self.pool.apply_async(learner_run.run)してより詳細に問題を見ることができることを発見しました。これは、 "SystemError:PyObject_CallでエラーなしのNULL結果"を表示します。

偉大な、私はGoogleすることができます。しかし、私がマルチプロセッシングでこの問題を見つけることができるのは、それがサブプロセスに拾うには大きすぎる引数を渡すときに発生する可能性があるということです。 しかし、、私は明らかに私のサブプロセスに引数を渡しています。だから何を与える?

割り当てられたメモリサイズを超えている引数を除いて - これは問題ではないと確信していますが、apply_asyncにnullの結果が出る可能性がありますか?

また、これは休暇の前に変更されていません。 他のコードのどのような変更により、これが機能しなくなる可能性がありますか?

enter image description here

私は実行がエラーで停止しないハンドラからget()にしようとしていない場合は、メモリ使用量は、この奇妙なパターンに従います。

答えて

0

問題が見つかりました。実際、私のLearnerRun は、マルチプロセッシングで扱うには大きすぎるでした。しかし、それがあった方法はかなり微妙なので、私は説明します。

明らかに、単に節約する必要がある引数ではありません。その関数の実行に依存するLearnerRunオブジェクト(self)も含めて、関数がpickleされます。

LearnerRunのコンストラクターは、渡されたオプション辞書内のすべてのものを受け取り、setattrを使用して、すべてのキーと値をメンバー変数に値で変換します。これだけで問題はありませんが、私の同僚はこれがデータベース参照である必要がある文字列を残して、通常self.trainDatabase = LarData(self.trainDatabase)self.coverageDatabase = LarData(self.coverageDatabase)になります。

を除いて、これはクラス全体をピクルする必要があることを意味します。私はpickle.dumps(learner_run)で何が起きるかを見るためにLearnerRun自体をシリアライズしたサニティチェック中にこれを発見しました。私の記憶は浸水し、スワップは驚くほど早くいっぱいになった。stackoverflow

それでは、ディスクの酸洗はどうですか?pickle.dump(learner_run, filename)もまた爆発した。私が終了する前に14.3 GiBになった!

これらの参照を削除し、必要に応じて後でLarDataコンストラクタを呼び出すのはどうですか? Bam。一定。すべてが機能します。マルチプロセッシングはもはや神秘的なSystemErrorを与えません。

これは最近、大きな痛みを引き起こしたsecond timeピクルスです。

関連する問題