TensorFlowはCaffeよりも早いのか?(前編)

caffe
前回の記事の関係でconvnet-benchmarksを訪れた際、TensorFlowがCaffeよりも上位にランキングされるという気になるベンチマーク結果がありました。CNNに関する処理速度は、ベンチマーク結果の逆の感覚があるので調査してみました。これが長い旅の始まりでした。

スポンサーリンク

準備

GitHubからconvnet-benchmarksをcloneします。

$ cd
$ git clone https://github.com/soumith/convnet-benchmarks

Caffeベンチマーク

最初に、Caffeのベンチマークを行うために、ディレクトリを移動します。

$ cd ~/convnet-benchmarks/caffe

同ディレクトリにあるベンチマーク・スクリプトrun_imagenet.shは、同ディレクトリにあるinstall.shでコンパイルしたCaffeをベンチマークに使用する設定になっていましたので、前回の記事でアップデートされたcaffe-nvを使用するように変更します。
また、convnet-benchmarksの中ではGoogleNet V1と表現されているGoogLeNetだけを実行するように変更し、出力するログファイル名も変更しておきます。
変更後のスクリプトrun_imagenet.shは、以下のようになります。

#!/bin/bash
caffe time --model=./imagenet_winners/googlenet.prototxt \
  --iterations=10 --gpu 0 --logtostderr=1 \
  >>output_googlenet_gtx960.log 2>&1

早速実行すると、

$ ./run_imagenet.sh

convnet-benchmarksの作者のSoumithさんのTitan X (12GB)とは違って、GTX 960 (4GB)という低火力環境なので、メモリ不足でコアダンプします。
そこで、~/convnet-benchmarks/caffe/imagenet_winnersにあるgooglenet.prototxtの3行目のinput_dim: 128input_dim: 32に変更します。

name: "googlenet"
input: "data"
input_dim: 128
↓
input_dim: 32

これで、GoogLeNetのバッチサイズが、128から32に変更されます。
再度実行すると、

$ ./run_imagenet.sh

今度は、正常終了しました。
output_googlenet_gtx960.logを確認してみると、以下のように前回とほぼ同等の結果が得られていました。

Average Forward pass: 98.409 ms.
Average Backward pass: 222.41 ms.
Average Forward-Backward: 321.224 ms.

一方で、~/convnet-benchmarksのREADME.mdのGoogleNet V1のCaffeベンチマーク結果(Average Forward-Backwardに相当する時間が1935ms)と比較すると、バッチサイズを128から32に変更したことを考慮しても、差がありすぎます。

Caffeベンチマーク結果の考察

本家のベンチマーク結果は、README.mdのCaffe (native)の表現、install.sh等の内容を総合すると、どうもcuDNNを使用していないようです。
なお、cloneしたoutput_googlenet.logを確認してみると、

Average Forward pass: 146.263 ms.
Average Backward pass: 338.261 ms.
Average Forward-Backward: 484.671 ms.

かなり高速な結果が得られており、このログを作成したときのCaffeは、cuDNNを有効にしてコンパイルされた可能性があります。

Caffeベンチマーク終了時のまとめ

GoogleNet V1 (GoogLeNet) – Input 32x3x224x224

Library Time (ms) forward (ms) backward (ms)
Caffe *1 321 98 222

*1: caffe-nv 0.14.5-2+cuda7.5

TensorFlowベンチマーク

次に、TensorFlowのベンチマークを行います。
VirtualenvでインストールしたTensorFlow 0.7.1 (GPU版)をactivateし、ディレクトリを移動します。

$ source ~/tensorflow-gpu/bin/activate
(tensorflow-gpu)$ cd ~/convnet-benchmarks/tensorflow

同ディレクトリにあるベンチマーク・スクリプトrun.shでは、bazelでコンパイルしてベンチマークを実行していますが、ここではPythonスクリプトbenchmark_googlenet.pyを実行します。
また、benchmark_googlenet.pyのデフォルトのバッチサイズは128ですが、引数でバッチサイズを変更できるので、--batch_size 32を追加して、バッチサイズを32に変更します。
早速実行すると、

(tensorflow-gpu)$ python benchmark_googlenet.py --batch_size 32

途中でエラーが発生しますが、メモリ不足ではないようです。
なんとなく、嫌な予感がします(後編に続く)。