בנוסף ל- API של gRPC TensorFlow ModelServer תומך גם ב- API של RESTful. דף זה מתאר נקודות קצה אלה של API ודוגמא מקצה לקצה על השימוש.
הבקשה והתגובה היא אובייקט JSON. הרכב אובייקט זה תלוי בסוג הבקשה או בפועל. לפרטים, עיין בסעיפים הספציפיים לממשק API.
במקרה של שגיאה, כל ממשקי ה- API יחזירו אובייקט JSON בגוף התגובה עם error
כמפתח ואת הודעת השגיאה כערך:
{
"error": <error message string>
}
ממשק API למצב דגם
ממשק 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 למטא נתונים
ממשק 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
protobuf.
API Classify and Regress
ממשק API זה עוקב מקרוב אחר השיטות Classify
and Regress
של PredictionService
gRPC API.
כתובת אתר
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:(classify|regress)
כולל /versions/${VERSION}
או /labels/${LABEL}
הוא אופציונלי. אם הושמט נעשה שימוש בגרסה האחרונה.
פורמט בקשה
גוף הבקשה לממשקי ה- API 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>
היא רשימה של ערכים כאלה. פורמט זה דומה לפרוטוס ClassificationRequest
ו- RegressionRequest
של gRPC. שתי הגרסאות מקבלות רשימת אובייקטים 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 יבחינו בדמיון של פורמט זה עם Protos ClassificationResponse
ו- RegressionResponse
.
חיזוי API
API זה עוקב מקרוב אחר ה- API של PredictionService.Predict
gRPC.
כתובת אתר
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
פרוטו של API gRPC ואת 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 ( שני בדוגמה לעיל, מכיוון שיש שני אובייקטים ברשימת המקרים ). אם ציינת תשומות בעלות ממד 0th שונה, השתמש בתבנית העמודה המתוארת להלן.
ציון טנזורי קלט בפורמט עמודות.
השתמש בתבנית זו כדי לציין את טנסורי הקלט שלך, אם תשומות בעלות שם אינן בעלות אותו ממד 0 או שאתה רוצה ייצוג קומפקטי יותר. תבנית זו דומה inputs
בתחום gRPC Predict
בקשה.
בפורמט העמודי, הקלטים מקודדים למפתח הקלט בבקשת JSON.
הערך עבור מקש הקלט יכול להיות טנסור קלט יחיד או מפה של שם קלט לטנסורים (המופיעים בצורתם המקוננת הטבעית). כל קלט יכול להיות בעל צורה שרירותית ואינו צריך לחלוק את אותו ממד 0 (aka גודל אצווה) כנדרש בפורמט השורה המתואר לעיל.
הייצוג העמודי של הדוגמה הקודמת הוא כדלקמן:
{
"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
ממשקי ה- 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 משתמש בקידוד UTF-8. אם יש לך תכונת קלט או ערכי טנסור שצריכים להיות בינאריים (כמו בתים של תמונה), עליך Base64 לקודד את הנתונים b64
באובייקט 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 עושה).
ממשק ה- API של REST המתואר בדף זה מאפשר לאובייקטים של 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 כדי לראות ממשקי API של 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
לייצוא נקודת קצה של 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 ...
בצע שיחות REST API ל- ModelServer
במסוף אחר, השתמש בכלי 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
זמינה בשם חתימה שאינו ברירת מחדל ויש לציין אותה במפורש. כתובת אתר או גוף שגוי של בקשה מחזירים סטטוס שגיאת 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)" }
$