メインコンテンツへジャンプ

TensorFlow™ on Databricks

Illustration

GPU の使用

GPU(画像処理ユニット)は、3D グラフィックスに必要な計算を実行するために設計された、最新コンピュータのコンポーネントです。最も一般的な用途は、ビデオゲームにおいてアクションを実行することで、ユーザーにゲームを表示するためにポリゴンがどこに移動するかを計算します。基本的に GPU は、高度に並列化された計算を実行する小型プロセッサの大規模なアレイです。あなたは今、ミニスーパーコンピュータ* を使用しているといってもいいでしょう!

GPU の各「CPU」はかなり低速ですが、その数は多く、数値処理に特化しています。これは、GPU が同時に多数の単純な数値処理タスクを実行できることを意味します。幸運なことに、これこそが多くの機械学習アルゴリズムが必要としていることなのです。

GPU を持っていない場合は?

最新(過去 10 年)のほとんどのコンピュータには、マザーボードに内蔵されている場合を含め、何らかの GPU が搭載されています。このチュートリアルの目的には、それで十分です。

お持ちのグラフィックスカードの種類を知る必要があります。Windows ユーザーはこちらの手順に従うと確認できます。その他のシステムのユーザーは、各システムのマニュアルをご参照ください。

NVIDIA 社製グラフィックスカード以外のユーザー

他社製のグラフィックスカードもサポートされている可能はありますが、このチュートリアルは最新の NVIDIA 社製グラフィックスカードでのみテストしています。もし、ご使用のグラフィックスカードが別のタイプの場合は、NVIDIA 社製グラフィックスカードを購入、または借用して学習することをおすすめします。それがどうしても難しい場合は、お近くの大学や学校にサポートが可能かどうかを問い合わせてみてください。それでも問題が解決しない場合は、このまま読み進めて、代わりに標準的な CPU で作業してみてくださ。後日、学んだことを引き継ぐことができます。

* 注:実際には、スーパーコンピュータではありません。しかし、多くの点で幾分似ています。

GPU 対応 TensorFlow のインストール

もし GPU 対応の TensorFlow を以前にインストールしていない場合は、まず最初に行う必要があります。レッスン 1 の手順では、GPU のサポートを有効にするよう指示していません。

以前の環境を更新するのではなく、このために新しい Anaconda 環境を作成することをおすすめします。

始める前に

公式の TensorFlow インストール手順で、Anaconda のインストール手順に従ってください。レッスン 1 で行ったこととの主な違いは、GPU 対応バージョンの TensorFlow が必要だということです。ただし、この環境に TensorFlow をインストールする前に、CUDA と CuDNN で GPU が有効になるようにコンピュータをセットアップする必要があります。TensorFlow の公式ドキュメントには、この手順の概要が記載されていますが、最近の Ubuntu インストールをセットアップしようとしている場合は、このチュートリアルをおすすめします。主な理由は、執筆時点(2016 年 7 月)では CUDA はまだ最新の Ubuntu バージョン用に構築されておらず、プロセスがより手作業になるためです。

GPU の使用

実にシンプルです。少なくとも、構文的には。以下の構文を変更するだけです。

 

# Setup operations

with tf.Session() as sess:
    # Run your code

 

このように。

 

with tf.device("/gpu:0"):
    # Setup operations

with tf.Session() as sess:
    # Run your code

 

この新しい行は、新しいコンテキストマネージャーを作成し、TensorFlow に GPU 上でこれらのアクションを実行するように指示します。

具体例を見てみましょう。次のコードは、コマンドラインで指定されたサイズでランダムな行列を作成します。コマンドラインオプションを使用して、CPU または GPU 上でコードを実行できます。

 

import sys
import numpy as np
import tensorflow as tf
from datetime import datetime

device_name = sys.argv[1]  # Choose device from cmd line. Options: gpu or cpu
shape = (int(sys.argv[2]), int(sys.argv[2]))
if device_name == "gpu":
    device_name = "/gpu:0"
else:
    device_name = "/cpu:0"

with tf.device(device_name):
    random_matrix = tf.random_uniform(shape=shape, minval=0, maxval=1)
    dot_operation = tf.matmul(random_matrix, tf.transpose(random_matrix))
    sum_operation = tf.reduce_sum(dot_operation)


startTime = datetime.now()
with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as session:
        result = session.run(sum_operation)
        print(result)

# It can be hard to see the results on the terminal with lots of output -- add some newlines to improve readability.
print("\n" * 5)
print("Shape:", shape, "Device:", device_name)
print("Time taken:", datetime.now() - startTime)

print("\n" * 5)

 

次のコマンドラインで実行できます。

python matmul.py gpu 1500

これは、1500 平方の行列で CPU を使用します。CPU で同じ操作を実行するには、次を使用します。

python matmul.py cpu 1500

GPU に対応したコードを実行した際に最初に気づくのは、通常の TensorFlow スクリプトに比べて出力が大幅に増加することです。以下は、操作の結果を出力する前に、私のコンピュータが出力したものです。

 

I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcudnn.so.5 locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:108] successfully opened CUDA library libcurand.so locally
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:925] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_init.cc:102] Found device 0 with properties: 
name: GeForce GTX 950M
major: 5 minor: 0 memoryClockRate (GHz) 1.124
pciBusID 0000:01:00.0
Total memory: 3.95GiB
Free memory: 3.50GiB
I tensorflow/core/common_runtime/gpu/gpu_init.cc:126] DMA: 0 
I tensorflow/core/common_runtime/gpu/gpu_init.cc:136] 0:   Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:838] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 950M, pci bus id: 0000:01:00.0)

 

あなたのコードがこれと同じような出力を生成しない場合、GPU 対応の TensorFlow を実行していません。または、ImportError: libcudart.so.7.5: cannot open shared object file: No such file or directory のようなエラーになる場合は、CUDA ライブラリが正しくインストールされていません。システムに CUDA をインストールする手順に戻る必要があります。

上記のコードを CPU と GPU の両方で実行し、数値を少しずつ増やしてみてください。1500 から始めて 3000、4500 と試していきます。CPU はかなりの時間がかかりますが、GPU はこの操作では非常に高速であることがわかります。

複数の GPU がある場合は、どちらでも使用できます。GPU はゼロインデックスであり、上記のコードは最初の GPU にアクセスします。デバイスを gpu:1 に変更すると、2 番目の GPU が使用され、以下は同様になります。計算の一部をある GPU に送り、一部を別の GPU に送ることも可能です。さらに、同じような方法でマシンの CPU にアクセスすることもできます。cpu:0(または別の番号)を使用します。

GPU に送信するべき操作の種類は?

一般的に、「この数学的演算を何千回も行う」といった処理のステップを記述できる場合は、GPU に送信します。例には、行列の乗算や逆行列の計算が含まれます。実際、多くの基本的な行列演算は、GPU にとって最有力候補です。大まかなシンプルなルールとして、その他の操作は CPU で行う必要があります。

デバイスの変更や GPU の使用にもコストがかかります。GPU は、コンピュータの他の部分に直接アクセスできません。(もちろんディスプレイは除きます。)そのため、GPU 上でコマンドを実行する場合は、全てのデータを GPU にコピーしてから操作を行い、その結果をコンピュータのメインメモリにコピーし直す必要があります。TensorFlow は内部でこの処理を行うためコードはシンプルですが、作業は実行する必要があります。

全ての操作を GPU で実行できるわけではありません。次のようなエラーが出る場合は、GPU で実行できない操作を行おうとしています。

 

Cannot assign a device to node 'PyFunc': Could not satisfy explicit device specification '/device:GPU:1' because no devices matching that specification are registered in this process;

 

この場合、手動でデバイスを CPU に変更するか、TensorFlow が自動的にデバイスを変更するように設定できます。これを行うには、構成で allow_soft_placementTrue に設定します。セッション作成の一部として行われます。プロトタイプは次のようになります。

 

with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)):
    # Run your graph here

 

また、GPU を使用する際には、デバイスの配置をログに記録することをおすすめします。これにより、異なるデバイスの使用に関する問題を簡単にデバッグできるようになります。これにより、デバイスの使用状況がログに出力され、デバイスがいつ変更され、それがグラフにどのように影響するかを確認できるようになります。

 

with tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)):
    # Run your graph here

 

  1. TensorFlow 用の GPU を使用するようにコンピュータをセットアップします。(最新の GPU がない場合は、使用できるコンピュータを探します。)
  2. GPU 上で前回の演習ソリューションを実行してみましょう。GPU で実行できる操作とできない操作を確認します。
  3. GPU と CPU の両方で演算を使用するプログラムを構築します。レッスン 5 のプロファイリングコードを使用して、GPU へのデータ送信と GPU からのデータ取得の影響を推定します。
  4. コードを送ってください!コードの例や、TensorFlow の使い方、発見したトリックがあれば是非教えてください。