此页面由 Cloud Translation API 翻译。
Switch to English

RESTful API

除了gRPC API, TensorFlow ModelServer还支持RESTful API。该页面描述了这些API端点以及用法的端到端示例

请求和响应是一个JSON对象。该对象的组成取决于请求类型或动词。有关详情,请参见下面的API特定部分。

发生错误时,所有API都会在响应主体中返回一个JSON对象,并以error作为键,并将error消息作为值:

{
  "error": <error message string>
}

型号状态API

该API紧随ModelService.GetModelStatus gRPC API。它返回ModelServer中模型的状态。

网址

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

包含/versions/${VERSION}/labels/${LABEL}是可选的。如果省略,则在响应中返回所有版本的状态。

回应格式

如果成功,则返回GetModelStatusResponse protobuf的JSON表示GetModelStatusResponse

模型元数据API

该API紧随PredictionService.GetModelMetadata gRPC API。它返回ModelServer中模型的元数据。

网址

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

包含/versions/${VERSION}/labels/${LABEL}是可选的。如果省略,则在响应中返回最新版本的模型元数据。

回应格式

如果成功,则返回GetModelMetadataResponse protobuf的JSON表示GetModelMetadataResponse

分类和回归API

这个API紧随ClassifyRegress的方法PredictionService GRPC API。

网址

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数字(整数或十进制)或字符串,而<list>是此类值的列表。有关如何表示二进制(字节流)值的详细信息,请参见下面的编码二进制值部分。此格式类似于gRPC的ClassificationRequest请求和RegressionRequest请求原型。两种版本均接受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>是十进制数字。

gRPC API的用户将注意到此格式与ClassificationResponse响应和RegressionResponse响应原型的相似性。

预测API

该API紧随PredictionService.Predict gRPC API。

网址

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>
}

以行格式指定输入张量。

此格式类似于gRPC API的PredictRequest原型和CMLE预测API 。如果所有命名的输入张量都具有相同的第0维,则使用此格式。如果不行,请使用下文所述的列格式。

在行格式中,输入被键入JSON请求中的instances键。

如果只有一个命名输入,则将instances key的值指定为输入的值:

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

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

由于无需手动拉平列表,因此张量自然以嵌套表示法表示。

对于多个命名输入,每个项目都应该是一个包含输入名称/张量值对的对象,每个命名输入一个。例如,以下是一个具有两个实例的请求,每个实例带有一组三个命名输入张量:

{
 "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]]
   }
 ]
}

注意,每个命名的输入(“标签”,“信号”,“传感器”)被隐含地假定有相同的第0维( 两个上述例子中,因为有在实例列表中的两个对象)。如果命名的输入具有第0维的不同值,请使用下面描述的列格式。

以列格式指定输入张量。

如果各个命名输入的维数不相同,或者想要更紧凑的表示形式,则使用此格式来指定输入张量。此格式类似于gRPC Predict请求的inputs字段。

在列格式中,输入被键入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值将是一个十进制数字。
DT_FLOAT,DT_DOUBLE 1.1,-10.0,0, NaNInfinity JSON值将是数字或特殊令牌值之一NaNInfinity-Infinity 。有关更多信息,请参见JSON一致性 。指数表示法也被接受。

编码二进制值

JSON使用UTF-8编码。如果您具有需要为二进制的输入特征或张量值(例如图像字节),则必须对数据进行Base64编码并将其封装在以b64为键的JSON对象中,如下所示:

{ "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规范一样)。

本页描述的REST API允许请求/响应JSON对象具有此类值。这意味着以下请求是有效的:

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

符合(严格)标准的JSON解析器将拒绝此解析错误(由于NaNInfinity令牌与实际数字混合)。要正确处理代码中的请求/响应,请使用支持这些令牌的JSON解析器。

NaNInfinity-Infinity令牌可以被proto3 ,Python JSON模块和JavaScript语言识别。

我们可以使用玩具half_plus_three模型来查看REST API的运行情况。

使用REST API端点启动ModelServer

git仓库下载half_plus_three模型:

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

我们将使用Docker运行ModelServer。如果要在系统上本机安装ModelServer,请按照安装说明进行安装,然后使用--rest_api_port选项启动--rest_api_port以导出REST API端点(使用Docker时不需要)。

$ 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进行REST API调用

在其他终端中,使用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": ""
   }
  }
 ]
}

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)" }
$