RESTful API

加えてgRPCのAPI TensorFlow ModelServerもRESTfulなAPIをサポートしています。このページでは、これらのAPIエンドポイントとエンドツーエンドの記述の使用上を。

リクエストとレスポンスはJSONオブジェクトです。このオブジェクトの構成は、要求のタイプまたは動詞によって異なります。詳細については、以下のAPI固有のセクションを参照してください。

エラーの場合には、全てのAPIが持つレスポンスボディにJSONオブジェクトが返されるerrorキーおよび値としてエラーメッセージとして:

{
  "error": <error message string>
}

モデルステータスAPI

このAPIは、密接に次のModelService.GetModelStatus gRPCのAPIを。 ModelServer内のモデルのステータスを返します。

URL

GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]

含む/versions/${VERSION}又は/labels/${LABEL}任意です。省略した場合、すべてのバージョンのステータスが応答で返されます。

応答形式

成功した場合、のJSON表現を返しGetModelStatusResponseいるProtobufを。

モデルメタデータAPI

このAPIは、密接に次のPredictionService.GetModelMetadata gRPCのAPIを。 ModelServer内のモデルのメタデータを返します。

URL

GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]/metadata

含む/versions/${VERSION}又は/labels/${LABEL}任意です。省略した場合、最新バージョンのモデルメタデータが応答で返されます。

応答形式

成功した場合、のJSON表現を返しGetModelMetadataResponseいるProtobufを。

分類および回帰API

このAPIは、密接に以下のClassifyおよびRegressの方法PredictionService gRPCのAPIを。

URL

POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:(classify|regress)

含む/versions/${VERSION}又は/labels/${LABEL}任意です。省略した場合は、最新バージョンが使用されます。

リクエストフォーマット

要求ボディclassifyregress APIは、次のようにフォーマットされたJSONオブジェクトでなければなりません。

{
  // Optional: serving signature to use.
  // If unspecifed default serving signature is used.
  "signature_name": <string>,

  // Optional: Common context shared by all examples.
  // Features that appear here MUST NOT appear in examples (below).
  "context": {
    "<feature_name3>": <value>|<list>
    "<feature_name4>": <value>|<list>
  },

  // List of Example objects
  "examples": [
    {
      // Example 1
      "<feature_name1>": <value>|<list>,
      "<feature_name2>": <value>|<list>,
      ...
    },
    {
      // Example 2
      "<feature_name1>": <value>|<list>,
      "<feature_name2>": <value>|<list>,
      ...
    }
    ...
  ]
}

<value> JSON番号(全部または小数)、JSON文字列、または(参照バイナリデータを表すJSONオブジェクトでエンコードバイナリ値の詳細については、以下のセクション)。 <list> 、このような値のリストです。この形式は、gRPCのに似ているClassificationRequestRegressionRequest PROTOS。どちらのバージョンものリスト受け入れるExampleオブジェクトを。

応答形式

classify要求は、次のようにフォーマットされ、レスポンスボディにJSONオブジェクトを返します。

{
  "result": [
    // List of class label/score pairs for first Example (in request)
    [ [<label1>, <score1>], [<label2>, <score2>], ... ],

    // List of class label/score pairs for next Example (in request)
    [ [<label1>, <score1>], [<label2>, <score2>], ... ],
    ...
  ]
}

<label> (空の文字列にすることができ、文字列である""モデルがスコアに関連付けられたラベルを持っていない場合)。 <score>小数(浮動小数点)数です。

regress要求は次のようにフォーマットされ、レスポンスボディにJSONオブジェクトを返します。

{
  // One regression value for each example in the request in the same order.
  "result": [ <value1>, <value2>, <value3>, ...]
}

<value> 10進数です。

gRPC APIのユーザーは、この形式の類似性に気づくでしょうClassificationResponseRegressionResponseプロトを。

APIを予測する

このAPIは、密接に次のPredictionService.Predict gRPCのAPIを。

URL

POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:predict

含む/versions/${VERSION}又は/labels/${LABEL}任意です。省略した場合は、最新バージョンが使用されます。

リクエストフォーマット

以下のためのリクエストボディpredict APIは、次のようにフォーマットされたJSONオブジェクトである必要があります。

{
  // (Optional) Serving signature to use.
  // If unspecifed default serving signature is used.
  "signature_name": <string>,

  // Input Tensors in row ("instances") or columnar ("inputs") format.
  // A request can have either of them but NOT both.
  "instances": <value>|<(nested)list>|<list-of-objects>
  "inputs": <value>|<(nested)list>|<object>
}

行形式での入力テンソルの指定。

このフォーマットは、に似てPredictRequest gRPCのAPIのプロトとCMLEはAPIを予測します。すべての名前付き入力テンソルが同じ0番目の次元を持っている場合は、この形式を使用します。そうでない場合は、以下で説明する列形式を使用してください。

行フォーマットでは、入力は、JSON要求内のインスタンスキーにキー止めされています。

唯一の名前の入力がある場合には、入力の値であることが重要なのインスタンスの値を指定します。

{
  // List of 3 scalar tensors.
  "instances": [ "foo", "bar", "baz" ]
}

{
  // List of 2 tensors each of [1, 2] shape
  "instances": [ [[1, 2]], [[3, 4]] ]
}

リストを手動でフラット化する必要がないため、テンソルはネストされた表記で自然に表現されます。

複数の名前付き入力の場合、各アイテムは、名前付き入力ごとに1つずつ、入力名/テンソル値のペアを含むオブジェクトであることが期待されます。例として、以下は2つのインスタンスを持つリクエストであり、それぞれに3つの名前付き入力テンソルのセットがあります。

{
 "instances": [
   {
     "tag": "foo",
     "signal": [1, 2, 3, 4, 5],
     "sensor": [[1, 2], [3, 4]]
   },
   {
     "tag": "bar",
     "signal": [3, 4, 1, 2, 5]],
     "sensor": [[4, 5], [6, 8]]
   }
 ]
}

注、各名前の入力(「タグ」、「信号」、「センサー」)が暗黙的に(インスタンスリスト内の2つのオブジェクトがあるように、上記の例では2つ)と同じ0番目の寸法を有するものとします。 0次元が異なる入力に名前を付けた場合は、以下で説明する列形式を使用してください。

列形式での入力テンソルの指定。

個々の名前付き入力が同じ0次元を持たない場合、またはよりコンパクトな表現が必要な場合は、この形式を使用して入力テンソルを指定します。このフォーマットは、に似ているinputs gRPCのフィールドPredict要求を。

列形式では、入力はJSONリクエストで入力キーにキーが付いています。

入力キーの値は、単一の入力テンソル又はテンソルに入力された名前のマップのいずれかが(その天然のネストされた形で記載されている)ことができます。各入力は任意の形状にすることができ、上記の行形式で必要とされる同じ0番目の次元(別名バッチサイズ)を共有する必要はありません。

前の例の列表現は次のとおりです。

{
 "inputs": {
   "tag": ["foo", "bar"],
   "signal": [[1, 2, 3, 4, 5], [3, 4, 1, 2, 5]],
   "sensor": [[[1, 2], [3, 4]], [[4, 5], [6, 8]]]
 }
}

ノートでは、入力は、JSONオブジェクトとしない(行表現で使用される)の場合のようなリストです。また、前述の行形式で行われた個々の行にそれらを展開するのではなく、すべての名前付き入力が一緒に指定されます。これにより、表現がコンパクトになります(ただし、読みにくくなる可能性があります)。

応答形式

predictリクエストがレスポンスボディにJSONオブジェクトを返します。

リクエスト行の形式は次のように応答がフォーマットされています。

{
  "predictions": <value>|<(nested)list>|<list-of-objects>
}

モデルの出力は一つだけという名前のテンソルが含まれている場合、我々は名前と省略predictionsキーがスカラーやリストの値のリストにマップされます。モデルが複数の名前付きテンソルを出力する場合、上記の行形式の要求と同様に、代わりにオブジェクトのリストを出力します。

で要求列形式は、次のように応答フォーマットされています:

{
  "outputs": <value>|<(nested)list>|<object>
}

モデルの出力は一つだけという名前のテンソルが含まれている場合、我々は名を省略し、 outputsキーは、スカラーやリストの値のリストにマップされます。モデルが複数の名前付きテンソルを出力する場合、代わりにオブジェクトを出力します。このオブジェクトの各キーは、名前付き出力テンソルに対応しています。形式は、上記の列形式のリクエストに似ています。

バイナリ値の出力

TensorFlowは、非バイナリ文字列とバイナリ文字列を区別しません。すべてがされているDT_STRINGタイプを。持っている名前付きテンソル_bytes自分の名前にサフィックスとしては、バイナリ値を有すると考えられます。記載されているように、このような値は、異なる符号化されるコードのバイナリ値以下のセクション。

JSONマッピング

RESTful APIは、JSONでの正規のエンコードをサポートしているため、システム間でデータを簡単に共有できます。サポートされているタイプの場合、エンコーディングはタイプごとに次の表で説明されています。以下にリストされていないタイプは、サポートされていないことを意味します。

TFデータ型JSON値JSONの例ノート
DT_BOOL真/偽真/偽
DT_STRINGストリング"こんにちは世界!"場合DT_STRINGバイナリバイト(例えばシリアライズ画像バイトいるProtobuf)、エンコードにBase64でこれらを表します。参照バイナリ値をエンコード詳細は。
DT_INT8、DT_UINT8、DT_INT16、DT_INT32、DT_UINT32、DT_INT64、DT_UINT64番号1、-10、0 JSON値は10進数になります。
DT_FLOAT、DT_DOUBLE番号1.1、-10.0、0、 NaNInfinity - JSON値は番号または特別なトークンの値のいずれかであろうNaNInfinity 、および-Infinity 。参照してください。 JSONの適合性をより多くの情報のため。指数表記も使用できます。

浮動小数点精度

JSONには単一の数値データ型があります。したがって、精度が低下する入力の値を指定することができます。例えば、入力があればxあるfloatデータ・タイプ、および入力{"x": 1435774380} 、値の意志、IEEE 754浮動小数点規格(例えばインテル又はAMD)に基づいて、ハードウェア上で実行されているモデルに送信されますサイレントにunderylingハードウェアによって変換さ1435774336ため1435774380正確に32ビットの浮動小数点数で表すことができません。通常、サービングへの入力はトレーニングと同じ分布である必要があります。したがって、トレーニング時に同じ変換が行われたため、これは通常問題にはなりません。ただし、完全な精度が必要な場合は、モデルで目的の精度を処理できる基になるデータ型を使用するか、クライアント側のチェックを検討してください。

バイナリ値のエンコード

JSONはUTF-8エンコーディングを使用します。あなた(画像バイトのように)必要がバイナリであるために、その入力機能またはテンソルの値を有する場合は、Base64では、データを符号化し持つJSONオブジェクト内にカプセル化しなければならないb64次のようにキーのように:

{ "b64": <base64 encoded string> }

このオブジェクトを入力特徴またはテンソルの値として指定できます。同じフォーマットが出力応答のエンコードにも使用されます。

分類要求image (バイナリデータ)とcaptionの特徴を以下に示します:

{
  "signature_name": "classify_objects",
  "examples": [
    {
      "image": { "b64": "aW1hZ2UgYnl0ZXM=" },
      "caption": "seaside"
    },
    {
      "image": { "b64": "YXdlc29tZSBpbWFnZSBieXRlcw==" },
      "caption": "mountains"
    }
  ]
}

JSON準拠

多くの特徴またはテンソル値は浮動小数点数です。別に有限値(例えば3.14、1.0など)からこれらを持つことができるNaNと非有限( Infinity-Infinity )の値を。残念ながら、JSONの仕様( RFC 7159は)(JavaScriptの仕様はありませんが)、これらの値を認識しません

このページで説明されているRESTAPIを使用すると、リクエスト/レスポンスのJSONオブジェクトにそのような値を設定できます。これは、次のようなリクエストが有効であることを意味します。

{
  "example": [
    {
      "sensor_readings": [ 1.0, -3.14, Nan, Infinity ]
    }
  ]
}

A(厳密な)標準に準拠JSONパーサーは(による解析エラーでこれを拒否するNaNInfinity実際の数字と混合トークン)。コード内のリクエスト/レスポンスを正しく処理するには、これらのトークンをサポートするJSONパーサーを使用します。

NaNInfinity-Infinityトークンがで認識されているproto3 、PythonのJSONのモジュールとJavaScript言語。

私たちは、おもちゃを使用することができますhalf_plus_threeのアクションにREST APIを参照するモデルを。

RESTAPIエンドポイントでModelServerを起動します

ダウンロードhalf_plus_threeからモデルをgitのリポジトリ

$ mkdir -p /tmp/tfserving
$ cd /tmp/tfserving
$ git clone --depth=1 https://github.com/tensorflow/serving

Dockerを使用してModelServerを実行します。あなたは、あなたのシステム上でネイティブにModelServerをインストールフォローしたい場合はセットアップ手順を代わりにインストールすると、とModelServer開始--rest_api_port輸出REST APIエンドポイントへのオプションを(ドッカーを使用している場合、これは必要ありません)。

$ cd /tmp/tfserving
$ docker pull tensorflow/serving:latest
$ docker run --rm -p 8501:8501 \
    --mount type=bind,source=$(pwd),target=$(pwd) \
    -e MODEL_BASE_PATH=$(pwd)/serving/tensorflow_serving/servables/tensorflow/testdata \
    -e MODEL_NAME=saved_model_half_plus_three -t tensorflow/serving:latest
...
.... Exporting HTTP/REST API at:localhost:8501 ...

ModelServerへのRESTAPI呼び出しを行います

別の端末では、使用curl REST API呼び出しを行うためのツールを。

次のようにモデルのステータスを取得します。

$ curl http://localhost:8501/v1/models/saved_model_half_plus_three
{
 "model_version_status": [
  {
   "version": "123",
   "state": "AVAILABLE",
   "status": {
    "error_code": "OK",
    "error_message": ""
   }
  }
 ]
}

Aはpredict 、次のように呼び出しがなります。

$ curl -d '{"instances": [1.0,2.0,5.0]}' -X POST http://localhost:8501/v1/models/saved_model_half_plus_three:predict
{
    "predictions": [3.5, 4.0, 5.5]
}

そして、 regress 、次のコールルックスと:

$ curl -d '{"signature_name": "tensorflow/serving/regress", "examples": [{"x": 1.0}, {"x": 2.0}]}' \
  -X POST http://localhost:8501/v1/models/saved_model_half_plus_three:regress
{
    "results": [3.5, 4.0]
}

注、 regress 、デフォルト以外の署名の名前の上に利用可能であり、明示的に指定する必要があります。リクエストのURLまたは本文が正しくないと、HTTPエラーステータスが返されます。

$ curl -i -d '{"instances": [1.0,5.0]}' -X POST http://localhost:8501/v1/models/half:predict
HTTP/1.1 404 Not Found
Content-Type: application/json
Date: Wed, 06 Jun 2018 23:20:12 GMT
Content-Length: 65

{ "error": "Servable not found for request: Latest(half)" }
$