#RubyKaigi 2018 LTで「Improve Red Chainer and Numo::NArray performance」というタイトルで発表しました。

naitoh.hatenablog.com で記載した通り、RubyKaigi 2018 LT で発表させて頂きました。

内容は、今自分が py2rb.py を使用して取り組んでいる Red Chainer のポーティング作業中に気づいた、 Red ChainerNumo::NArray に対する処理速度改善のための取り組みです。

具体的には、下記になります。

  • Red Chainer の行列計算(Numo::NArray)の精度を DFloat→SFloat に変更することで mnist 1epoc の学習処理を 1.73倍速くした。
  • Numo::NArrayの inplace と BroadCast 計算の処理速度を最大3.8倍速くした。
  • 残りの下記2点のボトルネックの修正が完了すれば、Red Chainer は python Chainer 2.0 と比較してmnist 1epoc の学習処理が 16%遅いところまで処理速度が改善されること。 (CPU比較)
    • 「転置行列に対する dot 計算 "x.dot(w.transpose)"が遅い」=> view に対する dot が遅いので、dup で配列のコピーを作る"x.dot(w.dup.transpose)"ことで暫定対処可能。
    • 平方根"Numo::NMath.sqrt "が遅い」=> SIMD演算を使用することで対処可能 (暫定実装で確認済)。

最後、時間切れでお伝えしきれませんでしたが、Red Chainer の処理速度の改善が進んできているので、興味がある方はぜひ Red Chainerをさわってみて、RubyDeep Learning を始めてみるきっかけになればと考えています。

なお、OpenBlas を用いた Red Chainer の環境は下記のようにして構築しました。(CentOS7 x86_64環境) ご参考までに。

  • numpy を使って、OSにインストールされている OpenBlas のライブラリパスを確認。
$ python
Python 2.7.5 (default, Aug  4 2017, 00:39:18) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy.distutils.system_info as sysinfo
>>> sysinfo.get_info('atlas')
/usr/lib64/python2.7/site-packages/numpy/distutils/system_info.py:624: UserWarning: 
*********************************************************************
    Could not find lapack library within the ATLAS installation.
*********************************************************************

  self.calc_info()
{'libraries': ['tatlas'], 'library_dirs': ['/usr/lib64/atlas'], 'define_macros': [('ATLAS_WITHOUT_LAPACK', None)], 'language': 'c', 'include_dirs': ['/usr/include']}
>>> sysinfo.get_info('openblas')
{'libraries': ['openblas', 'openblas'], 'library_dirs': ['/usr/lib64'], 'define_macros': [('HAVE_CBLAS', None)], 'language': 'c'}
>>> sysinfo.get_info('lapack')
{'libraries': ['lapack', 'lapack'], 'library_dirs': ['/usr/lib64'], 'language': 'f77'}
>>> sysinfo.get_info('mkl')
{}
>>> 
  • OpenBlas が入っていなければ、インストールしてください。rpm コマンでも OpenBlas のパスがわかります。
# yum install openblas-devel.x86_64
# rpm -ql openblas-devel.x86_64
 (略)
/usr/lib64/libopenblas.so
  • numo-narray と numo-linalg をインストール (nomo-linalg のインストール時に、上記で確認した OpenBlas のパスを指定。)
$ rvm 2.5.1
$ gem install numo-narray
$ gem install numo-linalg -- --with-openblas-dir=/usr/lib64/  --with-atlas-dir=/usr/lib64/   --with-lapack-lib=/usr/lib64/
$ ruby  -r numo/linalg -e "p Numo::Linalg::Loader.libs"
["libopenblaso.so", "liblapacke.so"]
  • red-chainer をインストール、git clone、minist 実行。
$ gem install red-chainer
$ git clone https://github.com/red-data-tools/red-chainer.git
$ cd red-chainer
$ ruby  -r numo/linalg/use/openblas examples/mnist.rb --epoch 1
epoch       main/loss   validation/main/loss  main/accuracy  validation/main/accuracy  elapsed_time
1           0.193477                          0.94225                                  28.5615       

※ Red Chainer に転地行列のdotのdupと、Numo::NArrayに平方根に対するSIMD処理の実装(あと、inplace の最適化)を反映して計測した mnist の結果です。