สร้าง TensorFlow Lite สำหรับ iOS

เอกสารนี้จะอธิบายวิธีสร้างไลบรารี TensorFlow Lite สำหรับ iOS ด้วยตัวคุณเอง โดยปกติแล้ว คุณไม่จำเป็นต้องสร้างไลบรารี iOS ของ TensorFlow Lite ภายในเครื่อง หากต้องการใช้งาน วิธีที่ง่ายที่สุดคือการใช้ 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 เป็นระบบบิลด์หลักสำหรับ TensorFlow ติดตั้ง Bazel ตามวิธีการในเว็บไซต์ Bazel ตรวจสอบว่าได้เลือกเวอร์ชันระหว่าง _TF_MIN_BAZEL_VERSION ถึง _TF_MAX_BAZEL_VERSION ใน ไฟล์ configure.py ที่รูทของที่เก็บ tensorflow

กำหนดค่า WORKSPACE และ .bazelrc

เรียกใช้สคริปต์ ./configure ในไดเรกทอรีการชำระเงิน TensorFlow รูท และตอบว่า "ใช่" เมื่อสคริปต์ถามว่าต้องการสร้าง TensorFlow ด้วยการรองรับ iOS หรือไม่

เมื่อ Bazel ได้รับการกำหนดค่าด้วยการรองรับ iOS อย่างถูกต้องแล้ว คุณจะสร้างเฟรมเวิร์ก 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 โดยค่าเริ่มต้น เฟรมเวิร์กที่สร้างขึ้นจะมีไบนารี "fat" ซึ่งประกอบด้วย armv7, arm64 และ x86_64 (แต่ไม่มี i386) หากต้องการดูรายการแฟล็กบิลด์ทั้งหมดที่ใช้เมื่อคุณระบุ --config=ios_fat โปรดดูส่วนการกำหนดค่า iOS ในไฟล์ .bazelrc

สร้างเฟรมเวิร์กแบบคงที่ของ TensorFlowLiteC

โดยค่าเริ่มต้น เราจะเผยแพร่เฟรมเวิร์กแบบไดนามิกผ่าน Cocoapods เท่านั้น หากต้องการใช้เฟรมเวิร์กแบบคงที่แทน คุณสร้างเฟรมเวิร์กแบบคงที่ 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 เฟรมเวิร์กแบบคงที่นี้ใช้ในลักษณะเดียวกันกับเฟรมเวิร์กแบบไดนามิกได้

เลือกสร้างเฟรมเวิร์ก TFLite

คุณสามารถสร้างเฟรมเวิร์กที่เล็กลงซึ่งกำหนดเป้าหมายเฉพาะชุดโมเดลโดยใช้บิลด์ที่เลือกได้ ซึ่งจะข้ามการดำเนินการที่ไม่ได้ใช้ในชุดโมเดลของคุณ และรวมเฉพาะเคอร์เนลการดำเนินการที่จำเป็นต่อการเรียกใช้ชุดโมเดลที่ระบุเท่านั้น คําสั่งมีดังนี้

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

คำสั่งด้านบนจะสร้างเฟรมเวิร์กแบบคงที่ bazel-bin/tensorflow/lite/ios/tmp/TensorFlowLiteC_framework.zip สำหรับ TensorFlow Lite ในตัวและ Ops ที่กำหนดเอง และอาจสร้างเฟรมเวิร์กแบบคงที่ bazel-bin/tensorflow/lite/ios/tmp/TensorFlowLiteSelectTfOps_framework.zip หรือไม่ก็ได้หากโมเดลของคุณมีการดำเนินการ Select TensorFlow โปรดทราบว่าแฟล็ก --target_archs สามารถใช้เพื่อระบุสถาปัตยกรรมการทำให้ใช้งานได้

ใช้ในแอปพลิเคชันของคุณเอง

นักพัฒนาซอฟต์แวร์ CocoaPods

CocoaPods สำหรับ TensorFlow Lite มี 3 แบบ ได้แก่

  • TensorFlowLiteSwift: ให้ Swift API สำหรับ TensorFlow Lite
  • TensorFlowLiteObjC: ให้ Objective-C API สำหรับ TensorFlow Lite
  • TensorFlowLiteC: พ็อดฐานทั่วไปซึ่งฝังรันไทม์หลักของ TensorFlow Lite และแสดง API ฐาน C ที่พ็อด 2 รายการข้างต้นใช้ ไม่ได้มีไว้เพื่อ ให้ผู้ใช้ใช้งานโดยตรง

ในฐานะนักพัฒนาซอฟต์แวร์ คุณควรเลือกพ็อด TensorFlowLiteSwift หรือ TensorFlowLiteObjC ตามภาษาที่ใช้เขียนแอป แต่ไม่ใช่ทั้ง 2 แบบ ขั้นตอนที่แน่นอนสำหรับการใช้บิลด์ภายในของ TensorFlow Lite จะแตกต่างกันไปขึ้นอยู่กับส่วนที่คุณต้องการสร้าง

การใช้ Swift หรือ Objective-C API ในเครื่อง

หากคุณใช้ CocoaPods และต้องการทดสอบการเปลี่ยนแปลงในเครื่องเท่านั้นกับ Swift API หรือ Objective-C API ของ TensorFlow Lite ให้ทำตามขั้นตอนที่นี่

  1. ทำการเปลี่ยนแปลงกับ Swift หรือ Objective-C API ที่จุดชำระเงินของ 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-4:00 น. ตามเวลาแปซิฟิก) แทนที่จะเป็นเวอร์ชันเสถียรซึ่งอาจล้าสมัยเมื่อเทียบกับการชำระเงินtensorflow ในท้องถิ่น หรือจะเลือกเผยแพร่ TensorFlowLiteC เวอร์ชันของคุณเองและใช้เวอร์ชันนั้นก็ได้ (ดูส่วนการใช้ TensorFlow Lite Core ในเครื่องด้านล่าง)

  3. ใน Podfile ของโปรเจ็กต์ iOS ให้เปลี่ยนทรัพยากร Dependency ดังต่อไปนี้ให้ชี้ไปที่เส้นทางในเครื่องไปยังไดเรกทอรีรูท tensorflow
    สำหรับ Swift:
    pod 'TensorFlowLiteSwift', :path => '<your_tensorflow_root_dir>'
    สำหรับ Objective-C:
    pod 'TensorFlowLiteObjC', :path => '<your_tensorflow_root_dir>'

  4. อัปเดตการติดตั้งพ็อดจากไดเรกทอรีรูทของโปรเจ็กต์ iOS
    $ pod update

  5. เปิดพื้นที่ทำงานที่สร้างขึ้นอีกครั้ง (<project>.xcworkspace) และสร้างแอปอีกครั้งภายใน Xcode

การใช้ TensorFlow Lite Core ในเครื่อง

คุณตั้งค่าที่เก็บข้อมูลจำเพาะของ CocoaPods ส่วนตัวและเผยแพร่เฟรมเวิร์ก 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 เป็นเครื่องมือบิลด์หลัก คุณสามารถเพิ่มทรัพยากร Dependency TensorFlowLite ไปยังเป้าหมายในไฟล์ BUILD ได้เลย

สำหรับ Swift:

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

สำหรับ Objective-C:

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

เมื่อสร้างโปรเจ็กต์แอป ระบบจะรวบรวมการเปลี่ยนแปลงทุกอย่างในไลบรารี TensorFlow Lite มาใส่ไว้ในแอป

แก้ไขการตั้งค่าโปรเจ็กต์ Xcode โดยตรง

เราขอแนะนำให้ใช้ CocoaPods หรือ Bazel เพื่อเพิ่มทรัพยากร Dependency ของ TensorFlow Lite ลงในโปรเจ็กต์ หากยังต้องการเพิ่มเฟรมเวิร์ก TensorFlowLiteC ด้วยตนเอง คุณจะต้องเพิ่มเฟรมเวิร์ก TensorFlowLiteC เป็นเฟรมเวิร์กที่ฝังลงในโปรเจ็กต์แอปพลิเคชันของคุณ แตกไฟล์ TensorFlowLiteC_framework.zip ที่สร้างจากบิลด์ด้านบนเพื่อรับไดเรกทอรี TensorFlowLiteC.framework ไดเรกทอรีนี้เป็นเฟรมเวิร์กจริง ที่ Xcode เข้าใจได้

เมื่อเตรียม TensorFlowLiteC.framework เรียบร้อยแล้ว คุณต้องเพิ่มเป็นไบนารีแบบฝังลงในเป้าหมายของแอปก่อน ส่วนการตั้งค่าโปรเจ็กต์ที่แน่นอนสำหรับกรณีนี้อาจแตกต่างกันไปตามเวอร์ชัน Xcode

  • Xcode 11: ไปที่แท็บ "ทั่วไป" ของตัวแก้ไขโปรเจ็กต์สำหรับเป้าหมายของแอป และเพิ่ม TensorFlowLiteC.framework ในส่วน "เฟรม ไลบรารี และเนื้อหาที่ฝัง"
  • Xcode 10 และเวอร์ชันที่ต่ำกว่า: ไปที่แท็บ "ทั่วไป" ของเครื่องมือแก้ไขโปรเจ็กต์สำหรับเป้าหมายแอป แล้วเพิ่ม TensorFlowLiteC.framework ในส่วน "ไบนารีที่ฝัง" ควรเพิ่มเฟรมเวิร์กโดยอัตโนมัติในส่วน "เฟรมและไลบรารีที่ลิงก์"

เมื่อคุณเพิ่มเฟรมเวิร์กเป็นไบนารีแบบฝัง Xcode จะอัปเดตรายการ "เส้นทางการค้นหาของเฟรม" ในแท็บ "การตั้งค่าบิลด์" เพื่อรวมไดเรกทอรีระดับบนสุดของเฟรมเวิร์กด้วย ในกรณีที่กรณีนี้ไม่เกิดขึ้นโดยอัตโนมัติ คุณควรเพิ่มไดเรกทอรีระดับบนสุดของไดเรกทอรี TensorFlowLiteC.framework ด้วยตนเอง

เมื่อตั้งค่าทั้ง 2 อย่างนี้เสร็จแล้ว คุณควรจะนำเข้าและเรียก C API ของ TensorFlow Lite ตามที่กำหนดโดยไฟล์ส่วนหัวภายในไดเรกทอรี TensorFlowLiteC.framework/Headers ได้