コメントはまだありません概要Pythonで並列計算を実施したい時、joblibは最も手軽なライブラリの1つです。本記事では、このjoblibを使った並列計算の実施方法とそのパラメータの効果を整理しました。joblibのバージョンは0.11です。joblibの使用方法joblibを使うためには、以下の3手順が必要です。並列計算のコーディングjoblibのインストールpipを使って簡単にインストールできます。joblibちなみに、マニュアルは以下にあります。並列計算を実行するためには、処理をファンクションにする必要があります。現状のコードが#各ループ内でhoge1〜hogenの処理を実施する。hogenのようにループ内で書き下されている状態であれば、下記のように処理を関数化し、functionを呼び出すだけでループが回せるように書き換える必要があります。#hoge1〜hogenをファンクションにまとめる。paramsは適当な引数。#ここには書いていないが戻り値があるファンクションでももちろん問題なし。hogen#ループ内はファンクションの呼び出しのみ。i)並列計算のコーディング最後に以下のようにコーディングすれば並列計算を実行することができ、2並列(n_jobs)で計算が実行されます。並列計算のコード自体はたったの1行であることが最大の特徴です。__name__...の処理がないとフリーズするので注意してください。ii)引数一覧joblibのParallelには以下の9引数があります。以降、それぞれについて説明していきます。n_jobsbackendverbosetimeoutpre_dispatchbatch_sizetemp_foldermax_nbytesmmap_moden_jobs並列処理数を指定するパラメータ。デフォルトは1(並列処理なし)。この数を大きくするほど並列数が増え、処理速度が早くなりますが、当然CPUの数以上に指定してもそれ以上は計算速度は上がりません。-1を指定するとコア数と等しい(=すべてのコアを使用)並列数となります。n_jobs)の並列数となります。これは、-2を指定した場合、1コア残して残りすべてを使う、-3を指定した場合、2コア残して残りすべてを使う、ことを示します。システム開発の時などでデータベースやウェブアプリケーション等、別にCPUを使う場合に便利です。以下のようなサンプルでコア数を変えて実行してみました。start))結果は以下。コア数が2の場合、計算時間がおおよそ半減していることが分かり、並列計算の効果を確認できました。1コアの場合:15.376秒2コアの場合:8.063秒backendマルチプロセスとするか、マルチスレッドにするか、を指定できます。デフォルトはマルチプロセスです。マルチプロセスとスレッドの違いは下記のサイト等が参考になるかと思います。https://qiita.com/shotaTsuge/items/0ad41fcee63a00a52f68基本的な考え方は、並列計算で引数に渡すパラメータを独立に使うものはマルチプロセス、共有して使うものはマルチスレッドが有効です。以下の例のように、共通のパラメータが非常にサイズが大きく、独立に扱うとメモリの専有やオーバヘッド(並列計算の準備にかかる時間)が大きくなる場合、処理のパラメータの上書きがないのであれば、マルチスレッドを指定すると結果はそのままで、計算速度が改善する可能性があります。range(4))結果は以下。マルチスレッドの場合、計算時間(オーバヘッドの時間)が1/60程度に短縮しています。joblibが遅いと思った時に有効かもしれません。マルチプロセスの場合:67.247秒マルチスレッドの場合:1.108秒verbose並列計算のログの頻度を指定するパラメータ。デフォルトは0(ログ無し)。1からログが出るようになり、10が最も高頻度になります。51より大きい値を指定すると結果がログに出るようになります。動作を確認したい時に有効です。finishedtimeoutタスクが所定の時間を超えた場合にエラーを返すためのパラメータ(単位は秒だと思います。デフォルトはNone(時間制限無し)。エラーを検知した場合、そのタスクだけを落とすわけではなく、処理全体が落ちてしまうようです。使いどころは少し微妙ですね。n_jobsが1の時は機能しません。start))途中で処理が1秒を超えたためエラーが発生し、処理が停止しました。TimeoutErrorTimeoutErrorpre_dispatchタスクに計算資源が割り当てられる前に、何個のタスクを生成させておくか、というパラメータ。デフォルトは2*n_jobs(並列数の2倍)。この値がreasonableと書かれており、あまり調整する必要はなさそうです。パラメータを変えて検証した感じでも、1等の極端に小さな値にしない限り、計算速度に大きな影響はなさそうでした。batch_size1プロセスにいくつのタスクを割り当てるかを設定するパラメータ。デフォルトはauto(自動)。この値が小さすぎると、処理が早い時にタスクの生成が間に合わなくなる等で全体の処理が遅くなってしまいますが、autoにしておけば自動でバッチサイズを大きく調整してくれます。下記の例では、バッチサイズが36に調整されています。この値も特に調整する必要はなさそうですね。0.9stemp_folder各タスクにデータを渡すときに一定サイズ(max_nbytes)を超える場合、ここで指定したtemp_folderに保存して共有されるようになります(多分)。自動にしているとシステムのテンポラリフォルダ等が使われるようです。device」というエラーが発生することがあります。発生した時テンポラリファイル等では容量が不足していることが原因ですので、保存ファイルを別のフォルダに変えましょう。range(20))メッセージを鵜呑みにして、HD容量を削減したり、PCを再起動しても直りませんので気をつけてください。(私はハマりました)max_nbytestemp_folderに指定するしきい値を設定するパラメータ。デフォルトは1M(メガバイト)。大容量のメモリを搭載している時など、メモリに乗せて処理したいときは大きめの値を設定すると処理が早くなるかもしれません。mmap_mode上記の保存時のオプションで、デフォルトは’r’。closeとかでしょうか。ドキュメントを呼んでもちょっと良くわかりませんでした。まとめPythonで並列計算を実施したい時に便利なjoblibのパラメータについて検証しました。基本的には「n_jobs」と「verbose」だけ使えば良いと思いますが、ファイルサイズが大きくなってくると、「backend」や「temp_folder」の出番も出てくると考えられます。コメントをキャンセルメールアドレスが公開されることはありません。*サイト上に表示された文字を入力してください。プロフィール兵庫県在住の30代データサイエンティスト。Pythonを使った機械学習等によるデータ分析や、ウェブアプリ等のシステム開発に取り組んでいます。