API RESTful

בנוסף gRPC APIs TensorFlow ModelServer תומך גם APIs נינוחה. דף זה מתאר נקודות קצה API אלה וסוף-לקצה למשל על השימוש.

הבקשה והתגובה הם אובייקט JSON. ההרכב של אובייקט זה תלוי בסוג הבקשה או הפועל. עיין בסעיפים הספציפיים של ממשק API להלן לפרטים.

במקרה של שגיאה, כל APIs יחזור אובייקט JSON בגוף התגובה עם error כמפתח ואת הודעת השגיאה כערך:

{
  "error": <error message string>
}

API של סטטוס דגם

API זה מקרוב אחרי ModelService.GetModelStatus API gRPC. זה מחזיר את המצב של מודל ב-ModelServer.

כתובת אתר

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.

כתובת אתר

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

כולל /versions/${VERSION} או /labels/${LABEL} הוא אופציונלי. אם הושמט, המטא-נתונים של המודל עבור הגרסה העדכנית ביותר מוחזרים בתגובה.

פורמט תגובה

אם מוצלח, חוזר ייצוג JSON של GetModelMetadataResponse Protobuf.

סיווג ו-Regress API

API זה מקרוב אחרי Classify ו Regress שיטות PredictionService API gRPC.

כתובת אתר

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

כולל /versions/${VERSION} או /labels/${LABEL} הוא אופציונלי. אם הושמט, נעשה שימוש בגרסה העדכנית ביותר.

פורמט בקשה

גוף הבקשה classify ו regress APIs חייב להיות אובייקט 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 API יבחינו הדמיון של פורמט זה עם ClassificationResponse ו RegressionResponse Protos.

חיזוי API

API זה מקרוב אחרי PredictionService.Predict API gRPC.

כתובת אתר

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 פרוטו של API gRPC ואת CMLE לחזות API . השתמש בפורמט זה אם כל tensors קלט בשם יש את אותה 0-th מימד. אם לא, השתמש בפורמט העמודות המתואר בהמשך למטה.

ב פורמט השורות, תשומות ננעלות כדי מפתח מקרי בקשת 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-th ממד (שתי בדוגמה שלעיל, שכן ישנם שני אובייקטים ברשימת המקרים). אם ציינתם שמות שיש להם ממד 0 שונה, השתמש בפורמט העמודות המתואר להלן.

ציון טנסור קלט בפורמט עמודה.

השתמש בפורמט זה כדי לציין את טנסור הקלט שלך, אם לקלטים עם שם בודדים אין את אותו ממד 0 או שאתה רוצה ייצוג קומפקטי יותר. תבנית זו דומה inputs בתחום gRPC Predict בקשה.

במתכונת עמוד, תשומות ננעלות כדי מפתח התשומות בבקשה JSON.

את הערך של מפתח תשומות יכולים טנזור קלט יחיד או מפה של שם קלט כדי 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

ממשקי API של 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 (למשל אינטל או AMD), אז את הערך יומרו בשקט על ידי החומרה underyling כדי 1435774336 מאז 1435774380 לא יכול להיות מיוצג בדיוק בכמה נקודה צפה 32-bit. בדרך כלל, התשומות להגשה צריכות להיות באותה התפלגות כמו האימון, כך שבדרך כלל זה לא יהיה בעייתי מכיוון שאותן ההמרות התרחשו בזמן האימון. עם זאת, במקרה שדרוש דיוק מלא, הקפד להשתמש בסוג נתונים בסיסי במודל שלך שיכול להתמודד עם הדיוק הרצוי ו/או לשקול בדיקה בצד הלקוח.

קידוד ערכים בינאריים

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 ) אינו מזהה את הערכים הללו (אם כי המפרט JavaScript עושה).

REST API המתואר בדף זה מאפשר לאובייקטי JSON בקשה/תגובה לקבל ערכים כאלה. זה מרמז שבקשות כמו הבקשות הבאות תקפות:

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

A (קפדנים) בהתאם לתקנים הנדרש מנתח JSON ידחה זה עם שגיאה בניתוח (עקב NaN ו Infinity אסימונים מעורב עם מספרים אמיתיים). כדי לטפל בצורה נכונה בבקשות/תגובות בקוד שלך, השתמש במנתח JSON שתומך באסימונים אלה.

NaN , Infinity , -Infinity אסימונים מוכרים על ידי proto3 , Python JSON מודול ושפה JavaScript.

דוגמא

אנו יכולים להשתמש צעצוע half_plus_three מודל לראות APIs REST בפעולה.

הפעל את ModelServer עם נקודת הקצה REST API

הורד את half_plus_three מודל מן המאגר Git :

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

נשתמש ב-Docker כדי להפעיל את ModelServer. אם ברצונך להתקין ModelServer מקורי על המערכת שלך, בצע את הוראות ההתקנה להתקין במקום, ולהתחיל את ModelServer עם --rest_api_port אפשרות לנקודת הסיום API REST הייצוא (זו אינה נחוצה בעת שימוש דוקר).

$ 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 נגישה שם חתימה הלא ברירת מחדל יש לציין במפורש. כתובת אתר או גוף שגויים של בקשה מחזירה סטטוס שגיאת 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)" }
$