このドキュメントでは、TensorFlow Serving を拡張してさまざまなストレージ システムを監視し、提供する新しいモデル (バージョン) やデータを検出する方法について説明します。特に、新しいサブパスの出現についてストレージ システム パスを監視するモジュールの作成方法と使用方法について説明します。各サブパスは、ロードする新しいサービス可能なバージョンを表します。この種のモジュールは、 StoragePath
型 ( string
に typedefed) のオブジェクトを出力するため、 Source<StoragePath>
と呼ばれます。これは、ソースが検出した特定のパスからサービス可能なLoader
を作成するSourceAdapter
で構成できます。
まず、一般性についての注意事項
提供可能なデータへのハンドルとしてパスを使用する必要はありません。これは、サーバブルをシステムに取り込む 1 つの方法を示しているだけです。ご使用の環境で提供可能なデータがパスにカプセル化されていない場合でも、このドキュメントを読めば主要な抽象化を理解できます。環境に適したタイプのSource<T>
およびSourceAdapter<T1, T2>
モジュール (RPC または pub/sub メッセージ、データベース レコードなど) を作成するか、単純にモノリシックSource<std::unique_ptr<Loader>>
を作成するオプションがあります。 Source<std::unique_ptr<Loader>>
、サービング可能なローダーを直接発行します。
もちろん、ソースが出力するデータの種類が何であれ (POSIX パス、Google Cloud Storage パス、RPC ハンドルのいずれであっても)、それに基づいてサーバブルをロードできる付随モジュールが必要です。このようなモジュールはSourceAdapters
と呼ばれます。カスタムの作成については、 「カスタム サーバブル」ドキュメントで説明されています。 TensorFlow Serving には、TensorFlow がサポートするファイル システム内のパスに基づいて TensorFlow セッションをインスタンス化するためのものが付属しています。 RandomAccessFile
抽象化 ( tensorflow/core/public/env.h
) を拡張することで、追加のファイル システムのサポートを TensorFlow に追加できます。
このドキュメントでは、TensorFlow がサポートするファイル システムでパスを発行するソースの作成に焦点を当てます。最後に、ソースを既存のモジュールと組み合わせて使用して TensorFlow モデルを提供する方法のウォークスルーで終了します。
ソースの作成
FileSystemStoragePathSource
というSource<StoragePath>
のリファレンス実装があります ( sources/storage_path/file_system_storage_path_source*
にあります)。 FileSystemStoragePathSource
、特定のファイル システム パスを監視し、サブディレクトリの数値を監視し、それらの最新のものをロードしたいバージョンとして報告します。このドキュメントでは、 FileSystemStoragePathSource
の重要な側面について説明します。 FileSystemStoragePathSource
のコピーを作成し、ニーズに合わせて変更すると便利な場合があります。
まず、 FileSystemStoragePathSource
Source<StoragePath>
API を実装します。これは、 T
がStoragePath
にバインドされたSource<T>
API の特殊化です。 API は、単一のメソッドSetAspiredVersionsCallback()
で構成されます。このメソッドは、特定のサーブ可能なバージョンのセットをロードする必要があることを伝えるためにソースが呼び出すことができるクロージャを提供します。
FileSystemStoragePathSource
、非常に単純な方法で aspired-versions コールバックを使用します。ファイル システムを定期的に検査し (基本的にls
を実行します)、提供可能なバージョンと思われる 1 つ以上のパスを見つけた場合は、どれが最新バージョンであるかを判断して呼び出します。そのバージョンのみを含むサイズ 1 のリストを持つコールバック (デフォルト設定の下)。そのため、 FileSystemStoragePathSource
常に最大 1 つのサーブブルのロードを要求し、その実装はコールバックの冪等性を利用してステートレスを維持します (同じ引数でコールバックを繰り返し呼び出しても問題はありません)。
FileSystemStoragePathSource
には、構成プロトコル メッセージを受け取る静的初期化ファクトリー ( Create()
メソッド) があります。設定メッセージには、監視するベース パスや監視間隔などの詳細が含まれます。これには、発行するサービス可能なストリームの名前も含まれます。 (別のアプローチでは、ベース パスからサービス可能ストリーム名を抽出し、より深いディレクトリ階層の観察に基づいて複数のサービス可能ストリームを発行する可能性があります。これらのバリアントは、リファレンス実装の範囲を超えています。)
実装の大部分は、ファイル システムを定期的に検査するスレッドと、検出された数値サブパスを識別して並べ替えるためのいくつかのロジックで構成されます。スレッドはSetAspiredVersionsCallback()
内 ( Create()
内ではない) 内で起動されます。これは、ソースが「開始」する必要があるポイントであり、希望するバージョンのリクエストをどこに送信するかを認識しているためです。
ソースを使用して TensorFlow セッションをロードする
新しいソース モジュールをSavedModelBundleSourceAdapter
( servables/tensorflow/saved_model_bundle_source_adapter*
) と組み合わせて使用するとよいでしょう。これにより、ソースが TensorFlow エクスポートとして出力する各パスが解釈され、各パスが TensorFlow SavedModelBundle
サーバブルのローダーに変換されます。おそらく、 SavedModelBundle
アダプターをAspiredVersionsManager
にプラグインすることになります。これは、サーバブルの実際のロードと提供を処理します。これら 3 種類のモジュールを連鎖させて動作するサーバー ライブラリを取得する方法の良い例はservables/tensorflow/simple_servers.cc
にあります。以下は、メインのコード フローのウォークスルーです (エラー処理が不適切です。実際のコードはもっと注意する必要があります)。
まず、マネージャーを作成します。
std::unique_ptr<AspiredVersionsManager> manager = ...;
次に、 SavedModelBundle
ソース アダプターを作成し、マネージャーに接続します。
std::unique_ptr<SavedModelBundleSourceAdapter> bundle_adapter;
SavedModelBundleSourceAdapterConfig config;
// ... populate 'config' with TensorFlow options.
TF_CHECK_OK(SavedModelBundleSourceAdapter::Create(config, &bundle_adapter));
ConnectSourceToTarget(bundle_adapter.get(), manager.get());
最後に、パス ソースを作成し、それをSavedModelBundle
アダプターに接続します。
auto your_source = new YourPathSource(...);
ConnectSourceToTarget(your_source, bundle_adapter.get());
ConnectSourceToTarget()
関数 ( core/target.h
で定義されている) はSetAspiredVersionsCallback()
を呼び出してSource<T>
をTarget<T>
に接続するだけです ( Target
、希望するバージョンの要求をキャッチするモジュール、つまりアダプターまたはマネージャーです) )。