TensorFlowのチュートリアルや自作コードなどを、GCPのCloud Machine Learning(ML-engine)で動作させてみたのですが、いくつか自分がはまったポイントを記録しておきます。
Pythonのバージョン
動いているPythonバージョンは2.7です。3系ではありません。
TensorFlowのバージョン
1.0.0になったんだしそれが動いているのだろう、と思っていたがそんなことはありませんでした。執筆時点(2017/03/06)では0.11rc2でした。
追記(2017/4/25): 1.0ベースに変わったとのアナウンスがメールで送られてきました。
確認方法
こちらの記事がヒントになりました。
以下のようなコードを実行するだけのジョブを投入し、ログを確認することでバージョンを把握できます。
import tensorflow as tf
import os
def main(_):
os.system('pip list')
if __name__ == '__main__':
tf.app.run()
seq2seqのサンプルが動かない
上記の要因で、1.0.0向けに記述されたseq2seqサンプルが動きません。tf.nn.rnn_cellはtf.contrib.rnnに変わりました。tf.nn.seq2seqもtf.contrib.legacy_seq2seqに変わっています。
スタックトレース全体がログで確認できない
上記問題を把握するためにログを見ていたのですが、スタックトレース出力が長すぎて途中で打ち切られている感じでした。これは私の探し方が悪く、実は見る方法があるのかもしれません。
解決策を見つけられなかったので考えた結果、以下のようにtf.app.run()の例外をCloud Storageに保存するようにしました。
try:
if __name__ == '__main__':
try:
tf.app.run()
except:
import traceback
with tf.gfile.Open("gs://bucket-name/log.txt", "w") as f:
traceback.print_exc(file=f)
setup.pyのオプションでtypo
最初、setup.pyを以下のように記述していたのですが、localでは動作するもののcloudで動かないという現象に悩まされました。
from setuptools import setup
if __name__ == '__main__':
setup(name='trainer',
package=['trainer']
)
正しくは以下になります。
from setuptools import setup
if __name__ == '__main__':
setup(name='trainer',
packages=['trainer']
)
packagesとすべきところをpackageと書き間違えていました。ローカルで動作していたのは、カレントディレクトリのtrainer/以下にあるファイルを参照できてしまっていたせいだと思われます。
cloud環境だと一旦wheelパッケージを作成し、ローカルにインストールした上で動作するので、
- packages引数がない
- パッケージにtrainer以下のファイルが含まれないパッケージが出来上がる
- python -m trainer.task等を実行しようとした時trainer/task.pyが参照できなくてエラー発生
という挙動をしていました。
gcloudコマンド更新
ドキュメントには"gcloud beta ml"で実行せよと書かれていますが、つい最近の更新で"gcloud ml-engine"に変わりました。一応古い形式もまだ受け付けてくれますが、警告が出ます。
最後に
Google Cloud MLは今もベータ版であることに変わりはないので、今後も何かしらの非互換な変更(いくつかのdeprecatedなメソッドが使えなくなる等)ことは発生すると思われます。その点に注意しつつ利用しましょう。