Grafik işleme birimleri (GPU'lar), CPU'lara kıyasla büyük paralel işleme kapasiteleri nedeniyle derin öğrenme hızlandırması için yaygın olarak kullanılır. LiteRT, derlenmiş bir model (CompiledModel) oluştururken kullanıcıların donanım hızlandırmayı parametre olarak belirtmesine olanak tanıyarak GPU hızlandırmayı kullanma sürecini basitleştirir.
LiteRT'nin GPU hızlandırması sayesinde GPU dostu giriş ve çıkış arabellekleri oluşturabilir, GPU belleğindeki verilerinizle sıfır kopya elde edebilir ve paralelliği en üst düzeye çıkarmak için görevleri eşzamansız olarak yürütebilirsiniz.
LiteRT GPU'nun örnek uygulamaları için aşağıdaki demo uygulamalarına bakın:
GPU bağımlılığı ekleme
Kotlin veya C++ uygulamanıza GPU bağımlılığı eklemek için aşağıdaki adımları uygulayın.
Kotlin
Kotlin kullanıcıları için GPU hızlandırıcı yerleşiktir ve Başlangıç kılavuzunda belirtilen adımlar dışında ek adım gerektirmez.
C++
C++ kullanıcıları, uygulamanın bağımlılıklarını LiteRT GPU hızlandırmasıyla oluşturmalıdır. Temel uygulama mantığını paketleyen cc_binary kuralı
(ör. main.cc) için aşağıdaki çalışma zamanı bileşenleri gerekir:
- LiteRT C API paylaşılan kitaplığı:
dataözelliği, LiteRT C API paylaşılan kitaplığını (//litert/c:litert_runtime_c_api_shared_lib) ve GPU'ya özel bileşenleri (@litert_gpu//:jni/arm64-v8a/libLiteRtGpuAccelerator.so) içermelidir. - Özellik bağımlılıkları:
depsözelliği genellikle GLES bağımlılıklarınıgles_deps(),linkoptsözelliği ise genelliklegles_linkopts()bağımlılıklarını içerir. LiteRT genellikle Android'de OpenGLES kullandığından her ikisi de GPU hızlandırma için son derece önemlidir. - Model dosyaları ve diğer öğeler:
dataözelliği aracılığıyla eklenir.
Aşağıda bir cc_binary kuralı örneği verilmiştir:
cc_binary(
name = "your_application",
srcs = [
"main.cc",
],
data = [
...
# litert c api shared library
"//litert/c:litert_runtime_c_api_shared_lib",
# GPU accelerator shared library
"@litert_gpu//:jni/arm64-v8a/libLiteRtGpuAccelerator.so",
],
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
)
Bu kurulum, derlenmiş ikilinizin hızlandırılmış makine öğrenimi çıkarımı için GPU'yu dinamik olarak yüklemesine ve kullanmasına olanak tanır.
CompiledModel API ile GPU kullanma
GPU hızlandırıcıyı kullanmaya başlamak için Derlenmiş Model'i (CompiledModel) oluştururken GPU parametresini iletin. Aşağıdaki kod snippet'inde tüm sürecin temel bir uygulaması gösterilmektedir:
C++
// 1. Load model
LITERT_ASSIGN_OR_RETURN(auto model, Model::CreateFromFile("mymodel.tflite"));
// 2. Create a compiled model targeting GPU
LITERT_ASSIGN_OR_RETURN(auto env, Environment::Create({}));
LITERT_ASSIGN_OR_RETURN(auto compiled_model, CompiledModel::Create(env, model, kLiteRtHwAcceleratorGpu));
// 3. Prepare input/output buffers
LITERT_ASSIGN_OR_RETURN(auto input_buffers, compiled_model.CreateInputBuffers());
LITERT_ASSIGN_OR_RETURN(auto output_buffers, compiled_model.CreateOutputBuffers());
// 4. Fill input data (if you have CPU-based data)
input_buffers[0].Write<float>(absl::MakeConstSpan(cpu_data, data_size));
// 5. Execute
compiled_model.Run(input_buffers, output_buffers);
// 6. Access model output
std::vector<float> data(output_data_size);
output_buffers.Read<float>(absl::MakeSpan(data));
Kotlin
// 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()
Daha fazla bilgi için C++ ile Başlarken veya Kotlin ile Başlarken kılavuzlarına bakın.
GPU hızlandırmasıyla sıfır kopyalama
Sıfır kopyalama, CPU'nun bu verileri açıkça kopyalamasına gerek kalmadan bir GPU'nun kendi belleğindeki verilere doğrudan erişmesini sağlar. Verileri CPU belleğine ve CPU belleğinden kopyalamayarak sıfır kopyalama, uçtan uca gecikmeyi önemli ölçüde azaltabilir.
Aşağıdaki kod, vektör grafiklerin oluşturulması için kullanılan bir API olan OpenGL ile Sıfır Kopyalı GPU'nun örnek bir uygulamasıdır. Kod, OpenGL arabellek biçimindeki görüntüleri doğrudan LiteRT'ye iletir:
// 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 model, Model::CreateFromFile("mymodel.tflite"));
LITERT_ASSIGN_OR_RETURN(auto env, Environment::Create({}));
LITERT_ASSIGN_OR_RETURN(auto compiled_model,
CompiledModel::Create(env, model, 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());
Eşzamansız yürütme
LiteRT'nin RunAsync() gibi eşzamansız yöntemleri, GPU çıkarımını planlamanıza olanak tanırken CPU veya NPU kullanarak diğer görevlere devam etmenizi sağlar. Karmaşık işlem hatlarında GPU genellikle CPU veya NPU'larla birlikte eşzamansız olarak kullanılır.
Aşağıdaki kod snippet'i, Zero-copy GPU
acceleration örneğinde sağlanan kodu temel alır. Kod, hem CPU hem de GPU'yu eşzamansız olarak kullanır ve giriş arabelleğine bir LiteRT Event ekler. LiteRT Event
farklı senkronizasyon temel öğelerini yönetmekten sorumludur ve aşağıdaki kod, LiteRtEventTypeEglSyncFence türünde yönetilen bir LiteRT Event nesnesi oluşturur. Bu Event nesnesi, GPU işlemi tamamlanana kadar giriş arabelleğinden okuma yapmamamızı sağlar. Tüm bu işlemler CPU kullanılmadan yapılır.
LITERT_ASSIGN_OR_RETURN(auto env, Environment::Create({}));
LITERT_ASSIGN_OR_RETURN(auto compiled_model,
CompiledModel::Create(env, model, 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));
Desteklenen modeller
LiteRT, aşağıdaki modellerde GPU hızlandırmayı destekler. Karşılaştırma testinin sonuçları, Samsung Galaxy S24 cihazda yapılan testlere dayanmaktadır.
| Model | LiteRT GPU Hızlandırma | LiteRT GPU (ms) |
|---|---|---|
| hf_mms_300m | Tam yetki verilmiş | 19,6 |
| hf_mobilevit_small | Tam yetki verilmiş | 8.7 |
| hf_mobilevit_small_e2e | Tam yetki verilmiş | 8.0 |
| hf_wav2vec2_base_960h | Tam yetki verilmiş | 9.1 |
| hf_wav2vec2_base_960h_dynamic | Tam yetki verilmiş | 9,8 |
| isnet | Tam yetki verilmiş | 43,1 |
| timm_efficientnet | Tam yetki verilmiş | 3,7 |
| timm_nfnet | Tam yetki verilmiş | 9.7 |
| timm_regnety_120 | Tam yetki verilmiş | 12.1 |
| torchaudio_deepspeech | Tam yetki verilmiş | 4,6 |
| torchaudio_wav2letter | Tam yetki verilmiş | 4.8 |
| torchvision_alexnet | Tam yetki verilmiş | 3.3 |
| torchvision_deeplabv3_mobilenet_v3_large | Tam yetki verilmiş | 5.7 |
| torchvision_deeplabv3_resnet101 | Tam yetki verilmiş | 35.1 |
| torchvision_deeplabv3_resnet50 | Tam yetki verilmiş | 24,5 |
| torchvision_densenet121 | Tam yetki verilmiş | 13,9 |
| torchvision_efficientnet_b0 | Tam yetki verilmiş | 3.6 |
| torchvision_efficientnet_b1 | Tam yetki verilmiş | 4,7 |
| torchvision_efficientnet_b2 | Tam yetki verilmiş | 5,0 |
| torchvision_efficientnet_b3 | Tam yetki verilmiş | 6.1 |
| torchvision_efficientnet_b4 | Tam yetki verilmiş | 7.6 |
| torchvision_efficientnet_b5 | Tam yetki verilmiş | 8.6 |
| torchvision_efficientnet_b6 | Tam yetki verilmiş | 11.2 |
| torchvision_efficientnet_b7 | Tam yetki verilmiş | 14.7 |
| torchvision_fcn_resnet50 | Tam yetki verilmiş | 19,9 |
| torchvision_googlenet | Tam yetki verilmiş | 3,9 |
| torchvision_inception_v3 | Tam yetki verilmiş | 8.6 |
| torchvision_lraspp_mobilenet_v3_large | Tam yetki verilmiş | 3.3 |
| torchvision_mnasnet0_5 | Tam yetki verilmiş | 2.4 |
| torchvision_mobilenet_v2 | Tam yetki verilmiş | 2.8 |
| torchvision_mobilenet_v3_large | Tam yetki verilmiş | 2.8 |
| torchvision_mobilenet_v3_small | Tam yetki verilmiş | 2.3 |
| torchvision_resnet152 | Tam yetki verilmiş | 15,0 |
| torchvision_resnet18 | Tam yetki verilmiş | 4,3 |
| torchvision_resnet50 | Tam yetki verilmiş | 6.9 |
| torchvision_squeezenet1_0 | Tam yetki verilmiş | 2.9 |
| torchvision_squeezenet1_1 | Tam yetki verilmiş | 2.5 |
| torchvision_vgg16 | Tam yetki verilmiş | 13.4 |
| torchvision_wide_resnet101_2 | Tam yetki verilmiş | 25,0 |
| torchvision_wide_resnet50_2 | Tam yetki verilmiş | 13.4 |
| u2net_full | Tam yetki verilmiş | 98,3 |
| u2net_lite | Tam yetki verilmiş | 51,4 |
| hf_distil_whisper_small_no_cache | Kısmen devredildi | 251,90 E£ |
| hf_distilbert | Kısmen devredildi | 13.7 |
| hf_tinyroberta_squad2 | Kısmen devredildi | 17.1 |
| hf_tinyroberta_squad2_dynamic_batch | Kısmen devredildi | 52.1 |
| snapml_StyleTransferNet | Kısmen devredildi | 40,9 |
| timm_efficientformer_l1 | Kısmen devredildi | 17,6 |
| timm_efficientformerv2_s0 | Kısmen devredildi | 16.1 |
| timm_pvt_v2_b1 | Kısmen devredildi | 73,5 |
| timm_pvt_v2_b3 | Kısmen devredildi | 246,70 E£ |
| timm_resnest14d | Kısmen devredildi | 88,9 |
| torchaudio_conformer | Kısmen devredildi | 21,5 |
| torchvision_convnext_tiny | Kısmen devredildi | 8.2 |
| torchvision_maxvit_t | Kısmen devredildi | 194,0 |
| torchvision_shufflenet_v2 | Kısmen devredildi | 9.5 |
| torchvision_swin_tiny | Kısmen devredildi | 164,4 |
| torchvision_video_resnet2plus1d_18 | Kısmen devredildi | 6832,0 |
| torchvision_video_swin3d_tiny | Kısmen devredildi | 2617,8 |
| yolox_tiny | Kısmen devredildi | 11.2 |