Además de GRPC APIs TensorFlow ModelServer también soporta APIs reparador. Esta página describe estos criterios de valoración de la API y una de extremo a extremo ejemplo del uso.
La solicitud y la respuesta es un objeto JSON. La composición de este objeto depende del tipo de petición o verbo. Consulte las secciones específicas de la API a continuación para obtener más detalles.
En caso de error, todas las API devolverá un objeto JSON en el cuerpo de la respuesta con error
como la clave y el mensaje de error como el valor:
{
"error": <error message string>
}
API de estado del modelo
Esta API sigue de cerca la ModelService.GetModelStatus
API GRPC. Devuelve el estado de un modelo en ModelServer.
URL
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]
Incluyendo /versions/${VERSION}
o /labels/${LABEL}
es opcional. Si se devuelve el estado omitido para todas las versiones en la respuesta.
Formato de respuesta
Si tiene éxito, devuelve una representación JSON de GetModelStatusResponse
protobuf.
API de metadatos del modelo
Esta API sigue de cerca la PredictionService.GetModelMetadata
API GRPC. Devuelve los metadatos de un modelo en ModelServer.
URL
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]/metadata
Incluyendo /versions/${VERSION}
o /labels/${LABEL}
es opcional. Si se omite, los metadatos del modelo para la última versión se devuelven en la respuesta.
Formato de respuesta
Si tiene éxito, devuelve una representación JSON de GetModelMetadataResponse
protobuf.
API de clasificación y regresión
Esta API sigue de cerca las Classify
y Regress
métodos de PredictionService
API GRPC.
URL
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:(classify|regress)
Incluyendo /versions/${VERSION}
o /labels/${LABEL}
es opcional. Si se omite, se utiliza la última versión.
Formato de solicitud
El cuerpo de la solicitud para los classify
y regress
APIs debe ser un objeto JSON formateado como sigue:
{
// 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>
es un número JSON (entero o decimal), cadena JSON, o un objeto JSON que representa datos binarios (ver el valores Codificación binaria siguiente sección para detalles). <list>
es una lista de tales valores. Este formato es similar al de GRPC ClassificationRequest
y RegressionRequest
Protos. Ambas versiones lista de aceptan Example
objetos.
Formato de respuesta
A classify
solicitud devuelve un objeto JSON en el cuerpo de la respuesta, con el formato siguiente:
{
"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>
es una cadena (que puede ser una cadena vacía ""
si el modelo no tiene una etiqueta asociada con la puntuación). <score>
es un número decimal (coma flotante).
La regress
solicitud devuelve un objeto JSON en el cuerpo de la respuesta, con el formato siguiente:
{
// One regression value for each example in the request in the same order.
"result": [ <value1>, <value2>, <value3>, ...]
}
<value>
es un número decimal.
Los usuarios de GRPC API se dará cuenta de la similitud de este formato con ClassificationResponse
y RegressionResponse
Protos.
Predecir API
Esta API sigue de cerca la PredictionService.Predict
API GRPC.
URL
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:predict
Incluyendo /versions/${VERSION}
o /labels/${LABEL}
es opcional. Si se omite, se utiliza la última versión.
Formato de solicitud
El cuerpo de la petición para predict
API debe ser objeto JSON siguiente formato:
{
// (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>
}
Especificación de tensores de entrada en formato de fila.
Este formato es similar a PredictRequest
proto de API GRPC y la CMLE predecir API . Utilice este formato si todos los tensores de entrada tienen el mismo nombre 0-ésima dimensión. Si no es así, utilice el formato de columnas que se describe más adelante.
En el formato de fila, las entradas tienen la forma adecuada a las instancias clave en la solicitud JSON.
Cuando sólo hay una llamada de entrada, especifique el valor de instancias claves para ser el valor de la entrada:
{
// List of 3 scalar tensors.
"instances": [ "foo", "bar", "baz" ]
}
{
// List of 2 tensors each of [1, 2] shape
"instances": [ [[1, 2]], [[3, 4]] ]
}
Los tensores se expresan de forma natural en notación anidada, ya que no es necesario aplanar manualmente la lista.
Para múltiples entradas con nombre, se espera que cada elemento sea un objeto que contenga un par de valor de tensor/nombre de entrada, uno para cada entrada con nombre. Como ejemplo, la siguiente es una solicitud con dos instancias, cada una con un conjunto de tres tensores de entrada con nombre:
{
"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]]
}
]
}
Nota, cada entrada de llamada ( "etiqueta", "señal", "sensor") está implícitamente asumido tener mismo 0-ésima dimensión (dos en el ejemplo anterior, ya que hay dos objetos de la lista instancias). Si ha nombrado entradas que tienen una dimensión 0-ésima diferente, use el formato de columnas que se describe a continuación.
Especificación de tensores de entrada en formato de columna.
Utilice este formato para especificar sus tensores de entrada, si las entradas nombradas individuales no tienen la misma dimensión 0 o si desea una representación más compacta. Este formato es similar a la inputs
campo de la GRPC Predict
petición.
En el formato de columnas, las entradas tienen la forma adecuada a las entradas clave en la solicitud JSON.
El valor de clave de entradas puede ya sea un solo tensor de entrada o un mapa de nombre de entrada a los tensores (enumerados en su forma anidada natural). Cada entrada puede tener una forma arbitraria y no necesita compartir la misma dimensión 0 (también conocido como tamaño de lote) como lo requiere el formato de fila descrito anteriormente.
La representación en columnas del ejemplo anterior es la siguiente:
{
"inputs": {
"tag": ["foo", "bar"],
"signal": [[1, 2, 3, 4, 5], [3, 4, 1, 2, 5]],
"sensor": [[[1, 2], [3, 4]], [[4, 5], [6, 8]]]
}
}
Nota, las entradas es un objeto JSON y no una lista como casos (utilizado en la representación fila). Además, todas las entradas con nombre se especifican juntas, en lugar de desplegarlas en filas individuales en el formato de fila descrito anteriormente. Esto hace que la representación sea compacta (pero tal vez menos legible).
Formato de respuesta
El predict
la petición devuelve un objeto JSON en el cuerpo de la respuesta.
Una solicitud en formato de fila ha formateado la respuesta de la siguiente manera:
{
"predictions": <value>|<(nested)list>|<list-of-objects>
}
Si la salida del modelo contiene sólo un tensor de nombre, omitimos el nombre y predictions
clave se asigna a una lista de valores escalares o lista. Si el modelo genera múltiples tensores con nombre, generamos una lista de objetos en su lugar, similar a la solicitud en formato de fila mencionada anteriormente.
Una solicitud en formato de columnas ha formateado la respuesta de la siguiente manera:
{
"outputs": <value>|<(nested)list>|<object>
}
Si la salida del modelo contiene sólo un tensor de nombre, omitimos el nombre y outputs
clave de mapas a una lista de valores escalares o lista. Si el modelo genera múltiples tensores con nombre, generamos un objeto en su lugar. Cada clave de este objeto corresponde a un tensor de salida con nombre. El formato es similar a la solicitud en formato de columna mencionada anteriormente.
Salida de valores binarios
TensorFlow no distingue entre cadenas binarias y no binarias. Todos están DT_STRING
tipo. Tensores con nombre que tienen _bytes
como un sufijo en su nombre se considera que tienen valores binarios. Tales valores están codificados de manera diferente como se describe en el valores binarios que codifica sección de abajo.
Mapeo JSON
Las API RESTful admiten una codificación canónica en JSON, lo que facilita el intercambio de datos entre sistemas. Para los tipos admitidos, las codificaciones se describen tipo por tipo en la siguiente tabla. Se supone que los tipos que no se enumeran a continuación no son compatibles.
Tipo de datos TF | Valor JSON | ejemplo JSON | notas |
---|---|---|---|
DT_BOOL | verdadero Falso | verdadero Falso | |
DT_STRING | cuerda | "¡Hola Mundo!" | Si DT_STRING representa bytes binarios (por ejemplo, bytes de imagen serializados o protobuf), codifican estas en Base64. Ver Codificación de valores binarios para obtener más información. |
DT_INT8, DT_UINT8, DT_INT16, DT_INT32, DT_UINT32, DT_INT64, DT_UINT64 | número | 1, -10, 0 | El valor JSON será un número decimal. |
DT_FLOTANTE, DT_DOBLE | número | 1,1, -10,0, 0, NaN , Infinity | JSON valor será un número o uno de los valores de los símbolos especiales - NaN , Infinity , y -Infinity . Ver JSON conformidad para obtener más información. También se acepta la notación exponencial. |
Precisión de punto flotante
JSON tiene un tipo de datos de un solo número. Por lo tanto, es posible proporcionar un valor para una entrada que resulte en una pérdida de precisión. Por ejemplo, si la entrada x
es un float
tipo de datos, y la entrada {"x": 1435774380}
se envía al modelo que se ejecuta en hardware basado en el estándar de punto flotante IEEE 754 (por ejemplo, Intel o AMD), entonces el valor será convierte automáticamente el hardware underyling al 1435774336
puesto 1435774380
no se puede representar exactamente en un número de coma flotante de 32 bits. Por lo general, las entradas para servir deben tener la misma distribución que el entrenamiento, por lo que esto generalmente no será problemático porque se produjeron las mismas conversiones en el momento del entrenamiento. Sin embargo, en caso de que se necesite precisión total, asegúrese de usar un tipo de datos subyacente en su modelo que pueda manejar la precisión deseada y/o considere la verificación del lado del cliente.
Codificación de valores binarios
JSON utiliza la codificación UTF-8. Si tiene valores de características o tensores de entrada que deben ser binario (como la imagen bytes), debe Base64 codificar los datos y encapsular en un objeto JSON con b64
como la clave de la siguiente manera:
{ "b64": <base64 encoded string> }
Puede especificar este objeto como un valor para una entidad de entrada o un tensor. El mismo formato también se utiliza para codificar la respuesta de salida.
Una solicitud de clasificación con image
(datos binarios) y caption
características se muestra a continuación:
{
"signature_name": "classify_objects",
"examples": [
{
"image": { "b64": "aW1hZ2UgYnl0ZXM=" },
"caption": "seaside"
},
{
"image": { "b64": "YXdlc29tZSBpbWFnZSBieXRlcw==" },
"caption": "mountains"
}
]
}
Conformidad con JSON
Muchos valores de características o tensores son números de punto flotante. Aparte de valores finitos (por ejemplo, 3,14, 1,0, etc.) éstos pueden tener NaN
y no finitos ( Infinity
y -Infinity
valores). Por desgracia la especificación JSON ( el RFC 7159 ) NO reconoce estos valores (aunque la especificación JavaScript hace).
La API REST descrita en esta página permite que los objetos JSON de solicitud/respuesta tengan dichos valores. Esto implica que solicitudes como la siguiente son válidas:
{
"example": [
{
"sensor_readings": [ 1.0, -3.14, Nan, Infinity ]
}
]
}
A (estrictos estándares JSON) compatible analizador rechazará esto con un error de análisis (debido a NaN
e Infinity
fichas mezclado con números reales). Para manejar correctamente las solicitudes/respuestas en su código, use un analizador JSON que admita estos tokens.
NaN
, Infinity
, -Infinity
fichas son reconocidos por proto3 , Python JSON módulo y Javascript.
Ejemplo
Podemos utilizar el juguete half_plus_three modelo para ver las API REST en acción.
Inicie ModelServer con el punto final de la API REST
Descargar el half_plus_three
modelo de repositorio git :
$ mkdir -p /tmp/tfserving
$ cd /tmp/tfserving
$ git clone --depth=1 https://github.com/tensorflow/serving
Usaremos Docker para ejecutar ModelServer. Si desea instalar ModelServer de forma nativa en el sistema, siga las instrucciones de instalación para instalar en su lugar, e iniciar el ModelServer con --rest_api_port
opción de punto final de exportación API REST (esto no es necesario cuando se utiliza estibador).
$ 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 ...
Hacer llamadas API REST a ModelServer
En un terminal diferente, utilice el curl
herramienta para hacer llamadas a la API REST.
Obtenga el estado del modelo de la siguiente manera:
$ curl http://localhost:8501/v1/models/saved_model_half_plus_three
{
"model_version_status": [
{
"version": "123",
"state": "AVAILABLE",
"status": {
"error_code": "OK",
"error_message": ""
}
}
]
}
Un predict
llamada se vería de la siguiente manera:
$ 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]
}
Y un regress
de llamada es el siguiente:
$ 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]
}
Tenga en cuenta, regress
está disponible en el nombre de la firma no predeterminada y debe especificarse de forma explícita. Una URL o un cuerpo de solicitud incorrectos devuelven un estado de error 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)" }
$