Ủy quyền tăng tốc GPU bằng API C/C++

Sử dụng đơn vị xử lý đồ hoạ (GPU) để chạy các mô hình học máy (ML) có thể cải thiện đáng kể hiệu suất và trải nghiệm người dùng của ứng dụng các ứng dụng hỗ trợ ML. Trên thiết bị Android, bạn có thể bật chế độ tăng tốc GPU thực thi các mô hình của mình bằng cách sử dụng uỷ quyền và một trong các API sau:

  • API phiên dịch – hướng dẫn
  • API gốc (C/C++) – hướng dẫn này

Hướng dẫn này trình bày cách sử dụng nâng cao của tính năng uỷ quyền GPU cho API C, API C++ và việc sử dụng mô hình lượng tử hoá. Để biết thêm thông tin về cách sử dụng uỷ quyền GPU cho LiteRT, bao gồm các phương pháp hay nhất và kỹ thuật nâng cao, hãy xem GPU uỷ quyền.

Bật tính năng tăng tốc GPU

Sử dụng uỷ quyền GPU LiteRT cho Android trong C hoặc C++ bằng cách tạo uỷ quyền bằng TfLiteGpuDelegateV2Create() và huỷ bỏ nó bằng TfLiteGpuDelegateV2Delete(), như minh hoạ trong mã ví dụ sau đây:

// Set up interpreter.
auto model = FlatBufferModel::BuildFromFile(model_path);
if (!model) return false;
ops::builtin::BuiltinOpResolver op_resolver;
std::unique_ptr<Interpreter> interpreter;
InterpreterBuilder(*model, op_resolver)(&interpreter);

// NEW: Prepare GPU delegate.
auto* delegate = TfLiteGpuDelegateV2Create(/*default options=*/nullptr);
if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;

// Run inference.
WriteToInputTensor(interpreter->typed_input_tensor<float>(0));
if (interpreter->Invoke() != kTfLiteOk) return false;
ReadFromOutputTensor(interpreter->typed_output_tensor<float>(0));

// NEW: Clean up.
TfLiteGpuDelegateV2Delete(delegate);

Xem lại mã đối tượng TfLiteGpuDelegateOptionsV2 để tạo một thực thể uỷ quyền với các lựa chọn tuỳ chỉnh. Bạn có thể khởi chạy các tuỳ chọn mặc định bằng TfLiteGpuDelegateOptionsV2Default(), sau đó sửa đổi chúng nếu cần.

Tính năng uỷ quyền GPU LiteRT cho Android trong C hoặc C++ sử dụng Bazel. Bạn có thể tạo uỷ quyền bằng cách sử dụng sau đây:

bazel build -c opt --config android_arm64 tensorflow/lite/delegates/gpu:delegate                           # for static library
bazel build -c opt --config android_arm64 tensorflow/lite/delegates/gpu:libtensorflowlite_gpu_delegate.so  # for dynamic library

Khi gọi Interpreter::ModifyGraphWithDelegate() hoặc Interpreter::Invoke(), phương thức gọi phải có một EGLContext trong hiện tại luồng và Interpreter::Invoke() phải được gọi từ cùng một EGLContext. Nếu EGLContext không tồn tại, người được uỷ quyền sẽ tạo một tài khoản nội bộ, nhưng sau đó Bạn phải đảm bảo rằng Interpreter::Invoke() luôn được gọi từ cùng một luồng trong đó Interpreter::ModifyGraphWithDelegate() được gọi.

Với LiteRT trong Dịch vụ Google Play:

Nếu bạn đang sử dụng LiteRT trong API C của Dịch vụ Google Play, bạn sẽ cần sử dụng API Java/Kotlin để kiểm tra xem có uỷ quyền GPU hay không cho thiết bị của mình trước khi khởi chạy thời gian chạy LiteRT.

Thêm các phần phụ thuộc gradle uỷ quyền của GPU vào ứng dụng của bạn:

implementation 'com.google.android.gms:play-services-tflite-gpu:16.2.0'

Sau đó, hãy kiểm tra tính sẵn có của GPU và khởi chạy TfLiteNative nếu kết quả kiểm tra là thành công:

Java

Task<Void> tfLiteHandleTask =
TfLiteGpu.isGpuDelegateAvailable(this)
   .onSuccessTask(gpuAvailable -> {
      TfLiteInitializationOptions options =
        TfLiteInitializationOptions.builder()
          .setEnableGpuDelegateSupport(gpuAvailable).build();
        return TfLiteNative.initialize(this, options);
      }
    );
      

Kotlin

val tfLiteHandleTask = TfLiteGpu.isGpuDelegateAvailable(this)
    .onSuccessTask { gpuAvailable ->
        val options = TfLiteInitializationOptions.Builder()
            .setEnableGpuDelegateSupport(gpuAvailable)
            .build()
        TfLiteNative.initialize(this, options)
    }
        

Bạn cũng cần cập nhật cấu hình CMake để đưa vào Cờ trình biên dịch TFLITE_USE_OPAQUE_DELEGATE:

add_compile_definitions(TFLITE_USE_OPAQUE_DELEGATE)

Thư viện FlatBuffers được dùng để định cấu hình trình bổ trợ uỷ quyền, vì vậy, bạn cần thêm trình bổ trợ này vào các phần phụ thuộc của mã gốc. Bạn có thể sử dụng cấu hình dự án CMake chính thức như sau:

target_include_directories(tflite-jni PUBLIC
        third_party/headers # flatbuffers
     ...)

Bạn cũng có thể chỉ cần nhóm các tiêu đề vào ứng dụng của mình.

Cuối cùng, để sử dụng suy luận GPU trong mã C, hãy tạo uỷ quyền GPU bằng cách sử dụng TFLiteSettings:

#include "flatbuffers/flatbuffers.h"
#include "tensorflow/lite/acceleration/configuration/configuration_generated.h"

flatbuffers::FlatBufferBuilder fbb;
tflite::TFLiteSettingsBuilder builder(fbb);
const tflite::TFLiteSettings* tflite_settings =
    flatbuffers::GetTemporaryPointer(fbb, builder.Finish());

const TfLiteOpaqueDelegatePlugin* pluginCApi = TfLiteGpuDelegatePluginCApi();
TfLiteOpaqueDelegate* gpu_delegate = pluginCApi->create(tflite_settings);

Mô hình lượng tử hoá

Theo mặc định, thư viện uỷ quyền GPU của Android hỗ trợ các mô hình lượng tử hoá. Bạn không phải thực hiện bất kỳ thay đổi nào về mã để sử dụng các mô hình lượng tử hoá với bộ uỷ quyền GPU. Chiến lược phát hành đĩa đơn phần sau đây giải thích cách tắt tính năng hỗ trợ lượng tử hoá cho việc kiểm thử hoặc cho mục đích thử nghiệm.

Tắt tính năng hỗ trợ mô hình lượng tử hoá

Đoạn mã sau đây cho biết cách tắt tính năng hỗ trợ cho các mô hình lượng tử hoá.

C++

TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
options.experimental_flags = TFLITE_GPU_EXPERIMENTAL_FLAGS_NONE;

auto* delegate = TfLiteGpuDelegateV2Create(options);
if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Để biết thêm thông tin về cách chạy các mô hình lượng tử hoá bằng tính năng tăng tốc GPU, hãy xem Tổng quan về Uỷ quyền GPU.