นอกจากนี้ในการ gRPC APIs TensorFlow ModelServer ยังสนับสนุนสงบ APIs หน้านี้จะอธิบายถึงปลายทาง 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
API Metadata ของโมเดล
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
จำแนกและถอยหลัง 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}
เป็นตัวเลือก หากละเว้นจะใช้เวอร์ชันล่าสุด
แบบคำขอ
ร่างกายคำขอสำหรับ classify
และ regress
APIs จะต้องเป็นวัตถุ 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 (ทั้งหมดหรือทศนิยม) สตริง JSON หรือวัตถุ JSON ที่แสดงถึงข้อมูลไบนารี (ดู Encoding ค่าไบนารี ส่วนรายละเอียดด้านล่าง) <list>
คือรายการของค่าดังกล่าว รูปแบบนี้จะคล้ายกับ gRPC ของ ClassificationRequest
และ RegressionRequest
Protos ทั้งสองรุ่นรับรายชื่อของ 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
ทำนาย API
API นี้อย่างใกล้ชิดต่อไปนี้ PredictionService.Predict
gRPC API
URL
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:predict
รวมทั้ง /versions/${VERSION}
หรือ /labels/${LABEL}
เป็นตัวเลือก หากละเว้นจะใช้เวอร์ชันล่าสุด
แบบคำขอ
ร่างกายร้องขอสำหรับการ predict
API จะต้องมีการจัดรูปแบบ 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
โปรโตของ gRPC API และ CMLE ทำนาย API ใช้รูปแบบนี้ถ้าทั้งหมด tensors การป้อนข้อมูลชื่อมีเดียวกันมิติ 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]] ]
}
เทนเซอร์จะแสดงออกมาอย่างเป็นธรรมชาติในสัญกรณ์ซ้อน เนื่องจากไม่จำเป็นต้องทำให้รายการแบนราบ
สำหรับอินพุตที่มีชื่อหลายรายการ แต่ละรายการควรเป็นอ็อบเจ็กต์ที่มีชื่ออินพุต/ค่าเทนเซอร์คู่ หนึ่งรายการสำหรับอินพุตที่มีชื่อแต่ละรายการ ตัวอย่างเช่น ต่อไปนี้คือคำขอที่มีสองอินสแตนซ์ โดยแต่ละรายการมีชุดของเมตริกซ์อินพุตที่มีชื่อสามชุด:
{
"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]]
}
]
}
หมายเหตุแต่ละชื่ออินพุท ( "แท็ก", "สัญญาณ", "เซ็นเซอร์") จะสันนิษฐานโดยปริยายมีเดียวกัน 0 TH มิติ (สองในตัวอย่างข้างต้นที่มีวัตถุสองในรายการอินสแตนซ์) หากคุณตั้งชื่ออินพุตที่มีมิติข้อมูล 0 ต่างกัน ให้ใช้รูปแบบคอลัมน์ที่อธิบายด้านล่าง
การระบุเทนเซอร์อินพุตในรูปแบบคอลัมน์
ใช้รูปแบบนี้เพื่อระบุเทนเซอร์อินพุตของคุณ หากอินพุตที่มีชื่อแต่ละรายการไม่มีมิติที่ 0 เท่ากัน หรือคุณต้องการการแสดงที่กะทัดรัดกว่านี้ รูปแบบนี้จะคล้ายกับ inputs
ด้านการ gRPC Predict
คำขอ
ในรูปแบบคอลัมน์ปัจจัยการผลิตที่มีการคีย์คีย์ปัจจัยการผลิตในคำขอ JSON
ค่าปัจจัยการผลิตที่สำคัญสามารถเมตริกซ์อินพุตเดียวหรือแผนที่ใส่ชื่อที่จะเทนเซอร์ (รายการที่ซ้อนกันในรูปแบบธรรมชาติของพวกเขา) อินพุตแต่ละรายการสามารถมีรูปร่างที่กำหนดเองได้ และไม่จำเป็นต้องแชร์/มิติที่ 0 เดียวกัน (หรือขนาดแบทช์) ตามที่กำหนดโดยรูปแบบแถวที่อธิบายข้างต้น
การแสดงคอลัมน์ของตัวอย่างก่อนหน้านี้มีดังนี้:
{
"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 หมายถึงไบต์ไบนารี (เช่นไบต์ภาพต่อเนื่องหรือ protobuf) เข้ารหัสเหล่านี้ใน Base64 ดู Encoding ค่าไบนารี สำหรับข้อมูลเพิ่มเติม |
DT_INT8, DT_UIT8, DT_INT16, DT_INT32, DT_UIT32, DT_INT64, DT_UIT64 | ตัวเลข | 1, -10, 0 | ค่า JSON จะเป็นเลขฐานสิบ |
DT_FLOAT, DT_DOUBLE | ตัวเลข | 1.1 -10.0, 0, NaN , Infinity | ค่า JSON จะเป็นตัวเลขหรือหนึ่งในค่าโทเค็นพิเศษ - NaN , Infinity และ -Infinity ดู JSON สอดคล้อง สำหรับข้อมูลเพิ่มเติม สัญกรณ์เลขชี้กำลังก็เป็นที่ยอมรับเช่นกัน |
ความแม่นยำของจุดลอยตัว
JSON มีประเภทข้อมูลตัวเลขเดียว ดังนั้นจึงเป็นไปได้ที่จะระบุค่าสำหรับอินพุตที่ส่งผลให้สูญเสียความแม่นยำ ตัวอย่างเช่นถ้าใส่ x
เป็น float
ชนิดข้อมูลและใส่ {"x": 1435774380}
ถูกส่งไปยังรูปแบบที่ทำงานบนฮาร์ดแวร์บนพื้นฐานของมาตรฐาน IEEE 754 จุดลอยมาตรฐาน (เช่น Intel หรือ AMD) แล้วค่าจะ จะแปลงเงียบฮาร์ดแวร์ underyling เพื่อ 1435774336
ตั้งแต่ 1435774380
ไม่สามารถแสดงว่าในจำนวนจุดลอยตัว 32 บิต โดยทั่วไป ข้อมูลป้อนเข้าในการแสดงโฆษณาควรเป็นการกระจายแบบเดียวกับการฝึกอบรม ดังนั้นโดยทั่วไปจะไม่เป็นปัญหาเนื่องจากเกิด Conversion เดียวกันในขณะฝึก อย่างไรก็ตาม ในกรณีที่ต้องการความแม่นยำสูงสุด อย่าลืมใช้ชนิดข้อมูลพื้นฐานในแบบจำลองของคุณที่สามารถจัดการกับความแม่นยำที่ต้องการ และ/หรือพิจารณาการตรวจสอบฝั่งไคลเอ็นต์
การเข้ารหัสค่าไบนารี
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
และไม่ จำกัด ( Infinity
และ -Infinity
) ค่า แต่น่าเสียดายที่สเปค JSON ( RFC 7,159 ) ไม่รู้จักค่าเหล่านี้ (แม้ว่าข้อกำหนด JavaScript ไม่)
REST API ที่อธิบายในหน้านี้อนุญาตให้คำขอ/ตอบสนองวัตถุ JSON มีค่าดังกล่าว ซึ่งหมายความว่าคำขอดังต่อไปนี้ถูกต้อง:
{
"example": [
{
"sensor_readings": [ 1.0, -3.14, Nan, Infinity ]
}
]
}
A (เข้มงวด) มาตรฐานตาม JSON parser จะปฏิเสธนี้กับข้อผิดพลาดในการแยกวิเคราะห์ (เนื่องจาก NaN
และ Infinity
โทเค็นผสมกับตัวเลขที่แท้จริง) หากต้องการจัดการคำขอ/การตอบกลับในโค้ดของคุณอย่างถูกต้อง ให้ใช้ตัวแยกวิเคราะห์ JSON ที่รองรับโทเค็นเหล่านี้
NaN
, Infinity
, -Infinity
ราชสกุลเป็นที่ยอมรับจาก proto3 , Python JSON โมดูลและภาษา JavaScript
ตัวอย่าง
เราสามารถใช้ของเล่น half_plus_three รุ่นเพื่อดู APIs REST ในการดำเนินการ
เริ่ม ModelServer ด้วย REST API endpoint
ดาวน์โหลด half_plus_three
โมเดลจาก เก็บคอมไพล์ :
$ mkdir -p /tmp/tfserving
$ cd /tmp/tfserving
$ git clone --depth=1 https://github.com/tensorflow/serving
เราจะใช้ Docker เพื่อเรียกใช้ ModelServer หากคุณต้องการติดตั้ง ModelServer กำเนิดในระบบของคุณทำตาม คำแนะนำการตั้งค่า การติดตั้งแทนและเริ่มต้น ModelServer กับ --rest_api_port
ตัวเลือกในการส่งออกปลายทาง REST API (นี้ไม่จำเป็นต้องเมื่อใช้หาง)
$ 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)" }
$