私はScikit-Learnから一連のKMeansクラスタリングモデルをPythonのmulitprocessing
ライブラリを使用して別々のプロセスでトレーニングしようとしています。を使用multiprocess.Pool
してモデルをトレーニングしようとすると、実行時エラーが発生することなくコードが実行されますが、実行が完了しません。
さらに調査すると、トレーニングデータのメモリ内のサイズ(以下のコードスニペット内)が2 ^ 16 = 65536バイトを超えた場合にのみコードが終了しないことが明らかになりX
ました。それより少なく、コードは期待どおりに動作します。
import sys
import numpy as np
from multiprocessing import Pool
from sklearn.cluster import KMeans
# The Code Below Executes and Completes with MULTIPLIER = 227 but not when MULTIPLIER = 228
MULTIPLIER = 227
# Some Random Training Data
X = np.array(
[[ 0.19276125, -0.05182922, -0.06014779, 0.06234482, -0.00727767, -0.05975948],
[ 0.3541313, -0.29502648, 0.3088767, 0.02438405, -0.01978588, -0.00060496],
[ 0.22324295, -0.04291656, -0.0991894, 0.04455933, -0.00290042, 0.0316047 ],
[ 0.30497936, -0.03115212, -0.26681659, -0.00742825, 0.00978793, 0.00555566],
[ 0.1584528, -0.01984878, -0.03908984, -0.03246589, -0.01520335, -0.02516451],
[ 0.16888249, -0.04196552, -0.02432088, -0.02362059, 0.0353778, 0.02663082]]
* MULTIPLIER)
# Prints 65488 when MULTIPLIER = 227 and 65776 when MULTIPLIER = 228
print("Input Data Size: ", sys.getsizeof(X))
# Training without Multiprocessing Always Works Regardless of the Size of X
no_multiprocessing = KMeans(n_clusters=2, n_jobs=1).fit(X)
print("Training without multiprocessing complete!") # Always prints
# Training with Mulitprocessing Fails when X is too Large
def run_kmeans(X):
return KMeans(n_clusters=2, n_jobs=1).fit(X)
with Pool(processes=1) as p:
yes_multiprocessing = p.map(run_kmeans, [X])
print("Training with multiprocessing complete!") # Doesn't print when MULTIPLIER = 228
プロセスが独自のプロセスを生成しないように、n_jobs
パラメーターを1
またはに設定するように常に注意を払ってNone
います。
不思議なことに、このメモリ制限はmultiprocessing.Pool
「要素ごとの」メモリ制限として組み込まれていないようです。非常に長い文字列(65536バイト以上を消費)を渡すことができ、コードが文句なしに終了するためです。
import sys
from multiprocessing import Pool
my_string = "This sure is a silly string" * 2500
print("String size:", sys.getsizeof(y)) # Prints 79554
def add_exclamation(x):
return x + "!"
with Pool(processes=1) as p:
my_string = p.map(add_exclamation, [my_string])
print("Multiprocessing Completed!") # Prints Just Fine
最初のコードスニペットがハングアップしたときに実行を終了すると、常に次のエラーメッセージが表示されます。
File "/path/to/my/code", line 29, in <module>
yes_multiprocessing = p.map(run_kmeans, [X])
File "/.../anaconda3/envs/Main36Env/lib/python3.6/multiprocessing/pool.py", line 266, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "/.../anaconda3/envs/Main36Env/lib/python3.6/multiprocessing/pool.py", line 638, in get
self.wait(timeout)
File "/.../anaconda3/envs/Main36Env/lib/python3.6/multiprocessing/pool.py", line 635, in wait
self._event.wait(timeout)
File "/.../anaconda3/envs/Main36Env/lib/python3.6/threading.py", line 551, in wait
signaled = self._cond.wait(timeout)
File "/.../anaconda3/envs/Main36Env/lib/python3.6/threading.py", line 295, in wait
waiter.acquire()
KeyboardInterrupt
ここで推奨されているように、MacOSシステムにプロセスをフォークする代わりに強制的にスポーンさせようとしました。関連するすべてのコードがwith
ブロック内に存在することを確認したり、iPython環境(ターミナルから直接Pythonコードを実行したり)を回避したりするなどの提案を調査しました。Pool
プロセス数を変更しても影響はありません。また、ここで説明するように、デーモンプロセスがKMeans統合内からプロセスを生成しようとしないように、からmultiprocessing.Pool
に切り替えてみましたが、成功しませんでした。multiprocessing.Process
Pool
joblib
65536バイトを超えるトレーニングデータを使用して、別々のプロセスで複数のKMeansモデルをトレーニングするにはどうすればよいですか?
試行錯誤を繰り返した結果、上記のコードを新しい環境で実行したため、問題は環境エラーのようです。どのパッケージが問題を引き起こしたのか完全にはわかりません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加