X

Big Data、Data Integration、Data Lakeに関するテクノロジー、製品・サービス情報、セミナー情報などをお届けします

TensorFlowにおけるGPUの威力

はじめに

かつてグラフィックス・コンピューティングという限られた用途に利用されていたGPUはディープラーニングというテクノロジーのトレンドよってここ十数年で一気に市場を拡大しました。

GPU(グラフィックス・プロセッシング・ユニット)は、その名の通りグラフィックス処理を実行するためのプロセッサです。自然界では、人間は、視点と光源と物体の位置関係によって、その物体の色、形、動きを認識します。この3次元空間で起こる仕組みを、そのままコンピュータの中に取り込んだ技術がいわゆるコンピュータ・グラフィックス(CG)です。2次元の画面に疑似的に3次元空間をつくりだすこのCGという技術は、コンピューターが単純なベクトル演算を延々とこなし続けることによって成り立っています。必然、多種類の複雑な演算器を備えたCPUではこのワークロードには不都合なため、ベクトル演算器だけを切り出しそれ専用のプロセッサを作ろう、というのがGPUの生い立ちです。GPUは非常に大量のベクトル演算を高速に処理することができる反面、その他の処理、たとえばOSを起動する、ということさえできないプロセッサであるのはこれが理由です。

一見したところ、CGとディープラーニングには何も接点がない技術に思われるのではないでしょうか。商品の売り上げを予測したり、ショッピングサイトでオススメ商品をレコメンドしてくれるプログラムの処理がなぜCGの技術と同じなのかと。ディープラーニングの処理では、あらゆる情報をベクトルに変換し統計アルゴリズムにかけて分析するというプロセスになり、実は、これは大量のベクトル演算を扱うCGと同じタイプのワークロードとなるからです。この大量のベクトル演算をGPUに丸投げしてしまうことで、CPUよりも高速に分析処理を完了させることが期待できます。

本記事では、TensorFlowのワークロードを使って、OCIのGPUとCPUの性能を比較し、いかにGPUが有効であるかを確認してみたいと思います。


GPUインスタンスの作成

OCIのマニュアル Using NVIDIA GPU Cloud with Oracle Cloud Infrastructure に沿ってGPUインスタンスを作成します。今回は一番小規模なインスタンスである VM.GPU3.1 というシェイプを使ってみます。このシェイプのスペックは下記の通りです。

VM.GPU3.1のスペック概要
- インスタンスタイプ:仮想マシン
- CPU : 2.0 GHz Intel Xeon Platinum 8167M x6
- GPU : Nvidia Tesla V100 x1
- Memory : 90GB


インスタンス作成後ログインし、GPUを確認します。

ubuntu@vm-gpu:~$ nvidia-smi
Tue Dec  3 09:42:15 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.40.04    Driver Version: 418.40.04    CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  Off  | 00000000:00:04.0 Off |                    0 |
| N/A   39C    P0    36W / 300W |      0MiB / 16130MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

Nvidia V100が一枚登載されていることがわかります。まだ何も処理を実行していないのでGPU使用率は0%であることが確認できます。


ディープラーニングのワークロードを実行

Nvidia社の NGC からTensorFlowの実行環境が整ったコンテナをプルし、起動します。 

 
ubuntu@vm-gpu:~$ docker pull nvcr.io/nvidia/tensorflow:17.10
ubuntu@vm-gpu:~$ nvidia-docker run --rm -it nvcr.io/nvidia/tensorflow:17.10

TensorFlowに附属するチュートリアルの一つmnist_deep.pyを実行します。これは畳み込みニューラルネットワークと呼ばれる、統計アルゴリズムを使った分類器により、任意の画像データが正解画像データと同じものかを予測するディープラーニングのワークロードです。画像、すなわちピクセルの二次元配列から特徴を抽出し、別の画像から特徴が一致する部分を検出する、という処理を繰り返し行うワークロードになります。このプロセスはあまり複雑なロジックではありませんが、比較的負荷の高いベクトル処理が行われるため、GPUの効果が期待できると思います。

※畳み込みニューラルネットワークの詳細にご興味がある方は 「How do Convolutional Neural Networks work?」 をご参照ください。

mnist_deep.pyファイルのディレクトリまで移動し、同プログラムを実行します。

root@ca5b5d75045d: cd /opt/tensorflow/tensorflow/examples/tutorials/mnist
root@ca5b5d75045d: time python mnist_deep.py
...................
step 100, training accuracy 0.76
...................
step 19900, training accuracy 1
test accuracy 0.9923

real 1m8.576s
user 1m23.545s
sys 0m24.040s

精度約99.23%で処理時間は約1分8秒という結果になりました。

GPUの無効化

同じ処理をCPUで実行した場合と比較するために、GPUを無効化します。このインスタンスはGPUが一つだけ登載されていますので nvidia-smiコマンドで確認すると、GPUのIDは"0"となります。 CUDA環境では環境変数CUDA_VISIBLE_DEVICESにこのIDを指定することで利用するGPUを変更することができます。下記のように、この環境変数に何も値を入れないことにより、GPUを無効化します。

root@c1c0b8010327:/workspace# export CUDA_VISIBLE_DEVICES=""

(戻すときは # unset CUDA_VISIBLE_DEVICES です)

pythonからGPUが認識されていないことを確認します。下記2行のプログラムの出力に確認できます。 

from tensorflow.python.client import device_lib
device_lib.list_local_devices()

以下の実行例のようにエラーが出力される場合はGPUが無効化できています。

root@c1c0b8010327:/workspace# python
.......(中略)...........
>>> from tensorflow.python.client import device_lib
>>> device_lib.list_local_devices()
2019-12-04 05:05:49.830082: E tensorflow/stream_executor/cuda/cuda_driver.cc:406] failed call to cuInit: CUDA_ERROR_NO_DEVICE
.......(中略)...........
因みに、GPUが認識されている場合は以下のようなメッセージが出力されているはずです。
root@c1c0b8010327:/workspace# python
.......(中略)...........
>>> from tensorflow.python.client import device_lib
>>> device_lib.list_local_devices()
2019-12-04 08:46:09.024885: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:893] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
.......(中略)...........


GPU無効状態で計測実行

再度mnist_deep.pyを実行します。
root@ca5b5d75045d: time python mnist_deep.py
...................
step 100, training accuracy 0.76
...................
step 19900, training accuracy 1
test accuracy 0.9926

real 18m44.608s
user 139m47.511s
sys 26m7.055s

精度約99.26%、処理時間は18分44秒という結果になりました。

 

結果の比較

GPUはCPUと比較して処理時間が約16陪短いという結果になりました。

 

また、GPU、CPUの使用率としては以下の通りです。
- GPU有効時は、CPUが平均約12%、GPUは平均約52%の使用率
- GPU無効時は、CPUが平均約73%、GPUは当然0%の使用率

 

 

このグラフには掲載していませんが、ネットワークやメモリにボトルネックは見られませんでしたので、結果としてGPUが有効に利用されていることが確認できました。


まとめ

Nvidia V100 GPUベースのVMインスタンスはIntel Xeon CPUベースのVMインスタンスと比較して、約10倍弱も高価になりますが、今回のワークロードでは16陪以上の性能を手に入れることができるということにもなります。GPUインスタンスはもちろん高価ですが、ここまで効果が大きいわけですから、予算に収まるようであれば時間をお金で買うという考え方はアリかと思います。(※参考までに、こちらがGPUの価格とスペックになります。)

また、オンプレミスではGPUサーバーを購入するのに数百万円から数千万円というコストがかかるわけですが、クラウドでは初期投資を抑えながら従量課金という点も魅力的です。特にディープラーニングという分野は、ビジネス的効果が見込まれない場合、最終的にはイグジットするという選択肢もありえるプロジェクトになるため、そのリスクヘッジをクラウドで、という考え方はごく自然かと思います。

 

Join the discussion

Comments ( 1 )
  • m Saturday, January 25, 2020
    とても有用な記事をシェアしてくださりありがとうございます。2点質問があります。

    スクリプト実行時のCPU, GPUの使用率のグラフがありますが、どのような方法で取ってきて可視化したものでしょうか。
    また、
    > ネットワークやメモリにボトルネックは見られませんでした
    とありますが、例えばどのような方法で検証可能なのでしょうか。

    個人的にGPUを導入しても計算速度が改善しない状況にあり、自分の環境でのボトルネックを探る際の参考にさせていただきたいという意図です。よろしくお願いします。
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.