GRPC API के अलावा TensorFlow ModelServer भी Restful API का समर्थन करता है। यह पृष्ठ इन एपीआई एंडपॉइंट और उपयोग पर एक एंड-टू-एंड उदाहरण का वर्णन करता है।
अनुरोध और प्रतिक्रिया एक JSON ऑब्जेक्ट है। इस ऑब्जेक्ट की रचना अनुरोध प्रकार या क्रिया पर निर्भर करती है। विवरण के लिए नीचे एपीआई विशिष्ट अनुभाग देखें।
त्रुटि के मामले में, सभी API के साथ प्रतिक्रिया शरीर में एक JSON ऑब्जेक्ट वापस आ जाएगी error
कुंजी और मान के रूप में त्रुटि संदेश के रूप में:
{
"error": <error message string>
}
मॉडल स्थिति एपीआई
यह API ModelService.GetModelStatus
gRPC API को बारीकी से ModelService.GetModelStatus
करता है। यह ModelServer में एक मॉडल की स्थिति देता है।
यूआरएल
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]
सहित /versions/${VERSION}
या /labels/${LABEL}
वैकल्पिक है। यदि प्रतिक्रिया में सभी संस्करणों के लिए छोड़ी गई स्थिति वापस कर दी जाती है।
प्रतिक्रिया स्वरूप
सफल होने पर, GetModelStatusResponse
प्रोटोफ्यू का एक JSON प्रतिनिधित्व लौटाता है।
मॉडल मेटाडेटा एपीआई
यह एपीआई PredictionService.GetModelMetadata
जीआरपीसी एपीआई का बारीकी से अनुसरण करता है। यह ModelServer में एक मॉडल का मेटाडेटा लौटाता है।
यूआरएल
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]/metadata
सहित /versions/${VERSION}
या /labels/${LABEL}
वैकल्पिक है। यदि नवीनतम संस्करण के लिए मॉडल मेटाडेटा को छोड़ दिया जाता है, तो प्रतिक्रिया में वापस कर दिया जाता है।
प्रतिक्रिया स्वरूप
सफल होने पर, GetModelMetadataResponse
प्रोटोबॉफ़ का JSON प्रतिनिधित्व लौटाता है।
वर्गीकृत करें और एपीआई एपीआई
यह एपीआई PredictionService
जीआरपीसी एपीआई के Classify
और Regress
तरीकों का बारीकी से अनुसरण करता है।
यूआरएल
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:(classify|regress)
सहित /versions/${VERSION}
या /labels/${LABEL}
वैकल्पिक है। यदि छोड़ा गया है तो नवीनतम संस्करण का उपयोग किया जाता है।
अनुरोध प्रारूप
के लिए अनुरोध शरीर 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>
ऐसे मूल्यों की एक सूची है। द्विआधारी (बाइट्स की धारा) मान का प्रतिनिधित्व करने के तरीके के बारे में जानकारी के लिए नीचे द्विआधारी मूल्य अनुभाग एन्कोडिंग देखें। यह प्रारूप gRPC के ClassificationRequest
Request और RegressionRequest
प्रोटोस के समान है। दोनों संस्करण 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 PredictionService.Predict
gRPC API को बारीकी से फॉलो करता है।
यूआरएल
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
प्रोटो के समान है। इस प्रारूप का उपयोग करें यदि सभी नामित इनपुट टेनर्स में समान 0-वें आयाम हैं । यदि वे नहीं करते हैं, तो नीचे वर्णित स्तंभ प्रारूप का उपयोग करें।
पंक्ति प्रारूप में, इनपुट 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-वें आयाम (उपरोक्त उदाहरण में दो, के रूप में ऐसी घटनाएं सूची में दो वस्तुओं रहे हैं)। यदि आपने ऐसे इनपुट्स का नाम दिया है, जिनके अलग-अलग 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
जिनके नाम में प्रत्यय के रूप में _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 | संख्या | १, -१०, ० | JSON मान एक दशमलव संख्या होगी। |
DT_FLOAT, DT_DOUBLE | संख्या | 1.1, -10.0, 0, NaN , Infinity | JSON मान एक संख्या या विशेष टोकन मानों में से एक होगा - NaN , Infinity , और -Infinity । अधिक जानकारी के लिए JSON अनुरूपता देखें। घातांक संकेतन भी स्वीकार किया जाता है। |
बाइनरी मान एन्कोडिंग
JSON UTF-8 एन्कोडिंग का उपयोग करता है। यदि आपके पास इनपुट फ़ीचर या टेन्सर मान हैं जो बाइनरी होना आवश्यक है (जैसे कि इमेज बाइट्स), तो आपको बेस 64 को डेटा को एनकोड करना होगा और इसे JSON ऑब्जेक्ट में b64
रूप में निम्नानुसार कुंजी के रूप में 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 7159 ) इन मूल्यों को नहीं पहचानता (हालांकि जावास्क्रिप्ट विनिर्देश करता है)।
इस पृष्ठ पर वर्णित REST API, JSON ऑब्जेक्ट को ऐसे मान रखने के लिए अनुरोध / प्रतिक्रिया देता है। तात्पर्य यह है कि निम्नलिखित जैसे अनुरोध मान्य हैं:
{
"example": [
{
"sensor_readings": [ 1.0, -3.14, Nan, Infinity ]
}
]
}
ए (सख्त) मानकों के अनुरूप JSON पार्सर इसे पार्स त्रुटि ( NaN
और Infinity
टोकन के कारण वास्तविक संख्याओं के साथ मिश्रित) के साथ अस्वीकार कर देगा। अपने कोड में अनुरोधों / प्रतिक्रियाओं को सही ढंग से संभालने के लिए, एक JSON पार्सर का उपयोग करें जो इन टोकन का समर्थन करता है।
NaN
, Infinity
, -Infinity
टोकन द्वारा मान्यता प्राप्त हैं proto3 , अजगर JSON मॉड्यूल और जावास्क्रिप्ट भाषा।
उदाहरण
REST API को कार्रवाई में देखने के लिए हम खिलौना half_plus_three मॉडल का उपयोग कर सकते हैं।
REST API समापन बिंदु के साथ ModelServer प्रारंभ करें
Git रिपॉजिटरी से half_plus_three
मॉडल डाउनलोड करें:
$ mkdir -p /tmp/tfserving
$ cd /tmp/tfserving
$ git clone --depth=1 https://github.com/tensorflow/serving
हम मॉडलस्वर को चलाने के लिए डॉकर का उपयोग करेंगे। यदि आप अपने सिस्टम पर मूल रूप से ModelServer को स्थापित करना चाहते हैं, तो इसके बजाय स्थापित करने के लिए सेटअप निर्देशों का पालन करें, और REST API समापन बिंदु को निर्यात करने के लिए --rest_api_port
विकल्प के साथ --rest_api_port
प्रारंभ करें (डॉकर का उपयोग करते समय इसकी आवश्यकता नहीं है)।
$ 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 ...
ModelServer पर REST API कॉल करें
किसी भिन्न टर्मिनल में, REST API कॉल करने के लिए curl
टूल का उपयोग करें।
मॉडल की स्थिति निम्नानुसार प्राप्त करें:
$ 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)" }
$