update.TL;DRColabのTPUを使って今すぐCNNを試してみよう。Colaboratoryユーザーに激震が走った。Unit)凄さはこのニュースを見れば恐ろしいほど伝わってくる。GPUと比較すると、性能は15~30倍、電力効率は30~80倍になっているという。K80は現在ColabのGPUアクセラレータとして用いられているGPUだ。この15~30倍という値が本当なら、1080Tiを2枚刺し程度ではとてもかなわないぐらいのモンスター計算リソースであることは間違いない。それを体感してみたい。追記:9/27に書いたコードだと並列化が効いてなくて本来のパワーが出せていませんでした。そのため大幅に内容を変えて書き直しました。お詫びして訂正します。追記:NVIDIAの中の人に紹介されました。ありがとうございます!TPUは素晴らしいデバイスですが、K80がかわいそうなのでちょっと補足。・K80は4年前のモデル、V100の3世代前。・K80は2発のGK210を搭載、8.74TFLOPSは2発の合計。単精度、TPUの数値は半精度。Cloudでも使えてクラウドでは割と一般的。追記(11/22):GoogleがクラウドTPUv3を使ってImageNetのデータをResNet-50で「2.2分」で訓練することに成功したらしい2018/11/16付けのarXivの論文。Scalehttps://arxiv.org/abs/1811.06992v1これによると、TPUv3のチップ1024個を使い精度を落とすことなく、ImageNetの訓練を2.2分で完了することに成功したとのこと。実は似た研究でChainer+GPU(P100×1024)を使って15分で訓練を終わらせたという論文が約1年前に出ています。Networksの方の論文です。Minuteshttps://arxiv.org/abs/1711.04325これは2017/11/12の論文です。ちなみにこのPFNの記録は、2018/7/30の論文でP40×1024を使い8.7分での訓練に成功したことで破られています。Minuteshttps://arxiv.org/abs/1807.11205(2),(3)どちらの論文も(1)の論文に引用されています。図は(1)の論文からです。TensorFlow/KerasはTPUに対応しました。PyTorchはTPU対応することが表明されています。記録見て真っ青になってる暇あったら対応したほうがいいのではないでしょうか?多層パーセプトロンを試してみる上の記事を読むと、TPUの使用頻度のうち6割がMLP(多層パーセプトロン)であるという。それを考えるとMLP向けにチューニングされていてもおかしくはない。そこで、CIFAR-10をMLPとCNNで分類してみたい。TPUの扱い方は以下のノートブックが参考になる1。Kerashttps://colab.research.google.com/github/tensorflow/tpu/blob/master/tools/colab/shakespeare_with_tpu_and_keras.ipynbkeras.layersを使うとエラーが出てしまったのだが、全てtensorflow.kerasで置き換えたら上手く行った。main()通常、CIFAR-10をMLPで分類することはまずないが、今回TPUの性能を見るためにあえてこのようにした。「FC→BatchNorm→ReLU→Dropout」を組み合わせたシンプルにしてみた。ログはこのように出てくる。確かに上手く行っている。ColabのGPUで実行して比較していこう。TPUの設定を無視できる。main()の部分を以下のようにする。tensorflow.kerasを使っているが、よくあるKerasの例と同じなので詳細は省略。epochs=10)ログに出てくる1エポックあたりの秒数と、ステップあたりのマイクロ秒数に着目する。これをバッチサイズを変えて、TPUとGPUで比較する。時間は10エポックのうち最も少ない(速かった)値とした。Keras==2.1.6意外なことに、単体の計算性能を比べるとまだGPUのほうが速かった。3秒と2秒の差なら「どっちも速いからいいじゃん」で良さそうな気はする。TPUはバッチサイズを小さくすると露骨に遅くなる。ここだけは注意が必要だ。ちなみにTPUの場合、8個ワーカーがあるので、バッチサイズ÷8サイズのテンソルを並列処理する。バッチサイズが1024なら128個のサンプルを同時並列に、バッチサイズが8192なら1024個を同時並列にとなる。1024×8=8192あたりがよさげ?(追記:128の倍数ならなんでもいいらしい)バッチサイズが256ではGPUが約5.4倍差で速かったが、バッチサイズを5万まで限りなく大きくすると、GPUとTPUの速度差は1.5倍程度に縮んだ。GPUはメモリの制約が問題になることが多いので、OOM(OutOfMemory)するバッチサイズを比べないと計算性能はよくわからない。畳み込みニューラルネットワークを試してみる畳み込みニューラルネットワーク(CNN)の例としてAlexNetも試してみよう。CNNはGPUの場合、バッチサイズを大きくするとすぐOOMするがTPUの場合どうだろうか。x)5層の畳み込みレイヤーからなるモデル(AlexNet)を定義し、main()内のmodel生成を以下のように変える。create_cnn_model()これで同様にTPUとGPUを比較してみよう。記事では「CNN向けに最適化するのは間違い」とは言っているがどのぐらいの速度が出るだろうか。OOM条件はMLPと同じだが、結果は打って変わってCNNではTPUの独壇場となってしまった。OOMとならずに比較できる範囲内でもTPUはGPUより3倍近く速い。K80というGPUの中でもかなり速い部類なので、これに完全勝利したのは強いを通り越して末恐ろしい。OutOfMemoryを示す。TPUはメモリ性能も良くて、GPUの場合はバッチサイズが4096でOOMとなり力尽きてしまったが、TPUの場合はバッチサイズCIFAR5万枚全部1バッチで処理することができた。軽いAlexNetといえど、1バッチで5万枚同時に画像入れられるというのは正気の沙汰とは思えない。Google謹製のTPU、やばい。ちなみにこれで「CNN向けに最適化するのは間違い」とか言うものだからクレイジーすぎる。まとめGoogleColabで無料で使えるTPUとGPUを比較してみた。Colab版の無料のアクセラレータでは、MLPはGPUのほうがまだ速いが、CNNはTPUの完全勝利。これで無料版なので、有料のCloud版ならもっと速いと思う。Cluoud版なら評定どおりのK80の15~30倍という速さが出てもおかしくはない。測定結果を随時募集中。メモリ性能は無料版で既にGPU(ColabのK80:11GB)を超えている。ビッグデータや高解像度の画像処理に対しては無類の強さを発揮すると思われる。ここでは試していなかったがLSTMもよさそう?Googleは神。Google」と言われてるようにGoogleと結婚したい。ColabのTPUを体験してみてください。追記tensorflow.kerasとkerasでどう違うのか?Colabにプリインストールされているkeras2.1.6前提だとTPU未対応なのかエラーが出る。keras==2.2.0」でアップデートしても変わらない。各レイヤー(keras.layers)、モデル(keras.model)、オプティマイザー(keras.optimizers)を「tensorflow.keras.~」に全て置き換えると動く。importの部分をtensorflow.kerasに置き換えればいいだけで、TensorflowのAPIに置き換える必要はない。他にもエラーが出る場合は、バックエンド(keras.backend)、コールバック(keras.callbacks)を置き換えると動いた。エラー出たらtensorflowのものに変えればよさそう。後で調べたら、オプティマイザーはtf.train.~に置き換えなくてもよくて、KerasAPIのオプティマイザーでよい。Singapore」の発表資料より。https://www.dropbox.com/s/jg7j07unw94wbom/TensorFlow%20Keras%20Colab%20TPUs.pdf?dl=0この方が書いているMNISTサンプル。v2は1チップあたり最大で45TFLOPSと書かれている。K80の性能が最大で8.74TFLOPS(ColabのはK80は半分のみ使っているそうです。補足してくださった方ありがとうございました2)であることを踏まえると、そのぐらい出ていてもおかしくはないと思う。TPUの場合はGPUとモデルのコンパイルが全く違っていて、大きいモデルだとコンパイルの時間がかかったり、他のボトルネックとなる要素もかなり目につく。同じ分析でモデルを深くしても計算速度が変わってなかったり、TPUの計算処理以外の部分がボトルネックとなっているということもある。最大FLOPSの性能を引き出せるとは限らないということは頭の片隅においておいたほうが良さそう。GPUのFLOPSからはかなり割り引いて考えたほうがいい。メモリが足りないって怒られたとりあえずカーネルを再起動してみよう。それでも怒られたら仕方ない。save_weightsしたときにhdf5形式で保存できないTensorFlowの仕様変更が原因。詳しくはこちらに書いた。ものすごい遅いんだけど自分も同じケースになったことがある。modelをTPU用のモデルに変換していないから(例えばself.modelで定義しているところをmodelと書いていないか?)。ColabのTPUで対GPUの最速に挑戦するhttps://qiita.com/koshian2/items/fb989cebe0266d1b32fcバグかもしれないことKerasのLearningRateSchedulerが機能せず、全体の50%で学習率を1/10にするというようなことができない。Callbackでオプティマイザーのlrを直接変更してもできない。TPU環境でhistoryが消える→TPU用にモデルを変換したためです。keras.callbacks.Historyを使いましょう。こちらに解決法を書きました。こちらのツイートでTPUの扱い方の突破口が見えました。新刊委託@koshian2C#使ってましたがPythonに浮気してます。IoTでビッグデータをディープラーニングする闇の魔術の趣味をはじめました。技術書典8で新刊出す予定です。upLoginユーザーは見つかりませんでした。