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:
ADDAVERAGE_POOL_2DCONCATENATIONCONV_2DDEPTHWISE_CONV_2D v1-2EXPFULLY_CONNECTEDLOGICAL_ANDLOGISTICLSTM v2 (Basic LSTM only)MAX_POOL_2DMAXIMUMMINIMUMMULPADPRELURELURELU6RESHAPERESIZE_BILINEAR v1-3SOFTMAXSTRIDED_SLICESUBTRANSPOSE_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:
- MobileNet v1 (224x224) görüntü sınıflandırması
- Mobil ve yerleşik tabanlı görme uygulamaları için tasarlanmış bir görüntü sınıflandırma modeli.
(model)
* DeepLab segmentasyonu (257x257)
- Giriş resmindeki her piksele köpek, kedi, araba gibi anlamsal etiketler atayan bir görüntü segmentasyonu modeli.
(model)
* MobileNet SSD nesne algılama
- Sınırlayıcı kutularla birden fazla nesneyi algılayan bir görüntü sınıflandırma modeli.
(model)
* Poz tahmini için PoseNet
- Resim veya videodaki kişilerin pozlarını tahmin eden bir görme modeli. (model)
- Sınırlayıcı kutularla birden fazla nesneyi algılayan bir görüntü sınıflandırma modeli.
(model)
* Poz tahmini için PoseNet
- Giriş resmindeki her piksele köpek, kedi, araba gibi anlamsal etiketler atayan bir görüntü segmentasyonu modeli.
(model)
* MobileNet SSD nesne algılama
- Mobil ve yerleşik tabanlı görme uygulamaları için tasarlanmış bir görüntü sınıflandırma modeli.
(model)
* DeepLab segmentasyonu (257x257)
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_DEPTHgibi 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:
- Kuantizasyona duyarlı eğitim ile eğitilmiş modeller
- Eğitim sonrası dinamik aralık nicemleme
- Eğitim sonrası tam sayı kuantizasyonu
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::Fingerprint64gibi kitaplıkları kullanarak model verilerinden parmak izi oluşturarak model jetonu hesaplayabilirsiniz.