(以下の情報はすべて記事執筆時(2021/04)のものです)
この記事ではanaconda有償化の影響を回避しながら高速化されたIntel MKL版のnumpyを簡単にインストールする方法を解説します。
2020/04にanacondaが大規模商用利用ではanacondaとdefaultsチャンネルの使用を有償化したことは有名かと思います。
これにより仕事でIntel MKL版numpyを手軽にインストール出来なくなりそうだったので、利用規約に抵触しない形で簡単にIntel MKL版numpyをインストールする方法を調べ、まとめました。
scipy、scikit-learnの高速化版も見つけた方法でインストールが可能です。
尚、各位このブログを鵜呑みにするのではなく利用規約(Terms of Service)を各自で確認する様にして下さい。
TL;DR
- intelチャンネル版のnumpyのインストール方法を知りたい方はここのリンクから
- intelチャンネル版のnumpy、scipy、scikit-learn等をまとめてインストールするyamlを見たい方はここのリンクから
- TL;DR
- anacondaの利用規約
- Intelチャンネル版numpy
- まとめ
- 参考文献
anacondaの利用規約
anacondaの利用規約は「大規模な商用利用」を禁止
2020/04にanacondaの利用規約が改定され、「大規模な商用利用」ではanacondaの無償版を利用できなくなりました。 尚、ここでいう「大規模な商用利用」は利用規約の原文を読むと「規模が200人以上の営利団体による利用」と解釈できます。*1 *2
minicondaとdefaults以外のチャンネルの組み合わせは無償利用可能
しかしこの規約はanacondaとそれに類するもの一切合切の利用を禁止するものではありません。 anacondaのCEO曰く、
- minicondaとconda-forgeチャンネルの組み合わせは無償で利用できる*3
ですし、conda-forgeのブログには、
- この利用規約の変更はdefaultsチャンネルと
repo.anaconda.com
でホストされているその他のソフトウェアにのみ適用される*4
との記載があります。
つまりminiconda + defaults以外のチャンネルの組み合わせでは引き続き無償でanaconda相当の環境が使用できるわけです。
しかしconda-forge経由で入るnumpyはIntel MKL版ではない
ここまでだけ読むとじゃあminiconda + defaults以外のチャンネルを使えば何も問題ないじゃないかと思うかもしれません。 しかしanaconda(のdefaultsチャンネル経由)でインストールされたnumpyはIntel MKLを利用しているため、conda-forge(pip)で入れられるOpenBLASを使用したnumpyよりも早いということが知られています。*5*6 しかしconda-forgeでインストールできるnumpyはOpenBLAS版であるため、単純にminiconda環境に乗り換えただけでは今までより計算速度が遅くなってしまいます。
もちろん一から自分でビルドすれば有償化の影響を回避しつつIntel MKL版numpyをインストールできるのでしょうがそれは流石に面倒です。そこでIntel MKL版numpyを簡単にインストールする方法について調べてみました。
Intelチャンネル版numpy
intel公式がIntel MKL版を用意してくれている
調べた結果、Intelが公式にIntel MKL版numpyをintelチャンネルで以下に公開していることがわかりました。
intelチャンネルからnumpyをインストールする方法
以下にintelチャンネルからnumpyをインストールする方法を記載します。
尚、yamlの方ではchannel
にnodefaults
を設定してdefaultsチャンネルを利用しない(利用規約への抵触を避ける)様にしていますが、
minicondaも初期設定ではdefaultsチャンネルを使うようになっていますので、うっかりdefaultsチャンネルからパッケージをインストールしてしまわないように
conda config --remove channels defaults
でdefaultsチャンネルを取り除き、conda config --add channels conda-forge
でconda-forgeチャンネルを初期値に設定しておく
と良いでしょう。
CLIからインストールする場合
conda install -c intel numpy
yamlで仮想環境を作る場合
name: intel_numpy channels: - intel - nodefaults # defaultsチャンネルを使わないように設定 dependencies: - python=3.7 # Intelが配布しているnumpyは3.7までしか対応していない - intel::numpy
intelチャンネル版とdefaultsチャンネル版numpyの速度比較
ではdefaultsチャンネルとintelチャンネルのnumpyの違いは何なのでしょうか? どちらもIntel MKLを採用していると思われますが(明確な記載は発見できず)、Intel版は公式で配布されているだけあってさらなるチューニングがされている可能性も考えられます。 そこでintel、defaults、conda-forgeの3種のチャンネルからインストールしたnumpyの実行速度を比較してみることにしました。
実験はGCP上でIntel(R) Xeon(R) CPU @ 2.20GHzを使って行いました。
実行速度の比較にはIntel公式が使用していたコードを改変した以下のものを使用しました。
import numpy as np import time np.random.seed(8492) N = 6000 M = 10000 k_list = [64, 80, 96, 104, 112, 120, 128, 144, 160, 176, 192, 200, 208, 224, 240, 256, 384] def get_gflops(M, N, K): return M*N*(2.0*K-1.0) / 1000**3 np.show_config() for K in k_list: a = np.array(np.random.random((M, N)), dtype=np.double, order='C', copy=False) b = np.array(np.random.random((N, K)), dtype=np.double, order='C', copy=False) A = np.matrix(a, dtype=np.double, copy=False) B = np.matrix(b, dtype=np.double, copy=False) C = A*B start = time.time() C = A*B C = A*B C = A*B C = A*B C = A*B end = time.time() tm = (end-start) / 5.0 # 行列のKの大きさ、計算時間、GFLOPS print ('{0:4}, {1:9.7}, {2:9.7}'.format(K, tm, get_gflops(M, N, K) / tm))
結果は以下のグラフの通りです。
グラフを見るとIntel版の方が気持ちdefaults版より実行時間が短いように見えます。
この程度の差であればあまり気にしなくても良さそうですが、環境によってはdefaultsチャンネル版とOpenBLAS版で倍の性能差が出るとのことなので、Intelチャンネル版とdefaultsチャンネル版でももっと差がつく場合があるそうです。
なのでカリカリにチューニングする必要がある場合は積極的にIntelチャンネル版のnumpyを積極的に試して良いかもしれません。
逆に個人の趣味開発などでは利用規約が問題になることも無いでしょうし、わざわざintelチャンネル版を使わずずとも今まで通りdefaultsチャンネル版を使用すれば良さそうです。
scipy、scikit-learnも intelチャンネルに用意されている
ここまではnumpyだけの話をしてきましたが先程記載したIntelチャンネルを見ると判るように、他にも様々なパッケージがIntelチャンネルには用意されています。
中にはscipy、scikit-learnもあり、numpyと同様に通常のものより高速な動作が期待できます(実際にどれだけ早いのかは未確認ですが高速であることは間違いないようです)。*7
尚、scikit-learnの高速版を使用するにはdaal4py
もインストールしてpathを適切に設定する必要があることに注意して下さい(インストール時のlogを参照のこと)。
intelpython3メタパッケージを利用すれば複数パッケージをまとめてインストール可能
上記Intelチャンネル内の各種パッケージをまとめてインストールするためにintelpython3_core
、intelpython3_full
の2つのメタパッケージが用意されています。
これを利用して
conda install -c intel intelpython3_core
等とすることでIntelチャンネルのパッケージをまとめてインストールすることができます。
intelpython3_core
、intelpython3_full
の違いはパッケージの数だけ(勿論fullの方が多い)と思われます。
full版を入れるとなんとxgboostも一緒に入ります。
実際にIntelチャンネルを利用して環境を使用する際は、個別にnumpyなどを入れるのではなくintelpython3_core
を使用するのが効率的でしょう。
intelチャンネル版パッケージの問題点・不明点
自分の調査した限りここで紹介したIntel版のnumpy等の各種パッケージには以下の問題点・不明点があります
問題点:Windowsではpandasインポート時にエラーが出る
windowsでintelチャンネルのnumpyを入れた環境を作り、その後のその環境内でpandasをimportすると「numpyが正常にビルドされていない」というエラーが出てimportに失敗する現象を確認しています。
問題点:使えるPythonのバージョンが低い
記事執筆時点でのpythonの最新版は3.9ですが、Intelチャンネルの各種パッケージをインストールできる最大のバージョンは3.7です。
不明点:numpy以外のパッケージが通常版と比べてどれだけ早いか不明
これは私が実験していないだけなのですが、Intelチャンネル版のscipyとscikit-learnがどれだけpipやconda-forgeのものより早いかは不明です。
まとめ
以上ここまでanaconda有償化の影響を回避ししつつ、Intel MKL版のnumpyやその他の高速化されているであろうパッケージをインストールする方法についてまとめました。
使えるpythonのバージョンには制限があるものの、defaultチャンネル版よりも若干高速なnumpyとその他インテルが最適化してくれたであろうパッケージが使えるIntelチャンネルは良い代替案になりそうです。
最後に今回の調査内容を踏まえたおすすめの環境構築用のyamlを記して終わりにしたいと思います。
おすすめの環境構築用yamlファイル
name: intel-all channels: - intel # 優先的にintelチャンネルを利用するようにする - conda-forge # intelチャンネルにないパッケージはconda-forgeから入れる - nodefaults # defaultチャンネルを除外する dependencies: - python=3.7 # Intelが配布しているpkgは3.7までしか対応していない - intel::intelpython3_core # Intel® Distribution for Pythonを可能な限り使う
参考文献
- Intel® Distribution for Python
- Installing Intel® Distribution for Python* and Intel® Performance...
- Numpy/Scipy with Intel® MKL and Intel® Compilers
- pwang99 comments on I want to use Python commercially for free. Is Miniconda the best way to go (as opposed to Anaconda)?
- Anaconda | Sustaining our stewardship of the open-source data science…
- Anaconda | Terms of Service
- conda Numpyのようにscikit-learnも高速化する方法 - Qiita
- Anaconda パッケージリポジトリが「大規模な」商用利用では有償になっていた - Qiita
- Anaconda の NumPy が高速みたいなので試してみた - Morikatron Engineer Blog
- python - How update/remove conda-forge channel from Anaconda? - Stack Overflow
*2:Sustaining our stewardship of the open-source data science community
*3:I want to use Python commercially for free. Is Miniconda the best way to go (as opposed to Anaconda)?
*4:Package Distribution and the anaconda.com Terms of Service
*5:Anaconda の NumPy が高速みたいなので試してみた
*6:conda-forge版もpip版も明確にOpenBLASを採用しているであるという記述を見つけたわけでは無いが、一般にそう言われているのでその様に判断した
*7:https://qiita.com/sugulu_Ogawa_ISID/items/43efed6d8ccece677159