Joblibとは
Joblibは、並列処理などいろんな便利機能を寄せ集めたようなPythonライブラリです。
Joblibを使うことで
- 並列化
- メモ化
- 直列化〔シリアライズ〕
などを簡単に実装でき、特にPythonコードの高速化に役立ちます。
Joblibは一般に並列化に使われることが多いようですが、ドキュメントを覗いてみると他にも便利な機能が色々とまとめられていたので、本記事ではその辺を整理してみました。
なお、Joblibはpipでインストールできます。
pip install joblib
並列化
下記の例では平方根を返す関数(math.sqrt)を並列化しています。
from joblib import Parallel, delayed
from math import sqrt
out = Parallel(n_jobs=2)(delayed(sqrt)(i) for i in range(100))
print(out)
# [0.0, 1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979, ...
ポイントは、n_jobs=2でコア数を指定しているところです。
n_jobs=1でコア数が1、n_jobs=2でコア数が2になります。
もちろん、コア数が多ければ多いほど高速になります。
またコア数の上限は環境に依りますが、n_jobs=-1とすることで自動的に上限のコア数がセットされます。
メモ化
下記の例では平方根を返す関数(math.sqrt)をメモ化(Wikipedia)しています。
from joblib import Memory
import math
cachedir = "./memory_cache"
memory = Memory(cachedir, verbose=0)
@memory.cache
def calc(x):
     print("RUNNING......")
     return math.sqrt(x)
print(calc(2))
print(calc(2))
print(calc(5))
# RUNNING......
# 1.41421356237
# 1.41421356237
# RUNNING......
# 1.73205080757
ポイントは、関数を@memory.cacheでデコレートしているところです。
デコレートした関数の出力結果に注目してみましょう。
1回目の実行では、引数2を与えて通常通り計算が行われています。
しかし、同じ引数(2)を与えた2回目の実行では、関数の中で計算は行われず計算結果だけが返ってきていることがわかります。
そして、1回目や2回目と異なる引数(5)を与えた3回目の実行では、今度は関数の中で計算が行われた上で計算結果が返ってきています。
このような挙動を特定の関数に与えるテクニックをメモ化と言います。
重複する引数による関数の再計算を防ぐことで、特に同じ引数が頻出する場面(フィボナッチ数列など)で高速化が期待できます。
直列化 〔シリアライズ〕
※ここでの直列化はオブジェクトのバイナリ列への変換を指します。
下記の例では平方根を返す関数(numpy.sqrt)が返したリストを直列化(Wikipedia)しています。
import joblib
import numpy as np
out = np.sqrt(np.arange(1024)) 
filename = "./pydata"
with open(filename, "wb") as f:  
    joblib.dump(out, f, compress=3)
    
with open(filename, "rb") as f:  
    loaded = joblib.load(f)
print(loaded)
# [  0.           1.           1.41421356 ...,  31.95309062  31.96873473  31.98437118]
流れとしては、
- 関数(numpy.sqrt)がリストを出力する(もちろん関数は何でもよい)
- 
joblib.dumpを使ってリストを圧縮して./pydataに保存する(compressで圧縮率の変更が可能)
- 
joblib.loadを使って圧縮データから元のリストを復元する
ということを行なっています。
まとめ
| 項目 | 利用 | 備考 | 
|---|---|---|
| 並列化 | joblib.Parallel | 同時に複数の演算処理を実行する | 
| メモ化 | joblib.Memory | 計算結果を一時保存し、重複する引数による関数の再計算を防ぐ | 
| 直列化 | joblib.dump,joblib.load | 大容量の計算結果を圧縮して保存する(取り出す) | 
Joblibで素敵なPythonライフを!