背景
- TensorFlow GPU版の評価環境において、tf.truncated_normal()を用いて、大量の乱数データ生成を試みるとエラーになることがわかった。
- 他の処理においても、GPU環境でのみエラーが多発し、ハードウェア的な制約が原因の可能性も考えられ、すぐに解決することが難しいと感じた。
- 気軽にGPU資源を活用するために、処理によってCPUとGPUを使い分ける必要があると感じ、その方法を調査した。
環境
- iMac14,2
- Intel Core i7
- 3.5 GHz
- プロセッサー数: 1
- コア数: 4
- システムメモリ: 8 GB
- NVIDIA GeForce GTX 775M
- VRAM: 2048 MB
- TensorFlow 1.10.0 (GPUを利用設定でソースからコンパイル)
データ処理の設計について
ドライブ、システムメモリ、VRAMで容量が異なり、各デバイスの長所を活かして処理するためには、各デバイスの性能を理解して、設計を工夫する必要があると考える。
処理の流れ
以下のような構成のサンプルを作成した。データ生成処理については、ドライブからデータ読み込む処理に、置き換える予定だ。
- tf.truncated_normal()で複数のデータを生成(CPU)
- このデータがVRAMの容量を越えてもエラーにならないことを期待する
- VRAMで処理できる容量にスライスする(CPU)
- スライスされたデータをtf.multiply()する(GPU)
TensorFlow の実装方法
処理デバイスの切り替え
- 以下のメソッドの引数でデバイス名を指定する
Graph.device()
# 以下のラッパーを使い実装することも可能
with tf.device(DEVICE_NAME):
pass
デバイス名の一覧の取得
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
処理されるデバイスを確認するためのログの出力
設定方法
- 以下の設定で、コンソールログに出力される
tf.Session(config=tf.ConfigProto(log_device_placement=True))
ログ出力の例
- TruncatedNormalはCPU、multiply_operatorはGPUに設定されたことが確認できる
image_generator/TruncatedNormal: (TruncatedNormal): /job:localhost/replica:0/task:0/device:CPU:0
multiply_operator: (Mul): /job:localhost/replica:0/task:0/device:GPU:0
実行結果
CPU と GPUで処理を切り替えたときのアプリケーションログ
- 乱数の生成:CPU
- この処理をGPUに指定するとエラーになることを確認
- 乱数の生成の処理時間
- multiply演算:GPU
- multiply演算の処理時間
start: generate images. /device:CPU:0
finished: generate images. 36.227976999999996 sec
start: multiply operations. /device:GPU:0
finished: multiply operations. 35.92272199999999 sec
GPU版で、デバイス指定を全てCPUにしたときのアプリケーションログ
- multiplyの演算において、GPUを指定したときよりも時間がかかるという結果が得られた
start: generate images. /device:CPU:0
finished: generate images. 38.002104 sec
start: multiply operations. /device:CPU:0
finished: multiply operations. 108.50434299999999 sec
macOS のGPU使用率のスクリーンショット
- macOSのGPU使用率のモニターツールでGPUの使用を確認した
- デバイスの指定をGPUに設定したときのみ、モニターが大きく反応した
- デバイスの指定が正常にされていることが期待できる結果となった
考察
- GPUとCPUで処理を切り替えることで、GPU資源を有効活用しやすくなると感じた。
- 実現可能なのかは、別途、調査が必要だが、CPUでのファイルのロードを分割し、ロードが完了したデータから先にGPUに演算させるような構成を取ることで、効率を上げることができるのではないかと考えた。
- システムメモリ、VRAMへのデータの割り当て状況についての確認方法を模索したい。