פיתוח TensorFlow Lite ל-iOS

במסמך הזה מוסבר איך ליצור בעצמכם את ספריית TensorFlow Lite ל-iOS. בדרך כלל, אין צורך לפתח גרסת build מקומית של ספריית TensorFlow Lite ל-iOS. אם רוצים פשוט להשתמש בו, הדרך הקלה ביותר היא להשתמש בגרסאות היציבות או הליליות של TensorFlow Lite CocoaPods. למידע נוסף על השימוש בפרויקטים ב-iOS, קראו את המדריך למתחילים ל-iOS.

בנייה מקומית

במקרים מסוימים, כדאי להשתמש בגרסה מקומית של TensorFlow Lite, למשל כשרוצים לבצע שינויים מקומיים ב-TensorFlow Lite ולבדוק את השינויים האלה באפליקציה ל-iOS, או אם מעדיפים להשתמש במסגרת הסטטית במסגרת הדינמית הדינמית שסיפקנו. כדי ליצור סביבת iOS אוניברסלית ל-TensorFlow Lite באופן מקומי, צריך לפתח אותה באמצעות Bazel במחשב עם macOS.

להתקנת Xcode

אם עדיין לא עשיתם זאת, תצטרכו להתקין Xcode 8 ואילך ואת הכלים באמצעות xcode-select:

xcode-select --install

אם זו התקנה חדשה, צריך לאשר את הסכם הרישיון עבור כל המשתמשים באמצעות הפקודה הבאה:

sudo xcodebuild -license accept

להתקנת Bazel

Bazel היא מערכת ה-build הראשית של TensorFlow. מתקינים את Bazel בהתאם להוראות באתר של Bazel. חשוב לבחור גרסה בין _TF_MIN_BAZEL_VERSION ל-_TF_MAX_BAZEL_VERSION בקובץ configure.py ברמה הבסיסית (root) של המאגר tensorflow.

הגדרת WORKSPACE ו- .bazelrc

מריצים את הסקריפט ./configure בספריית התשלום הבסיסית של TensorFlow ועונים "Yes" (כן) כאשר הסקריפט שואל אם רוצים ליצור את TensorFlow באמצעות תמיכה ב-iOS.

אחרי ש-Bazel מוגדרת כראוי בתמיכה ב-iOS, אפשר ליצור את ה-framework TensorFlowLiteC באמצעות הפקודה הבאה.

bazel build --config=ios_fat -c opt --cxxopt=--std=c++17 \
  //tensorflow/lite/ios:TensorFlowLiteC_framework

הפקודה הזו תיצור את הקובץ TensorFlowLiteC_framework.zip בספרייה bazel-bin/tensorflow/lite/ios/ שבספריית השורש של TensorFlow. כברירת מחדל, ה-framework שנוצר מכיל קובץ בינארי fat שמכיל את Armv7, arm64 ו-x86_64 (אבל לא את i386). כדי לראות את הרשימה המלאה של דגלי build שבהם אתם משתמשים לציון --config=ios_fat, עיינו בקטע ההגדרות של iOS בקובץ .bazelrc.

יצירת מסגרת סטטית של TensorFlowLiteC

כברירת מחדל, אנחנו מפיצים את המסגרת הדינמית רק דרך Cocoapods. אם רוצים להשתמש במקום זאת ב-framework, אפשר ליצור את המסגרת הסטטית TensorFlowLiteC באמצעות הפקודה הבאה:

bazel build --config=ios_fat -c opt --cxxopt=--std=c++17 \
  //tensorflow/lite/ios:TensorFlowLiteC_static_framework

הפקודה תיצור קובץ בשם TensorFlowLiteC_static_framework.zip בספרייה bazel-bin/tensorflow/lite/ios/ שבספריית הבסיס של TensorFlow. אפשר להשתמש במסגרת הסטטית הזו בדיוק כמו במסגרת הדינמית.

יצירה סלקטיבית של frameworks ב-TFLite

אפשר ליצור מסגרות קטנות יותר שמטרגטות רק קבוצת מודלים באמצעות build סלקטיבי, וכך לדלג על פעולות שלא נמצאות בשימוש בקבוצת המודלים ולכלול רק את ליבות הפעולה הנדרשות כדי להפעיל את קבוצת המודלים הנתונה. הפקודה תהיה:

bash tensorflow/lite/ios/build_frameworks.sh \
  --input_models=model1.tflite,model2.tflite \
  --target_archs=x86_64,armv7,arm64

הפקודה שלמעלה תיצור את ה-framework הסטטי bazel-bin/tensorflow/lite/ios/tmp/TensorFlowLiteC_framework.zip לפעולות מובנות ב-TensorFlow Lite ובהתאמה אישית. אפשר גם ליצור את ה-framework הסטטי bazel-bin/tensorflow/lite/ios/tmp/TensorFlowLiteSelectTfOps_framework.zip אם המודלים שלכם מכילים פעולות Select TensorFlow. שימו לב שאפשר להשתמש בדגל --target_archs כדי לציין את ארכיטקטורות הפריסה.

שימוש באפליקציה שלכם

מפתחי CocoaPods

יש שלושה CocoaPods ב-TensorFlow Lite:

  • TensorFlowLiteSwift: מספקת את ממשקי ה-API של Swift עבור TensorFlow Lite.
  • TensorFlowLiteObjC: מתן ממשקי API ל-Objective-C עבור TensorFlow Lite.
  • TensorFlowLiteC: פוד בסיס משותף, שבו מוטמע זמן הריצה הליבה של TensorFlow Lite וחושף את ממשקי ה-API הבסיסיים של C שבהם משתמשים שני רצפי ה-pod שלמעלה. לא מיועד לשימוש ישיר על ידי משתמשים.

מפתחים צריכים לבחור רצף TensorFlowLiteSwift או TensorFlowLiteObjC בהתאם לשפה שבה האפליקציה נכתבת, אבל לא לשתיהן. השלבים המדויקים לשימוש בגרסאות build מקומיות של TensorFlow Lite משתנים בהתאם לחלק המדויק שרוצים לבנות.

שימוש בממשקי API מקומיים של Swift או Objective-C

אם אתם משתמשים ב-CocoaPods ורוצים לבדוק רק כמה שינויים מקומיים ב-Swift APIs או ב-Objective-C APIs של TensorFlow Lite, בצעו את השלבים המפורטים כאן.

  1. יש לבצע שינויים בממשקי ה-API של Swift או Objective-C בקופה עם tensorflow.

  2. פותחים את הקובץ TensorFlowLite(Swift|ObjC).podspec ומעדכנים את השורה הזו:
    s.dependency 'TensorFlowLiteC', "#{s.version}"
    כך שתהיה:
    s.dependency 'TensorFlowLiteC', "~> 0.0.1-nightly"
    הקפידו ליצור את ממשקי ה-API של Swift או Objective-C כנגד הגרסה האחרונה הזמינה ללילה של ממשקי TensorFlowLiteC API (שנבנה מדי לילה בין 1:00 ל-4:00 לפי שעון החוף המערבי) ולא בגרסה היציבה, שעשויה להיות מיושנת בהשוואה לקופה המקומי tensorflow. לחלופין, אתם יכולים לפרסם גרסה משלכם של TensorFlowLiteC ולהשתמש בגרסה הזו (עיינו בקטע שימוש בליבה מקומית של TensorFlow Lite בהמשך).

  3. ב-Podfile של פרויקט iOS, משנים את התלות באופן הבא כדי להצביע על הנתיב המקומי לספריית הבסיס tensorflow.
    עבור סוויפט:
    pod 'TensorFlowLiteSwift', :path => '<your_tensorflow_root_dir>'
    עבור מטרה ג':
    pod 'TensorFlowLiteObjC', :path => '<your_tensorflow_root_dir>'

  4. יש לעדכן את התקנת ה-pod מספריית השורש של פרויקט iOS.
    $ pod update

  5. פותחים מחדש את סביבת העבודה שנוצרה (<project>.xcworkspace) ויוצרים מחדש את האפליקציה ב-Xcode.

שימוש בליבה מקומית של TensorFlow Lite

אתם יכולים להגדיר מאגר מפרטים פרטי של CocoaPods ולפרסם את ה-framework TensorFlowLiteC בהתאמה אישית למאגר הפרטי שלכם. אפשר להעתיק את קובץ ה-podspec ולשנות כמה ערכים:

  ...
  s.version      = <your_desired_version_tag>
  ...
  # Note the `///`, two from the `file://` and one from the `/path`.
  s.source       = { :http => "file:///path/to/TensorFlowLiteC_framework.zip" }
  ...
  s.vendored_frameworks = 'TensorFlowLiteC.framework'
  ...

אחרי שיצרתם קובץ TensorFlowLiteC.podspec משלכם, תוכלו לפעול לפי ההוראות לשימוש ב-CocoaPods פרטי כדי להשתמש בו בפרויקט משלכם. אפשר גם לשנות את TensorFlowLite(Swift|ObjC).podspec כך שיצביע על רצף TensorFlowLiteC בהתאמה אישית ולהשתמש ב-Swift או ב-Objective-C בפרויקט האפליקציה.

מפתחי Bazel

אם אתם משתמשים ב-Bazel ככלי ה-build הראשי, אתם יכולים פשוט להוסיף תלות TensorFlowLite ליעד בקובץ BUILD.

עבור סוויפט:

swift_library(
  deps = [
      "//tensorflow/lite/swift:TensorFlowLite",
  ],
)

עבור יעד ג':

objc_library(
  deps = [
      "//tensorflow/lite/objc:TensorFlowLite",
  ],
)

כשיוצרים פרויקט לאפליקציה, המערכת מתעדת את כל השינויים בספריית TensorFlow Lite ומובנית באפליקציה.

שינוי ישיר של הגדרות פרויקט Xcode

מומלץ מאוד להשתמש ב-CocoaPods או ב-Bazel להוספת תלות של TensorFlow Lite לפרויקט. אם תרצו להוסיף את ה-framework של TensorFlowLiteC באופן ידני, תצטרכו להוסיף את ה-framework TensorFlowLiteC כמסגרת מוטמעת לפרויקט האפליקציה. כדי לקבל את הספרייה TensorFlowLiteC.framework, מחלצים את קובץ TensorFlowLiteC_framework.zip שנוצר מה-build שלמעלה. הספרייה הזו היא ה-framework בפועל ש-Xcode יכול להבין.

אחרי שמכינים את TensorFlowLiteC.framework, צריך קודם להוסיף אותו כקובץ בינארי מוטמע ליעד האפליקציה. הקטע המדויק של הגדרות הפרויקט עשוי להשתנות בהתאם לגרסת ה-Xcode שלכם.

  • Xcode 11: עוברים לכרטיסייה General (כללי) בעורך הפרויקט של יעד האפליקציה ומוסיפים את השדה TensorFlowLiteC.framework בקטע Frameworks, ספריות ותוכן מוטמע.
  • Xcode 10 ומטה: עוברים לכרטיסייה 'כללי' בעורך הפרויקטים של יעד האפליקציה ומוסיפים את ה-TensorFlowLiteC.framework בקטע 'דפים בינאריים מוטמעים'. אתם אמורים גם להוסיף את ה-framework באופן אוטומטי בקטע Linked Framework and Libraries (מסגרות וספריות מקושרות).

כשמוסיפים את ה-framework כבינארי מוטמע, ב-Xcode מתעדכנים גם הערך של מסגרת החיפוש ב-Framework בכרטיסייה 'יצירת הגדרות' כך שיכלול את ספריית ההורה של ה-framework. אם זה לא קורה באופן אוטומטי, צריך להוסיף באופן ידני את ספריית ההורה של ספריית TensorFlowLiteC.framework.

אחרי שתסיימו את שתי ההגדרות האלה, תוכלו לייבא ולהתקשר ל-C API של TensorFlow Lite, שמוגדר על ידי קובצי הכותרת בספרייה TensorFlowLiteC.framework/Headers.