Delegat do akceleracji GPU za pomocą interfejsu API C/C++

Zastosowanie procesorów graficznych (GPU) do uruchamiania modeli systemów uczących się może znacznie zwiększyć wydajność i wygodę użytkowników aplikacji obsługujących systemy uczące się. Na urządzeniach z Androidem możesz włączyć przyspieszanie przez GPU wykonywanie modeli za pomocą osoby, której przekazano dostęp i jednego z tych interfejsów API:

  • Interpreter API – przewodnik
  • Natywny interfejs API (C/C++) – ten przewodnik

W tym przewodniku omawiamy zaawansowane zastosowania delegata GPU do interfejsów API C i C++ oraz korzystania z modeli skwantyzowanych. Więcej informacji o korzystaniu z delegata GPU dla TensorFlow Lite, w tym o sprawdzonych metodach i zaawansowanych technikach, znajdziesz na stronie delegatów GPU.

Włącz akcelerację GPU

Użyj delegata GPU TensorFlow Lite dla Androida w języku C lub C++, tworząc delegat za pomocą TfLiteGpuDelegateV2Create() i niszcząc go za pomocą TfLiteGpuDelegateV2Delete(), jak w tym przykładowym kodzie:

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

Sprawdź kod obiektu TfLiteGpuDelegateOptionsV2, aby utworzyć instancję delegata z opcjami niestandardowymi. Opcje domyślne możesz zainicjować za pomocą TfLiteGpuDelegateOptionsV2Default(), a potem w razie potrzeby je zmodyfikować.

Delegat GPU TensorFlow Lite dla Androida w języku C lub C++ korzysta z systemu kompilacji Bazel. Delegata możesz utworzyć za pomocą tego polecenia:

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

Aby można było wywołać metodę Interpreter::ModifyGraphWithDelegate() lub Interpreter::Invoke(), element wywołujący musi mieć w bieżącym wątku EGLContext, a Interpreter::Invoke() musi być wywoływany z tego samego parametru EGLContext. Jeśli obiekt EGLContext nie istnieje, delegat utworzy go wewnętrznie, ale musisz zadbać o to, aby funkcja Interpreter::Invoke() była zawsze wywoływana z tego samego wątku, w którym wywołano metodę Interpreter::ModifyGraphWithDelegate().

Dzięki TensorFlow Lite w Usługach Google Play:

Jeśli używasz TensorFlow Lite w interfejsie API C Usług Google Play, to przed zainicjowaniem środowiska wykonawczego TensorFlow Lite musisz użyć interfejsu API Java/Kotlin, aby sprawdzić, czy dla Twojego urządzenia dostępny jest delegat GPU.

Dodaj do aplikacji zależności GPU delegowane przez Gradle:

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

Następnie sprawdź dostępność GPU i zainicjuj TfLiteNative, jeśli test się uda:

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

Musisz też zaktualizować konfigurację CMake, aby uwzględnić flagę kompilatora TFLITE_USE_OPAQUE_DELEGATE:

add_compile_definitions(TFLITE_USE_OPAQUE_DELEGATE)

Biblioteka FlatBuffers służy do konfigurowania przekazanych wtyczek, więc musisz ją dodać do zależności kodu natywnego. Możesz użyć oficjalnej konfiguracji projektu CMake w następujący sposób:

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

Możesz też połączyć nagłówki z aplikacją.

Aby użyć wnioskowania na podstawie GPU w kodzie C, utwórz delegata GPU za pomocą 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);

Modele kwantyzowane

Biblioteki delegowania GPU w Androidzie domyślnie obsługują modele poddane kwantyzacji. Aby używać skwantyzowanych modeli z delegatem GPU, nie musisz wprowadzać żadnych zmian w kodzie. W sekcji poniżej wyjaśniono, jak wyłączyć obsługę ilościową na potrzeby testowania lub eksperymentu.

Wyłącz obsługę modelu skwantyzowanego

Poniższy kod pokazuje, jak wyłączyć obsługę modeli skwantyzowanych.

C++

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

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

Więcej informacji o uruchamianiu modeli skwantyzowanych z akceleracją GPU znajdziesz w artykule o przekazywaniu delegacji GPU.