RESTful API

GRPC APIs ছাড়াও TensorFlow ModelServer এছাড়াও RESTful API সমর্থন করে। এই পৃষ্ঠাটি এই API এন্ডপয়েন্ট এবং ব্যবহারের একটি এন্ড-টু-এন্ড উদাহরণ বর্ণনা করে।

অনুরোধ এবং প্রতিক্রিয়া একটি JSON অবজেক্ট। এই বস্তুর গঠন অনুরোধের ধরন বা ক্রিয়াপদের উপর নির্ভর করে। বিস্তারিত জানার জন্য নীচের API নির্দিষ্ট বিভাগ দেখুন.

ত্রুটির ক্ষেত্রে, সমস্ত API গুলি কী হিসাবে error এবং মান হিসাবে ত্রুটি বার্তা সহ প্রতিক্রিয়া বডিতে একটি JSON অবজেক্ট ফিরিয়ে দেবে:

{
  "error": <error message string>
}

মডেল স্ট্যাটাস API

এই API ঘনিষ্ঠভাবে ModelService.GetModelStatus gRPC API অনুসরণ করে। এটি মডেল সার্ভারে একটি মডেলের স্থিতি প্রদান করে।

URL

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

/versions/${VERSION} বা /labels/${LABEL} সহ ঐচ্ছিক। সব সংস্করণের জন্য স্ট্যাটাস বাদ দেওয়া হলে উত্তরে ফেরত দেওয়া হয়।

প্রতিক্রিয়া বিন্যাস

সফল হলে, GetModelStatusResponse protobuf-এর একটি JSON উপস্থাপনা প্রদান করে।

মডেল মেটাডেটা API

এই API নিবিড়ভাবে PredictionService.GetModelMetadata gRPC API অনুসরণ করে। এটি মডেল সার্ভারে একটি মডেলের মেটাডেটা প্রদান করে।

URL

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

/versions/${VERSION} বা /labels/${LABEL} সহ ঐচ্ছিক। বাদ দিলে সর্বশেষ সংস্করণের জন্য মডেল মেটাডেটা প্রতিক্রিয়াতে ফেরত দেওয়া হয়।

প্রতিক্রিয়া বিন্যাস

সফল হলে, GetModelMetadataResponse protobuf-এর একটি JSON উপস্থাপনা প্রদান করে।

শ্রেণীবদ্ধ এবং প্রত্যাবর্তন API

এই API ঘনিষ্ঠভাবে PredictionService gRPC API-এর Classify এবং Regress পদ্ধতি অনুসরণ করে।

URL

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

/versions/${VERSION} বা /labels/${LABEL} সহ ঐচ্ছিক। বাদ দিলে সর্বশেষ সংস্করণ ব্যবহার করা হয়।

বিন্যাস অনুরোধ

classify এবং regress API-এর জন্য অনুরোধের বডি অবশ্যই একটি 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 প্রোটোর অনুরূপ। উভয় সংস্করণ 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 প্রোটোর সাথে এই ফর্ম্যাটের মিল লক্ষ্য করবেন।

অনুমান 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>
}

সারি বিন্যাসে ইনপুট টেনসর নির্দিষ্ট করা।

এই বিন্যাসটি gRPC API এর PredictRequest প্রোটো এবং CMLE পূর্বাভাস API এর অনুরূপ। এই বিন্যাসটি ব্যবহার করুন যদি সমস্ত নামযুক্ত ইনপুট টেনসরের 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-তম মাত্রা না থাকে বা আপনি আরও কমপ্যাক্ট উপস্থাপনা চান। এই বিন্যাসটি gRPC Predict অনুরোধের inputs ক্ষেত্রের অনুরূপ।

কলামার বিন্যাসে, ইনপুটগুলি 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 বাইনারি বাইট (যেমন সিরিয়ালাইজড ইমেজ বাইট বা প্রোটোবাফ) প্রতিনিধিত্ব করে, তাহলে বেস64 এ এনকোড করুন। আরও তথ্যের জন্য বাইনারি মান এনকোডিং দেখুন।
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} IEEE 754 ফ্লোটিং পয়েন্ট স্ট্যান্ডার্ড (যেমন ইন্টেল বা AMD) এর উপর ভিত্তি করে হার্ডওয়্যারে চলমান মডেলে পাঠানো হয়, তাহলে মান হবে আন্ডারলাইং হার্ডওয়্যার দ্বারা নীরবে 1435774336 তে রূপান্তর করা হবে যেহেতু 1435774380 একটি 32-বিট ফ্লোটিং পয়েন্ট সংখ্যাতে সঠিকভাবে উপস্থাপন করা যায় না। সাধারণত, পরিবেশনের জন্য ইনপুটগুলি প্রশিক্ষণের মতোই বিতরণ করা উচিত, তাই এটি সাধারণত সমস্যাযুক্ত হবে না কারণ প্রশিক্ষণের সময় একই রূপান্তরগুলি ঘটেছিল৷ যাইহোক, সম্পূর্ণ নির্ভুলতার প্রয়োজন হলে, আপনার মডেলে একটি অন্তর্নিহিত ডেটা টাইপ ব্যবহার করতে ভুলবেন না যা পছন্দসই নির্ভুলতা পরিচালনা করতে পারে এবং/অথবা ক্লায়েন্ট-সাইড চেকিং বিবেচনা করতে পারে।

বাইনারি মান এনকোডিং

JSON UTF-8 এনকোডিং ব্যবহার করে। আপনার যদি ইনপুট বৈশিষ্ট্য বা টেনসর মান থাকে যা বাইনারি হতে হবে (যেমন ইমেজ বাইট), আপনাকে অবশ্যই বেস 64 ডেটা এনকোড করতে হবে এবং এটিকে একটি 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 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 ভাষা দ্বারা স্বীকৃত।

উদাহরণ

আমরা REST API গুলিকে কার্যকর দেখতে খেলনা হাফ_প্লাস_থ্রি মডেল ব্যবহার করতে পারি।

REST API শেষ পয়েন্ট দিয়ে মডেল সার্ভার শুরু করুন

গিট রিপোজিটরি থেকে half_plus_three মডেল ডাউনলোড করুন:

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

আমরা মডেল সার্ভার চালানোর জন্য ডকার ব্যবহার করব। আপনি যদি আপনার সিস্টেমে নেটিভভাবে মডেল সার্ভার ইনস্টল করতে চান তবে পরিবর্তে ইনস্টল করার জন্য সেটআপ নির্দেশাবলী অনুসরণ করুন এবং REST API শেষ পয়েন্ট রপ্তানি করতে মডেল সার্ভারটি --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 ...

মডেল সার্ভারে 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)" }
$