TensorFlow モデルの提供

このチュートリアルでは、TensorFlow Serving コンポーネントを使用してトレーニングされた TensorFlow モデルをエクスポートし、標準の tensorflow_model_server を使用してそれを提供する方法を示します。 TensorFlow Serving にすでに精通していて、サーバー内部の仕組みについてさらに知りたい場合は、 TensorFlow Serving の上級チュートリアルを参照してください。

このチュートリアルでは、手書きの数字を分類する単純なソフトマックス回帰モデルを使用します。これは、Fashion MNIST データセットを使用した画像分類に関する TensorFlow チュートリアルで紹介されたものと非常に似ています。

このチュートリアルのコードは 2 つの部分で構成されます。

  • モデルをトレーニングしてエクスポートする Python ファイルmnist_saved_model.py

  • Apt を使用してインストールするか、C++ ファイル ( main.cc ) からコンパイルできる ModelServer バイナリ。 TensorFlow Serving ModelServer は、新しいエクスポートされたモデルを検出し、それらを提供するためにgRPCサービスを実行します。

始める前に、まずDocker をインストールします

TensorFlow モデルのトレーニングとエクスポート

トレーニング フェーズでは、入力テンソル (イメージ) をx 、出力テンソル (ソフトマックス スコア) をyとして、TensorFlow グラフが TensorFlow セッションsessで起動されます。

次に、TensorFlow のSavedModelBuilder モジュールを使用してモデルをエクスポートします。 SavedModelBuilderトレーニングされたモデルの「スナップショット」を信頼できるストレージに保存し、後で推論のためにロードできるようにします。

SavedModel 形式の詳細については、 SavedModel README.mdのドキュメントを参照してください。

以下は、 mnist_saved_model.pyの短いコード スニペットで、モデルをディスクに保存する一般的なプロセスを示しています。

export_path_base = sys.argv[-1]
export_path = os.path.join(
    tf.compat.as_bytes(export_path_base),
    tf.compat.as_bytes(str(FLAGS.model_version)))
print('Exporting trained model to', export_path)
builder = tf.saved_model.builder.SavedModelBuilder(export_path)
builder.add_meta_graph_and_variables(
    sess, [tf.compat.v1.saved_model.tag_constants.SERVING],
    signature_def_map={
        'predict_images':
            prediction_signature,
        tf.compat.v1.saved_model.signature_constants
            .DEFAULT_SERVING_SIGNATURE_DEF_KEY:
            classification_signature,
    },
    main_op=tf.compat.v1.tables_initializer(),
    strip_default_attrs=True)
builder.save()

SavedModelBuilder.__init__次の引数を受け取ります。

  • export_pathはエクスポート ディレクトリのパスです。

ディレクトリが存在しない場合は、 SavedModelBuilder作成されます。この例では、コマンド ライン引数とFLAGS.model_versionを連結して、エクスポート ディレクトリを取得します。 FLAGS.model_versionモデルのバージョンを指定します。同じモデルの新しいバージョンをエクスポートする場合は、より大きな整数値を指定する必要があります。各バージョンは、指定されたパスの下の異なるサブディレクトリにエクスポートされます。

次の引数を指定してSavedModelBuilder.add_meta_graph_and_variables()を使用すると、メタ グラフと変数をビルダーに追加できます。

  • sessは、エクスポートするトレーニング済みモデルを保持する TensorFlow セッションです。

  • tagsメタグラフを保存するためのタグのセットです。この場合、グラフを提供時に使用する予定であるため、事前定義された SavedModel タグ定数からのserveタグを使用します。詳細については、 tag_constants.pyおよび関連する TensorFlow API ドキュメントを参照してください。

  • signature_def_mapメタ グラフに追加する、署名のユーザー指定キーの tensorflow::SignatureDef へのマップを指定します。署名は、エクスポートされるモデルのタイプと、推論の実行時にバインドする入力/出力テンソルを指定します。

    特別な署名キーserving_defaultデフォルトの提供署名を指定します。デフォルトの提供署名 def キーは、署名に関連する他の定数とともに、SavedModel 署名定数の一部として定義されます。詳細については、 signature_constants.pyおよび関連する TensorFlow API ドキュメント を参照してください。

    さらに、署名定義を簡単に構築できるように、SavedModel API は署名 def utilsを提供します。具体的には、元のmnist_saved_model.pyファイルでは、 signature_def_utils.build_signature_def()を使用して、 predict_signatureclassification_signatureを構築します。

    predict_signatureの定義方法の例として、ユーティリティは次の引数を受け取ります。

    • inputs={'images': tensor_info_x}入力テンソル情報を指定します。

    • outputs={'scores': tensor_info_y}スコアのテンソル情報を指定します。

    • method_nameは、推論に使用されるメソッドです。予測リクエストの場合は、 tensorflow/serving/predictに設定する必要があります。他のメソッド名については、 signature_constants.pyおよび関連する TensorFlow API ドキュメント を参照してください。

tensor_info_xtensor_info_yここで定義されたtensorflow::TensorInfoプロトコル バッファの構造を持つことに注意してください。テンソル情報を簡単に構築するために、TensorFlow SavedModel APIは関連する TensorFlow API ドキュメントとともにutils.pyも提供します。

また、 imagesscoresテンソルのエイリアス名であることに注意してください。これらは任意の一意の文字列にすることができ、後で予測リクエストを送信するときにテンソル バインディングで参照するテンソルxyの論理名になります。

たとえば、 xが 'long_tensor_name_foo' という名前のテンソルを参照し、 yが 'generated_tensor_name_bar' という名前のテンソルを参照する場合、 builderテンソル論理名を実名マッピング ('images' -> 'long_tensor_name_foo') および ('scores) に保存します。 ' -> 'generated_tensor_name_bar')。これにより、ユーザーは推論を実行するときに論理名でこれらのテンソルを参照できるようになります。

実行してみましょう!

まず、まだ行っていない場合は、このリポジトリのクローンをローカル マシンに作成します。

git clone https://github.com/tensorflow/serving.git
cd serving

エクスポート ディレクトリが既に存在する場合はクリアします。

rm -rf /tmp/mnist

次に、モデルをトレーニングしましょう。

tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
  /tmp/mnist

これにより、次のような出力が得られます。

Training model...

...

Done training!
Exporting trained model to models/mnist
Done exporting!

次に、エクスポート ディレクトリを見てみましょう。

$ ls /tmp/mnist
1

前述したように、モデルの各バージョンをエクスポートするためにサブディレクトリが作成されます。 FLAGS.model_versionデフォルト値は 1 であるため、対応するサブディレクトリ1が作成されます。

$ ls /tmp/mnist/1
saved_model.pb variables

各バージョンのサブディレクトリには次のファイルが含まれています。

  • saved_model.pbはシリアル化された tensorflow::SavedModel です。これには、モデルの 1 つ以上のグラフ定義と、署名などのモデルのメタデータが含まれます。

  • variablesグラフのシリアル化された変数を保持するファイルです。

これで、TensorFlow モデルがエクスポートされ、ロードする準備が整いました。

エクスポートされたモデルを標準 TensorFlow ModelServer でロードする

Docker サービス提供イメージを使用して、提供するモデルを簡単にロードします。

docker run -p 8500:8500 \
--mount type=bind,source=/tmp/mnist,target=/models/mnist \
-e MODEL_NAME=mnist -t tensorflow/serving &

サーバーをテストする

提供されているmnist_clientユーティリティを使用してサーバーをテストできます。クライアントは MNIST テスト データをダウンロードし、リクエストとしてサーバーに送信し、推論エラー率を計算します。

tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
  --num_tests=1000 --server=127.0.0.1:8500

これにより、次のようなものが出力されるはずです

    ...
    Inference error rate: 11.13%

トレーニングされた Softmax モデルの精度は約 90% であると予想され、最初の 1000 枚のテスト画像では推論エラー率が 11% でした。これにより、サーバーがトレーニング済みモデルを正常にロードして実行していることが確認されます。