نماینده GPU TensorFlow Lite

TensorFlow Lite از چندین شتاب دهنده سخت افزاری پشتیبانی می کند. این سند نحوه استفاده از پشتیبان GPU را با استفاده از APIهای نماینده TensorFlow Lite در Android و iOS شرح می دهد.

پردازنده‌های گرافیکی به گونه‌ای طراحی شده‌اند که توان عملیاتی بالایی برای بارهای کاری بسیار موازی‌پذیر داشته باشند. بنابراین، آن‌ها برای شبکه‌های عصبی عمیق، که از تعداد زیادی عملگر تشکیل شده‌اند، مناسب هستند، که هر کدام روی برخی تانسور(های) ورودی کار می‌کنند که می‌توانند به راحتی به بارهای کاری کوچک‌تر تقسیم شوند و به صورت موازی انجام شوند، که معمولاً منجر به تأخیر کمتر می‌شود. در بهترین سناریو، استنتاج بر روی GPU ممکن است اکنون برای برنامه‌های بلادرنگ که قبلاً در دسترس نبودند، سریع اجرا شود.

برخلاف پردازنده‌های مرکزی، پردازنده‌های گرافیکی با اعداد ممیز شناور ۱۶ بیتی یا ۳۲ بیتی محاسبه می‌شوند و برای عملکرد بهینه نیازی به کوانتیزاسیون ندارند. نماینده مدل های کوانتیزه 8 بیتی را می پذیرد، اما محاسبه در اعداد ممیز شناور انجام می شود. برای جزئیات بیشتر به اسناد پیشرفته مراجعه کنید.

یکی دیگر از مزایای استنتاج GPU راندمان انرژی آن است. پردازنده‌های گرافیکی محاسبات را به شیوه‌ای بسیار کارآمد و بهینه انجام می‌دهند، به طوری که نسبت به زمانی که همان کار روی CPU اجرا می‌شود، انرژی کمتری مصرف می‌کنند و گرمای کمتری تولید می‌کنند.

آموزش اپلیکیشن دمو

ساده‌ترین راه برای آزمایش نماینده GPU این است که آموزش‌های زیر را دنبال کنید، که به ساخت برنامه‌های نمایشی طبقه‌بندی ما با پشتیبانی GPU می‌پردازد. کد GPU در حال حاضر فقط باینری است. به زودی منبع باز خواهد شد. هنگامی که متوجه شدید که چگونه دموهای ما را به کار بیاندازید، می توانید این را در مدل های سفارشی خود امتحان کنید.

اندروید (با اندروید استودیو)

برای آموزش گام به گام، ویدیوی GPU Delegate برای اندروید را تماشا کنید.

مرحله 1. کد منبع TensorFlow را کلون کنید و آن را در Android Studio باز کنید

git clone https://github.com/tensorflow/tensorflow

مرحله 2. app/build.gradle را ویرایش کنید تا از GPU AAR شبانه استفاده کنید

بسته tensorflow-lite-gpu را در کنار بسته tensorflow-lite موجود در بلوک dependencies موجود اضافه کنید.

dependencies {
    ...
    implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    implementation 'org.tensorflow:tensorflow-lite-gpu:2.3.0'
}

مرحله 3. بسازید و اجرا کنید

اجرا → اجرای برنامه. هنگامی که برنامه را اجرا می کنید، دکمه ای برای فعال کردن GPU خواهید دید. از quantized به یک مدل float تغییر دهید و سپس روی GPU کلیک کنید تا روی GPU اجرا شود.

اجرای دمو اندروید gpu و تغییر به gpu

iOS (با XCode)

برای آموزش گام به گام، ویدیوی GPU Delegate برای iOS را تماشا کنید.

مرحله 1. کد منبع آزمایشی را دریافت کنید و مطمئن شوید که کامپایل شده است.

آموزش برنامه آزمایشی iOS ما را دنبال کنید. این شما را به نقطه ای می رساند که نسخه ی نمایشی دوربین iOS اصلاح نشده روی گوشی شما کار می کند.

مرحله 2. Podfile را برای استفاده از TensorFlow Lite GPU CocoaPod تغییر دهید

از نسخه 2.3.0، به طور پیش فرض نماینده GPU از پاد حذف می شود تا اندازه باینری کاهش یابد. شما می توانید آنها را با تعیین subspec اضافه کنید. برای TensorFlowLiteSwift pod:

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

یا

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

اگر می‌خواهید از Objective-C (از نسخه 2.4.0) یا C API استفاده کنید، می‌توانید به همین ترتیب برای TensorFlowLiteObjC یا TensorFlowLitC این کار را انجام دهید.

قبل از انتشار 2.3.0

تا TensorFlow Lite 2.0.0

ما یک CocoaPod باینری ساخته‌ایم که شامل نماینده GPU است. برای تغییر پروژه برای استفاده از آن، فایل «tensorflow/tensorflow/lite/examples/ios/camera/Podfile» را تغییر دهید تا به جای «TensorFlowLite» از «TensorFlowLiteGpuExperimental» استفاده کنید.


    target 'YourProjectName'
      # pod 'TensorFlowLite', '1.12.0'
      pod 'TensorFlowLiteGpuExperimental'
    

تا TensorFlow Lite 2.2.0

از TensorFlow Lite 2.1.0 تا 2.2.0، نماینده GPU در غلاف «TensorFlowLiteC» گنجانده شده است. بسته به زبان می توانید بین «TensorFlowLiteC» و «TensorFlowLiteSwift» انتخاب کنید.

مرحله 3. نماینده GPU را فعال کنید

برای فعال کردن کدی که از نماینده GPU استفاده می کند، باید TFLITE_USE_GPU_DELEGATE را از 0 به 1 در CameraExampleViewController.h تغییر دهید.

#define TFLITE_USE_GPU_DELEGATE 1

مرحله 4. برنامه آزمایشی را بسازید و اجرا کنید

پس از انجام مرحله قبل، باید بتوانید برنامه را اجرا کنید.

مرحله 5. حالت انتشار

در حالی که در مرحله 4 در حالت اشکال زدایی اجرا می‌شدید، برای به دست آوردن عملکرد بهتر، باید به نسخه‌ای با تنظیمات بهینه Metal تغییر دهید. به طور خاص، برای ویرایش این تنظیمات به مسیر Product > Scheme > Edit Scheme... بروید. Run انتخاب کنید. در برگه Info ، Build Configuration را از Debug به Release تغییر دهید، علامت Debug executable را بردارید.

راه اندازی انتشار

سپس روی زبانه Options کلیک کنید و GPU Frame Capture را به Disabled و Metal API Validation را به Disabled تغییر دهید.

راه اندازی گزینه های فلزی

در نهایت مطمئن شوید که ساخت‌های Release-Only بر اساس معماری 64 بیتی را انتخاب کنید. در Project navigator -> tflite_camera_example -> PROJECT -> tflite_camera_example -> Build Settings را تنظیم کنید Build Active Architecture Only > Release را روی Yes.

راه اندازی گزینه های انتشار

نماینده GPU را در مدل خود امتحان کنید

اندروید

بسته به اینکه از Android Studio ML Model Binding یا TensorFlow Lite Interpreter استفاده می کنید، دو راه برای فراخوانی شتاب مدل وجود دارد.

مترجم TensorFlow Lite

برای مشاهده نحوه اضافه کردن نماینده، به نسخه آزمایشی نگاه کنید. در برنامه خود، AAR را مانند بالا اضافه کنید، ماژول org.tensorflow.lite.gpu.GpuDelegate وارد کنید و از تابع addDelegate برای ثبت نماینده GPU در مفسر استفاده کنید:

کاتلین

    import org.tensorflow.lite.Interpreter
    import org.tensorflow.lite.gpu.CompatibilityList
    import org.tensorflow.lite.gpu.GpuDelegate

    val compatList = CompatibilityList()

    val options = Interpreter.Options().apply{
        if(compatList.isDelegateSupportedOnThisDevice){
            // if the device has a supported GPU, add the GPU delegate
            val delegateOptions = compatList.bestOptionsForThisDevice
            this.addDelegate(GpuDelegate(delegateOptions))
        } else {
            // if the GPU is not supported, run on 4 threads
            this.setNumThreads(4)
        }
    }

    val interpreter = Interpreter(model, options)

    // Run inference
    writeToInput(input)
    interpreter.run(input, output)
    readFromOutput(output)
      

جاوا

    import org.tensorflow.lite.Interpreter;
    import org.tensorflow.lite.gpu.CompatibilityList;
    import org.tensorflow.lite.gpu.GpuDelegate;

    // Initialize interpreter with GPU delegate
    Interpreter.Options options = new Interpreter.Options();
    CompatibilityList compatList = CompatibilityList();

    if(compatList.isDelegateSupportedOnThisDevice()){
        // if the device has a supported GPU, add the GPU delegate
        GpuDelegate.Options delegateOptions = compatList.getBestOptionsForThisDevice();
        GpuDelegate gpuDelegate = new GpuDelegate(delegateOptions);
        options.addDelegate(gpuDelegate);
    } else {
        // if the GPU is not supported, run on 4 threads
        options.setNumThreads(4);
    }

    Interpreter interpreter = new Interpreter(model, options);

    // Run inference
    writeToInput(input);
    interpreter.run(input, output);
    readFromOutput(output);
      

iOS

سریع

    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 ...
    }
      

هدف-C

    // 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 ...

        ```
          

C (تا 2.3.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);
          

## Supported Models and Ops

With the release of the GPU delegate, we included a handful of models that can
be run on the backend:

*   [MobileNet v1 (224x224) image classification](https://ai.googleblog.com/2017/06/mobilenets-open-source-models-for.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/mobilenet_v1_1.0_224.tflite)
    <br /><i>(image classification model designed for mobile and embedded based vision applications)</i>
*   [DeepLab segmentation (257x257)](https://ai.googleblog.com/2018/03/semantic-image-segmentation-with.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/deeplabv3_257_mv_gpu.tflite)
    <br /><i>(image segmentation model that assigns semantic labels (e.g., dog, cat, car) to every pixel in the input image)</i>
*   [MobileNet SSD object detection](https://ai.googleblog.com/2018/07/accelerated-training-and-inference-with.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/mobile_ssd_v2_float_coco.tflite)
    <br /><i>(image classification model that detects multiple objects with bounding boxes)</i>
*   [PoseNet for pose estimation](https://github.com/tensorflow/tfjs-models/tree/master/posenet) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/multi_person_mobilenet_v1_075_float.tflite)
    <br /><i>(vision model that estimates the poses of a person(s) in image or video)</i>

To see a full list of supported ops, please see the
[advanced documentation](gpu_advanced).

## Non-supported models and ops

If some of the ops are not supported by the GPU delegate, the framework will
only run a part of the graph on the GPU and the remaining part on the CPU. Due
to the high cost of CPU/GPU synchronization, a split execution mode like this
will often result in slower performance than when the whole network is run on
the CPU alone. In this case, the user will get a warning like:

```none
WARNING: op code #42 cannot be handled by this delegate.
```

ما برای این شکست تماسی ارائه نکردیم، زیرا این یک شکست واقعی در زمان اجرا نیست، بلکه چیزی است که توسعه‌دهنده می‌تواند در حین تلاش برای اجرای شبکه روی نماینده مشاهده کند.

نکاتی برای بهینه سازی

بهینه سازی برای دستگاه های تلفن همراه

برخی از عملیاتی که در CPU بی اهمیت هستند ممکن است هزینه بالایی برای GPU در دستگاه های تلفن همراه داشته باشند. اجرای عملیات تغییر شکل بسیار گران است، از جمله BATCH_TO_SPACE ، SPACE_TO_BATCH ، SPACE_TO_DEPTH ، و غیره. شما باید استفاده از عملیات تغییر شکل را از نزدیک بررسی کنید و در نظر بگیرید که ممکن است فقط برای کاوش داده ها یا برای تکرارهای اولیه مدل شما اعمال شده باشد. حذف آنها می تواند به طور قابل توجهی عملکرد را بهبود بخشد.

در GPU، داده های تانسور به 4 کانال تقسیم می شوند. بنابراین، محاسبه بر روی یک تانسور شکل [B,H,W,5] تقریباً روی یک تانسور شکل [B,H,W,8] یکسان عمل خواهد کرد اما به طور قابل توجهی بدتر از [B,H,W,4] . از این نظر، اگر سخت‌افزار دوربین از فریم‌های تصویر در RGBA پشتیبانی کند، می‌توان از تغذیه آن ورودی 4 کانالی به‌عنوان یک کپی حافظه (از RGB 3 کانالی تا RGBX 4 کانالی) سریع‌تر جلوگیری کرد.

برای بهترین عملکرد، باید طبقه‌بندی‌کننده را با معماری شبکه بهینه‌شده برای موبایل آموزش دهید. بهینه‌سازی برای استنباط روی دستگاه می‌تواند با بهره‌گیری از ویژگی‌های سخت‌افزاری موبایل، تأخیر و مصرف انرژی را به‌طور چشمگیری کاهش دهد.

کاهش زمان اولیه سازی با سریال سازی

ویژگی GPU delegate به شما امکان می دهد کدهای هسته از پیش کامپایل شده را بارگیری کنید و داده ها را به صورت سریالی و ذخیره شده روی دیسک از اجراهای قبلی مدل کنید. این رویکرد از کامپایل مجدد جلوگیری می کند و زمان راه اندازی را تا 90٪ کاهش می دهد. برای دستورالعمل‌های مربوط به نحوه اعمال سریال‌سازی به پروژه، به سریال‌سازی نماینده GPU مراجعه کنید.