深層学習で学習やるならNVIDIA一択？いや、AMDという選択肢がありますよ

## はじめに
本稿の内容は、某イベントで私が頒布した頒布物の内容を一部転載し、最新の情報(2018/05現在)へと対応した内容をまとめたものとなります。

*(2019/01/28修正)*
ROCm2.0について、Linuxカーネル4.19以上でのインストール法、Tensorflow-rocmのPyPI登録等について加筆しました
*(2018/05/19修正)*
Radeon Open Computeの現状部分、およびインストール環境の制約に関して修正を行いました。

#TL;DR
・Radeon Open Compute（ROCm）というAMDの提供するGPU環境のオープンソースプロジェクトの一環と、それを利用したCudaライブラリのユーザーのポーティングで深層学習ライブラリがAMDのGPUでも動くよ！
・対応ライブラリが大幅に増え、ROCmを支えるGPUドライバもLinux公式カーネルに組み込まれるなど、環境のコモディティ化は大きく進んでるよ！
・ただ、まだまだバグが少なからず存在しているのでより良い環境となるためにみんなの参加を歓迎してるよ！

## Radeon Open ComputeとHIP言語
2012年のImageNetでの画像認識ベンチマークのテストで過去の特徴エンジニアリングを伴う機械学習モデルのスコアを大幅に突き放しての優勝から、深層学習は機械学習・コンピュータサイエンスの分野で大きな注目を集める事となります。
同時に深層学習に用いる各種ライブラリの発展の過程においてCuda環境というGPGPU開発環境を提供してきたNVidiaはかつてのゲーム用グラフィックチップの提供メーカーにとどまらない、GPGPUコンピューティングの雄として大きく飛躍することとなりました。

一方でGPGPUの分野ではOpenCLを用いたAMDは、大きくこの分野において後れを取ることになりました。ゲーミング分野においても、DirectX12への移行が部分的にとどまったこともあり二番手にとどまっていたAMDは、GPU環境の開発において大きな奇策を打つことになりました。
「基本的にプロプリエイタリなドライバ基盤の元で動作していたグラフィックアクセラレータを、ハードウェアにごく近い低位層の規格まで解放しGPUドライバ・およびその開発アプリケーションの成熟を狙う」GPUOpenプロジェクトを発表しましたが、その一環として「GPU を用いたコンピューティングの活性化を企図し、過去のCuda 開発資産をソフトウェアの書き換えをほとんど行うことなく活用できる、オープンソースのプロジェクトを展開する」というプロジェクトの声明として「Boltzmann Initiative」を提唱しました。Boltzmann Initiativeで提示された、RadeonOpenComputeの構成は以下のようになっています。

![ROCm環境](https://rocm.github.io/images/ROCm_Stack.png "ROCm公式ホームページより")
[^1]

オープンソースなGPGPUアクセラレーション基盤として、専用のグラフィックドライバを含むROCkカーネルに、Cudaコンバージョンのデバイス側への低位の中間言語への翻訳を行うHCCと、CudaコンバージョンとしてCuda開発言語 互換の処理を記述するHIP、そしてのちにはCuDNN相当のニューラルネットで用いられる畳み込み演算をはじめとした行列算のアクセラレーションを担うMIOpen、以上を統合した環境がRadeonOpenComputeです。

RadeonOpenCompute(以下ROCmと表記)の取り組みは、発表から幾度か注目を集める事となります。「Caffeのソースコードの99パーセントを書き換えることなく、100行程度のコードの修正でAMD環境でもCaffeが動作する」というSC16でのAMDの発表[^2]はNvidia社GPUからのAMD社GPUへの移行に大いに期待を抱かせるものでありましたし、2017年11月のNVidia社のEULA改訂に伴う「ワークステーション環境におけるコンシューマ向けGPU利用制限」はNVidia社の規約に振り回されることへの危機感を覚えるユーザーに逃避先としてのAMD社GPUの利用を検討させるものとなりました。
しかし、当時のROCmは環境のインストール、および対応ライブラリ両者の未成熟もあり、関心を寄せるユーザーの期待を裏切るものとなっていました。それに伴い、ROCmへの注目も大いに後退したものと考えられます。

## ROCmを取り巻く環境(2019年1月現在)

2018年11月のAMD社イベントでROCm2.0が発表されました。ROCm2.0の特徴としてROCmカーネルの起動時のオーバーヘッドの削減や、MIOpenでのニューラルネット演算向けのFuse-Matrixの追加がうたわれました。この事でROCmの実行速度がより速くなることが期待されています。


(2018年5月頃の環境) 
>ROCmへの注視がされなくなる一方で、ROCmは着実に発展してきました。Cudaを開発言語の多くがCuda Toolkitで開発されている現状を踏まえてか、
>2017年からは公式レポジトリにCu*　Toolkit相当のBLAS, FFT,　Eigen他のツールキットが登録され、更新が行われています。
>また昨年2017年12月のROCmバージョン1.7においてDKMSを用いたカーネル管理が行われるようになり、専用のカーネルではなく公式のLinux最新カーネルに追従したまま利用ができるようになりました。
>ROCkカーネルが管理する専用グラフィックドライバKFD（Kernel fusion Driver)はLinuxカーネル4.17でLinux公式のデバイスドライバとなります。

>ROCm環境下で動作する深層学習ライブラリに関しても大きな進展がありました。四月初頭に更新されたMIOpenバージョン1.3において、再帰的ニューラルネットのサポート対応を発表、LSTMやGRUといったネットワークの演算もAMDGPUの恩恵が受けられるようになりました。
>ROCmで動作する深層学習ライブラリに関しても、公式のブランチから遅れること半年でTensorFlowがバージョン1.3のモデルをベースにHIPポーティングされたことを皮切り[^3]としてHIPポーティングがなされたPyTorchがROCm公式レポジトリに追加され[^4]、
>またCuPyもHIPへの対応を企図している[^5][^6]状況にあります。


## ROCm環境のインストール

ROCm環境の導入は現在では非常に容易に行えます。ただし、現在のところ利用できるハードウェアに関しては次のような制限が設けられております。

`* PCI express3.0 Atomicに対応したCPU（Haswell以降のIntel社製CPUまたはAMD Ryzenプロセッサ）` 
`* Fiji(例:R9 nano)、Polaris（例:Radeon RX4X0 または　RX5X0シリーズ）、Vega（例:Vega 64）アーキテクチャのAMD GPU `
`* ノートパソコン向けGPUでの動作は現在保証しない `

以上を踏まえた上で、以下のコマンドでROCmの導入は可能になります。
ただし、2018年5月現在最新の開発ブランチとなるROCm1.8ではPCIe3.0 Atomicへの対応は必要条件には含まれなくなり、Vega搭載CPUなど動作条件の緩和が図られる見込みです。
以下の記事から、「Vega搭載CPUでROCmを動かす」事を目標としていることが見て取れます。
[MonoIstの記事より](http://monoist.atmarkit.co.jp/mn/articles/1805/11/news049.html)

まずはROCmの公式レポジトリを登録します。aptにROCmレポジトリの内容を登録したら、それらをaptに反映させます。

```bash:shell
$ wget -qO - http://repo.radeon.com/rocm/apt/debian/rocm.gpg.key | sudo apt-key add 
$ sudo sh -c ’echo deb [arch=amd64] http://repo.radeon.com/rocm/apt/debian/ xenial main\ > /etc/apt/sources.list.d/rocm.list’
$ sudo apt-get update 
```

ROCmのレポジトリから、ROCkカーネルおよびROCmのOpenCL向け開発環境をダウンロードします。KFDグラフィックドライバの
管理のため、ビデオデバイスのグループユーザーとアカウントの紐づけを行います。

```bash:shell
$ sudo apt-get install rocm-dkms rocm-opencl-dev
$ sudo usermod -a -G video $LOGNAME
```

#### Linux 4.17以上でのKFD有効化について(2019/01/28加筆)

先述の通り、ROCm向けのGPUデバイスドライバ「KFD」はLinux4.17からの公式カーネルとの統合を目指して開発メンバーは活動しておりましたが、昨年無事に公式デバイスドライバとしてカーネルに統合されました。
たとえばUbuntu18.10のようなデフォルトからLinux kernel4.17を用いるディストリビューションであったり、既存のディストリビューションのカーネルを4.17以上とした場合には
Dynamic kernel Managementでドライバを管理するだけではなく、直接カーネル上のデバイスドライバを利用することも出来ます。

```bash:shell
sudo apt install rocm-dev
echo 'SUBSYSTEM=="kfd", KERNEL=="kfd", TAG+="uaccess", GROUP="video"' | sudo tee /etc/udev/rules.d/70-kfd.rules
```

なお、DKMSによるデバイスドライバの管理と、Kernel上のデバイスドライバを利用するのでは一長一短が存在している事が、現在公式GitHubには記載されております。
(https://github.com/RadeonOpenCompute/ROCm#rocm-support-in-upstream-linux-kernels) 

(加筆終わり)

そして、任意で深層学習ドメイン向けのアクセラレータMIOpenをインストールします。今回はCuda環境下で開発されたライブラリをHIPへポーティングしたものを対象とするため、次のように入力します。

```bash:shell
$ sudo apt-get install miopen-hip miopengemm
```
最後に、ROCm関連の環境変数を登録すれば完了です。HCCコンパイラを用いたコードのコンパイルも行うため、以下のような環境変数を
.bashrcといったユーザー向けのシステム変数保管先に記載をしておくのが望ましいでしょう。

```bash:.bashrc
export ROCM_PATH=/opt/rocm
export HCC_HOME=/opt/rocm/hcc
export HIP_PATH=/opt/rocm/hip
export PATH=$HCC_HOME/bin:$HIP_PATH/bin:$PATH

```

以上で準備は完了です。

## HIPポーティングライブラリのインストール

以下に、現在HIPポーティングが公開されているライブラリのインストール方法を紹介します。なお、システム上のPythonにインストールするのではなく、VirtualEnv等を用いて仮想環境を分離することを強く推奨します。

### TensorFlowのインストール

#### コンパイル済みTensorflow Wheelのインストール(19/01/28追記)

去る2018年の10月頃にTensorFlow公式のMediumでROCm向けTensorflow1.8の照会がなされたのち、ROCm向けTensorflowのビルド済みWheelはPyPI(Python Package Index)で提供がなされるようになりました。ROCm向けのTensorflowはpipからのインストールも可能になりました。

```bash:shell
$ pip install tensorflow-rocm
```
(加筆終わり)

#### AMD提供Tensorflowビルド済みWheelのインストール(旧版)

Tensorflow のインストールに当たっては、現在Python2およびPython3共にWheelパッケージを提供しています。
今回はPython3のパッケージのインストール法を記載します。
Python2のインストールに当たっては"cp35"の部分を"cp27"に、"cp35m"の部分を"cp27mu"に置き換えて実行してください。

```bash:python3版
$ wget  http://repo.radeon.com/rocm/misc/tensorflow/tensorflow-1.3.0-cp35-cp35m-linux_x86_64.whl
$ pip install tensorflow-1.3.0-cp35-cp35m-linux_x86_64.whl && rm tensorflow-1.3.0-cp35-cp35m-linux_x86_64.whl
``` 

 * (python2.7版のTensorflowインストール)

```bash:Python2.7版
$ wget  http://repo.radeon.com/rocm/misc/tensorflow/tensorflow-1.3.0-cp27-cp27mu-linux_x86_64.whl
$ pip install tensorflow-1.3.0-cp27-cp27mu-linux_x86_64.whl && rm tensorflow-1.3.0-cp27-cp27mu-linux_x86_64.whl
``` 

* Pytorchのインストール

```bash:PyTorch
$ git clone https://github.com/ROCmSoftWarePlatform/pytorch && cd pytorch
$ pip install -r requirements.txt
$ python setup.py install
```

## 終わりに

以上駆け足になりましたが、2018年現在のAMDGPUを用いた深層学習環境の構築について紹介していきました。
個人的な感想を言うとするならば、現在のROCm周辺の発展は2015年から2016年くらいまでのCuda環境での深層学習ライブラリ開発の勃興期から、それ以降のコモディティ化するまでの数年間の流れを圧縮したような形で、往時での開発環境の差異を埋めインストールを容易にする努力を見ていた身としては興味深いところがあります。
ROCm公式レポジトリでも、ハードウェア側の開発者を交えながら目まぐるしい勢いでバグチェックやソフトウェアの改善が進んでいるさまが見られます。
ただ、どうしてもバグをつぶすにはユーザーの利用が必要で、一方現在のROCm周辺はユーザーの一層の盛り上がりが欲しいところであります。

興味を持たれた方がテストすることを期待しています。

[^1]: Radeon Open Compute公式ホームページより転載
[^2]: https://www.amd.com/en-us/press-releases/Pages/rocm-platform-2016nov14.aspx
[^3]: https://github.com/ROCmSoftwarePlatform/tensorflow
[^4]: https://github.com/ROCmSoftwarePlatform/pytorch
[^5]: https://twitter.com/mitmul/status/981408674605404160
[^6]: https://github.com/cupy/cupy/pull/1094