ผู้แทน GPU TensorFlow Lite

TensorFlow Lite รองรับตัวเร่งฮาร์ดแวร์หลายตัว เอกสารนี้อธิบายวิธีใช้แบ็กเอนด์ GPU โดยใช้ API ผู้รับมอบสิทธิ์ TensorFlow Lite บน Android และ iOS

GPU ได้รับการออกแบบให้มีปริมาณงานสูงสำหรับปริมาณงานแบบขนานจำนวนมาก ดังนั้น พวกมันจึงเหมาะอย่างยิ่งสำหรับโครงข่ายประสาทส่วนลึก ซึ่งประกอบด้วยตัวดำเนินการจำนวนมาก โดยแต่ละตัวทำงานบนเทนเซอร์อินพุตบางตัวที่สามารถแบ่งออกเป็นปริมาณงานที่เล็กลงอย่างง่ายดายและดำเนินการควบคู่กัน ซึ่งโดยทั่วไปแล้วจะส่งผลให้เวลาแฝงต่ำลง ในสถานการณ์ที่ดีที่สุด การอนุมานบน GPU อาจทำงานเร็วพอสำหรับแอปพลิเคชันแบบเรียลไทม์ที่ไม่พร้อมใช้งานก่อนหน้านี้

ต่างจากซีพียู GPUs คำนวณด้วยตัวเลขทศนิยม 16 บิตหรือ 32 บิต และไม่ต้องการการควอนตัมเพื่อประสิทธิภาพสูงสุด ผู้รับมอบสิทธิ์ยอมรับแบบจำลองเชิงปริมาณ 8 บิต แต่การคำนวณจะดำเนินการเป็นตัวเลขทศนิยม โปรดดูรายละเอียดใน เอกสารประกอบขั้นสูง

ข้อดีอีกประการหนึ่งของการอนุมาน GPU คือประสิทธิภาพการใช้พลังงาน GPU ดำเนินการคำนวณอย่างมีประสิทธิภาพและเหมาะสมที่สุด เพื่อให้ใช้พลังงานน้อยลงและสร้างความร้อนน้อยกว่าเมื่อทำงานเดียวกันบน CPU

บทช่วยสอนแอปสาธิต

วิธีที่ง่ายที่สุดในการทดลองใช้ผู้แทน GPU คือทำตามบทช่วยสอนด้านล่าง ซึ่งจะผ่านการสร้างแอปพลิเคชันการสาธิตการจัดหมวดหมู่ของเราด้วยการรองรับ GPU รหัส GPU เป็นเพียงเลขฐานสองสำหรับตอนนี้ มันจะเป็นโอเพ่นซอร์สเร็ว ๆ นี้ เมื่อคุณเข้าใจวิธีทำให้การสาธิตของเราทำงานแล้ว คุณสามารถลองใช้แบบจำลองที่คุณกำหนดเองได้

Android (พร้อม Android Studio)

สำหรับบทแนะนำทีละขั้นตอน โปรดดูวิดีโอ GPU Delegate สำหรับ Android

ขั้นตอนที่ 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 model จากนั้นคลิก GPU เพื่อรันบน GPU

เรียกใช้การสาธิต android gpu และเปลี่ยนเป็น gpu

iOS (พร้อม XCode)

สำหรับบทแนะนำทีละขั้นตอน โปรดดูวิดีโอ GPU Delegate สำหรับ iOS

ขั้นตอนที่ 1 รับซอร์สโค้ดสาธิตและตรวจดูให้แน่ใจว่าคอมไพล์แล้ว

ทำตามบทช่วย สอน แอปสาธิต iOS ของเรา สิ่งนี้จะนำคุณไปสู่จุดที่การสาธิตกล้อง iOS ที่ไม่ได้แก้ไขนั้นทำงานบนโทรศัพท์ของคุณ

ขั้นตอนที่ 2 แก้ไข Podfile เพื่อใช้ TensorFlow Lite GPU CocoaPod

ตั้งแต่รุ่น 2.3.0 โดยค่าเริ่มต้น ผู้รับมอบสิทธิ์ GPU จะไม่รวมอยู่ในพ็อดเพื่อลดขนาดไบนารี คุณสามารถรวมได้โดยระบุข้อกำหนดย่อย สำหรับพ็อด TensorFlowLiteSwift :

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

หรือ

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

คุณสามารถทำเช่นเดียวกันกับ TensorFlowLiteObjC หรือ TensorFlowLitC หากคุณต้องการใช้ Objective-C (จากรุ่น 2.4.0) หรือ C API

ก่อนปล่อย 2.3.0

จนถึง TensorFlow Lite 2.0.0

เราได้สร้าง CocoaPod ไบนารีที่รวมผู้แทน GPU หากต้องการเปลี่ยนโปรเจ็กต์ไปใช้ ให้แก้ไขไฟล์ "tensorflow/tensorflow/lite/examples/ios/camera/Podfile" เพื่อใช้พ็อด "TensorFlowLiteGpuExperimental" แทน "TensorFlowLite"


    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 คุณทำงานในโหมดดีบัก เพื่อให้ได้ประสิทธิภาพที่ดีขึ้น คุณควรเปลี่ยนเป็นรุ่นวางจำหน่ายด้วยการตั้งค่าโลหะที่เหมาะสมที่สุด โดยเฉพาะอย่างยิ่ง หากต้องการแก้ไขการตั้งค่าเหล่านี้ ให้ไปที่ Product > Scheme > Edit Scheme... เลือก Run บนแท็บ Info เปลี่ยน Build Configuration จาก Debug เป็น Release ยกเลิกการเลือก Debug executable

ตั้งปล่อย

จากนั้นคลิกแท็บ Options และเปลี่ยน GPU Frame Capture เป็น Disabled และ Metal API Validation เป็น Disabled

การตั้งค่าตัวเลือกโลหะ

สุดท้าย ตรวจสอบให้แน่ใจว่าได้เลือกรุ่นที่วางจำหน่ายเท่านั้นบนสถาปัตยกรรม 64 บิต ภายใต้ Project navigator -> tflite_camera_example -> PROJECT -> tflite_camera_example -> Build Settings ตั้งค่า Build Active Architecture Only > Release เป็นใช่

การตั้งค่าตัวเลือกการเปิดตัว

ลองใช้ผู้แทน GPU ในรุ่นของคุณเอง

Android

มีสองวิธีในการเรียกใช้การเร่งโมเดล ขึ้นอยู่กับว่าคุณกำลังใช้ Android Studio ML Model Binding หรือ TensorFlow Lite Interpreter

ล่าม TensorFlow Lite

ดูการสาธิตเพื่อดูวิธีเพิ่มผู้รับมอบสิทธิ์ ในแอปพลิเคชันของคุณ ให้เพิ่ม AAR ตามด้านบน นำเข้าโมดูล org.tensorflow.lite.gpu.GpuDelegate และใช้ฟังก์ชัน addDelegate เพื่อลงทะเบียนผู้รับมอบสิทธิ์ GPU ให้กับล่าม:

Kotlin

    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)
      

Java

    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

Swift

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

        ```
          

ค (จนถึง 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 ให้คุณโหลดจากโค้ดเคอร์เนลที่คอมไพล์ล่วงหน้าและข้อมูลโมเดลที่จัดลำดับและบันทึกบนดิสก์จากการรันครั้งก่อน วิธีนี้ช่วยหลีกเลี่ยงการคอมไพล์ซ้ำและลดเวลาเริ่มต้นได้ถึง 90% สำหรับคำแนะนำเกี่ยวกับวิธีการใช้การทำให้เป็นอนุกรมกับโปรเจ็กต์ของคุณ โปรดดูการทำให้เป็นอนุกรมของ ผู้รับมอบสิทธิ์ GPU