Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

API RESTful

Selain API gRPC, TensorFlow ModelServer juga mendukung RESTful API. Halaman ini menjelaskan titik akhir API ini dan end-to-end contoh pada penggunaan.

Permintaan dan respons adalah objek JSON. Komposisi objek ini bergantung pada jenis permintaan atau kata kerja. Lihat bagian khusus API di bawah untuk detailnya.

Jika terjadi kesalahan, semua API akan mengembalikan objek JSON dalam isi respons dengan error sebagai kunci dan pesan kesalahan sebagai nilai:

{
  "error": <error message string>
}

API status model

API ini mengikuti API ModelService.GetModelStatus ModelService.GetModelStatus. Ini mengembalikan status model di ModelServer.

URL

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

Menyertakan /versions/${VERSION} atau /labels/${LABEL} bersifat opsional. Jika status yang dihilangkan untuk semua versi dikembalikan dalam respons.

Format tanggapan

Jika berhasil, menampilkan representasi JSON dari protobuf GetModelStatusResponse .

Model Metadata API

API ini mengikuti API gRPC PredictionService.GetModelMetadata . Ini mengembalikan metadata model di ModelServer.

URL

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

Menyertakan /versions/${VERSION} atau /labels/${LABEL} bersifat opsional. Jika dihilangkan, metadata model untuk versi terbaru dikembalikan dalam respons.

Format tanggapan

Jika berhasil, menampilkan representasi JSON dari protobuf GetModelMetadataResponse .

Klasifikasi dan Regres API

API ini mengikuti metode Classify and Regress dari PredictionService gRPC API.

URL

POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:(classify|regress)

Menyertakan /versions/${VERSION} atau /labels/${LABEL} bersifat opsional. Jika dihilangkan, versi terbaru digunakan.

Format permintaan

Badan permintaan untuk classify and regress API harus berupa objek JSON dengan format 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 angka JSON (keseluruhan atau desimal) atau string, dan <list> adalah daftar nilai tersebut. Lihat bagian Mengenkode nilai biner di bawah untuk mengetahui detail tentang cara merepresentasikan nilai biner (aliran byte). Format ini mirip dengan protos ClassificationRequest dan RegressionRequest gRPC. Kedua versi menerima daftar objek Example .

Format tanggapan

Permintaan classify mengembalikan objek JSON dalam isi respons, dengan format 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 bisa menjadi string kosong "" jika model tidak memiliki label yang terkait dengan skor). <score> adalah bilangan desimal (floating point).

Permintaan regress mengembalikan objek JSON dalam isi respons, dengan format 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 protos ClassificationResponse dan RegressionResponse .

Predict API

API ini mengikuti API gRPC PredictionService.Predict .

URL

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

Menyertakan /versions/${VERSION} atau /labels/${LABEL} bersifat opsional. Jika dihilangkan, versi terbaru digunakan.

Format permintaan

Badan permintaan untuk API predict harus berupa objek JSON dengan format 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 dimensi ke-0 yang sama . Jika tidak, gunakan format kolom yang dijelaskan nanti di bawah.

Dalam format baris, masukan dimasukkan ke kunci instance dalam permintaan JSON.

Jika hanya ada satu input bernama, tentukan nilai kunci instance 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]] ]
}
.dll

Tensor diekspresikan secara alami dalam notasi bertingkat 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, setiap input bernama ("tag", "signal", "sensor") secara implisit diasumsikan memiliki dimensi ke-0 yang sama ( dua dalam contoh di atas, karena ada dua objek dalam daftar instance ). 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 ingin representasi yang lebih ringkas. Format ini mirip dengan bidang inputs pada permintaan Predict gRPC.

Dalam format kolom, masukan dimasukkan ke kunci masukan dalam permintaan JSON.

Nilai untuk kunci input bisa berupa tensor input tunggal atau peta nama input ke tensor (tercantum dalam bentuk bertingkat aslinya). Setiap masukan dapat memiliki bentuk yang berubah-ubah dan tidak perlu berbagi / dimensi ke-0 yang sama (alias ukuran kumpulan) seperti yang diharuskan 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]]]
 }
}
.dll

Catatan, input adalah objek JSON dan bukan daftar seperti instance (digunakan dalam representasi baris). Selain itu, semua input bernama ditentukan bersama-sama, sebagai kebalikan dari membukanya menjadi baris individual yang dilakukan dalam format baris yang dijelaskan sebelumnya. Ini membuat representasi kompak (tapi mungkin kurang terbaca).

Format tanggapan

Permintaan predict mengembalikan objek JSON dalam isi respons.

Permintaan dalam format baris memiliki format respons sebagai berikut:

{
  "predictions": <value>|<(nested)list>|<list-of-objects>
}

Jika keluaran model hanya berisi satu tensor bernama, kita menghilangkan peta kunci nama dan predictions ke daftar nilai skalar atau daftar. Jika model mengeluarkan beberapa tensor bernama, sebagai gantinya kita menampilkan daftar objek, mirip dengan permintaan dalam format baris yang disebutkan di atas.

Permintaan dalam format kolom memiliki format tanggapan sebagai berikut:

{
  "outputs": <value>|<(nested)list>|<object>
}

Jika keluaran model hanya berisi satu tensor bernama, kita menghilangkan nama dan outputs peta kunci ke daftar nilai skalar atau daftar. Jika model mengeluarkan beberapa tensor bernama, kami mengeluarkan objek sebagai gantinya. Setiap kunci dari objek ini sesuai dengan tensor keluaran bernama. Formatnya mirip dengan request dalam format kolom yang disebutkan di atas.

Output dari nilai biner

TensorFlow tidak membedakan antara string non-biner dan biner. Semua adalah tipe DT_STRING . Tensor bernama yang memiliki _bytes sebagai sufiks pada namanya dianggap memiliki nilai biner. Nilai-nilai tersebut dikodekan secara berbeda seperti yang dijelaskan di bagian pengkodean nilai biner di bawah ini.

Pemetaan JSON

RESTful API mendukung encoding kanonik di JSON, sehingga lebih mudah untuk berbagi data antar sistem. Untuk jenis yang didukung, penyandiaksaraan dijelaskan menurut jenisnya pada tabel di bawah. Jenis yang tidak tercantum di bawah tersirat tidak didukung.

Tipe Data TF Nilai JSON Contoh JSON Catatan
DT_BOOL benar salah benar salah
DT_STRING tali "Halo Dunia!" Jika DT_STRING mewakili byte biner (mis. DT_STRING gambar berseri atau protobuf), encode ini di Base64. Lihat Mengenkode nilai biner untuk info lebih lanjut.
DT_INT8, DT_UINT8, DT_INT16, DT_INT32, DT_UINT32, DT_INT64, DT_UINT64 jumlah 1, -10, 0 Nilai JSON akan menjadi angka desimal.
DT_FLOAT, DT_DOUBLE jumlah 1.1, -10.0, 0, NaN , Infinity Nilai JSON akan berupa angka atau salah satu nilai token khusus - NaN , Infinity , dan -Infinity . Lihat kesesuaian JSON untuk info lebih lanjut. Notasi eksponen juga diterima.

Mengkodekan nilai biner

JSON menggunakan pengkodean UTF-8. Jika Anda memiliki fitur masukan atau nilai tensor yang harus berupa biner (seperti byte gambar), Anda harus menyandikan data dan mengenkapsulasi Base64 dalam objek JSON yang memiliki b64 sebagai kuncinya sebagai berikut:

{ "b64": <base64 encoded string> }

Anda dapat menentukan objek ini sebagai nilai untuk fitur input atau tensor. Format yang sama juga digunakan untuk menyandikan respons keluaran.

Permintaan klasifikasi dengan image (data biner) dan fitur caption ditampilkan di bawah ini:

{
  "signature_name": "classify_objects",
  "examples": [
    {
      "image": { "b64": "aW1hZ2UgYnl0ZXM=" },
      "caption": "seaside"
    },
    {
      "image": { "b64": "YXdlc29tZSBpbWFnZSBieXRlcw==" },
      "caption": "mountains"
    }
  ]
}

Kepatuhan JSON

Banyak fitur atau nilai tensor merupakan bilangan floating point. Terlepas dari nilai hingga (misalnya 3.14, 1.0 dll.) Ini dapat memiliki nilai NaN dan non-hingga ( Infinity dan -Infinity ). Sayangnya spesifikasi JSON ( RFC 7159 ) TIDAK mengenali nilai-nilai ini (meskipun spesifikasi JavaScript melakukannya).

REST API yang dijelaskan di halaman ini memungkinkan objek JSON permintaan / respons memiliki nilai seperti itu. Ini menyiratkan bahwa permintaan seperti berikut ini valid:

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

Pengurai JSON yang memenuhi standar (ketat) akan menolak ini dengan kesalahan penguraian (karena token NaN dan Infinity bercampur dengan angka sebenarnya). Untuk menangani permintaan / tanggapan dengan benar dalam kode Anda, gunakan parser JSON yang mendukung token ini.

Token NaN , Infinity , -Infinity dikenali oleh proto3 , modul Python JSON, dan bahasa JavaScript.

Contoh

Kita dapat menggunakan model mainan half_plus_three untuk melihat REST API beraksi.

Mulai ModelServer dengan titik akhir REST API

Unduh model half_plus_three dari git repository :

$ 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 secara native di sistem Anda, ikuti petunjuk penyiapan untuk menginstal, dan mulai ModelServer dengan opsi --rest_api_port untuk mengekspor titik akhir API REST (ini tidak diperlukan saat 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

Di terminal lain, gunakan alat curl untuk melakukan panggilan REST API.

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

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