Genel Bakış
Bu kılavuz, GPU'larınız hakkında bilgi edinmek ve onlardan maksimum performansı elde etmek ve bir veya daha fazla GPU'nuz yeterince kullanılmadığında hata ayıklamak için TensorBoard ile TensorFlow Profiler'ı nasıl kullanacağınızı gösterecektir.
Profiler'da yeniyseniz:
- TensorFlow Profiler'ı kullanmaya başlayın: Keras örneği ve TensorBoard içeren profil modeli performans dizüstü bilgisayarı.
- Profiler kılavuzunu kullanarak TensorFlow performansını Optimize Etme ile ana bilgisayardaki (CPU) TensorFlow performansını optimize etmek için mevcut çeşitli profil oluşturma araçları ve yöntemleri hakkında bilgi edinin.
Hesaplamaların GPU'ya aktarılmasının özellikle küçük modeller için her zaman faydalı olmayabileceğini unutmayın. Aşağıdaki nedenlerden dolayı ek yük olabilir:
- Ana bilgisayar (CPU) ve cihaz (GPU) arasında veri aktarımı; Ve
- Ana bilgisayar GPU çekirdeklerini başlattığında ortaya çıkan gecikme nedeniyle.
Performans optimizasyonu iş akışı
Bu kılavuzda, tek bir GPU ile başlayıp daha sonra birden fazla GPU'lu tek bir ana bilgisayara geçiş yaparak performans sorunlarının nasıl ayıklanacağı açıklanmaktadır.
Performans sorunlarının aşağıdaki sırayla ayıklanması önerilir:
- Tek bir GPU'daki performansı optimize edin ve hata ayıklayın:
- Giriş boru hattının bir darboğaz olup olmadığını kontrol edin.
- Bir GPU'nun performansında hata ayıklayın.
- Karışık hassasiyeti etkinleştirin (
fp16
(float16) ile) ve isteğe bağlı olarak XLA'yı etkinleştirin.
- Çoklu GPU'lu tek ana bilgisayardaki performansı optimize edin ve hata ayıklayın.
Örneğin, birden fazla GPU'ya sahip tek bir ana bilgisayarda bir modeli eğitmek için TensorFlow dağıtım stratejisi kullanıyorsanız ve optimumun altında GPU kullanımı fark ederseniz, çoklu GPU sisteminde hata ayıklamadan önce ilk olarak bir GPU'nun performansını optimize etmeli ve hatalarını ayıklamalısınız.
GPU'larda performanslı kod elde etmek için bir temel olarak bu kılavuz, halihazırda tf.function
kullandığınızı varsaymaktadır. Keras Model.compile
ve Model.fit
API'leri tf.function
otomatik olarak kullanacaktır. tf.GradientTape
ile özel bir eğitim döngüsü yazarken, tf.function
s'nin nasıl etkinleştirileceğini öğrenmek için tf.function ile daha iyi performans bölümüne bakın.
Sonraki bölümlerde, performans darboğazlarının belirlenmesine ve giderilmesine yardımcı olmak amacıyla yukarıdaki senaryoların her biri için önerilen yaklaşımlar tartışılmaktadır.
1. Bir GPU'nun performansını optimize edin
İdeal durumda, programınızın yüksek GPU kullanımına sahip olması, CPU'dan (ana bilgisayar) GPU'ya (cihaz) minimum düzeyde iletişim kurması ve giriş hattında herhangi bir ek yük olmaması gerekir.
Performansı analiz etmenin ilk adımı, tek GPU ile çalışan bir model için profil elde etmektir.
Modelinizin profil çalıştırması sırasında nasıl performans gösterdiğine dair üst düzey bir görünüm gösteren TensorBoard'ın Profiler genel bakış sayfası , programınızın ideal senaryodan ne kadar uzakta olduğuna dair bir fikir verebilir.
Genel bakış sayfasında dikkat edilmesi gereken önemli rakamlar şunlardır:
- Adım süresinin ne kadarı gerçek cihaz uygulamasından kaynaklanıyor?
- Cihaza ve ana makineye yerleştirilen işlemlerin yüzdesi
- Kaç tane çekirdek
fp16
kullanıyor?
Optimum performansa ulaşmak, her üç durumda da bu sayıları en üst düzeye çıkarmak anlamına gelir. Programınızı derinlemesine anlamak için TensorBoard'un Profiler izleme görüntüleyicisine aşina olmanız gerekir. Aşağıdaki bölümlerde performans darboğazlarını teşhis ederken aramanız gereken bazı genel iz görüntüleyici modelleri gösterilmektedir.
Aşağıda bir GPU'da çalışan model izleme görünümünün görüntüsü bulunmaktadır. TensorFlow Name Scope ve TensorFlow Ops bölümlerinden ileri geçiş, kayıp işlevi, geri geçiş/gradyan hesaplaması ve optimize edici ağırlık güncellemesi gibi modelin farklı bölümlerini tanımlayabilirsiniz. Ayrıca, CUDA akışlarına atıfta bulunan her Stream öğesinin yanında GPU üzerinde çalışan operasyonları da sağlayabilirsiniz. Her akış belirli görevler için kullanılır. Bu izlemede Stream#118 , bilgi işlem çekirdeklerini ve aygıttan aygıta kopyaları başlatmak için kullanılır. Stream#119, ana bilgisayardan cihaza kopyalama için ve Stream#120, cihazdan ana bilgisayara kopyalama için kullanılır.
Aşağıdaki iz, performans gösteren bir modelin ortak özelliklerini göstermektedir.
Örneğin, GPU hesaplama zaman çizelgesi ( Stream#118 ) çok az boşlukla "meşgul" görünüyor. Ana bilgisayardan cihaza ( Akış #119 ) ve cihazdan ana bilgisayara ( Akış #120 ) minimum sayıda kopya vardır ve adımlar arasında da minimum boşluk vardır. Programınız için Profiler'ı çalıştırdığınızda, bu ideal özellikleri izleme görünümünüzde tanımlayamayabilirsiniz. Bu kılavuzun geri kalanı yaygın senaryoları ve bunların nasıl düzeltileceğini kapsar.
1. Giriş hattında hata ayıklayın
GPU performansında hata ayıklamanın ilk adımı programınızın girdiye bağlı olup olmadığını belirlemektir. Bunu anlamanın en kolay yolu Profiler'ın TensorBoard üzerindeki Giriş hattı analizörünü kullanmaktır; bu, giriş hattında harcanan süreye genel bir bakış sağlar.
Giriş hattınız adım zamanına önemli ölçüde katkıda bulunuyorsa aşağıdaki potansiyel eylemleri gerçekleştirebilirsiniz:
- Giriş hattınızda nasıl hata ayıklayacağınızı öğrenmek için
tf.data
özel kılavuzu kullanabilirsiniz. - Giriş hattının darboğaz olup olmadığını kontrol etmenin bir başka hızlı yolu, herhangi bir ön işleme gerek duymadan rastgele oluşturulmuş giriş verilerini kullanmaktır. Burada bu tekniğin ResNet modeli için kullanılmasına ilişkin bir örnek verilmiştir . Giriş hattı optimalse, gerçek verilerle ve oluşturulan rastgele/sentetik verilerle benzer performansı deneyimlemelisiniz. Sentetik veri durumundaki tek ek yük, yine önceden alınabilen ve optimize edilebilen girdi verileri kopyasından kaynaklanacaktır.
Ayrıca, giriş verileri ardışık düzenini optimize etmeye yönelik en iyi uygulamalara bakın.
2. Bir GPU'nun performansında hata ayıklama
Düşük GPU kullanımına katkıda bulunabilecek çeşitli faktörler vardır. Aşağıda , izleme görüntüleyiciye ve olası çözümlere bakarken yaygın olarak gözlemlenen bazı senaryolar yer almaktadır.
1. Adımlar arasındaki boşlukları analiz edin
Programınızın en iyi şekilde çalışmadığı durumlarda yaygın olarak görülen bir gözlem, eğitim adımları arasındaki boşluklardır. Aşağıdaki izleme görünümü görüntüsünde, 8. ve 9. adımlar arasında büyük bir boşluk vardır; bu, GPU'nun bu süre boyunca boşta olduğu anlamına gelir.
İzleme görüntüleyiciniz adımlar arasında büyük boşluklar gösteriyorsa bu, programınızın girdiye bağlı olduğunun bir göstergesi olabilir. Bu durumda, henüz yapmadıysanız giriş hattınızda hata ayıklamayla ilgili önceki bölüme başvurmalısınız.
Bununla birlikte, optimize edilmiş bir giriş hattında bile, CPU iş parçacığı çekişmesi nedeniyle bir adımın sonu ile diğerinin başlangıcı arasında hala boşluklar olabilir. tf.data
ardışık düzen işlemeyi paralelleştirmek için arka plan iş parçacıklarını kullanır. Bu iş parçacıkları, verilerin kopyalanması veya GPU işlemlerinin planlanması gibi her adımın başında gerçekleşen GPU ana bilgisayar tarafı etkinliğine müdahale edebilir.
Bu işlemleri GPU'da planlayan ana bilgisayar tarafında büyük boşluklar fark ederseniz, TF_GPU_THREAD_MODE=gpu_private
ortam değişkenini ayarlayabilirsiniz. Bu, GPU çekirdeklerinin kendi özel iş parçacıklarından başlatılmasını ve tf.data
çalışmasının arkasında sıraya girmemesini sağlar.
Adımlar arasındaki boşluklara metrik hesaplamalar, Keras geri aramaları veya ana bilgisayarda çalışan tf.function
dışındaki işlemler de neden olabilir. Bu operasyonlar TensorFlow grafiğindeki operasyonlar kadar iyi performansa sahip değil. Ek olarak, bu operasyonlardan bazıları CPU üzerinde çalışır ve tensörleri GPU'dan ileri geri kopyalar.
Giriş hattınızı optimize ettikten sonra, izleme görüntüleyicideki adımlar arasında hala boşluklar olduğunu fark ederseniz, adımlar arasındaki model koduna bakmalı ve geri aramaları/ölçümleri devre dışı bırakmanın performansı artırıp artırmadığını kontrol etmelisiniz. Bu operasyonların bazı ayrıntıları aynı zamanda izleme görüntüleyicisinde de bulunur (hem cihaz hem de ana bilgisayar tarafında). Bu senaryodaki öneri, bu operasyonların yükünü, bunları her adım yerine sabit sayıda adımdan sonra yürüterek amorti etmektir. tf.keras
API'sinde Model.compile
yöntemini kullanırken, steps_per_execution
bayrağının ayarlanması bunu otomatik olarak yapar. Özel eğitim döngüleri için tf.while_loop
kullanın.
2. Daha yüksek cihaz kullanımı elde edin
1. Küçük GPU çekirdekleri ve ana bilgisayar çekirdeği başlatma gecikmeleri
Ana bilgisayar, çekirdekleri GPU'da çalıştırılacak şekilde sıraya koyar, ancak çekirdekler GPU'da gerçekten yürütülmeden önce bir gecikme (yaklaşık 20-40 μs) vardır. İdeal bir durumda, ana bilgisayar, GPU üzerinde yeterli sayıda çekirdeği sıraya alır, böylece GPU, ana bilgisayarın daha fazla çekirdeği sıraya koymasını beklemek yerine, zamanının çoğunu yürütmeye harcar.
Profiler'ın TensorBoard'daki genel bakış sayfası, ana bilgisayarın çekirdekleri başlatmasını beklemek nedeniyle GPU'nun ne kadar süre boşta kaldığını gösterir. Aşağıdaki resimde GPU, çekirdeklerin başlatılmasını bekleyen adım süresinin yaklaşık %10'u boyunca boştadır.
Aynı programın izleme görüntüleyicisi, ana bilgisayarın GPU'da çekirdekleri başlatmakla meşgul olduğu çekirdekler arasındaki küçük boşlukları gösterir.
GPU'da çok sayıda küçük işlem başlatıldığında (örneğin, skaler ekleme gibi), ana bilgisayar GPU'ya ayak uyduramayabilir. Aynı Profil için TensorBoard'daki TensorFlow İstatistikleri aracı, 2,77 saniye süren 126.224 Mul işlemini gösteriyor. Bu nedenle, her bir çekirdek yaklaşık 21,9 μs'dir ve bu çok küçüktür (başlatma gecikmesiyle hemen hemen aynı zamanda) ve potansiyel olarak ana bilgisayar çekirdeğinin başlatılmasında gecikmelere neden olabilir.
İzleme görüntüleyiciniz yukarıdaki resimde olduğu gibi GPU'daki işlemler arasında çok sayıda küçük boşluk gösteriyorsa şunları yapabilirsiniz:
- Küçük tensörleri birleştirin ve vektörleştirilmiş operasyonlar kullanın veya başlatılan her çekirdeğin daha fazla iş yapmasını sağlamak için daha büyük bir toplu iş boyutu kullanın; bu, GPU'yu daha uzun süre meşgul edecektir.
- TensorFlow grafikleri oluşturmak için
tf.function
kullandığınızdan emin olun, böylece işlemleri saf istekli modda çalıştırmazsınız.Model.fit
kullanıyorsanız (tf.GradientTape
ile özel bir eğitim döngüsünün aksine),tf.keras.Model.compile
bunu sizin için otomatik olarak yapacaktır. -
tf.function(jit_compile=True)
veya otomatik kümeleme ile XLA kullanarak çekirdekleri birleştirin. Daha fazla ayrıntı için, daha yüksek performans elde etmek amacıyla XLA'nın nasıl etkinleştirileceğini öğrenmek için aşağıdaki Karma hassasiyeti ve XLA'yı etkinleştirme bölümüne gidin. Bu özellik yüksek cihaz kullanımına yol açabilir.
2. TensorFlow operasyon yerleşimi
Profiler'a genel bakış sayfası, ana makineye ve cihaza yerleştirilen op'ların yüzdesini gösterir (aynı zamanda izleme görüntüleyiciye bakarak belirli op'ların yerleşimini de doğrulayabilirsiniz. Aşağıdaki resimde olduğu gibi, ana bilgisayardaki op'ların yüzdesini istiyorsunuz) cihaza göre çok küçük.
İdeal olarak, yoğun işlem gerektiren operasyonların çoğu GPU'ya yerleştirilmelidir.
Modelinizdeki işlemlerin ve tensörlerin hangi cihazlara atandığını bulmak için tf.debugging.set_log_device_placement(True)
değerini programınızın ilk ifadesi olarak ayarlayın.
Bazı durumlarda, belirli bir cihaza yerleştirilecek bir op belirtseniz bile uygulamasının bu koşulu geçersiz kılabileceğini unutmayın (örnek: tf.unique
). Tek GPU eğitimi için bile tf.distribute.OneDeviceStrategy
gibi bir dağıtım stratejisi belirlemek, operasyonların cihazınıza daha belirleyici bir şekilde yerleştirilmesine neden olabilir.
İşlemlerin çoğunluğunun GPU'ya yerleştirilmesinin bir nedeni, ana bilgisayar ile aygıt arasında aşırı bellek kopyalarının önlenmesidir (ana bilgisayar ile aygıt arasındaki model giriş/çıkış verileri için bellek kopyaları beklenir). Aşırı kopyalamanın bir örneği , #167 , #168 ve #169 GPU akışlarındaki aşağıdaki izleme görünümünde gösterilmektedir.
Bu kopyalar bazen GPU çekirdeklerinin çalışmasını engellerse performansa zarar verebilir. İzleme görüntüleyicideki bellek kopyalama işlemleri, bu kopyalanan tensörlerin kaynağı olan işlemler hakkında daha fazla bilgiye sahiptir, ancak bir memCopy'yi bir işlemle ilişkilendirmek her zaman kolay olmayabilir. Bu durumlarda, bellek kopyasının her adımda aynı konumda olup olmadığını kontrol etmek için yakındaki operasyonlara bakmak faydalı olacaktır.
3. GPU'larda daha verimli çekirdekler
Programınızın GPU kullanımı kabul edilebilir seviyeye geldiğinde, bir sonraki adım Tensör Çekirdekleri veya birleştirme işlemlerini kullanarak GPU çekirdeklerinin verimliliğini artırmaya çalışmaktır.
1. Tensör Çekirdeklerini Kullanın
Modern NVIDIA® GPU'lar, uygun çekirdeklerin performansını önemli ölçüde artırabilen özel Tensör Çekirdeklerine sahiptir.
Hangi GPU çekirdeklerinin Tensor Çekirdeğine uygun olduğunu ve hangi çekirdeklerin Tensor Çekirdeklerini kullandığını görselleştirmek için TensorBoard'un GPU çekirdek istatistiklerini kullanabilirsiniz. fp16
etkinleştirmek (aşağıdaki Karma Hassasiyeti Etkinleştirme bölümüne bakın), programınızın Genel Matris Çarpması (GEMM) çekirdeklerinin (matmul ops) Tensör Çekirdeğini kullanmasını sağlamanın bir yoludur. Hassasiyet fp16 olduğunda ve giriş/çıkış tensör boyutları 8 veya 16'ya bölünebildiğinde ( int8
için) GPU çekirdekleri Tensör Çekirdeklerini verimli bir şekilde kullanır.
Çekirdeklerin GPU'lar için nasıl verimli hale getirileceğine ilişkin diğer ayrıntılı öneriler için NVIDIA® derin öğrenme performans kılavuzuna bakın.
2. Sigorta işlemleri
Önemli performans kazanımlarına yol açacak şekilde daha büyük çekirdekler oluşturmak üzere daha küçük operasyonları birleştirmek için tf.function(jit_compile=True)
kullanın. Daha fazla bilgi edinmek için XLA kılavuzuna bakın.
3. Karma hassasiyeti ve XLA'yı etkinleştirin
Yukarıdaki adımları izledikten sonra, karma hassasiyeti ve XLA'yı etkinleştirmek, performansı daha da artırmak için atabileceğiniz iki isteğe bağlı adımdır. Önerilen yaklaşım, bunları birer birer etkinleştirmek ve performans avantajlarının beklendiği gibi olduğunu doğrulamaktır.
1. Karma hassasiyeti etkinleştirin
TensorFlow Mixed hassaslık kılavuzu, GPU'larda fp16
hassasiyetinin nasıl etkinleştirileceğini gösterir. Tensor Çekirdeklerini kullanmak için NVIDIA® GPU'larda AMP'yi etkinleştirin ve Volta ve daha yeni GPU mimarilerinde yalnızca fp32
(float32) hassasiyeti kullanmaya kıyasla 3 kata kadar genel hızlanma elde edin.
Matris/tensör boyutlarının, Tensör Çekirdekleri kullanan çekirdeklerin çağrılmasına ilişkin gereksinimleri karşıladığından emin olun. Hassasiyet fp16 olduğunda ve giriş/çıkış boyutları 8 veya 16'ya bölünebildiğinde (int8 için) GPU çekirdekleri Tensör Çekirdeklerini verimli bir şekilde kullanır.
CuDNN v7.6.3 ve sonraki sürümlerde, Tensör Çekirdeklerinden yararlanmak için evrişim boyutlarının gerekli olduğu yerlerde otomatik olarak doldurulacağını unutmayın.
fp16
hassasiyetinin performans avantajlarını en üst düzeye çıkarmak için aşağıdaki en iyi uygulamaları izleyin.
1. Optimum fp16 çekirdeklerini kullanın
fp16
etkinleştirildiğinde programınızın matris çarpımları (GEMM) çekirdekleri, Tensör Çekirdeklerini kullanan karşılık gelen fp16
sürümünü kullanmalıdır. Ancak bazı durumlarda bu gerçekleşmez ve programınız verimsiz uygulamaya geri döndüğü için fp16
etkinleştirdiğinizde beklenen hızlanmayı yaşamazsınız.
GPU çekirdek istatistikleri sayfası, hangi operasyonların Tensor Core'a uygun olduğunu ve hangi çekirdeklerin gerçekte verimli Tensor Core'u kullandığını gösterir. Derin öğrenme performansına ilişkin NVIDIA® kılavuzu, Tensör Çekirdeklerinden nasıl yararlanılacağına ilişkin ek öneriler içerir. Ek olarak, fp16
kullanmanın faydaları, daha önce belleğe bağlı olan çekirdeklerde de görülecektir, çünkü artık işlemler yarı yarıya sürecektir.
2. Dinamik ve statik kayıp ölçeklendirmesi
Düşük hassasiyet nedeniyle yetersiz akışı önlemek için fp16
kullanılırken kayıp ölçeklendirmesi gereklidir. Her ikisi de Karma Hassasiyet kılavuzunda daha ayrıntılı olarak açıklanan dinamik ve statik olmak üzere iki tür kayıp ölçeklendirme vardır. Keras iyileştirici içinde kayıp ölçeklendirmeyi otomatik olarak etkinleştirmek için mixed_float16
ilkesini kullanabilirsiniz.
Performansı optimize etmeye çalışırken, dinamik kayıp ölçeklendirmenin ana bilgisayarda çalışan ek koşullu işlemler getirebileceğini ve izleme görüntüleyicideki adımlar arasında görülebilecek boşluklara yol açabileceğini unutmamak önemlidir. Öte yandan, statik kayıp ölçeklendirmenin bu tür ek yükleri yoktur ve doğru statik kayıp ölçeği değerini belirtmeniz gereken yakalama ile performans açısından daha iyi bir seçenek olabilir.
2. XLA'yı tf.function(jit_compile=True) veya otomatik kümeleme ile etkinleştirin
Tek bir GPU ile en iyi performansı elde etmenin son adımı olarak, XLA'yı etkinleştirmeyi deneyebilirsiniz; bu, işlemleri birleştirir ve daha iyi cihaz kullanımına ve daha düşük bellek alanına yol açar. Programınızda XLA'yı tf.function(jit_compile=True)
veya otomatik kümeleme ile nasıl etkinleştireceğinize ilişkin ayrıntılar için XLA kılavuzuna bakın.
Genel JIT düzeyini -1
(kapalı), 1
veya 2
olarak ayarlayabilirsiniz. Daha yüksek bir düzey daha agresiftir ve paralelliği azaltabilir ve daha fazla bellek kullanabilir. Bellek kısıtlamalarınız varsa değeri 1
olarak ayarlayın. XLA derleyicisinin yeni şekillerle karşılaştığında çekirdekleri derlemeye devam etmesi gerekeceğinden, XLA'nın değişken giriş tensör şekillerine sahip modeller için iyi performans göstermediğini unutmayın.
2. Çoklu GPU'lu tek ana bilgisayardaki performansı optimize edin
tf.distribute.MirroredStrategy
API, model eğitimini tek bir GPU'dan tek bir ana bilgisayardaki birden fazla GPU'ya ölçeklendirmek için kullanılabilir. (TensorFlow ile dağıtılmış eğitimin nasıl yapılacağı hakkında daha fazla bilgi edinmek için TensorFlow ile Dağıtılmış eğitim , GPU Kullanma ve TPU'ları Kullanma kılavuzlarına ve Keras ile Dağıtılmış eğitim eğitimine bakın.)
Bir GPU'dan birden fazla GPU'ya geçişin ideal olarak kutudan çıktığı haliyle ölçeklenebilir olması gerekmesine rağmen bazen performans sorunlarıyla karşılaşabilirsiniz.
Tek bir GPU ile eğitimden aynı ana bilgisayardaki birden fazla GPU'ya geçerken, ideal olarak performans ölçeklendirmesini yalnızca ek degrade iletişim yükü ve artan ana bilgisayar iş parçacığı kullanımıyla deneyimlemelisiniz. Bu ek yük nedeniyle, örneğin 1 GPU'dan 2 GPU'ya geçerseniz tam olarak 2 kat hızlanma elde edemezsiniz.
Aşağıdaki izleme görünümü, birden fazla GPU üzerinde eğitim sırasında oluşan ekstra iletişim yükünün bir örneğini göstermektedir. Ağırlık güncellemesini yapmadan önce degradeleri birleştirmek, bunları kopyalar arasında iletmek ve bölmek için bir miktar ek yük vardır.
Aşağıdaki kontrol listesi, çoklu GPU senaryosunda performansı optimize ederken daha iyi performans elde etmenize yardımcı olacaktır:
- Toplu iş boyutunu en üst düzeye çıkarmaya çalışın; bu, daha yüksek cihaz kullanımına yol açacak ve birden fazla GPU arasındaki iletişim maliyetlerini azaltacaktır. Bellek profili oluşturucuyu kullanmak, programınızın bellek kullanımını en üst düzeye ne kadar yaklaştığına dair bir fikir edinmenize yardımcı olur. Daha yüksek bir toplu iş boyutunun yakınsamayı etkileyebileceğini ancak performans avantajlarının genellikle buna ağır bastığını unutmayın.
- Tek bir GPU'dan birden fazla GPU'ya geçerken, aynı ana bilgisayarın artık çok daha fazla giriş verisi işlemesi gerekiyor. Dolayısıyla (1)'den sonra giriş hattı performansının yeniden kontrol edilmesi ve bunun bir darboğaz olmadığından emin olunması önerilir.
- Gereksiz AllReduce çağrıları için programınızın izleme görünümündeki GPU zaman çizelgesini kontrol edin; bu, tüm cihazlar arasında senkronizasyonla sonuçlanır. Yukarıda gösterilen izleme görünümünde AllReduce, NCCL çekirdeği aracılığıyla yapılır ve her adımdaki degradeler için her GPU'da yalnızca bir NCCL çağrısı vardır.
- En aza indirilebilecek gereksiz D2H, H2D ve D2D kopyalama işlemlerini kontrol edin.
- Her kopyanın aynı işi yaptığından emin olmak için adım süresini kontrol edin. Örneğin, ana bilgisayarın yanlışlıkla daha fazla iş yapması nedeniyle bir GPU'ya (tipik olarak
GPU0
) fazla abone olunabilir. - Son olarak, sırayla yürütülen işlemler için izleme görünümünüzdeki tüm GPU'lardaki eğitim adımını kontrol edin. Bu genellikle programınız bir GPU'dan diğerine kontrol bağımlılıkları içerdiğinde meydana gelir. Geçmişte, bu durumda performansın hatalarını ayıklamak duruma göre çözülüyordu. Programınızda bu davranışı gözlemlerseniz izleme görünümünüzün resimlerini içeren bir GitHub sorunu bildirin .
1. AllReduce degradesini optimize edin
Senkronize bir stratejiyle eğitim sırasında her cihaz, giriş verilerinin bir kısmını alır.
Modeldeki ileri ve geri geçişler hesaplandıktan sonra, her cihazda hesaplanan eğimlerin toplanması ve azaltılması gerekir. Bu degrade AllReduce, her cihazdaki degrade hesaplamasından sonra ve optimize edici model ağırlıklarını güncellemeden önce gerçekleşir.
Her GPU ilk olarak degradeleri model katmanları boyunca birleştirir, bunları tf.distribute.CrossDeviceOps
( tf.distribute.NcclAllReduce
varsayılandır) kullanarak GPU'lar arasında iletir ve ardından katman başına azaltmanın ardından degradeleri döndürür.
Optimize edici, modelinizin ağırlıklarını güncellemek için bu azaltılmış degradeleri kullanacaktır. İdeal olarak, herhangi bir ek yükü önlemek için bu işlemin tüm GPU'larda aynı anda gerçekleşmesi gerekir.
AllReduce'a kadar olan süre yaklaşık olarak şu şekilde olmalıdır:
(number of parameters * 4bytes)/ (communication bandwidth)
Bu hesaplama, dağıtılmış bir eğitim işini çalıştırırken elde ettiğiniz performansın beklendiği gibi olup olmadığını veya daha fazla performans hata ayıklaması yapmanız gerekip gerekmediğini anlamak için hızlı bir kontrol olarak kullanışlıdır. Modelinizdeki parametre sayısını Model.summary
adresinden alabilirsiniz.
TensorFlow degradeleri iletmek için fp32
(float32) kullandığından her model parametresinin boyutunun 4 bayt olduğunu unutmayın. fp16
etkinleştirdiğinizde bile NCCL AllReduce, fp32
parametrelerini kullanır.
Ölçeklendirmenin avantajlarından yararlanmak için adım süresinin bu genel giderlere kıyasla çok daha yüksek olması gerekir. Bunu başarmanın bir yolu, toplu iş boyutunun adım süresini etkilemesi ancak iletişim yükünü etkilememesi nedeniyle daha yüksek bir toplu iş boyutu kullanmaktır.
2. GPU ana iş parçacığı çekişmesi
Birden fazla GPU çalıştırırken CPU'nun görevi, cihazlar arasında GPU çekirdeklerini verimli bir şekilde başlatarak tüm cihazları meşgul etmektir.
Bununla birlikte, CPU'nun bir GPU'da planlayabileceği çok sayıda bağımsız işlem olduğunda CPU, bir GPU'yu meşgul tutmak için ana bilgisayar iş parçacıklarının çoğunu kullanmaya karar verebilir ve ardından çekirdekleri başka bir GPU'da deterministik olmayan bir sırayla başlatabilir. . Bu, performansı olumsuz yönde etkileyebilecek bir çarpıklığa veya negatif ölçeklemeye neden olabilir.
Aşağıdaki izleme görüntüleyici, GPU1
boşta kalması ve GPU2
başladıktan sonra işlemleri çalıştırmaya başlaması nedeniyle CPU'nun GPU çekirdeğini verimsiz bir şekilde başlatmasını şaşırtması durumunda ortaya çıkan ek yükü gösterir.
Ana makinenin izleme görünümü, ana bilgisayarın çekirdekleri GPU1
başlatmadan önce GPU2
başlattığını gösterir (aşağıdaki tf_Compute*
işlemlerinin CPU iş parçacıklarını göstermediğini unutmayın).
Programınızın izleme görünümünde GPU çekirdeklerinde bu tür şaşırtıcı bir durumla karşılaşırsanız önerilen eylem şudur:
- TensorFlow ortam değişkeni
TF_GPU_THREAD_MODE
gpu_private
olarak ayarlayın. Bu ortam değişkeni, ana bilgisayara bir GPU için iş parçacıklarını özel tutmasını söyleyecektir. - Varsayılan olarak
TF_GPU_THREAD_MODE=gpu_private
iş parçacığı sayısını 2'ye ayarlar; bu çoğu durumda yeterlidir. Ancak bu sayı, TensorFlow ortam değişkeniTF_GPU_THREAD_COUNT
istenen iş parçacığı sayısına ayarlanmasıyla değiştirilebilir.