Elastic Algorithm Service (EAS) は、標準のSavedModel形式でTensorFlowモデルをオンラインサービスとして展開するための組み込みTensorFlowプロセッサを提供します。 このトピックでは、TensorFlowモデルサービスをデプロイして呼び出す方法について説明します。
背景情報
モデルがKerasまたはCheckpointモデルの場合は、デプロイする前に、まずSavedModelモデルに変換する必要があります。 詳細については、「SavedModel形式でのTensorFlowモデルのエクスポート」をご参照ください。 Bladeによって最適化されたモデルは直接実行できます。
TensorFlowプロセッサのバージョン
TensorFlowは、CPUデバイスとGPUデバイスの両方をサポートする複数のバージョンで利用できます。 特別なビジネス要件がない場合は、サービスのデプロイ時に最新バージョンを使用することを推奨します。 TensorFlowの新しいバージョンは、パフォーマンスが向上し、以前のバージョンの機能と下位互換性があります。 次の表に、各TensorFlowバージョンに対応するプロセッサ名を示します。
プロセッサ名 | TensorFlowバージョン | GPUサポート |
tensorflow_cpu_1.12 | Tensorflow 1.12 | 不可 |
tensorflow_cpu_1.14 | Tensorflow 1.14 | 不可 |
tensorflow_cpu_1.15 | Tensorflow 1.15 | 不可 |
tensorflow_cpu_2.3 | Tensorflow 2.3 | 不可 |
tensorflow_cpu_2.4 | Tensorflow 2.4 | 不可 |
tensorflow_cpu_2.7 | Tensorflow 2.7 | 不可 |
tensorflow_gpu_1.12 | Tensorflow 1.12 | 可 |
tensorflow_gpu_1.14 | Tensorflow 1.14 | 可 |
tensorflow_gpu_1.15 | Tensorflow 1.15 | 可 |
tensorflow_gpu_2.4 | Tensorflow 2.4 | 可 |
tensorflow_gpu_2.7 | Tensorflow 2.7 | 可 |
手順1: モデルサービスのデプロイ
オプション: ウォームアップ要求ファイルを設定します。
一部のTensorFlowモデルサービスでは、サービスを最初に呼び出すときに、モデル関連のファイルとパラメーターをメモリにロードする必要があります。 このプロセスには大量の時間がかかる可能性があり、最初のいくつかの要求の応答時間が予想よりも遅くなります。 リクエストは、タイムアウトエラーまたは450エラー408返される場合があります。 ロールオーバー中にサービスにジッタが発生しないようにするには、サービスの展開中に関連するパラメーターを追加してモデルをウォームアップする必要があります。 これにより、ウォームアップが完了した後、サービスインスタンスがトラフィックを正常に受信することが保証されます。 詳細については、「ウォームアップモデルサービス」をご参照ください。
サービスをデプロイします。
EASCMDクライアントを使用してTensorFlowモデルサービスをデプロイする場合は、processorパラメーターをプロセッサ名に設定する必要があります。 次のコードブロックに例を示します。
{ "name": "tf_serving_test", "model_path": "http://examplebucket.oss-cn-shanghai.aliyuncs.com/models/model.tar.gz", "processor": "tensorflow_cpu_1.15", "warm_up_data_path":"oss://path/to/warm_up_test.bin", // The path of the warm-up request file in Object Storage Service (OSS). "metadata": { "instance": 1, "cpu": 1, "memory": 4000 } }
EASCMDクライアントを使用してモデルサービスをデプロイする方法の詳細については、「EASCMDまたはDSWを使用したモデルサービスのデプロイ」をご参照ください。
TensorFlowモデルサービスは、Machine Learning Platform for AI (PAI) コンソールでデプロイすることもできます。 詳細については、「PAIコンソールでのモデルサービスのデプロイ」をご参照ください。
TensorFlowモデルサービスをデプロイした後、次の手順を実行して、サービスのパブリックおよび仮想プライベートクラウド (VPC) エンドポイントと、サービス認証に使用されるトークンを取得できます。[Elastic Algorithm service (EAS)] ページで、呼び出すサービスを見つけ、[service Type] 列の [call Inform] をクリックします。
ステップ2: モデルサービスを呼び出す
TensorFlowサービスの入力と出力は、両方ともプレーンテキストではなくプロトコルバッファファイルです。 ただし、PAIコンソールのオンラインデバッグ機能はプレーンテキストのみをサポートします。 したがって、オンラインデバッグ機能は使用できません。
EASは、サービス要求および応答データをパッケージ化するために、異なるバージョンのPAI SDKを提供する。 SDKには、直接接続とフォールトトレランスのステートメントが含まれています。 リクエストの作成と送信には、SDKを使用することを推奨します。
モデルの構造を照会します。
空のリクエストが標準のSavedModel形式でモデルに送信された場合、JSON形式のモデル構造情報が返されます。
// Send an empty request. $ curl 1828488879222***.cn-shanghai.pai-eas.aliyuncs.com/api/predict/mnist_saved_model_example -H 'Authorization: YTg2ZjE0ZjM4ZmE3OTc0NzYxZDMyNmYzMTJjZTQ1***' // The following model structure information is returned. { "inputs": [ { "name": "images", "shape": [ -1, 784 ], "type": "DT_FLOAT" } ], "outputs": [ { "name": "scores", "shape": [ -1, 10 ], "type": "DT_FLOAT" } ], "signature_name": "predict_images" }
説明凍結pbモデルの構造情報は取得できません。
推論リクエストを送信します。
次のコードブロックは、PAI SDK for Pythonを使用して推論リクエストを送信する方法の例を示しています。
#!/usr/bin/env python from eas_prediction import PredictClient from eas_prediction import TFRequest if __name__ == '__main__': client = PredictClient('http://1828488879222***.cn-shanghai.pai-eas.aliyuncs.com', 'mnist_saved_model_example') client.set_token('YTg2ZjE0ZjM4ZmE3OTc0NzYxZDMyNmYzMTJjZTQ1****') client.init() req = TFRequest('predict_images') req.add_feed('images', [1, 784], TFRequest.DT_FLOAT, [1] * 784) for x in range(0, 1000000): resp = client.predict(req) print(resp)
パラメーター設定の詳細については、「SDK For Python」をご参照ください。
後で、独自のサービス要求を作成することもできます。 詳細については、「リクエスト構文」をご参照ください。
リクエスト構文
TensorFlowプロセッサの入出力データがプロトコルバッファ形式であることを確認する必要があります。 PAI SDKを使用してリクエストを送信すると、SDKはリクエストをパッケージ化します。 SDKが提供する機能に基づいてリクエストを作成するだけです。 カスタムサービス呼び出しロジックを作成する場合は、次の構文に基づいてリクエストコードを生成できます。 詳細については、「TensorFlowサービスのリクエストの構築」をご参照ください。
syntax = "proto3";
option cc_enable_arenas = true;
option java_package = "com.aliyun.openservices.eas.predict.proto";
option java_outer_classname = "PredictProtos";
enum ArrayDataType {
// Not a legal value for DataType. Used to indicate a DataType field
// has not been set.
DT_INVALID = 0;
// Data types that all computation devices are expected to be
// capable to support.
DT_FLOAT = 1;
DT_DOUBLE = 2;
DT_INT32 = 3;
DT_UINT8 = 4;
DT_INT16 = 5;
DT_INT8 = 6;
DT_STRING = 7;
DT_COMPLEX64 = 8; // Single-precision complex.
DT_INT64 = 9;
DT_BOOL = 10;
DT_QINT8 = 11; // Quantized int8.
DT_QUINT8 = 12; // Quantized uint8.
DT_QINT32 = 13; // Quantized int32.
DT_BFLOAT16 = 14; // Float32 truncated to 16 bits. Only for cast ops.
DT_QINT16 = 15; // Quantized int16.
DT_QUINT16 = 16; // Quantized uint16.
DT_UINT16 = 17;
DT_COMPLEX128 = 18; // Double-precision complex.
DT_HALF = 19;
DT_RESOURCE = 20;
DT_VARIANT = 21; // Arbitrary C++ data types.
}
// Dimensions of an array.
message ArrayShape {
repeated int64 dim = 1 [packed = true];
}
// Protocol buffer representing an array.
message ArrayProto {
// Data Type.
ArrayDataType dtype = 1;
// Shape of the array.
ArrayShape array_shape = 2;
// DT_FLOAT.
repeated float float_val = 3 [packed = true];
// DT_DOUBLE.
repeated double double_val = 4 [packed = true];
// DT_INT32, DT_INT16, DT_INT8, DT_UINT8.
repeated int32 int_val = 5 [packed = true];
// DT_STRING.
repeated bytes string_val = 6;
// DT_INT64.
repeated int64 int64_val = 7 [packed = true];
// DT_BOOL.
repeated bool bool_val = 8 [packed = true];
}
// PredictRequest specifies which TensorFlow model to run, as well as
// how inputs are mapped to tensors and how outputs are filtered before
// returning to user.
message PredictRequest {
// A named signature to evaluate. If unspecified, the default signature
// will be used.
string signature_name = 1;
// Input tensors.
// Names of input tensor are alias names. The mapping from aliases to real
// input tensor names is expected to be stored as named generic signature
// under the key "inputs" in the model export.
// Each alias listed in a generic signature named "inputs" should be provided
// exactly once in order to run the prediction.
map<string, ArrayProto> inputs = 2;
// Output filter.
// Names specified are alias names. The mapping from aliases to real output
// tensor names is expected to be stored as named generic signature under
// the key "outputs" in the model export.
// Only tensors specified here will be run/fetched and returned, with the
// exception that when none is specified, all tensors specified in the
// named signature will be run/fetched and returned.
repeated string output_filter = 3;
}
// Response for PredictRequest on successful run.
message PredictResponse {
// Output tensors.
map<string, ArrayProto> outputs = 1;
}