आईओएस के लिए जीपीयू त्वरण प्रतिनिधि

अपने मशीन लर्निंग (एमएल) मॉडल को चलाने के लिए ग्राफिक्स प्रोसेसिंग यूनिट (जीपीयू) का उपयोग करने से आपके मॉडल के प्रदर्शन और आपके एमएल-सक्षम अनुप्रयोगों के उपयोगकर्ता अनुभव में नाटकीय रूप से सुधार हो सकता है। iOS उपकरणों पर, आप एक प्रतिनिधि का उपयोग करके अपने मॉडलों के GPU-त्वरित निष्पादन के उपयोग को सक्षम कर सकते हैं। प्रतिनिधि TensorFlow Lite के लिए हार्डवेयर ड्राइवर के रूप में कार्य करते हैं, जिससे आप अपने मॉडल का कोड GPU प्रोसेसर पर चला सकते हैं।

यह पृष्ठ बताता है कि iOS ऐप्स में TensorFlow Lite मॉडल के लिए GPU त्वरण को कैसे सक्षम किया जाए। सर्वोत्तम प्रथाओं और उन्नत तकनीकों सहित, TensorFlow Lite के लिए GPU प्रतिनिधि का उपयोग करने के बारे में अधिक जानकारी के लिए, GPU प्रतिनिधि पृष्ठ देखें।

इंटरप्रेटर एपीआई के साथ जीपीयू का उपयोग करें

टेन्सरफ्लो लाइट इंटरप्रेटर एपीआई मशीन लर्निंग एप्लिकेशन बनाने के लिए सामान्य प्रयोजन एपीआई का एक सेट प्रदान करता है। निम्नलिखित निर्देश आपको iOS ऐप में GPU समर्थन जोड़ने में मार्गदर्शन करते हैं। यह मार्गदर्शिका मानती है कि आपके पास पहले से ही एक iOS ऐप है जो TensorFlow Lite के साथ एक ML मॉडल को सफलतापूर्वक निष्पादित कर सकता है।

GPU समर्थन को शामिल करने के लिए पॉडफ़ाइल को संशोधित करें

TensorFlow Lite 2.3.0 रिलीज के साथ शुरू करके, बाइनरी आकार को कम करने के लिए GPU प्रतिनिधि को पॉड से बाहर रखा गया है। आप TensorFlowLiteSwift पॉड के लिए एक उप-विशिष्टता निर्दिष्ट करके उन्हें शामिल कर सकते हैं:

pod 'TensorFlowLiteSwift/Metal', '~> 0.0.1-nightly',

या

pod 'TensorFlowLiteSwift', '~> 0.0.1-nightly', :subspecs => ['Metal']

यदि आप ऑब्जेक्टिव-सी का उपयोग करना चाहते हैं, जो 2.4.0 और उच्चतर संस्करणों या सी एपीआई के लिए उपलब्ध है, तो आप TensorFlowLiteObjC या TensorFlowLiteC भी उपयोग कर सकते हैं।

प्रारंभ करें और GPU प्रतिनिधि का उपयोग करें

आप कई प्रोग्रामिंग भाषाओं के साथ TensorFlow Lite इंटरप्रेटर एपीआई के साथ GPU प्रतिनिधि का उपयोग कर सकते हैं। स्विफ्ट और ऑब्जेक्टिव-सी की सिफारिश की जाती है, लेकिन आप सी++ और सी का भी उपयोग कर सकते हैं। यदि आप 2.4 से पहले टेन्सरफ्लो लाइट के संस्करण का उपयोग कर रहे हैं तो सी का उपयोग करना आवश्यक है। निम्नलिखित कोड उदाहरण बताते हैं कि इनमें से प्रत्येक भाषा के साथ प्रतिनिधि का उपयोग कैसे किया जाए।

तीव्र

import TensorFlowLite

// Load model ...

// Initialize TensorFlow Lite interpreter with the GPU delegate.
let delegate = MetalDelegate()
if let interpreter = try Interpreter(modelPath: modelPath,
                                      delegates: [delegate]) {
  // Run inference ...
}
      

उद्देश्य सी

// Import module when using CocoaPods with module support
@import TFLTensorFlowLite;

// Or import following headers manually
#import "tensorflow/lite/objc/apis/TFLMetalDelegate.h"
#import "tensorflow/lite/objc/apis/TFLTensorFlowLite.h"

// Initialize GPU delegate
TFLMetalDelegate* metalDelegate = [[TFLMetalDelegate alloc] init];

// Initialize interpreter with model path and GPU delegate
TFLInterpreterOptions* options = [[TFLInterpreterOptions alloc] init];
NSError* error = nil;
TFLInterpreter* interpreter = [[TFLInterpreter alloc]
                                initWithModelPath:modelPath
                                          options:options
                                        delegates:@[ metalDelegate ]
                                            error:&error];
if (error != nil) { /* Error handling... */ }

if (![interpreter allocateTensorsWithError:&error]) { /* Error handling... */ }
if (error != nil) { /* Error handling... */ }

// Run inference ...
      

सी++

// Set up interpreter.
auto model = FlatBufferModel::BuildFromFile(model_path);
if (!model) return false;
tflite::ops::builtin::BuiltinOpResolver op_resolver;
std::unique_ptr<Interpreter> interpreter;
InterpreterBuilder(*model, op_resolver)(&interpreter);

// Prepare GPU delegate.
auto* delegate = TFLGpuDelegateCreate(/*default options=*/nullptr);
if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;

// Run inference.
WriteToInputTensor(interpreter->typed_input_tensor<float>(0));
if (interpreter->Invoke() != kTfLiteOk) return false;
ReadFromOutputTensor(interpreter->typed_output_tensor<float>(0));

// Clean up.
TFLGpuDelegateDelete(delegate);
      

सी (2.4.0 से पहले)

#include "tensorflow/lite/c/c_api.h"
#include "tensorflow/lite/delegates/gpu/metal_delegate.h"

// Initialize model
TfLiteModel* model = TfLiteModelCreateFromFile(model_path);

// Initialize interpreter with GPU delegate
TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();
TfLiteDelegate* delegate = TFLGPUDelegateCreate(nil);  // default config
TfLiteInterpreterOptionsAddDelegate(options, metal_delegate);
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);
TfLiteInterpreterOptionsDelete(options);

TfLiteInterpreterAllocateTensors(interpreter);

NSMutableData *input_data = [NSMutableData dataWithLength:input_size * sizeof(float)];
NSMutableData *output_data = [NSMutableData dataWithLength:output_size * sizeof(float)];
TfLiteTensor* input = TfLiteInterpreterGetInputTensor(interpreter, 0);
const TfLiteTensor* output = TfLiteInterpreterGetOutputTensor(interpreter, 0);

// Run inference
TfLiteTensorCopyFromBuffer(input, inputData.bytes, inputData.length);
TfLiteInterpreterInvoke(interpreter);
TfLiteTensorCopyToBuffer(output, outputData.mutableBytes, outputData.length);

// Clean up
TfLiteInterpreterDelete(interpreter);
TFLGpuDelegateDelete(metal_delegate);
TfLiteModelDelete(model);
      

GPU API भाषा उपयोग नोट्स

  • 2.4.0 से पहले के TensorFlow Lite संस्करण केवल ऑब्जेक्टिव-सी के लिए C API का उपयोग कर सकते हैं।
  • C++ API केवल तभी उपलब्ध होता है जब आप बेज़ेल का उपयोग कर रहे हों या स्वयं TensorFlow Lite का निर्माण कर रहे हों। C++ API का उपयोग CocoaPods के साथ नहीं किया जा सकता.
  • C++ के साथ GPU प्रतिनिधि के साथ TensorFlow Lite का उपयोग करते समय, TFLGpuDelegateCreate() फ़ंक्शन के माध्यम से GPU प्रतिनिधि प्राप्त करें और फिर इसे Interpreter::ModifyGraphWithDelegate() Interpreter::AllocateTensors() पर पास करें।

रिलीज़ मोड के साथ निर्माण और परीक्षण करें

बेहतर प्रदर्शन और अंतिम परीक्षण के लिए उपयुक्त मेटल एपीआई एक्सेलेरेटर सेटिंग्स के साथ रिलीज बिल्ड में बदलाव करें। यह अनुभाग बताता है कि मेटल एक्सेलेरेशन के लिए रिलीज़ बिल्ड और कॉन्फिगर सेटिंग को कैसे सक्षम किया जाए।

रिलीज़ बिल्ड में बदलने के लिए:

  1. उत्पाद > योजना > योजना संपादित करें... का चयन करके और फिर चलाएँ का चयन करके बिल्ड सेटिंग्स संपादित करें।
  2. जानकारी टैब पर, बिल्ड कॉन्फ़िगरेशन को रिलीज़ में बदलें और डीबग निष्पादन योग्य को अनचेक करें।रिलीज की स्थापना
  3. विकल्प टैब पर क्लिक करें और GPU फ़्रेम कैप्चर को अक्षम और मेटल एपीआई सत्यापन को अक्षम में बदलें।
    धातु विकल्प स्थापित करना
  4. 64-बिट आर्किटेक्चर पर केवल-रिलीज़ बिल्ड का चयन करना सुनिश्चित करें। प्रोजेक्ट नेविगेटर के अंतर्गत > tflite_camera_example > PROJECT > your_project_name > बिल्ड सेटिंग्स सेट करें केवल सक्रिय आर्किटेक्चर बनाएँ > हाँ पर रिलीज़ करें। रिलीज़ विकल्प सेट करना

उन्नत जीपीयू समर्थन

यह अनुभाग iOS के लिए GPU प्रतिनिधि के उन्नत उपयोगों को शामिल करता है, जिसमें प्रतिनिधि विकल्प, इनपुट और आउटपुट बफ़र्स और परिमाणित मॉडल का उपयोग शामिल है।

आईओएस के लिए प्रतिनिधि विकल्प

GPU प्रतिनिधि के लिए कंस्ट्रक्टर स्विफ्ट एपीआई , ऑब्जेक्टिव-सी एपीआई और सी एपीआई में विकल्पों की एक struct स्वीकार करता है। इनिशियलाइज़र nullptr (C API) या कुछ भी नहीं (ऑब्जेक्टिव-C और स्विफ्ट API) पास करने से डिफ़ॉल्ट विकल्प सेट हो जाते हैं (जो ऊपर मूल उपयोग उदाहरण में बताए गए हैं)।

तीव्र

// THIS:
var options = MetalDelegate.Options()
options.isPrecisionLossAllowed = false
options.waitType = .passive
options.isQuantizationEnabled = true
let delegate = MetalDelegate(options: options)

// IS THE SAME AS THIS:
let delegate = MetalDelegate()
      

उद्देश्य सी

// THIS:
TFLMetalDelegateOptions* options = [[TFLMetalDelegateOptions alloc] init];
options.precisionLossAllowed = false;
options.waitType = TFLMetalDelegateThreadWaitTypePassive;
options.quantizationEnabled = true;

TFLMetalDelegate* delegate = [[TFLMetalDelegate alloc] initWithOptions:options];

// IS THE SAME AS THIS:
TFLMetalDelegate* delegate = [[TFLMetalDelegate alloc] init];
      

सी

// THIS:
const TFLGpuDelegateOptions options = {
  .allow_precision_loss = false,
  .wait_type = TFLGpuDelegateWaitType::TFLGpuDelegateWaitTypePassive,
  .enable_quantization = true,
};

TfLiteDelegate* delegate = TFLGpuDelegateCreate(options);

// IS THE SAME AS THIS:
TfLiteDelegate* delegate = TFLGpuDelegateCreate(nullptr);
      

C++ API का उपयोग करके इनपुट/आउटपुट बफ़र्स

GPU पर गणना के लिए आवश्यक है कि डेटा GPU के लिए उपलब्ध हो। इस आवश्यकता का अर्थ अक्सर यह होता है कि आपको एक मेमोरी कॉपी निष्पादित करनी होगी। यदि संभव हो तो आपको अपने डेटा को सीपीयू/जीपीयू मेमोरी सीमा पार करने से बचना चाहिए, क्योंकि इसमें काफी समय लग सकता है। आमतौर पर, ऐसी क्रॉसिंग अपरिहार्य है, लेकिन कुछ विशेष मामलों में, एक या दूसरे को छोड़ा जा सकता है।

यदि नेटवर्क का इनपुट पहले से ही GPU मेमोरी में लोड की गई छवि है (उदाहरण के लिए, कैमरा फ़ीड वाली GPU बनावट) तो यह CPU मेमोरी में प्रवेश किए बिना GPU मेमोरी में रह सकता है। इसी तरह, यदि नेटवर्क का आउटपुट रेंडर करने योग्य छवि के रूप में है, जैसे छवि शैली स्थानांतरण ऑपरेशन, तो आप परिणाम को सीधे स्क्रीन पर प्रदर्शित कर सकते हैं।

सर्वोत्तम प्रदर्शन प्राप्त करने के लिए, TensorFlow Lite उपयोगकर्ताओं के लिए TensorFlow हार्डवेयर बफ़र से सीधे पढ़ना और लिखना और टालने योग्य मेमोरी प्रतियों को बायपास करना संभव बनाता है।

यह मानते हुए कि छवि इनपुट GPU मेमोरी में है, आपको पहले इसे मेटल के लिए MTLBuffer ऑब्जेक्ट में परिवर्तित करना होगा। आप TFLGpuDelegateBindMetalBufferToTensor() फ़ंक्शन के साथ TfLiteTensor को उपयोगकर्ता द्वारा तैयार MTLBuffer से जोड़ सकते हैं। ध्यान दें कि इस फ़ंक्शन को Interpreter::ModifyGraphWithDelegate() के बाद कॉल किया जाना चाहिए । इसके अतिरिक्त, अनुमान आउटपुट, डिफ़ॉल्ट रूप से, GPU मेमोरी से CPU मेमोरी में कॉपी किया जाता है। आप आरंभीकरण के दौरान Interpreter::SetAllowBufferHandleOutput(true) कॉल करके इस व्यवहार को बंद कर सकते हैं।

सी++

#include "tensorflow/lite/delegates/gpu/metal_delegate.h"
#include "tensorflow/lite/delegates/gpu/metal_delegate_internal.h"

// ...

// Prepare GPU delegate.
auto* delegate = TFLGpuDelegateCreate(nullptr);

if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;

interpreter->SetAllowBufferHandleOutput(true);  // disable default gpu->cpu copy
if (!TFLGpuDelegateBindMetalBufferToTensor(
        delegate, interpreter->inputs()[0], user_provided_input_buffer)) {
  return false;
}
if (!TFLGpuDelegateBindMetalBufferToTensor(
        delegate, interpreter->outputs()[0], user_provided_output_buffer)) {
  return false;
}

// Run inference.
if (interpreter->Invoke() != kTfLiteOk) return false;
      

एक बार डिफ़ॉल्ट व्यवहार बंद हो जाने पर, GPU मेमोरी से सीपीयू मेमोरी में अनुमान आउटपुट को कॉपी करने के लिए प्रत्येक आउटपुट टेंसर के लिए Interpreter::EnsureTensorDataIsReadable() पर एक स्पष्ट कॉल की आवश्यकता होती है। यह दृष्टिकोण क्वांटाइज्ड मॉडल के लिए भी काम करता है, लेकिन आपको अभी भी फ्लोट32 डेटा के साथ फ्लोट32 आकार के बफर का उपयोग करने की आवश्यकता है, क्योंकि बफर आंतरिक डी-क्वांटाइज्ड बफर से जुड़ा हुआ है।

परिमाणित मॉडल

आईओएस जीपीयू प्रतिनिधि पुस्तकालय डिफ़ॉल्ट रूप से परिमाणित मॉडल का समर्थन करते हैं । आपको GPU प्रतिनिधि के साथ परिमाणित मॉडल का उपयोग करने के लिए कोई कोड परिवर्तन करने की आवश्यकता नहीं है। निम्नलिखित अनुभाग बताता है कि परीक्षण या प्रयोगात्मक उद्देश्यों के लिए परिमाणित समर्थन को कैसे अक्षम किया जाए।

परिमाणित मॉडल समर्थन अक्षम करें

निम्नलिखित कोड दिखाता है कि परिमाणित मॉडलों के लिए समर्थन को कैसे अक्षम किया जाए

तीव्र

    var options = MetalDelegate.Options()
    options.isQuantizationEnabled = false
    let delegate = MetalDelegate(options: options)
      

उद्देश्य सी

    TFLMetalDelegateOptions* options = [[TFLMetalDelegateOptions alloc] init];
    options.quantizationEnabled = false;
      

सी

    TFLGpuDelegateOptions options = TFLGpuDelegateOptionsDefault();
    options.enable_quantization = false;

    TfLiteDelegate* delegate = TFLGpuDelegateCreate(options);
      

GPU त्वरण के साथ क्वांटाइज़्ड मॉडल चलाने के बारे में अधिक जानकारी के लिए, GPU प्रतिनिधि अवलोकन देखें।