私はpythonパッケージを探しています。これは、単一のコンピューター内の異なるコアだけでなく、複数のマシンに分散されたクラスターでもマルチプロセッシングを実行できます。さまざまなpythonパッケージですが、ほとんどは実行するためにコードの変更が必要なようです(たとえば、オブジェクトがリモートマシン上にあることを示すプレフィックスなど)。具体的には、マルチプロセッシングpool.map
関数。したがって、たとえば、単一のマシンの場合、スクリプトは次のようになります。
from multiprocessing import Pool
pool = Pool(processes = 8)
resultlist = pool.map(function, arglist)
次に、分散クラスターの疑似コードは次のようになります。
from distprocess import Connect, Pool, Cluster
pool1 = Pool(processes = 8)
c = Connect(ipaddress)
pool2 = c.Pool(processes = 4)
cluster = Cluster([pool1, pool2])
resultlist = cluster.map(function, arglist)
私は Ray を見てみることをお勧めします。
Rayは、単一マシンのマルチコア設定でも、分散設定と同じ構文を使用してコードを並列化します。マップ呼び出しの代わりにforループを使用する場合、例は次のようになります。
_import ray
import time
ray.init()
@ray.remote
def function(x):
time.sleep(0.1)
return x
arglist = [1, 2, 3, 4]
result_ids = [function.remote(x) for x in arglist]
resultlist = ray.get(result_ids)
_
ローカルにある多くのコアを使用して、4つのタスクを並行して実行します。クラスターで同じ例を実行する場合、変更されるのはray.init()
の呼び出しだけです。関連ドキュメントは here にあります。
Ray の開発を支援していることに注意してください。
非常に簡単な解決策が必要な場合はありません。
ただし、multiprocessing
インターフェイス-pathos
-を使用して、並列マップを介してリモートサーバーへの接続を確立し、マルチプロセッシングを実行するソリューションがあります。
Sshトンネル接続が必要な場合は、それを行うことができます。または、安全性の低い方法で問題がなければ、それも行うことができます。
>>> # establish a ssh tunnel
>>> from pathos.core import connect
>>> tunnel = connect('remote.computer.com', port=1234)
>>> tunnel
Tunnel('-q -N -L55774:remote.computer.com:1234 remote.computer.com')
>>> tunnel._lport
55774
>>> tunnel._rport
1234
>>>
>>> # define some function to run in parallel
>>> def sleepy_squared(x):
... from time import sleep
... sleep(1.0)
... return x**2
...
>>> # build a pool of servers and execute the parallel map
>>> from pathos.pp import ParallelPythonPool as Pool
>>> p = Pool(8, servers=('localhost:55774',))
>>> p.servers
('localhost:55774',)
>>> y = p.map(sleepy_squared, x)
>>> y
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
または、代わりに直接接続を構成できます(SSHなし)
>>> p = Pool(8, servers=('remote.computer.com:5678',))
# use an asynchronous parallel map
>>> res = p.amap(sleepy_squared, x)
>>> res.get()
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
それは少し厄介です、リモートサーバーが機能するためには、事前に指定されたポートでremote.computer.com
で実行されているサーバーを起動する必要があります-そして、ローカルホストとリモートホストの両方の設定を確認する必要があります直接接続またはsshトンネル接続のいずれかを許可します。さらに、各ホストで実行しているpathos
とpathos
のpp
フォークのバージョンが同じである必要があります。また、sshでは、sshを使用してパスワードなしでログインできるように、ssh-agentを実行する必要があります。
しかし、うまくいけばそれがすべてうまくいく...もしあなたの関数コードがdill.source.importable
でリモートホストに転送できれば。
参考までに、pathos
はリリースが大幅に遅れており、基本的に、新しい安定版リリースがカットされる前に解決する必要があるいくつかのバグとインターフェースの変更があります。
ここのパーティーには少し遅れましたが、同様の解決策も探していたため、この質問にはまだ回答済みのマークが付いていないので、自分の調査結果に貢献したいと思いました。
私は [〜#〜] scoop [〜#〜] を使用してしまいました。複数のホスト間で複数のコア間で機能できる並列マップ実装を提供します。呼び出し中に必要に応じて、Pythonのシリアルmap
関数にフォールバックすることもできます。
SCOOPの紹介ページから、次の機能が引用されています。
SCOOPの機能と、フューチャー、マルチプロセッシング、および類似のモジュールに対する利点は次のとおりです。
- ネットワークを介して複数のコンピューターの能力を利用します。
- タスク内で複数のタスクを生成する機能。
- APIは PEP-3148 と互換性があります。
- わずかな変更のみでシリアルコードを並列化します。
- 効率的な負荷分散。
いくつかの癖(関数/クラスはピクル可能にする必要があります)があり、複数のホスト間でスムーズに実行するための設定は、それらがすべて同じファイルシステムスキーマを共有していない場合、面倒な場合がありますが、全体的に結果に非常に満足しています。私たちの目的では、かなりのNumpy&Cythonを実行することで、優れたパフォーマンスを提供します。
お役に立てれば。
disco を見ましたか?
特徴:
ディスコのドキュメントからの簡単な例:
from disco.core import Job, result_iterator
def map(line, params):
for Word in line.split():
yield Word, 1
def reduce(iter, params):
from disco.util import kvgroup
for Word, counts in kvgroup(sorted(iter)):
yield Word, sum(counts)
if __name__ == '__main__':
job = Job().run(input=["http://discoproject.org/media/text/chekhov.txt"],
map=map,
reduce=reduce)
for Word, count in result_iterator(job.wait(show=True)):
print(Word, count)