מדריך זה מראה לך כיצד להשתמש ברכיבי TensorFlow Serving כדי לבנות את TensorFlow ModelServer הסטנדרטי שמגלה באופן דינמי ומשרת גרסאות חדשות של מודל TensorFlow מאומן. אם אתה רק רוצה להשתמש בשרת הסטנדרטי לשרת המודלים שלך, לראות TensorFlow הגשת הדרכה בסיסית .
מדריך זה משתמש במודל הפשוט של Softmax Regression שהוצג במדריך TensorFlow לסיווג תמונה בכתב יד (נתוני MNIST). אם אתה לא יודע מה TensorFlow או MNIST הוא, לראות את MNIST עבור ML למתחילים הדרכה.
הקוד של הדרכה זו מורכב משני חלקים:
פייתון קובץ mnist_saved_model.py כי רכבות היצוא מספר גרסאות של המודל.
הקובץ ++ C main.cc המהווה את ModelServer TensorFlow התקן שמגלה מיוצאים חדש מודלים ומפעיל gRPC שירות עבור המשרתים אותם.
מדריך זה מוביל את המשימות הבאות:
- אימון ויצוא של מודל TensorFlow.
- ניהול מודל גרסאות עם הגשה TensorFlow
ServerCore
. - ומינון Configure באמצעות
SavedModelBundleSourceAdapterConfig
. - מגיש בקשה עם הגשת TensorFlow
ServerCore
. - הפעל ובדוק את השירות.
לפני תחילת עבודה, ראשון להתקין דוקר
אימון וייצוא מודל TensorFlow
ראשית, אם עדיין לא עשית זאת, שכפל את המאגר הזה למחשב המקומי שלך:
git clone https://github.com/tensorflow/serving.git
cd serving
נקה את ספריית הייצוא אם היא כבר קיימת:
rm -rf /tmp/models
התאמן (עם 100 איטרציות) וייצא את הגרסה הראשונה של הדגם:
tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
--training_iteration=100 --model_version=1 /tmp/mnist
רכב (עם 2000 איטרציות) וייצא את הגרסה השנייה של הדגם:
tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
--training_iteration=2000 --model_version=2 /tmp/mnist
כפי שניתן לראות ב mnist_saved_model.py
, ההכשרה ויצוא נעשית באותו אופן הוא נמצא TensorFlow הגשת הדרכה בסיסית . למטרות הדגמה, אתה מחייג בכוונה את איטרציות האימון לריצה הראשונה ומייצא אותו כ-v1, תוך כדי אימון רגיל לריצה השנייה ומייצא אותו כ-v2 לאותה ספריית אב -- כפי שאנו מצפים שהאחרון ישיג. דיוק סיווג טוב יותר בגלל אימון אינטנסיבי יותר. אתה צריך לראות אימונים נתונים עבור כל מחזור אימונים שלך /tmp/mnist
בספרייה:
$ ls /tmp/mnist
1 2
ServerCore
כעת דמיינו לעצמכם את v1 ו-v2 של המודל נוצרים באופן דינמי בזמן ריצה, כאשר אלגוריתמים חדשים מתנסים, או כאשר המודל מאומן עם מערך נתונים חדש. בסביבת ייצור, ייתכן שתרצה לבנות שרת שיכול לתמוך בהשקה הדרגתית, שבה ניתן לגלות, לטעון, להתנסות, לנטר או להחזיר את v2 בזמן הגשת v1. לחלופין, ייתכן שתרצה להרוס את v1 לפני העלאת v2. TensorFlow Serving תומך בשתי האפשרויות -- בעוד שאחת טובה לשמירה על זמינות במהלך המעבר, השנייה טובה למזעור השימוש במשאבים (למשל זיכרון RAM).
TensorFlow הגשת Manager
עושה בדיוק את זה. הוא מטפל במחזור החיים המלא של דגמי TensorFlow כולל טעינה, הגשה ופריקה שלהם וכן מעברי גרסאות. במדריך זה, תוכל לבנות את השרת על גבי TensorFlow הגשת ServerCore
, אשר פנימי כורך AspiredVersionsManager
.
int main(int argc, char** argv) {
...
ServerCore::Options options;
options.model_server_config = model_server_config;
options.servable_state_monitor_creator = &CreateServableStateMonitor;
options.custom_model_config_loader = &LoadCustomModelConfig;
::google::protobuf::Any source_adapter_config;
SavedModelBundleSourceAdapterConfig
saved_model_bundle_source_adapter_config;
source_adapter_config.PackFrom(saved_model_bundle_source_adapter_config);
(*(*options.platform_config_map.mutable_platform_configs())
[kTensorFlowModelPlatform].mutable_source_adapter_config()) =
source_adapter_config;
std::unique_ptr<ServerCore> core;
TF_CHECK_OK(ServerCore::Create(options, &core));
RunServer(port, std::move(core));
return 0;
}
ServerCore::Create()
לוקח ServerCore :: פרמטר אפשרויות. להלן מספר אפשרויות נפוצות:
-
ModelServerConfig
המציין דגמים להיות טעון. מודלים מוכרזים או באמצעותmodel_config_list
, אשר מצהיר רשימה סטטית של דגמים, או באמצעותcustom_model_config
, המגדיר בצורה המנהג להכריז על רשימת הדגמים שעשויים להתעדכן בזמן ריצה. -
PlatformConfigMap
הממפה משמו של הפלטפורמה (כגוןtensorflow
) אלPlatformConfig
, אשר משמש ליצירתSourceAdapter
.SourceAdapter
מסתגלStoragePath
(הנתיב בו גרסת מודל מתגלה) למדלLoader
(המון גרסת מודל מנתיב אחסון ומספק ממשקי המעבר למדינה אליManager
). אםPlatformConfig
מכילSavedModelBundleSourceAdapterConfig
, ASavedModelBundleSourceAdapter
תיווצר, אשר נסביר בהמשך.
SavedModelBundle
הוא מרכיב מרכזי של הצגת TensorFlow. הוא מייצג מודל TensorFlow נטען מ נתיב נתון ומספק אותו Session::Run
הממשק כמו TensorFlow כדי היקש ריצה. SavedModelBundleSourceAdapter
נתיב האחסון מסתגל Loader<SavedModelBundle>
כך בחי מודל יכולים להיות מנוהלים על ידי Manager
. שימו לב SavedModelBundle
הוא ממשיכו של עוד בשימוש SessionBundle
. אנו מעודדים את המשתמשים להשתמש SavedModelBundle
כמו תמיכה SessionBundle
יוסר בקרוב.
עם כל אלה, ServerCore
פנימי מבצע את הפעולות הבאות:
- Instantiates
FileSystemStoragePathSource
כי נתיבי ייצוא מודל צגים הכריזmodel_config_list
. - Instantiates
SourceAdapter
באמצעותPlatformConfigMap
עם פלטפורמת מודל הכריזmodel_config_list
ומחבר אתFileSystemStoragePathSource
אליו. בדרך זו, בכל פעם שיוצאת גרסה חדשה מודל מתגלה תחת נתיב הייצוא,SavedModelBundleSourceAdapter
מסתגל אותוLoader<SavedModelBundle>
. - Instantiates יישום ספציפי של
Manager
שנקראAspiredVersionsManager
שמנהלת את כל כגוןLoader
מקרים נוצר על ידיSavedModelBundleSourceAdapter
.ServerCore
מייצאת אתManager
הממשק ידי האצלת קריאותAspiredVersionsManager
.
בכל פעם גרסה חדשה זמינה, זה AspiredVersionsManager
טוען את הגרסה החדשה, ותחת מסיר התנהגות ברירת המחדל שלו לישנה. אם אתה רוצה להתחיל להתאים אישית, אתה מוזמן להבין את הרכיבים שהוא יוצר באופן פנימי, וכיצד להגדיר אותם.
ראוי להזכיר כי TensorFlow Serving תוכנן מאפס להיות מאוד גמיש וניתן להרחבה. אתה יכול לבנות תוספים שונים להתנהגות מערכת אישית, תוך ניצול רכיבי ליבה גנריות כמו ServerCore
ו AspiredVersionsManager
. לדוגמה, אתה יכול לבנות תוסף מקור נתונים שמנטר אחסון בענן במקום אחסון מקומי, או שאתה יכול לבנות תוסף מדיניות גרסה שעושה מעבר גרסה בצורה אחרת -- למעשה, אתה יכול אפילו לבנות תוסף דגם מותאם אישית שמשרת דגמים שאינם TensorFlow. נושאים אלה אינם בהיקף של הדרכה זו. עם זאת, אתה יכול להפנות את מקור המנהג ואת מנהג servable הדרכות לקבלת מידע נוסף.
אצווה
תכונת שרת טיפוסית נוספת שאנו רוצים בסביבת ייצור היא אצווה. מאיצי חומרה מודרניים (GPU וכו') המשמשים להסקת למידה חישובית משיגים בדרך כלל את יעילות החישוב הטובה ביותר כאשר בקשות הסקת מסקנות מופעלות באצוות גדולות.
מינון ניתן להפעיל באמצעות מתן נאה SessionBundleConfig
בעת יצירת SavedModelBundleSourceAdapter
. במקרה זה אנו קובעים את BatchingParameters
עם ערכי ברירת מחדל פחות או יותר. ניתן לכוונן עדין את האצווה על ידי הגדרת ערכי זמן קצוב מותאם אישית, batch_size וכו'. לפרטים, עיין BatchingParameters
.
SessionBundleConfig session_bundle_config;
// Batching config
if (enable_batching) {
BatchingParameters* batching_parameters =
session_bundle_config.mutable_batching_parameters();
batching_parameters->mutable_thread_pool_name()->set_value(
"model_server_batch_threads");
}
*saved_model_bundle_source_adapter_config.mutable_legacy_config() =
session_bundle_config;
בהגיעו אצווה מלא, בקשות היקש ימוזגו באופן פנימי בקשה גדולה אחת (מותח), ו tensorflow::Session::Run()
מופעלת (וזו בדיוק המטרה של שיפור ביעילות בפועל על GPUs מגיע).
מגישים עם מנהל
כפי שצוין לעיל, הגשת TensorFlow Manager
נועד להיות מרכיב גנרי שיכול לטפל טעינה, הגשה, פריקת המעבר לגרסה של דגמים שנוצרו על ידי מערכות למידת מכונה שרירותיות. ממשקי ה-API שלו בנויים סביב מושגי המפתח הבאים:
Servable: servable הוא אובייקט כלשהו אטום שניתן להשתמש בהם כדי לשרת בקשות הלקוח. הגודל והפירוט של חומר הגשה גמישים, כך שניתן להגשה בודד עשוי לכלול כל דבר, החל מרסיס בודד של טבלת חיפוש, לדגם אחד שנלמד על ידי מכונה ועד למספר דגמים. ניתן להגשה יכול להיות מכל סוג וממשק.
Servable גרסה: Servables הם versioned ו הגשה TensorFlow
Manager
יכול לנהל גירסאות אחד או יותר של servable. גירסאות מאפשרות לטעון יותר מגרסה אחת של קובץ הגשה בו-זמנית, התומכת בהשקה הדרגתית ובניסויים.Servable זרם: זרם servable הוא רצף של גרסאות של servable, עם הגדלת מספרי גרסאות.
דגם: דגם-נודע מכונית מיוצג על ידי servables אחד או יותר. דוגמאות להגשה הן:
- הפעלה או עטיפות TensorFlow סביבם, כגון
SavedModelBundle
. - סוגים אחרים של מודלים שנלמדו על ידי מכונה.
- טבלאות חיפוש אוצר מילים.
- הטמעת טבלאות חיפוש.
מודל מרוכב יכול להיות מיוצג כמספר רכיבים עצמאיים להגשה, או כרכיב מרוכב יחיד. Servable עשויה גם מתאימה שבריר דגם, למשל עם טבלת חיפוש גדולה sharded פני רבי
Manager
מקרים.- הפעלה או עטיפות TensorFlow סביבם, כגון
כדי לשים את כל אלה בהקשר של הדרכה זו:
מודלים TensorFlow מיוצגים על ידי סוג אחד של servable -
SavedModelBundle
.SavedModelBundle
פנימי מורכבtensorflow:Session
זיווג עם כמה מטא נתונים לגבי מה הגרף נטען לתוך הפגישה וכיצד להפעיל אותו עבור היקש.ישנה ספריית מערכת קבצים המכילה זרם של יצוא TensorFlow, כל אחד בספריית המשנה שלו ששמה הוא מספר גרסה. ניתן לחשוב על הספרייה החיצונית כייצוג בסידרה של הזרם הניתן להגשה עבור מודל TensorFlow המוגש. כל ייצוא מתאים ל-servables שניתן לטעון.
AspiredVersionsManager
מנטר את זרם הייצוא, ומנהלת מחזור החיים של כלSavedModelBundle
servables דינמי.
TensorflowPredictImpl::Predict
אז פשוט:
- בקשות
SavedModelBundle
ממנהל (דרך ServerCore). - משתמש
generic signatures
למפות שמות מותח לוגייםPredictRequest
לשמות מותחים אמיתיים וערכי נקשרי tensors. - מפעיל מסקנות.
בדוק והפעל את השרת
העתק את הגרסה הראשונה של הייצוא לתיקיה המנוטרת:
mkdir /tmp/monitored
cp -r /tmp/mnist/1 /tmp/monitored
ואז הפעל את השרת:
docker run -p 8500:8500 \
--mount type=bind,source=/tmp/monitored,target=/models/mnist \
-t --entrypoint=tensorflow_model_server tensorflow/serving --enable_batching \
--port=8500 --model_name=mnist --model_base_path=/models/mnist &
השרת ישלח הודעות יומן בכל שנייה אחת שאומרות "גרסה שואפת להגשה...", כלומר הוא מצא את הייצוא ועוקב אחר המשך קיומו.
בואו להפעיל את הלקוח עם --concurrency=10
. זה ישלח בקשות במקביל לשרת ובכך יפעיל את היגיון האצווה שלך.
tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
--num_tests=1000 --server=127.0.0.1:8500 --concurrency=10
מה שמביא לפלט שנראה כך:
...
Inference error rate: 13.1%
לאחר מכן אנו מעתיקים את הגרסה השנייה של הייצוא לתיקיה המנוטרת ונפעיל מחדש את הבדיקה:
cp -r /tmp/mnist/2 /tmp/monitored
tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
--num_tests=1000 --server=127.0.0.1:8500 --concurrency=10
מה שמביא לפלט שנראה כך:
...
Inference error rate: 9.5%
זה מאשר שהשרת שלך מגלה אוטומטית את הגרסה החדשה ומשתמש בה להגשה!