LiteRT, satıcıya özel derleyiciler, çalışma zamanları veya kitaplık bağımlılıkları arasında gezinmek zorunda kalmadan sinirsel işlem birimlerini (NPU'lar) kullanmak için birleşik bir arayüz sağlar. NPU hızlandırması için LiteRT kullanmak, gerçek zamanlı ve büyük model çıkarımı için performansı artırır ve sıfır kopyalı donanım arabellek kullanımı sayesinde bellek kopyalarını en aza indirir.
Başlayın
Başlamak için NPU'ya genel bakış kılavuzuna göz atın:
- Klasik makine öğrenimi modelleri için dönüşüm, derleme ve dağıtım adımları hakkında bilgi edinmek için aşağıdaki bölümleri inceleyin.
- Büyük Dil Modelleri (LLM'ler) için LiteRT-LM çerçevemizi kullanın:
NPU desteğiyle LiteRT'nin örnek uygulamaları için aşağıdaki demo uygulamalarına bakın:
NPU Tedarikçileri
LiteRT, aşağıdaki tedarikçilerle NPU hızlandırmayı destekler:
Qualcomm AI Engine Direct
- AOT ve cihaz üzerinde derleme yürütme yolları, Compiled Model API aracılığıyla desteklenir.
- Kurulum ayrıntıları için Qualcomm AI Engine Direct başlıklı makaleyi inceleyin.
MediaTek NeuroPilot
- AOT ve JIT yürütme yolları, Compiled Model API aracılığıyla desteklenir.
- Kurulum ayrıntıları için MediaTek NeuroPilot başlıklı makaleyi inceleyin.
NPU için modelleri dönüştürme ve derleme
LiteRT ile NPU hızlandırmayı kullanmak için modellerin LiteRT dosya biçimine dönüştürülmesi ve cihaz üzerinde NPU kullanımı için derlenmesi gerekir. Modelleri, derlenmiş modellerinizi cihaz hedefleme yapılandırmalarıyla birlikte paketleyen bir yapay zeka paketine derlemek için LiteRT AOT (önceden derleme) derleyicisini kullanabilirsiniz. Bu işlem, modellerin belirli SoC'ler için donatılıp donatılmadığına veya optimize edilip edilmediğine bağlı olarak cihazlara doğru şekilde sunulup sunulmadığını doğrular.
Modelleri dönüştürüp derledikten sonra, Play for On-device AI (PODAI)'yı kullanarak modelleri Google Play'e yükleyebilir ve On-Demand AI çerçevesi aracılığıyla cihazlara dağıtabilirsiniz.
NPU için modelleri dönüştürme ve derleme konusunda uçtan uca bir kılavuz için LiteRT AOT derleme not defterini kullanın.
[Yalnızca AOT] Play Yapay Zeka Paketi ile dağıtma
Modeli dönüştürüp bir yapay zeka paketi derledikten sonra, yapay zeka paketini Google Play ile dağıtmak için aşağıdaki adımları uygulayın.
AI Pack'leri Gradle projesine aktarma
Yapay zeka paketlerini Gradle projesinin kök dizinine kopyalayın. Örneğin:
my_app/
...
ai_packs/
my_model/...
my_model_mtk/...
Her bir Yapay Zeka Paketini Gradle derleme yapılandırmasına ekleyin:
// 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
NPU çalışma zamanı kitaplıklarını projeye ekleme
AOT için litert_npu_runtime_libraries.zip, JIT için litert_npu_runtime_libraries_jit.zip dosyasını indirip projenin kök dizininde açın:
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
NPU destek kitaplıklarını indirmek için komut dosyasını çalıştırın. Örneğin, Qualcomm NPU'lar için aşağıdakileri çalıştırın:
$ ./litert_npu_runtime_libraries/fetch_qualcomm_library.sh
Gradle yapılandırmasına yapay zeka paketleri ve NPU çalışma zamanı kitaplıkları ekleme
Oluşturulan yapay zeka paketlerinden device_targeting_configuration.xml öğesini ana uygulama modülünün dizinine kopyalayın. Ardından settings.gradle.kts öğesini güncelleyin:
// my_app/setting.gradle.kts
...
// [AOT only]
// AI Packs
include(":ai_packs:my_model")
include(":ai_packs:my_model_mtk")
// 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")
build.gradle.kts adresini güncelleyin:
// 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
}
}
// [AOT Only]
// AI Packs
assetPacks.add(":ai_packs:my_model")
assetPacks.add(":ai_packs:my_model_mtk")
// 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"))
...
}
[Yalnızca AOT] İsteğe bağlı dağıtımı kullanma
build.gradle.kts dosyasında Android Yapay Zeka Paketi özelliği yapılandırılmışken,
cihaz özelliklerini kontrol edin ve uygun cihazlarda NPU'yu kullanın. Yedek olarak GPU ve CPU'yu kullanın:
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,
)
JIT modu için CompiledModel oluşturma
val env = Environment.create(BuiltinNpuAcceleratorProvider(context))
val compiledModel = CompiledModel.create(
"model/my_model.tflite",
CompiledModel.Options(Accelerator.NPU),
env,
)
Kotlin'de LiteRT kullanarak NPU'da çıkarım
NPU hızlandırıcıyı kullanmaya başlamak için Derlenmiş Model'i (CompiledModel) oluştururken NPU parametresini iletin.
Aşağıdaki kod snippet'inde, tüm sürecin Kotlin'deki temel uygulaması gösterilmektedir:
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()
inputBuffers[0].writeFloat(FloatArray(data_size) { data_value })
model.run(inputBuffers, outputBuffers)
val outputFloatArray = outputBuffers[0].readFloat()
inputBuffers.forEach { it.close() }
outputBuffers.forEach { it.close() }
model.close()
C++'ta LiteRT kullanarak NPU'da çıkarım
Derleme bağımlılıkları
C++ kullanıcıları, uygulamanın bağımlılıklarını LiteRT NPU hızlandırmasıyla oluşturmalıdır. Temel uygulama mantığını paketleyen cc_binary kuralı
(ör. main.cc) için aşağıdaki çalışma zamanı bileşenleri gerekir:
- LiteRT C API paylaşılan kitaplığı:
dataözelliği, LiteRT C API paylaşılan kitaplığını (//litert/c:litert_runtime_c_api_shared_lib) ve NPU için tedarikçiye özel dağıtım paylaşılan nesnesini (//litert/vendors/qualcomm/dispatch:dispatch_api_so) içermelidir. - NPU'ya özel arka uç kitaplıkları: Örneğin, Android ana makinesi için Qualcomm AI RT (QAIRT) kitaplıkları (
libQnnHtp.so,libQnnHtpPrepare.sogibi) ve ilgili Hexagon DSP kitaplığı (libQnnHtpV79Skel.so). Bu, LiteRT çalışma zamanının hesaplamaları NPU'ya aktarabilmesini sağlar. - Özellik bağımlılıkları:
depsözelliği, LiteRT'nin tensör arabelleği (//litert/cc:litert_tensor_buffer) ve NPU dağıtım katmanının API'si (//litert/vendors/qualcomm/dispatch:dispatch_api) gibi temel derleme zamanı bağımlılıklarına karşı bağlantı oluşturur. Bu, uygulama kodunuzun LiteRT aracılığıyla NPU ile etkileşim kurmasını sağlar. - Model dosyaları ve diğer öğeler:
dataözelliği aracılığıyla eklenir.
Bu kurulum, derlenmiş ikilinizin hızlandırılmış makine öğrenimi çıkarımı için NPU'yu dinamik olarak yüklemesine ve kullanmasına olanak tanır.
NPU ortamı ayarlama
Bazı NPU arka uçları, çalışma zamanı bağımlılıkları veya kitaplıklar gerektirir. Derlenmiş model API'si kullanılırken LiteRT, bu gereksinimleri bir Environment nesnesi aracılığıyla düzenler.
Uygun NPU kitaplıklarını veya sürücülerini bulmak için aşağıdaki kodu kullanın:
// 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)));
Çalışma zamanı entegrasyonu
Aşağıdaki kod snippet'inde, tüm sürecin C++'taki temel uygulaması gösterilmektedir:
// 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));
NPU hızlandırmasıyla sıfır kopyalama
Sıfır kopyalama, NPU'nun verileri doğrudan kendi belleğinde erişmesini sağlar. Bu durumda CPU'nun verileri açıkça kopyalaması gerekmez. Verileri CPU belleğine ve CPU belleğinden kopyalamayarak sıfır kopyalama, uçtan uca gecikmeyi önemli ölçüde azaltabilir.
Aşağıdaki kod, verileri doğrudan NPU'ya aktararak AHardwareBuffer ile Sıfır Kopyalı NPU'nun örnek bir uygulamasıdır. Bu uygulama, CPU belleğine yapılan pahalı gidiş-gelişleri önleyerek çıkarım yükünü önemli ölçüde azaltır.
// 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();
Birden fazla NPU çıkarımını zincirleme
Karmaşık işlem hatları için birden fazla NPU çıkarımını zincirleyebilirsiniz. Her adımda hızlandırıcı dostu bir arabellek kullanıldığından işlem hattınız büyük ölçüde NPU tarafından yönetilen bellekte kalır:
// 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);
NPU anında derleme önbelleğe alma
LiteRT, .tflite modellerinin NPU just-in-time (JIT) derlemesini destekler. JIT derlemesi, özellikle modelin önceden derlenmesinin mümkün olmadığı durumlarda yararlı olabilir.
Ancak JIT derlemesi, kullanıcı tarafından sağlanan modeli isteğe bağlı olarak NPU bayt kodu talimatlarına çevirmek için bir miktar gecikme ve bellek ek yüküyle birlikte gelebilir. Performans etkisini en aza indirmek için NPU derleme yapıları önbelleğe alınabilir.
Önbelleğe alma etkinleştirildiğinde LiteRT, modelin yeniden derlenmesini yalnızca gerektiğinde tetikler. Örneğin:
- Sağlayıcının NPU derleyici eklentisinin sürümü değiştiyse;
- Android derleme parmak izi değiştiyse,
- Kullanıcı tarafından sağlanan model değiştiyse;
- Derleme seçenekleri değişti.
NPU derleme önbelleğini etkinleştirmek için ortam seçeneklerinde CompilerCacheDir
ortam etiketini belirtin. Değer, uygulamanın mevcut bir yazılabilir yolu olarak ayarlanmalıdır.
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));
Örnek gecikme ve bellek tasarrufu:
NPU derlemesi için gereken süre ve bellek, temel alınan NPU çipi ve giriş modelinin karmaşıklığı gibi çeşitli faktörlere bağlı olarak değişebilir.
Aşağıdaki tabloda, NPU derlemesi gerektiğinde ve önbelleğe alma nedeniyle derlemenin atlanabildiği durumlarda çalışma zamanı başlatma süresi ve bellek tüketimi karşılaştırılmaktadır. Bir örnek cihazda şunları elde ederiz:
| TFLite modeli | NPU derlemesiyle model başlatma | model init with cached compilation | NPU derlemesiyle başlatılan bellek alanı | init memory with cached compilation |
|---|---|---|---|---|
| torchvision_resnet152.tflite | 7465,22 ms | 198,34 ms | 1525,24 MB | 355,07 MB |
| torchvision_lraspp_mobilenet_v3_large.tflite | 1592,54 ms | 166,47 ms | 254,90 MB | 33,78 MB |
Başka bir cihazda aşağıdaki bilgileri alırız:
| TFLite modeli | NPU derlemesiyle model başlatma | model init with cached compilation | NPU derlemesiyle başlatılan bellek alanı | init memory with cached compilation |
|---|---|---|---|---|
| torchvision_resnet152.tflite | 2766,44 ms | 379,86 ms | 653,54 MB | 501,21 MB |
| torchvision_lraspp_mobilenet_v3_large.tflite | 784,14 ms | 231,76 ms | 113,14 MB | 67,49 MB |