conda を用いた python環境について、AMD EPYC(Ryzen) も含めて調べてみたのでまとめる。
Contents
背景
新しい開発環境が手に入ったのでセットアップすることになったが、
性能を律速する要因がいくつかあるのでシステム最適化を検討する。
オプションは以下。
- 以前触れたように Anaconda が色々アレなので、conda-forge ベースで構築する訳だが、
Anaconda のライブラリは各種最適化がなされており、numpy なども標準で MKL を使うようになっている。
一方、conda-forge の numpy は標準では openblas 版になっており、最適化具合が異なる。
環境によっては2倍程度の性能差になるという記事を見たような気もする。 - ところが上記の MKL の最適化は Intel の CPU に特に顕著であり、AMD ではまた事情が変わるようである。
このあたりについて調査する。
環境
今回セットアップする新環境と、特に MKLの比較のために、旧環境も併せて紹介する。
新環境
開発機
- CPU: AMD EPYC 7742 (64C128T, 2.25GHz, Rome) x2
- Memory: 1TB (64GB x16)
- GPU: NVIDIA A100 HGX NVLink x4
実運用機 (開発機の縮小版)
- CPU: AMD EPYC 7742 (64C128T, 2.25GHz, Rome) x1
- Memory: 512GB (64GB x8)
- GPU: NVIDIA A100 PCIe 40GB
旧環境
(他用途マシンの転用)
- CPU: Intel Xeon Gold 5115 (10C20T, 2.4GHz, Skylake) x2
- Memory: 192GB
- GPU: None
anaconda/miniforge
conda/python 環境
anaconda, miniforge について。
なるべく近い環境にそろえた。
旧 Intel 環境の詳細は割愛。
python | numpy | mkl/blas | |
---|---|---|---|
anaconda | 3.8.5 | 1.19.2 | mkl: 2020.2 |
miniforge | 3.8.8 | 1.20.2 | lib(c)blas: 3.9.0 libopenblas: 0.3.15 |
速度比較
numpy で 20000x20000 の行列について、乱数行列の生成と行列積に掛かる時間を調べた。
CPU | EPYC x2 | Xeon x2 | ||
python環境 | anaconda | miniforge | anaconda | miniforge |
乱数行列生成 | 5.3 | 5.4 | 6.3 | 6.3 |
行列積計算 | 14.3 | 11.6 | 32.8 | 32.8 |
- EPYC では anaconda/MKL, miniforge/openblas の差が見えない、というか miniforge の方が速い?
MKLは後半CPUロードが徐々に落ちる - EPYC(Ryzen) では MKL_DEBUG_CPU_TYPE=5 が必要という記述が散見されるが、
MKL 2020.2 では(実際に試したが)効果がなさそう。
特定の ver以降は参照していない(なくても遅くならず速い)という記載あり。 - Xeon でも anaconda/MKL, miniforge/openblas に差がなく、MKL が特段速いという訳ではない。
- 処理が単純なので難しいが、Xeon → EPYC でコア数は x6倍以上あるが、処理時間的にはそこまでは短くはならなかった。
ボトルネックによるオーバーヘッドかもしれないが、コア数倍ほどには速くならないかもしれない。
numpy/pytorch
今度は numpy と pytorch の違いについて。
python環境
miniforge ベース @ EPYCx2。
1 2 3 4 |
$ conda create -n xxx python=3.8.8 $ conda activate xxx $ conda install numpy $ conda install pytorch torchvision torchaudio cudatoolkit=11.1 -c pytorch -c nvidia |
なお、pytorch 導入時に(conda-forge channelにも関わらず) openblas が MKLに置き換わったようだ。
速度比較
numpy/pytorch で、さきほど同様 20000x20000 の行列について、乱数行列の生成と行列積に掛かる時間を調べた。
pytorch については、ついでに cuda による演算も試してみた。
numpy | pytorch(CPU) | pytorch(CUDA) | ||||
dtype | float64 | float32 | float64 | float32 | float64 | float32 |
乱数行列生成 | 5.1 | 2.4 | 6.8 | 4.1 | 1.8 | 1.8 |
行列積計算 | 9.4 | 5.0 | 10.6 | 5.2 | 0.50 | 0.49 |
- 一つ前の "2xEPYC x numpy" の結果と、今回の numpy倍精度は同じ処理のはずだが、なぜか若干速い。
conda-forge で MKL が入っているという、また異なる組み合わせが原因か??? - CPU だと pytorch より numpy の方が速かった
- ただし、pytorch はかなり簡単に CUDA での処理に切り替えることができ、単純計算は10倍以上速そう
- 単/倍精度浮動小数点演算という観点では、CPU はほぼ倍の処理時間で reasonable、CUDA は差が見えなかった。
NVIDIA A100 は、倍精度の演算も極端に遅くならず速いはずだが、差が無いというのはやや不思議。
(ゲーム用の GeForce などでは倍精度は極端に遅くなる)
負荷が軽すぎてオーバーヘッドのみをみている?
現状のまとめ
Anaconda のパッケージは最適化が進んでいるという記事を見かける一方、
Anaconda が使いにくくなるので conda-forge をベースとした環境を検討中であり、miniforge はその筆頭候補。
例えば標準で入る numpy は、MKL(by Intel) と OpenBlas を用いるという違いがあり、
特にそれが AMD EPYC ではどう効いてくるかわからなかったため、簡単なテストを行った。
20000 x 20000 程度の行列の簡単な計算速度を比較する限りでは、
anaconda/mkl, miniforge/openblas に大きな差は見られなかった。
AMD EPYC(Rome) においても、そして Intel系においても、今のところ conda-forge ベースでも問題なさそうである。
# それでも conda-forge はインストール完了まで結構時間が掛かるのに対して、Anaconda のレポジトリは動作が速いというメリットもあるとは思うが。
今後はもう少し実践的な複雑な処理についても比較・検証できたらと思う。