Use as previsões on-line ao fazer solicitações em resposta a uma entrada de aplicativo ou em situações que exigem inferência em tempo hábil (respostas em tempo real).
Nesta página, mostramos como formatar solicitações de previsão on-line usando a API Online Prediction para seus modelos treinados personalizados e fornecemos exemplos de solicitações e respostas. Depois de formatar sua solicitação, você pode receber uma previsão on-line.
Antes de começar
Antes de formatar uma solicitação para fazer previsões on-line, siga estas etapas:
- Exporte o artefato do modelo para previsão.
Implante o recurso de modelo em um endpoint.
Essa ação associa recursos de computação ao modelo para que ele possa fazer previsões on-line com baixa latência.
Verifique o status do recurso personalizado
DeployedModel
do seu modelo e confirme se ele está pronto para aceitar solicitações de previsão:kubectl --kubeconfig PREDICTION_CLUSTER_KUBECONFIG get -f DEPLOYED_MODEL_NAME.yaml -o jsonpath='{.status.primaryCondition}'
Substitua:
PREDICTION_CLUSTER_KUBECONFIG
: o caminho para o arquivo kubeconfig no cluster de previsão.DEPLOYED_MODEL_NAME
: o nome do arquivo de definiçãoDeployedModel
.
A condição principal precisa mostrar que o
DeployedModel
está pronto.A saída a seguir mostra um exemplo de resposta:
{"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"}
Verifique o status do recurso personalizado
Endpoint
e confira se ele está pronto para aceitar solicitações de previsão:kubectl --kubeconfig PREDICTION_CLUSTER_KUBECONFIG get -f ENDPOINT_NAME.yaml -o jsonpath='{$.status.conditions[?(@.type == "EndpointReady")]}'
Substitua:
PREDICTION_CLUSTER_KUBECONFIG
: o caminho para o arquivo kubeconfig no cluster de previsão.ENDPOINT_NAME
: o nome do arquivo de definiçãoEndpoint
.
O campo
status
da condiçãoEndpointReady
precisa mostrar um valorTrue
.A saída a seguir mostra um exemplo de resposta:
{"lastTransitionTime":"2024-01-19T05:12:26Z","message":"Endpoint Ready", "observedGeneration":1,"reason":"ResourceReady","status":"True","type":"EndpointReady"}%
Formatar a entrada para previsões on-line
A previsão on-line tem dois métodos para enviar solicitações:
- Solicitação de previsão: envie uma solicitação para o método
predict
para receber uma previsão on-line. - Solicitação de previsão bruta: envie uma solicitação para o método
rawPredict
, que permite usar um payload HTTP arbitrário em vez de seguir um formato JSON.
Se você precisar de baixa latência, receba previsões brutas porque rawPredict
ignora as etapas de serialização e encaminha diretamente a solicitação para o contêiner de previsão.
Nesta seção, mostramos como formatar e codificar suas instâncias de entrada de previsão usando JSON, o que é necessário se você estiver usando o método predict
. Essas informações não são necessárias se você estiver usando o método rawPredict
.
Se você estiver usando o SDK da Vertex AI para Python para enviar solicitações de previsão, especifique
a lista de instâncias sem o campo instances
. Por exemplo, especifique [
["the","quick","brown"], ... ]
em vez de { "instances": [
["the","quick","brown"], ... ] }
.
Formatar instâncias como strings JSON
O formato básico da previsão on-line é uma lista de instâncias de dados. Ela pode ser uma lista simples de valores ou membros de um objeto JSON, dependendo de como você configurou as entradas no aplicativo de treinamento. Os modelos do TensorFlow podem aceitar entradas mais complexas.
O exemplo a seguir mostra um tensor de entrada e uma chave de instância para um modelo do TensorFlow:
{"values": [1, 2, 3, 4], "key": 1}
A composição da string JSON pode ser complexa, contanto que siga estas regras:
O nível superior dos dados da instância precisa ser um objeto JSON, que é um dicionário de pares de chave-valor.
Os valores individuais em um objeto de instância podem ser strings, números ou listas. Não é possível incorporar objetos JSON.
As listas devem conter apenas itens do mesmo tipo (incluindo outras listas). Não misture strings e valores numéricos.
Transmita as instâncias de entrada para previsão on-line como o corpo da mensagem da
chamada predict
. Saiba mais sobre os
requisitos de formatação do corpo da solicitação.
Torne cada instância um item em uma matriz JSON e forneça a matriz como o
campo instances
de um objeto JSON, como no exemplo a seguir:
{"instances": [
{"values": [1, 2, 3, 4], "key": 1},
{"values": [5, 6, 7, 8], "key": 2}
]}
Codificar dados binários para entrada de previsão
Não é possível formatar dados binários como as strings codificadas em UTF-8 compatíveis com JSON. Se houver dados binários nas entradas, use a codificação base64 para representá-los. Você precisa da seguinte formatação especial:
Formate a string codificada como um objeto JSON com uma única chave chamada
b64
. No Python 3, a codificação base64 gera uma sequência de bytes. Converta esta sequência em uma string para torná-la serializável em JSON:{'image_bytes': {'b64': base64.b64encode(jpeg_data).decode()}}
No código do modelo do TensorFlow, nomeie os aliases dos seus tensores binários de entrada e saída para que terminem com
_bytes
.
Exemplos de solicitação e resposta
Nesta seção, descrevemos o formato dos corpos da solicitação e da resposta de previsão on-line com exemplos para TensorFlow e PyTorch.
Detalhes do corpo da solicitação
TensorFlow
O corpo da solicitação contém dados com a seguinte estrutura na representação JSON:
{
"instances": [
<value>|<simple/nested list>|<object>,
...
]
}
O objeto instances[]
é obrigatório e precisa conter a lista de instâncias para as quais você receberá previsões.
A estrutura de cada elemento da lista é determinada pela definição de entrada do modelo. As instâncias podem incluir entradas nomeadas, como objetos, ou conter apenas valores sem rótulo.
Nem todos os dados incluem entradas nomeadas. Algumas instâncias são valores JSON (booleano, número ou string). No entanto, as instâncias costumam ser listas de valores ou listas aninhadas complexas.
Confira alguns exemplos de corpos de solicitação:
- Dados CSV com cada linha codificada como um valor de string:
{"instances": ["1.0,true,\\"x\\"", "-2.0,false,\\"y\\""]}
- Texto simples:
{"instances": ["the quick brown fox", "the lazy dog"]}
- Frases codificadas como listas de palavras (vetores de strings):
{
"instances": [
["the","quick","brown"],
["the","lazy","dog"],
...
]
}
- Valores de ponto flutuante escalares:
{"instances": [0.0, 1.1, 2.2]}
- Vetores de números inteiros:
{
"instances": [
[0, 1, 2],
[3, 4, 5],
...
]
}
- Tensores (neste caso, bidimensionais):
{
"instances": [
[
[0, 1, 2],
[3, 4, 5]
],
...
]
}
- Imagens, que podem ser representadas de maneiras diferentes:
Neste esquema de codificação, as duas primeiras dimensões representam as linhas e colunas da imagem. Já a terceira dimensão contém listas (vetores) dos valores R, G e B de cada pixel:
{
"instances": [
[
[
[138, 30, 66],
[130, 20, 56],
...
],
[
[126, 38, 61],
[122, 24, 57],
...
],
...
],
...
]
}
Codificação de dados
As strings JSON precisam ser codificadas em UTF-8. Para enviar dados binários, é necessário codificar os dados em base64 e marcá-los como binários. Para marcar uma string JSON como binária, substitua-a por um objeto JSON com um único atributo chamado b64
:
{"b64": "..."}
O exemplo a seguir mostra duas instâncias tf.Examples
serializadas, que exigem codificação base64 (dados falsos, apenas para fins ilustrativos):
{"instances": [{"b64": "X5ad6u"}, {"b64": "IA9j4nx"}]}
O exemplo a seguir mostra duas strings de byte de imagem JPEG que exigem a codificação base64 (dados meramente ilustrativos):
{"instances": [{"b64": "ASa8asdf"}, {"b64": "JLK7ljk3"}]}
Vários tensores de entrada
Alguns modelos têm um gráfico subjacente do TensorFlow que aceita vários tensores de entrada. Nesse caso, use os nomes dos pares de chave-valor JSON para identificar os tensores de entrada.
Para um gráfico com os aliases de tensor de entrada tag
(string) e image
(string codificada em Base64):
{
"instances": [
{
"tag": "beach",
"image": {"b64": "ASa8asdf"}
},
{
"tag": "car",
"image": {"b64": "JLK7ljk3"}
}
]
}
Para um gráfico com os aliases de tensor de entrada tag
(string) e image
(matriz tridimensional com ints de 8 bits):
{
"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
Se o modelo usa um contêiner pré-criado do PyTorch,
os gerenciadores padrão do TorchServe esperam que cada instância seja encapsulada em um
campo data
. Exemplo:
{
"instances": [
{ "data": , <value> },
{ "data": , <value> }
]
}
Detalhes do corpo da resposta
Se a chamada for bem-sucedida, o corpo da resposta terá uma entrada de previsão por instância no corpo da solicitação, dadas na mesma ordem:
{
"predictions": [
{
object
}
],
"deployedModelId": string
}
Se a previsão falhar em qualquer instância, o corpo da resposta não terá previsões. Em vez disso, ele inclui uma única entrada de erro:
{
"error": string
}
O objeto predictions[]
contém a lista de previsões, uma para cada instância na solicitação.
Em caso de erro, a string error
contém uma mensagem descrevendo o problema. Se ocorrer um erro durante o processamento de qualquer instância, ele será retornado em vez de uma lista de previsão.
Há uma previsão por instância, mas o formato da previsão não está diretamente relacionado ao da instância. As previsões recebem o formato especificado no conjunto de saídas definido no modelo. O conjunto de previsões é retornado em uma lista JSON. Cada membro da lista pode ser um valor, uma lista ou um objeto JSON de qualquer complexidade. Se o seu modelo tiver mais de um tensor de saída, cada previsão será um objeto JSON com um par de chave-valor para cada saída. As chaves identificam os aliases de saída no gráfico.
Exemplos de corpo de resposta
Confira alguns exemplos de respostas possíveis para o TensorFlow:
Conjunto de previsões de três instâncias de entrada, em que cada previsão é um valor inteiro:
{"predictions": [5, 4, 3], "deployedModelId": 123456789012345678 }
Um conjunto mais complexo de previsões, cada uma contendo dois valores nomeados que correspondem aos tensores de saída, denominados
label
escores
, respectivamente. O valor delabel
é a categoria prevista (carro ou praia) escores
contém uma lista de probabilidades para essa instância nas categorias possíveis:{ "predictions": [ { "label": "beach", "scores": [0.1, 0.9] }, { "label": "car", "scores": [0.75, 0.25] } ], "deployedModelId": 123456789012345678 }
Resposta quando há um erro ao processar uma instância de entrada:
{"error": "Divide by zero"}