การเร่งความเร็ว NPU ด้วย LiteRT

LiteRT มีอินเทอร์เฟซแบบรวมเพื่อใช้หน่วยประมวลผลนิวรอน (NPU) โดยไม่ต้องขอให้คุณไปยังคอมไพเลอร์ รันไทม์ หรือ การอ้างอิงไลบรารีของผู้ให้บริการที่เฉพาะเจาะจง การใช้ LiteRT เพื่อการเร่งความเร็ว NPU จะช่วยเพิ่มประสิทธิภาพสำหรับการอนุมานแบบเรียลไทม์และแบบโมเดลขนาดใหญ่ รวมถึงลดการคัดลอกหน่วยความจำผ่านการใช้บัฟเฟอร์ฮาร์ดแวร์แบบไม่คัดลอก

เริ่มต้นใช้งาน

โมเดล ML แบบคลาสสิก

สำหรับโมเดล ML แบบคลาสสิก โปรดดูแอปพลิเคชันเดโมต่อไปนี้

โมเดล GenAI

สำหรับโมเดล GenAI โปรดดูการสาธิตและคำแนะนำต่อไปนี้

ผู้ให้บริการ NPU

LiteRT รองรับการเร่งความเร็ว NPU กับผู้ให้บริการต่อไปนี้

Google Tensor

  • รองรับการดำเนินการ AOT ผ่าน CompiledModel API
  • ดูรายละเอียดการตั้งค่าได้ที่ Google Tensor

Qualcomm AI Engine Direct

MediaTek NeuroPilot

Intel OpenVino

  • รองรับการดำเนินการ AOT และการคอมไพล์ในอุปกรณ์ผ่าน CompiledModel API
  • ดูรายละเอียดการตั้งค่าได้ที่ Intel OpenVino

AOT และการคอมไพล์ในอุปกรณ์

NPU ของ LiteRT รองรับทั้ง AOT และการคอมไพล์ในอุปกรณ์เพื่อให้เป็นไปตามข้อกำหนดในการ ติดตั้งใช้งานที่เฉพาะเจาะจง

  • การคอมไพล์ออฟไลน์ (AOT): เหมาะสำหรับโมเดลขนาดใหญ่และซับซ้อน ซึ่งทราบ SoC เป้าหมาย การคอมไพล์ล่วงหน้าจะช่วยลดต้นทุนการเริ่มต้นและการใช้งานหน่วยความจำได้อย่างมากเมื่อผู้ใช้เปิดแอปของคุณ
  • การคอมไพล์ออนไลน์ (ในอุปกรณ์): หรือที่เรียกว่าการคอมไพล์ JIT ซึ่งเหมาะสําหรับการกระจายโมเดลขนาดเล็กที่ไม่ขึ้นกับแพลตฟอร์ม ระบบจะคอมไพล์โมเดลในอุปกรณ์ของผู้ใช้ระหว่างการเริ่มต้น ซึ่งไม่จำเป็นต้องมีขั้นตอนการเตรียมการเพิ่มเติม แต่จะมีค่าใช้จ่ายในการเรียกใช้ครั้งแรกสูงกว่า

วิธีติดตั้งใช้งานโมเดลโดยใช้ตัวเลือกการคอมไพล์ AOT หรือการคอมไพล์ในอุปกรณ์มีดังนี้

ขั้นตอนที่ 1: การคอมไพล์ AOT สำหรับ SoC ของ NPU เป้าหมาย

คุณสามารถใช้คอมไพเลอร์ AOT (ล่วงหน้า) ของ LiteRT เพื่อคอมไพล์โมเดล .tflite ไปยัง SoC ที่รองรับ นอกจากนี้ คุณยังกำหนดเป้าหมายผู้ให้บริการ SoC และ เวอร์ชันต่างๆ พร้อมกันได้ภายในกระบวนการคอมไพล์เดียว ดูรายละเอียดเพิ่มเติมได้ในสมุดบันทึกการคอมไพล์ AOT ของ LiteRT นี้ แม้จะไม่บังคับ แต่ขอแนะนำอย่างยิ่งให้คอมไพล์ AOT สำหรับโมเดลขนาดใหญ่เพื่อลดเวลาในการเริ่มต้นในอุปกรณ์ ขั้นตอนนี้ไม่จำเป็นสำหรับการคอมไพล์ในอุปกรณ์

ขั้นตอนที่ 2: หากใช้ Android ให้ติดตั้งใช้งานด้วย Google Play

ใน Android ให้ใช้ Play สำหรับ AI ในอุปกรณ์ (PODAI) ของ Google เพื่อติดตั้งใช้งาน โมเดลและไลบรารีรันไทม์ของ NPU กับแอป

  • สำหรับโมเดลการคอมไพล์ในอุปกรณ์ ให้เพิ่มไฟล์โมเดล .tflite ต้นฉบับ ลงในไดเรกทอรี assets/ ของแอปโดยตรง
  • สำหรับโมเดลของการคอมไพล์ AOT: ใช้ LiteRT เพื่อส่งออกโมเดลที่คอมไพล์แล้ว เป็น Play AI Pack เดียวของ Google จากนั้นให้อัปโหลดแพ็ก AI ไปยัง Google Play เพื่อส่งโมเดลที่คอมไพล์แล้วอย่างถูกต้องไปยังอุปกรณ์ของผู้ใช้โดยอัตโนมัติ
  • สำหรับไลบรารีรันไทม์ของ NPU ให้ใช้การนำส่งฟีเจอร์ Play เพื่อเผยแพร่ไลบรารีรันไทม์ที่ถูกต้องไปยังอุปกรณ์ของผู้ใช้

ดูส่วนต่อไปนี้เกี่ยวกับวิธีติดตั้งใช้งานด้วย Play AI Pack และ การนำส่งฟีเจอร์ Play

ติดตั้งใช้งานโมเดล AOT ด้วย Play AI Pack

ขั้นตอนต่อไปนี้จะแนะนําวิธีการติดตั้งใช้งานโมเดลที่คอมไพล์ AOT โดยใช้ Play AI Packs

เพิ่มแพ็ก AI ลงในโปรเจ็กต์

นำเข้าแพ็ก AI ไปยังโปรเจ็กต์ Gradle โดยการคัดลอกแพ็ก AI ไปยังไดเรกทอรีราก ของโปรเจ็กต์ Gradle เช่น

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

เพิ่มแพ็ก AI แต่ละแพ็กในการกำหนดค่าบิลด์ 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

เพิ่มแพ็ก AI ลงในการกำหนดค่า Gradle

คัดลอก device_targeting_configuration.xml จากแพ็ก AI ที่สร้างขึ้นไปยัง ไดเรกทอรีของโมดูลแอปหลัก จากนั้นอัปเดต 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 สำหรับการนำส่งตามต้องการ

การนำส่งตามต้องการช่วยให้คุณขอโมเดลได้ในขณะรันไทม์ ซึ่งมีประโยชน์ในกรณีที่ ต้องใช้โมเดลเฉพาะสำหรับโฟลว์ของผู้ใช้บางรายการเท่านั้น ระบบจะดาวน์โหลดโมเดล ไปยังพื้นที่จัดเก็บข้อมูลภายในของแอป เมื่อกำหนดค่าฟีเจอร์ Android AI Pack ในไฟล์ build.gradle.kts แล้ว ให้ตรวจสอบความสามารถของอุปกรณ์ ดูวิธีการสำหรับการนำส่งเมื่อติดตั้งและการดาวน์โหลดอัตโนมัติจาก 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,
)

ติดตั้งใช้งานไลบรารีรันไทม์ของ NPU ด้วยการนำส่งฟีเจอร์ Play

การนำส่งฟีเจอร์ Play รองรับตัวเลือกการนำส่งหลายรายการเพื่อเพิ่มประสิทธิภาพขนาดการดาวน์โหลดเริ่มต้น ซึ่งรวมถึงการนำส่งเมื่อติดตั้ง การนำส่งตามคำขอ การนำส่งแบบมีเงื่อนไข และ การนำส่งทันที ในที่นี้ เราจะแสดงคำแนะนำพื้นฐานในการนำส่งขณะติดตั้ง

เพิ่มไลบรารีรันไทม์ของ NPU ลงในโปรเจ็กต์

ดาวน์โหลด litert_npu_runtime_libraries.zipจากรุ่นล่าสุด สำหรับการคอมไพล์ AOT หรือ 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

เรียกใช้สคริปต์เพื่อดาวน์โหลดไลบรารีการสนับสนุน NPU เช่น เรียกใช้คำสั่งต่อไปนี้สำหรับ NPU ของ Qualcomm

$ ./litert_npu_runtime_libraries/fetch_qualcomm_library.sh

เพิ่มไลบรารีรันไทม์ของ NPU ลงในการกำหนดค่า Gradle

คัดลอก device_targeting_configuration.xml จากแพ็ก AI ที่สร้างขึ้นไปยัง ไดเรกทอรีของโมดูลแอปหลัก จากนั้นอัปเดต 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"))
  ...
}

ขั้นตอนที่ 3: การอนุมานใน NPU โดยใช้รันไทม์ LiteRT

LiteRT จะซ่อนความซับซ้อนของการพัฒนาเทียบกับ SoC เวอร์ชันที่เฉพาะเจาะจง ทำให้คุณเรียกใช้โมเดลใน NPU ได้ด้วยโค้ดเพียงไม่กี่บรรทัด นอกจากนี้ยังมีกลไกการทำงานสำรองในตัวที่แข็งแกร่งด้วย โดยคุณสามารถระบุ CPU, GPU หรือทั้ง 2 อย่างเป็นตัวเลือก และ LiteRT จะใช้ตัวเลือกเหล่านั้นโดยอัตโนมัติหาก NPU ไม่พร้อมใช้งาน การคอมไพล์ AOT ยังรองรับการสำรองข้อมูลด้วย โดยจะมีการ มอบสิทธิ์บางส่วนใน NPU ซึ่งกราฟย่อยที่ไม่รองรับจะทำงานบน CPU หรือ GPU ได้อย่างราบรื่นตามที่ระบุ

เรียกใช้ใน Kotlin

ดูตัวอย่างการใช้งานในแอปเดโมต่อไปนี้

เพิ่มการขึ้นต่อกันของ Android

คุณเพิ่มแพ็กเกจ Maven ของ LiteRT เวอร์ชันล่าสุดลงในทรัพยากร Dependency build.gradle ได้โดยทำดังนี้

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++ การแบ่งกลุ่มแบบไม่พร้อมกัน

ทรัพยากร Dependency ของ Bazel Build

ผู้ใช้ C++ ต้องสร้างทรัพยากร Dependency ของแอปพลิเคชันด้วยการเร่งความเร็ว LiteRT NPU cc_binary กฎที่แพ็กเกจตรรกะของแอปพลิเคชันหลัก (เช่น main.cc) ต้องมีคอมโพเนนต์รันไทม์ต่อไปนี้

  • ไลบรารีที่ใช้ร่วมกันของ LiteRT C API: แอตทริบิวต์ data ต้องมี ไลบรารีที่ใช้ร่วมกันของ LiteRT C API (//litert/c:litert_runtime_c_api_shared_lib) และออบเจ็กต์ที่ใช้ร่วมกันในการเรียกใช้เฉพาะผู้จำหน่ายสำหรับ NPU (//litert/vendors/qualcomm/dispatch:dispatch_api_so)
  • ไลบรารีแบ็กเอนด์เฉพาะ NPU: เช่น ไลบรารี Qualcomm AI RT (QAIRT) สำหรับโฮสต์ Android (เช่น libQnnHtp.so, libQnnHtpPrepare.so) และไลบรารี Hexagon DSP ที่เกี่ยวข้อง (libQnnHtpV79Skel.so) ซึ่งจะช่วยให้รันไทม์ LiteRT สามารถลดภาระการคำนวณไปยัง NPU ได้
  • การขึ้นต่อกันของแอตทริบิวต์: แอตทริบิวต์ deps จะลิงก์กับทรัพยากร Dependency ที่จำเป็น การขึ้นต่อกันในเวลาคอมไพล์ เช่น บัฟเฟอร์ Tensor ของ LiteRT (//litert/cc:litert_tensor_buffer) และ API สำหรับเลเยอร์การจัดส่ง NPU (//litert/vendors/qualcomm/dispatch:dispatch_api) ซึ่งจะช่วยให้โค้ดของแอปพลิเคชัน โต้ตอบกับ NPU ผ่าน LiteRT ได้
  • ไฟล์โมเดลและชิ้นงานอื่นๆ: รวมไว้ผ่านแอตทริบิวต์ data

การตั้งค่านี้ช่วยให้ไบนารีที่คอมไพล์โหลดและใช้ NPU แบบไดนามิกเพื่อ การอนุมานแมชชีนเลิร์นนิงที่เร่งความเร็ว

ตั้งค่าสภาพแวดล้อม NPU

แบ็กเอนด์ NPU บางตัวต้องใช้ทรัพยากร Dependency หรือไลบรารีรันไทม์ เมื่อใช้ API ของโมเดลที่คอมไพล์แล้ว LiteRT จะจัดระเบียบข้อกำหนดเหล่านี้ผ่านออบเจ็กต์ Environment ใช้โค้ดต่อไปนี้เพื่อค้นหาไลบรารีหรือไดรเวอร์ NPU ที่เหมาะสม

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

การคัดลอกแบบไม่ต้องคัดลอกด้วยการเร่งความเร็ว NPU

การใช้การคัดลอกเป็นศูนย์ช่วยให้ NPU เข้าถึงข้อมูลในหน่วยความจำของตัวเองได้โดยตรงโดยไม่จำเป็นต้องให้ CPU คัดลอกข้อมูลนั้นอย่างชัดเจน การไม่คัดลอกข้อมูลไปยังและจากหน่วยความจำ CPU จะช่วยลดเวลาในการตอบสนองแบบต้นทางถึงปลายทางได้อย่างมาก

โค้ดต่อไปนี้เป็นตัวอย่างการติดตั้งใช้งาน NPU แบบไม่คัดลอกด้วย AHardwareBuffer ซึ่งส่งข้อมูลไปยัง NPU โดยตรง การใช้งานนี้หลีกเลี่ยง การเดินทางไปกลับที่หน่วยความจำ CPU ซึ่งมีค่าใช้จ่ายสูง จึงช่วยลดค่าใช้จ่ายในการอนุมานได้อย่างมาก

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

เชื่อมโยงการอนุมาน NPU หลายรายการ

สำหรับไปป์ไลน์ที่ซับซ้อน คุณสามารถเชื่อมโยงการอนุมาน NPU หลายรายการได้ เนื่องจากแต่ละขั้นตอน ใช้บัฟเฟอร์ที่เหมาะกับตัวเร่งความเร็ว ไปป์ไลน์จึงส่วนใหญ่อยู่ในหน่วยความจำที่ 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);

การแคชการคอมไพล์ในอุปกรณ์ NPU

LiteRT รองรับการคอมไพล์ .tflite โมเดล NPU ในอุปกรณ์ (หรือที่เรียกว่า JIT) การคอมไพล์ JIT มีประโยชน์อย่างยิ่งในสถานการณ์ที่การคอมไพล์โมเดล ล่วงหน้าไม่สามารถทำได้

อย่างไรก็ตาม การคอมไพล์ JIT อาจมีเวลาในการตอบสนองและค่าใช้จ่ายด้านหน่วยความจำบางอย่างเพื่อ แปลโมเดลที่ผู้ใช้ระบุเป็นคำสั่งไบต์โค้ด NPU ตามต้องการ หากต้องการ ลดผลกระทบต่อประสิทธิภาพ คุณสามารถแคชอาร์ติแฟกต์การคอมไพล์ NPU ได้

เมื่อเปิดใช้แคช LiteRT จะทริกเกอร์การคอมไพล์โมเดลอีกครั้งเฉพาะเมื่อจำเป็นเท่านั้น เช่น

  • เวอร์ชันปลั๊กอินคอมไพเลอร์ NPU ของผู้ให้บริการมีการเปลี่ยนแปลง
  • รหัสเฉพาะของบิลด์ Android เปลี่ยนไป
  • โมเดลที่ผู้ใช้ระบุมีการเปลี่ยนแปลง
  • ตัวเลือกการคอมไพล์มีการเปลี่ยนแปลง

หากต้องการเปิดใช้การแคชการคอมไพล์ NPU ให้ระบุแท็กสภาพแวดล้อม 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));

ตัวอย่างการประหยัดเวลาในการตอบสนองและหน่วยความจำ

เวลาและหน่วยความจำที่จำเป็นสำหรับการคอมไพล์ NPU อาจแตกต่างกันไปตามปัจจัยหลายประการ เช่น ชิป NPU พื้นฐาน ความซับซ้อนของโมเดลอินพุต เป็นต้น

ตารางต่อไปนี้เปรียบเทียบเวลาเริ่มต้นรันไทม์และการใช้หน่วยความจำ เมื่อต้องมีการคอมไพล์ NPU กับเมื่อข้ามการคอมไพล์ได้ เนื่องจากการแคช ในอุปกรณ์ตัวอย่างเครื่องหนึ่ง เราได้รับข้อมูลต่อไปนี้

โมเดล TFLite model init with NPU compilation model init with cached compilation หน่วยความจำที่ใช้เริ่มต้นเมื่อคอมไพล์ด้วย NPU เริ่มต้นหน่วยความจำด้วยการคอมไพล์ที่แคชไว้
torchvision_resnet152.tflite 7465.22 มิลลิวินาที 198.34 มิลลิวินาที 1525.24 MB 355.07 MB
torchvision_lraspp_mobilenet_v3_large.tflite 1592.54 มิลลิวินาที 166.47 มิลลิวินาที 254.90 MB 33.78 MB

ในอุปกรณ์อื่น เราจะได้รับข้อมูลต่อไปนี้

โมเดล TFLite model init with NPU compilation model init with cached compilation หน่วยความจำที่ใช้เริ่มต้นเมื่อคอมไพล์ด้วย NPU เริ่มต้นหน่วยความจำด้วยการคอมไพล์ที่แคชไว้
torchvision_resnet152.tflite 2766.44 มิลลิวินาที 379.86 มิลลิวินาที 653.54 MB 501.21 MB
torchvision_lraspp_mobilenet_v3_large.tflite 784.14 มิลลิวินาที 231.76 มิลลิวินาที 113.14 MB 67.49 MB