1. TFservingとは何か モデルをトレーニングし、それを外部の関係者に提供する必要がある場合は、モデルをオンラインでデプロイし、外部呼び出し用の適切なインターフェースを提供する必要があります。検討すべき質問としては、次のようなものがあります: - 展開するもの
- APIインターフェースの提供方法
- 複数のモデルに GPU リソースを割り当てる方法
- サービスを中断せずにオンラインモデルを更新する方法
現在、人気のディープラーニング フレームワークは Tensorflow と Pytorch です。Pytorch は適切なオンライン デプロイメント ソリューションを公式に提供していませんが、Tensorflow はオンライン モデル推論をデプロイするための TFserving ソリューションを提供しています。さらに、Model Server for Apache MXNet は、MXNet モデル用の推論サービスを提供します。 この記事は、TFServing の使用ガイドです。 pytorch または MXNet モデルを使用する場合は、ONNX を介して TFserving モデルに変換し、TFServing にデプロイすることもできます。 TFserving とは何でしょうか? TFserving は、2017 年に Google が開始したオンライン推論サービスです。クライアント サーバー アーキテクチャを採用しており、クライアントは gRPC および RESTfull API を介してモデル サービスと通信できます。 TFServing の機能: - モデルのバージョン管理とロールバックをサポート: マネージャーがモデルのバージョンを管理します
- 同時実行をサポートし、高いスループットを実現
- すぐに使用でき、カスタマイズ可能
- マルチモデルサービスをサポート
- バッチ処理をサポート
- ホットアップデートをサポート: ソースはローカルモデルをロードし、新しいモデルをロードする必要があることをマネージャーに通知し、マネージャーはモデルのバージョンをチェックし、ソースによって作成されたローダーにモデルをロードするように通知します。
- 分散モデルをサポート
2. TFservingのインストール TFserving を docker モードでインストールすることを強くお勧めします。これは docker と nvidia-docker (TFserving の GPU に必要) に依存します。 - #yum-utilsツールとデバイスマッパー関連の依存パッケージをインストールします
- yum をインストール -y yum-utils \
- デバイスマッパー永続データ \
- lvm2
- #docker-ce安定版のリポジトリを追加
- yum-config-manager \
- --リポジトリを追加\
- https://download.docker.com/linux/centos/docker-ce.repo
- #yum キャッシュ ファイルを更新する
- yum makecache 高速
- #インストール可能なすべての docker-ce バージョンを表示
- yum list docker-ce --showduplicates | sort -r
- # docker-ce をインストールする
- yum で docker-ce-17.12.1.ce-1.el7.centos をインストールします。
- #起動時にdocker-ceサービスが起動するようにする
- systemctl で docker.service を有効にする
- #Docker-ceサービスを開始する
- systemctl ドッカーを起動する
- #テストコンテナhello-worldを実行する
- docker run --rm hello-world
- # nvidia-docker2 をインストール
- yum インストール -y nvidia-docker2-2.0.3-1.docker17.12.1.ce
- # dockerサービスを再起動します
- サービスdockerの再起動
- docker pull tensorflow/serving:latest-gpu
- # docker pull tensorflow/serving:1.14.0-rc0-gpu などの他のバージョンを選択することもできます
注意: dockerのバージョンとnvidia-dockerは一致している必要があります - 最新のnvidia-dockerにはDocker 19.03が必要です。公式のhttps://github.com/NVIDIA/nvidia-dockerを参照してください。
- nvidia-docker2 は、19.03 未満の Docker バージョン (1.12 以上) をサポートしています。現在のサーバーには、18.09、1.17、1.13 があります https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(version-2.0)
3.TFserving使用方法の説明 3.1 モデル変換 TFserving モデルは TFserving 形式に変換する必要があります。通常のチェックポイントおよび pb 形式はサポートされていません。 TFserving モデルには .pb ファイルと変数ディレクトリ (空でも可) が含まれており、エクスポート形式は次のとおりです。 - ├── 1
- │ ├── saved_model.pb
- │ └── 変数
- ├── 2
- │ ├── saved_model.pb
- │ └── 変数
さまざまなディープラーニング フレームワークの変換パス: - (1) pytorch(.pth)-- > onnx(.onnx)-- > tensorflow(.pb) - > TFserving
- (2) keras(.h5) -- > tensorflow(.pb) -- > TFserving
- (3) テンソルフロー(.pb) - > TFserving
ここではpbからTFservingモデルへの変換の詳細な説明を示します。 - テンソルフローをtfとしてインポートする
- def create_graph(pb_file):
- """保存された GraphDef ファイルからグラフを作成し、セーバーを返します。"""
- # 保存された graph_def.pb からグラフを作成します。
- tf.gfile.FastGFile(pb_file, 'rb') を f として:
- graph_def = tf .GraphDef()
- graph_def.ParseFromString(f.read())
- _ = tf .import_graph_def(graph_def、名前= '' )
- pb_to_tfserving を定義します(pb_file、export_path、 pb_io_name = []、 input_node_name = 'input' 、 output_node_name = 'output' 、 signature_name = 'default_tfserving' ):
- # pb_io_name は、pb モデルの入力と出力のノード名です。
- # input_node_nameは変換後の入力名です
- # output_node_nameは変換後の出力名です
- # signature_nameは署名です
- グラフを作成します(pb_file)
- # tensor_name_list = [tf.get_default_graph().as_graph_def().node 内のテンソルの tensor.name]
- 入力名= '%s:0' % pb_io_name[0]
- 出力名= '%s:0' % pb_io_name[1]
- tf.Session() を sess として使用:
- in_tensor = sess.graph.get_tensor_by_name (入力名)
- out_tensor = sess.graph.get_tensor_by_name (出力名)
- builder = tf .saved_model.builder.SavedModelBuilder(export_path) ## export_path エクスポートパス
- 入力= {input_node_name: tf.saved_model.utils.build_tensor_info(in_tensor)}
- 出力= {output_node_name: tf.saved_model.utils.build_tensor_info(out_tensor)}
- 署名= tf .saved_model.signature_def_utils.build_signature_def(
- 入力、出力、 method_name = tf.saved_model.signature_constants.PREDICT_METHOD_NAME )
- ビルダー.add_meta_graph_and_variables(
- sess sess =sess、タグ=[tf.saved_model.tag_constants.SERVING]、
- signature_def_map ={signature_name: signature}, clear_devices = True ) ## signature_name はカスタマイズ可能な署名です
- ビルダー.save()
- pb_model_path = 'test.pb'
- pb_to_tfserving(pb_model_path, './1', pb_io_name = ['input_1_1', 'output_1'], signature_name = 'your_model' )
3.2 TFservingの設定と起動 モデルをエクスポートした後、同じモデルを異なるバージョン (バージョンの後に番号が付く) でエクスポートできます。モデルとバージョンは、TFserving 構成で指定できます。 TFserving モデルは、モデル名と署名によって一意に特定されます。 TFserving は、GPU リソースを最大限に活用するために複数のモデルを構成できます。 - # モデル.config
- モデル構成リスト{
- 設定{
- 名前: 'your_model'
- ベースパス: '/models/your_model/'
- モデルプラットフォーム: 'tensorflow'
- # モデルバージョンポリシー {
- # 特定の {
- バージョン数: 42
- バージョン数: 43
- # }
- # }
- # バージョンラベル {
- # キー: 'stable'
- # 値: 43
- # }
- # バージョンラベル {
- # キー: 'canary'
- # 値: 43
- # }
- }
- 設定{
- 名前: "mnist",
- ベースパス: "/models/mnist",
- モデルプラットフォーム: "テンソルフロー",
- モデルバージョンポリシー: {
- 特定の:
- バージョン: 1,
- バージョン: 2
- }
- }
- }
- # バージョン管理はmodel_version_policyを通じて実行できます
- # モデルと設定ファイルを /home/tfserving/models などの docker 外のローカルパスに配置し、-v で docker にマウントすることをお勧めします。
- # --model_config_file: モデル設定ファイルを指定する
- # -e NVIDIA_VISIBLE_DEVICES = 0 : GPUを指定する
- # -p はポートマッピングを指定します。8500 は gRpc、8501 は RESTful API ポートです。
- # -t はDockerイメージです
- nvidia-docker run -it --privileged -d -e NVIDIA_VISIBLE_DEVICES = 0 -v /home/tfserving/models:/models -p 8500:8500 -p 8501:8501 \
- -t テンソルフロー/サービング:最新のGPU \
- --model_config_file =/models/models.config
- # /home/tfserving/models 構造
- ├── モデル.config
- └── あなたのモデル
- ├── 1
- │ ├── saved_model.pb
- │ └── 変数
- └── 2
- ├── saved_model.pb
- └── 変数
- # テスト
- curl http://192.168.0.3:8501/v1/models/your_model
- {
- "モデルバージョンステータス": [
- {
- "バージョン": "2",
- "状態": "利用可能",
- "状態": {
- "エラーコード": "OK",
- "エラーメッセージ": ""
- }
- }
- ]
- }
- # その他の起動方法
- # 複数のモデルが異なるディレクトリにある場合は、-mount で個別にロードできます。
- nvidia-docker 実行 -it --privileged -d -e NVIDIA_VISIBLE_DEVICES = 0 \
- --mount type = bind 、 source = /home/tfserving/models/your_model、 target = /models/your_model \
- --mount type = bind 、 source =/home/tfserving/models/your_model/models.config、 target =/models/models.config \
- -p 8510:8500 -p 8501:8501 \
- -t テンソルフロー/サービング:最新のGPU \
- --model_config_file =/models/models.config
3.3 TFservingサービス呼び出し クライアントは、複数のクライアント言語をサポートし、gRpc と http を介して TFserving サービス モデルを呼び出すことができます。以下は Python 呼び出しメソッドです。呼び出しは、モデル名とシグネチャを通じてモデルに一意に対応します。 - gRpc 呼び出し、gRpc ポートは 8500 です
- #
- # -*-コーディング:utf-8 -*-
- テンソルフローをtfとしてインポートする
- tensorflow_serving.apis から predict_pb2 をインポートします
- tensorflow_serving.apis から prediction_service_pb2_grpc をインポートします
- grpc をインポートする
- インポート時間
- numpyをnpとしてインポートする
- cv2をインポート
- クラスYourModel(オブジェクト):
- def __init__(self, ソケット):
- 「」
- 引数:
- socket: tfserving のホストとポート (192.168.0.3:8500 など)
- 「」
- self.socket = ソケット
- 開始=時間.time()
- self.request、 self self.stub = self.__get_request()
- 終了=時間.time()
- print('コスト時間の初期化: ' + str(end - start) + ' s')
- __get_request(自分)を定義します:
- チャネル= grpc.insecure_channel (self.socket、オプション=[('grpc.max_send_message_length'、1024 * 1024 * 1024)、
- ('grpc.max_receive_message_length', 1024 * 1024 * 1024)]) # 設定可能なサイズ
- スタブ= prediction_service_pb2_grpc.PredictionServiceStub (チャネル)
- リクエスト= predict_pb2.PredictRequest ()
- request.model_spec.name = "your_model" # モデル名
- request.model_spec.signature_name = "your_model" # モデル署名名
- 返品リクエスト、スタブ
- def run(self, イメージ):
- 「」
- 引数:
- 画像: 入力画像(RGB 形式)
- 戻り値: 埋め込みはモデルの出力です
- 「」
- img =画像[..., ::-1]
- self.request.inputs['input'].CopyFrom(tf.contrib.util.make_tensor_proto(img)) # 画像はモデルの入力です
- 結果= self.stub.Predict (self.request, 30.0)
- tf.make_ndarray(result.outputs['output']) を返します
- def run_file(self, image_file):
- 「」
- 引数:
- image_file: 入力画像ファイル
- 戻り値:
- 「」
- 画像= cv2.imread (画像ファイル)
- 画像= cv2.cvtColor (画像、cv2.COLOR_BGR2RGB)
- self.run(画像) を返します
- __name__ == '__main__' の場合:
- モデル= YourModel ('192.168.0.3:8500')
- テストファイル= './test.jpg'
- 結果=モデル.run_file(test_file)
- 印刷(結果)
- # [8.014745e-05 9.999199e-01]
- RESTful API 呼び出し: RESTful ポートは 8501 です
- cv2をインポート
- 輸入リクエスト
- クラスSelfEncoder(json.JSONEncoder):
- def default(self, obj):
- isinstance(obj, np.ndarray): の場合
- obj.tolist() を返す
- elif isinstance(obj, np.floating):
- float(obj) を返す
- elif isinstance(obj, バイト):
- str(obj、エンコーディング= 'utf-8' ) を返します。
- json.JSONEncoder.default(self, obj) を返します。
- 画像ファイル= '/home/tfserving/test.jpg'
- 画像= cv2.imread (画像ファイル)
- 画像= cv2.cvtColor (画像、cv2.COLOR_BGR2RGB)
- img =画像[..., ::-1]
- 入力データ= {
- "署名名": "あなたのモデル",
- 「インスタンス」: 画像
- }
- data = json.dumps (input_data、 cls = SelfEncoder 、インデント= None )
- 結果=リクエスト.post("http://192.168.0.3:8501/v1/models/your_model:predict",データデータ=data)
- eval(結果.コンテンツ)
- # {'予測': [8.01474525e-05, 0.999919891]}
5. まとめ この記事では、モデルの変換からデプロイメントの起動、推論の呼び出しまで、TFserving を使用してオンライン推論サービスをデプロイする方法を紹介します。アイデアの交換を歓迎し、お役に立てれば幸いです。冒頭で提起した疑問に答えてみましょう - 導入するもの: もちろんTFserving
- API インターフェースの提供方法: TFserving は RESTful API インターフェースを提供します。実際のデプロイメントでは、Flask API などの別のレイヤーが前面に追加されます。
- 複数のモデルにGPUリソースを割り当てる方法:TFservingは、設定によって複数のモデルを展開することをサポートしています。
- サービスを中断せずにオンライン モデルを更新する方法: TFserving はさまざまなバージョンのモデルをサポートしています。たとえば、your_model にはバージョン 1 と 2 の 2 つがあります。新しいモデル 3 を追加すると、TFserving は再起動せずにモデル 3 を現在のモデルとして自動的に判別し、自動的にロードします。
|