रेस्टफुल एपीआई

संग्रह की मदद से व्यवस्थित रहें अपनी प्राथमिकताओं के आधार पर, कॉन्टेंट को सेव करें और कैटगरी में बांटें.

के अलावा gRPC एपीआई TensorFlow ModelServer भी RESTful एपीआई का समर्थन करता है। यह पृष्ठ इन API अंतिमबिंदुओं और एंड-टू-एंड का वर्णन करता है उदाहरण के उपयोग पर।

अनुरोध और प्रतिक्रिया एक JSON ऑब्जेक्ट है। इस वस्तु की संरचना अनुरोध प्रकार या क्रिया पर निर्भर करती है। विवरण के लिए नीचे दिए गए API विशिष्ट अनुभाग देखें।

त्रुटि के मामले में, सभी API के साथ प्रतिक्रिया शरीर में एक JSON ऑब्जेक्ट वापस आ जाएगी error कुंजी और मान के रूप में त्रुटि संदेश के रूप में:

{
  "error": <error message string>
}

मॉडल स्थिति API

यह API बारीकी से इस प्रकार ModelService.GetModelStatus gRPC एपीआई। यह ModelServer में एक मॉडल की स्थिति लौटाता है।

यूआरएल

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

भी शामिल है /versions/${VERSION} या /labels/${LABEL} वैकल्पिक है। यदि सभी संस्करणों के लिए छोड़ी गई स्थिति प्रतिक्रिया में वापस कर दी जाती है।

प्रतिक्रिया प्रारूप

यदि सफल, की एक JSON प्रतिनिधित्व रिटर्न GetModelStatusResponse Protobuf।

मॉडल मेटाडेटा एपीआई

यह API बारीकी से इस प्रकार PredictionService.GetModelMetadata gRPC एपीआई। यह ModelServer में किसी मॉडल का मेटाडेटा लौटाता है।

यूआरएल

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

भी शामिल है /versions/${VERSION} या /labels/${LABEL} वैकल्पिक है। यदि छोड़ा जाता है तो नवीनतम संस्करण के लिए मॉडल मेटाडेटा प्रतिक्रिया में वापस कर दिया जाता है।

प्रतिक्रिया प्रारूप

यदि सफल, की एक JSON प्रतिनिधित्व रिटर्न GetModelMetadataResponse Protobuf।

वर्गीकृत और प्रतिगमन एपीआई

यह API बारीकी से इस प्रकार Classify और Regress के तरीकों PredictionService gRPC एपीआई।

यूआरएल

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 संख्या (पूरे या दशमलव), JSON स्ट्रिंग, या एक JSON ऑब्जेक्ट (देखें कि बाइनरी डेटा का प्रतिनिधित्व करता है एन्कोडिंग द्विआधारी मूल्यों विवरण नीचे के अनुभाग)। <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 एपीआई के उपयोगकर्ताओं के साथ इस प्रारूप की समानता देखेंगे ClassificationResponse और RegressionResponse protos।

भविष्यवाणी एपीआई

यह API बारीकी से इस प्रकार PredictionService.Predict gRPC एपीआई।

यूआरएल

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

भी शामिल है /versions/${VERSION} या /labels/${LABEL} वैकल्पिक है। यदि छोड़ा गया है तो नवीनतम संस्करण का उपयोग किया जाता है।

अनुरोध प्रारूप

के लिए अनुरोध शरीर 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 gRPC एपीआई के आद्य और CMLE एपीआई का अनुमान है । इस प्रारूप का उपयोग करता है, तो सभी नामित इनपुट tensors ही 0-वें आयाम है। यदि वे नहीं करते हैं, तो बाद में नीचे वर्णित कॉलमर प्रारूप का उपयोग करें।

पंक्ति प्रारूप में, आदानों JSON अनुरोध में उदाहरणों कुंजी को keyed रहे हैं।

जब केवल एक का नाम इनपुट नहीं है, उदाहरणों इनपुट के मूल्य होने के लिए कुंजी का मान निर्दिष्ट करें:

{
  // 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 अनुरोध में आदानों कुंजी को keyed रहे हैं।

आदानों कुंजी के लिए मूल्य सकते हैं या तो एक एकल इनपुट टेन्सर या tensors के लिए इनपुट नाम का एक नक्शा (उनके प्राकृतिक नेस्टेड रूप में सूचीबद्ध)। प्रत्येक इनपुट में मनमाना आकार हो सकता है और ऊपर वर्णित पंक्ति प्रारूप द्वारा आवश्यक / समान 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 प्रकार। नामांकित tensors है _bytes उनके नाम में एक प्रत्यय के रूप में द्विआधारी मूल्यों के लिए माना जाता है। में वर्णित के रूप में इस तरह के मूल्यों को अलग ढंग से इनकोड एन्कोडिंग द्विआधारी मूल्यों अनुभाग देखें।

JSON मैपिंग

RESTful API JSON में एक कैननिकल एन्कोडिंग का समर्थन करते हैं, जिससे सिस्टम के बीच डेटा साझा करना आसान हो जाता है। समर्थित प्रकारों के लिए, एन्कोडिंग को नीचे दी गई तालिका में प्रकार-दर-प्रकार के आधार पर वर्णित किया गया है। नीचे सूचीबद्ध नहीं किए गए प्रकारों को असमर्थित माना जाता है।

टीएफ डेटा प्रकार JSON मान JSON उदाहरण टिप्पणियाँ
डीटी_BOOL सही गलत सही गलत
डीटी_STRING डोरी "नमस्ते दुनिया!" यदि DT_STRING द्विआधारी बाइट्स (जैसे धारावाहिक छवि बाइट या Protobuf), एनकोड 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 में एकल संख्या डेटा प्रकार है। इस प्रकार एक इनपुट के लिए एक मूल्य प्रदान करना संभव है जिसके परिणामस्वरूप परिशुद्धता का नुकसान होता है। उदाहरण के लिए, यदि इनपुट x एक है float डेटा प्रकार, और इनपुट {"x": 1435774380} आईईईई 754 चल बिन्दु मानक (जैसे इंटेल या एएमडी), तो मूल्य पर आधारित हार्डवेयर पर चल रहे मॉडल के लिए भेज दिया जाता है चुपचाप करने के लिए underyling हार्डवेयर द्वारा परिवर्तित किया जा 1435774336 के बाद से 1435774380 वास्तव में एक 32-बिट चल बिन्दु संख्या में नहीं दर्शाया जा सकता। आम तौर पर, सेवा देने के लिए इनपुट प्रशिक्षण के समान वितरण होना चाहिए, इसलिए यह आम तौर पर समस्याग्रस्त नहीं होगा क्योंकि प्रशिक्षण के समय वही रूपांतरण हुए थे। हालांकि, यदि पूर्ण सटीकता की आवश्यकता है, तो अपने मॉडल में एक अंतर्निहित डेटा प्रकार का उपयोग करना सुनिश्चित करें जो वांछित सटीकता को संभाल सके और/या क्लाइंट-साइड जांच पर विचार कर सके।

एन्कोडिंग बाइनरी मान

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 विनिर्देश ( आर एफ सी 7159 ) इन मूल्यों को नहीं पहचानता है (हालांकि जावास्क्रिप्ट विनिर्देश करता है)।

इस पृष्ठ पर वर्णित आरईएसटी एपीआई अनुरोध/प्रतिक्रिया JSON ऑब्जेक्ट्स को ऐसे मान रखने की अनुमति देता है। इसका तात्पर्य है कि निम्नलिखित जैसे अनुरोध मान्य हैं:

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

ए (सख्त) मानकों के अनुरूप JSON पार्सर (की वजह से एक पार्स त्रुटि के साथ इस को अस्वीकार कर देंगे NaN और Infinity वास्तविक संख्या के साथ मिश्रित टोकन)। अपने कोड में अनुरोधों/प्रतिक्रियाओं को सही ढंग से संभालने के लिए, एक JSON पार्सर का उपयोग करें जो इन टोकन का समर्थन करता है।

NaN , Infinity , -Infinity टोकन द्वारा मान्यता प्राप्त हैं proto3 , अजगर JSON मॉड्यूल और जावास्क्रिप्ट भाषा।

उदाहरण

हम खिलौना का उपयोग कर सकते half_plus_three कार्रवाई में बाकी एपीआई देखने के लिए मॉडल।

REST API समापन बिंदु के साथ ModelServer प्रारंभ करें

डाउनलोड half_plus_three से मॉडल Git भंडार :

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

हम ModelServer को चलाने के लिए Docker का उपयोग करेंगे। आप अपने सिस्टम पर देशी रूप 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 ...

ModelServer को REST API कॉल करें

एक अलग टर्मिनल में, का उपयोग 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)" }
$