LiteRT için GPU delegeleri

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 iyileştirebilir. LiteRT, delegeler adı verilen bir donanım sürücüsü aracılığıyla GPU'ların ve diğer özel işlemcilerin kullanılmasını sağlar. LiteRT ML uygulamalarınızda GPU kullanımını etkinleştirmek aşağıdaki avantajları sağlayabilir:

  • Hız: GPU'lar, büyük ölçüde paralel iş yüklerinin yüksek verimliliği için tasarlanmıştır. Bu tasarım, her biri paralel olarak işlenebilen giriş tensörleri üzerinde çalışan çok sayıda operatörden oluşan derin nöral ağlar için uygundur. Bu da genellikle daha düşük gecikme süresiyle sonuçlanır. En iyi senaryoda, modelinizi GPU'da çalıştırmak, daha önce mümkün olmayan gerçek zamanlı uygulamaları etkinleştirecek kadar hızlı olabilir.
  • Güç verimliliği: GPU'lar, makine öğrenimi hesaplamalarını çok verimli ve optimize edilmiş bir şekilde gerçekleştirir. Genellikle daha az güç tüketir ve aynı görevin CPU'larda çalıştırılmasına kıyasla daha az ısı üretir.

Bu belgede, LiteRT'de GPU desteğine genel bakış ve GPU işlemciler için bazı gelişmiş kullanım alanları açıklanmaktadır. Belirli platformlarda GPU desteğini uygulama hakkında daha ayrıntılı bilgi için aşağıdaki kılavuzlara bakın:

GPU ML işlemleri desteği

LiteRT GPU temsilcisi tarafından hızlandırılabilecek TensorFlow makine öğrenimi işlemleri veya işlemler ile ilgili bazı sınırlamalar vardır. Temsilci, 16 bit ve 32 bit kayan nokta duyarlığında aşağıdaki işlemleri destekler:

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • LOGISTIC
  • LSTM v2 (Basic LSTM only)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

Varsayılan olarak tüm işlemler yalnızca 1. sürümde desteklenir. Kuantizasyon desteğini etkinleştirmek, uygun sürümleri (ör. ADDv2) etkinleştirir.

GPU desteğiyle ilgili sorunları giderme

İşlemlerden bazıları GPU temsilcisi tarafından desteklenmiyorsa çerçeve, grafiğin yalnızca bir bölümünü GPU'da, kalan bölümünü ise CPU'da çalıştırır. CPU/GPU senkronizasyonunun yüksek maliyeti nedeniyle, bu tür bir bölünmüş yürütme modu genellikle tüm ağın yalnızca CPU'da çalıştırılmasına kıyasla daha yavaş performansla sonuçlanır. Bu durumda uygulama, aşağıdakiler gibi uyarılar oluşturur:

WARNING: op code #42 cannot be handled by this delegate.

Bu gerçek bir çalışma zamanı hatası olmadığından bu tür hatalar için geri çağırma yoktur. Modelinizin GPU temsilcisiyle yürütülmesini test ederken şu uyarılara dikkat etmeniz gerekir. Bu uyarılardan çok sayıda olması, modelinizin GPU hızlandırma için en uygun model olmadığını gösterebilir ve modelin yeniden düzenlenmesini gerektirebilir.

Örnek modeller

Aşağıdaki örnek modeller, LiteRT ile GPU hızlandırmadan yararlanmak için oluşturulmuştur ve referans ile test amacıyla sağlanmıştır:

GPU'lar için optimizasyon

Aşağıdaki teknikler, LiteRT GPU temsilcisini kullanarak GPU donanımında modeller çalıştırırken daha iyi performans elde etmenize yardımcı olabilir:

  • Yeniden şekillendirme işlemleri: CPU'da hızlı olan bazı işlemler, mobil cihazlarda GPU için yüksek maliyetli olabilir. BATCH_TO_SPACE, SPACE_TO_BATCH, SPACE_TO_DEPTH gibi yeniden şekillendirme işlemleri özellikle maliyetlidir. Yeniden şekillendirme işlemlerinin kullanımını yakından incelemeli ve bu işlemlerin yalnızca verileri keşfetmek veya modelinizin ilk yinelemeleri için uygulanmış olabileceğini göz önünde bulundurmalısınız. Bunları kaldırmak performansı önemli ölçüde artırabilir.

  • Görüntü veri kanalları: GPU'da tensör verileri 4 kanala ayrılır. Bu nedenle, [B,H,W,5] şeklindeki bir tensör üzerinde yapılan hesaplama, [B,H,W,8] şeklindeki bir tensör üzerinde yapılan hesaplamayla yaklaşık olarak aynıdır ancak [B,H,W,4] şeklindeki bir tensör üzerinde yapılan hesaplamadan önemli ölçüde daha kötüdür. Kullandığınız kamera donanımı RGBA'daki görüntü karelerini destekliyorsa 3 kanallı RGB'den 4 kanallı RGBX'e bellek kopyalama işlemi yapılmadığı için bu 4 kanallı girişi beslemek önemli ölçüde daha hızlıdır.

  • Mobil cihazlar için optimize edilmiş modeller: En iyi performansı elde etmek için sınıflandırıcınızı mobil cihazlar için optimize edilmiş bir ağ mimarisiyle yeniden eğitmeniz gerekir. Cihaz üzerinde çıkarım için optimizasyon, mobil donanım özelliklerinden yararlanarak gecikmeyi ve güç tüketimini önemli ölçüde azaltabilir.

Gelişmiş GPU desteği

Kuantizasyon ve serileştirme gibi modellerinizde daha da iyi performans sağlamak için GPU işleme ile ek ve gelişmiş teknikler kullanabilirsiniz. Aşağıdaki bölümlerde bu teknikler daha ayrıntılı olarak açıklanmıştır.

Kuantize edilmiş modelleri kullanma

Bu bölümde, GPU temsilcisinin aşağıdakiler de dahil olmak üzere 8 bit nicelenmiş modelleri nasıl hızlandırdığı açıklanmaktadır:

Performansı optimize etmek için hem kayan nokta girişli hem de çıkışlı tensörlere sahip modeller kullanın.

Nasıl çalışır?

GPU arka ucu yalnızca kayan nokta yürütmesini desteklediğinden, nicelenmiş modelleri orijinal modelin "kayan nokta görünümünü" vererek çalıştırırız. Özet olarak bu işlem aşağıdaki adımları içerir:

  • Sabit tensörler (ör. ağırlıklar/önyargılar) GPU belleğinde bir kez niceliksizleştirilir. Bu işlem, LiteRT için temsilci etkinleştirildiğinde gerçekleşir.

  • 8 bitlik nicelendirme kullanılıyorsa GPU programının girişleri ve çıkışları her çıkarım için nicelendirilmemiş ve nicelendirilmiş (sırasıyla) olur. Bu işlem, LiteRT'nin optimize edilmiş çekirdekleri kullanılarak CPU üzerinde yapılır.

  • Kuantizasyon simülatörleri, kuantize edilmiş davranışı taklit etmek için işlemler arasına yerleştirilir. Bu yaklaşım, işlemlerin nicemleme sırasında öğrenilen sınırlara uyması beklendiği modeller için gereklidir.

Bu özelliği GPU temsilcisiyle etkinleştirme hakkında bilgi için aşağıdakilere bakın:

Serileştirme ile başlatma süresini azaltma

GPU temsilcisi özelliği, önceden derlenmiş çekirdek kodundan ve önceki çalıştırmalardan diskte serileştirilmiş ve kaydedilmiş model verilerinden yükleme yapmanıza olanak tanır. Bu yaklaşım, yeniden derlemeyi önler ve başlatma süresini %90'a kadar azaltabilir. Bu iyileştirme, disk alanının zamandan tasarruf için kullanılmasıyla sağlanır. Bu özelliği, aşağıdaki kod örneklerinde gösterildiği gibi birkaç yapılandırma seçeneğiyle etkinleştirebilirsiniz:

C++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Java

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

Serileştirme özelliğini kullanırken kodunuzun aşağıdaki uygulama kurallarına uygun olduğundan emin olun:

  • Serileştirme verilerini diğer uygulamaların erişemeyeceği bir dizinde saklayın. Android cihazlarda, geçerli uygulamaya özel bir konumu işaret eden getCodeCacheDir() kullanın.
  • Model jetonu, belirli bir model için cihaza özgü olmalıdır. farmhash::Fingerprint64 gibi kitaplıkları kullanarak model verilerinden parmak izi oluşturarak model jetonu hesaplayabilirsiniz.