智慧型應用程式

運用 Google Play 服務中的 ML Kit 和 LiteRT,掌握裝置端智慧功能

喇叭

  • Chintan Parikh

    產品經理主管

  • Fergus Henderson

    軟體工程部門人員

關於

講座簡介

不必再為了兼顧即插即用 AI 的便利性和自訂模型的彈性而煩惱,您可以在單一超精簡應用程式中部署這兩者,而不會增加數 MB 的二進位檔。

在這場講座中,我們將示範如何在單一 Android 應用程式中建構這種雙堆疊架構。您將瞭解如何運用 ML Kit 執行現成的傳統機器學習工作 (例如掃描文件),並在 Play 服務中搭配使用 LiteRT 獨立版,處理自訂電腦視覺或音訊工作負載。我們將深入探討這兩種實作路徑如何整合,運用現代 LiteRT 執行階段,讓應用程式在 CPU 和 GPU 上享有流暢的硬體加速效能,且下載體積幾乎為零。

開發人員重點摘要:

- 效能不打折:無論是現成或自訂模型,都能透過統一的 CompiledModel API 自動進行硬體加速。

- 微型 APK:將 ML Kit 和 LiteRT 執行階段卸載至 Play 服務,大幅縮減應用程式的下載大小。

- 混合整合:掌握在正式環境中並行執行多個機器學習工作流程,避免資源衝突。

摘要

  • Google Play 服務中的 LiteRT 會在應用程式之間共用一個維護的執行階段,將 APK 大小縮減約 8 MB。
  • Turnkey ML Kit 功能和自訂 LiteRT 模型,可在同一個執行階段的單一應用程式中一起執行。
  • CompiledModel API 可簡化 GPU 加速作業,效能比舊版 TFLite GPU 推論快上 1.4 倍。
  • 除了手機,Wear OS 4 以上版本和 Android 11 以上版本的 Android Automotive OS 也支援這個平台。
  • 如要在 Google Play 服務中採用 LiteRT,請將 Maven 依附元件更新為 play-services-litert,呼叫 LiteRt.initialize 取得環境,然後將環境傳遞至 CompiledModel.create。
  • 建議您改用 2.x CompiledModel API,因為 1.x 處於維護模式,且 NNAPI 即將停用。

技能

資源

Gemini Notebook

主題

  • on-device-ai
  • ml-kit
  • litert
  • google-play-services
  • gpu-acceleration
  • 機器學習

轉錄稿

LiteRT 簡介與總覽

  • 各位晚安。

  • 講座即將開始。

  • 因此,現在人們提到「裝置端 AI」時,通常是指 LLM。

  • 今天稍早,我們也舉辦了幾場關於 Gemini Nano 的講座,內容涵蓋 ML Kit、Firebase 和許多其他 Google 產品。

  • 本課程將介紹另一半:傳統機器學習和您自行提供的模型。

  • 您今天可能已經用過幾次,只是未曾發覺。

  • 想想看,你是否曾使用任何應用程式模糊背景、掃描條碼或編輯圖片。

  • 其中許多功能都採用傳統機器學習技術,通常甚至是在裝置端執行。

  • 如果您曾在自己的應用程式或 APK 中加入這些功能,可能經常面臨以下取捨:基本上,我應該使用統包 API,還是自備模型?

  • 這對應用程式大小會有什麼影響?

  • 今天,您會發現不必在統包式或自備模型之間做出選擇。

  • 事實上,只要使用一個精簡的執行階段,就能同時做到這兩點。

  • 我是 Chintan Parikh。

  • 我是 LiteRT 的產品經理,身旁這位是 Android 機器學習服務的工程主管 Fergus。

  • 你好!

  • 最後,您將瞭解如何建構一個應用程式,在每個相機影格上執行兩個模型,速度約為每秒影格數 30 個。

  • 這場講座分為四個部分。

  • 第一部分將介紹 Google 的裝置端 AI 解決方案,著重於傳統機器學習,也就是 ML Kit 和 LiteRT。

  • 接著,我們也會介紹 LiteRT 和 Play 服務的新功能。

  • 此外,我們也會介紹 LiteRT 的新 CompiledModel API,以及支援的裝置。

  • 第三,我們會示範如何建構新應用程式。

  • Fergus 將說明如何使用 ML Kit 和自訂模型建構應用程式,並將所有內容整合至單一 APK。

  • 最後,我們將示範如何使用代理模式升級現有應用程式。

  • 此外,您甚至可以透過這個代理建構新應用程式。

  • 現在我們來做個小測驗

  • 首先,什麼是 LiteRT?

  • LiteRT 是 Google 的裝置端推論執行階段,適用於您自己的模型。

  • 如果您曾使用 TensorFlow Lite,就會發現兩者都採用相同的 .tflite 檔案格式。

  • 經過重新設計,效能更佳,且支援多種架構。

  • 也就是說,您可以從 PyTorch、TensorFlow 甚至 JAX 匯入模型,並將其轉換為 LiteRT 的 FlatBuffer 格式。

  • 自 2022 年起,Google Play 服務中的 TensorFlow Lite 已成為 Android 官方的自訂模型裝置端執行階段。

  • 今天,這項服務將大幅升級,這也是本次演講的重點。

  • 升級後,您將可使用最新的 LiteRT CompiledModel API,包括全新改良的 GPU 推論功能,速度可提升 1.4 倍,還能建構更精簡的 APK,打造更小巧的應用程式。

  • 那麼,為什麼要透過 Play 服務提供這項功能呢?

  • 這有幾個優點,而且我聽過許多談話,發現應用程式大小和 APK 膨脹確實是個大痛點,對吧?

  • 因此,您會獲得較小的執行階段。

  • 執行階段不在 APK 中,因此您必須依賴精簡型用戶端,這會使 APK 縮小約 8 MB。

  • 第二個好處是效率。

  • 執行階段只有一個,因此所有應用程式都會共用 LiteRT 執行階段。

  • 因此,如果您有多個應用程式,每個應用程式都能節省 8 MB。

  • 如果想節省磁碟空間並精簡應用程式,這項功能就非常實用。

  • 第二,有人維護。

  • Google 會修正錯誤、解決 GPU 驅動程式問題,您不必費心處理,其他安全性更新也會透過自動更新提供。

  • 如前所述,GPU 速度提升 1.4 倍,我們也會進一步詳細說明。

  • 從涵蓋範圍的角度來看,我們可以將功能推送至舊版 Android 裝置。

  • Play 服務中的 LiteRT 最早支援 2016 年推出的 Android 7。

  • Fergus 也會向各位展示我們在後續投影片中擴展的其他新裝置。

  • 這就是傳遞媒介,接下來我們來談談執行階段。

  • 因此,LiteRT 並非新技術,也不是實驗性技術。

  • 目前已有超過 25 萬個應用程式採用 TensorFlow Lite 和 LiteRT。

  • 目前有超過 38 億部裝置搭載 Android 系統。

  • 因此,你可能正在使用許多應用程式,但甚至不知道這些應用程式都是在執行這項服務。

  • 這也相當於每天超過一兆次推論,對吧?

  • 在這種規模下,我們肯定會遇到各種奇怪的晶片組問題,我們已經能夠解決 ROM 問題或 GPU 驅動程式問題,而且我們有專門為您提供的解決方法。

  • Google 也在旗艦應用程式中採用 LiteRT,橫跨多個應用程式、平台,甚至多種裝置。

  • YouTube Shorts 特效、Meet 背景分割、相片修復模糊等,都是在 LiteRT 上執行即時影片和大型圖像模型的例子。

  • 這點也相當重要,因為讓應用情境變得更快速、更吸引使用者,是極為關鍵的一環。

  • 因此,這個執行階段與我們為這些旗艦功能強化的執行階段相同,這也是您透過 Play 服務取得的內容。

在裝置端執行 AI 的優點

  • 接著,我們來談談為什麼要使用裝置端 AI。

  • 如果延遲時間、隱私權、離線運作或低成本對您來說很重要,請離線執行。

  • 可能還有更多原因,但這些是我們聽過最明顯的原因,說明為什麼要在裝置端執行。

  • 在裝置端執行也不一定免費。

  • 不過,這項技術仍有一些細微差異和挑戰。

  • 因此,我們也會探討其中一些挑戰,並為您提供解決方案,對吧?

  • 接著是效能:如您所見,在先前應用程式的例子中,延遲時間和記憶體預算總是吃緊,對吧?

  • 即時影片和音訊需要極高的效率。

  • 即使是簡單的互動功能,也必須快速回應。

  • 否則,使用者參與度會降低。

  • 硬體多樣性:市面上有數百種 SoC,CPU 和 GPU 設定各不相同。

  • 您不可能為所有裝置編寫程式碼,對吧?

  • 該如何解決這些問題?

  • APK 大小:如果搭配原生執行階段,每次下載的檔案大小也會增加,可能會影響轉換率。

  • 自訂:模型訓練、品質、模型大小,這些在部署前都非常重要。

  • 因此,打造出色的裝置端應用程式確實不容易。

  • 不過,在上述所有情況下,我們都希望平台能為您代勞,而不是反過來,對吧?

  • Google 的裝置端產品組合正是為瞭解決這些挑戰而生,我們接下來會詳細介紹。

  • 所以今天我們會著重在兩個簡單的解決方案,對吧?

  • 您可以透過 Play 服務,輕鬆新增裝置端 AI。

  • 路徑 1 是使用 ML Kit 的統包路徑,對吧?

  • 這些是立即可用的視覺和語言 API,只需具備有限的機器學習專業知識,且提供多種模型,全部透過 Play 服務提供。

  • 接下來幾張投影片也會提供一些範例。

  • 自訂路徑,這是透過 LiteRT 進行。

  • LiteRT 可讓您自備模型,並在 CPU、GPU 上執行。

  • 執行階段也來自 Play 服務。

  • 因此,您不需要將其納入 APK。

  • 這些並非二選一。

  • 搭配使用,效果更佳。

  • 這正是我們接下來幾分鐘要建構的內容。

  • 首先,我們來談談 ML Kit 涵蓋的內容。

  • 以下是 ML Kit 現成提供的功能。

  • 因此,如果您認為其中一些功能符合您的需求,這就是一個很好的起點,而且您已經領先一步。

  • 我們涵蓋了視覺、條碼、文件、文字、姿勢等許多功能,以及翻譯、智慧回覆,甚至是實體擷取等語言 API,對吧?

  • 重點是,許多這類視覺和語言 API 都是在 LiteRT 的基礎上運作。

  • 因此,如果 ML Kit 符合您的需求,可以從這裡開始。

  • 如果沒有,您也可以自行提供模型。

  • 重點是,正如我所說,ML Kit 和自訂模型不會是兩個執行階段。

  • 您可以將這兩者視為兩個入口,通往同一個在背景執行的 LiteRT。

  • 因此,LiteRT 將成為 Play 執行階段,負責協調這兩項功能。

  • 因此,如果您的應用程式已使用 Play 商店,請放心使用 ML Kit。

  • 否則,我們也會介紹 LiteRT 路徑。

LiteRT 新功能

  • 接著,我們來看看 LiteRT 的新功能。

  • 如前所述,LiteRT 是 TensorFlow Lite 的進化版。

  • 因此,最大的改進是我們有更快的 GPU。

  • 速度更快的 GPU 支援 OpenCL、OpenGL,甚至支援 Metal 後端等跨平台。

  • 因此,您可以視需要用於多個平台。

  • 也更簡單。

  • 我們提供統一的工作流程,可加速 CPU、GPU 和 NPU。

  • CPU 和 GPU 目前位於 Play 服務中,而 NPU 目前透過 LiteRT 整合,這項工作正在進行中。

  • 所以,以前每個加速器都代表不同的委派設定,對吧?

  • 現在只要執行一次即可。

  • 因此,只要使用一個 API,就能自動切換回 CPU,不必進行專屬委派設定。

  • 您只要呼叫加速器,就能更輕鬆地管理這項作業,而且程式碼更少。

  • 此外,如前所述,同一個模型可在多個平台上執行,功能十分強大。

  • 這點非常重要,也就是彈性。

  • 因此 .tflite 格式保持不變。

  • 如果您已有應用程式,仍可使用這個格式。

  • 如果您要建構新的應用程式,可以再次沿用這個檔案格式。

  • 此外,我們也支援 Interpreter API,這個 API 過去位於 TensorFlow Lite 中。

  • 因此,如果您想分階段遷移,可以使用 Interpreter API,這也是新版 LiteRT 的一部分,可讓您輕鬆遷移。

  • 這就是執行階段。

  • 接著來談談這項技術的應用。

  • 以下是 Android 應用程式目前的建構內容。

  • 從相機特效、相片編輯、智慧輸入、遊戲到虛擬化身,應有盡有,對吧?

  • 許多應用程式都需要即時功能。

  • GPU 會直接從相機傳送影格,因此必須快速即時處理。

  • 部分相片編輯模型也越來越龐大。

  • AR/VR 功能也是如此,正如您在一些眼鏡展示中看到的那樣,許多功能在底層都運行 LiteRT。

  • Google 的旗艦功能和 Play 服務目前都採用這個執行階段,因此您不必在 APK 中綁定任何內容,就能享有上述所有優勢。

  • 現在就來建構應用程式,Fergus 會示範如何操作。

  • 那就開始吧。

  • 感謝您!Chintan 敬上

  • 接下來,我會簡單介紹 Google Play 服務中的 LiteRT 新功能。

  • 在建構之前,還有一項消息:剛才介紹的所有功能,現在不只能在手機上執行,LiteRT in Play 服務也支援 Wear OS 和 Android Automotive OS。

  • 因此,您可以在手錶或其他穿戴式裝置,或車輛本身執行裝置端模型。

  • 過去,您可以在手機上使用 Wear 隨附應用程式,但現在您可以在穿戴式裝置上實際執行該應用程式,Android Automotive 也是如此。

  • 因此,您可以使用相同的 API、相同的 .tflite 模型,但有更多介面。

  • 您不需要為每個板型規格分別導入,只要在所有不同裝置上使用相同的導入方式即可。

  • Play 服務發布模式的優點在於,我們實際上可以將這項功能向後移植,在舊版裝置上執行。

  • 因此,Android Automotive OS 最早支援 2020 年推出的 Android 11,Wear OS 則支援 Wear OS 4 以上版本。

  • 好的。

  • 接下來,我會說明兩種不同的做法:建構新應用程式和升級現有應用程式。

  • 這就是講座其餘部分要探討的內容。

  • 首先,我會介紹一個範例應用程式,結合使用 ML Kit 和在 LiteRT 上執行的自訂 GPU 模型。

  • 如要升級現有應用程式,則需要進行三項小幅調整:修改 Gradle 以更新依附元件、修改 init 以啟用 Play 服務中的 LiteRT,以及從 Interpreter API 切換至 CompiledModel API。

  • 不過,我們會先建立新應用程式,因為您在瞭解升級後的內容後,升級會更有意義。

範例應用程式總覽

  • 所以,建構新的應用程式。

  • 我們要建構的應用程式如下。

  • 這項功能會提供即時相機畫面,讓您保持清晰,並為背景增添藝術風格。

  • 因此,我們會擷取攝影機畫面。

  • 我們會透過 ML Kit 自拍分割功能,串流傳輸相機影格中的圖片。

  • 這是現有的 ML Kit Turnkey API 之一。

  • 這會產生前景遮罩,基本上會指出圖片中的哪些像素對應到圖片中的人物。

  • 接著,我們會使用自訂模型 (類似風格移轉模型),將風格套用至圖片。

  • 我們會將這個樣式套用到整個相機畫面,但我們真正關心的是背景部分,因為最後我們會將原始相機畫面、遮罩和樣式背景,透過一些簡單的邏輯組合起來,這樣我們就能得到一個合成畫面,其中主體保持不變,而背景則具有樣式。

  • 因此,我們希望在現有情況下使用統包 API,並在自訂 API 區分應用程式時使用。

  • 這是第一部分,我們會叫用 ML Kit 自拍分割 API。

    // 1. Configure and create segmenter client
    val segmenter = Segmentation.getClient(
        SelfieSegmenterOptions.Builder()
            .setDetectorMode(
                SelfieSegmenterOptions.STREAM_MODE)
            .build())
    
    // 2. Prepare image & run inference
    fun processFrame(mediaImage: Image) {
      val image = InputImage.fromMediaImage(
          mediaImage, /* rotationDegrees= */ 0)
      segmenter.process(image)
          .addOnSuccessListener { mask -> … }
    }
  • 這就像一般的 API,對吧?

  • 這就像是 Android 開發人員的家常便飯。

  • 只要查看 API 文件,或要求 Gemini 幫忙建構即可。

  • 但其實相當簡單。

  • 建構用戶端時,您會傳入一些選項。

  • 在本例中,我們指定串流模式,以便處理影片影格串流。

  • 接著,您會呼叫這個程序方法,而該方法的回呼會取得自拍分割功能計算後傳回的遮罩。

  • 輸入內容則是相機拍攝的圖片。

  • 所有 API 都使用應用程式層級類型,而非原始張量,因此您實際上是在非常高階的層級進行程式設計,非常簡單。

LiteRT 自訂模型

  • 第二部分是自訂模型,我們會使用 PyTorch 模型。

  • 我想 Chintan 是從 Kaggle 或 Hugging Face 等平台取得這個模型…

  • 好

  • 對,你也可以自行轉換。

  • 您可以自行建構模型。

  • 抱歉,返回。

  • 沒錯,這就是這類堆疊的樣子。

  • 您可以將 PyTorch 模型轉換及量化,取得 LiteRT 模型。

  • 接著,您就可以透過任何方式,將該檔案與應用程式一起發布。

  • 模型可以做為素材資源與應用程式一起打包,也可以單獨下載。

  • 兩種方式都可行。

  • 而這項功能會位於 Play 服務的 LiteRT 執行階段之上。

  • 此外,還有用於在 CPU 上最佳化的 CPU 核心,以及名為 ML Drift 的 GPU 加速器。

  • 沒錯,如我所說,你可以自行訓練 TFLite 模型,也可以尋找現有模型,兩種方式都可行。

  • 只要幾行 Python 程式碼,就能從 PyTorch 轉換。

    import litert_torch
    
    model = my_models.Stylizer().eval()
    
    # Convert with torch.export under the hood
    edge_model = litert_torch.convert(
        model, sample_inputs)
    edge_model.export("stylizer_f32.tflite")
  • 因此,您可以使用 pip 安裝 LiteRT-Torch,呼叫 litert_torch.convert,傳遞一些可以是隨機輸入內容的 sample_inputs,然後匯出 TFLite 檔案。

  • 順帶一提,LiteRT-Torch 是 ai-edge-torch 的新名稱,如果您熟悉這個名稱的話。

  • 量化也同樣非常簡單。

    # Python
    # previously ai_edge_quantizer
    from litert_quantizer import quantizer, recipe
    
    qt = quantizer.Quantizer("stylizer_f32.tflite")
    
    # int8 weights, float activations
    qt.load_quantization_recipe(
        recipe.dynamic_wi8_afp32())
    
    qt.quantize().export_model("stylizer_int8.tflite")
  • 從 LiteRT Quantizer 匯入量化器和配方。

  • 建構量化器時,您會傳入原始浮點模型,並傳入我們建議用於 GPU 的標準配方,該配方使用 8 位元整數權重,但將活化函數保留為 32 位元浮點。

  • 接著,只要呼叫 quantize 和 export_model,即可儲存輸出模型。

  • 這樣一來,您就能執行量化模型,權重會小得多,執行效率也會更高。

使用 CompiledModel API 進行 GPU 加速

  • 沒錯,CompiledModel API 和 GPU 確實是這項技術的亮點。

  • 正如 Chintan 所說,與舊版 TFLite GPU 相比,速度大幅提升。

  • 確切數字會因型號而異,但 1.4 倍是合理的預期。

  • 速度比 CPU 推論快上 10 倍,這就是一大優勢,對吧?

  • 如果您目前使用模型,可能是在 CPU 上執行,因此無法享有 GPU 帶來的 10 倍效能提升。

  • 這確實是一大誘因。

  • 為什麼能快速完成?

  • 我們支援許多功能,例如非同步執行,因此您可以直接傳遞 AHardwareBuffer,或從相機轉譯管道傳遞 OpenGL 緩衝區,直接傳遞至張量緩衝區。

  • 我們支援零複製最佳化,因此在處理低延遲預算時,例如必須在幾十毫秒內處理每個影格,即使只是複製記憶體緩衝區,也可能造成不小的負擔。

  • 因此,如果應用程式對即時性的要求非常高,建議使用零複製最佳化功能,我們也支援這項功能。

  • 此外,正如 Chintan 所說,這項技術支援跨平台,並支援 OpenGL、OpenCL 和 Metal 做為 GPU 後端。

  • 最後,機器學習漂移最佳化工具是開放原始碼,

  • 並依據 Apache 授權提供。

  • Google 最近已將其開放原始碼。

  • 好的,接著是應用程式程式碼。

    // Kotlin
    // Build once, off the main thread.
    private val model: CompiledModel =
        CompiledModel.create(
            context.assets,
            "stylizer_int8.tflite",
            // Simple GPU setup!
            CompiledModel.Options(Accelerator.GPU),
            environment
        )
    
    // Reuse buffers across frames.
    private val inputBuffers  = model.createInputBuffers()
    private val outputBuffers = model.createOutputBuffers()
    
    fun stylize(input: FloatArray): FloatArray {
        inputBuffers[0].writeFloat(input)
        model.run(inputBuffers, outputBuffers) // sync
        return outputBuffers[0].readFloat()
    }
  • 如您所見,這段程式碼相當簡短,而且容易理解。

  • 因此,您只要建立一次模型,就能在每個影格中重複使用。

  • 因此,CompiledModel.create 會傳入 .tflite 檔案。

  • 只要指定要在 GPU 上執行,然後建構輸入和 outputBuffers 即可。

  • 接著,在實際處理每個影格的主迴圈中,呼叫這個 model.run,傳遞輸入和輸出。

  • 寫入 inputBuffers 後,請呼叫 model.run,然後從 outputBuffers 讀取。

  • 好的。

  • 沒錯,只要在該處指定 GPU,就會在 GPU 上執行。

  • 如果同時指定 CPU 和 GPU,系統會嘗試執行 GPU。

  • 如果因任何原因無法使用 GPU,則會改用 CPU。

  • 因此,在某些情況下,CPU 備用方案可能無法為應用程式提供足夠的效率,這時您就會想要使用 GPU,就像這樣。

  • 更常見的做法是使用 CPU 備用機制。

在 Google Play 服務中使用 LiteRT

  • 好的。

  • 因此,我們在建構時綁定了 LiteRT,但尚未採用 Play 服務。

  • 接下來,我會說明如何在 Play 服務中使用 LiteRT。

  • 因此,有三項變更:第一項是依附元件變更。

    // Easier with CompiledModel API: 3 steps
    
    // 1. app/build.gradle: replace litert with play-services-litert
    - implementation 'com.google.ai.edge.litert:litert:...'
    + implementation 'com.google.android.gms:play-services-litert:17.0.0'  // also pulls in litert-api
  • 無論您使用哪種建構系統,只要在 Gradle 檔案或其他位置,找出指定 Maven 套件依附元件的地方,並將其替換掉即可。

  • 移除 litert 依附元件或任何舊版 TensorFlow Lite Maven 套件依附元件,並替換為 play-services-litert。

  • 這也會一併提取 litert-api 套件。

  • 現在,如果您編寫的中介層只想依賴 LiteRT,但不在乎執行階段是來自應用程式還是 Play 服務,則可以只依賴 LiteRT API,並將環境做為輸入參數。

  • 因此,第二個步驟是環境參數。

  • 您可以在這裡提供依附元件插入,基本上就是指定要使用 Play 服務 LiteRT。

  • 因此,您需要匯入 gms.litert.LiteRt,並呼叫初始化函式,傳入背景資訊 (即 Android 活動)。

    // 2. Initialize the LiteRT Environment from Play services (context = your Activity)
    - val environment = Environment.create(...)
    + import com.google.android.gms.litert.LiteRt
    + val environment = LiteRt.initialize(context).await()
    
    // 3. Pass environment whenever you call CompiledModel.create
    
    // That's it! The rest of your app uses the normal CompiledModel APIs from litert-api.
  • 這項作業是非同步的,因此您必須呼叫 .await,或讓其餘部分以回呼為基礎。

  • 最後,只要在呼叫 CompiledModel.create 時傳遞該環境即可。

  • 這樣一來,應用程式就會使用 Play 服務的 LiteRT 執行階段。

  • 以上就是全部內容。

  • 也就是說,應用程式的其他部分會使用 LiteRT API 中完全相同的 LiteRT CompiledModel API。

  • 其餘推論程式碼不會因使用 Play 服務而變更。

  • 而且可以逐步遷移。

  • 您不必一次完成所有作業,可以一次遷移一個元件。

  • 如果應用程式規模較大,建議逐一遷移使用 LiteRT 的元件,並在每次遷移後進行測試。

  • 唯一要注意的是,只有在移除對套裝組合執行階段的最後一個依附元件時,才能節省空間。

  • 此外,請勿混用 Play 服務中的 LiteRT 和套裝 LiteRT。

  • 因此,如果您從 Play 服務中的 LiteRT 取得張量、編譯模型或解譯器,請勿將這些內容傳遞至套裝 LiteRT,反之亦然。

  • 但除此之外,混合這些內容的效果很好。

  • 好的。

  • 以上是建構新應用程式的步驟。

  • 接下來,我會說明如何升級現有應用程式。

  • 因此,您可能已有使用 Interpreter API 的應用程式。

  • 這是我們所謂的舊版 TFLite API,使用解譯器做為主要類別。

  • 左側是使用 Interpreter API 的程式碼,右側則是新的 CompiledModel API 程式碼。

    // Dependencies (Gradle):
    // play-services-tflite-java and/or litert (bundled)
    
    // Init
    TfLite.initialize(context).await()
    
    // Load
    val interpreterOptions =
        InterpreterApi.Options().apply {
          runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
        }
    
    val interpreter =
        InterpreterApi.create(modelFile, interpreterOptions)
    
    // Prepare inputs/outputs
    val inputs = …
    val outputs = …
    
    // Execute
    interpreter.run(inputs, outputs)
    // Dependencies (Gradle):
    // play-services-litert
    
    // Init
    val environment =
      LiteRt.initialize(context).await()
    
    // Load
    val modelOptions = CompiledModel.Options(Accelerator.CPU)
    
    val model =
        CompiledModel.create(modelPath, modelOptions, environment)
    
    // Prepare inputs/outputs
    val inputBuffers = model.createInputBuffers()
    val outputBuffers = model.createOutputBuffers()
    
    // Execute
    model.run(inputBuffers, outputBuffers
  • 因此,只要將 TfLite.initialize 變更為 LiteRt.initialize,現在就會傳回環境。

  • 然後將環境傳遞至 CompiledModel.create。

  • 所以這只是小幅變更,APK 不會變大。

  • 下一張投影片會說明如何使用 GPU,這只是另一個選項。

  • 因此,您需要額外編寫這段程式碼,才能啟用 GPU。

    // Dependencies (Gradle):
    // play-services-tflite-java and/or litert (bundled)
    
    // Init
    val initOptions = TfLiteInitializationOptions.builder()
        .setEnableGpuDelegateSupport(true).build()
    TfLite.initialize(context, initOptions).await()
    val useGpu =
        TfLiteGpu.isGpuDelegateAvailable(context).await()
    
    // Load
    val interpreterOptions =
        InterpreterApi.Options().apply {
          runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
        }
    if (useGpu) {
        interpreterOptions.addDelegateFactory(
            GpuDelegateFactory());
    }
    val interpreter =
        InterpreterApi.create(modelFile, interpreterOptions)
    
    // Prepare inputs/outputs
    val inputs = …
    val outputs = …
    
    // Execute
    interpreter.run(inputs, outputs)
    // Dependencies (Gradle):
    // play-services-litert
    
    // Init
    val initOptions = LiteRtInitializationOptions.builder()
        .setEnableGpu(true).build()
    val environment = LiteRt.initialize(context, initOptions).await()
    
    // Load
    val modelOptions =
        CompiledModel.Options(Accelerator.CPU, Accelerator.GPU)
    
    val model =
        CompiledModel.create(modelPath, modelOptions, environment)
    
    // Prepare inputs/outputs
    val inputBuffers = model.createInputBuffers()
    val outputBuffers = model.createOutputBuffers()
    
    // Execute
    model.run(inputBuffers, outputBuffers)
  • 如您所見,啟用 GPU 的新 API 程式碼比之前的程式碼更簡單。

  • 因此,在 LiteRT 初始化選項中,首次呼叫 setEnableGpu 並傳遞至 LiteRt.initialize 時,系統會將 GPU 加速器的程式碼載入應用程式。

  • 接著,在建構 modelOptions 並傳遞至 CompiledModel.create 時,您會指定特定模型要使用的加速器,以及其他模型是否只在 GPU 上執行、在 GPU 上執行並以 CPU 做為備用,或只在 CPU 上執行。

  • 現在我們來做個小測驗

  • 沒錯,如您所見,使用新版 API 啟用 GPU 簡單多了。

  • 那麼,您實際上能獲得什麼?

  • Chintan 會告訴你。

  • 現在我們來做個小測驗

  • 好的,謝謝 Fergus。

  • 接著來談談,這一切能帶來什麼好處。

  • 還記得我們說過要建構應用程式嗎?現在就來看看實際建構的成果。

  • 總之,這就是我。我們在這裡使用 ML Kit 找到我,因此區隔是由 ML Kit 等統包 API 完成。

  • 所以,這只是找到我的頭。

  • 接著,LiteRT 會使用類似風格移轉的模型,為背景上色。

  • 如前所述,其他好處包括節省約 8 MB 的空間、所有應用程式共用一個執行階段 (或至少像這裡分享的那樣),以及自動更新。此外,GPU 速度更快,在需要即時處理的情況下,每秒可達近 30 個影格,提供豐富的使用者體驗。

  • 更棒的是,您不必手動執行所有操作。

  • 我們最近也推出一項新的 Android 技能,基本上就是 Android LiteRT 技能,只要幾分鐘就能升級裝置端機器學習技術。

  • 因此,您可以執行幾項操作:升級現有應用程式、建構新應用程式,也可以升級應用程式,使用這項新的 Play 服務整合功能。

  • 這些功能都可使用。

  • 連結位於投影片和 GitHub 上,也會顯示在說明文件和網誌中。

  • 所以,如果有人想盡快改用新版,這項資訊應該也很有幫助。

  • Fergus 接下來會說明這項技術的未來發展。

LiteRT 發展藍圖和摘要

  • 因此,我們致力於透過 LiteRT 發展裝置端 AI。

  • 我們持續投入大量資源,改善 GPU 加速和模型涵蓋範圍,並定期更新 LiteRT 2.x,包括開放原始碼套件 LiteRT,以及 Play 服務中的 LiteRT Maven 套件。

  • 我們也會繼續提供回溯相容性。

  • Play 服務執行階段會繼續支援以舊版 SDK 建構的應用程式。

  • 是啊

  • 這對使用者和我們來說都非常重要。

  • LiteRT 1.x SDK 目前處於維護模式,因此只會提供重大安全性修正。

  • 我們在 2024 年淘汰的 NNAPI 也將停用,預計從 2027 年起移除。

  • 因此,如果您有任何使用 NNAPI 的情況,請改用 GPU 加速或 NPU 加速,並搭配 LiteRT。

  • 好的。

  • 是啊

  • 因此,越早改用 2.x 和 CompiledModel,日後要處理的事項就越少。

  • 最後,請記住三個重點。

  • 所以,請開始建構。

  • 建議先從 ML Kit 開始,如果能滿足需求,那就太好了。

  • 如果沒有,請使用 LiteRT 建立自訂模型。

  • 升級至 Google Play 服務中的 LiteRT,即可節省 APK 空間並共用執行階段。

  • 此外,您也可以使用 CompiledModel API,更快速、輕鬆地執行 GPU 推論。

  • 是啊

  • 所有內容都記錄在 AI Edge 的 LiteRT 說明文件網站,網址就在這裡。

  • 所以,

  • 感謝各位參與,我們非常期待看到大家打造的成果。

程式碼

程式碼片段

「範例應用程式總覽」中 15:09 的 Kotlin 程式碼片段
// 1. Configure and create segmenter client
val segmenter = Segmentation.getClient(
    SelfieSegmenterOptions.Builder()
        .setDetectorMode(
            SelfieSegmenterOptions.STREAM_MODE)
        .build())

// 2. Prepare image & run inference
fun processFrame(mediaImage: Image) {
  val image = InputImage.fromMediaImage(
      mediaImage, /* rotationDegrees= */ 0)
  segmenter.process(image)
      .addOnSuccessListener { mask -> … }
}
「LiteRT 自訂模型」影片 17:34 處的 Python 程式碼片段
import litert_torch

model = my_models.Stylizer().eval()

# Convert with torch.export under the hood
edge_model = litert_torch.convert(
    model, sample_inputs)
edge_model.export("stylizer_f32.tflite")
「Custom models on LiteRT」影片 18:04 處的 Python 程式碼片段
# Python
# previously ai_edge_quantizer
from litert_quantizer import quantizer, recipe

qt = quantizer.Quantizer("stylizer_f32.tflite")

# int8 weights, float activations
qt.load_quantization_recipe(
    recipe.dynamic_wi8_afp32())

qt.quantize().export_model("stylizer_int8.tflite")
「GPU acceleration with CompiledModel API」影片 21:06 處的 Kotlin 程式碼片段
// Kotlin
// Build once, off the main thread.
private val model: CompiledModel =
    CompiledModel.create(
        context.assets,
        "stylizer_int8.tflite",
        // Simple GPU setup!
        CompiledModel.Options(Accelerator.GPU),
        environment
    )

// Reuse buffers across frames.
private val inputBuffers  = model.createInputBuffers()
private val outputBuffers = model.createOutputBuffers()

fun stylize(input: FloatArray): FloatArray {
    inputBuffers[0].writeFloat(input)
    model.run(inputBuffers, outputBuffers) // sync
    return outputBuffers[0].readFloat()
}
「在 Google Play 服務中使用 LiteRT」影片 22:36 處的 Groovy 程式碼片段
// Easier with CompiledModel API: 3 steps

// 1. app/build.gradle: replace litert with play-services-litert
- implementation 'com.google.ai.edge.litert:litert:...'
+ implementation 'com.google.android.gms:play-services-litert:17.0.0'  // also pulls in litert-api
「在 Google Play 服務中使用 LiteRT」影片 23:43 處的 Kotlin 程式碼片段
// 2. Initialize the LiteRT Environment from Play services (context = your Activity)
- val environment = Environment.create(...)
+ import com.google.android.gms.litert.LiteRt
+ val environment = LiteRt.initialize(context).await()

// 3. Pass environment whenever you call CompiledModel.create

// That's it! The rest of your app uses the normal CompiledModel APIs from litert-api.
「在 Google Play 服務中使用 LiteRT」影片 25:45 處的 Kotlin 程式碼片段
// Dependencies (Gradle):
// play-services-tflite-java and/or litert (bundled)

// Init
TfLite.initialize(context).await()

// Load
val interpreterOptions =
    InterpreterApi.Options().apply {
      runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
    }

val interpreter =
    InterpreterApi.create(modelFile, interpreterOptions)

// Prepare inputs/outputs
val inputs = …
val outputs = …

// Execute
interpreter.run(inputs, outputs)
「在 Google Play 服務中使用 LiteRT」影片 25:45 處的 Kotlin 程式碼片段
// Dependencies (Gradle):
// play-services-litert

// Init
val environment =
  LiteRt.initialize(context).await()

// Load
val modelOptions = CompiledModel.Options(Accelerator.CPU)

val model =
    CompiledModel.create(modelPath, modelOptions, environment)

// Prepare inputs/outputs
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()

// Execute
model.run(inputBuffers, outputBuffers
「在 Google Play 服務中使用 LiteRT」影片 26:25 處的 Kotlin 程式碼片段
// Dependencies (Gradle):
// play-services-tflite-java and/or litert (bundled)

// Init
val initOptions = TfLiteInitializationOptions.builder()
    .setEnableGpuDelegateSupport(true).build()
TfLite.initialize(context, initOptions).await()
val useGpu =
    TfLiteGpu.isGpuDelegateAvailable(context).await()

// Load
val interpreterOptions =
    InterpreterApi.Options().apply {
      runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
    }
if (useGpu) {
    interpreterOptions.addDelegateFactory(
        GpuDelegateFactory());
}
val interpreter =
    InterpreterApi.create(modelFile, interpreterOptions)

// Prepare inputs/outputs
val inputs = …
val outputs = …

// Execute
interpreter.run(inputs, outputs)
「在 Google Play 服務中使用 LiteRT」影片 26:25 處的 Kotlin 程式碼片段
// Dependencies (Gradle):
// play-services-litert

// Init
val initOptions = LiteRtInitializationOptions.builder()
    .setEnableGpu(true).build()
val environment = LiteRt.initialize(context, initOptions).await()

// Load
val modelOptions =
    CompiledModel.Options(Accelerator.CPU, Accelerator.GPU)

val model =
    CompiledModel.create(modelPath, modelOptions, environment)

// Prepare inputs/outputs
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()

// Execute
model.run(inputBuffers, outputBuffers)