واحدهای پردازش گرافیکی (GPU) به دلیل توان عملیاتی موازی عظیمشان در مقایسه با CPUها، معمولاً برای شتابدهی یادگیری عمیق استفاده میشوند. LiteRT با اجازه دادن به کاربران برای تعیین شتاب سختافزاری به عنوان یک پارامتر هنگام ایجاد یک مدل کامپایل شده ( CompiledModel )، فرآیند استفاده از شتابدهی GPU را ساده میکند.
با شتابدهی GPU در LiteRT، میتوانید بافرهای ورودی و خروجی سازگار با GPU ایجاد کنید، به کپی صفر از دادههای خود در حافظه GPU دست یابید و وظایف را به صورت ناهمزمان اجرا کنید تا موازیسازی را به حداکثر برسانید.
برای مثال، پیادهسازیهای LiteRT GPU، به برنامههای نمایشی زیر مراجعه کنید:
وابستگی به GPU را اضافه کنید
برای افزودن وابستگی به GPU به برنامه Kotlin یا C++ خود، مراحل زیر را دنبال کنید.
کاتلین
برای کاربران کاتلین، شتابدهندهی پردازندهی گرافیکی (GPU) به صورت داخلی تعبیه شده است و نیازی به مراحل اضافی فراتر از راهنمای شروع به کار ندارد.
سی++
برای کاربران ++C، شما باید وابستگیهای برنامه را با شتابدهنده گرافیکی LiteRT بسازید. قانون cc_binary که منطق اصلی برنامه (مثلاً main.cc ) را بستهبندی میکند، به اجزای زمان اجرای زیر نیاز دارد:
- کتابخانه مشترک LiteRT C API : ویژگی
dataباید شامل کتابخانه مشترک LiteRT C API (//litert/c:litert_runtime_c_api_shared_lib) و اجزای مخصوص GPU (@litert_gpu//:jni/arm64-v8a/libLiteRtGpuAccelerator.so) باشد. - وابستگیهای ویژگی : ویژگی
depsمعمولاً شامل وابستگیهای GLESgles_deps()است وlinkoptsمعمولاً شاملgles_linkopts()است. هر دو برای شتابدهی GPU بسیار مرتبط هستند، زیرا LiteRT اغلب از OpenGLES در اندروید استفاده میکند. - فایلهای مدل و سایر داراییها : از طریق ویژگی
dataگنجانده شدهاند.
مثال زیر یک قانون 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
)
این تنظیمات به فایل باینری کامپایل شده شما اجازه میدهد تا به صورت پویا بارگذاری شود و از پردازنده گرافیکی (GPU) برای استنتاج یادگیری ماشینی شتابیافته استفاده کند.
استفاده از GPU با CompiledModel API
برای شروع استفاده از شتابدهنده GPU، هنگام ایجاد مدل کامپایلشده ( CompiledModel ) پارامتر GPU را ارسال کنید. قطعه کد زیر پیادهسازی اولیه کل فرآیند را نشان میدهد:
سی++
// 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));
کاتلین
// 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» یا «شروع با کاتلین» مراجعه کنید.
کپی صفر با شتابدهی GPU
استفاده از کپی صفر، پردازنده گرافیکی (GPU) را قادر میسازد تا بدون نیاز به کپی کردن صریح دادهها توسط CPU، مستقیماً به دادهها در حافظه خود دسترسی پیدا کند. با عدم کپی کردن دادهها به و از حافظه CPU، کپی صفر میتواند تأخیر انتها به انتها را به میزان قابل توجهی کاهش دهد.
کد زیر نمونهای از پیادهسازی 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 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());
اجرای ناهمزمان
متدهای غیرهمزمان LiteRT، مانند RunAsync() ، به شما امکان میدهند استنتاج GPU را زمانبندی کنید و در عین حال به انجام سایر وظایف با استفاده از CPU یا NPU ادامه دهید. در خطوط لوله پیچیده، GPU اغلب به صورت غیرهمزمان در کنار CPU یا NPU استفاده میشود.
قطعه کد زیر بر اساس کد ارائه شده در مثال شتابدهی 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, 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));
مدلهای پشتیبانیشده
LiteRT از شتابدهی GPU با مدلهای زیر پشتیبانی میکند. نتایج بنچمارک بر اساس آزمایشهای انجام شده روی دستگاه Samsung Galaxy S24 است.
| مدل | شتابدهنده گرافیکی LiteRT | پردازنده گرافیکی LiteRT (میلیثانیه) |
|---|---|---|
| hf_mms_300m | کاملاً تفویض اختیار شده | ۱۹.۶ |
| hf_mobilevit_small | کاملاً تفویض اختیار شده | ۸.۷ |
| hf_mobilevit_small_e2e | کاملاً تفویض اختیار شده | ۸.۰ |
| hf_wav2vec2_base_960h | کاملاً تفویض اختیار شده | ۹.۱ |
| hf_wav2vec2_base_960h_dynamic | کاملاً تفویض اختیار شده | ۹.۸ |
| ایزنت | کاملاً تفویض اختیار شده | ۴۳.۱ |
| timm_efficientnet | کاملاً تفویض اختیار شده | ۳.۷ |
| تیم_ان_اف_نت | کاملاً تفویض اختیار شده | ۹.۷ |
| timm_regnety_120 | کاملاً تفویض اختیار شده | ۱۲.۱ |
| torchaudio_deepspeech | کاملاً تفویض اختیار شده | ۴.۶ |
| torchaudio_wav2letter | کاملاً تفویض اختیار شده | ۴.۸ |
| torchvision_alexnet | کاملاً تفویض اختیار شده | ۳.۳ |
| torchvision_deeplabv3_mobilenet_v3_large | کاملاً تفویض اختیار شده | ۵.۷ |
| torchvision_deeplabv3_resnet101 | کاملاً تفویض اختیار شده | ۳۵.۱ |
| torchvision_deeplabv3_resnet50 | کاملاً تفویض اختیار شده | ۲۴.۵ |
| torchvision_densenet121 | کاملاً تفویض اختیار شده | ۱۳.۹ |
| torchvision_efficientnet_b0 | کاملاً تفویض اختیار شده | ۳.۶ |
| torchvision_efficientnet_b1 | کاملاً تفویض اختیار شده | ۴.۷ |
| torchvision_efficientnet_b2 | کاملاً تفویض اختیار شده | ۵.۰ |
| torchvision_efficientnet_b3 | کاملاً تفویض اختیار شده | ۶.۱ |
| torchvision_efficientnet_b4 | کاملاً تفویض اختیار شده | ۷.۶ |
| torchvision_efficientnet_b5 | کاملاً تفویض اختیار شده | ۸.۶ |
| torchvision_efficientnet_b6 | کاملاً تفویض اختیار شده | ۱۱.۲ |
| torchvision_efficientnet_b7 | کاملاً تفویض اختیار شده | ۱۴.۷ |
| torchvision_fcn_resnet50 | کاملاً تفویض اختیار شده | ۱۹.۹ |
| torchvision_googlenet | کاملاً تفویض اختیار شده | ۳.۹ |
| torchvision_inception_v3 | کاملاً تفویض اختیار شده | ۸.۶ |
| torchvision_lraspp_mobilenet_v3_large | کاملاً تفویض اختیار شده | ۳.۳ |
| torchvision_mnasnet0_5 | کاملاً تفویض اختیار شده | ۲.۴ |
| torchvision_mobilenet_v2 | کاملاً تفویض اختیار شده | ۲.۸ |
| torchvision_mobilenet_v3_large | کاملاً تفویض اختیار شده | ۲.۸ |
| torchvision_mobilenet_v3_small | کاملاً تفویض اختیار شده | ۲.۳ |
| torchvision_resnet152 | کاملاً تفویض اختیار شده | ۱۵.۰ |
| torchvision_resnet18 | کاملاً تفویض اختیار شده | ۴.۳ |
| torchvision_resnet50 | کاملاً تفویض اختیار شده | ۶.۹ |
| torchvision_squeezenet1_0 | کاملاً تفویض اختیار شده | ۲.۹ |
| torchvision_squeezenet1_1 | کاملاً تفویض اختیار شده | ۲.۵ |
| torchvision_vgg16 | کاملاً تفویض اختیار شده | ۱۳.۴ |
| torchvision_wide_resnet101_2 | کاملاً تفویض اختیار شده | ۲۵.۰ |
| torchvision_wide_resnet50_2 | کاملاً تفویض اختیار شده | ۱۳.۴ |
| u2net_full | کاملاً تفویض اختیار شده | ۹۸.۳ |
| u2net_lite | کاملاً تفویض اختیار شده | ۵۱.۴ |
| hf_distil_whisper_small_no_cache | تا حدی تفویض شده | ۲۵۱.۹ |
| hf_distilbert | تا حدی تفویض شده | ۱۳.۷ |
| hf_tinyroberta_squad2 | تا حدی تفویض شده | ۱۷.۱ |
| hf_tinyroberta_squad2_dynamic_batch | تا حدی تفویض شده | ۵۲.۱ |
| snapml_StyleTransferNet | تا حدی تفویض شده | ۴۰.۹ |
| timm_efficientformer_l1 | تا حدی تفویض شده | ۱۷.۶ |
| timm_efficientformerv2_s0 | تا حدی تفویض شده | ۱۶.۱ |
| timm_pvt_v2_b1 | تا حدی تفویض شده | ۷۳.۵ |
| timm_pvt_v2_b3 | تا حدی تفویض شده | ۲۴۶.۷ |
| timm_resnest14d | تا حدی تفویض شده | ۸۸.۹ |
| torchaudio_conformer | تا حدی تفویض شده | ۲۱.۵ |
| torchvision_convnext_tiny | تا حدی تفویض شده | ۸.۲ |
| torchvision_maxvit_t | تا حدی تفویض شده | ۱۹۴.۰ |
| torchvision_shufflenet_v2 | تا حدی تفویض شده | ۹.۵ |
| torchvision_swin_tiny | تا حدی تفویض شده | ۱۶۴.۴ |
| torchvision_video_resnet2plus1d_18 | تا حدی تفویض شده | ۶۸۳۲.۰ |
| torchvision_video_swin3d_tiny | تا حدی تفویض شده | ۲۶۱۷.۸ |
| یولوکس_تینی | تا حدی تفویض شده | ۱۱.۲ |