ホーム » TensorFlow Serving

TensorFlow Serving」カテゴリーアーカイブ

TensorFlow : Guide : 低位 API : セーブとリストア

TensorFlow : Guide : 低位 API : セーブとリストア (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
更新日時 : 07/14/2018
作成日時 : 09/19/2017

* 本ページは、TensorFlow 本家サイトの Guide – Low Level APIs – Saving and Restoring を翻訳した上で
適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、適宜、追加改変している場合もあります。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

本文

このドキュメントは 変数 とモデルをどのようにセーブしてリストアするするかについて説明します。

 

変数のセーブとリストア

TensorFlow 変数は貴方のプログラムで操作される共有され永続性のある状態を表わすための最善の方法です (詳細は 変数 を見てください)。このセクションは変数をどのようにセーブしてリストアするかを説明します。Estimator は変数を (model_dir に) 自動的にセーブしてリストアすることに注意してください。

tf.train.Saver クラスはモデルをセーブしてリストアするためのメソッドを提供します。tf.train.Saver コンストラクタはグラフの変数の総て、または指定されたリストのために save と restore ops をグラフに追加します。Saver オブジェクトは、読み書きするチェックポイントファイルのためのパスを指定し、これらの ops を実行するためのメソッドを提供します。

saver は貴方のモデルで既に定義された変数総てをリストアするでしょう。もしそのグラフをどのように構築したのか知らないでモデルをロードする場合は (例えば、モデルをロードする一般的なプログラムを書いている場合)、このドキュメントの後方の モデルのセーブとリストアの概要 セクションを読んでください。

TensorFlow は変数をバイナリ・チェックポイント・ファイルにセーブします、これは大雑把に言えば、変数名をテンソル値にマップします。

変数をセーブする

tf.train.Saver() でモデルの変数総てを管理する Saver を作成します。例えば、次のスニペットは変数をチェックポイント・ファイルにセーブする tf.train.Saver.save メソッドをどのように呼び出すかを示します :

# Create some variables.
v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
v2 = tf.get_variable("v2", shape=[5], initializer = tf.zeros_initializer)

inc_v1 = v1.assign(v1+1)
dec_v2 = v2.assign(v2-1)

# Add an op to initialize the variables.
init_op = tf.global_variables_initializer()

# Add ops to save and restore all the variables.
saver = tf.train.Saver()

# Later, launch the model, initialize the variables, do some work, and save the
# variables to disk.
with tf.Session() as sess:
  sess.run(init_op)
  # Do some work with the model.
  inc_v1.op.run()
  dec_v2.op.run()
  # Save the variables to disk.
  save_path = saver.save(sess, "/tmp/model.ckpt")
  print("Model saved in file: %s" % save_path)

変数をリストアする

tf.train.Saver オブジェクトは変数をチェックポイント・ファイルにセーブするだけでなく、変数をリストアもします。ファイルから変数をリストアするときそれらを予め初期化する必要はないことに注意してください。例えば、次のスニペットはチェックポイント・ファイルから変数をリストアするために tf.train.Saver.restore メソッドをどのように呼び出すかを示します :

tf.reset_default_graph()

# Create some variables.
v1 = tf.get_variable("v1", shape=[3])
v2 = tf.get_variable("v2", shape=[5])

# Add ops to save and restore all the variables.
saver = tf.train.Saver()

# Later, launch the model, use the saver to restore variables from disk, and
# do some work with the model.
with tf.Session() as sess:
  # Restore variables from disk.
  saver.restore(sess, "/tmp/model.ckpt")
  print("Model restored.")
  # Check the values of the variables
  print("v1 : %s" % v1.eval())
  print("v2 : %s" % v2.eval())

どの変数をセーブしてリストアするかを選択する

tf.train.Saver() にどのような引数も渡さない場合には、saver はグラフの総ての変数を処理します。変数が作成されたときに渡された名前に基づいて各変数はセーブされます。

チェックポイント・ファイルの変数に対して名前を明示的に指定するのは時々有用です。例えば、”weights” という名前の変数を持つ訓練されたモデルを持ち、その値を “params” という名前の変数にリストアすることを望むかもしれません。

モデルで使用される変数のサブセットだけをセーブまたはリストアすることも時々有用です。例えば、貴方は 5 層のニューラルネットを訓練したかもしれません、そして今、5つの訓練された層の既存の重みを再利用した 6 層で新しいモデルを訓練することを望みます。最初の 5 層だけの重みをリストアするために saver を使用できます。

次のいずれかを tf.train.Saver() コンストラクタに渡すことによりセーブまたはロードするために名前と変数を簡単に指定してできます :

  • 変数のリスト (それらはそれら自身の名前の下にストアされます)。
  • Python 辞書、そこではキーは使用するための名前で値は管理するための変数です。

先に示した save/resotre サンプルからの続きです :

tf.reset_default_graph()
# Create some variables.
v1 = tf.get_variable("v1", [3], initializer = tf.zeros_initializer)
v2 = tf.get_variable("v2", [5], initializer = tf.zeros_initializer)

# Add ops to save and restore only `v2` using the name "v2"
saver = tf.train.Saver({"v2": v2})

# Use the saver object normally after that.
with tf.Session() as sess:
  # Initialize v1 since the saver will not.
  v1.initializer.run()
  saver.restore(sess, "/tmp/model.ckpt")

  print("v1 : %s" % v1.eval())
  print("v2 : %s" % v2.eval())

Notes:

  • モデル変数の異なるサブセットをセーブしてリストアする必要がある場合には望むだけの数の Saver オブジェクトを作成することができます。同じ変数は複数の saver オブジェクトでリストされることができます ; その値は Saver.restore() メソッドが実行されるときに変更されるだけです。
  • セッション開始時にモデル変数のサブセットだけをリストアする場合、他の変数のために初期化 op を実行しなければなりません。更なる情報のためには tf.variables_initializer を見てください。
  • チェックポイントの変数を調べるためには、inspect_checkpoint ライブラリ、特に print_tensors_in_checkpoint_file 関数を使用できます。
  • デフォルトでは、Saver は各変数のために tf.Variable.name プロパティの値を使用できます。けれども、Saver オブジェクトを作成するとき、チェックポイント・ファイルの変数のためにオプションで名前を選択しても良いです。

 

モデルのセーブとリストアの概要

変数、グラフ、そしてグラフのメタデータをセーブそしてロードすることを望むとき — 基本的に、貴方のモデルをセーブまたはリストアすることを望むとき — SavedModel を使用することを推奨します。

SavedModel は言語ニュートラルで、復旧可能で、密封された (= hermetic) シリアライゼーション形式です。SavedModel は高位システムとツールに TensorFlow モデルを生成し、消費し (= consume)、そして変換することを可能にします。TensorFlow は、tf.saved_model API, Estimator API そして CLI を含む、SavedModel と相互作用するための幾つかのメカニズムを提供します。

 

SavedModel を構築してロードするための API

このセクションは SavedModel を構築してロードするための API にフォーカスを当てます、特に低位 TensorFlow API を使用するときです。

SavedModel を構築する

SavedModel builder の Python 実装を提供します。SavedModelBuilder クラスは複数の MetaGraphDef をセーブするための機能を提供します。MetaGraph はデータフロー・グラフ、加えてそれに関連する変数、アセット、そして signature です。MetaGraphDef は MetaGraph のプロトコル・バッファ表現です。signature はグラフへの入力とグラフからの出力のセットです。

アセットがディスクにセーブされて書き出されるかコピーされる必要がある場合には、最初の MetaGraphDef が追加されたときにそれらは提供されます。複数の MetaGraphDef が同じ名前のアセットに関連付けられる場合には、最初のバージョンだけが保持されます。

SavedModel に追加された各 MetaGraphDef はユーザ指定のタグでアノテートされなければなりません。タグは、変数とアセットの共有されたセットと一緒に、ロードしてリストアするための特定の MetaGraphDef を識別するための方法を提供します。これらのタグは典型的にはその機能性 (例えば、サービングまたは訓練)、そしてオプションでハードウェア仕様的な局面 (例えば、GPU) で MetaGraphDef をアノテートします。

例えば、次のコードは SavedModel を構築するために SavedModelBuilder を使用する典型的な方法を提案します :

export_dir = ...
...
builder = tf.saved_model_builder.SavedModelBuilder(export_dir)
with tf.Session(graph=tf.Graph()) as sess:
  ...
  builder.add_meta_graph_and_variables(sess,
                                       [tag_constants.TRAINING],
                                       signature_def_map=foo_signatures,
                                       assets_collection=foo_assets)
...
# Add a second MetaGraphDef for inference.
with tf.Session(graph=tf.Graph()) as sess:
  ...
  builder.add_meta_graph([tag_constants.SERVING])
...
builder.save()

Python で SavedModel をロードする

SavedModel loader の Python バージョンは SavedModel のためのロードとリストアの性能を提供します。ロード演算は次の情報を必要とします :

  • セッション、そこでグラフ定義と変数をリストアします。
  • タグ、ロードする MegaGraphDef を識別するために使用されます。
  • SavedModel の位置 (ディレクトリ)。

ロード時、特定の MetaGraphDef の一部として供給される変数、アセット、そして signature のサブセットは
供給されるセッション内にリストアされます。

export_dir = ...
...
with tf.Session(graph=tf.Graph()) as sess:
  tf.saved_model.loader.load(sess, [tag_constants.TRAINING], export_dir)
  ...

C++ で SavedModel をロードする

SavedModel loader の C++ バージョンは SessionOptions と RunOptions を許可し、パスから SavedModel をロードするための API を提供します。ロードされるグラフに関連付けられたタグを指定しなければなりません。SavedModel のロードされたバージョンは SavedModelBundle として参照されて MetaGraphDef とそれが内部にロードされるセッションを含みます。

const string export_dir = ...
SavedModelBundle bundle;
...
LoadSavedModel(session_options, run_options, export_dir, {kSavedModelTagTrain},
               &bundle);

標準的な constants

SavedModel は様々なユースケースのために TensorFlow グラフを構築してロードする柔軟性を提供します。最も一般的なユースケースのために、SavedModel の API は Python と C++ で constants のセットを提供します、これはツールの一貫性に渡り再利用して共有することを容易にします。

標準的な MetaGraphDef タグ

SavedModel にセーブされた MetaGraphDef を一意に識別するためにタグのセットを使用するかもしれません。一般に使用されるタグのサブセットは以下で指定されます :

標準的な SignatureDef constants

SignatureDef はグラフによりサポートされる計算の signature を定義するプロトコル・バッファです。一般的に使用される入力キー、出力キー、そしてメソッド名は以下で定義されます :

 

Estimator で SavedModel を使用する

Estimator モデルを訓練した後、リクエストを取り結果を返すような、モデルからのサービスを作成することを望むかもしれません、そのようなサービスを貴方のマシン上でローカルに実行したりクラウドでそれをスケーラブルにデプロイすることができます。

サービングのための訓練された Estimator を用意するためには、標準的な SavedModel フォーマットでそれをエクスポートしなければなりません。このセクションはどのように以下を行なうかを説明します :

  • 出力ノードとサーブ可能な相当する API を指定する(分類、回帰、または予測する)。
  • 貴方のモデルを SavedModel 形式にエクスポートする。
  • ローカル・サーバからモデルをサーブして予測を要求する。

サービング入力を準備する

訓練中、input_fn() はデータを摂取してそれをモデルによる使用のために準備します。サービス提供時には、同様に、serving_input_receiver_fn() は推論リクエストを受け取りそれらをモデルのために準備します。この関数は次の目的を持ちます :

  • グラフに placeholder を追加する、これにはサービング・システムが推論リクエストを供給します。
  • データを入力フォーマットからモデルにより期待される特徴テンソルに変換するために必要な、任意の追加の ops を追加する

関数は tf.estimator.export.ServingInputReceiver オブジェクトを返します、これは placeholder と結果の特徴テンソルを一緒にまとめます。

典型的なパターンは推論リクエストはシリアライズ化された tf.Examples の形式で到着します、そのため serving_input_receiver_fn() はそれらを受け取るために単一の文字列 placeholder を作成します。そして serving_input_receiver_fn() はまたグラフに tf.parse_example op を追加することにより tf.Examples を構文解析する責任も負います。

そのような serving_input_receiver_fn() を書くとき、解析器 (= parser) にどんな特徴名を期待するかそしてどのようにそれらをテンソルにマップするかを教えてるために tf.parse_example に解析仕様 (= parsing specification) を渡さなければなりません。解析仕様は特徴名から tf.FixedLenFeature, tf.VarLenFeature, と tf.SparseFeature への辞書の形式を取ります。この解析仕様はどのようなラベルあるいは重みカラムも含むべきではないことに注意してください、何故ならばそれらはサービング時には利用可能ではないからです — 訓練時に input_fn() で使用される解析使用とは対照的です。

組み合わせて、そして :

feature_spec = {'foo': tf.FixedLenFeature(...),
                'bar': tf.VarLenFeature(...)}

def serving_input_receiver_fn():
  """An input receiver that expects a serialized tf.Example."""
  serialized_tf_example = tf.placeholder(dtype=tf.string,
                                         shape=[default_batch_size],
                                         name='input_example_tensor')
  receiver_tensors = {'examples': serialized_tf_example}
  features = tf.parse_example(serialized_tf_example, feature_spec)
  return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)

tf.estimator.export.build_parsing_serving_input_receiver_fn ユティリティ関数は一般的なケースのためにその入力レシーバーを提供します。

Note: ローカルサーバで Predict API を使用してサーブされるモデルを訓練するとき、解析ステップは必要ありません、何故ならばモデルは生の (= raw) 特徴データを受け取るからです。

解析や他の入力処理を必要としない場合でさえも — つまり、もしサービング・システムが特徴テンソルを直接供給する場合でも — 依然として serving_input_receiver_fn() を提供しなければなりません、これは特徴テンソルのための placeholder を作成してそれらを通り抜けさせます。tf.estimator.export.build_raw_serving_input_receiver_fn ユティリティはこれのために提供します。

もしこれらのユティリティが貴方のニーズに合わない場合には、貴方は貴方自身の serving_input_receiver_fn() を自由に書くことができます。これが必要となるかもしれない一つのケースは貴方の訓練 input_fn() がサービング時に要約 (recapitulated) されなければならない何某かの前処理ロジックを組み入れる場合です。訓練-サービングの歪みのリスクを軽減するためには、そのような処理を、input_fn() and serving_input_receiver_fn() の両者から呼び出される関数内にカプセル化することを推奨します。

serving_input_receiver_fn() はまた signature の入力部分を決定することに注意してください。つまり、serving_input_receiver_fn() を書くとき、どのような signature を期待してそれらを貴方のモデルの期待する入力にどのようにマップするかを解析器 (= parser) に知らせなければなりません。対照的に、signature の出力部分はモデルにより決定されます。

エクスポートを遂行する

訓練された Estimator をエクスポートするためには、tf.estimator.Estimator.export_savedmodel を export ベース・パスと serving_input_receiver_fn と一緒に呼び出します。

estimator.export_savedmodel(export_dir_base, serving_input_receiver_fn)

このメソッドは、特徴テンソルを得るために最初に serving_input_receiver_fn() を呼び出し、そしてそれらの特徴に基づくモデル・グラフを生成するためにこの Estimator の model_fn() を呼び出すことにより、新しいグラフを構築します。それはフレッシュなセッションを開始し、そしてデフォルトでは、最も最近のチェックポイントをそれにリストアします。(必要であれば、異なるチェックポイントが渡されるかもしれません。)
最終的にそれは与えられた export_dir_base の下にタイムスタンプつきの export ディレクトリを作成し (i.e., export_dir_base/) 、そしてこのセッションからセーブされた単一の MetaGraphDef を含む SavedModel をその内に書きます。

Note: 古い exports をガベージコレクトするのは貴方の責任です。さもなければ、続く export は export_dir_base 下に蓄積されるでしょう。

カスタム・モデルの出力を指定する

カスタム model_fn を書くとき、tf.estimator.EstimatorSpec の export_outputs 要素を戻り値として populate しなければなりません。これは {name: output} の辞書で、エクスポートされてサービングの間に使用される出力 signature を記述します。

単一の予測を行なう通常のケースでは、この辞書は一つの要素を含み、名前は重要ではありません。マルチ・ヘッドのモデルでは、各ヘッドはこの辞書のエントリとして表わされます。名前は貴方の選択の文字列でサービング時に特定のヘッドをリクエストするために使用できます。

各出力値は tf.estimator.export.ClassificationOutput, tf.estimator.export.RegressionOutput, または tf.estimator.export.PredictOutput のような ExportOutput オブジェクトでなければなりません。

これらの出力型は率直に TensorFlow Serving API にマップされてどのリクエスト型が重視されるかを決定します。

Note: マルチ・ヘッドなケースでは、SignatureDef は、model_fn から返される、同じキーで命名された、export_outputs 辞書の各要素のために生成されるでしょう。これらの SignatureDefs は、相当する ExportOutput エントリで定められているように、それらの出力の点のみ異なります。入力は常に serving_input_receiver_fn により提供されるものです。推論リクエストは名前でヘッドを指定するかもしれません。一つのヘッドは、推論リクエストが一つを指定していないときにどの SignatureDef がサーブされるかを示す signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY を使用して命名されなければなりません。

エクスポートされたモデルをローカルでサーブする

ローカル・デプロイメントのためには、TensorFlow Serving を使用して貴方のモデルをサーブできます、これは SavedModel をロードしてそれを gRPC サービスとして公開するオープンソース・プロジェクトです。

最初に、TensorFlow Serving をインストール します。

それから、$export_dir_base を上でエクスポートした SavedModel へのパスで置き換えてローカル model server を構築して実行します :

bazel build //tensorflow_serving/model_servers:tensorflow_model_server
bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server --port=9000 --model_base_path=$export_dir_base

 
今ではポート 9000 上の gRPC 経由で推論リクエストのためにリスンするサーバを持ちます!

ローカルサーバから予測をリクエストする

サーバは PredictionService gRPC API サービス定義に従って gRPC リクエストに応答します。(ネストされたプロトコル・バッファは様々な 近接したファイル で定義されています。)

API サービス定義から、gRPC フレームワークは API へのリモートアクセスを提供するために様々な言語のクライアント・ライブラリを生成します。Bazel ビルドツールを使用したプロジェクトでは、これらのライブラリは自動的にビルドされて (例として Python を使用して) これらのように依存を通して提供されます :

  deps = [
    "//tensorflow_serving/apis:classification_proto_py_pb2",
    "//tensorflow_serving/apis:regression_proto_py_pb2",
    "//tensorflow_serving/apis:predict_proto_py_pb2",
    "//tensorflow_serving/apis:prediction_service_proto_py_pb2"
  ]

それから Python クライアント・コードはこのようにしてライブラリをインポートできます :

from tensorflow_serving.apis import classification_pb2
from tensorflow_serving.apis import regression_pb2
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2

Note: prediction_service_pb2 はサービス全体を定義していますので常に必要です。けれども典型的なクライアントは行なわれるリクエストの型に依存して、classification_pb2, regression_pb2, そして predict_pb2 の一つだけを必要とするでしょう。

 
そして gRPC リクエストの送信はリクエスト・データを含むプロトコルバッファを集めてそれをサービス・スタブに渡すことによって成されます。リクエスト・プロトコルバッファがどのように空で作成されてそして generated protocol buffer API を通して populate されるかに注意してください。

from grpc.beta import implementations

channel = implementations.insecure_channel(host, int(port))
stub = prediction_service_pb2.beta_create_PredictionService_stub(channel)

request = classification_pb2.ClassificationRequest()
example = request.input.example_list.examples.add()
example.features.feature['x'].float_list.value.extend(image[0].astype(float))

result = stub.Classify(request, 10.0)  # 10 secs timeout

このサンプルで返される結果は ClassificationResponse プロトコルバッファです。

これはスケルトンのサンプルです ; 更なる詳細のためには TensorFlow Serving 文書と サンプル を見てください。

Note: ClassificationRequest と RegressionRequest は tensorflow.serving.Input プロトコルバッファを含み、これは tensorflow.Example プロトコルバッファのリストを順番に含みます。PredictRequest は対照的に、特徴名から TensorProto を通してエンコードされる値へのマッピングを含みます。相応して: Classify と Regress API を使用するとき、TensorFlow Serving はシリアライズ化された tf.Examples をグラフに供給しますので、serving_input_receiver_fn() は tf.parse_example() Op を含むべきです。一般的な Predict API を使用するときは、けれども、TensorFlow Serving は生の特徴データをグラフに供給しますので、serving_input_receiver_fn() の通り抜けが使用さえるべきです。

 

SavedModel を探求して実行する CLI

SavedModel を探求して実行するために SavedModel コマンドライン・インターフェイス (CLI, Command Line Interface) を使用することができます。例えば、モデルの SignatureDefs を探求するために CLI を使用できます。CLI は入力 テンソルの dtype と shape がモデルに適合しているかを迅速に確かめることを可能にします。更に、貴方のモデルをテストすることを望むのであれば、様々な形式 (例えば、Python 式) のサンプル入力を渡してそれから出力を取得することでサニティ・チェックを行なうために CLI を使用できます。

SavedModel CLI をインストールする

大まかに言えば、TensorFlow を次の2つの方法のどちらかでインストールできます :

  • 事前ビルドされた TensorFlow バイナリをインストールする。
  • ソースコードから TensorFlow をビルドする。

もし事前ビルドされた TensorFlow ライブラリを通して TensorFlow をインストールしたのであれば、SavedModel CLI は貴方のシステムにパス名 bin\saved_model_cli で既にインストールされています。

もしソースコードから TensorFlow をビルドした場合には、saved_model_cli をビルドするために次の追加のコマンドを実行しなければなりません :

$ bazel build tensorflow/python/tools:saved_model_cli

コマンドの概要

SavedModel CLI は SavedModel の MetaGraphDef 上の次の2つのコマンドをサポートします :

  • show, これは SavedModel の MetaGraphDef 上の計算を表示します。
  • run, これは MetaGraphDef 上の計算を実行します。

show コマンド

SavedModel は、タグセットで識別される一つまたはそれ以上の MetaGraphDefs を含みます。モデルをサーブするために、どのような種類の SignatureDefs が各モデルにあり、そしてそれらの入力と出力が何であるか知りたいと思うかもしれません。show コマンドは SavedModel の内容を階層順で調べることを許します。ここに構文があります :

usage: saved_model_cli show [-h] --dir DIR [--all]
[--tag_set TAG_SET] [--signature_def SIGNATURE_DEF_KEY]

例えば、次のコマンドは SavedModel の総ての利用可能な MetaGraphDef タグセットを表示します :

$ saved_model_cli show --dir /tmp/saved_model_dir
The given SavedModel contains the following tag-sets:
serve
serve, gpu

次のコマンドは MetaGraphDef の総ての利用可能な SignatureDef キーを表示します :

$ saved_model_cli show --dir /tmp/saved_model_dir --tag_set serve
The given SavedModel `MetaGraphDef` contains `SignatureDefs` with the
following keys:
SignatureDef key: "classify_x2_to_y3"
SignatureDef key: "classify_x_to_y"
SignatureDef key: "regress_x2_to_y3"
SignatureDef key: "regress_x_to_y"
SignatureDef key: "regress_x_to_y2"
SignatureDef key: "serving_default"

MetaGraphDef がタグセットの複数のタグを持つ場合には、各タグがカンマ区切りの、総てのタグを指定しなければなりません。例えば :

$ saved_model_cli show --dir /tmp/saved_model_dir --tag_set serve,gpu

特定の SignatureDef のための総ての入力と出力 TensorInfo を表示するためには、signature_def オプションに SignatureDef キーを渡します。これは、計算グラフを後で実行するために入力テンソルのテンソル・キー値、dtype と shape を知りたいときに非常に有用です。例えば :

$ saved_model_cli show --dir \
/tmp/saved_model_dir --tag_set serve --signature_def serving_default
The given SavedModel SignatureDef contains the following input(s):
inputs['x'] tensor_info:
    dtype: DT_FLOAT
    shape: (-1, 1)
    name: x:0
The given SavedModel SignatureDef contains the following output(s):
outputs['y'] tensor_info:
    dtype: DT_FLOAT
    shape: (-1, 1)
    name: y:0
Method name is: tensorflow/serving/predict

SavedModel で利用可能な総ての情報を表示するためには、–all オプションを使用します。例えば :

$ saved_model_cli show --dir /tmp/saved_model_dir --all
MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['classify_x2_to_y3']:
The given SavedModel SignatureDef contains the following input(s):
inputs['inputs'] tensor_info:
    dtype: DT_FLOAT
    shape: (-1, 1)
    name: x2:0
The given SavedModel SignatureDef contains the following output(s):
outputs['scores'] tensor_info:
    dtype: DT_FLOAT
    shape: (-1, 1)
    name: y3:0
Method name is: tensorflow/serving/classify

...

signature_def['serving_default']:
The given SavedModel SignatureDef contains the following input(s):
inputs['x'] tensor_info:
    dtype: DT_FLOAT
    shape: (-1, 1)
    name: x:0
The given SavedModel SignatureDef contains the following output(s):
outputs['y'] tensor_info:
    dtype: DT_FLOAT
    shape: (-1, 1)
    name: y:0
Method name is: tensorflow/serving/predict

run コマンド

グラフ計算を実行するためには run コマンドを起動します、入力を渡してそれから出力を表示します (そしてオプションでセーブ)。ここに構文があります :

usage: saved_model_cli run [-h] --dir DIR --tag_set TAG_SET --signature_def
                           SIGNATURE_DEF_KEY [--inputs INPUTS]
                           [--input_exprs INPUT_EXPRS] [--outdir OUTDIR]
                           [--overwrite] [--tf_debug]

run コマンドは入力をモデルに渡す次の2つの方法を提供します :

  • –inputs オプションはファイルの numpy ndarray を渡すことを可能にします。
  • –input_exprs オプションは Python 式を渡すことを可能にします。

–inputs

ファイルで入力データを渡すためには、–inputs オプションを指定します、これは次の一般的な形式を取ります :

--inputs <INPUTS>

ここで INPUTS は次の形式のいずれかです :

  • <input_key>=<filename>

  • <input_key>=<filename>[<variable_name>]

複数の INPUTS を渡しても良いです。複数の inputs を渡す場合には、INPUTS の各々を分割するためにセミコロンを使用してください。

saved_model_cli はファイル名をロードするために numpy.load を使用します。ファイル名は次の形式のどれでも良いです :

  • .npy
  • .npz
  • pickle 形式

.npy ファイルは常に numpy ndarray を含みます。従って、.npy ファイルからロードするときは、内容は指定された入力テンソルに直接的に割り当てられます。もし variable_name をその .npy ファイルで指定した場合には、variable_name は無視されて警告が発行されるでしょう。

.npz (zip) ファイルからロードするときは、入力テンソル・キーに対してロードするために zip ファイル内の変数を識別するための variable_name をオプションで指定しても良いです。variable_name を指定しない場合には、SavedModel CLI は zip ファイルに一つのファイルだけが含まれていることを確認して指定された入力テンソル・キーのためにそれをロードします。

pickle ファイルからロードするときは、角括弧 (= square brackets) で variable_name が指定されない場合、pickle ファイル内が何であれそれが指定された入力テンソル・キーに渡されます。そうでなければ、SavedModel CLI は辞書が pickle ファイルにストアされていると仮定して variable_name に相当する値が使用されるでしょう。

–inputs_exprs

Python 式を通して入力を渡す場合には、–input_exprs オプションを指定します。これは、転がっているデータファイルを持たないが、しかし依然として (モデルの SignatureDefs の dtype と shape に適合する) 何某かの単純な入力でモデルをサニティ・チェックすることを望むときのために有用です。例えば :

`input_key=[[1], [2], [3]]`

Python 式に加えて、numpy 関数を渡しても良いです。例えば :

input_key=np.ones((32, 32, 3))

(numpy モジュールは np として既に利用可能であることに注意してください。)

出力をセーブする

デフォルトでは、SavedModel CLI は出力を stdout に書きます。もしディレクトリが –outdir オプションで渡された場合は、出力は出力テンソル・キーにちなんで命名された npy ファイルとして与えられたディレクトリ下にセーブされます。

既存の出力ファイルに上書きするためには –overwrite を使用します。

TensorFlow デバッガー (tfdbg) 統合

–tf_debug オプションがセットされた場合は、SavedModel CLI は TensorFlow デバッガー (tfdbg) を使用して SavedModel を実行する間、中間テンソルと実行時グラフまたはサブグラフを監視します。

完全なサンプル

以下を仮定した場合 :

  • モデルは単に x1 と x2 を加算して出力 y を得ます。
  • モデルの総てのテンソルは shape (-1, 1) を持ちます。
  • 2つの npy ファイルを持ちます :
  • /tmp/my_data1.npy, これは numpy ndarray [[1], [2], [3]] を含みます。
  • /tmp/my_data2.npy, これは他の numpy ndarray [[0.5], [0.5], [0.5]] を含みます。

出力 y を得るためのモデルを通してこれら2つの npy ファイルを実行するには、 次のコマンドを発行します ;

$ saved_model_cli run --dir /tmp/saved_model_dir --tag_set serve \
--signature_def x1_x2_to_y --inputs x1=/tmp/my_data1.npy;x2=/tmp/my_data2.npy \
--outdir /tmp/out
Result for output key y:
[[ 1.5]
 [ 2.5]
 [ 3.5]]

先のサンプルを少し変更しましょう。今度は、2つの .npy ファイルの代わりに、今は .npz ファイルと pickle ファイルを持ちます。更に、既存の出力ファイルに上書きしたいとします。ここにコマンドがあります :

$ saved_model_cli run --dir /tmp/saved_model_dir --tag_set serve \
--signature_def x1_x2_to_y \
--inputs x1=/tmp/my_data1.npz[x];x2=/tmp/my_data2.pkl --outdir /tmp/out \
--overwrite
Result for output key y:
[[ 1.5]
 [ 2.5]
 [ 3.5]]

入力ファイルの代わりに python 式を指定しても良いです。例えば、次のコマンドは入力 x2 を Python 式で置き換えます :

$ saved_model_cli run --dir /tmp/saved_model_dir --tag_set serve \
--signature_def x1_x2_to_y --inputs x1=/tmp/my_data1.npz[x] \
--input_exprs 'x2=np.ones((3,1))'
Result for output key y:
[[ 2]
 [ 3]
 [ 4]]

モデルを TensorFlow デバッガー on で実行するためには、次のコマンドを発行します :

$ saved_model_cli run --dir /tmp/saved_model_dir --tag_set serve \
--signature_def serving_default --inputs x=/tmp/data.npz[x] --tf_debug

 

SavedModel ディレクトリの構造

SavedModel 形式でモデルをセーブするとき、TensorFlow は次のサブディレクトリとファイルから成る SavedModel ディレクトリを作成します :

assets/
assets.extra/
variables/
    variables.data-?????-of-?????
    variables.index
saved_model.pb|saved_model.pbtxt

ここで :

  • assets は語彙のような補助 (外部) ファイルを含むサブフォルダです。assets は特定の MetaGraphDef をロードするときに SavedModel 位置へコピーされ読まれます。
  • assets.extra はサブフォルダでここでは高位ライブラリとユーザがそれら自身のモデルと共存するアセットを追加できますが、グラフによりロードされません。このサブフォルダは SavedModel ライブラリにより管理されません。
  • variables は tf.train.Saver からの出力を含むサブフォルダです。
  • saved_model.pb または saved_model.pbtxt は SavedModel プロトコルバッファです。それは MetaGraphDef プロトコルバッファとしてグラフ定義を含みます。

単一の SavedModel は複数のグラフを表わすことができます。この場合、SavedModel の総てのグラフはチェックポイント (variables) と assets の単一のセットを共有します。例えば、次のダイアグラムは3つの MetaGraphDefs を含む一つの SavedModel を示します、それらの3つ総てはチェックポイントと assets の同じセットを共有します :

 
以上



TensorFlow : Deploy : TensorFlow Serving と Kubernetes で Inception モデルをサービス提供する

TensorFlow : Deploy : TensorFlow Serving と Kubernetes で Inception モデルをサービス提供する (翻訳)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 09/09/2017

* 本ページは、TensorFlow 本家サイトの Deploy : TensorFlow Serving – Serving Inception Model with TensorFlow Serving and Kubernetes を翻訳した上で適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

このチュートリアルでは、Docker コンテナで動作する TensorFlow Serving コンポーネントを TensorFlow Inception モデルをサービス提供するためにどのように使用するかそして serving クラスタを Kubernetes でどのように配備するかを示します。

TensorFlow Serving についてより学習するためには、TensorFlow Serving 基本チュートリアルTensorFlow Serving 上級チュートリアル を推奨します。

TensorFlow Inception モデルについてより学習するためには、Inception in TensorFlow を推奨します。

  • パート 0 は配備のための TensorFlow Serving Docker イメージをどのように作成するかを示します。
  • パート 1 はローカル・コンテナでイメージをどのように実行するかを示します。
  • パート 2 は Kubernetes でどのように配備するかを示します。

 

パート 0: Docker イメージを作成する

TensorFlow Serving Docker イメージを構築することについての詳細は Using TensorFlow Serving via Docker を参照してください。

コンテナを実行する

Dockerfile.devel を使用してベースイメージ $USER/tensorflow-serving-devel を構築します。そしてビルド・イメージを使用してコンテナをローカルでスタートさせます。

$ docker build --pull -t $USER/tensorflow-serving-devel -f tensorflow_serving/tools/docker/Dockerfile.devel .
$ docker run --name=inception_container -it $USER/tensorflow-serving-devel

コンテナで TensorFlow Serving を clone、configure そしてビルドする

Note: 後述のすべての bazel ビルド・コマンドは標準的な -c opt フラグを使用します。ビルドをさらに最適化するためには、ここの手順 を参照してください。

実行中のコンテナ内で、clone して configure して、そして TensorFlow Serving サンプル・コードをビルドします。

root@c97d8e820ced:/# git clone --recurse-submodules https://github.com/tensorflow/serving
root@c97d8e820ced:/# cd serving/tensorflow
root@c97d8e820ced:/serving/tensorflow# ./configure
root@c97d8e820ced:/serving# cd ..
root@c97d8e820ced:/serving# bazel build -c opt tensorflow_serving/example/...

次に TensorFlow ModelServer を ここの手順 を使用して apt-get でインストールするか、以下を使用して ModelServer バイナリをビルドします :

root@c97d8e820ced:/serving# bazel build -c opt tensorflow_serving/model_servers:tensorflow_model_server

このチュートリアルの残りでは貴方が ModelServer をローカルでコンパイルしたことを仮定します、その場合はそれを実行するためにコマンドは bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server です。けれどももし apt-get を使用して ModelServer をインストールした場合には、単にそのコマンドを tensorflow_model_server で置き換えてください。

コンテナで Inception モデルをエクスポートする

実行中のコンテナで、リリースされた Inception モデル訓練チェックポイント を使用して inception モデルをエクスポートするために inception_saved_model.py を実行します。ゼロから訓練する代わりに、推論グラフをリストアしてそれを直接エクスポートするために良く訓練された variable の容易に利用可能なチェックポイントを使用します。

root@c97d8e820ced:/serving# curl -O http://download.tensorflow.org/models/image/imagenet/inception-v3-2016-03-01.tar.gz
root@c97d8e820ced:/serving# tar xzf inception-v3-2016-03-01.tar.gz
root@c97d8e820ced:/serving# ls inception-v3
README.txt  checkpoint  model.ckpt-157585
root@c97d8e820ced:/serving# bazel-bin/tensorflow_serving/example/inception_saved_model --checkpoint_dir=inception-v3 --output_dir=inception-export
Successfully loaded model from inception-v3/model.ckpt-157585 at step=157585.
Successfully exported model to inception-export
root@c97d8e820ced:/serving# ls inception-export
1
root@c97d8e820ced:/serving# [Ctrl-p] + [Ctrl-q]

配備のためにイメージを Commit

上の手順の最後で (コンテナを) 停止する代わりにコンテナからデタッチしていることに注意してください、何故ならば Kubernetes 配備のために総ての変更を新しいイメージ $USER/inception_serving に commit したいからです。

$ docker commit inception_container $USER/inception_serving
$ docker stop inception_container

 

パート 1: ローカル Docker コンテナ内で実行する

ビルドしたイメージを使用して serving ワークフローをローカルでテストしましょう。

$ docker run -it $USER/inception_serving

サーバをスタートする

コンテナで gRPC tensorflow_model_server を実行する。

root@f07eec53fd95:/# cd serving
root@f07eec53fd95:/serving# bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server --port=9000 --model_name=inception --model_base_path=inception-export &> inception_log &
[1] 45

サーバに問い合わせる

inception_client.py でサーバに問い合わせます。クライアントはコマンドライン・パラメータで指定された画像を ImageNet カテゴリの人間に読める説明への分類のために gRPC を通してサーバに送ります。

root@f07eec53fd95:/serving# bazel-bin/tensorflow_serving/example/inception_client --server=localhost:9000 --image=/path/to/my_cat_image.jpg
outputs {
  key: "classes"
  value {
    dtype: DT_STRING
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 5
      }
    }
    string_val: "tiger cat"
    string_val: "Egyptian cat"
    string_val: "tabby, tabby cat"
    string_val: "lynx, catamount"
    string_val: "Cardigan, Cardigan Welsh corgi"
  }
}
outputs {
  key: "scores"
  value {
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 5
      }
    }
    float_val: 9.5486907959
    float_val: 8.52025032043
    float_val: 8.05995368958
    float_val: 4.30645561218
    float_val: 3.93207240105
  }
}

root@f07eec53fd95:/serving# exit

 
動きました!サーバは貴方の猫の画像を成功的に分類しました。

 

パート 2: Kubernetes 内で配備する

このセクションでは Google Cloud Platform において Kubernetes で serving クラスタを配備するためにパート 0 でビルドしたコンテナ・イメージを使用します。

GCloud プロジェクト・ログイン

ここでは貴方が tensorflow-serving という名前の gcloud project を作成してログインしていることを仮定しています。

$ gcloud auth login --project tensorflow-serving

コンテナ・クラスタを作成する

最初にサービス配備のために Google Container Engine クラスタを作成します。

$ gcloud container clusters create inception-serving-cluster --num-nodes 5
Creating cluster inception-serving-cluster...done.
Created [https://container.googleapis.com/v1/projects/tensorflow-serving/zones/us-central1-f/clusters/inception-serving-cluster].
kubeconfig entry generated for inception-serving-cluster.
NAME                       ZONE           MASTER_VERSION  MASTER_IP        MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
inception-serving-cluster  us-central1-f  1.1.8           104.197.163.119  n1-standard-1  1.1.8         5          RUNNING

 
gcloud container コマンドのためのデフォルト・クラスタを設定して kubectl にクラスタ credentials を渡します。

$ gcloud config set container/cluster inception-serving-cluster
$ gcloud container clusters get-credentials inception-serving-cluster
Fetching cluster endpoint and auth data.
kubeconfig entry generated for inception-serving-cluster.

Docker イメージをアップロードする

さて私たちのイメージを Google Cloud Platform 上でそれを実行できるように Google Container Registry に push しましょう。

最初に Container Registry フォーマットとプロジェクト名を使用して $USER/inception_serving イメージにタグ付けします、

$ docker tag $USER/inception_serving gcr.io/tensorflow-serving/inception

次にイメージをレジストリに push します。

$ gcloud docker -- push gcr.io/tensorflow-serving/inception

Kubernetes Deployment とサービスを作成する

配備は、Kubernetes Deployment で制御される inception_inference サーバの3つのレプリカから成ります。レプリカは Kubernetes サービス により External ロードバランサと共に外部的に晒されます。

サンプル Kubernetes config inception_k8s.yaml を使用してそれらを作成します。

$ kubectl create -f tensorflow_serving/example/inception_k8s.yaml
deployment "inception-deployment" created
service "inception-service" created

deployment と pods のステータスを見るためには :

$ kubectl get deployments
NAME                    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
inception-deployment    3         3         3            3           5s
$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
inception-deployment-bbcbc   1/1       Running   0          10s
inception-deployment-cj6l2   1/1       Running   0          10s
inception-deployment-t1uep   1/1       Running   0          10s

サービスのステータスを見るためには :

$ kubectl get services
NAME                    CLUSTER-IP       EXTERNAL-IP       PORT(S)     AGE
inception-service       10.239.240.227   104.155.184.157   9000/TCP    1m

総てがアップして実行中になるにはしばらくかかります。

$ kubectl describe service inception-service
Name:           inception-service
Namespace:      default
Labels:         run=inception-service
Selector:       run=inception-service
Type:           LoadBalancer
IP:         10.239.240.227
LoadBalancer Ingress:   104.155.184.157
Port:           <unset> 9000/TCP
NodePort:       <unset> 30334/TCP
Endpoints:      <none>
Session Affinity:   None
Events:
  FirstSeen LastSeen    Count   From            SubobjectPath   Type        Reason      Message
  --------- --------    -----   ----            -------------   --------    ------      -------
  1m        1m      1   {service-controller }           Normal      CreatingLoadBalancer    Creating load balancer
  1m        1m      1   {service-controller }           Normal      CreatedLoadBalancer Created load balancer

サービス外部 IP アドレスは LoadBalancer Ingress のすぐ次にリストされています。

モデルを問い合わせる

今、ローカルホストから (サービスの) 外部アドレスのサービスを問い合わせることができます。

$ bazel-bin/tensorflow_serving/example/inception_client --server=104.155.184.157:9000 --image=/path/to/my_cat_image.jpg
outputs {
  key: "classes"
  value {
    dtype: DT_STRING
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 5
      }
    }
    string_val: "tiger cat"
    string_val: "Egyptian cat"
    string_val: "tabby, tabby cat"
    string_val: "lynx, catamount"
    string_val: "Cardigan, Cardigan Welsh corgi"
  }
}
outputs {
  key: "scores"
  value {
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 5
      }
    }
    float_val: 9.5486907959
    float_val: 8.52025032043
    float_val: 8.05995368958
    float_val: 4.30645561218
    float_val: 3.93207240105
  }
}

 
Kubernetes のサービスとしてサーブする Inception モデルを成功的に配備しました!

 
以上


TensorFlow : Deploy : TensorFlow Serving : 標準的な TensorFlow ModelServer を構築する

TensorFlow : Deploy : TensorFlow Serving : 標準的な TensorFlow ModelServer を構築する (翻訳)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 09/07/2017

* 本ページは、TensorFlow 本家サイトの Deploy : TensorFlow Serving – Building Standard TensorFlow ModelServer を翻訳した上で適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

このチュートリアルは、訓練された TensorFlow モデルの新しいバージョンを動的に探索してサーブする、標準的な TensorFlow ModelServer をビルドするために TensorFlow コンポーネントをどのように使用するかを示します。もし貴方のモデルをサーブするために標準的なサーバを使用したいだけであるならば、TensorFlow Serving 基本チュートリアル を見てください。

このチュートリアルは、手書き画像 (MNIST データ) 分類のための TensorFlow チュートリアルで紹介された単純な Softmax 回帰モデルを使用します。もし貴方が TensorFlow または MNIST が何であるか知らないのであれば、ML 初心者向けの MNIST を見てください。

このチュートリアルのためのコードは2つのパートから成ります :

  • Python ファイル、mnist_saved_model.py これはモデルの複数のバージョンを訓練してエクスポートします。
  • C++ ファイル main.cc、これは標準的な TensorFlow ModelServer で新しいエクスポートされたモデルを探索してそれらをサーブ (サービス提供) するために gRPC サービスを実行します。

このチュートリアルは次のタスクを通して進みます :

  1. TensorFlow モデルを訓練してエクスポートする。
  2. TensorFlow Serving ServerCore でモデル・バージョニングを管理する。
  3. SessionBundleSourceAdapterConfig を使用してバッチ処理を構成する。
  4. TensorFlow Serving ServerCore でリクエストにサーブする。
  5. サービスを実行してテストする。

始める前に、(インストール) 要件 は完了しておいてください。

Note: 後述のすべての bazel ビルド・コマンドは標準的な -c opt フラグを使用します。ビルドをさらに最適化するためには、ここの手順 を参照してください。

 

TensorFlow モデルを訓練してエクスポートする

export ディレクトリが既に存在しているならばクリアします :

$>rm -rf /tmp/mnist_model

モデルの最初のバージョンを (100 反復で) 訓練してエクスポートする :

$>bazel build -c opt //tensorflow_serving/example:mnist_saved_model
$>bazel-bin/tensorflow_serving/example/mnist_saved_model --training_iteration=100 --model_version=1 /tmp/mnist_model

 
モデルの2番目のバージョンを (2000 反復で) 訓練してエクスポートする :

$>bazel-bin/tensorflow_serving/example/mnist_saved_model --training_iteration=2000 --model_version=2 /tmp/mnist_model

 
mnist_saved_model.py で見れるように、訓練とエクスポートは TensorFlow Serving 基本チュートリアルにおけるものと同じように行なわれます。デモ目的では、最初の実行のために訓練反復を意図的に抑えて v1 としてエクスポートして、その一方で2番目の実行のために通常のようにそれを訓練して同じ親ディレクトリに v2 としてエクスポートします — より徹底した訓練で後者により良い分類精度を獲得することを期待しますので。mnist_model ディレクトリで各訓練実行のための訓練データを見るでしょう :

$>ls /tmp/mnist_model
1  2

 

ServerCore

さて新しいアルゴリズムが実験されている時、あるいはモデルが新しいデータセットで訓練されている時、モデルの v1 と v2 が実行時に動的に生成されることを想像してください。本番環境では、段階的なロールアウトをサポート可能なサーバをビルドすることを望むかもしれません、そこでは v1 をサーブする一方で v2 が探索され、ロードされ、実験され、モニターされ、あるいは元に戻されます。あるいは、v2 を持ってくる前に v1 を取り壊すことを望むかもしれません。TensorFlow Serving は両方のオプションをサポートします — 一つは移行 (transition) 時の可用性を維持するのに良く、他方はリソース使用 (e.g. RAM) を最小化するのに良いです。

TensorFlow Serving Manager は正確にそれを行ないます。それは、それらのロード、サービングそしてアンロード、更にはバージョン移行を含む TensorFlow モデルの完全なライフサイクルを処理します。このチュートリアルでは、内部的には AspiredVersionsManager をラップする、TensorFlow Serving ServerCore の上に貴方のサーバを構築します。

int main(int argc, char** argv) {
  ...

  ServerCore::Options options;
  options.model_server_config = model_server_config;
  options.servable_state_monitor_creator = &CreateServableStateMonitor;
  options.custom_model_config_loader = &LoadCustomModelConfig;

  ::google::protobuf::Any source_adapter_config;
  SavedModelBundleSourceAdapterConfig
      saved_model_bundle_source_adapter_config;
  source_adapter_config.PackFrom(saved_model_bundle_source_adapter_config);
  (*(*options.platform_config_map.mutable_platform_configs())
      [kTensorFlowModelPlatform].mutable_source_adapter_config()) =
      source_adapter_config;

  std::unique_ptr<ServerCore> core;
  TF_CHECK_OK(ServerCore::Create(options, &core));
  RunServer(port, std::move(core));

  return 0;
}

ServerCore::Create() は ServerCore::Options パラメータを取ります。ここに2、3の一般に使用されるオプションがあります :

  • ModelServerConfig はロードされるモデルを指定します。モデルは、モデルの静的リストを宣言する model_config_list を通してか、実行時に更新されるかもしれないモデルのリストを宣言する custom_model_config を通して宣言されます。
  • PlatformConfigMap、これは (tensorflow のような) プラットフォームの名前から PlatformConfig へマップします、これは SourceAdapter を作成するために使用されます。SourceAdapter は StoragePath (モデル・バージョンが探索されるパス) をモデル Loader (モデル・バージョンをストレージ・パスからロードして Manager に状態移行 (= state transition) インターフェイスを提供する) に適合させます。PlatformConfig が SavedModelBundleSourceAdapterConfig を含むのであれば、SavedModelBundleSourceAdapter が作成され、これは後で説明されます。

SavedModelBundle は TensorFlow Serving の基本的なコンポーネントです。それは与えられたパスからロードされた TensorFlow モデルを表してそして TensorFlow が推論を実行するのと同じ Session::Run インターフェイスを提供します。SavedModelBundleSourceAdapter はストレージ・パスを Loader に適合させることによってモデル・ライフタイムは Manger に管理されます。SavedModelBundle は deprecated な SessionBundle の後継であることに注意してください。ユーザは SavedModelBundle を使用することが推奨されます、何故ならば SessionBundle のサポートは間もなく取り除かれますので。

これら総てとともに、ServerCore は内部的には以下を行ないます :

  • FileSystemStoragePathSource をインスタンス化します、これは model_config_list で宣言されたモデル export パスをモニタします。
  • model_config_list で宣言されたモデル・プラットフォームを持つ PlatformConfigMap を使用して SourceAdapter をインスタンス化して、FileSystemStoragePathSource をそれに接続します。このように、export パス下で新しいモデル・バージョンが探索された時はいつでも、SavedModelBundleSourceAdapter はそれを Loader に適合させます。
  • AspiredVersionsManager と呼ばれる Manager の特定の実装をインスタンス化します、これは SavedModelBundleSourceAdapter により作成された総てのそのような Loader インスタンスを管理します。ServerCore は Manager インターフェイスを呼び出しを AspiredVersionsManager に委任することによりエクスポートします。

新しいバージョンが利用可能なときはいつでも、この AspiredVersionsManager は新しいバージョンをロードし、そしてそのデフォルトの挙動では古いものをアンロードします。もし貴方がカスタマイズを始めることを望むのであれば、それが内部的に作成するコンポーネントとそれをどのように構成するかを理解することが奨励されます。

TensorFlow Serving は非常に柔軟で拡張性があるように最初から設計されていることに言及することは価値があるでしょう。ServerCore と AspiredVersionsManager のような一般的なコア・コンポーネントを活用する一方で、システムの挙動をカスタマイズするために様々なプラグインをビルドできます。例えば、ローカル・ストレージの代わりにクラウド・ストレージをモニタする data source プラグインをビルドできますし、あるいは異なる方法でバージョン移行を行なう version policy プラグインをビルドすることもできるでしょう — 実際に、non-TensorFlow モデルをサーブする custom model プラグインをビルドすることさえできるでしょう。これらのトピックはこのチュートリアルの範囲外です。けれども、更なる情報のために custom sourcecustom servable チュートリアルを参照可能です。

 

バッチ処理

本番環境で望むもう一つの典型的なサーバ特徴はバッチ処理です。機械学習の推論を行なうために使用される現代的なハードウェア・アクセラレータ (GPU, etc.) は推論リクエストが巨大なバッチで実行されるときに通常はベストな計算効率を達成します。SavedModelBundleSourceAdapter を作成するときに適切な SessionBundleConfig を提供することによりバッチ処理は有効になります。このケースでは BatchingParameters を殆どデフォルト値で設定します。バッチ処理は custom timeout, batch_size, etc. 値を設定することで微調整できます。詳細は、BatchingParameters を参照してください (訳注: リンクなし)。

SessionBundleConfig session_bundle_config;
// Batching config
if (enable_batching) {
  BatchingParameters* batching_parameters =
      session_bundle_config.mutable_batching_parameters();
  batching_parameters->mutable_thread_pool_name()->set_value(
      "model_server_batch_threads");
}
*saved_model_bundle_source_adapter_config.mutable_legacy_config() =
    session_bundle_config;

バッチ全体に到達した時、推論リクエストは内部的に単一の巨大なリクエスト (テンソル) にマージされ、tensorflow::Session::Run() が呼び起こされます (これは GPU 上の実際の効率上の有益が由来する場所です)。

 

Manager でサーブする

上述したように、TensorFlow Serving Manager は任意の機械学習システムにより生成されるモデルのロード、サーブ、アンロードとバージョン移行を処理する一般的なコンポーネントとして設計されています。その API は次の基本的な概念を中心として構築されています :

  • Servable: Servable は、クライアント・リクエストにサーブすることに使用できる任意の Opaque (型) オブジェクトです。servable のサイズと粒度 (= granularity) は柔軟で、単一の servable は単一の機械学習されたモデルへの検索テーブルの単一のシャードからモデルのタプルまで任意のものを含むかもしれません。servable は任意の型とインターフェイスを取ることができます。
  • Servable Version: Servable はバージョン化され TensorFlow Serving Manager は servable の一つまたはそれ以上の version を管理できます。バージョニングは servable の一つのバージョン以上が同時にロードされることを許可し、段階的なロールアウトと実験をサポートします。
  • Servable Stream: servable stream は、増加する version 番号を持つ、servable の version のシークエンスです。
  • Model: 機械学習されたモデルは一つまたはそれ以上の servable で表されます。servable のサンプルは :
    • TensorFlow session またはそれ回りの SavedModelBundle のような、ラッパー。
    • 他の種類の機械学習されたモデル。
    • 語彙検索テーブル。
    • 埋め込み検索テーブル。

    合成モデル (= composite model) は複数の独立した servable として、または単一の合成 servable として表されます。servable はまた、例えば多くの Manager インスタンスに渡るシャードされた巨大な検索ケーブルを持つ、モデルの断片にも相当するかもしれません。

これら総てをこのチュートリアルのコンテクストに集約するために :

  • TensorFlow モデルは一つの種類の servable で表されます — SavedModelBundle です。SavedModelBundle は内部的には、どのようなグラフが session にロードされるかそして推論のためにそれをどのように実行するかについての何某かの metadata を伴う tensorflow:Session から成ります。
  • TensorFlow エクスポートのストリームを含むファイルシステム・ディレクトリが、それぞれは名前がバージョン番号であるそれ自身のサブディレクトリ内にあります。外側のディレクトリは、サーブされる TensorFlow モデルのための servable stream のシリアライズ化された表現として考えることができます。各エクスポートはロード可能な servable に相当します。
  • AspiredVersionsManager は export stream をモニタし、総ての SavedModelBundle servable のライフサイクルを動的に管理します。

それから TensorflowPredictImpl::Predict は丁度 :

  • manager から (ServerCore を通して) SavedModelBundle をリクエストする。
  • PredictRequest の論理テンソル名を実際のテンソル名にマップして値をテンソルにバインドするために generic signatures を使用する。
  • 推論を実行する。

 

サーバをテストして実行する

エクスポート (されたモデル) の最初のバージョンをモニタされるフォルダーにコピーしてそしてサーバをスタートします。

$>mkdir /tmp/monitored
$>cp -r /tmp/mnist_model/1 /tmp/monitored
$>bazel build -c opt //tensorflow_serving/model_servers:tensorflow_model_server
$>bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server --enable_batching --port=9000 --model_name=mnist --model_base_path=/tmp/monitored

 
サーバは毎秒 “Aspiring version for servable …” というログ・メッセージを吐きます、これはそれがエクスポート (されたモデル) を見つけて、その存続を追跡中であることを意味します。–concurrency=10 とともに実行します。これはサーバに同時リクエストを送りそしてバッチ処理ロジックのトリガーとなります。

$>bazel build -c opt //tensorflow_serving/example:mnist_client
$>bazel-bin/tensorflow_serving/example/mnist_client --num_tests=1000 --server=localhost:9000 --concurrency=10
...
Inference error rate: 13.1%

 
それからエクスポート (されたモデル) の2番目のバージョンをモニタされるフォルダにコピーしてテストを再実行します :

$>cp -r /tmp/mnist_model/2 /tmp/monitored
$>bazel-bin/tensorflow_serving/example/mnist_client --num_tests=1000 --server=localhost:9000 --concurrency=10
...
Inference error rate: 9.5%

 
これは貴方のサーバが自動的に新しいバージョンを探索してそれを serving のために使用していることを確かなものとします!

 
以上



TensorFlow : Deploy : TensorFlow Serving : TensorFlow モデルをサーブする

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% 推論エラー率を得ます。これはサーバが訓練されたモデルを成功的にロードして実行することを確かめます!

 
以上


TensorFlow : Deploy : TensorFlow Serving : インストール

TensorFlow : Deploy : TensorFlow Serving: インストール (翻訳)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 09/01/2017

* 本ページは、TensorFlow 本家サイトの Deploy : TensorFlow Serving – Installation を翻訳した上で
適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

要件

TensorFlow Serving をコンパイルして使用するためには、幾つかの要件をセットアップする必要があります。

Bazel (ソースコードをコンパイルする場合のみ)

TensorFlow Serving は Bazel 0.45 またはそれ以上を要求します。Bazel インストレーション手順は ここ で見つかります。

Bazel のための要件を満たす場合、それらの手順は次のステップから成ります :

  1. 関連したバイナリを ここ からダウンロードします。bazel-0.4.5-installer-linux-x86_64.sh をダウンロードしたとします。貴方は次を実行するでしょう :
    cd ~/Downloads
    chmod +x bazel-0.4.5-installer-linux-x86_64.sh
    ./bazel-0.4.5-installer-linux-x86_64.sh --user
    
  2. 環境をセットアップします。これを ~/.bashrc に置きます。
    export PATH="$PATH:$HOME/bin"
    

gRPC

チュートリアルは RPC フレームワークとして gRPC (1.0.0 またはそれ以上) を使用します。インストール手順は ここ で見つかります。

パッケージ

TensorFlow Serving 依存をインストールするためには、次を実行します :

sudo apt-get update && sudo apt-get install -y \
        build-essential \
        curl \
        libcurl3-dev \
        git \
        libfreetype6-dev \
        libpng12-dev \
        libzmq3-dev \
        pkg-config \
        python-dev \
        python-numpy \
        python-pip \
        software-properties-common \
        swig \
        zip \
        zlib1g-dev

TensorFlow Serving Python API PIP パッケージ

Bazel をインストールする必要なく Python クライアントコードを実行するためには、以下を利用して tensorflow-serving-api PIP パッケージをインストールすることができます :

pip install tensorflow-serving-api

 

apt-get を使用してインストールする

利用可能なバイナリ

TensorFlow Serving ModelServer バイナリは2つの変形 (= variant) で利用可能です :

tensorflow-model-server: 完全に最適化されたサーバで、SSE4 と AVX 命令のような幾つかのプラットフォームに特化されたコンパイラ最適化を使用しています。これは多くのユーザに好まれるオプションでしょう、しかしある(種の)より古いマシンでは動作しないかもしれません。

tensorflow-model-server-universal: 基本的な最適化でコンパイルされていますが、プラットフォームに特化された命令セットは含みませんので、世の中のすべてのマシンでないにしても殆どの上で動作するはずです。貴方のために tensorflow-model-server が動作しないのであればこれを使用してください。バイナリ名が両方のパッケージについて同じですので、既に tensorflow-model-server をインストールしているならば、次を使用して最初にそれをアンインストールするべきです。

sudo apt-get remove tensorflow-model-server

ModelServer をインストールする

  1. パッケージ・ソースとして TensorFlow Serving ディストリビューション URI を追加する (ワンタイム・セットアップ)
    echo "deb [arch=amd64] http://storage.googleapis.com/tensorflow-serving-apt stable tensorflow-model-server tensorflow-model-server-universal" | sudo tee /etc/apt/sources.list.d/tensorflow-serving.list
    
    curl https://storage.googleapis.com/tensorflow-serving-apt/tensorflow-serving.release.pub.gpg | sudo apt-key add -
    
  2. TensorFlow ModelServer をインストールして更新する
    sudo apt-get update && sudo apt-get install tensorflow-model-server
    

一度インストールされれば、バイナリはコマンド tensorflow_model_server を使用して起動されます。

tensorflow-model-server のより新しいバージョンへは次でアップグレードできます :

sudo apt-get upgrade tensorflow-model-server

Note: 上のコマンドにおいて、もし貴方のプロセッサが AVX 命令をサポートしてないのであれば、tensorflow-model-server を tensorflow-model-server-universal で置き換えてください。

 

ソースからインストールする

TensorFlow Serving レポジトリを clone する

git clone --recurse-submodules https://github.com/tensorflow/serving
cd serving

–recurse-submodules は TensorFlow, gRPC, そして TensorFlow Serving が依存する他のライブラリを取得するために必要です。これらの手順は TensorFlow Serving の最新の master ブランチをインストールすることに注意してください。(release ブランチのような) 特定のブランチをインストールすることを望む場合には、git clone コマンドに -b を渡してください。

要件をインストールする

全ての依存をインストールするためには上述の要件セクションに追随してください。TensorFlow を configure するためには、以下を実行します

cd tensorflow
./configure
cd ..

TensorFlow のセットアップやその依存の問題にぶつかったならば TensorFlow インストール手順 を調べてください。

ビルド

TensorFlow Serving はビルドに Bazel を使用します。個々のターゲットや全体のソースツリーをビルドするためには Bazel コマンドを使用します。

全体のツリーをビルドするためには、以下を実行します :

bazel build -c opt tensorflow_serving/...

バイナリは bazel-bin ディレクトリに置かれ、次のようなコマンドを使用して実行できます :

bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server

インストールをテストするためには、以下を実行します :

bazel test -c opt tensorflow_serving/...

TensorFlow Serving を実行するより掘り下げたサンプルについては basic tutorialadvanced tutorial を見てください。

最適化されたビルド

幾つかのプラットフォームに特化した命令セット (e.g. AVX) を使用してコンパイルすることができます、これは本質的にパフォーマンスを改善できます。このドキュメントで ‘bazel build’ を見る場所ではどこでも、フラグ -c opt –copt=-msse4.1 –copt=-msse4.2 –copt=-mavx –copt=-mavx2 –copt=-mfma –copt=-O3 (あるいはこれらのフラグの幾つかのサブセット) を追加することができます。例えば :

bazel build -c opt --copt=-msse4.1 --copt=-msse4.2 --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-O3 tensorflow_serving/...

Note: これらの命令セットはすべてのマシン上で利用可能ではありません、特により古いプロセッサでは。そのためすべてのフラグでは動作しないかもしれません。それらのあるサブセットを試すか、基本的な ‘-c opt’ だけに戻すこともできます。

継続的インテグレーション・ビルド

TensorFlow ci_build インフラを使用した継続的インテグレーション・ビルドは docker を利用した単純化された開発を貴方に提供します。貴方の必要なものすべては git と docker です。すべての他の依存を手動でインストールする必要はありません。

git clone --recursive https://github.com/tensorflow/serving
cd serving
CI_TENSORFLOW_SUBMODULE_PATH=tensorflow tensorflow/tensorflow/tools/ci_build/ci_build.sh CPU bazel test //tensorflow_serving/...

Note: serving ディレクトリはコンテナ内にマップされます。貴方は docker コンテナの外側で (貴方のお気に入りのエディタで) 開発が可能でそしてこのビルドを実行する時、それは貴方の変更と一緒にビルドするでしょう。

 
以上


TensorFlow : Deploy : TensorFlow Serving : アーキテクチャ概要

TensorFlow : Deploy : TensorFlow Serving: アーキテクチャ概要 (翻訳)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 08/31/2017

* 本ページは、TensorFlow の本家サイトの Deploy : TensorFlow Serving – Architecture Overview を翻訳した上で
適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

TensorFlow Serving は機械学習モデルのための柔軟で、高パフォーマンスなサービング・システムで、本番環境 (= production environments) のためにデザインされています。TensorFlow Serving は同じサーバ・アーキテクチャと API を保持したまま、新しいアルゴリズムと実験を配備することを簡単にします。TensorFlow Serving は TensorFlow モデルとの独創的な統合を提供しますが、他のタイプのモデルをサーブするために簡単に拡張できます。

 

キー・コンセプト

TensorFlow Serving のアーキテクチャを理解するためには、以下ののキー・コンセプトを理解する必要があります :

Servable

Servable は TensorFlow Serving 内の中心的な抽象です。Servable はクライアントが計算 (例えば、検索や推論) を実行するために利用する、基礎となるオブジェクトです。

Servable のサイズや粒度 (= granularity) は柔軟です。単一の Servable は、単一のモデルへの検索テーブルの単一のシャードから推論モデルのタプルまで任意のものを含むかもしれません。

Servable は任意の型とインターフェイスから成ることができ、柔軟性と以下のような将来的な改良を可能にします :

  • ストリーミングの結果
  • 実験的な API
  • 演算の非同期モデル

Servable はそれら自身のライフサイクルは管理しません。

典型的な servable は次を含みます :

  • TensorFlow SavedModelBundle (tensorflow::Session)
  • embedding や語彙検索のための検索テーブル

Servable Version

TensorFlow Serving は、単一のサーバ・インスタンスの生存時間 (= lifetime) に渡り一つまたはそれ以上の servable の version を扱うことができます。これは新たなアルゴリズムの configuration、重み、そして他のデータが時間をかけてロードされることを可能にします。version は servable の一つ以上のバージョンが同時にロードされることを可能にし、段階的な (= gradual) ロールアウトと実験をサポートします。serving 時には、クライアントは特定のモデルに対して、最新バージョンか特定のバージョン id をリクエストできます。

Servable Stream

servable stream は servable の version のシークエンスで、増加する version ナンバーによりソートされます。

Model

TensorFlow Serving は model を一つまたはそれ以上の servable として表します。機械学習されたモデルは一つまたはそれ以上の (学習された重みを含む) アルゴリズムと検索または embedding テーブルを含みます。

composite model (合成モデル) は次のどちらかとして表すことができます :

  • 複数の独立した servable
  • 単一の composite servable

servable はまたモデルの断片 (= fraction) にも相当するかもしれません。例えば、巨大な検索テーブルは多くの TensorFlow Serving インスタンスに渡りシャードされるでしょう。

Loader

Loader は servable のライフサイクルを管理します。Loader API は特定の学習アルゴリズム、データまたは付随する製品ユースケースからは独立な共通インフラを可能にします。特に、Loader は servable をロードとアンロードするための API を標準化します。

Source

Source は servable を開始するプラグイン・モジュールです; 各 Source はゼロまたはそれ以上の servable stream を開始します。各 stream に対して、Source はロードすることを望んだ各 version のために一つの Loader を供給します。(正確に言えば、Source は実際にはゼロまたはそれ以上の SourceAdapter と一緒に連鎖していて、鎖の最後のアイテムが Loader を発行します。)

Source のための TensorFlow Serving のインターフェイスは単純で限定的ですので、ロードするための servable を探索するためには任意のストレージ・システムを貴方に使用させます。Source は RPC のような他のメカニズムにアクセスするかもしれません。TensorFlow Serving は共通のリファレンス Source 実装を含みます。例えば、TensorFlow Serving はファイルシステムをポーリングできます。

差分更新 (= delta update) を効率的に受け取るモデルのような特別なケースのために、Source は複数の servable または version に渡り共有される状態を保持することができます。

Aspired Version

Aspired version はロードされて準備されるべき servable version のセットを表します。Source は、単一の servable stream のための servable version のこのセットと同時に通信します。Source が Manager に aspired version の新しいリストを与えたとき、それはその servable stream のための以前のリストに取って替わります。Manager はもはやリストに現れない以前にロードされた version をアンロードします。

version ローディングが実際にどのように動作するかを見るためには advanced tutorial を参照してください。

Manager

Manager は Servable の完全ライフサイクルを処理し、以下を含みます :

  • Servable をロードする
  • Servable をサーブする
  • Servable をアンロードする

Manager は Source をリスンして全ての version を追跡します。Manager は Source のリクエストを実行しようとしますが、必要となるリソースが利用可能でない場合には aspired version のロードを拒否するかもしれません。Manager はまた “アンロード” を延期するかもしれません。例えば、少なくとも一つの version が常にロードされていることを保証するというポリシーをベースに、Manager は新しい vesion のロードが完了するまでアンロードを待つかもしれません。

TensorFlow Serving Manager は単純で、限定的なインターフェイス — GetServableHandle() — をロードされた servable インスタンスにアクセスするためにクライアントに提供します。

Core

TensorFlow Serving Core は (標準 TensorFlow Serving API を通して) servable の以下の局面を管理します :

  • ライフサイクル
  • メトリクス

TensorFlow Serving Core は servable と loader を opaque オブジェクトとして扱います。

 

Servable のライフ

大雑把に言えば :

  1. Source が Servable Version のために Loader を作成する。
  2. Loader は Aspired Version として Manager に送られ、これはそれらをクライアント要求にロードしてサーブします。

より詳細には :

  1. Source プラグインが特定の version のための Loader を作成します。Loader は Servable をロードするために必要などのようなメタデータも含みます。
  2. Source は Manager に Aspired Version を通知するためにコールバックを使用します。
  3. Manager は取るべき次のアクションを決定するために設定された Version Policy を適用します、これは以前にロードされた version のアンロードあるいは新しい version のロードかもしれません。
  4. Manager が安全であると決定した場合、それは Loader に必要なリソースを与え、Loader に新しい version をロードするように伝えます。
  5. クライアントは Manager に Servable を要求します、version を明示的に指定するか最新 version を単に要求するかです。

例えば、Source が頻繁に更新されるモデル重みを持つ TensorFlow グラフを表すとします。重みはディスクのファイルにストアされます。

  1. Source はモデル重みの新しい version を検出します。それはディスクのモデル・データへのポインタを含む Loader を作成します。
  2. Source は Dynamic Manager に Aspired Version を通知します。
  3. Dynamic Manager は Version Policy を適用して新しい version を決定します。
  4. Dynamic Manager は Loader に十分なメモリがあることを伝えます。Loader は TensorFlow グラフを新しい重みでインスタンス化します。
  5. クライアントはモデルの最新 version へのハンドルを要求し、そして Dynamic Manager は Servable の新しい version へのハンドルを返します。

 

拡張性

TensorFlow Serving は幾つかの拡張ポイントを提供します、そこでは貴方は新しい機能を追加することができます。

Version Policy

Version Policy は、単一の servable stream 内の version ローディングとアンローディングのシークエンスを指定します。

TensorFlow Serving は最も良く知られたユースケースに適合する2つの policy を含みます。これらは Availability Preserving Policy (version が一つもロードされないことを回避するため; 典型的には古いものをアンロードする前に新しい version をロードします) 、そして Resource Preserving Policy (2つの version が同時にロードされ、2倍のリソースが必要となることを回避します; 新しいものをロードする前に古い vesion をアンロードします) です。model の serving 可用性が重要でリソースが低コストであるTensorFlow Serving の単純な使用のために、 Availability Preserving Policy は、古いものをアンロードする前に新しい version がロードされて準備できていることを保証します。TensorFlow Serving の洗練された使用のためには、例えば複数のサーバ・インスタンスに渡る version を管理する時、 Resource Preserving Policy は最小のリソースを要求します(新しい version をロードするための余分なバッファなし)。

Source

新しい Source は新しいファイルシステム、クラウド製品 (= offerings) そしてアルゴリズム・バックエンドをサポートできます。TensorFlow Serving は新しい source を簡単に速く作成するために幾つかの共通のビルディング・ブロックを提供します。例えば、TensorFlow Serving は単純な source まわりのポーリング挙動ををラップするユティリティを含みます。Source は特定のアルゴリズムとデータ・ホスティング servable のための Loader に密接に関係しています。

詳しくはカスタム Source をどのように作成するかについての Custom Source 文書を見てください。

Loaders

Loader はアルゴリズムとデータ・バックエンドのための拡張ポイントです。TensorFlow はそのようなアルゴリズム・バックエンドの一つです。例えば、貴方は新しいタイプの servable 機械学習モデルのインスタンスをロードし、それへのアクセスを提供し、そしてアンロードするための新しい Loader を実装するでしょう。私たちは検索テーブルと追加アルゴリズムのための Loader を作成することを予期します。

カスタム servable をどのように作成するかを学習するためには Custom Servable 文書を見てください。

Batcher

複数のリクエストの単一のリクエストへのバッチングは本質的に推論の実行のコストを減少させることができます、特に GPU のようなハードウェア・アクセラレータが存在する場合です。TensorFlow Serving はリクエスト・バッチング・ウイジェットを含み、これはクライアントに、リクエストに渡る type-specific 推論を (アルゴリズム・システムがより効率的に扱える)バッチ・リクエストに簡単にバッチ化させます。更なる情報のためには Batching Guide を見てください。

 

Next Steps

TensorFlow Serving を始めるには、Basic Tutorial にトライしてください。

 
以上

AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com