LiteRT Accelerator Test Suite (ATS) הוא כלי מקיף שמשמש לאימות של נכונות פונקציונלית ולמדידת הביצועים של הטמעות מותאמות אישית של מאיצים שמשולבים עם מסגרת LiteRT.
סקירה כללית ופונקציונליות ליבה
הפונקציה העיקרית של ATS היא להריץ מודלים מוגדרים מראש של למידת מכונה על מאיץ יעד ולהשוות את התוצאות ל-LiteRT backend רגיל של CPU.
- אימות: חבילת הבדיקה מבצעת אימות מספרי על ידי השוואה בין טנסורים של פלט (הפעלות) שנוצרו על ידי המאיץ לבין טנסורים שנוצרו על ידי קצה העורפי של המעבד שידוע שהוא תקין. כך אפשר לוודא שההטמעה של המאיץ תהיה מדויקת ונכונה.
- מדדי ביצועים: המערכת אוספת ומתעדת באופן אוטומטי פרטים חשובים על הביצועים, כולל זמן האחזור ומדדים רלוונטיים אחרים, שזמינים למשתמש.
- ביצוע: הבדיקות מבוצעות בדרך כלל במכשיר יעד (למשל, טלפון Android) ומנוהלות על ידי עטיפה של סקריפט shell שמטפל בהעברות קבצים ובהגדרה באמצעות הכלי
adb(Android Debug Bridge).
נתוני בדיקה (מודלים)
חבילת ATS משתמשת באוסף של מודלים.tflite שנמצאים בשימוש נרחב כנתוני בדיקה. נתוני הקלט נוצרים באופן אקראי על סמך סוג הנתונים, ואפשר להגדיר אותם לפי הצורך.
מודלים כלולים
המודלים הבאים נכללים באופן אוטומטי ומוורדים לבדיקה (המודלים עשויים להשתנות):
hf_all_minilm_l6_v2hf_mobilevit_smallqai_hub_midasqai_hub_real_esrgan_x4plustorchvision_mobilenet_v2torchvision_resnet18torchvision_squeezenet1_1u2net_litewhisper_tiny_decoderwhisper_tiny_encoderyamnetyolo11n
שליפה ידנית של מודל
המודלים מורדים אוטומטית במהלך bazel run, אבל אפשר לאחזר ידנית את כל קבוצת המודלים באמצעות wget:
wget -p -O <target_file> https://storage.googleapis.com/litert/ats_models.tar.gz
הגדרת חבילת ATS באמצעות Bazel
משתמשים בפקודת המאקרו litert_define_ats Bazel כדי להגדיר ולהגדיר יעד ספציפי לבדיקת ATS במאיץ.
המאקרו יוצר באופן אוטומטי שני יעדים להפעלה:
- בדיקת JIT במכשיר (לביצוע ולאימות).
- בדיקה ייעודית של מצב AOT 'קומפילציה בלבד' (לקומפילציה של המארח).
דוגמה לשימוש ב-litert_define_ats
בדוגמה מוגדרת חבילת ATS בשם example_ats למאיץ עם שם ה-backend example:
# Emits aot-mode and jit-mode test targets, one for running compilation test on host
# and another for running JIT and inference on device
# These targets are named with their respective suffix attribute.
litert_define_ats(
name = "example_ats",
backend = "example",
compile_only_suffix = "_aot",
do_register = [
"*mobilenet*",
],
extra_flags = ["--limit=1"],
jit_suffix = "",
)
ביצוע
כדי להריץ את הבדיקה הרגילה שמיועדת ל-Android (שמטפלת בכל הפעולות של adb):
# Handles environment setup, and build + push of library and data dependencies to the device,
# executes the suite on the target.
bazel run -c opt --config=android_arm64 :example_ats
כדי להריץ את בדיקת הקומפילציה של AOT:
# Handle environment setup, and builds library dependencies for host platform.
# Executes the ats compile only flow. The "--compile_mode" flag is already
# bound to the program arguments.
bazel run :example_ats_aot
הרצה ב-Linux (מארח)
במערכות Linux, שבהן ATS מופעל באותה מכונה שבה מתבצעת הבנייה, המשתמשים צריכים להשתמש ישירות בקובץ הבינארי :ats:
bazel run -c opt :ats
ביצוע IoT
כדי להפעיל את התוכנה ב-IoT, המשתמשים יצטרכו ליצור את הקובץ הבינארי במארח ולהעביר אותו למכשיר באופן ידני.
התרעות לגבי שורת פקודה
קובץ ההפעלה ats מקבל כמה דגלים לשליטה מפורטת בבדיקות ובדיווח.
| דגל | סוג | תיאור |
|---|---|---|
--backend |
std::string |
חובה. איזה עורף קצה של LiteRT ישמש כמאיץ שנבדק (ה'בפועל'). האפשרויות הן cpu, npu או gpu. |
--compile_mode |
bool |
אם הערך הוא true, שלב הקומפילציה של AOT מופעל בתחנת העבודה במקום בהפעלה במכשיר. הערה: האפשרות הזו משויכת אוטומטית ליעד הבנייה 'aot' ולא צריך להגדיר אותה באופן מפורש. |
--models_out |
std::string |
נתיב הספרייה שבה נשמרים מודלים של תופעות לוואי שעברו סריאליזציה (קומפילציה). רלוונטי רק להידור AOT או JIT. |
--dispatch_dir |
std::string |
הנתיב לספרייה שמכילה את ספריית השליחה של המאיץ (רלוונטי ל-NPU). |
--plugin_dir |
std::string |
הנתיב לספריית הפלאגין של מהדר המאיץ (רלוונטי ל-NPU). |
--soc_manufacturer |
std::string |
היצרן של ה-SOC לטירגוט עבור קומפילציה של AOT (רלוונטי לקומפילציה של NPU). |
--soc_model |
std::string |
מודל ה-SOC לטירגוט עבור קומפילציה של AOT (רלוונטי לקומפילציה של NPU). |
--iters_per_test |
size_t |
מספר האיטרציות להרצה לכל בדיקה, כל אחת עם נתוני טנסור אקראיים שונים. |
--max_ms_per_test |
int64_t |
משך הזמן המרבי באלפיות השנייה להרצת כל בדיקה לפני פסק זמן. |
--fail_on_timeout |
bool |
האם הבדיקה תיכשל אם יפוג הזמן הקצוב להפעלה. |
--csv |
std::string |
נתיב הקובץ לשמירת הדוח המפורט בפורמט CSV. |
--dump_report |
bool |
האם להציג את כל פרטי הדוח ישירות בפלט של מסוף המשתמש. |
--data_seed |
std::optional<int> | seed אחד ליצירת נתונים גלובליים. |
--do_register |
std::vector<std::string> | ביטויי Regex להכללה מפורשת של בדיקות ספציפיות (למשל, *mobilenet*). |
--dont_register |
std::vector<std::string> | ביטויי Regex להחרגה של בדיקות ספציפיות. |
--extra_models |
std::vector<std::string> | רשימה אופציונלית של ספריות או קבצים של מודלים להוספה לחבילת הבדיקה. |
--limit |
int32_t |
הגבלת המספר הכולל של בדיקות שנרשמו והופעלו. |
--quiet |
bool |
צמצום פלט הרישום במהלך הרצת הבדיקה. |
שימוש בכלי השירות לבנייה של ATS litert_device_script
היעדים של ATS שהמשתמשים מריצים באופן אוטומטי כוללים נקודת כניסה של מעטפת שמטפלת בכל הגדרת הסביבה, ובכל דחיפה של ספריות נדרשות כשהמכשיר היעד שונה מהמארח שבו הושלם ה-build (לדוגמה, adb push).
הפונקציונליות הזו מסופקת באופן כללי באמצעות כלי השירות litert_device_script שבהם נעשה שימוש מאחורי הקלעים בגרסאות של ATS. יש תהליך רישום שצריך לבצע כדי לקבל גישה לפונקציונליות הזו של בניית אפליקציות. בנוסף לתמיכה ב-ats, אפשר להשתמש בכלי השירות האלה באופן עצמאי כדי לדמות את cc_binary ואת cc_test, שנועדו להפעלה במכשיר שונה ממארח הבנייה שדורש שליחה של יחסי תלות.
רישום בקצה העורפי
כדי להפעיל מאיץ חדש לשימוש ב-litert_device_script (ולכן ב-ATS), צריך לרשום את הספריות הנדרשות שלו בקובץ litert_device_common.bzl Bazel. ההרשמה מבוססת על שם ייחודי של 'קצה עורפי' שממופה לקבוצה של ספריות שאפשר לבנות או שהן קומפלו מראש, שנדרשות כדי שמערכת LiteRT תפעל עם המאיץ הזה.
שלבי ההרשמה
הגדרת פונקציית
BackendSpec: יוצרים פונקציה שמחזירה מילון שמכיל את המפרט של המאיץ החדש.Specify Libraries (
libs): זו רשימה של טאפלים שמפרטים את נתיב היעד של Bazel לספרייה המשותפת ואת משתנה הסביבה (LD_LIBRARY_PATH) שנדרש כדי שמקשר המכשיר ימצא אותה.- ספריית השליחה: נדרשת להרצת זמן ריצה.
- ספריית פלאגין של קומפיילר: נדרשת למצב קומפילציה AOT.
מציינים שמות של ספריות (
plugin,dispatch): מציינים את שמות הקבצים של התוסף ושל ספריות השליחה.רישום המפרט: ממזגים את פונקציית המפרט החדשה עם הפונקציה הראשית
_Specsכדי שהיא תהיה זמינה באמצעות המזהה הייחודי שלה בבק-אנד.
דוגמה לרישום (_ExampleSpec)
הקוד הבא מתוך litert_device_common.bzl ממחיש איך נרשם המאיץ example:
def _ExampleSpec():
return {
# The unique backend ID
"example": BackendSpec(
id = "example",
libs = [
# Dispatch Library and how to find it on device
("//third_party/odml/litert/litert/vendors/examples:libLiteRtDispatch_Example.so", "LD_LIBRARY_PATH"),
# Compiler Plugin Library
("//third_party/odml/litert/litert/vendors/examples:libLiteRtCompilerPlugin_Example.so", "LD_LIBRARY_PATH"),
],
plugin = "libLiteRtCompilerPlugin_Example.so",
dispatch = "libLiteRtDispatch_Example.so",
),
}
# ... (Other specs are defined here)
def _Specs(name):
# Your new spec function must be included here
return (_QualcommSpec() | _GoogleTensorSpec() | _MediatekSpec() | _CpuSpec() | _GpuSpec() | _ExampleSpec())[name]
שימוש בתכונת ההרשמה ב-litert_device_exec
אחרי ההרשמה, משתמשים בפקודות המאקרו litert_device_exec ובפקודות מאקרו קשורות עם הפקודה החדשה backend_id. המאקרו הזה מאגד באופן אוטומטי את הספריות הנדרשות ואת כל קובצי הנתונים שצוינו עם קובץ הבינארי של היעד.
cc_binary(
name = "example_bin",
srcs = ["example_bin.cc"],
)
litert_device_exec(
name = "example_bin_device",
backend_id = "example", # Uses the libraries registered under "example"
data = [
"//third_party/odml/litert/litert/test:testdata/constant_output_tensor.tflite",
],
target = ":example_bin",
)
הפעלת היעד הזה (bazel run ... :example_bin_device) תגרום לפעולות הבאות:
- יוצרים את הקובץ הבינארי
example_binC++. - מעבירים את הקובץ הבינארי,
libLiteRtDispatch_Example.so,libLiteRtCompilerPlugin_Example.soואת הקובץ.tfliteלמכשיר. - מריצים את הקובץ הבינארי באמצעות
adb shell.
הערה לגבי נתיבי מכשירים: המיקום הקנוני של קבצים במכשיר משקף את עץ קובצי ההרצה של Bazel, באופן ספציפי
/data/local/tmp/runfiles/runfiles_relative_path. סקריפט המכשיר מטפל אוטומטית בהגדרת הנתיבים המתאימים ל-linker הדינמי.
מצב קומפילציה (AOT)
במאיצים שתומכים בשלב הקימפול מראש (AOT), אפשר להפעיל את ATS במצב קימפול ייעודי.
- מטרה: המצב הזה מיועד להפעלה בתחנת עבודה (מחשב מארח), ולא במכשיר היעד. הוא אוסף את המודלים עבור החומרה המיועדת שצוינה בלי להפעיל אותם.
- פלט: כל המודלים שעברו קומפילציה מועברים לספרייה ייעודית בתחנת העבודה.
- הפעלה: פקודות המאקרו של ATS build יפלטו יעד ספציפי עבור aot שבו הספריות נוצרות עבור פלטפורמת המארח. אפשר להפעיל את התהליך הזה בכל קובץ בינארי באמצעות הדגל
--compile_mode, אבל הוא מקושר אוטומטית לארגומנטים של בניית ה-AOT.
הרחבה עתידית
אנחנו מתכננים להרחיב את החבילה כך שתכלול בדיקות ייעודיות לפעולות (ops) בודדות, בנוסף למודלים מלאים.