TensorFlow Lite از چندین شتاب دهنده سخت افزاری پشتیبانی می کند. این سند نحوه استفاده از پردازنده GPU با استفاده از API های نمایندگی TensorFlow Lite در Android و iOS را توصیف می کند.
پردازنده های گرافیکی به گونه ای طراحی شده اند که برای بارهای انبوه قابل موازی سازی ، توان عملیاتی بالایی دارند. بنابراین ، آنها برای شبکه های عصبی عمیق ، که از تعداد زیادی اپراتور تشکیل شده اند ، مناسب هستند ، هر کدام روی برخی از تانسورهای ورودی کار می کنند که می توانند به راحتی به بارهای کوچکتر تقسیم شده و به صورت موازی انجام شوند ، که معمولاً منجر به تأخیر کمتری می شود. در بهترین سناریو ، ممکن است استنتاج در GPU به اندازه کافی سریع انجام شود که قبلاً در برنامه های واقعی در دسترس نبوده است.
بر خلاف پردازنده های مرکزی ، پردازنده های گرافیکی با اعداد شناور 16 بیتی یا 32 بیتی محاسبه می کنند و برای عملکرد مطلوب به مقداردهی احتیاج ندارند. نماینده مدل های کوانتیزه شده 8 بیتی را می پذیرد ، اما محاسبه در اعداد شناور انجام می شود. برای جزئیات بیشتر به اسناد پیشرفته مراجعه کنید.
یکی دیگر از مزایای استنتاج GPU بهره وری انرژی آن است. پردازنده های گرافیکی محاسبات را به روشی بسیار کارآمد و بهینه انجام می دهند ، به طوری که در مقایسه با زمانی که کار مشابهی روی پردازنده های مرکزی انجام می شود ، انرژی کمتری مصرف می کنند و گرمای کمتری تولید می کنند.
آموزش برنامه های آزمایشی
ساده ترین راه برای آزمایش نماینده GPU ، دنبال کردن آموزشهای زیر است که در ساخت برنامه های آزمایشی طبقه بندی ما با پشتیبانی GPU انجام می شود. کد GPU در حال حاضر فقط باینری است. به زودی منبع باز خواهد شد. هنگامی که نحوه کار کردن نسخه های نمایشی ما را فهمیدید ، می توانید این را در مدل های سفارشی خودتان امتحان کنید.
Android (با Android Studio)
برای آموزش گام به گام ، GPU Delegate برای ویدیوی Android را مشاهده کنید.
مرحله 1. کد منبع TensorFlow را شبیه سازی کرده و در Android Studio باز کنید
git clone https://github.com/tensorflow/tensorflow
مرحله 2. برای استفاده از GPU شبانه AAR ، app/build.gradle
ویرایش کنید
بسته 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. ساخت و اجرا
اجرا app اجرای 'برنامه'. هنگام اجرای برنامه دکمه ای برای فعال کردن پردازنده گرافیکی مشاهده خواهید کرد. از حالت کووانتی شده به مدل شناور تبدیل شده و سپس روی 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']
اگر می خواهید از API Objective-C (از نسخه 2.4.0) یا C استفاده کنید ، می توانید برای TensorFlowLiteObjC
یا TensorFlowLitC
به همین ترتیب کار کنید.
قبل از انتشار 2.3.0
تا TensorFlow Lite 2.0.0
ما یک CocoaPod باینری ساخته ایم که شامل نماینده GPU است. برای تغییر پروژه به استفاده از آن ، فایل `tensorflow / tensorflow / lite / samples / 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 در حالت اشکال زدایی اجرا می کنید ، برای به دست آوردن عملکرد بهتر ، باید به یک نسخه آزاد با تنظیمات مناسب 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
set Build Active Architecture Only > Release
to 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);
مدل ها و Ops های پشتیبانی شده
با انتشار نماینده GPU ، تعداد معدودی از مدلها را می توان در قسمت باطن اجرا کرد:
- طبقه بندی تصویر MobileNet v1 (224x224) [بارگیری]
(مدل طبقه بندی تصویر برای برنامه های دید مبتنی بر تلفن همراه و جاسازی شده طراحی شده) - تقسیم بندی DeepLab (257x257) [بارگیری]
(مدل تقسیم تصویر که برچسب های معنایی (مثلاً سگ ، گربه ، ماشین) را به هر پیکسل در تصویر ورودی اختصاص می دهد) - MobileNet SSD تشخیص شی object [بارگیری]
(مدل طبقه بندی تصویر که چندین شی را با جعبه های مرزی تشخیص می دهد) - PoseNet برای برآورد ژست [بارگیری]
(مدل بینایی که موقعیت های شخص (های) در تصویر یا فیلم را تخمین می زند)
برای دیدن لیست کاملی از عملکردهای پشتیبانی شده ، لطفاً به اسناد پیشرفته مراجعه کنید.
مدل ها و گزینه های غیر پشتیبانی شده
اگر برخی از گزینه ها توسط نماینده GPU پشتیبانی نشوند ، این چارچوب فقط بخشی از نمودار را روی GPU و قسمت باقیمانده را روی CPU اجرا می کند. به دلیل هزینه بالای همگام سازی CPU / GPU ، یک حالت اجرای تقسیم مانند این اغلب منجر به عملکرد کندتر از زمانی می شود که کل شبکه فقط روی CPU اجرا می شود. در این حالت ، کاربر هشداری مانند:
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 کاناله به طور قابل توجهی سریع تر است زیرا می توان از کپی حافظه (از 3 کانال RGB به 4 کانال RGBX) جلوگیری کرد.
برای بهترین کارایی ، از آموزش مجدد طبقه بندی با معماری شبکه بهینه شده برای تلفن همراه دریغ نکنید. این بخش قابل توجهی از بهینه سازی برای استنباط روی دستگاه است.