واحدهای پردازش گرافیکی (GPU) به دلیل توان عملیاتی موازی عظیمشان در مقایسه با CPU، معمولاً برای شتاب یادگیری عمیق استفاده می شوند. LiteRT Next فرآیند استفاده از شتاب GPU را با اجازه دادن به کاربران برای تعیین شتاب سخت افزاری به عنوان پارامتر هنگام ایجاد یک مدل کامپایل شده ( CompiledModel
) ساده می کند. LiteRT Next همچنین از یک پیاده سازی جدید و بهبود یافته شتاب GPU استفاده می کند که توسط LiteRT ارائه نشده است.
با شتاب GPU LiteRT Next، میتوانید بافرهای ورودی و خروجی سازگار با GPU ایجاد کنید، با دادههای خود در حافظه GPU به صفر کپی بردارید، و وظایف را به صورت ناهمزمان اجرا کنید تا موازیسازی را به حداکثر برسانید.
برای مثال اجرای LiteRT Next با پشتیبانی از GPU، به برنامه های آزمایشی زیر مراجعه کنید:
افزودن وابستگی به GPU
از مراحل زیر برای افزودن وابستگی GPU به برنامه Kotlin یا C++ خود استفاده کنید.
کاتلین
برای کاربران Kotlin، شتاب دهنده GPU داخلی است و نیازی به مراحل اضافی فراتر از راهنمای Get Started ندارد.
C++
برای کاربران ++C، باید وابستگی های برنامه را با شتاب GPU 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 در Android استفاده می کند. - فایلهای مدل و سایر داراییها : از طریق ویژگی
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، هنگام ایجاد مدل Compiled ( CompiledModel
) پارامتر GPU را ارسال کنید. قطعه کد زیر یک پیاده سازی اساسی از کل فرآیند را نشان می دهد:
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));
کاتلین
// 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()
برای اطلاعات بیشتر، به راهنمای Get Started with C++ یا Get Started with Kotlin مراجعه کنید.
LiteRT Next GPU Accelerator
شتاب دهنده GPU جدید، که فقط با LiteRT Next در دسترس است، برای مدیریت بارهای کاری هوش مصنوعی، مانند ضرب ماتریس های بزرگ و حافظه نهان KV برای LLM ها، بهینه شده است، که کارآمدتر از نسخه های قبلی است. LiteRT Next GPU Accelerator بهبودهای کلیدی زیر را نسبت به نسخه LiteRT دارد:
- پوشش گسترده اپراتور: شبکه های عصبی بزرگتر و پیچیده تر را مدیریت کنید.
- قابلیت همکاری بهتر بافر: استفاده مستقیم از بافرهای GPU را برای فریمهای دوربین، بافتهای دوبعدی یا حالتهای بزرگ LLM فعال کنید.
- پشتیبانی از اجرای Async: پیش پردازش CPU با استنتاج GPU همپوشانی دارد.
کپی صفر با شتاب GPU
استفاده از کپی صفر، یک GPU را قادر میسازد تا مستقیماً به دادهها در حافظه خود دسترسی داشته باشد بدون اینکه نیازی به کپی کردن صریح آن داده توسط CPU باشد. با کپی نکردن داده ها از حافظه CPU و از آن، کپی صفر می تواند تأخیر انتها به انتها را به میزان قابل توجهی کاهش دهد.
کد زیر نمونه ای از پیاده سازی Zero-Copy GPU با OpenGL است، یک API برای رندر کردن گرافیک های برداری. کد تصاویر را در قالب بافر OpenGL مستقیماً به 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());
اجرای ناهمزمان
روشهای ناهمزمان LiteRT، مانند RunAsync()
به شما امکان میدهد استنتاج GPU را برنامهریزی کنید در حالی که کارهای دیگر را با استفاده از CPU یا NPU ادامه میدهید. در خطوط لوله پیچیده، GPU اغلب به صورت ناهمزمان در کنار CPU یا NPU استفاده می شود.
قطعه کد زیر بر اساس کد ارائه شده در مثال شتاب GPU Zero-copy ساخته شده است. کد از CPU و GPU به صورت ناهمزمان استفاده می کند و یک Event
LiteRT را به بافر ورودی متصل می کند. LiteRT Event
مسئول مدیریت انواع مختلفی از همگام سازی های اولیه است و کد زیر یک شی رویداد 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 Next از شتاب GPU با مدل های زیر پشتیبانی می کند. نتایج بنچمارک بر اساس آزمایشهایی است که روی دستگاه گلکسی S24 سامسونگ انجام شده است.
مدل | شتاب پردازنده گرافیکی LiteRT | LiteRT GPU (ms) |
---|---|---|
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 |
isnet | کاملا تفویض شده | 43.1 |
timm_efficientnet | کاملا تفویض شده | 3.7 |
timm_nfnet | کاملا تفویض شده | 9.7 |
timm_regnety_120 | کاملا تفویض شده | 12.1 |
torchaudio_deeppeech | کاملا تفویض شده | 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 |