به انجمن SIG TFX-Addons بپیوندید و به پیشرفت TFX کمک کنید!
این صفحه به‌وسیله ‏Cloud Translation API‏ ترجمه شده است.
Switch to English

RESTful API

علاوه بر API های gRPC ، TensorFlow ModelServer همچنین از API های RESTful پشتیبانی می کند. این صفحه این نقاط انتهایی API و یک مثال پایان به پایان در مورد استفاده را توصیف می کند.

درخواست و پاسخ یک شی J JSON است. ترکیب این شی به نوع درخواست یا فعل بستگی دارد. برای جزئیات به بخشهای ویژه API در زیر مراجعه کنید.

در صورت خطا ، تمام API ها یک شی J JSON را در متن پاسخ با error به عنوان کلید و پیام خطا را به عنوان مقدار باز می گردانند:

{
  "error": <error message string>
}

API وضعیت مدل

این API از نزدیک ModelService.GetModelStatus gRPC API را دنبال می کند. وضعیت یک مدل را در ModelServer برمی گرداند.

آدرس اینترنتی

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

شامل /versions/${VERSION} یا /labels/${LABEL} اختیاری است. اگر وضعیت حذف شده برای همه نسخه ها در پاسخ برگردانده شود.

قالب پاسخ

در صورت موفقیت ، نمایندگی JSON از GetModelStatusResponse برمی گرداند.

Model Metadata API

این API از نزدیک PredictionService.GetModelMetadata gRPC API را دنبال می کند. فراداده یک مدل را در ModelServer برمی گرداند.

آدرس اینترنتی

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

شامل /versions/${VERSION} یا /labels/${LABEL} اختیاری است. در صورت حذف ، فراداده مدل برای آخرین نسخه در پاسخ بازگردانده می شود.

قالب پاسخ

در صورت موفقیت ، نمایندگی JSON از GetModelMetadataResponse برمی گرداند.

Classified and Regress API

این API از نزدیک روشهای Classify و Regress PredictionService gRPC API را دنبال می کند.

آدرس اینترنتی

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> لیستی از این مقادیر است. این قالب مشابه نمونه های اولیه ClassificationRequest و RegressionRequest gRPC است. هر دو نسخه لیستی از اشیا Example را می پذیرند.

قالب پاسخ

درخواست classify یک شی J 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 یک شی J 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 را دنبال می کند.

آدرس اینترنتی

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 پیش بینی 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]] ]
}

سنسورها به طور طبیعی در نماد تو در تو بیان می شوند زیرا نیازی به تسطیح دستی لیست نیست.

برای چندین ورودی نامگذاری شده ، انتظار می رود که هر مورد یک شی containing حاوی جفت مقدار نام ورودی / تنسور باشد ، یکی برای هر ورودی نامگذاری شده. به عنوان مثال ، در زیر یک درخواست با دو نمونه وجود دارد که هرکدام از آنها دارای مجموعه ای از سه سنسور ورودی هستند:

{
 "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 درخواست Predict gRPC است.

در فرمت ستونی، به ورودی ها به کلید ورودی در درخواست JSON کوک شده است.

مقدار کلید ورودی می تواند یک تنسور ورودی منفرد یا یک نقشه از نام ورودی به سنسورها باشد (در فرم تو در تو قرار گرفته است). هر ورودی می تواند شکل دلخواهی داشته باشد و نیازی نیست که همان اندازه 0/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]]]
 }
}

توجه داشته باشید ، ورودی ها یک شی J JSON است و لیستی مانند نمونه ها نیست (که در نمایش سطر استفاده می شود). همچنین ، در مقایسه با لغو باز کردن آنها در سطرهای منفرد که در قالب ردیف قبلاً شرح داده شده ، ، تمام ورودی های نام برده با هم مشخص شده اند. این باعث می شود نمایندگی جمع و جور باشد (اما شاید کمتر قابل خواندن باشد).

قالب پاسخ

درخواست predict یک شی J JSON را در متن پاسخ برمی گرداند.

یک درخواست در قالب ردیف ، پاسخ را به صورت زیر قالب می کند:

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

اگر خروجی مدل فقط شامل یک تنسور نامی باشد ، ما نقشه های کلید نام و predictions به لیستی از مقیاس های مقیاس یا لیست حذف می کنیم. اگر مدل چندین تنسور نامگذاری شده را تولید کند ، در عوض لیستی از اشیا را خارج می کنیم ، مشابه درخواست در قالب سطر که در بالا ذکر شد.

یک درخواست به صورت ستونی پاسخ را به صورت زیر قالب می کند:

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

اگر خروجی از مدل شامل تنها یک تانسور نام، ما را حذف نام و outputs کلیدی نقشه ها را به یک لیست از اسکالر یا لیست ارزش. اگر مدل چندین تنسور نامگذاری شده را تولید کند ، در عوض یک شی object را خارج می کنیم. هر کلید این شی مربوط به یک سنسور خروجی نامگذاری شده است. قالب مشابه درخواست در قالب ستون ذکر شده در بالا است.

خروجی مقادیر باینری

TensorFlow بین رشته های غیر باینری و باینری فرقی نمی گذارد. همه از نوع DT_STRING هستند. _bytes به نام که دارای _bytes به عنوان پسوند در نام خود هستند دارای مقادیر باینری هستند. این مقادیر به صورتی که در قسمت مقادیر دودویی کدگذاری در زیر توضیح داده شده است ، به صورت متفاوتی رمزگذاری می شوند .

نقشه برداری JSON

RESTful API از رمزگذاری متعارف در JSON پشتیبانی می کند ، به اشتراک گذاری داده ها بین سیستم ها آسان تر است. برای انواع پشتیبانی شده ، رمزگذاری ها به صورت نوع به نوع در جدول زیر توصیف شده است. ضمنی است که انواع بدون لیست ذکر شده در زیر پشتیبانی نمی شوند.

نوع داده TF ارزش JSON مثال JSON یادداشت
DT_BOOL درست غلط درست غلط
DT_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} به مدل در حال اجرا بر روی سخت افزار بر اساس استاندارد نقطه شناور IEEE 754 (به عنوان مثال Intel یا AMD) ارسال شود ، در این صورت مقدار از طریق 1435774336 به 1435774336 توسط سخت افزار 1435774336 1435774380 شود ، نمی توان دقیقاً در یک عدد شناور 32 بیتی نشان داد. به طور معمول ، ورودی های خدمت باید همان توزیع آموزش باشد ، بنابراین این امر معمولاً مشکلی نخواهد داشت زیرا در زمان آموزش ، همان تبدیل ها اتفاق افتاده است. با این حال ، در صورت نیاز به دقت کامل ، حتماً از یک نوع داده اساسی در مدل خود استفاده کنید که بتواند دقت مورد نظر را کنترل کند و یا بررسی سمت مشتری را در نظر بگیرید.

رمزگذاری مقادیر باینری

JSON از رمزگذاری UTF-8 استفاده می کند. اگر ویژگی ورودی یا مقادیر b64 دارید که باید باینری باشد (مانند بایت تصویر) ، باید 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 7159 ) این مقادیر را تشخیص نمی دهد (اگرچه مشخصات جاوا اسکریپت تشخیص می دهد).

REST API توصیف شده در این صفحه به درخواستها / پاسخهای اشیا J JSON اجازه می دهد چنین مقادیری را داشته باشند. این بدان معنی است که درخواست هایی مانند درخواست زیر معتبر هستند:

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

تجزیه کننده استاندارد (دقیق) JSON با خطای تجزیه (به دلیل نشانه های NaN و Infinity با اعداد واقعی مخلوط شده) این مورد را رد می کند. برای رسیدگی صحیح به درخواست ها / پاسخ ها در کد خود ، از تجزیه کننده JSON استفاده کنید که از این نشانه ها پشتیبانی می کند.

NaN ، Infinity ، -Infinity توکن ها توسط رسمیت شناخته proto3 ، پایتون JSON ماژول و زبان جاوا اسکریپت.

مثال

برای دیدن REST API ها در عمل می توانیم از مدل half_plus_three اسباب بازی استفاده کنیم.

ModelServer را با نقطه پایانی REST API شروع کنید

مدل half_plus_three را از مخزن git half_plus_three کنید :

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

ما برای اجرای ModelServer از داکر استفاده خواهیم کرد. اگر می خواهید ModelServer را بطور طبیعی بر روی سیستم خود نصب کنید ، دستورالعملهای نصب را برای نصب دنبال کنید و گزینه --rest_api_port with --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 ...

با 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)" }
$