Графические процессоры (GPU) широко используются для ускорения глубокого обучения благодаря их огромной параллельной пропускной способности по сравнению с центральными процессорами (CPU). LiteRT упрощает процесс использования аппаратного ускорения GPU, позволяя пользователям указывать аппаратное ускорение в качестве параметра при создании скомпилированной модели ( CompiledModel ).
Благодаря ускорению на графическом процессоре в LiteRT вы можете создавать удобные для графического процессора входные и выходные буферы, обеспечивать копирование данных в памяти графического процессора без копирования и выполнять задачи асинхронно для максимального параллелизма.
Начать
Для ознакомления с классическими моделями машинного обучения см. следующие демонстрационные приложения.
- Приложение Kotlin для сегментации изображений : вывод данных на CPU/GPU/NPU.
- Приложение для сегментации изображений на C++ : вывод данных с использованием CPU/GPU/NPU с асинхронным выполнением.
Для ознакомления с моделями GenAI см. следующие демонстрации и руководство:
- Приложение EmbeddingGemma для определения семантического сходства на C++ : вывод данных с использованием CPU/GPU/NPU.
- Руководство по запуску LLM-моделей с использованием LiteRT-LM .
Добавить зависимость от графического процессора.
Выполните следующие шаги, чтобы добавить зависимость от графического процессора в ваше приложение на Kotlin или C++.
Котлин
Для пользователей Kotlin графический ускоритель встроен и не требует дополнительных действий, помимо тех, что описаны в руководстве по началу работы .
C++
Для пользователей C++ необходимо скомпилировать зависимости приложения с использованием ускорения LiteRT GPU. Правило cc_binary , которое упаковывает основную логику приложения (например, main.cc ), требует наличия следующих компонентов среды выполнения:
- Библиотека LiteRT C API : атрибут
dataдолжен включать библиотеку LiteRT C API (//litert/c:litert_runtime_c_api_shared_lib) и компоненты, специфичные для графического процессора (litert_gpu_accelerator_prebuilts). - Атрибут dependencies : Атрибут
depsобычно включает зависимости GLESgles_deps(), аlinkoptsобычно включаетgles_linkopts(). Оба атрибута очень важны для ускорения работы GPU, поскольку LiteRT часто использует OpenGLES на Android. - Файлы моделей и другие ресурсы : включаются посредством атрибута
data.
Ниже приведён пример правила cc_binary :
load("//litert/build_common:special_rule.bzl", "litert_gpu_accelerator_prebuilts")
cc_binary(
name = "your_application",
srcs = [
"main.cc",
],
data = [
...
# litert c api shared library
"//litert/c:litert_runtime_c_api_shared_lib",
] + litert_gpu_accelerator_prebuilts(),
linkopts = select({
"@org_tensorflow//tensorflow:android": ["-landroid"],
"//conditions:default": [],
}) + gles_linkopts(), # gles link options
deps = [
...
"//litert/cc:litert_tensor_buffer", # litert cc library
...
] + gles_deps(), # gles dependencies
)
Такая настройка позволяет скомпилированному исполняемому файлу динамически загружать и использовать графический процессор для ускорения выполнения вычислений в рамках машинного обучения.
Предварительно собранные графические ускорители
Новый ускоритель LiteRT для графических процессоров пока не является открытым исходным кодом. Но доступны предварительно собранные версии. Для пользователей Kotlin пакет LiteRT Maven уже содержит ускорители для графических процессоров. Пользователям SDK для C++ необходимо загрузить его отдельно, используя эту ссылку .
В Bazel для добавления зависимости к вашей цели можно использовать следующее правило: ` cpp load("//litert/build_common:special_rule.bzl", "litert_gpu_accelerator_prebuilts")
Использование графического процессора с API CompiledModel
Для начала использования графического ускорителя передайте параметр GPU при создании скомпилированной модели ( CompiledModel ). Следующий фрагмент кода демонстрирует базовую реализацию всего процесса:
C++
// 1. Create a compiled model targeting GPU
LITERT_ASSIGN_OR_RETURN(auto env, Environment::Create({}));
LITERT_ASSIGN_OR_RETURN(auto compiled_model, CompiledModel::Create(env, "mymodel.tflite", kLiteRtHwAcceleratorGpu));
// 2. Prepare input/output buffers
LITERT_ASSIGN_OR_RETURN(auto input_buffers, compiled_model.CreateInputBuffers());
LITERT_ASSIGN_OR_RETURN(auto output_buffers, compiled_model.CreateOutputBuffers());
// 3. Fill input data (if you have CPU-based data)
input_buffers[0].Write<float>(absl::MakeConstSpan(cpu_data, data_size));
// 4. Execute
compiled_model.Run(input_buffers, output_buffers);
// 5. Access model output
std::vector<float> data(output_data_size);
output_buffers.Read<float>(absl::MakeSpan(data));
Котлин
// Load model and initialize runtime
val model =
CompiledModel.create(
context.assets,
"mymodel.tflite",
CompiledModel.Options(Accelerator.GPU),
env,
)
// Preallocate input/output buffers
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()
// Fill the first input
inputBuffers[0].writeFloat(FloatArray(data_size) { data_value /* your data */ })
// Invoke
model.run(inputBuffers, outputBuffers)
// Read the output
val outputFloatArray = outputBuffers[0].readFloat()
Для получения более подробной информации см. руководства « Начало работы с C++» или «Начало работы с Kotlin» .
Копирование без копирования с ускорением на графическом процессоре
Использование технологии «нулевого копирования» позволяет графическому процессору получать доступ к данным непосредственно в собственной памяти без необходимости явного копирования этих данных центральным процессором. Благодаря отсутствию копирования данных в память центрального процессора и из неё, технология «нулевого копирования» может значительно снизить сквозную задержку.
Приведённый ниже код представляет собой пример реализации технологии Zero-Copy GPU с использованием OpenGL , API для рендеринга векторной графики. Код передаёт изображения в формате буфера OpenGL непосредственно в LiteRT:
// Suppose you have an OpenGL buffer consisting of:
// target (GLenum), id (GLuint), size_bytes (size_t), and offset (size_t)
// Load model and compile for GPU
LITERT_ASSIGN_OR_RETURN(auto env, Environment::Create({}));
LITERT_ASSIGN_OR_RETURN(auto compiled_model,
CompiledModel::Create(env, "mymodel.tflite", kLiteRtHwAcceleratorGpu));
// Create a TensorBuffer that wraps the OpenGL buffer.
LITERT_ASSIGN_OR_RETURN(auto tensor_type, model.GetInputTensorType("input_tensor_name"));
LITERT_ASSIGN_OR_RETURN(auto gl_input_buffer, TensorBuffer::CreateFromGlBuffer(env,
tensor_type, opengl_buffer.target, opengl_buffer.id, opengl_buffer.size_bytes, opengl_buffer.offset));
std::vector<TensorBuffer> input_buffers{gl_input_buffer};
LITERT_ASSIGN_OR_RETURN(auto output_buffers, compiled_model.CreateOutputBuffers());
// Execute
compiled_model.Run(input_buffers, output_buffers);
// If your output is also GPU-backed, you can fetch an OpenCL buffer or re-wrap it as an OpenGL buffer:
LITERT_ASSIGN_OR_RETURN(auto out_cl_buffer, output_buffers[0].GetOpenClBuffer());
Асинхронное выполнение
Асинхронные методы LiteRT, такие как RunAsync() , позволяют планировать выполнение задач на графическом процессоре, продолжая при этом другие задачи на центральном процессоре или нейронном процессоре. В сложных конвейерах графический процессор часто используется асинхронно наряду с центральным процессором или нейронным процессором.
Приведенный ниже фрагмент кода основан на коде, представленном в примере ускорения GPU без копирования . Код использует как CPU, так и GPU асинхронно и прикрепляет Event LiteRT к входному буферу. Event LiteRT отвечает за управление различными типами примитивов синхронизации, и следующий код создает управляемый объект события LiteRT типа LiteRtEventTypeEglSyncFence . Этот объект Event гарантирует, что чтение из входного буфера не будет производиться до завершения работы GPU. Все это выполняется без участия CPU.
LITERT_ASSIGN_OR_RETURN(auto env, Environment::Create({}));
LITERT_ASSIGN_OR_RETURN(auto compiled_model,
CompiledModel::Create(env, "mymodel.tflite", kLiteRtHwAcceleratorGpu));
// 1. Prepare input buffer (OpenGL buffer)
LITERT_ASSIGN_OR_RETURN(auto gl_input,
TensorBuffer::CreateFromGlBuffer(env, tensor_type, opengl_tex));
std::vector<TensorBuffer> inputs{gl_input};
LITERT_ASSIGN_OR_RETURN(auto outputs, compiled_model.CreateOutputBuffers());
// 2. If the GL buffer is in use, create and set an event object to synchronize with the GPU.
LITERT_ASSIGN_OR_RETURN(auto input_event,
Event::CreateManagedEvent(env, LiteRtEventTypeEglSyncFence));
inputs[0].SetEvent(std::move(input_event));
// 3. Kick off the GPU inference
compiled_model.RunAsync(inputs, outputs);
// 4. Meanwhile, do other CPU work...
// CPU Stays busy ..
// 5. Access model output
std::vector<float> data(output_data_size);
outputs[0].Read<float>(absl::MakeSpan(data));
Поддерживаемая серверная часть
LiteRT поддерживает следующие графические процессоры для каждой платформы.
| Платформа | Бэкенд |
|---|---|
| Android | OpenCL + OpenGL |
| Linux | WebGPU (Vulkan) |
| macOS | Металл |
| Windows | WebGPU (Direct3D) |
| Android | OpenCL + OpenGL |
Поддерживаемые модели
LiteRT поддерживает ускорение графического процессора на следующих моделях. Результаты бенчмарков основаны на тестах, проведенных на устройстве Samsung Galaxy S24.
| Модель | Ускорение LiteRT на графическом процессоре | LiteRT GPU (мс) |
|---|---|---|
| hf_mms_300m | Полностью делегировано | 19.6 |
| hf_mobilevit_small | Полностью делегировано | 8.7 |
| hf_mobilevit_small_e2e | Полностью делегировано | 8.0 |
| hf_wav2vec2_base_960h | Полностью делегировано | 9.1 |
| hf_wav2vec2_base_960h_dynamic | Полностью делегировано | 9.8 |
| интернет | Полностью делегировано | 43.1 |
| timm_efficientnet | Полностью делегировано | 3.7 |
| timm_nfnet | Полностью делегировано | 9.7 |
| timm_regnety_120 | Полностью делегировано | 12.1 |
| torchaudio_deepspeech | Полностью делегировано | 4.6 |
| torchaudio_wav2letter | Полностью делегировано | 4.8 |
| torchvision_alexnet | Полностью делегировано | 3.3 |
| torchvision_deeplabv3_mobilenet_v3_large | Полностью делегировано | 5.7 |
| torchvision_deeplabv3_resnet101 | Полностью делегировано | 35.1 |
| torchvision_deeplabv3_resnet50 | Полностью делегировано | 24.5 |
| torchvision_densenet121 | Полностью делегировано | 13.9 |
| torchvision_efficientnet_b0 | Полностью делегировано | 3.6 |
| torchvision_efficientnet_b1 | Полностью делегировано | 4.7 |
| torchvision_efficientnet_b2 | Полностью делегировано | 5.0 |
| torchvision_efficientnet_b3 | Полностью делегировано | 6.1 |
| torchvision_efficientnet_b4 | Полностью делегировано | 7.6 |
| torchvision_efficientnet_b5 | Полностью делегировано | 8.6 |
| torchvision_efficientnet_b6 | Полностью делегировано | 11.2 |
| torchvision_efficientnet_b7 | Полностью делегировано | 14.7 |
| torchvision_fcn_resnet50 | Полностью делегировано | 19.9 |
| torchvision_googlenet | Полностью делегировано | 3.9 |
| torchvision_inception_v3 | Полностью делегировано | 8.6 |
| torchvision_lraspp_mobilenet_v3_large | Полностью делегировано | 3.3 |
| torchvision_mnasnet0_5 | Полностью делегировано | 2.4 |
| torchvision_mobilenet_v2 | Полностью делегировано | 2.8 |
| torchvision_mobilenet_v3_large | Полностью делегировано | 2.8 |
| torchvision_mobilenet_v3_small | Полностью делегировано | 2.3 |
| torchvision_resnet152 | Полностью делегировано | 15.0 |
| torchvision_resnet18 | Полностью делегировано | 4.3 |
| torchvision_resnet50 | Полностью делегировано | 6.9 |
| torchvision_squeezenet1_0 | Полностью делегировано | 2.9 |
| torchvision_squeezenet1_1 | Полностью делегировано | 2.5 |
| torchvision_vgg16 | Полностью делегировано | 13.4 |
| torchvision_wide_resnet101_2 | Полностью делегировано | 25.0 |
| torchvision_wide_resnet50_2 | Полностью делегировано | 13.4 |
| u2net_full | Полностью делегировано | 98.3 |
| u2net_lite | Полностью делегировано | 51.4 |
| hf_distil_whisper_small_no_cache | Частично делегированный | 251.9 |
| hf_distilbert | Частично делегированный | 13.7 |
| hf_tinyroberta_squad2 | Частично делегированный | 17.1 |
| hf_tinyroberta_squad2_dynamic_batch | Частично делегированный | 52.1 |
| snapml_StyleTransferNet | Частично делегированный | 40.9 |
| timm_efficientformer_l1 | Частично делегированный | 17.6 |
| timm_efficientformerv2_s0 | Частично делегированный | 16.1 |
| timm_pvt_v2_b1 | Частично делегированный | 73.5 |
| timm_pvt_v2_b3 | Частично делегированный | 246.7 |
| timm_resnest14d | Частично делегированный | 88.9 |
| torchaudio_conformer | Частично делегированный | 21.5 |
| torchvision_convnext_tiny | Частично делегированный | 8.2 |
| torchvision_maxvit_t | Частично делегированный | 194.0 |
| torchvision_shufflenet_v2 | Частично делегированный | 9.5 |
| torchvision_swin_tiny | Частично делегированный | 164.4 |
| torchvision_video_resnet2plus1d_18 | Частично делегированный | 6832.0 |
| torchvision_video_swin3d_tiny | Частично делегированный | 2617.8 |
| yolox_tiny | Частично делегированный | 11.2 |