全部產品
Search
文件中心

Platform For AI:Tensorflow

更新時間:Jul 13, 2024

EAS內建的Tensorflow Processor支援將Tensorflow標準的Savedmodel格式的模型部署成線上服務。本文為您介紹如何部署及調用Tensorflow模型服務。

背景資訊

對於Keras和Checkpoint模型,您需要先將其轉換為Savedmodel模型,再進行部署,詳情請參見TensorFlow模型如何匯出為SavedModel。PAI-Blade最佳化過的模型可以直接運行。

Tensorflow Processor版本說明

Tensorflow支援多個版本,包括GPU和CPU版本,服務部署時無特殊需求可以使用最新版本。Tensorflow版本功能會向前相容,新版本效能相對較好。各個Tensorflow版本對應的Processor名稱如下表所示。

Processor名稱

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模型,初次調用時需要將模型相關檔案或參數載入到記憶體中,該過程可能耗費較長時間,從而導致前幾次請求模型服務的RT較長,甚至出現408(請求計算逾時)或450(超出隊列長度丟棄請求)等情況。為保證服務在變換過程中不會發生抖動,需要在服務部署時增加相關參數對模型進行預熱,以保證在預熱完成後服務執行個體才會正式接收流量,具體操作,詳情請參見進階配置:模型服務預熱

  2. 部署服務。

    使用eascmd用戶端部署Tensorflow模型服務時,您需要指定Processor種類為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", // 模型預熱的請求檔案路徑。    
      "metadata": {
        "instance": 1,
        "cpu": 1,
        "memory": 4000
      }
    }

    關於如何使用用戶端工具部署服務,詳情請參見服務部署:EASCMD&DSW

    您也可以通過控制台部署Tensorflow模型服務,詳情請參見服務部署:控制台

  3. Tensorflow服務部署完成後,在PAI EAS模型線上服務頁面,單擊待調用服務服務方式列下的調用資訊,查看服務訪問的Endpoint和用於服務鑒權的Token資訊。

步驟二:調用服務

Tensorflow服務輸入輸出格式為protobuf,不是純文字,而線上調試目前僅支援純本文的輸入輸出資料,因此無法使用控制台的線上調試功能。

EAS提供了不同版本的SDK,對服務要求和響應資料進行了封裝,且SDK內部包含了直連和容錯相關的機制,推薦使用SDK來構建和發送請求,具體操作步驟如下。

  1. 查詢模型結構。

    對於標準的Savedmodel格式的模型,對服務發送空請求,會返回JSON格式的模型結構資訊。

    // 發送空請求。
    $ curl 1828488879222***.cn-shanghai.pai-eas.aliyuncs.com/api/predict/mnist_saved_model_example -H 'Authorization: YTg2ZjE0ZjM4ZmE3OTc0NzYxZDMyNmYzMTJjZTQ1***'
    
    // 返回模型結構資訊。
    {
        "inputs": [
            {
                "name": "images",
                "shape": [
                    -1,
                    784
                ],
                "type": "DT_FLOAT"
            }
        ],
        "outputs": [
            {
                "name": "scores",
                "shape": [
                    -1,
                    10
                ],
                "type": "DT_FLOAT"
            }
        ],
        "signature_name": "predict_images"
    }              
    說明

    對於freezon pb格式的模型,無法擷取模型結構資訊。

  2. 發送推理請求。

    使用Python SDK發送模型請求樣本如下。

    #!/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)

    關於代碼中的參數配置說明,詳情請參見Python SDK使用說明

後續您也可以自行構建服務要求,詳情請參見請求格式

請求格式

Tensorflow processor輸入輸出為protobuf格式。當您使用SDK發送請求時,SDK對請求進行了封裝,您只需根據SDK提供的函數來構建請求即可。如果您希望自行構建服務要求,則可以參考如下pb定義來產生相關的代碼,詳情請參見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;
}