iOS için GPU hızlandırma yetkisi

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 ve Interpreter::AllocateTensors() çağrısı yapmak yerine Interpreter::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:

  1. Ürün > Şema > Şemayı Düzenle... öğesini ve ardından Çalıştır'ı seçerek derleme ayarlarını düzenleyin.
  2. 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. çok sayıda kullanıcıya
erişmek için
  3. 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.
    metal seçeneklerini ayarlayarak
  4. 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. bu sebeple kullanıcılara
ulaşabilirsiniz.

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.