不必再為了兼顧即插即用 AI 的便利性和自訂模型的彈性而煩惱,您可以在單一超精簡應用程式中部署這兩者,而不會增加數 MB 的二進位檔。
在這場講座中,我們將示範如何在單一 Android 應用程式中建構這種雙堆疊架構。您將瞭解如何運用 ML Kit 執行現成的傳統機器學習工作 (例如掃描文件),並在 Play 服務中搭配使用 LiteRT 獨立版,處理自訂電腦視覺或音訊工作負載。我們將深入探討這兩種實作路徑如何整合,運用現代 LiteRT 執行階段,讓應用程式在 CPU 和 GPU 上享有流暢的硬體加速效能,且下載體積幾乎為零。
開發人員重點摘要:
- 效能不打折:無論是現成或自訂模型,都能透過統一的 CompiledModel API 自動進行硬體加速。
- 微型 APK:將 ML Kit 和 LiteRT 執行階段卸載至 Play 服務,大幅縮減應用程式的下載大小。
- 混合整合:掌握在正式環境中並行執行多個機器學習工作流程,避免資源衝突。
play-services-litert,呼叫 LiteRt.initialize 取得環境,然後將環境傳遞至 CompiledModel.create。轉錄稿
各位晚安。
講座即將開始。
因此,現在人們提到「裝置端 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。
如果延遲時間、隱私權、離線運作或低成本對您來說很重要,請離線執行。
可能還有更多原因,但這些是我們聽過最明顯的原因,說明為什麼要在裝置端執行。
在裝置端執行也不一定免費。
不過,這項技術仍有一些細微差異和挑戰。
因此,我們也會探討其中一些挑戰,並為您提供解決方案,對吧?
接著是效能:如您所見,在先前應用程式的例子中,延遲時間和記憶體預算總是吃緊,對吧?
即時影片和音訊需要極高的效率。
即使是簡單的互動功能,也必須快速回應。
否則,使用者參與度會降低。
硬體多樣性:市面上有數百種 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 是 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 都使用應用程式層級類型,而非原始張量,因此您實際上是在非常高階的層級進行程式設計,非常簡單。
第二部分是自訂模型,我們會使用 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 確實是這項技術的亮點。
正如 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 備用機制。
好的。
因此,我們在建構時綁定了 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 發展裝置端 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 說明文件網站,網址就在這裡。
所以,
感謝各位參與,我們非常期待看到大家打造的成果。
// 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 -> … }
}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")# 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")// 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()
}// 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// 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.// 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// 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)