بالإضافة إلى gRPC واجهات برمجة التطبيقات TensorFlow ModelServer كما يدعم واجهات برمجة التطبيقات مريحة. توضح هذه الصفحة هذه النهاية API ونهاية إلى نهاية مثال على الاستخدام.
الطلب والاستجابة عبارة عن كائن JSON. يعتمد تكوين هذا الكائن على نوع الطلب أو الفعل. راجع أقسام API المحددة أدناه للحصول على التفاصيل.
في حالة الخطأ، وجميع واجهات برمجة التطبيقات بإرجاع كائن JSON في الجسم استجابة مع error
كمفتاح ورسالة خطأ على أنها القيمة:
{
"error": <error message string>
}
نموذج حالة API
هذا API تتابع عن كثب ModelService.GetModelStatus
API gRPC. تقوم بإرجاع حالة النموذج في ModelServer.
URL
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]
بما في ذلك /versions/${VERSION}
أو /labels/${LABEL}
اختيارية. إذا تم حذف حالة جميع الإصدارات يتم إرجاعها في الاستجابة.
تنسيق الاستجابة
في حال نجاحها، بإرجاع تمثيل JSON من GetModelStatusResponse
protobuf.
نموذج Metadata API
هذا API تتابع عن كثب PredictionService.GetModelMetadata
API gRPC. تقوم بإرجاع البيانات الوصفية لنموذج في 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
يجب أن تكون واجهات برمجة التطبيقات كائن 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
الكائنات.
تنسيق الاستجابة
A 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
API gRPC.
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 . استخدام هذا الشكل إذا كانت كل التنسورات إدخال اسمه نفس 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-th أو كنت تريد تمثيلاً أكثر إحكاما. هذا شكل مشابه ل inputs
مجال gRPC Predict
الطلب.
في شكل عمودي، ومرتبطا المدخلات إلى مفتاح المدخلات في طلب JSON.
قيمة مفتاح المدخلات يمكن إما موتر مدخل واحد أو خريطة اسم الإدخال إلى التنسورات (المدرجة في المداخلات الطبيعي بهم). يمكن أن يكون لكل إدخال شكل تعسفي ولا يحتاج إلى مشاركة / نفس البعد 0-th (المعروف أيضًا باسم حجم الدُفعة) كما هو مطلوب بواسطة تنسيق الصف الموضح أعلاه.
التمثيل العمودي للمثال السابق كما يلي:
{
"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 التشفير المتعارف عليه في 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)، ثم سوف قيمة يتم تحويل بصمت من قبل الأجهزة 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 ( RFC 7159 ) لا تعترف بتلك القيم (على الرغم من أن مواصفات جافا سكريبت يفعل).
تسمح واجهة برمجة تطبيقات REST الموضحة في هذه الصفحة بامتلاك مثل هذه القيم لكائنات JSON للطلب / الاستجابة. هذا يعني أن الطلبات مثل الطلبات التالية صالحة:
{
"example": [
{
"sensor_readings": [ 1.0, -3.14, Nan, Infinity ]
}
]
}
وهناك معايير (صارمة) JSON متوافقة محلل رفض هذا مع خطأ تحليل (بسبب NaN
و Infinity
ورموز مختلطة مع الأرقام الفعلية). للتعامل مع الطلبات / الردود بشكل صحيح في التعليمات البرمجية الخاصة بك ، استخدم محلل JSON الذي يدعم هذه الرموز المميزة.
NaN
، Infinity
، -Infinity
يتم التعرف على الرموز التي proto3 ، بيثون JSON وحدة ولغة جافا سكريبت.
مثال
يمكننا استخدام لعبة half_plus_three نموذج لرؤية واجهات برمجة التطبيقات REST في العمل.
ابدأ ModelServer بنقطة نهاية REST API
تحميل 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
أداة لإجراء مكالمات API REST.
احصل على حالة النموذج على النحو التالي:
$ 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)" }
$