LiteRT के साथ NPU ऐक्सेलरेट करना

LiteRT, न्यूरल प्रोसेसिंग यूनिट (एनपीयू) का इस्तेमाल करने के लिए एक यूनीफ़ाइड इंटरफ़ेस उपलब्ध कराता है. इसके लिए, आपको वेंडर के हिसाब से कंपाइलर, रनटाइम या लाइब्रेरी डिपेंडेंसी के लिए अनुरोध करने की ज़रूरत नहीं होती. एनपीयू की मदद से परफ़ॉर्मेंस को बेहतर बनाने के लिए, LiteRT का इस्तेमाल करने से रीयल-टाइम और बड़े मॉडल के इन्फ़रेंस की परफ़ॉर्मेंस बेहतर होती है. साथ ही, ज़ीरो-कॉपी हार्डवेयर बफ़र का इस्तेमाल करके, मेमोरी कॉपी को कम किया जा सकता है.

शुरू करें

क्लासिक एमएल मॉडल

क्लासिक एमएल मॉडल के लिए, ये डेमो ऐप्लिकेशन देखें.

जनरेटिव एआई मॉडल

जनरेटिव एआई मॉडल के लिए, ये डेमो और गाइड देखें:

एनपीयू वेंडर

LiteRT, इन वेंडर के एनपीयू की मदद से परफ़ॉर्मेंस को बेहतर बनाने की सुविधा देता है:

Google Tensor

  • CompiledModel एपीआई की मदद से, AOT एक्ज़ीक्यूशन की सुविधा.
  • सेटअप की जानकारी के लिए, Google Tensor देखें.

Qualcomm AI Engine Direct

MediaTek NeuroPilot

Intel OpenVino

  • CompiledModel एपीआई की मदद से, AOT और ऑन-डिवाइस कंपाइलेशन एक्ज़ीक्यूशन की सुविधा.
  • सेटअप की जानकारी के लिए, Intel OpenVino देखें.

AOT और ऑन-डिवाइस कंपाइलेशन

LiteRT NPU, डिप्लॉयमेंट की आपकी ज़रूरतों को पूरा करने के लिए, AOT और ऑन-डिवाइस कंपाइलेशन, दोनों की सुविधा देता है:

  • ऑफ़लाइन (AOT) कंपाइलेशन: यह बड़े और जटिल मॉडल के लिए सबसे सही है इसमें टारगेट SoC की जानकारी होती है. AOT कंपाइलेशन से, शुरुआती लागत काफ़ी कम हो जाती है. साथ ही, जब उपयोगकर्ता आपका ऐप्लिकेशन लॉन्च करता है, तो मेमोरी का इस्तेमाल भी कम होता है.
  • ऑनलाइन (ऑन-डिवाइस) कंपाइलेशन: इसे JIT कंपाइलेशन भी कहा जाता है. यह छोटे मॉडल के प्लैटफ़ॉर्म-अग्नोस्टिक मॉडल डिस्ट्रिब्यूशन के लिए सबसे सही है. मॉडल को शुरुआती प्रोसेस के दौरान, उपयोगकर्ता के डिवाइस पर कंपाइल किया जाता है. इसके लिए, किसी अतिरिक्त तैयारी की ज़रूरत नहीं होती. हालांकि, पहली बार रन करने पर ज़्यादा लागत लगती है.

AOT या ऑन-डिवाइस कंपाइलेशन, दोनों विकल्पों का इस्तेमाल करके, अपने मॉडल को डिप्लॉय करने का तरीका यहां बताया गया है:

पहला चरण: टारगेट एनपीयू SoC के लिए AOT कंपाइलेशन

अपने .tflite मॉडल को, काम करने वाले SoCs पर कंपाइल करने के लिए, LiteRT AOT (ahead of time) कंपाइलर का इस्तेमाल किया जा सकता है. एक ही कंपाइलेशन प्रोसेस में, एक साथ कई SoC वेंडर और वर्शन को टारगेट किया जा सकता है. ज़्यादा जानकारी के लिए, इस LiteRT AOT कंपाइलेशन नोटबुक देखें. बड़े मॉडल के लिए, AOT कंपाइलेशन का इस्तेमाल करने का सुझाव दिया जाता है. इससे डिवाइस पर शुरुआती प्रोसेस में लगने वाला समय कम हो जाता है. हालांकि, यह ज़रूरी नहीं है. ऑन-डिवाइस कंपाइलेशन के लिए, इस चरण को पूरा करने की ज़रूरत नहीं है.

दूसरा चरण: Android पर होने पर, Google Play की मदद से डिप्लॉय करना

Android पर, मॉडल और एनपीयू रनटाइम लाइब्रेरी को अपने ऐप्लिकेशन के साथ डिप्लॉय करने के लिए, ऑन-डिवाइस एआई (PODAI) के लिए Google Play का इस्तेमाल करें.

Play AI Pack और Play Feature Delivery की मदद से डिप्लॉय करने के तरीके के बारे में जानने के लिए, ये सेक्शन देखें.

Play AI Pack की मदद से, AOT मॉडल डिप्लॉय करना

Play AI Pack की मदद से, AOT कंपाइल किए गए मॉडल डिप्लॉय करने के लिए, यह तरीका अपनाएं.

प्रोजेक्ट में AI Pack जोड़ना

Gradle प्रोजेक्ट में AI Pack इंपोर्ट करने के लिए, AI Pack(s) को Gradle प्रोजेक्ट की रूट डायरेक्ट्री में कॉपी करें. उदाहरण के लिए:

my_app/
    ...
    ai_packs/
        my_model/...
        my_model_mtk/...

हर AI Pack को 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

Gradle कॉन्फ़िगरेशन में AI Pack जोड़ना

जनरेट किए गए AI Pack से, device_targeting_configuration.xml को मुख्य ऐप्लिकेशन मॉड्यूल की डायरेक्ट्री में कॉपी करें. इसके बाद, settings.gradle.kts को अपडेट करें:

// my_app/setting.gradle.kts

...
// AI Packs
include(":ai_packs:my_model")
include(":ai_packs:my_model_mtk")

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")
}

ऑन-डिमांड डिलीवरी के लिए AI Pack कॉन्फ़िगर करना

ऑन-डिमांड डिलीवरी की मदद से, रनटाइम के दौरान मॉडल का अनुरोध किया जा सकता है. यह तब काम आता है, जब मॉडल की ज़रूरत सिर्फ़ कुछ उपयोगकर्ता-फ़्लो के लिए होती है. आपका मॉडल, आपके ऐप्लिकेशन के इंटरनल स्टोरेज स्पेस में डाउनलोड हो जाएगा. build.gradle.kts फ़ाइल में कॉन्फ़िगर की गई, Android AI Pack की सुविधा के साथ, डिवाइस की क्षमताओं की जांच करें. PODAI से निर्देश के लिए इंस्टॉल-टाइम डिलीवरी और फ़ास्ट-फ़ॉलो डिलीवरी भी देखें.

val env = Environment.create(BuiltinNpuAcceleratorProvider(context))

val cpuGpuModelProvider =
      ModelProvider.staticModel(
        ModelProvider.Type.ASSET,
        "model/my_model_cpu_gpu.tflite",
        if (accelerator != Accelerator.NPU) accelerator else Accelerator.CPU,
      )

val qualcommNpuModelProvider =
  AiPackModelProvider(context, "my_model", "model/my_model.tflite")
  {
    buildSet {
      if (
        accelerator == Accelerator.NPU && NpuCompatibilityChecker.Qualcomm.isDeviceSupported()
      )
        add(Accelerator.NPU)
    }
  }

val mtkNpuModelProvider =
  AiPackModelProvider(context, "my_model_mtk", "model/my_model.tflite")
  {
    buildSet {
      if (
        accelerator == Accelerator.NPU && NpuCompatibilityChecker.Mediatek.isDeviceSupported()
      )
        add(Accelerator.NPU)
    }
  }

val googleTensorTpuModelProvider =
  AiPackModelProvider(context, "my_model", "model/my_model.tflite")
  {
    buildSet {
      if (accelerator == Accelerator.NPU &&
          NpuCompatibilityChecker.GoogleTensor.isDeviceSupported()
      )
        add(Accelerator.NPU)
    }
  }

val aiPackModelProvider =
        ModelSelector(cpuGpuModelProvider, mtkNpuModelProvider, qualcommNpuModelProvider, googleTensorTpuModelProvider)
          .selectModel(env)

val compiledModel = CompiledModel.create(
    model.getPath(),
    CompiledModel.Options(model.getCompatibleAccelerators()),
    env,
)

Play Feature Delivery की मदद से, एनपीयू रनटाइम लाइब्रेरी डिप्लॉय करना

Play Feature Delivery शुरुआती डाउनलोड साइज़ को ऑप्टिमाइज़ करने के लिए, डिलीवरी के कई विकल्प उपलब्ध कराता है. इनमें इंस्टॉल-टाइम डिलीवरी, ऑन-डिमांड डिलीवरी, कंडीशनल डिलीवरी, और इंस्टैंट डिलीवरी शामिल हैं. यहां, इंस्टॉल-टाइम डिलीवरी के लिए बुनियादी गाइड दिखाई गई है.

प्रोजेक्ट में एनपीयू रनटाइम लाइब्रेरी जोड़ना

AOT कंपाइलेशन के लिए, सबसे नए वर्शन से litert_npu_runtime_libraries.zip या ऑन-डिवाइस कंपाइलेशन के लिए, सबसे नए वर्शन से litert_npu_runtime_libraries_jit.zip डाउनलोड करें. इसके बाद, इसे प्रोजेक्ट की रूट डायरेक्ट्री में अनपैक करें:

my_app/
    ...
    litert_npu_runtime_libraries/
        google_tensor_runtime/...
        mediatek_runtime/...
        qualcomm_runtime_v69/...
        qualcomm_runtime_v73/...
        qualcomm_runtime_v75/...
        qualcomm_runtime_v79/...
        qualcomm_runtime_v81/...
        fetch_qualcomm_library.sh

एनपीयू सपोर्ट लाइब्रेरी डाउनलोड करने के लिए, स्क्रिप्ट चलाएं. उदाहरण के लिए, Qualcomm एनपीयू के लिए यह स्क्रिप्ट चलाएं:

$ ./litert_npu_runtime_libraries/fetch_qualcomm_library.sh

Gradle कॉन्फ़िगरेशन में एनपीयू रनटाइम लाइब्रेरी जोड़ना

जनरेट किए गए AI Pack से, device_targeting_configuration.xml को मुख्य ऐप्लिकेशन मॉड्यूल की डायरेक्ट्री में कॉपी करें. इसके बाद, settings.gradle.kts को अपडेट करें:

// my_app/setting.gradle.kts

...
// NPU runtime libraries
include(":litert_npu_runtime_libraries:runtime_strings")
include(":litert_npu_runtime_libraries:google_tensor_runtime")
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 को अपडेट करें:

// 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:google_tensor_runtime")
  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"))
  ...
}

तीसरा चरण: LiteRT रनटाइम का इस्तेमाल करके, एनपीयू पर इन्फ़रेंस करना

LiteRT, SoC के खास वर्शन के लिए डेवलपमेंट की जटिलता को कम करता है. इससे, कुछ लाइनों का कोड लिखकर, एनपीयू पर अपना मॉडल चलाया जा सकता है. यह एक मज़बूत, इन-बिल्ट फ़ॉलबैक मैकेनिज़्म भी उपलब्ध कराता है: सीपीयू, जीपीयू या दोनों को विकल्प के तौर पर तय किया जा सकता है. अगर एनपीयू उपलब्ध नहीं है, तो LiteRT अपने-आप इनका इस्तेमाल करेगा. AOT कंपाइलेशन में भी फ़ॉलबैक की सुविधा मिलती है. यह एनपीयू पर पार्शियल डेलिगेशन की सुविधा देता है. इसमें, काम न करने वाले सबग्राफ़, तय किए गए तरीके के मुताबिक, सीपीयू या जीपीयू पर आसानी से रन होते हैं.

Kotlin में रन करना

उदाहरण के लिए, इन डेमो ऐप्लिकेशन में, इसे लागू करने का तरीका देखें:

Android डिपेंडेंसी जोड़ना

अपने build.gradle डिपेंडेंसी में, LiteRT Maven पैकेज का नया वर्शन जोड़ा जा सकता है:

dependencies {
  ...
  implementation("com.google.ai.edge.litert:litert:+")
}

रनटाइम इंटिग्रेशन

// 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()

C++ क्रॉस-प्लैटफ़ॉर्म में रन करना

उदाहरण के लिए, एसिंक्रोनस सेगमेंटेशन C++ ऐप्लिकेशन में, इसे लागू करने का तरीका देखें.

Bazel बिल्ड डिपेंडेंसी

C++ का इस्तेमाल करने वाले लोगों या कंपनियों को, LiteRT NPU की मदद से परफ़ॉर्मेंस को बेहतर बनाने के लिए, ऐप्लिकेशन की डिपेंडेंसी बनानी होंगी. cc_binary नियम, कोर ऐप्लिकेशन लॉजिक (जैसे, main.cc) को पैकेज करता है. इसके लिए, रनटाइम के इन कॉम्पोनेंट की ज़रूरत होती है:

  • LiteRT C API शेयर की गई लाइब्रेरी: data एट्रिब्यूट में, LiteRT C API शेयर की गई लाइब्रेरी (//litert/c:litert_runtime_c_api_shared_lib) और एनपीयू के लिए, वेंडर के हिसाब से डिस्पैच शेयर किया गया ऑब्जेक्ट (//litert/vendors/qualcomm/dispatch:dispatch_api_so) शामिल होना चाहिए.
  • एनपीयू के हिसाब से बैकएंड लाइब्रेरी: उदाहरण के लिए, Android होस्ट के लिए Qualcomm AI RT (QAIRT) लाइब्रेरी (जैसे, libQnnHtp.so, libQnnHtpPrepare.so) और उससे जुड़ी Hexagon DSP लाइब्रेरी (libQnnHtpV79Skel.so). इससे यह पक्का होता है कि LiteRT रनटाइम, एनपीयू पर कंप्यूटेशन को ऑफ़लोड कर सकता है.
  • एट्रिब्यूट डिपेंडेंसी: deps एट्रिब्यूट, कंपाइल-टाइम की ज़रूरी डिपेंडेंसी से लिंक होता है. जैसे, LiteRT का टेंसर बफ़र (//litert/cc:litert_tensor_buffer) और एनपीयू डिस्पैच लेयर के लिए एपीआई (//litert/vendors/qualcomm/dispatch:dispatch_api). इससे, आपके ऐप्लिकेशन का कोड, LiteRT के ज़रिए एनपीयू के साथ इंटरैक्ट कर पाता है.
  • मॉडल फ़ाइलें और अन्य ऐसेट: data एट्रिब्यूट के ज़रिए शामिल की जाती हैं.

इस सेटअप की मदद से, कंपाइल किया गया बाइनरी, मशीन लर्निंग इन्फ़रेंस की परफ़ॉर्मेंस को बेहतर बनाने के लिए, एनपीयू को डाइनैमिक तरीके से लोड और इस्तेमाल कर सकता है.

एनपीयू एनवायरमेंट सेट अप करना

कुछ एनपीयू बैकएंड के लिए, रनटाइम डिपेंडेंसी या लाइब्रेरी की ज़रूरत होती है. कंपाइल किए गए मॉडल एपीआई का इस्तेमाल करते समय, LiteRT इन ज़रूरी शर्तों को Environment ऑब्जेक्ट के ज़रिए व्यवस्थित करता है. एनपीयू की सही लाइब्रेरी या ड्राइवर ढूंढने के लिए, यह कोड इस्तेमाल करें:

// 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)));

रनटाइम इंटिग्रेशन

यहां दिए गए कोड स्निपेट में, 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));

एनपीयू की मदद से परफ़ॉर्मेंस को बेहतर बनाने के लिए, ज़ीरो-कॉपी का इस्तेमाल करना

ज़ीरो-कॉपी का इस्तेमाल करने से, एनपीयू अपने मेमोरी में मौजूद डेटा को सीधे ऐक्सेस कर सकता है. इसके लिए, सीपीयू को उस डेटा को साफ़ तौर पर कॉपी करने की ज़रूरत नहीं होती. सीपीयू मेमोरी में डेटा कॉपी न करने की वजह से, ज़ीरो-कॉपी की मदद से एंड-टू-एंड लेटेन्सी को काफ़ी कम किया जा सकता है.

यहां दिया गया कोड, AHardwareBuffer के साथ ज़ीरो-कॉपी एनपीयू को लागू करने का एक उदाहरण है. इसमें डेटा को सीधे एनपीयू पर पास किया जाता है. इस तरीके से, सीपीयू मेमोरी में बार-बार डेटा कॉपी करने से बचा जा सकता है. इससे इन्फ़रेंस ओवरहेड काफ़ी कम हो जाता है.

// 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();

एक से ज़्यादा एनपीयू इन्फ़रेंस को चेन करना

जटिल पाइपलाइन के लिए, एक से ज़्यादा एनपीयू इन्फ़रेंस को चेन किया जा सकता है. हर चरण में, ऐक्सेलरेटर के साथ काम करने वाले बफ़र का इस्तेमाल किया जाता है. इसलिए, आपकी पाइपलाइन ज़्यादातर एनपीयू-मैनेज की गई मेमोरी में रहती है:

// 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);

एनपीयू ऑन-डिवाइस कंपाइलेशन कैशिंग

LiteRT, .tflite मॉडल के एनपीयू ऑन-डिवाइस (जिसे JIT कहा जाता है) कंपाइलेशन की सुविधा देता है. JIT कंपाइलेशन, उन स्थितियों में खास तौर पर काम आ सकता है जहां मॉडल को पहले से कंपाइल करना मुमकिन नहीं होता.

हालांकि, JIT कंपाइलेशन में कुछ लेटेन्सी और मेमोरी ओवरहेड हो सकता है. ऐसा इसलिए, क्योंकि उपयोगकर्ता के दिए गए मॉडल को ऑन-डिमांड, एनपीयू बाइटकोड निर्देशों में ट्रांसलेट करना होता है. परफ़ॉर्मेंस पर पड़ने वाले असर को कम करने के लिए, एनपीयू कंपाइलेशन आर्टफ़ैक्ट को कैश किया जा सकता है.

कैशिंग की सुविधा चालू होने पर, LiteRT मॉडल को सिर्फ़ तब फिर से कंपाइल करेगा, जब इसकी ज़रूरत होगी. जैसे:

  • वेंडर के एनपीयू कंपाइलर प्लगिन का वर्शन बदल गया हो;
  • Android बिल्ड फ़िंगरप्रिंट बदल गया हो;
  • उपयोगकर्ता का दिया गया मॉडल बदल गया हो;
  • कंपाइलेशन के विकल्प बदल गए हों.

एनपीयू कंपाइलेशन कैशिंग की सुविधा चालू करने के लिए, एनवायरमेंट के विकल्पों में CompilerCacheDir एनवायरमेंट टैग तय करें. वैल्यू को, ऐप्लिकेशन के किसी मौजूदा पाथ पर सेट करना होगा, जिसमें लिखा जा सकता है.

   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));

लेटेन्सी और मेमोरी की बचत के उदाहरण:

एनपीयू कंपाइलेशन के लिए लगने वाला समय और मेमोरी, कई चीज़ों पर निर्भर करती है. जैसे, एनपीयू चिप, इनपुट मॉडल की जटिलता वगैरह.

यहां दिए गए टेबल में, रनटाइम की शुरुआती प्रोसेस में लगने वाले समय और मेमोरी के इस्तेमाल की तुलना की गई है. इसमें यह भी बताया गया है कि एनपीयू कंपाइलेशन की ज़रूरत कब होती है और कैशिंग की वजह से कंपाइलेशन को कब छोड़ा जा सकता है. एक सैंपल डिवाइस पर, हमें यह जानकारी मिलती है:

TFLite मॉडल एनपीयू कंपाइलेशन के साथ मॉडल की शुरुआती प्रोसेस कैश किए गए कंपाइलेशन के साथ मॉडल की शुरुआती प्रोसेस एनपीयू कंपाइलेशन के साथ शुरुआती प्रोसेस में इस्तेमाल की जाने वाली मेमोरी (मेमोरी फ़ुटप्रिंट) कैश किए गए कंपाइलेशन के साथ शुरुआती प्रोसेस में इस्तेमाल की जाने वाली मेमोरी
torchvision_resnet152.tflite 7465.22 मि॰से. 198.34 मि॰से. 1525.24 एमबी 355.07 एमबी
torchvision_lraspp_mobilenet_v3_large.tflite 1592.54 मि॰से. 166.47 मि॰से. 254.90 एमबी 33.78 एमबी

किसी दूसरे डिवाइस पर, हमें यह जानकारी मिलती है:

TFLite मॉडल एनपीयू कंपाइलेशन के साथ मॉडल की शुरुआती प्रोसेस कैश किए गए कंपाइलेशन के साथ मॉडल की शुरुआती प्रोसेस एनपीयू कंपाइलेशन के साथ शुरुआती प्रोसेस में इस्तेमाल की जाने वाली मेमोरी (मेमोरी फ़ुटप्रिंट) कैश किए गए कंपाइलेशन के साथ शुरुआती प्रोसेस में इस्तेमाल की जाने वाली मेमोरी
torchvision_resnet152.tflite 2766.44 मि॰से. 379.86 मि॰से. 653.54 एमबी 501.21 एमबी
torchvision_lraspp_mobilenet_v3_large.tflite 784.14 मि॰से. 231.76 मि॰से. 113.14 एमबी 67.49 एमबी