LiteRT menyediakan antarmuka terpadu untuk menggunakan Unit Pemrosesan Neural (NPU) tanpa mengharuskan Anda menavigasi compiler, runtime, atau dependensi library khusus vendor. Penggunaan LiteRT untuk akselerasi NPU meningkatkan performa untuk inferensi real-time dan model besar serta meminimalkan salinan memori melalui penggunaan buffer hardware tanpa salinan.
Mulai
- Untuk model ML klasik, lihat aplikasi demo berikut.
- Aplikasi Kotlin Segmentasi Gambar: memberikan contoh untuk kompilasi AOT dan kompilasi (JIT) di perangkat.
- Aplikasi C++ Segmentasi Asinkron: menunjukkan kompilasi AOT dan kompilasi di perangkat (JIT) dalam aplikasi yang sama.
- Untuk Model Bahasa Besar (LLM), lihat panduan tentang mengeksekusi LLM di NPU menggunakan LiteRT-LM.
Vendor NPU
LiteRT mendukung akselerasi NPU dengan vendor berikut:
Qualcomm AI Engine Direct
- Mendukung AOT dan eksekusi kompilasi di perangkat melalui
CompiledModelAPI. - Lihat Qualcomm AI Engine Direct untuk mengetahui detail penyiapan.
- Lihat Meningkatkan Performa Puncak di NPU Qualcomm dengan LiteRT untuk mengetahui update terbaru.
MediaTek NeuroPilot
- Mendukung AOT dan eksekusi kompilasi di perangkat melalui
CompiledModelAPI. - Lihat MediaTek NeuroPilot untuk mengetahui detail penyiapan.
- Lihat NPU MediaTek dan LiteRT: Mendukung AI di perangkat generasi berikutnya untuk mengetahui update terbaru.
Google Tensor
Google Tensor SDK dalam akses eksperimental. Daftar di sini.
Kompilasi AOT dan di perangkat
NPU LiteRT mendukung kompilasi AOT dan di perangkat untuk memenuhi persyaratan deployment spesifik Anda:
- Kompilasi offline (AOT): Ini paling cocok untuk model besar dan kompleks yang SoC targetnya diketahui. Mengompilasi ahead-of-time secara signifikan mengurangi biaya inisialisasi dan menurunkan penggunaan memori saat pengguna meluncurkan aplikasi Anda.
- Kompilasi online (di perangkat): Juga dikenal sebagai kompilasi JIT. Opsi ini ideal untuk distribusi model kecil yang tidak bergantung pada platform. Model dikompilasi di perangkat pengguna selama inisialisasi, tidak memerlukan langkah persiapan tambahan, tetapi menimbulkan biaya run pertama yang lebih tinggi.
Panduan berikut menunjukkan cara men-deploy untuk kompilasi AOT dan dalam perangkat dalam tiga langkah.
Langkah 1: Kompilasi AOT untuk SoC NPU target
Anda dapat menggunakan Compiler AOT (ahead of time) LiteRT untuk mengompilasi model .tflite ke SoC yang didukung. Anda juga dapat menargetkan beberapa vendor dan versi SoC secara bersamaan dalam satu proses kompilasi. Lihat detail selengkapnya di notebook Kompilasi AOT LiteRT ini. Meskipun bersifat opsional, kompilasi AOT sangat direkomendasikan untuk model yang lebih besar guna mengurangi waktu inisialisasi di perangkat. Langkah ini tidak diperlukan untuk kompilasi di perangkat.
Langkah 2: Deploy dengan Google Play jika menggunakan Android
Di Android, gunakan Play untuk AI di Perangkat (PODAI) Google untuk men-deploy model dan library runtime NPU dengan aplikasi Anda.
- Untuk model kompilasi di perangkat: tambahkan file model .tflite asli langsung ke direktori aset/ aplikasi Anda.
- Lihat contoh penerapan di Aplikasi Kotlin kompilasi dalam perangkat Segmentasi.
- Untuk model kompilasi AOT: gunakan LiteRT untuk mengekspor model yang dikompilasi ke dalam satu Paket AI Play Google.
Kemudian, Anda mengupload paket AI ke Google Play untuk otomatis mengirimkan model yang dikompilasi dengan benar ke perangkat pengguna.
- Lihat notebook Kompilasi AOT LiteRT untuk mengetahui petunjuk tentang cara mengekspor model yang dikompilasi ke dalam Paket AI Play.
- Lihat contoh penerapan di Aplikasi Kotlin kompilasi AOT Segmentasi.
- Untuk library runtime NPU, gunakan Play Feature Delivery untuk mendistribusikan library runtime yang benar ke perangkat pengguna.
Lihat bagian berikut tentang cara men-deploy dengan Paket AI Play dan Play Feature Delivery.
Men-deploy model AOT dengan Play AI Pack
Langkah-langkah berikut akan memandu Anda men-deploy model yang dikompilasi AOT menggunakan Paket AI Play.
Menambahkan Paket AI ke project
Impor Paket AI ke project Gradle dengan menyalin Paket AI ke direktori root project Gradle. Contoh:
my_app/
...
ai_packs/
my_model/...
my_model_mtk/...
Tambahkan setiap Paket AI ke konfigurasi build Gradle:
// my_app/ai_packs/my_model/build.gradle.kts
plugins { id("com.android.ai-pack") }
aiPack {
packName = "my_model" // ai pack dir name
dynamicDelivery { deliveryType = "on-demand" }
}
// Add another build.gradle.kts for my_model_mtk/ as well
Menambahkan Paket AI ke konfigurasi Gradle
Salin device_targeting_configuration.xml dari Paket AI yang dihasilkan ke
direktori modul aplikasi utama. Kemudian, perbarui settings.gradle.kts:
// my_app/setting.gradle.kts
...
// AI Packs
include(":ai_packs:my_model")
include(":ai_packs:my_model_mtk")
Perbarui build.gradle.kts:
// my_app/build.gradle.kts
android {
...
defaultConfig {
...
// API level 31+ is required for NPU support.
minSdk = 31
}
// AI Packs
assetPacks.add(":ai_packs:my_model")
assetPacks.add(":ai_packs:my_model_mtk")
}
Mengonfigurasi Paket AI untuk pengiriman on demand
Pengiriman on-demand memungkinkan Anda meminta model saat runtime, yang berguna jika
model hanya diperlukan untuk alur penggunaan tertentu. Model Anda akan didownload ke ruang penyimpanan internal aplikasi Anda. Dengan fitur Paket AI Android yang dikonfigurasi dalam file build.gradle.kts, periksa kemampuan perangkat.
Lihat juga
petunjuk
untuk pengiriman saat penginstalan dan pengiriman fast-follow dari PODAI.
val env = Environment.create(BuiltinNpuAcceleratorProvider(context))
val modelProvider = AiPackModelProvider(
context, "my_model", "model/my_model.tflite") {
if (NpuCompatibilityChecker.Qualcomm.isDeviceSupported())
setOf(Accelerator.NPU) else setOf(Accelerator.CPU, Accelerator.GPU)
}
val mtkModelProvider = AiPackModelProvider(
context, "my_model_mtk", "model/my_model_mtk.tflite") {
if (NpuCompatibilityChecker.Mediatek.isDeviceSupported())
setOf(Accelerator.NPU) else setOf()
}
val modelSelector = ModelSelector(modelProvider, mtkModelProvider)
val model = modelSelector.selectModel(env)
val compiledModel = CompiledModel.create(
model.getPath(),
CompiledModel.Options(model.getCompatibleAccelerators()),
env,
)
Men-deploy library runtime NPU dengan Play Feature Delivery
Play Feature Delivery mendukung beberapa opsi pengiriman untuk mengoptimalkan ukuran download awal, termasuk pengiriman saat penginstalan, pengiriman on-demand, pengiriman bersyarat, dan pengiriman instan. Di sini, kami menunjukkan panduan penayangan waktu penginstalan dasar.
Menambahkan library runtime NPU ke project
Download litert_npu_runtime_libraries.zip untuk kompilasi AOT atau litert_npu_runtime_libraries_jit.zip untuk kompilasi di perangkat, lalu ekstrak di direktori root project:
my_app/
...
litert_npu_runtime_libraries/
mediatek_runtime/...
qualcomm_runtime_v69/...
qualcomm_runtime_v73/...
qualcomm_runtime_v75/...
qualcomm_runtime_v79/...
qualcomm_runtime_v81/...
fetch_qualcomm_library.sh
Jalankan skrip untuk mendownload library dukungan NPU. Misalnya, jalankan perintah berikut untuk NPU Qualcomm:
$ ./litert_npu_runtime_libraries/fetch_qualcomm_library.sh
Menambahkan library runtime NPU ke konfigurasi Gradle
Salin device_targeting_configuration.xml dari Paket AI yang dihasilkan ke
direktori modul aplikasi utama. Kemudian, perbarui settings.gradle.kts:
// my_app/setting.gradle.kts
...
// NPU runtime libraries
include(":litert_npu_runtime_libraries:runtime_strings")
include(":litert_npu_runtime_libraries:mediatek_runtime")
include(":litert_npu_runtime_libraries:qualcomm_runtime_v69")
include(":litert_npu_runtime_libraries:qualcomm_runtime_v73")
include(":litert_npu_runtime_libraries:qualcomm_runtime_v75")
include(":litert_npu_runtime_libraries:qualcomm_runtime_v79")
include(":litert_npu_runtime_libraries:qualcomm_runtime_v81")
Perbarui build.gradle.kts:
// my_app/build.gradle.kts
android {
...
defaultConfig {
...
// API level 31+ is required for NPU support.
minSdk = 31
// NPU only supports arm64-v8a
ndk { abiFilters.add("arm64-v8a") }
// Needed for Qualcomm NPU runtime libraries
packaging { jniLibs { useLegacyPackaging = true } }
}
// Device targeting
bundle {
deviceTargetingConfig = file("device_targeting_configuration.xml")
deviceGroup {
enableSplit = true // split bundle by #group
defaultGroup = "other" // group used for standalone APKs
}
}
// NPU runtime libraries
dynamicFeatures.add(":litert_npu_runtime_libraries:mediatek_runtime")
dynamicFeatures.add(":litert_npu_runtime_libraries:qualcomm_runtime_v69")
dynamicFeatures.add(":litert_npu_runtime_libraries:qualcomm_runtime_v73")
dynamicFeatures.add(":litert_npu_runtime_libraries:qualcomm_runtime_v75")
dynamicFeatures.add(":litert_npu_runtime_libraries:qualcomm_runtime_v79")
dynamicFeatures.add(":litert_npu_runtime_libraries:qualcomm_runtime_v81")
}
dependencies {
// Dependencies for strings used in the runtime library modules.
implementation(project(":litert_npu_runtime_libraries:runtime_strings"))
...
}
Langkah 3: Inferensi di NPU menggunakan Runtime LiteRT
LiteRT menyederhanakan kompleksitas pengembangan terhadap versi SoC tertentu, sehingga Anda dapat menjalankan model di NPU hanya dengan beberapa baris kode. LiteRT juga menyediakan mekanisme penggantian bawaan yang andal: Anda dapat menentukan CPU, GPU, atau keduanya sebagai opsi, dan LiteRT akan otomatis menggunakannya jika NPU tidak tersedia. Hebatnya, kompilasi AOT juga mendukung penggantian. Delegasi parsial pada NPU memungkinkan subgraf yang tidak didukung berjalan dengan lancar di CPU atau GPU seperti yang ditentukan.
Menjalankan di Kotlin
Lihat contoh penerapan di aplikasi demo berikut:
Menambahkan dependensi Android
Anda dapat menambahkan paket Maven LiteRT terbaru ke dependensi build.gradle:
dependencies {
...
implementation("com.google.ai.edge.litert:litert:+")
}
Integrasi runtime
// 1. Load model and initialize runtime.
// If NPU is unavailable, inference will fallback to GPU.
val model =
CompiledModel.create(
context.assets,
"model/mymodel.tflite",
CompiledModel.Options(Accelerator.NPU, Accelerator.GPU)
)
// 2. Pre-allocate input/output buffers
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()
// 3. Fill the first input
inputBuffers[0].writeFloat(...)
// 4. Invoke
model.run(inputBuffers, outputBuffers)
// 5. Read the output
val outputFloatArray = outputBuffers[0].readFloat()
Menjalankan di C++ lintas platform
Lihat contoh implementasi di Aplikasi C++ segmentasi asinkron.
Dependensi Build Bazel
Pengguna C++ harus membuat dependensi aplikasi dengan akselerasi NPU LiteRT. Aturan cc_binary yang mengemas logika aplikasi inti
(misalnya, main.cc) memerlukan komponen runtime berikut:
- Library bersama LiteRT C API: atribut
dataharus menyertakan library bersama LiteRT C API (//litert/c:litert_runtime_c_api_shared_lib) dan objek bersama pengiriman khusus vendor untuk NPU (//litert/vendors/qualcomm/dispatch:dispatch_api_so). - Library backend khusus NPU: Misalnya, library Qualcomm AI RT (QAIRT) untuk host Android (seperti
libQnnHtp.so,libQnnHtpPrepare.so) dan library Hexagon DSP yang sesuai (libQnnHtpV79Skel.so). Hal ini memastikan bahwa runtime LiteRT dapat memindahkan komputasi ke NPU. - Dependensi atribut: atribut
depsditautkan dengan dependensi waktu kompilasi penting, seperti buffer tensor LiteRT (//litert/cc:litert_tensor_buffer) dan API untuk lapisan pengiriman NPU (//litert/vendors/qualcomm/dispatch:dispatch_api). Hal ini memungkinkan kode aplikasi Anda berinteraksi dengan NPU melalui LiteRT. - File model dan aset lainnya: Disertakan melalui atribut
data.
Penyiapan ini memungkinkan biner yang dikompilasi memuat dan menggunakan NPU secara dinamis untuk inferensi machine learning yang dipercepat.
Menyiapkan lingkungan NPU
Beberapa backend NPU memerlukan dependensi atau library runtime. Saat menggunakan API model yang dikompilasi, LiteRT mengatur persyaratan ini melalui objek Environment.
Gunakan kode berikut untuk menemukan library atau driver NPU yang sesuai:
// Provide a dispatch library directory (following is a hypothetical path) for the NPU
std::vector<Environment::Option> environment_options = {
{
Environment::OptionTag::DispatchLibraryDir,
"/usr/lib64/npu_dispatch/"
}
};
LITERT_ASSIGN_OR_RETURN(auto env, Environment::Create(absl::MakeConstSpan(environment_options)));
Integrasi runtime
Cuplikan kode berikut menunjukkan implementasi dasar seluruh proses di C++:
// 1. Load the model that has NPU-compatible ops
LITERT_ASSIGN_OR_RETURN(auto model, Model::Load("mymodel_npu.tflite"));
// 2. Create a compiled model with NPU acceleration
// See following section on how to set up NPU environment
LITERT_ASSIGN_OR_RETURN(auto compiled_model,
CompiledModel::Create(env, model, kLiteRtHwAcceleratorNpu));
// 3. Allocate I/O buffers
LITERT_ASSIGN_OR_RETURN(auto input_buffers, compiled_model.CreateInputBuffers());
LITERT_ASSIGN_OR_RETURN(auto output_buffers, compiled_model.CreateOutputBuffers());
// 4. Fill model inputs (CPU array -> NPU buffers)
float input_data[] = { /* your input data */ };
input_buffers[0].Write<float>(absl::MakeConstSpan(input_data, /*size*/));
// 5. Run inference
compiled_model.Run(input_buffers, output_buffers);
// 6. Access model output
std::vector<float> data(output_data_size);
output_buffers[0].Read<float>(absl::MakeSpan(data));
Zero-copy dengan akselerasi NPU
Penggunaan zero-copy memungkinkan NPU mengakses data secara langsung di memorinya sendiri tanpa perlu CPU menyalin data tersebut secara eksplisit. Dengan tidak menyalin data ke dan dari memori CPU, salinan nol dapat mengurangi latensi end-to-end secara signifikan.
Kode berikut adalah contoh penerapan NPU Zero-Copy dengan
AHardwareBuffer, yang meneruskan data langsung ke NPU. Implementasi ini menghindari
perjalanan pulang pergi yang mahal ke memori CPU, sehingga mengurangi overhead inferensi secara signifikan.
// Suppose you have AHardwareBuffer* ahw_buffer
LITERT_ASSIGN_OR_RETURN(auto tensor_type, model.GetInputTensorType("input_tensor"));
LITERT_ASSIGN_OR_RETURN(auto npu_input_buffer, TensorBuffer::CreateFromAhwb(
env,
tensor_type,
ahw_buffer,
/* offset = */ 0
));
std::vector<TensorBuffer> input_buffers{npu_input_buffer};
LITERT_ASSIGN_OR_RETURN(auto output_buffers, compiled_model.CreateOutputBuffers());
// Execute the model
compiled_model.Run(input_buffers, output_buffers);
// Retrieve the output (possibly also an AHWB or other specialized buffer)
auto ahwb_output = output_buffers[0].GetAhwb();
Merangkai beberapa inferensi NPU
Untuk pipeline yang kompleks, Anda dapat merangkai beberapa inferensi NPU. Karena setiap langkah menggunakan buffer yang kompatibel dengan akselerator, pipeline Anda sebagian besar tetap berada di memori yang dikelola NPU:
// compiled_model1 outputs into an AHWB
compiled_model1.Run(input_buffers, intermediate_buffers);
// compiled_model2 consumes that same AHWB
compiled_model2.Run(intermediate_buffers, final_outputs);
Penyimpanan dalam cache kompilasi di perangkat NPU
LiteRT mendukung kompilasi .tflite model di perangkat NPU (dikenal sebagai JIT). Kompilasi JIT dapat sangat berguna dalam situasi ketika mengompilasi model sebelumnya tidak memungkinkan.
Namun, kompilasi JIT dapat menimbulkan beberapa latensi dan overhead memori untuk menerjemahkan model yang disediakan pengguna ke dalam petunjuk bytecode NPU sesuai permintaan. Untuk meminimalkan dampak performa, artefak kompilasi NPU dapat di-cache.
Jika caching diaktifkan, LiteRT hanya akan memicu kompilasi ulang model jika diperlukan, misalnya:
- Versi plugin compiler NPU vendor berubah;
- Sidik jari build Android berubah;
- Model yang disediakan pengguna berubah;
- Opsi kompilasi berubah.
Untuk mengaktifkan penyimpanan ke dalam cache kompilasi NPU, tentukan tag lingkungan CompilerCacheDir di opsi lingkungan. Nilai harus ditetapkan ke jalur aplikasi yang dapat ditulis yang ada.
const std::array environment_options = {
litert::Environment::Option{
/*.tag=*/litert::Environment::OptionTag::CompilerPluginLibraryDir,
/*.value=*/kCompilerPluginLibSearchPath,
},
litert::Environment::Option{
litert::Environment::OptionTag::DispatchLibraryDir,
kDispatchLibraryDir,
},
// 'kCompilerCacheDir' will be used to store NPU-compiled model
// artifacts.
litert::Environment::Option{
litert::Environment::OptionTag::CompilerCacheDir,
kCompilerCacheDir,
},
};
// Create an environment.
LITERT_ASSERT_OK_AND_ASSIGN(
auto environment, litert::Environment::Create(environment_options));
// Load a model.
auto model_path = litert::testing::GetTestFilePath(kModelFileName);
LITERT_ASSERT_OK_AND_ASSIGN(auto model,
litert::Model::CreateFromFile(model_path));
// Create a compiled model, which only triggers NPU compilation if
// required.
LITERT_ASSERT_OK_AND_ASSIGN(
auto compiled_model, litert::CompiledModel::Create(
environment, model, kLiteRtHwAcceleratorNpu));
Contoh penghematan latensi dan memori:
Waktu dan memori yang diperlukan untuk kompilasi NPU dapat bervariasi berdasarkan beberapa faktor, seperti chip NPU yang mendasarinya, kompleksitas model input, dll.
Tabel berikut membandingkan waktu inisialisasi runtime dan konsumsi memori saat kompilasi NPU diperlukan dan saat kompilasi dapat dilewati karena adanya caching. Di salah satu perangkat contoh, kita mendapatkan hal berikut:
| Model TFLite | inisialisasi model dengan kompilasi NPU | inisialisasi model dengan kompilasi yang di-cache | jejak memori init dengan kompilasi NPU | menginisialisasi memori dengan kompilasi yang di-cache |
|---|---|---|---|---|
| torchvision_resnet152.tflite | 7465,22 md | 198,34 md | 1525,24 MB | 355,07 MB |
| torchvision_lraspp_mobilenet_v3_large.tflite | 1.592,54 md | 166,47 md | 254,90 MB | 33,78 MB |
Di perangkat lain, kami mendapatkan hal berikut:
| Model TFLite | inisialisasi model dengan kompilasi NPU | inisialisasi model dengan kompilasi yang di-cache | jejak memori init dengan kompilasi NPU | menginisialisasi memori dengan kompilasi yang di-cache |
|---|---|---|---|---|
| torchvision_resnet152.tflite | 2766,44 md | 379,86 md | 653,54 MB | 501,21 MB |
| torchvision_lraspp_mobilenet_v3_large.tflite | 784,14 md | 231,76 md | 113,14 MB | 67,49 MB |