Selain gRPC API TensorFlow ModelServer juga mendukung API tenang. Halaman ini menjelaskan titik akhir API ini dan end-to-end contoh pada penggunaan.
Permintaan dan respons adalah objek JSON. Komposisi objek ini tergantung pada jenis permintaan atau kata kerja. Lihat bagian khusus API di bawah untuk detailnya.
Dalam kasus kesalahan, semua API akan mengembalikan objek JSON dalam tubuh respon dengan error
sebagai kunci dan pesan kesalahan sebagai nilai:
{
"error": <error message string>
}
API status model
API ini erat mengikuti ModelService.GetModelStatus
API gRPC. Ini mengembalikan status model di ModelServer.
URL
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]
Termasuk /versions/${VERSION}
atau /labels/${LABEL}
adalah opsional. Jika dihilangkan status untuk semua versi dikembalikan dalam respons.
Format tanggapan
Jika berhasil, mengembalikan representasi JSON dari GetModelStatusResponse
protobuf.
Model Metadata API
API ini erat mengikuti PredictionService.GetModelMetadata
API gRPC. Ini mengembalikan metadata model di ModelServer.
URL
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]/metadata
Termasuk /versions/${VERSION}
atau /labels/${LABEL}
adalah opsional. Jika dihilangkan, metadata model untuk versi terbaru dikembalikan dalam respons.
Format tanggapan
Jika berhasil, mengembalikan representasi JSON dari GetModelMetadataResponse
protobuf.
Classify dan Regress API
API ini erat mengikuti Classify
dan Regress
metode PredictionService
gRPC API.
URL
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:(classify|regress)
Termasuk /versions/${VERSION}
atau /labels/${LABEL}
adalah opsional. Jika dihilangkan digunakan versi terbaru.
Format permintaan
Permintaan tubuh untuk classify
dan regress
API harus menjadi objek JSON diformat sebagai berikut:
{
// 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>
adalah nomor JSON (keseluruhan atau desimal), string JSON, atau objek JSON yang mewakili data biner (lihat Pengkodean biner nilai di bawah untuk rincian). <list>
adalah daftar nilai-nilai tersebut. Format ini mirip dengan gRPC ini ClassificationRequest
dan RegressionRequest
protos. Kedua versi menerima daftar Example
benda.
Format tanggapan
Sebuah classify
permintaan mengembalikan sebuah objek JSON dalam tubuh respon, diformat sebagai berikut:
{
"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>
adalah string (yang dapat menjadi string kosong ""
jika model tidak memiliki label yang berhubungan dengan skor). <score>
adalah desimal (floating point) nomor.
The regress
permintaan mengembalikan sebuah objek JSON dalam tubuh respon, diformat sebagai berikut:
{
// One regression value for each example in the request in the same order.
"result": [ <value1>, <value2>, <value3>, ...]
}
<value>
adalah angka desimal.
Pengguna gRPC API akan melihat kesamaan format ini dengan ClassificationResponse
dan RegressionResponse
protos.
Prediksi API
API ini erat mengikuti PredictionService.Predict
API gRPC.
URL
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:predict
Termasuk /versions/${VERSION}
atau /labels/${LABEL}
adalah opsional. Jika dihilangkan digunakan versi terbaru.
Format permintaan
Permintaan tubuh untuk predict
API harus JSON objek diformat sebagai berikut:
{
// (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>
}
Menentukan tensor input dalam format baris.
Format ini mirip dengan PredictRequest
proto dari gRPC API dan CMLE memprediksi API . Gunakan format ini jika semua tensor masukan bernama memiliki yang sama 0-th dimensi. Jika tidak, gunakan format kolom yang dijelaskan nanti di bawah.
Dalam format baris, input dikunci untuk kunci contoh dalam permintaan JSON.
Ketika hanya ada satu nama input, menentukan nilai contoh kunci untuk menjadi nilai input:
{
// List of 3 scalar tensors.
"instances": [ "foo", "bar", "baz" ]
}
{
// List of 2 tensors each of [1, 2] shape
"instances": [ [[1, 2]], [[3, 4]] ]
}
Tensor diekspresikan secara alami dalam notasi bersarang karena tidak perlu meratakan daftar secara manual.
Untuk beberapa input bernama, setiap item diharapkan menjadi objek yang berisi pasangan nama input/nilai tensor, satu untuk setiap input bernama. Sebagai contoh, berikut ini adalah permintaan dengan dua instance, masing-masing dengan satu set tiga tensor input bernama:
{
"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]]
}
]
}
Catatan, masing-masing bernama input ( "tag", "sinyal", "sensor") secara implisit diasumsikan memiliki yang sama 0-th dimensi (dua di contoh di atas, karena ada dua benda dalam daftar kasus). Jika Anda telah menamai input yang memiliki dimensi ke-0 yang berbeda, gunakan format kolom yang dijelaskan di bawah ini.
Menentukan tensor input dalam format kolom.
Gunakan format ini untuk menentukan tensor input Anda, jika input bernama individual tidak memiliki dimensi ke-0 yang sama atau Anda menginginkan representasi yang lebih ringkas. Format ini mirip dengan inputs
bidang gRPC Predict
permintaan.
Dalam format columnar, input dikunci untuk kunci masukan dalam permintaan JSON.
Nilai untuk kunci input bisa baik tensor masukan tunggal atau peta nama masukan untuk tensor (terdaftar dalam bentuk bersarang alami mereka). Setiap input dapat memiliki bentuk arbitrer dan tidak perlu berbagi/dimensi ke-0 yang sama (alias ukuran batch) seperti yang dipersyaratkan oleh format baris yang dijelaskan di atas.
Representasi kolom dari contoh sebelumnya adalah sebagai berikut:
{
"inputs": {
"tag": ["foo", "bar"],
"signal": [[1, 2, 3, 4, 5], [3, 4, 1, 2, 5]],
"sensor": [[[1, 2], [3, 4]], [[4, 5], [6, 8]]]
}
}
Catatan, masukan adalah objek JSON dan bukan daftar seperti contoh (yang digunakan dalam representasi baris). Juga, semua input bernama ditentukan bersama-sama, bukan membuka gulungannya ke dalam baris individual yang dilakukan dalam format baris yang dijelaskan sebelumnya. Ini membuat representasi menjadi ringkas (tetapi mungkin kurang mudah dibaca).
Format tanggapan
The predict
permintaan pengembalian objek JSON dalam tubuh respon.
Permintaan di format baris telah respon diformat sebagai berikut:
{
"predictions": <value>|<(nested)list>|<list-of-objects>
}
Jika output dari model yang hanya berisi satu bernama tensor, kita menghilangkan nama dan predictions
kunci peta ke daftar skalar atau daftar nilai-nilai. Jika model mengeluarkan beberapa tensor bernama, kami menampilkan daftar objek sebagai gantinya, mirip dengan permintaan dalam format baris yang disebutkan di atas.
Permintaan di Format columnar telah respon diformat sebagai berikut:
{
"outputs": <value>|<(nested)list>|<object>
}
Jika output dari model yang hanya berisi satu bernama tensor, kita menghilangkan nama dan outputs
kunci peta ke daftar skalar atau daftar nilai-nilai. Jika model mengeluarkan beberapa tensor bernama, kami mengeluarkan objek sebagai gantinya. Setiap kunci dari objek ini sesuai dengan tensor keluaran bernama. Formatnya mirip dengan permintaan dalam format kolom yang disebutkan di atas.
Keluaran nilai biner
TensorFlow tidak membedakan antara string non-biner dan biner. Semua yang DT_STRING
jenis. Dinamakan tensor yang memiliki _bytes
sebagai akhiran di nama mereka dianggap memiliki nilai-nilai biner. Nilai-nilai tersebut dikodekan berbeda seperti yang dijelaskan dalam pengkodean nilai biner bagian bawah.
pemetaan JSON
RESTful API mendukung pengkodean kanonik di JSON, membuatnya lebih mudah untuk berbagi data antar sistem. Untuk jenis yang didukung, pengkodean dijelaskan berdasarkan jenis per jenis dalam tabel di bawah ini. Jenis yang tidak tercantum di bawah dianggap tidak didukung.
Tipe Data TF | Nilai JSON | contoh JSON | Catatan |
---|---|---|---|
DT_BOOL | benar salah | benar salah | |
DT_STRING | rangkaian | "Halo Dunia!" | Jika DT_STRING mewakili byte biner (misalnya byte gambar serial atau protobuf), encode ini dalam Base64. Lihat Encoding nilai biner untuk info lebih lanjut. |
DT_INT8, DT_UINT8, DT_INT16, DT_INT32, DT_UINT32, DT_INT64, DT_UINT64 | nomor | 1, -10, 0 | Nilai JSON akan menjadi angka desimal. |
DT_FLOAT, DT_DOUBLE | nomor | 1.1, -10,0, 0, NaN , Infinity | Nilai JSON akan menjadi nomor atau salah satu dari nilai tanda khusus - NaN , Infinity , dan -Infinity . Lihat JSON kesesuaian untuk info lebih lanjut. Notasi eksponen juga diterima. |
Presisi Titik Mengambang
JSON memiliki tipe data angka tunggal. Dengan demikian dimungkinkan untuk memberikan nilai input yang mengakibatkan hilangnya presisi. Misalnya, jika input x
adalah float
tipe data, dan input {"x": 1435774380}
dikirim ke model yang berjalan pada hardware didasarkan pada IEEE 754 floating point standar (misalnya Intel atau AMD), maka nilai akan akan diam-diam dikonversi oleh hardware underyling ke 1435774336
sejak 1435774380
tidak dapat tepat diwakili dalam 32-bit angka floating point. Biasanya, input ke penayangan harus sama dengan distribusi pelatihan, jadi ini umumnya tidak akan bermasalah karena konversi yang sama terjadi pada waktu pelatihan. Namun, jika presisi penuh diperlukan, pastikan untuk menggunakan tipe data dasar dalam model Anda yang dapat menangani presisi yang diinginkan dan/atau mempertimbangkan pemeriksaan sisi klien.
Mengkodekan nilai biner
JSON menggunakan pengkodean UTF-8. Jika Anda memiliki fitur atau tensor masukan nilai-nilai yang perlu menjadi biner (seperti gambar byte), Anda harus Base64 menyandikan data dan merangkum dalam sebuah objek JSON memiliki b64
sebagai kunci sebagai berikut:
{ "b64": <base64 encoded string> }
Anda dapat menentukan objek ini sebagai nilai untuk fitur input atau tensor. Format yang sama juga digunakan untuk mengkodekan respons keluaran.
Permintaan klasifikasi dengan image
(data biner) dan caption
fitur ditunjukkan di bawah ini:
{
"signature_name": "classify_objects",
"examples": [
{
"image": { "b64": "aW1hZ2UgYnl0ZXM=" },
"caption": "seaside"
},
{
"image": { "b64": "YXdlc29tZSBpbWFnZSBieXRlcw==" },
"caption": "mountains"
}
]
}
Kesesuaian JSON
Banyak fitur atau nilai tensor adalah bilangan floating point. Terlepas dari nilai-nilai yang terbatas (misalnya 3,14, 1,0 dll) ini dapat memiliki NaN
dan non-terbatas ( Infinity
dan -Infinity
) nilai-nilai. Sayangnya JSON spesifikasi ( RFC 7159 ) TIDAK mengenali nilai-nilai ini (meskipun spesifikasi JavaScript tidak).
REST API yang dijelaskan pada halaman ini memungkinkan objek JSON permintaan/tanggapan memiliki nilai seperti itu. Ini menyiratkan bahwa permintaan seperti berikut ini valid:
{
"example": [
{
"sensor_readings": [ 1.0, -3.14, Nan, Infinity ]
}
]
}
A (ketat) sesuai standar JSON parser akan menolak ini dengan kesalahan parse (karena NaN
dan Infinity
token dicampur dengan angka yang sebenarnya). Untuk menangani permintaan/respons dalam kode Anda dengan benar, gunakan parser JSON yang mendukung token ini.
NaN
, Infinity
, -Infinity
token diakui oleh proto3 , Python JSON modul dan bahasa JavaScript.
Contoh
Kita dapat menggunakan mainan half_plus_three Model untuk melihat SISA API dalam tindakan.
Mulai ModelServer dengan titik akhir REST API
Download half_plus_three
Model dari repositori git :
$ mkdir -p /tmp/tfserving
$ cd /tmp/tfserving
$ git clone --depth=1 https://github.com/tensorflow/serving
Kami akan menggunakan Docker untuk menjalankan ModelServer. Jika Anda ingin menginstal ModelServer native pada sistem Anda, ikuti instruksi pengaturan untuk menginstal sebaliknya, dan memulai ModelServer dengan --rest_api_port
pilihan untuk ekspor SISA API endpoint (ini tidak diperlukan bila menggunakan 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 ...
Lakukan panggilan REST API ke ModelServer
Dalam terminal yang berbeda, gunakan curl
alat untuk membuat panggilan API REST.
Dapatkan status model sebagai berikut:
$ curl http://localhost:8501/v1/models/saved_model_half_plus_three
{
"model_version_status": [
{
"version": "123",
"state": "AVAILABLE",
"status": {
"error_code": "OK",
"error_message": ""
}
}
]
}
Sebuah predict
panggilan akan terlihat sebagai berikut:
$ 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]
}
Dan regress
panggilan terlihat sebagai berikut:
$ 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]
}
Catatan, regress
tersedia pada nama tanda tangan non-default dan harus ditentukan secara eksplisit. URL atau isi permintaan yang salah mengembalikan status kesalahan 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)" }
$