LiteRT के साथ जीपीयू ऐक्सेलरेटेड

ग्राफ़िक्स प्रोसेसिंग यूनिट (जीपीयू) का इस्तेमाल, डीप लर्निंग को बेहतर बनाने के लिए किया जाता है. ऐसा इसलिए, क्योंकि सीपीयू की तुलना में जीपीयू, पैरलल थ्रूपुट को बेहतर तरीके से मैनेज करते हैं. LiteRT, GPU ऐक्सेलरेटेड मॉडल का इस्तेमाल करने की प्रोसेस को आसान बनाता है. इसके लिए, यह उपयोगकर्ताओं को कंपाइल किया गया मॉडल (CompiledModel) बनाते समय, हार्डवेयर ऐक्सेलरेटेड मॉडल को पैरामीटर के तौर पर सेट करने की अनुमति देता है.

LiteRT के जीपीयू ऐक्सेलरेटर की मदद से, जीपीयू के साथ काम करने वाले इनपुट और आउटपुट बफ़र बनाए जा सकते हैं. साथ ही, जीपीयू मेमोरी में मौजूद डेटा को बिना कॉपी किए इस्तेमाल किया जा सकता है. इसके अलावा, टास्क को एसिंक्रोनस तरीके से पूरा किया जा सकता है, ताकि पैरललिज़्म को ज़्यादा से ज़्यादा किया जा सके.

शुरू करें

जीपीयू डिपेंडेंसी जोड़ना

अपने Kotlin या C++ ऐप्लिकेशन में GPU डिपेंडेंसी जोड़ने के लिए, यह तरीका अपनाएं.

Kotlin

Kotlin का इस्तेमाल करने वाले लोगों के लिए, GPU ऐक्सिलरेटर पहले से मौजूद होता है. इसके लिए, शुरू करें गाइड में दिए गए चरणों के अलावा, कोई और चरण पूरा करने की ज़रूरत नहीं होती.

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) शामिल होने चाहिए.
  • एट्रिब्यूट डिपेंडेंसी: आम तौर पर, deps एट्रिब्यूट में GLES डिपेंडेंसी gles_deps() शामिल होती है. साथ ही, linkopts एट्रिब्यूट में आम तौर पर gles_linkopts() शामिल होता है. ये दोनों, जीपीयू ऐक्सेलरेटेड रेंडरिंग के लिए बहुत ज़रूरी हैं. ऐसा इसलिए, क्योंकि LiteRT अक्सर Android पर OpenGLES का इस्तेमाल करता है.
  • मॉडल फ़ाइलें और अन्य ऐसेट: इन्हें 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
)

इस सेटअप की मदद से, कंपाइल किया गया बाइनरी, मशीन लर्निंग के अनुमान को बेहतर बनाने के लिए, GPU को डाइनैमिक तरीके से लोड और इस्तेमाल कर सकता है.

पहले से बनाए गए जीपीयू ऐक्सेलरेटर

नया LiteRT GPU ऐक्सेलरेटर, फ़िलहाल ओपन सोर्स नहीं है. हालांकि, प्रीबिल्ट उपलब्ध हैं. Kotlin का इस्तेमाल करने वाले लोगों के लिए, LiteRT Maven पैकेज में पहले से ही जीपीयू ऐक्सेलरेटर शामिल हैं. C++ SDK टूल का इस्तेमाल करने वाले लोगों को, इसे अलग से डाउनलोड करना होगा. इसके लिए, यह तरीका अपनाएं.

Bazel में, अपने टारगेट में डिपेंडेंसी जोड़ने के लिए, इस नियम का इस्तेमाल किया जा सकता है. cpp load("//litert/build_common:special_rule.bzl", "litert_gpu_accelerator_prebuilts")

CompiledModel API के साथ GPU का इस्तेमाल करना

जीपीयू ऐक्सेलरेटर का इस्तेमाल शुरू करने के लिए, कंपाइल किया गया मॉडल (CompiledModel) बनाते समय, GPU पैरामीटर पास करें. यहां दिए गए कोड स्निपेट में, पूरी प्रोसेस का बुनियादी तरीका दिखाया गया है:

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));

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()

ज़्यादा जानकारी के लिए, C++ का इस्तेमाल शुरू करना या Kotlin का इस्तेमाल शुरू करना गाइड देखें.

जीपीयू ऐक्सेलरेटेड रेंडरिंग के साथ ज़ीरो-कॉपी

ज़्यादातर मामलों में, ज़ीरो-कॉपी की सुविधा का इस्तेमाल करने पर, सीपीयू को डेटा कॉपी करने की ज़रूरत नहीं पड़ती. इससे जीपीयू, डेटा को सीधे तौर पर अपनी मेमोरी में ऐक्सेस कर पाता है. डेटा को सीपीयू मेमोरी में कॉपी न करने की वजह से, ज़ीरो-कॉपी से एंड-टू-एंड लेटेंसी को काफ़ी हद तक कम किया जा सकता है.

यहां दिया गया कोड, OpenGL के साथ Zero-Copy GPU को लागू करने का उदाहरण है. OpenGL, वेक्टर ग्राफ़िक रेंडर करने के लिए एक एपीआई है. यह कोड, 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(), आपको सीपीयू या एनपीयू का इस्तेमाल करके अन्य टास्क जारी रखते हुए, जीपीयू इन्फ़रेंस को शेड्यूल करने की सुविधा देते हैं. मुश्किल पाइपलाइन में, सीपीयू या एनपीयू के साथ-साथ जीपीयू का इस्तेमाल अक्सर एसिंक्रोनस तरीके से किया जाता है.

यहां दिया गया कोड स्निपेट, ज़ीरो-कॉपी जीपीयू ऐक्सेलरेटेड के उदाहरण में दिए गए कोड पर आधारित है. यह कोड, सीपीयू और जीपीयू, दोनों का इस्तेमाल एसिंक्रोनस तरीके से करता है. साथ ही, इनपुट बफ़र में LiteRT Event अटैच करता है. LiteRT Event, अलग-अलग तरह के सिंक्रनाइज़ेशन प्रिमिटिव को मैनेज करता है. साथ ही, यहां दिया गया कोड, LiteRtEventTypeEglSyncFence टाइप का मैनेज किया गया LiteRT इवेंट ऑब्जेक्ट बनाता है. यह Event ऑब्जेक्ट यह पक्का करता है कि जब तक जीपीयू का काम पूरा नहीं हो जाता, तब तक हम इनपुट बफ़र से डेटा न पढ़ें. यह सब सीपीयू के बिना किया जाता है.

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, हर प्लैटफ़ॉर्म के लिए यहां दिए गए GPU बैकएंड के साथ काम करता है.

प्लैटफ़ॉर्म बैकएंड
Android OpenCL + OpenGL
Linux WebGPU (Vulkan)
macOS मेटल
Windows WebGPU (Direct3D)
Android OpenCL + OpenGL

काम करने वाले मॉडल

LiteRT, इन मॉडल के साथ जीपीयू ऐक्सेलरेट करने की सुविधा देता है. बेंचमार्क के नतीजे, Samsung Galaxy 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_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