新しいサービス可能なパスを検出するモジュールの作成

このドキュメントでは、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 を実装します。これは、 TStoragePathにバインドされた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 、希望するバージョンの要求をキャッチするモジュール、つまりアダプターまたはマネージャーです) )。