Makine öğrenimi (ML) modellerinizi çalıştırmak için grafik işlem birimlerini (GPU'lar) kullanmak, modelinizin performansını ve ML özellikli uygulamalarınızın kullanıcı deneyimini önemli ölçüde artırabilir. iOS cihazlarda, bir temsilci kullanarak modellerinizin GPU hızlandırmalı yürütülmesinin kullanımını etkinleştirebilirsiniz. Temsilciler, TensorFlow Lite için donanım sürücüleri görevi görerek modelinizin kodunu GPU işlemcilerde çalıştırmanıza olanak tanır.
Bu sayfada iOS uygulamalarında TensorFlow Lite modelleri için GPU hızlandırmanın nasıl etkinleştirileceği açıklanmaktadır. En iyi uygulamalar ve gelişmiş teknikler de dahil olmak üzere TensorFlow Lite için GPU temsilcisini kullanma hakkında daha fazla bilgi için GPU temsilcileri sayfasına bakın.
Tercüman API'si ile GPU'yu kullanın
TensorFlow Lite Interpreter API, makine öğrenimi uygulamaları oluşturmak için bir dizi genel amaçlı API sağlar. Aşağıdaki talimatlar, bir iOS uygulamasına GPU desteği ekleme konusunda size yol gösterir. Bu kılavuz, TensorFlow Lite ile bir ML modelini başarıyla yürütebilecek bir iOS uygulamanızın zaten olduğunu varsayar.
Pod dosyasını GPU desteğini içerecek şekilde değiştirin
TensorFlow Lite 2.3.0 sürümünden başlayarak, ikili boyutu azaltmak için GPU temsilcisi bölmeden çıkarılır. TensorFlowLiteSwift
bölmesi için bir alt özellik belirterek bunları dahil edebilirsiniz:
pod 'TensorFlowLiteSwift/Metal', '~> 0.0.1-nightly',
VEYA
pod 'TensorFlowLiteSwift', '~> 0.0.1-nightly', :subspecs => ['Metal']
2.4.0 ve üzeri sürümler için mevcut olan Objective-C'yi veya C API'yi kullanmak istiyorsanız TensorFlowLiteObjC
veya TensorFlowLiteC
de kullanabilirsiniz.
GPU temsilcisini başlat ve kullan
GPU temsilcisini TensorFlow Lite Interpreter API ile çeşitli programlama dillerinde kullanabilirsiniz. Swift ve Objective-C önerilir ancak C++ ve C de kullanabilirsiniz. TensorFlow Lite'ın 2.4'ten önceki bir sürümünü kullanıyorsanız C kullanmanız gerekir. Aşağıdaki kod örnekleri, temsilcinin bu dillerin her birinde nasıl kullanılacağını özetlemektedir.
Süratli
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 ... }
Amaç-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++
// 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);
C (2.4.0'dan önce)
#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 dili kullanım notları
- 2.4.0'dan önceki TensorFlow Lite sürümleri yalnızca Objective-C için C API'yi kullanabilir.
- C++ API yalnızca bazel kullandığınızda veya TensorFlow Lite'ı kendiniz oluşturduğunuzda kullanılabilir. C++ API, CocoaPod'larla kullanılamaz.
- TensorFlow Lite'ı C++ ile GPU temsilcisiyle kullanırken, GPU temsilcisini
TFLGpuDelegateCreate()
işlevi aracılığıyla alın ve ardından bunuInterpreter::ModifyGraphWithDelegate()
çağırmak yerineInterpreter::AllocateTensors()
öğesine iletin.
Yayın moduyla derleyin ve test edin
Daha iyi performans elde etmek ve son testler için uygun Metal API hızlandırıcı ayarlarına sahip bir sürüm yapısına geçin. Bu bölümde, bir sürüm oluşturmanın nasıl etkinleştirileceği ve Metal hızlandırma ayarının nasıl yapılandırılacağı açıklanmaktadır.
Bir sürüm yapısına geçmek için:
- Ürün > Şema > Şemayı Düzenle...'yi ve ardından Çalıştır'ı seçerek derleme ayarlarını düzenleyin.
- Bilgi sekmesinde Yapı Yapılandırmasını Serbest Bırak olarak değiştirin ve Yürütülebilir Hata Ayıklama seçeneğinin işaretini kaldırın.
- Seçenekler sekmesine tıklayın ve GPU Çerçeve Yakalamayı Devre Dışı olarak ve Metal API Doğrulamasını Devre Dışı olarak değiştirin.
- 64 bit mimaride yalnızca sürüm sürümleri seçeneğini seçtiğinizden emin olun. Proje gezgini > tflite_camera_example > PROJECT > projenizin_adı > Yapı Ayarları altında Yalnızca Etkin Mimari Oluştur > Serbest Bırak seçeneğini Evet olarak ayarlayın.
Gelişmiş GPU desteği
Bu bölüm, iOS için GPU temsilcisinin, temsilci seçenekleri, giriş ve çıkış arabellekleri ve nicelenmiş modellerin kullanımı da dahil olmak üzere gelişmiş kullanımlarını kapsar.
iOS için Delege Seçenekleri
GPU temsilcisinin yapıcısı Swift API , Objective-C API ve C API'deki seçeneklerin struct
kabul eder. Başlatıcıya nullptr
(C API) veya hiçbir şeyin (Objective-C ve Swift API) iletilmesi, varsayılan seçenekleri ayarlar (bunlar yukarıdaki Temel Kullanım örneğinde açıklanmıştır).
Süratli
// 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()
Amaç-C
// 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];
C
// 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 kullanan Giriş/Çıkış arabellekleri
GPU üzerindeki hesaplama, verilerin GPU tarafından kullanılabilir olmasını gerektirir. Bu gereksinim genellikle bir bellek kopyalaması yapmanız gerektiği anlamına gelir. Mümkünse verilerinizin CPU/GPU bellek sınırını aşmasından kaçınmalısınız çünkü bu işlem çok fazla zaman alabilir. Genellikle böyle bir geçiş kaçınılmazdır ancak bazı özel durumlarda biri veya diğeri ihmal edilebilir.
Ağın girişi GPU belleğine önceden yüklenmiş bir görüntüyse (örneğin, kamera beslemesini içeren bir GPU dokusu), CPU belleğine girmeden GPU belleğinde kalabilir. Benzer şekilde, eğer ağın çıktısı görüntü stili aktarım işlemi gibi işlenebilen bir görüntü biçimindeyse, sonucu doğrudan ekranda görüntüleyebilirsiniz.
En iyi performansı elde etmek için TensorFlow Lite, kullanıcıların TensorFlow donanım arabelleğinden doğrudan okuma ve yazma yapmasını ve önlenebilir bellek kopyalarını atlamasını mümkün kılar.
Görüntü girişinin GPU belleğinde olduğunu varsayarsak, önce bunu Metal için bir MTLBuffer
nesnesine dönüştürmeniz gerekir. Bir TfLiteTensor
TFLGpuDelegateBindMetalBufferToTensor()
işleviyle kullanıcı tarafından hazırlanan bir MTLBuffer
ile ilişkilendirebilirsiniz. Bu işlevin Interpreter::ModifyGraphWithDelegate()
öğesinden sonra çağrılması gerektiğini unutmayın. Ek olarak çıkarım çıkışı varsayılan olarak GPU belleğinden CPU belleğine kopyalanır. Başlatma sırasında Interpreter::SetAllowBufferHandleOutput(true)
çağırarak bu davranışı kapatabilirsiniz.
C++
#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;
Varsayılan davranış kapatıldığında, çıkarım çıktısının GPU belleğinden CPU belleğine kopyalanması, her çıkış tensörü için Interpreter::EnsureTensorDataIsReadable()
işlevine açık bir çağrı yapılmasını gerektirir. Bu yaklaşım aynı zamanda nicelenmiş modeller için de işe yarar, ancak yine de float32 verileriyle birlikte float32 boyutlu bir arabellek kullanmanız gerekir, çünkü arabellek dahili kuantumsuzlaştırılmış arabelleğe bağlıdır.
Nicelenmiş modeller
iOS GPU temsilci kitaplıkları varsayılan olarak nicelenmiş modelleri destekler . Nicelenmiş modelleri GPU temsilcisiyle kullanmak için herhangi bir kod değişikliği yapmanıza gerek yoktur. Aşağıdaki bölümde, test veya deneysel amaçlarla nicelenmiş desteğin nasıl devre dışı bırakılacağı açıklanmaktadır.
Nicelenmiş model desteğini devre dışı bırakın
Aşağıdaki kod, nicelenmiş modeller için desteğin nasıl devre dışı bırakılacağını gösterir.
Süratli
var options = MetalDelegate.Options() options.isQuantizationEnabled = false let delegate = MetalDelegate(options: options)
Amaç-C
TFLMetalDelegateOptions* options = [[TFLMetalDelegateOptions alloc] init]; options.quantizationEnabled = false;
C
TFLGpuDelegateOptions options = TFLGpuDelegateOptionsDefault(); options.enable_quantization = false; TfLiteDelegate* delegate = TFLGpuDelegateCreate(options);
Nicelenmiş modelleri GPU hızlandırmayla çalıştırma hakkında daha fazla bilgi için bkz. GPU temsilcisine genel bakış.