หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

RESTful API

นอกจาก gRPC API แล้ว TensorFlow ModelServer ยังรองรับ RESTful API ด้วย หน้านี้จะอธิบายถึงปลายทาง API เหล่านี้และแบบ end-to-end ตัวอย่าง การใช้งาน

คำขอและการตอบกลับเป็นออบเจ็กต์ JSON องค์ประกอบของวัตถุนี้ขึ้นอยู่กับประเภทคำขอหรือคำกริยา ดูส่วนเฉพาะของ API ด้านล่างสำหรับรายละเอียด

ในกรณีที่เกิดข้อผิดพลาด API ทั้งหมดจะส่งคืนออบเจ็กต์ JSON ในเนื้อหาการตอบกลับโดยมี error เป็นคีย์และข้อความแสดงข้อผิดพลาดเป็นค่า:

{
  "error": <error message string>
}

โมเดลสถานะ API

API นี้ติดตาม ModelService.GetModelStatus gRPC API อย่างใกล้ชิด ส่งคืนสถานะของโมเดลใน ModelServer

URL

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

รวมถึง /versions/${VERSION} หรือ /labels/${LABEL} เป็นทางเลือก หากไม่ระบุสถานะสำหรับทุกเวอร์ชันจะถูกส่งกลับในการตอบกลับ

รูปแบบการตอบกลับ

หากสำเร็จให้ส่งคืนการแสดง JSON ของ GetModelStatusResponse protobuf

Model Metadata API

API นี้ติดตาม PredictionService.GetModelMetadata gRPC API อย่างใกล้ชิด ส่งคืนข้อมูลเมตาของโมเดลใน ModelServer

URL

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

รวมถึง /versions/${VERSION} หรือ /labels/${LABEL} เป็นทางเลือก หากละเว้นข้อมูลเมตาของโมเดลสำหรับเวอร์ชันล่าสุดจะถูกส่งกลับในการตอบกลับ

รูปแบบการตอบกลับ

หากสำเร็จให้ส่งคืนการแสดง JSON ของ GetModelMetadataResponse protobuf

Classify และ Regress API

API นี้อย่างใกล้ชิดต่อไปนี้ Classify และ Regress วิธีการ PredictionService gRPC API

URL

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

รวมถึง /versions/${VERSION} หรือ /labels/${LABEL} เป็นทางเลือก หากไม่ระบุเวอร์ชันล่าสุดจะถูกใช้

รูปแบบคำขอ

เนื้อหาการร้องขอสำหรับ API ที่ classify และ regress ต้องเป็นออบเจ็กต์ JSON ที่จัดรูปแบบดังนี้:

{
  // 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> คือตัวเลข JSON (ทั้งหมดหรือทศนิยม) หรือสตริงและ <list> คือรายการของค่าดังกล่าว ดูส่วนการ เข้ารหัสค่าไบนารี ด้านล่างสำหรับรายละเอียดเกี่ยวกับวิธีการแทนค่าไบนารี (สตรีมของไบต์) รูปแบบนี้คล้ายกับโปรโตส ClassificationRequest และ RegressionRequest gRPC ทั้งสองเวอร์ชันยอมรับรายการวัตถุ Example

รูปแบบการตอบกลับ

คำขอ classify จะส่งคืนอ็อบเจ็กต์ JSON ในเนื้อหาการตอบสนองโดยจัดรูปแบบดังนี้:

{
  "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> คือสตริง (ซึ่งอาจเป็นสตริงว่าง "" หากโมเดลไม่มีป้ายกำกับที่เกี่ยวข้องกับคะแนน) <score> คือตัวเลขทศนิยม (ทศนิยม)

คำขอ regress ส่งคืนอ็อบเจ็กต์ JSON ในเนื้อหาการตอบสนองโดยจัดรูปแบบดังนี้:

{
  // One regression value for each example in the request in the same order.
  "result": [ <value1>, <value2>, <value3>, ...]
}

<value> คือเลขฐานสิบ

ผู้ใช้ gRPC API จะสังเกตเห็นความคล้ายคลึงกันของรูปแบบนี้กับ ClassificationResponse และ RegressionResponse protos

Predict API

API นี้ติดตาม PredictionService.Predict อย่างใกล้ชิด PredictionService.Predict gRPC API

URL

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

รวมถึง /versions/${VERSION} หรือ /labels/${LABEL} เป็นทางเลือก หากไม่ระบุเวอร์ชันล่าสุดจะถูกใช้

รูปแบบคำขอ

เนื้อหาคำขอสำหรับ API การ predict ต้องเป็นออบเจ็กต์ JSON ที่จัดรูปแบบดังนี้:

{
  // (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>
}

การระบุอินพุตเทนเซอร์ในรูปแบบแถว

รูปแบบนี้คล้ายกับ PredictRequest proto ของ gRPC API และ CMLE Predict API ใช้รูปแบบนี้หากเทนเซอร์อินพุตที่มีชื่อทั้งหมดมี มิติ 0-th เหมือนกัน หากไม่มีให้ใช้รูปแบบคอลัมน์ที่อธิบายไว้ด้านล่าง

ในรูปแบบแถวอินพุตจะถูกกำหนดคีย์ อินสแตนซ์ ในคำขอ JSON

เมื่อมีอินพุตที่มีชื่อเพียงรายการเดียวให้ระบุค่าของคีย์ อินสแตนซ์ เพื่อเป็นค่าของอินพุต:

{
  // List of 3 scalar tensors.
  "instances": [ "foo", "bar", "baz" ]
}

{
  // List of 2 tensors each of [1, 2] shape
  "instances": [ [[1, 2]], [[3, 4]] ]
}

Tensors จะแสดงโดยธรรมชาติในสัญกรณ์ที่ซ้อนกันเนื่องจากไม่จำเป็นต้องแบนรายการด้วยตนเอง

สำหรับอินพุตที่มีชื่อหลายรายการแต่ละรายการคาดว่าจะเป็นอ็อบเจ็กต์ที่มีคู่ชื่ออินพุต / ค่าเทนเซอร์หนึ่งคู่สำหรับอินพุตที่ระบุชื่อแต่ละรายการ ดังตัวอย่างต่อไปนี้เป็นคำขอที่มีสองอินสแตนซ์แต่ละชุดมีเทนเซอร์อินพุตที่มีชื่อสามชุด:

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

หมายเหตุแต่ละอินพุตที่ตั้งชื่อ ("tag", "signal", "sensor") จะถือว่าโดยปริยายมีมิติ 0-th เหมือนกัน ( สองตัว ในตัวอย่างข้างต้นเนื่องจากมีออบเจ็กต์ สอง รายการในรายการ อินสแตนซ์ ) หากคุณตั้งชื่ออินพุตที่มีมิติข้อมูล 0 ที่แตกต่างกันให้ใช้รูปแบบคอลัมน์ที่อธิบายด้านล่าง

การระบุอินพุตเทนเซอร์ในรูปแบบคอลัมน์

ใช้รูปแบบนี้เพื่อระบุอินพุตเทนเซอร์ของคุณหากอินพุตที่ระบุชื่อแต่ละรายการไม่มีมิติ 0-th เหมือนกันหรือคุณต้องการการแสดงที่กะทัดรัดกว่านี้ รูปแบบนี้คล้ายกับ inputs ของคำขอ Predict gRPC

ในรูปแบบคอลัมน์อินพุตจะถูกคีย์ให้กับคีย์ อินพุต ในคำขอ JSON

ค่าสำหรับคีย์ อินพุต อาจเป็นเทนเซอร์อินพุตเดียวหรือแมปของชื่ออินพุตเป็นเทนเซอร์ (แสดงรายการในรูปแบบซ้อนกันตามธรรมชาติ) อินพุตแต่ละรายการสามารถมีรูปร่างตามอำเภอใจและไม่จำเป็นต้องใช้มิติ 0-th ร่วมกัน (หรือขนาดแบทช์) ตามที่ต้องการโดยรูปแบบแถวที่อธิบายข้างต้น

การแสดงคอลัมน์ของตัวอย่างก่อนหน้ามีดังนี้:

{
 "inputs": {
   "tag": ["foo", "bar"],
   "signal": [[1, 2, 3, 4, 5], [3, 4, 1, 2, 5]],
   "sensor": [[[1, 2], [3, 4]], [[4, 5], [6, 8]]]
 }
}

หมายเหตุ อินพุต เป็นออบเจ็กต์ JSON และไม่ใช่รายการเหมือน อินสแตนซ์ (ใช้ในการแทนค่าแถว) นอกจากนี้อินพุตที่ระบุชื่อทั้งหมดจะถูกระบุร่วมกันซึ่งต่างจากการคลายการป้อนข้อมูลลงในแต่ละแถวที่ทำในรูปแบบแถวที่อธิบายไว้ก่อนหน้านี้ สิ่งนี้ทำให้การแสดงมีขนาดกะทัดรัด (แต่อาจอ่านได้น้อยกว่า)

รูปแบบการตอบกลับ

คำขอ predict ส่งคืนออบเจ็กต์ JSON ในเนื้อหาการตอบสนอง

คำขอใน รูปแบบแถว มี รูปแบบ การตอบสนองดังนี้:

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

หากผลลัพธ์ของแบบจำลองมีค่าเทนเซอร์ที่มีชื่อเพียงตัวเดียวเราจะละเว้นการแมปคีย์ชื่อและ predictions ไปยังรายการค่าสเกลาร์หรือรายการ หากแบบจำลองแสดงผลลัพธ์ที่มีชื่อหลายตัวเราจะแสดงรายการของวัตถุแทนซึ่งคล้ายกับคำขอในรูปแบบแถวที่กล่าวถึงข้างต้น

คำขอใน รูปแบบคอลัมน์ มี รูปแบบ การตอบสนองดังนี้:

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

หากเอาต์พุตของแบบจำลองมีเพียงตัวเดียวที่มีชื่อเทนเซอร์เราจะละเว้นชื่อและ outputs คีย์แมปไปยังรายการค่าสเกลาร์หรือรายการ หากแบบจำลองส่งเอาต์พุตหลายตัวที่มีชื่อเราจะส่งออกวัตถุแทน แต่ละคีย์ของอ็อบเจ็กต์นี้สอดคล้องกับเทนเซอร์เอาต์พุตที่ระบุชื่อ รูปแบบจะคล้ายกับคำขอในรูปแบบคอลัมน์ที่กล่าวข้างต้น

ผลลัพธ์ของค่าไบนารี

TensorFlow ไม่แยกความแตกต่างระหว่างสตริงที่ไม่ใช่ไบนารีและไบนารี ทั้งหมดเป็นประเภท DT_STRING ชื่อเทนเซอร์ที่มี _bytes เป็นส่วนต่อท้ายในชื่อถือว่ามีค่าไบนารี ค่าดังกล่าวถูกเข้ารหัสแตกต่างกันตามที่อธิบายไว้ในส่วนการ เข้ารหัสค่าไบนารี ด้านล่าง

การแมป JSON

RESTful API รองรับการเข้ารหัสมาตรฐานใน JSON ทำให้แชร์ข้อมูลระหว่างระบบได้ง่ายขึ้น สำหรับประเภทที่รองรับการเข้ารหัสจะอธิบายแบบแยกตามประเภทในตารางด้านล่าง ประเภทที่ไม่อยู่ในรายการด้านล่างนี้ส่อว่าไม่ได้รับการสนับสนุน

ประเภทข้อมูล TF ค่า JSON ตัวอย่าง JSON หมายเหตุ
DT_BOOL ถูกผิด ถูกผิด
DT_STRING เชือก "สวัสดีชาวโลก!" ถ้า DT_STRING แสดงถึงไบต์ไบต์ (เช่นไบต์ของอิมเมจแบบอนุกรมหรือโปรโตบัฟ) ให้เข้ารหัสสิ่งเหล่านี้ใน Base64 ดูการ เข้ารหัสค่าไบนารี สำหรับข้อมูลเพิ่มเติม
DT_INT8, DT_UINT8, DT_INT16, DT_INT32, DT_UINT32, DT_INT64, DT_UINT64 จำนวน 1, -10, 0 ค่า JSON จะเป็นเลขฐานสิบ
DT_FLOAT, DT_DOUBLE จำนวน 1.1, -10.0, 0, NaN , Infinity ค่า JSON จะเป็นตัวเลขหรือหนึ่งในค่าโทเค็นพิเศษ - NaN , Infinity และ -Infinity ดูความ สอดคล้องของ JSON สำหรับข้อมูลเพิ่มเติม นอกจากนี้ยังยอมรับสัญกรณ์เลขชี้กำลัง

การเข้ารหัสค่าไบนารี

JSON ใช้การเข้ารหัส UTF-8 หากคุณมีคุณสมบัติการป้อนข้อมูลหรือค่าเทนเซอร์ที่จำเป็นต้องเป็นไบนารี (เช่นไบต์รูปภาพ) คุณ ต้อง Base64 เข้ารหัสข้อมูลและห่อหุ้มไว้ในออบเจ็กต์ JSON ที่มี b64 เป็นคีย์ดังนี้:

{ "b64": <base64 encoded string> }

คุณสามารถระบุอ็อบเจ็กต์นี้เป็นค่าสำหรับคุณสมบัติอินพุตหรือเทนเซอร์ รูปแบบเดียวกันนี้ใช้ในการเข้ารหัสการตอบสนองของเอาต์พุตด้วย

คำขอการจัดประเภทที่มี image (ข้อมูลไบนารี) และคุณสมบัติ caption แสดงอยู่ด้านล่าง:

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

ความสอดคล้องของ JSON

ค่าคุณลักษณะหรือค่าเทนเซอร์จำนวนมากเป็นตัวเลขทศนิยม นอกเหนือจากค่า จำกัด (เช่น 3.14, 1.0 เป็นต้น) ค่าเหล่านี้สามารถมีค่า NaN และ non-finite ( Infinity และ -Infinity ) ได้ น่าเสียดายที่ข้อกำหนด JSON ( RFC 7159 ) ไม่ รู้จักค่าเหล่านี้ (แม้ว่าข้อกำหนดของ JavaScript จะทำ)

REST API ที่อธิบายไว้ในเพจนี้อนุญาตให้อ็อบเจ็กต์ JSON ที่ร้องขอ / ตอบกลับมีค่าดังกล่าว นี่หมายความว่าคำขอดังต่อไปนี้ถูกต้อง:

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

โปรแกรมแยกวิเคราะห์ JSON ที่เป็นไปตามมาตรฐาน (เข้มงวด) จะปฏิเสธสิ่งนี้ด้วยข้อผิดพลาดในการแยกวิเคราะห์ (เนื่องจากโทเค็น NaN และ Infinity ผสมกับตัวเลขจริง) ในการจัดการคำขอ / การตอบกลับในโค้ดของคุณอย่างถูกต้องให้ใช้ตัวแยกวิเคราะห์ JSON ที่รองรับโทเค็นเหล่านี้

NaN , Infinity , -Infinity โทเค็นได้รับการยอมรับโดย proto3 , โมดูล Python JSON และภาษา JavaScript

ตัวอย่าง

เราสามารถใช้ toy half_plus_three model เพื่อดู REST APIs ในการทำงาน

เริ่ม ModelServer ด้วยปลายทาง REST API

ดาวน์โหลดโมเดล half_plus_three จากที่ เก็บ git :

$ mkdir -p /tmp/tfserving
$ cd /tmp/tfserving
$ git clone --depth=1 https://github.com/tensorflow/serving

เราจะใช้ Docker เพื่อเรียกใช้ ModelServer หากคุณต้องการติดตั้ง ModelServer ในระบบของคุณให้ทำตาม คำแนะนำการตั้งค่า เพื่อติดตั้งแทนและเริ่มตัวเลือก --rest_api_port ด้วย --rest_api_port เพื่อส่งออกปลายทาง REST API (ไม่จำเป็นเมื่อใช้ 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 ...

ทำการเรียก REST API ไปยัง ModelServer

ในเทอร์มินัลอื่นให้ใช้เครื่องมือ curl เพื่อทำการเรียก REST API

รับสถานะของโมเดลดังนี้:

$ 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 จะมีลักษณะดังนี้:

$ 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]
}

และการโทร regress มีลักษณะดังนี้:

$ 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]
}

หมายเหตุการ regress มีอยู่ในชื่อลายเซ็นที่ไม่ใช่ค่าเริ่มต้นและต้องระบุไว้อย่างชัดเจน URL คำขอหรือเนื้อหาที่ไม่ถูกต้องส่งคืนสถานะข้อผิดพลาด 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)" }
$