5

私は8GBもの大きさのデータセットを扱っています。私も、scikit-learnを使ってさまざまなMLモデルを訓練しています。データセットは基本的にintの1Dベクトルのリストです。Python共有読み込みメモリ

複数のPythonプロセスでデータセットを使用できるようにするにはどうすればいいですか、データセットをエンコードしてmultiprocessingのクラスを使用できるようにするにはどうすればよいですか?私は​​で読んでいましたが、私もmultiprocessingのドキュメントを読んできましたが、私は非常に混乱しています。私はそれを使ってモデルを鍛えることができるように、すべてのプロセスでデータを読みやすくする必要があります。

変数multiprocessingをctypeとして共有する必要がありますか?

どのようにデータセットを​​と表すことができますか?

答えて

3

データセット全体をRAMにnumpy配列で読み込み、LinuxまたはMacで作業していると仮定しています。 (もしあなたがWindowsの場合、または配列をRAMに収めることができない場合は、おそらくディスク上のファイルに配列をコピーしてnumpy.memmapを使ってアクセスする必要があります。コンピュータはディスクからRAMにデータをキャッシュしますこれらのキャッシュはプロセス間で共有されるため、恐ろしい解決策ではありません)。で作成された他のプロセスのデータセットへの読み取り専用アクセスが必要な場合は、上記の前提条件を使用して、他のプロセスを起動します。彼らは元の名前空間からのデータへの読み取り専用アクセス権を持ちます。それらは元の名前空間からデータを変更できますが、それらの変更は他のプロセスからは見えません(メモリマネージャは変更したメモリの各セグメントをローカルメモリマップにコピーします)。

あなたの他のプロセスが元のデータセットを変更し、親プロセスまたは他のプロセスに見えるそれらの変更を加える必要がある場合は、このような使用することができます

import multiprocessing 
import numpy as np 

# create your big dataset 
big_data = np.zeros((3, 3)) 

# create a shared-memory wrapper for big_data's underlying data 
# (it doesn't matter what datatype we use, and 'c' is easiest) 
# I think if lock=True, you get a serialized object, which you don't want. 
# Note: you will need to setup your own method to synchronize access to big_data. 
buf = multiprocessing.Array('c', big_data.data, lock=False) 

# at this point, buf and big_data.data point to the same block of memory, 
# (try looking at id(buf[0]) and id(big_data.data[0])) but for some reason 
# changes aren't propagated between them unless you do the following: 
big_data.data = buf 

# now you can update big_data from any process: 
def add_one_direct(): 
    big_data[:] = big_data + 1 

def add_one(a): 
    # People say this won't work, since Process() will pickle the argument. 
    # But in my experience Process() seems to pass the argument via shared 
    # memory, so it works OK. 
    a[:] = a+1 

print "starting value:" 
print big_data 

p = multiprocessing.Process(target=add_one_direct) 
p.start() 
p.join() 

print "after add_one_direct():" 
print big_data 

p = multiprocessing.Process(target=add_one, args=(big_data,)) 
p.start() 
p.join() 

print "after add_one():" 
print big_data 
1

は、あなたが新しいnumpyのmemmapオブジェクトに現在の表現から、あなたのデータセットを変換し、すべてのプロセスからそれを使用することができShare Large, Read-Only Numpy Array Between Multiprocessing Processes

の重複もございます。しかし、それはとにかく高速ではありません、それは単にラムからアレイで作業するという抽象を与えます。実際にはRAMから部分的にキャッシュされたHDDからのファイルになります。したがって、partial_fitメソッドを使ってscikit-learn algosを使用し、それらを使用する必要があります。

https://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

実際に(並列化のためのscikit学習に使用されている)JOBLIBは自動的に(それはもちろん、十分な大きさだ場合)異なるプロセスからそれを使用する表現をmemmapするデータセットに変換します。

関連する問題