Makine öğrenimi (ML) modellerinizi çalıştırmak için grafik işleme birimlerini (GPU) kullanmak, modelinizin performansını ve makine öğrenimi özellikli uygulamalarınızın kullanıcı deneyimini önemli ölçüde iyileştirebilir. iOS cihazlarda, bir yetki verilmiş kullanarak modellerinizin GPU ile hızlandırılmış yürütmesinin kullanımını etkinleştirebilirsiniz. Temsilciler, TensorFlow Lite için donanım sürücüleri görevi görür ve modelinizin kodunu GPU işlemcilerinde ç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 dahil olmak üzere TensorFlow Lite için GPU yetkilendirmesini kullanma hakkında daha fazla bilgi için GPU yetkileri sayfasına bakın.
Translateer API ile GPU kullan
TensorFlow Lite Translateer 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österecektir. Bu kılavuzda, TensorFlow Lite ile ML modelini başarıyla yürütebilecek bir iOS uygulamanızın olduğu varsayılmaktadır.
Podfile dosyasını GPU desteği içerecek şekilde değiştirme
TensorFlow Lite 2.3.0 sürümünden itibaren GPU yetkilendirmesi, ikili program boyutunu azaltmak için kapsülden hariç tutulur. TensorFlowLiteSwift
kapsülü için bir alt spesifikasyon belirterek bunları ekleyebilirsiniz:
pod 'TensorFlowLiteSwift/Metal', '~> 0.0.1-nightly',
VEYA
pod 'TensorFlowLiteSwift', '~> 0.0.1-nightly', :subspecs => ['Metal']
2.4.0 ve sonraki sürümler için sunulan Objective-C veya C API'yi kullanmak istiyorsanız TensorFlowLiteObjC
veya TensorFlowLiteC
de kullanabilirsiniz.
İlk kullanıma hazırlama ve GPU yetkilendirmesini kullanma
GPU yetkilendirmesini, birkaç programlama diliyle TensorFlow Lite Translateer API ile kullanabilirsiniz. Swift ve Objective-C önerilir, ancak C++ ve C'yi 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 örneklerinde, yetki verilmiş kullanıcının bu dillerin her birinde nasıl kullanılacağı özetlenmiştir.
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 ... }
Objective-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 kullanırken veya TensorFlow Lite'ı kendi başınıza derlerken kullanılabilir. C++ API, CocoaPods ile kullanılamaz.
- TensorFlow Lite'ı C++ ile GPU yetkilendirmesiyle birlikte kullanırken,
TFLGpuDelegateCreate()
işlevi aracılığıyla GPU yetkilendirmesini alın veInterpreter::AllocateTensors()
çağrısı yapmak yerineInterpreter::ModifyGraphWithDelegate()
işlevine iletin.
Sürüm moduyla derleme ve test etme
Daha iyi performans elde etmek ve son test için uygun Metal API hızlandırıcı ayarlarıyla sürüm derlemesine geçin. Bu bölümde, bir sürüm derlemesinin nasıl etkinleştirileceği ve Metal hızlandırma ayarını nasıl yapılandıracağınız açıklanmaktadır.
Sürüm derlemesine geçmek için:
- Ürün > Şema > Şemayı Düzenle... öğesini ve ardından Çalıştır'ı seçerek derleme ayarlarını düzenleyin.
- Bilgi sekmesinde, Derleme Yapılandırması'nı Sürüm olarak değiştirin ve Yürütülebilir hata ayıklama seçeneğinin işaretini kaldırın.
- Seçenekler sekmesini tıklayın ve GPU Çerçeve Yakalama'yı Devre Dışı olarak, Metal API Doğrulama'yı da Devre Dışı olarak değiştirin.
- 64 bit mimaride "Yalnızca sürüm" kullanılan derlemeleri seçtiğinizden emin olun. Project navigator > tflite_camera_example > PROJECT > your_project_name > Build Settings (Derleme Ayarları) bölümünde Build Active Architecture only (Yalnızca Aktif Mimari) > Sürüm seçeneğini Evet olarak ayarlayın.
Gelişmiş GPU desteği
Bu bölümde; yetki verme seçenekleri, giriş/çıkış arabellekleri ve ölçülmüş modellerin kullanımı dahil olmak üzere, iOS için GPU yetkilendirmesinin gelişmiş kullanımları ele alınmaktadır.
iOS için Seçenekler için Yetki Ver
GPU yetkilisinin oluşturucusu, Swift API, Objective-C API ve C API'deki seçenekleri struct
kabul eder.
İlk oluşturucuya nullptr
(C API) veya hiçbir şey (Objective-C ve Swift API) geçirildiğinde, varsayılan seçenekler ayarlanır (yukarıdaki Temel Kullanım örneğinde açıklanmıştır).
Swift
// 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()
Objective-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'da hesaplama işlemi, verilerin GPU'da kullanılabilir olmasını gerektirir. Bu gereksinim, genellikle bellek kopyalama işlemi gerçekleştirmeniz gerektiği anlamına gelir. Mümkünse verilerinizin CPU/GPU bellek sınırını aşmaması gerekir çünkü bu işlem çok fazla zaman alabilir. Genellikle bu tür bir geçişin olması kaçınılmazdır ancak bazı özel durumlarda, ikisinden biri atlanabilir.
Ağın girişi GPU belleğine daha önce yüklenmiş bir resimse (örneğin, kamera feed'ini içeren bir GPU dokusuysa) CPU belleğine hiç girmeden GPU belleğinde kalabilir. Benzer şekilde, ağın çıkışı resim stili aktarma işlemi gibi oluşturulabilir bir resim biçimindeyse sonucu doğrudan ekranda görüntüleyebilirsiniz.
En iyi performansı elde etmek için TensorFlow Lite, kullanıcıların doğrudan TensorFlow donanım arabelleğinden okumasına, oraya yazmasına ve kaçınılmaz bellek kopyalarını atlamasına olanak tanır.
Görüntü girişinin GPU belleğinde olduğunu varsayarsak önce bunu Metal için bir MTLBuffer
nesnesine dönüştürmeniz gerekir. TFLGpuDelegateBindMetalBufferToTensor()
işleviyle TfLiteTensor
öğesini, kullanıcı tarafından hazırlanmış bir MTLBuffer
ile ilişkilendirebilirsiniz. Bu işlevin Interpreter::ModifyGraphWithDelegate()
tarihinden sonra çağrılması gerektiğini unutmayın. Ayrıca, çıkarım çıkışı varsayılan olarak GPU belleğinden CPU belleğine kopyalanır. Başlatma sırasında Interpreter::SetAllowBufferHandleOutput(true)
yöntemini çağırarak bu özelliği 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ıktan sonra, çıkarım çıkışını GPU belleğinden CPU belleğine kopyalamak için her bir çıkış tensörü için açık bir Interpreter::EnsureTensorDataIsReadable()
çağrısı gerekir. Bu yaklaşım, nicelenmiş modeller için de işe yarar ancak arabellek, dahili nicelenmemiş arabelleğe bağlı olduğundan float32 verilerine sahip float32 boyutlu bir arabellek kullanmanız gerekir.
Nicel modeller
iOS GPU yetki kitaplıkları, varsayılan olarak sayısallaştırılmış modelleri destekler. GPU temsilcisiyle ölçülmüş modelleri kullanmak için herhangi bir kod değişikliği yapmanız gerekmez. Aşağıdaki bölümde, test veya deneysel amaçlar için nicelenmiş desteğin nasıl devre dışı bırakılacağı açıklanmaktadır.
Nicelleştirilmiş model desteğini devre dışı bırak
Aşağıdaki kod, ölçülmüş modeller için desteğin nasıl devre dışı bırakılacağını göstermektedir.
Swift
var options = MetalDelegate.Options() options.isQuantizationEnabled = false let delegate = MetalDelegate(options: options)
Objective-C
TFLMetalDelegateOptions* options = [[TFLMetalDelegateOptions alloc] init]; options.quantizationEnabled = false;
C
TFLGpuDelegateOptions options = TFLGpuDelegateOptionsDefault(); options.enable_quantization = false; TfLiteDelegate* delegate = TFLGpuDelegateCreate(options);
GPU hızlandırması ile nicelenmiş modelleri çalıştırma hakkında daha fazla bilgi için GPU yetkisi'ne genel bakış bölümüne bakın.