2017-02-01 13 views
1

現在、マルチプロセッシングで実装されているプログラムでspaCyを使用したいと考えています。具体的には、私はProcessingPoolを使って4つのサブプロセスを生成し、それから降りてメリータスクを行います。マルチプロセス時に各サブプロセスのspaCyデータのロードを回避する

spaCy(特にPOSタグ付け用)を使用するには、spacy.load('en')を呼び出す必要があります。これは高価な呼び出しです(約10秒かかる)。このオブジェクトを各サブプロセス内にロードする場合、すべて同じ場所から読み取るので、〜40秒かかります。これは面倒で長いです。

しかし、私はそれらがロードされているオブジェクトを共有する方法を見つけることができません。このオブジェクトは、(私の知る限り)を意味し、漬けすることはできません。

  1. その後のプロセス間で共有されることがManagerインスタンスで保存して使用することはできませんPool.mapコール
  2. に渡すことはできません

どうすればよいですか?

+0

どのバージョンのPythonを使用していますか? – amirouche

+0

3.5.2、Ubuntuで16.04 – tombird

+0

私の答えはどう思いますか? – amirouche

答えて

0

Pool.mapの使い方はありませんが、大量の入力ではPool.mapは機能しません。 Python 3.6では、Lib/multiprocessing/pool.pyに実装されています。iterableが最初の引数として指定されていますが、実装ではマルチプロセスマップを実行する前にconsume the whole iterableになります。だから、多くのデータを処理する必要がある場合は、使用する必要があるのはPool.mapではないと思います。たぶんPool.imapPool.imap_unorderedが動作する可能性があります。

実際の問題について私はPool.mapを含まない解決策を持っていて、マルチプロセスのようなものを扱っていますforeachqueue経由

queue = Queue() 
workers = list() 
for _ in range(cpu_count()): # minus one if the main processus is CPU intensive 
    worker = Worker(queue) 
    workers.append(worker) 
    worker.start() 

は、その後、あなたがプールを養うことができます:あなたはそのようなprocessusのプールを用意

from multiprocessing import cpu_count 
from multiprocessing import Queue 
from multiprocessing import Process 


class Worker(Process): 

    english = spacy.load('en') 

    def __init__(self, queue): 
     super(Worker, self).__init__() 
     self.queue = queue 

    def run(self): 
     for args in iter(self.queue.get, None): 
      # process args here, you can use self. 

まずあなたがPoolを継承し、ワーカープロセスを作成する必要があり

for args in iterable: 
    queue.put(args) 

iterableはargのリストですあなたが労働者に渡す痕跡。上記のコードは可能な限り速くiterableの内容をプッシュします。基本的には、作業者の速度が十分に遅い場合、作業者が作業を完了する前に、ほぼすべての反復可能命令がキューにプッシュされます。だから、の内容は、のメモリに収まる必要があります。

労働者の引数(別名iterableが。)あなたが何とかメインprocessusと労働者を同期する必要がありますメモリに収まらない場合は...終わり

は以下を呼び出してください:

for worker in workers: 
    queue.put(None) 

for worker in workers: 
    worker.join() 
関連する問題