如果您要发出请求以响应应用输入,或者在其他需要及时推断(实时响应)的情况下,可以使用在线预测。
本页介绍了如何使用在线预测 API 为自定义训练模型设置在线预测请求的格式,并提供了请求和响应示例。格式化请求后,您可以获取在线预测结果。
准备工作
在格式化请求以进行在线预测之前,请执行以下步骤:
- 导出模型制品以进行预测。
-
此操作会将计算资源与模型相关联,以便以低延迟方式执行在线预测。
检查模型的
DeployedModel
自定义资源的状态,并确保该资源已准备好接受预测请求:kubectl --kubeconfig PREDICTION_CLUSTER_KUBECONFIG get -f DEPLOYED_MODEL_NAME.yaml -o jsonpath='{.status.primaryCondition}'
替换以下内容:
PREDICTION_CLUSTER_KUBECONFIG
:预测集群中 kubeconfig 文件的路径。DEPLOYED_MODEL_NAME
:DeployedModel
定义文件的名称。
主要条件必须显示
DeployedModel
已就绪。以下输出显示了示例回答:
{"firstObservedTime":"2024-01-19T01:18:30Z","lastUpdateTime":"2024-01-19T01:35:47Z","message":"DeployedModel is ready", "observedGeneration":1, "reason":"Ready", "resourceName":"my-tf-model","type":"DeployedModel"}
检查
Endpoint
自定义资源的状态,确保其已准备好接受预测请求:kubectl --kubeconfig PREDICTION_CLUSTER_KUBECONFIG get -f ENDPOINT_NAME.yaml -o jsonpath='{$.status.conditions[?(@.type == "EndpointReady")]}'
替换以下内容:
PREDICTION_CLUSTER_KUBECONFIG
:预测集群中 kubeconfig 文件的路径。ENDPOINT_NAME
:Endpoint
定义文件的名称。
EndpointReady
条件的status
字段必须显示True
值。以下输出显示了示例回答:
{"lastTransitionTime":"2024-01-19T05:12:26Z","message":"Endpoint Ready", "observedGeneration":1,"reason":"ResourceReady","status":"True","type":"EndpointReady"}%
格式化输入以进行在线预测
在线预测可通过以下两种方法发送请求:
- 预测请求:向
predict
方法发送请求以获取在线预测结果。 - 原始预测请求:向
rawPredict
方法发送请求,以便使用任意 HTTP 载荷,而不是遵循 JSON 格式。
如果您需要低延迟,请获取原始预测结果,因为 rawPredict
会跳过序列化步骤并直接将请求转发到预测容器。
本部分介绍了如何使用 JSON 设置预测输入实例的格式并进行编码,如果您使用的是 predict
方法,则需要执行此操作。如果您使用的是 rawPredict
方法,则无需提供此信息。
如果您使用 Python 版 Vertex AI SDK 发送预测请求,请指定不带 instances
字段的实例列表。例如,指定 [
["the","quick","brown"], ... ]
而不是 { "instances": [
["the","quick","brown"], ... ] }
。
将实例格式设置为 JSON 字符串
在线预测的基本格式是数据实例列表。这些列表可以是普通的值列表,也可以是 JSON 对象的成员,具体取决于您在训练应用中配置输入的方式。 TensorFlow 模型可以接受更复杂的输入。
以下示例显示了 TensorFlow 模型的输入张量和实例键:
{"values": [1, 2, 3, 4], "key": 1}
只要遵循以下规则,JSON 字符串的构成可能会很复杂:
顶级实例数据必须是 JSON 对象,即键值对的字典。
实例对象中的各个值可以是字符串、数字或列表。 您无法嵌入 JSON 对象。
列表必须仅包含相同类型的内容(包括其他列表)。 请勿混用字符串和数值。
您将在线预测的输入实例作为 predict
调用的消息正文进行传递。详细了解请求正文的格式要求。
使每个实例成为 JSON 数组中的一项,并将该数组作为 JSON 对象的 instances
字段提供,如以下示例所示:
{"instances": [
{"values": [1, 2, 3, 4], "key": 1},
{"values": [5, 6, 7, 8], "key": 2}
]}
对二进制数据进行编码以进行预测预测
您无法将二进制数据格式化为 JSON 支持的 UTF-8 编码字符串。如果输入中包含二进制数据,请使用 base64 编码来表示。您需要使用以下特殊格式:
将编码的字符串的格式设置为 JSON 对象,并包含名为
b64
的单个键。在 Python 3 中,base64 编码会输出一个字节序列。将此序列转换为字符串,使其能够进行 JSON 序列化:{'image_bytes': {'b64': base64.b64encode(jpeg_data).decode()}}
在 TensorFlow 模型代码中,为二进制输入和输出张量提供别名,使这些名称以
_bytes
结尾。
请求和响应示例
本部分介绍在线预测请求和响应正文的格式,并提供 TensorFlow 和 PyTorch 的示例。
请求正文详情
TensorFlow
请求正文包含的数据采用以下结构(JSON 表示法):
{
"instances": [
<value>|<simple/nested list>|<object>,
...
]
}
instances[]
对象是必需的,而且必须包含待预测实例的列表。
实例列表中每个元素的结构由模型的输入定义决定。实例可包含命名输入(作为对象),或者仅包含未加标签的值。
并非所有数据都包含命名输入。有些实例是 JSON 值(布尔值、数字或字符串)。不过,实例通常是值列表或复杂的嵌套列表。
以下是一些请求正文示例:
- CSV 数据,其中每行编码为字符串值:
{"instances": ["1.0,true,\\"x\\"", "-2.0,false,\\"y\\""]}
- 纯文本:
{"instances": ["the quick brown fox", "the lazy dog"]}
- 编码为字词列表的句子(字符串矢量):
{
"instances": [
["the","quick","brown"],
["the","lazy","dog"],
...
]
}
- 浮点标量值:
{"instances": [0.0, 1.1, 2.2]}
- 整数向量:
{
"instances": [
[0, 1, 2],
[3, 4, 5],
...
]
}
- 张量(在本示例中为二维张量):
{
"instances": [
[
[0, 1, 2],
[3, 4, 5]
],
...
]
}
- 图片,可通过不同方式来表示:
在本编码方案中,前两个维度表示图片的行和列,第三个维度包含每个像素的 R、G 和 B 值的列表(矢量):
{
"instances": [
[
[
[138, 30, 66],
[130, 20, 56],
...
],
[
[126, 38, 61],
[122, 24, 57],
...
],
...
],
...
]
}
数据编码
JSON 字符串必须采用 UTF-8 编码。如要发送二进制数据,您必须对数据进行 base64 编码并将数据标记为二进制。如要将 JSON 字符串标记为二进制,请将其替换为具有单一 b64
特性的 JSON 对象:
{"b64": "..."}
以下示例展示了两个需要 base64 编码的序列化 tf.Examples
实例(虚构的数据,仅作说明之用):
{"instances": [{"b64": "X5ad6u"}, {"b64": "IA9j4nx"}]}
以下示例显示两个需要 base64 编码的 JPEG 图片字节字符串(虚构的数据,仅作说明之用):
{"instances": [{"b64": "ASa8asdf"}, {"b64": "JLK7ljk3"}]}
多个输入张量
一些模型具有可接受多个输入张量的底层 TensorFlow 图。在这种情况下,请使用 JSON 键值对的名称来识别输入张量。
对于带有输入张量别名 tag
(字符串)和 image
(以 base64 编码的字符串)的图,请使用以下代码:
{
"instances": [
{
"tag": "beach",
"image": {"b64": "ASa8asdf"}
},
{
"tag": "car",
"image": {"b64": "JLK7ljk3"}
}
]
}
对于带有输入张量别名 tag
(字符串)和 image
(8 位整数的三维数组)的图,请使用以下代码:
{
"instances": [
{
"tag": "beach",
"image": [
[
[138, 30, 66],
[130, 20, 56],
...
],
[
[126, 38, 61],
[122, 24, 57],
...
],
...
]
},
{
"tag": "car",
"image": [
[
[255, 0, 102],
[255, 0, 97],
...
],
[
[254, 1, 101],
[254, 2, 93],
...
],
...
]
},
...
]
}
PyTorch
如果您的模型使用 PyTorch 预构建容器,则 TorchServe 的默认处理程序预期将每个实例封装在 data
字段中。例如:
{
"instances": [
{ "data": , <value> },
{ "data": , <value> }
]
}
响应正文详情
如果调用成功,则对于请求正文中的每个实例,响应正文都包含一个预测条目,并按相同顺序列出:
{
"predictions": [
{
object
}
],
"deployedModelId": string
}
如有任何实例的预测失败,则响应正文不会包含任何预测条目, 而是包含一个错误条目:
{
"error": string
}
predictions[]
对象包含预测结果列表,其中每个预测结果对应请求中的一个实例。
如果发生错误,error
字符串会包含一条描述问题的消息。如果在处理任何实例时发生错误,则系统会返回错误,而非预测结果列表。
即使每个实例只有一个预测结果,预测结果的格式也与实例的格式没有直接关联。预测结果的格式是由模型中定义的输出集合所指定。预测结果集合会以 JSON 列表的形式返回。列表的每个成员可以是值、列表或任何复杂度的 JSON 对象。如果模型具有多个输出张量,则每个预测结果都是一个 JSON 对象,其中包含每个输出的键值对。这些键可标识图中的输出别名。
响应正文示例
以下示例展示了 TensorFlow 的一些可能响应:
针对三个输入实例产生的一组预测结果,其中每个预测结果均为一个整数值:
{"predictions": [5, 4, 3], "deployedModelId": 123456789012345678 }
一组较复杂的预测结果,各包含两个与输出张量相对应的命名值,分别名为
label
和scores
。label
的值是预测的类别(car 或 beach),scores
包含该实例在各可能类别之间的概率列表:{ "predictions": [ { "label": "beach", "scores": [0.1, 0.9] }, { "label": "car", "scores": [0.75, 0.25] } ], "deployedModelId": 123456789012345678 }
处理输入实例出错时的响应:
{"error": "Divide by zero"}