Njësitë e përpunimit grafik (GPU) përdoren zakonisht për përshpejtimin e të mësuarit të thellë për shkak të xhiros së tyre masive paralele në krahasim me CPU-të. LiteRT Next thjeshton procesin e përdorimit të përshpejtimit të GPU-së duke i lejuar përdoruesit të specifikojnë përshpejtimin e harduerit si parametër kur krijojnë një Model të përpiluar ( CompiledModel
). LiteRT Next përdor gjithashtu një zbatim të ri dhe të përmirësuar të përshpejtimit të GPU, që nuk ofrohet nga LiteRT.
Me përshpejtimin e GPU-së së LiteRT Next, mund të krijoni bufera hyrëse dhe dalëse të përshtatshme për GPU-në, të arrini kopjim zero me të dhënat tuaja në memorien GPU dhe të ekzekutoni detyra në mënyrë asinkrone për të maksimizuar paralelizmin.
Për shembull, zbatimet e LiteRT Next me mbështetje GPU, referojuni aplikacioneve demo të mëposhtme:
Shtoni varësinë nga GPU
Përdorni hapat e mëposhtëm për të shtuar varësinë e GPU në aplikacionin tuaj Kotlin ose C++.
Kotlin
Për përdoruesit e Kotlin, përshpejtuesi GPU është i integruar dhe nuk kërkon hapa shtesë përtej udhëzuesit Get Started .
C++
Për përdoruesit e C++, duhet të ndërtoni varësitë e aplikacionit me përshpejtimin e LiteRT GPU. Rregulli cc_binary
që paketon logjikën bazë të aplikacionit (p.sh., main.cc
) kërkon komponentët e mëposhtëm të ekzekutimit:
- Biblioteka e përbashkët e LiteRT C API : atributi i
data
duhet të përfshijë bibliotekën e përbashkët LiteRT C API (//litert/c:litert_runtime_c_api_shared_lib
) dhe komponentët specifikë të GPU-së (@litert_gpu//:jni/arm64-v8a/libLiteRtGpuAccelerator.so
). - Varësitë e atributeve : Atributi
deps
zakonisht përfshin varësitë GLESgles_deps()
dhelinkopts
zakonisht përfshingles_linkopts()
. Të dyja janë shumë të rëndësishme për përshpejtimin e GPU, pasi LiteRT shpesh përdor OpenGLES në Android. - Skedarët e modelit dhe asetet e tjera : Përfshihen përmes atributit të
data
.
Më poshtë është një shembull i një rregulli cc_binary
:
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
)
Ky konfigurim lejon që binarja juaj e përpiluar të ngarkojë dhe përdorë në mënyrë dinamike GPU-në për konkluzionet e përshpejtuara të mësimit të makinerive.
Filloni
Për të filluar përdorimin e përshpejtuesit GPU, kaloni parametrin GPU kur krijoni Modelin e Përpiluar ( CompiledModel
). Pjesa e mëposhtme e kodit tregon një zbatim bazë të të gjithë procesit:
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()
Për më shumë informacion, shihni udhëzuesit Filloni me C++ ose Filloni me Kotlin .
LiteRT Next GPU Accelerator
Përshpejtuesi i ri GPU, i disponueshëm vetëm me LiteRT Next, është i optimizuar për të trajtuar ngarkesat e punës së AI, si shumëzimet e matricave të mëdha dhe cache KV për LLM, në mënyrë më efikase se versionet e mëparshme. LiteRT Next GPU Accelerator përmban përmirësimet kryesore të mëposhtme mbi versionin LiteRT:
- Mbulimi i zgjeruar i operatorit: Trajtoni rrjete nervore më të mëdha dhe më komplekse.
- Ndërveprim më i mirë i bufferit: Aktivizoni përdorimin e drejtpërdrejtë të buferave të GPU për kornizat e kamerës, teksturat 2D ose gjendjet e mëdha LLM.
- Mbështetje për ekzekutimin e asinkronizuar: Mbivendosja e para-përpunimit të CPU-së me konkluzionet e GPU-së.
Zero-kopje me përshpejtimin e GPU
Përdorimi i kopjimit zero i mundëson një GPU të aksesojë të dhënat drejtpërdrejt në memorien e tij, pa pasur nevojë që CPU t'i kopjojë në mënyrë eksplicite ato të dhëna. Duke mos kopjuar të dhëna nga dhe nga memoria e CPU-së, kopjimi zero mund të reduktojë ndjeshëm vonesën nga skaji në skaj.
Kodi i mëposhtëm është një shembull i zbatimit të Zero-Copy GPU me OpenGL , një API për paraqitjen e grafikëve vektoriale. Kodi i kalon imazhet në formatin e tamponit OpenGL direkt në LiteRT Next:
// 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());
Ekzekutimi asinkron
Metodat asinkrone të LiteRT, si RunAsync()
, ju lejojnë të planifikoni konkluzionet e GPU ndërsa vazhdoni detyra të tjera duke përdorur CPU ose NPU. Në tubacionet komplekse, GPU shpesh përdoret në mënyrë asinkrone së bashku me CPU ose NPU.
Pjesa e mëposhtme e kodit bazohet në kodin e dhënë në shembullin e përshpejtimit të GPU-së me kopje Zero . Kodi përdor CPU-në dhe GPU-në në mënyrë asinkrone dhe bashkëngjit një Event
LiteRT në buferin e hyrjes. LiteRT Event
është përgjegjës për menaxhimin e llojeve të ndryshme të primitivëve të sinkronizimit dhe kodi i mëposhtëm krijon një objekt të menaxhuar LiteRT Event të llojit LiteRtEventTypeEglSyncFence
. Ky objekt Event
siguron që ne të mos lexojmë nga buferi i hyrjes derisa të përfundojë GPU. E gjithë kjo bëhet pa përfshirë CPU-në.
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));
Modelet e mbështetura
LiteRT Next mbështet përshpejtimin GPU me modelet e mëposhtme. Rezultatet e standardeve bazohen në testet e kryera në një pajisje Samsung Galaxy S24.
Model | Përshpejtimi i GPU LiteRT | LiteRT GPU (ms) |
---|---|---|
hf_mms_300m | I deleguar plotësisht | 19.6 |
hf_mobilevit_small | I deleguar plotësisht | 8.7 |
hf_mobilevit_small_e2e | I deleguar plotësisht | 8.0 |
hf_wav2vec2_bazë_960h | I deleguar plotësisht | 9.1 |
hf_wav2vec2_base_960h_dynamic | I deleguar plotësisht | 9.8 |
isnet | I deleguar plotësisht | 43.1 |
timm_efficientnet | I deleguar plotësisht | 3.7 |
timm_nfnet | I deleguar plotësisht | 9.7 |
timm_regnety_120 | I deleguar plotësisht | 12.1 |
torchaudio_deeppeech | I deleguar plotësisht | 4.6 |
shkronja torchaudio_wav2 | I deleguar plotësisht | 4.8 |
torchvision_alexnet | I deleguar plotësisht | 3.3 |
torchvision_deeplabv3_mobilenet_v3_large | I deleguar plotësisht | 5.7 |
torchvision_deeplabv3_resnet101 | I deleguar plotësisht | 35.1 |
torchvision_deeplabv3_resnet50 | I deleguar plotësisht | 24.5 |
torchvision_densenet121 | I deleguar plotësisht | 13.9 |
torchvision_efficientnet_b0 | I deleguar plotësisht | 3.6 |
torchvision_efficientnet_b1 | I deleguar plotësisht | 4.7 |
torchvision_efficientnet_b2 | I deleguar plotësisht | 5.0 |
torchvision_efficientnet_b3 | I deleguar plotësisht | 6.1 |
torchvision_efficientnet_b4 | I deleguar plotësisht | 7.6 |
torchvision_efficientnet_b5 | I deleguar plotësisht | 8.6 |
torchvision_efficientnet_b6 | I deleguar plotësisht | 11.2 |
torchvision_efficientnet_b7 | I deleguar plotësisht | 14.7 |
torchvision_fcn_resnet50 | I deleguar plotësisht | 19.9 |
torchvision_googlenet | I deleguar plotësisht | 3.9 |
torchvision_inception_v3 | I deleguar plotësisht | 8.6 |
torchvision_lraspp_mobilenet_v3_large | I deleguar plotësisht | 3.3 |
torchvision_mnasnet0_5 | I deleguar plotësisht | 2.4 |
torchvision_mobilenet_v2 | I deleguar plotësisht | 2.8 |
torchvision_mobilenet_v3_large | I deleguar plotësisht | 2.8 |
torchvision_mobilenet_v3_small | I deleguar plotësisht | 2.3 |
torchvision_resnet152 | I deleguar plotësisht | 15.0 |
torchvision_resnet18 | I deleguar plotësisht | 4.3 |
torchvision_resnet50 | I deleguar plotësisht | 6.9 |
torchvision_squeezenet1_0 | I deleguar plotësisht | 2.9 |
torchvision_squeezenet1_1 | I deleguar plotësisht | 2.5 |
pishtari_vgg16 | I deleguar plotësisht | 13.4 |
torchvision_wide_resnet101_2 | I deleguar plotësisht | 25.0 |
torchvision_wide_resnet50_2 | I deleguar plotësisht | 13.4 |
u2net_plot | I deleguar plotësisht | 98.3 |
u2net_lite | I deleguar plotësisht | 51.4 |
hf_distil_whisper_small_no_cache | Pjesërisht e deleguar | 251.9 |
hf_distilbert | Pjesërisht e deleguar | 13.7 |
hf_tinyroberta_squad2 | Pjesërisht e deleguar | 17.1 |
hf_tinyroberta_squad2_dynamic_batch | Pjesërisht e deleguar | 52.1 |
snapml_StyleTransferNet | Pjesërisht e deleguar | 40.9 |
timm_efektivformer_l1 | Pjesërisht e deleguar | 17.6 |
timm_efficientformerv2_s0 | Pjesërisht e deleguar | 16.1 |
timm_pvt_v2_b1 | Pjesërisht e deleguar | 73.5 |
timm_pvt_v2_b3 | Pjesërisht e deleguar | 246.7 |
timm_resnest14d | Pjesërisht e deleguar | 88.9 |
torchaudio_conformer | Pjesërisht e deleguar | 21.5 |
torchvision_convnext_tiny | Pjesërisht e deleguar | 8.2 |
torchvision_maxvit_t | Pjesërisht e deleguar | 194.0 |
torchvision_shufflenet_v2 | Pjesërisht e deleguar | 9.5 |
torchvision_swin_tiny | Pjesërisht e deleguar | 164.4 |
torchvision_video_resnet2plus1d_18 | Pjesërisht e deleguar | 6832.0 |
torchvision_video_swin3d_tiny | Pjesërisht e deleguar | 2617.8 |
yoloks_vogël | Pjesërisht e deleguar | 11.2 |