TensorFlow : Deploy : TensorFlow Serving : TensorFlow モデルをサーブする (翻訳)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 09/04/2017
* 本ページは、TensorFlow 本家サイトの Deploy : TensorFlow Serving – Serving a TensorFlow Model を翻訳した上で
適宜、補足説明したものです:
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
このチュートリアルは、訓練された TensorFlow モデルをエクスポートするために TensorFlow Serving コンポーネントをどのように使用するか、そしてそれをサーブするために標準的な tensorflow_model_server をどのように使用するかを貴方に示します。もし貴方が TensorFlow Serving に既に精通していてサーバ内部がどのように動作するかについてより知りたいのであれば、TensorFlow Serving advanced tutorial を見てください。
このチュートリアルは、手書き画像 (MNIST データ) 分類のための TensorFlow チュートリアルで紹介された単純な Softmax 回帰モデルを使用します。もし貴方が TensorFlow または MNIST が何であるか知らないのであれば、ML 初心者向けの MNIST を見てください。
このチュートリアルのためのコードは2つのパートから成ります :
- Python ファイル、mnist_saved_model.py これはモデルを訓練してエクスポートします。
- ModelServer バイナリ、これは apt-get を使用してインストールされるか、C++ ファイル (main.cc) からコンパイルされます。TensorFlow Serving ModelServer は新しいエクスポートされたモデルを見つけてそれをサーブするために gRPC サービスを実行します。
始める前に、(インストール) 要件 は完了しておいてください。
Note: 後述のすべての bazel ビルド・コマンドは標準的な -c opt フラグを使用します。ビルドをさらに最適化するためには、ここの手順 を参照してください。
TensorFlow モデルを訓練してエクスポートする
mnist_saved_model.py で見れるように、訓練は ML 初心者向けの MNIST チュートリアル内と同じ方法で行われます。TensorFlow グラフは、x としての入力テンソル (画像) と y としての出力テンソル (Softmax score) とともに、TensorFlow session sess で launch されます。
それからモデルをエクスポートするために TensorFlow の SavedModelBuilder モジュール を使用します。SavedModelBuilder は訓練したモデルの “スナップショット” を信頼性のあるストレージに保存し、それは後で推論のためにロードできます。
SavedModel フォーマットの詳細については、SavedModel README.md のドキュメントを見てください。
mnist_saved_model.py から、次は、モデルをディスクに保存する一般的なプロセスを示すための短いコード・スニペットです。
from tensorflow.python.saved_model import builder as saved_model_builder ... export_path_base = sys.argv[-1] export_path = os.path.join( compat.as_bytes(export_path_base), compat.as_bytes(str(FLAGS.model_version))) print 'Exporting trained model to', export_path builder = saved_model_builder.SavedModelBuilder(export_path) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ 'predict_images': prediction_signature, signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: classification_signature, }, legacy_init_op=legacy_init_op) builder.save()
SavedModelBuilder.__init__ は次の引数を取ります :
- export_path は export ディレクトリのパス。
SavedModelBuilder はディレクトリが存在しない場合はそれを作成します。例えば、export ディレクトリを得るためにコマンドライン引数と FLAGS.model_version を連結し FLAGS.model_version はモデルのバージョンを指定します。同じモデルのより新しいバージョンをエクスポートする時はより大きい整数値を指定するべきです。各バージョンは与えられたパス下の異なるサブディレクトリにエクスポートされます。
次の引数で SavedModelBuilder.add_meta_graph_and_variables() を使用して meta graph と variable をビルダーに追加できます :
- sess は TensorFlow session で、エクスポートしている訓練モデルを保持しています。
- tags はタグのセットで、それと共に meta graph を保存します。この場合は、グラフを serving で利用しようとしていますから、事前定義された SavedModel tag constants から serve tag を使用します。より詳細は、tag_constants.py と 関連する TensorFlow API 文書 を見てください。
- signature_def_map は、meta graph に追加するための tensorflow::SignatureDef への signature のためのユーザ提供キーのマップを指定します。signature はどのタイプのモデルがエクスポートされるか、そして推論を実行するときにバインドする入力/出力テンソルを指定します。
特別な signature key serving_default は default serving signature を指定します。default serving signature def key は、signature に関連する他の constant と一緒に SavedModel signature constants の一部として定義されています。より詳細は、signature_constants.py と 関連する TensorFlow 1.0 API 文書 を見てください。
更に、signature defs を簡単にビルドすることを助けるために、SavedModel API は signature def utils を提供しています。特に、上掲の mnist_saved_model.py コード・スニペット内では、predict_signature と classification_signature をビルドするために signature_def_utils.build_signature_def() を使用しています。
predict_signature がどのように定義されるかのためのサンプルとして、util は次の引数を取ります :
- inputs={‘images’: tensor_info_x} は入力テンソル info を指定します。
- outputs={‘scores’: tensor_info_y} は score テンソル info を指定します。
- method_name は推論のために使用されるメソッドです。予想リクエストのためには、それは tensorflow/serving/predict に設定されるべきです。他のメソッド名については、signature_constants.py と 関連する TensorFlow 1.0 API 文書 を見てください。
tensor_info_x と tensor_info_y は ここ で定義されている tensorflow::TensorInfo protocol buffer の構造を持つことに注意してください。テンソル info を簡単にビルドするために、TensorFlow SavedModel API はまた utils.py を 関連する TensorFlow 1.0 API 文書 とともに提供しています。
また、images と scores がテンソル・エイリアス名であることにも注意してください。それらはどのような一意の文字列を望んでも良く、そしてそれらは、予想リクエストを後で送る時のテンソル・バインディングのために参照するテンソル x と y の論理名になるでしょう。
例えば、もし x が名前 ‘long_tensor_name_foo’ のテンソルを参照して y が名前 ‘generated_tensor_name_bar’ のテンソルを参照する場合、builder はテンソル論理名を実際の名前マッピング (‘images’ -> ‘long_tensor_name_foo’) と (‘scores’ -> ‘generated_tensor_name_bar’) にストアします。推論を実行するとき、これはユーザにこれらのテンソルを論理名で参照することを可能にします。
Note: 上の記述に加えて、signature def 構造に関係する文書とそれをどのようにセットアップするかについては ここ で見つけられます。
Let’s run it!
export ディレクトリが既に存在しているならばクリアします :
$>rm -rf /tmp/mnist_model
tensorflow と tensorflow-serving-api PIP パッケージをインストールしたいのであれば、単純な python コマンドを使用してすべての Python コード (export と client) を実行できます。PIP パッケージをインストールするためには、ここの手順 をフォローしてください。それらのパッケージをインストールすることなしに必要な依存をビルドしてすべてのコードを実行するために Bazel を使用することもまた可能です。codelab の残りは Bazel と PIP オプションのための手順を持ちます。
Bazel:
$>bazel build -c opt //tensorflow_serving/example:mnist_saved_model $>bazel-bin/tensorflow_serving/example/mnist_saved_model /tmp/mnist_model Training model... ... Done training! Exporting trained model to /tmp/mnist_model Done exporting!
あるいは tensorflow-serving-api をインストールしているならば、次を実行できます :
python tensorflow_serving/example/mnist_saved_model.py /tmp/mnist_model
さて export ディレクトリを見てみましょう。
$>ls /tmp/mnist_model 1
上で述べたように、モデルの各バージョンをエクスポートするためにサブディレクトリが作成されます。FLAGS.model_version は 1 のデフォルト値を持ちますので、従って相当するサブディレクトリ 1 が作成されます。
$>ls /tmp/mnist_model/1 saved_model.pb variables
各バージョンのサブディレクトリは次のファイルを含みます :
- saved_model.pb はシリアライズされた tensorflow::SavedModel です。それはモデルの一つまたそれ以上のグラフ定義を、更には signature のようなモデルの metadata も含みます。
- variables はグラフのシリアライズされた variable を保持するファイルです。
それによって、貴方の TensorFlow モデルはエクスポートされてロードされる準備が整います!
エクスポートされたモデルを標準的な TensorFlow ModelServer でロードする
ローカルでコンパイルされた ModelServer を使用したい場合には、次を実行します :
$>bazel build -c opt //tensorflow_serving/model_servers:tensorflow_model_server $>bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server --port=9000 --model_name=mnist --model_base_path=/tmp/mnist_model/
コンパイルをスキップして apt-get を使用してインストールすることを好む場合には、ここの手順 を追ってください。それから次のコマンドでサーバを実行します :
tensorflow_model_server --port=9000 --model_name=mnist --model_base_path=/tmp/mnist_model/
Server をテストする
サーバをテストするためには提供されている mnist_client ユティリティが使用できます。クライアントは MNIST テストデータをダウンロードし、それらをサーバにリクエストとして送り、そして推論エラー率を計算します。
それを Bazel で実行するには :
$>bazel build -c opt //tensorflow_serving/example:mnist_client $>bazel-bin/tensorflow_serving/example/mnist_client --num_tests=1000 --server=localhost:9000 ... Inference error rate: 10.5%
あるいは PIP パッケージをインストールした場合には、以下を実行します :
python tensorflow_serving/example/mnist_client.py --num_tests=1000 --server=localhost:9000
訓練された Softmax モデルに対して 91% 精度を期待します、そして最初の 1000 テスト画像に対して 10.5% 推論エラー率を得ます。これはサーバが訓練されたモデルを成功的にロードして実行することを確かめます!
以上