TensorFlow.org'da görüntüleyin | Google Colab'da çalıştırın | Kaynağı GitHub'da görüntüleyin | Not defterini indir |
genel bakış
Karma hassasiyet, bir modelin daha hızlı çalışmasını ve daha az bellek kullanmasını sağlamak için eğitim sırasında bir modelde hem 16 bit hem de 32 bit kayan nokta türlerinin kullanılmasıdır. Sayısal kararlılık için modelin belirli kısımları 32 bitlik tiplerde tutularak, model daha düşük adım süresine sahip olacak ve doğruluk gibi değerlendirme ölçütleri açısından da eşit olarak eğitilecektir. Bu kılavuz, modellerinizi hızlandırmak için Keras karma hassas API'sinin nasıl kullanılacağını açıklar. Bu API'yi kullanmak, performansı modern GPU'larda 3 kattan ve TPU'larda %60'tan fazla artırabilir.
Günümüzde çoğu model, 32 bit bellek alan float32 dtype'ı kullanır. Bununla birlikte, her biri 16 bit bellek alan, daha düşük hassasiyetli iki tip vardır, float16 ve bfloat16. Modern hızlandırıcılar, 16 bitlik hesaplamaları çalıştırmak için özel donanıma sahip oldukları ve 16 bitlik türler bellekten daha hızlı okunabildiğinden, 16 bitlik türlerde işlemleri daha hızlı çalıştırabilir.
NVIDIA GPU'lar, işlemleri float16'da float32'den daha hızlı çalıştırabilir ve TPU'lar, işlemleri bfloat16'da float32'den daha hızlı çalıştırabilir. Bu nedenle, bu cihazlarda mümkün olduğunca düşük hassasiyetli bu türler kullanılmalıdır. Bununla birlikte, modelin aynı kalitede çalışabilmesi için değişkenler ve birkaç hesaplama sayısal nedenlerle hala float32'de olmalıdır. Keras karma hassas API'si, float16/bfloat16'nın performans avantajlarını ve float32'nin sayısal kararlılık avantajlarını elde etmek için float16 veya bfloat16'nın float32 ile bir karışımını kullanmanıza olanak tanır.
Kurmak
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras import mixed_precision
Desteklenen donanım
Karışık hassasiyet çoğu donanımda çalışacak olsa da, yalnızca en son NVIDIA GPU'larında ve Cloud TPU'larında modelleri hızlandıracaktır. NVIDIA GPU'lar, bir float16 ve float32 karışımının kullanılmasını desteklerken TPU'lar, bir bfloat16 ve float32 karışımını destekler.
NVIDIA GPU'lar arasında, 7.0 veya daha yüksek işlem kapasitesine sahip olanlar, float16 matris çarpımlarını ve evrişimlerini hızlandırmak için Tensör Çekirdekleri adı verilen özel donanım birimlerine sahip olduklarından, karma hassasiyetten en yüksek performans avantajını göreceklerdir. Daha eski GPU'lar, karışık hassasiyet kullanmak için matematiksel performans avantajı sağlamaz, ancak bellek ve bant genişliği tasarrufları bazı hızlanmaları sağlayabilir. NVIDIA'nın CUDA GPU web sayfasında GPU'nuzun hesaplama kabiliyetini arayabilirsiniz. Karma hassasiyetten en fazla yararlanacak GPU örnekleri arasında RTX GPU'lar, V100 ve A100 bulunur.
GPU tipinizi aşağıdaki ile kontrol edebilirsiniz. Komut yalnızca NVIDIA sürücüleri kuruluysa mevcuttur, bu nedenle, aksi takdirde aşağıdakiler bir hataya neden olur.
nvidia-smi -L
tutucu9 l10n-yerGPU 0: Tesla V100-SXM2-16GB (UUID: GPU-99e10c4d-de77-42ee-4524-6c41c4e5e47d)
Tüm Cloud TPU'lar bfloat16'yı destekler.
Hızlanmanın beklenmediği CPU'larda ve daha eski GPU'larda bile, birim testi, hata ayıklama veya yalnızca API'yi denemek için karma hassas API'ler kullanılabilir. Bununla birlikte, CPU'larda karma hassasiyet önemli ölçüde daha yavaş çalışacaktır.
dtype politikasını ayarlama
Keras'ta karma kesinliği kullanmak için, genellikle dtype ilkesi olarak adlandırılan bir tf.keras.mixed_precision.Policy
oluşturmanız gerekir. Dtype politikaları, katmanların çalışacağı dtypes'i belirtir. Bu kılavuzda, 'mixed_float16'
dizesinden bir politika oluşturacak ve bunu global politika olarak ayarlayacaksınız. Bu, daha sonra oluşturulan katmanların, float16 ve float32 karışımıyla karışık hassasiyet kullanmasına neden olur.
policy = mixed_precision.Policy('mixed_float16')
mixed_precision.set_global_policy(policy)
tutucu11 l10n-yerINFO:tensorflow:Mixed precision compatibility check (mixed_float16): OK Your GPU will likely run quickly with dtype policy mixed_float16 as it has compute capability of at least 7.0. Your GPU: Tesla V100-SXM2-16GB, compute capability 7.0
Kısacası, genellikle pratikte yapılan set_global_policy
doğrudan bir dize iletebilirsiniz.
# Equivalent to the two lines above
mixed_precision.set_global_policy('mixed_float16')
Politika, bir katmanın iki önemli yönünü belirtir: katmanın hesaplamalarının yapıldığı tür ve bir katmanın değişkenlerinin türü. Yukarıda, bir mixed_float16
ilkesi oluşturdunuz (yani, 'mixed_float16'
dizesini yapıcısına ileterek oluşturulan bir mixed_precision.Policy
). Bu politika ile katmanlar, float16 hesaplamalarını ve float32 değişkenlerini kullanır. Performans için hesaplamalar float16'da yapılır, ancak sayısal kararlılık için değişkenler float32'de tutulmalıdır. Politikanın bu özelliklerini doğrudan sorgulayabilirsiniz.
print('Compute dtype: %s' % policy.compute_dtype)
print('Variable dtype: %s' % policy.variable_dtype)
tutucu14 l10n-yerCompute dtype: float16 Variable dtype: float32
Daha önce belirtildiği gibi, mixed_float16
politikası, en az 7.0 hesaplama kapasitesiyle NVIDIA GPU'lardaki performansı önemli ölçüde artıracaktır. Politika, diğer GPU'larda ve CPU'larda çalışır ancak performansı iyileştirmeyebilir. TPU'lar için bunun yerine mixed_bfloat16
politikası kullanılmalıdır.
Modeli oluşturmak
Ardından, basit bir model oluşturmaya başlayalım. Çok küçük oyuncak modelleri tipik olarak karışık hassasiyetten faydalanmaz, çünkü TensorFlow çalışma zamanından gelen ek yük tipik olarak yürütme süresine hükmeder ve GPU'daki herhangi bir performans iyileştirmesini ihmal edilebilir hale getirir. Bu nedenle, bir GPU kullanılıyorsa, her biri 4096 birim olan iki büyük Dense
katman oluşturalım.
inputs = keras.Input(shape=(784,), name='digits')
if tf.config.list_physical_devices('GPU'):
print('The model will run with 4096 units on a GPU')
num_units = 4096
else:
# Use fewer units on CPUs so the model finishes in a reasonable amount of time
print('The model will run with 64 units on a CPU')
num_units = 64
dense1 = layers.Dense(num_units, activation='relu', name='dense_1')
x = dense1(inputs)
dense2 = layers.Dense(num_units, activation='relu', name='dense_2')
x = dense2(x)
tutucu16 l10n-yerThe model will run with 4096 units on a GPU
Her katmanın bir ilkesi vardır ve varsayılan olarak genel ilkeyi kullanır. Bu nedenle, Dense
katmanların her biri, daha önce genel ilkeyi mixed_float16
olarak ayarladığınızdan, mixed_float16
ilkesine sahiptir. Bu, yoğun katmanların float16 hesaplamaları yapmasına ve float32 değişkenlerine sahip olmasına neden olur. Float16 hesaplamaları yapmak için girdilerini float16'ya çevirirler, bu da sonuç olarak çıktılarının float16 olmasına neden olur. Değişkenleri float32'dir ve tür uyumsuzluklarından kaynaklanan hataları önlemek için katmanlar çağrıldığında float16'ya dönüştürülür.
print(dense1.dtype_policy)
print('x.dtype: %s' % x.dtype.name)
# 'kernel' is dense1's variable
print('dense1.kernel.dtype: %s' % dense1.kernel.dtype.name)
tutucu18 l10n-yer<Policy "mixed_float16"> x.dtype: float16 dense1.kernel.dtype: float32
Ardından, çıktı tahminlerini oluşturun. Normalde, çıktı tahminlerini aşağıdaki gibi oluşturabilirsiniz, ancak bu, float16 ile her zaman sayısal olarak kararlı değildir.
# INCORRECT: softmax and model output will be float16, when it should be float32
outputs = layers.Dense(10, activation='softmax', name='predictions')(x)
print('Outputs dtype: %s' % outputs.dtype.name)
tutucu20 l10n-yerOutputs dtype: float16
Modelin sonunda bir softmax aktivasyonu float32 olmalıdır. dtype politikası mixed_float16
olduğundan, softmax etkinleştirme normalde bir float16 hesaplama dtype ve çıktı float16 tensörlerine sahip olacaktır.
Bu, Dense ve softmax katmanlarını ayırarak ve softmax katmanına dtype='float32'
geçirerek düzeltilebilir:
# CORRECT: softmax and model output are float32
x = layers.Dense(10, name='dense_logits')(x)
outputs = layers.Activation('softmax', dtype='float32', name='predictions')(x)
print('Outputs dtype: %s' % outputs.dtype.name)
tutucu22 l10n-yerOutputs dtype: float32
softmax katman oluşturucusuna dtype='float32'
iletmek, katmanın float32
politikasını, hesaplamaları yapan ve değişkenleri float32'de tutan float32 politikası olacak şekilde geçersiz kılar. Eşdeğer olarak, bunun yerine dtype=mixed_precision.Policy('float32')
; katmanlar her zaman dtype bağımsız değişkenini bir ilkeye dönüştürür. Activation
katmanında değişken olmadığından, politikanın değişken tipi yok sayılır, ancak politikanın hesaplama tipi float32, softmax'a ve model çıktısının float32 olmasına neden olur.
Bir modelin ortasına bir float16 softmax eklemek iyidir, ancak modelin sonuna bir softmax float32'de olmalıdır. Bunun nedeni, softmax'tan kayba akan ara tensör float16 veya bfloat16 ise, sayısal sorunlar ortaya çıkabilir.
Float16 hesaplamalarıyla sayısal olarak kararlı olmayacağını düşünüyorsanız, herhangi bir katmanın dtype'ını float32 olacak şekilde dtype='float32'
ileterek geçersiz kılabilirsiniz. Ancak genellikle, çoğu katman mixed_float16
ve mixed_bfloat16
ile yeterli kesinliğe sahip olduğundan, bu yalnızca modelin son katmanında gereklidir.
Model bir softmax ile bitmese bile çıktılar yine de float32 olmalıdır. Bu özel model için gereksiz olmakla birlikte, model çıktıları aşağıdakilerle float32'ye dönüştürülebilir:
# The linear activation is an identity function. So this simply casts 'outputs'
# to float32. In this particular case, 'outputs' is already float32 so this is a
# no-op.
outputs = layers.Activation('linear', dtype='float32')(outputs)
Ardından, modeli tamamlayın ve derleyin ve girdi verilerini oluşturun:
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(loss='sparse_categorical_crossentropy',
optimizer=keras.optimizers.RMSprop(),
metrics=['accuracy'])
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(60000, 784).astype('float32') / 255
x_test = x_test.reshape(10000, 784).astype('float32') / 255
Bu örnek, girdi verilerini int8'den float32'ye aktarır. 255'e bölme, float16 işlemlerini float32 işlemlerinden daha yavaş çalıştıran CPU'da olduğundan, float16'ya yayın yapmazsınız. Bu durumda, performans farkı ihmal edilebilir düzeydedir, ancak genel olarak, CPU üzerinde çalışıyorsa, float32'de girdi işleme matematiğini çalıştırmalısınız. Modelin ilk katmanı, her katman kayan noktalı girdileri kendi hesaplama tipine attığından, girdileri float16'ya çevirecektir.
Modelin başlangıç ağırlıkları alınır. Bu, ağırlıkları yükleyerek tekrar sıfırdan eğitime izin verecektir.
initial_weights = model.get_weights()
Model.fit ile modeli eğitmek
Ardından, modeli eğitin:
history = model.fit(x_train, y_train,
batch_size=8192,
epochs=5,
validation_split=0.2)
test_scores = model.evaluate(x_test, y_test, verbose=2)
print('Test loss:', test_scores[0])
print('Test accuracy:', test_scores[1])
tutucu27 l10n-yerEpoch 1/5 6/6 [==============================] - 2s 78ms/step - loss: 4.9609 - accuracy: 0.4132 - val_loss: 0.6643 - val_accuracy: 0.8437 Epoch 2/5 6/6 [==============================] - 0s 34ms/step - loss: 0.7752 - accuracy: 0.7789 - val_loss: 0.3098 - val_accuracy: 0.9175 Epoch 3/5 6/6 [==============================] - 0s 34ms/step - loss: 0.3620 - accuracy: 0.8848 - val_loss: 0.3149 - val_accuracy: 0.8969 Epoch 4/5 6/6 [==============================] - 0s 34ms/step - loss: 0.2998 - accuracy: 0.9066 - val_loss: 0.2988 - val_accuracy: 0.9068 Epoch 5/5 6/6 [==============================] - 0s 33ms/step - loss: 0.2298 - accuracy: 0.9285 - val_loss: 0.5062 - val_accuracy: 0.8414 313/313 - 0s - loss: 0.5163 - accuracy: 0.8392 Test loss: 0.5163048505783081 Test accuracy: 0.8392000198364258
Modelin günlüklerde adım başına süreyi yazdırdığına dikkat edin: örneğin, "25ms/adım". TensorFlow modeli optimize etmek için biraz zaman harcadığından ilk dönem daha yavaş olabilir, ancak daha sonra adım başına süre sabitlenmelidir.
Bu kılavuzu Colab'da çalıştırıyorsanız, karışık hassasiyetin performansını float32 ile karşılaştırabilirsiniz. Bunu yapmak için, "dtype ilkesini ayarlama" bölümünde ilkeyi mixed_float16
float32
, ardından bu noktaya kadar tüm hücreleri yeniden çalıştırın. 7.X işlem yeteneğine sahip GPU'larda, adım başına sürenin önemli ölçüde arttığını görmelisiniz, bu da karışık hassasiyetin modeli hızlandırdığını gösterir. Kılavuza devam etmeden önce, ilkeyi yeniden mixed_float16
olarak değiştirdiğinizden ve hücreleri yeniden çalıştırdığınızdan emin olun.
Hesaplama kapasitesi en az 8,0 olan GPU'larda (Amper GPU'lar ve üstü), bu kılavuzdaki oyuncak modelinde, float32'ye kıyasla karışık hassasiyet kullanırken büyük olasılıkla hiçbir performans artışı görmeyeceksiniz. Bunun nedeni, tf.linalg.matmul gibi belirli tf.linalg.matmul
işlemlerinde otomatik olarak daha düşük hassasiyetli matematik kullanan TensorFloat-32'nin kullanılmasıdır. TensorFloat-32, float32 kullanılırken karışık hassasiyetin performans avantajlarından bazılarını sağlar. Bununla birlikte, gerçek dünya modellerinde, bellek bant genişliği tasarrufları ve TensorFloat-32'nin desteklemediği işlemler nedeniyle karışık hassasiyetten tipik olarak önemli performans iyileştirmeleri göreceksiniz.
Bir TPU üzerinde karışık hassasiyet çalıştırıyorsanız, GPU'larda, özellikle Amper öncesi GPU'larda karışık hassasiyet çalıştırmaya kıyasla çok fazla bir performans kazancı görmezsiniz. Bunun nedeni, TPU'ların, varsayılan float32 dtype politikasıyla bile kaputun altında bfloat16'da belirli işlemler yapmasıdır. Bu, Ampere GPU'ların varsayılan olarak TensorFloat-32'yi nasıl kullandığına benzer. Amper GPU'larla karşılaştırıldığında TPU'lar, gerçek dünya modellerinde karışık hassasiyetle tipik olarak daha az performans artışı görür.
Birçok gerçek dünya modeli için, karma kesinlik, float16 tensörleri belleğin yarısını kapladığından, bellek tükenmeden parti boyutunu iki katına çıkarmanıza da olanak tanır. Ancak bu, bu oyuncak modeli için geçerli değildir, çünkü modeli büyük olasılıkla her bir grubun 60.000 görüntüden oluşan tüm MNIST veri kümesinden oluştuğu herhangi bir türde çalıştırabilirsiniz.
Kayıp ölçekleme
Kayıp ölçeklendirme, sayısal taşmayı önlemek için mixed_float16
tf.keras.Model.fit
otomatik olarak gerçekleştirdiği bir tekniktir. Bu bölüm, kayıp ölçeklemenin ne olduğunu açıklar ve sonraki bölüm, bunun özel bir eğitim döngüsüyle nasıl kullanılacağını açıklar.
Alt Akış ve Taşma
float16 veri türü, float32 ile karşılaştırıldığında dar bir dinamik aralığa sahiptir. Bu, \(65504\) üzerindeki değerlerin sonsuza taşacağı ve \(6.0 \times 10^{-8}\) altındaki değerlerin sıfıra ineceği anlamına gelir. float32 ve bfloat16 çok daha yüksek dinamik aralığa sahiptir, böylece taşma ve yetersizlik sorun olmaz.
Örneğin:
x = tf.constant(256, dtype='float16')
(x ** 2).numpy() # Overflow
infyer tutucu30 l10n-yer
x = tf.constant(1e-5, dtype='float16')
(x ** 2).numpy() # Underflow
0.0
Pratikte, float16 ile taşma nadiren meydana gelir. Ek olarak, ileri geçiş sırasında alt akış da nadiren meydana gelir. Ancak geriye doğru geçiş sırasında eğimler sıfıra inebilir. Kayıp ölçeklendirme, bu alt akışı önlemek için bir tekniktir.
Kayıp ölçeklendirmesine genel bakış
Kayıp ölçeklendirmesinin temel konsepti basittir: basitçe kaybı büyük bir sayı ile çarpın, örneğin \(1024\)ve kayıp ölçeği değerini elde edin. Bu, eğimlerin \(1024\) tarafından da ölçeklenmesine neden olacak ve taşma olasılığını büyük ölçüde azaltacaktır. Son gradyanlar hesaplandıktan sonra, onları doğru değerlerine geri getirmek için \(1024\) bölün.
Bu işlemin sözde kodu:
loss_scale = 1024
loss = model(inputs)
loss *= loss_scale
# Assume `grads` are float32. You do not want to divide float16 gradients.
grads = compute_gradient(loss, model.trainable_variables)
grads /= loss_scale
Bir kayıp ölçeği seçmek zor olabilir. Kayıp ölçeği çok düşükse, gradyanlar yine de sıfıra düşebilir. Çok yüksekse, sorun tam tersi olur: gradyanlar sonsuza taşabilir.
Bunu çözmek için TensorFlow, kayıp ölçeğini dinamik olarak belirler, böylece manuel olarak bir tane seçmek zorunda kalmazsınız. Eğer tf.keras.Model.fit
kullanıyorsanız kayıp ölçeklendirmesi sizin yerinize yapılır, böylece ekstra bir iş yapmanıza gerek kalmaz. Özel bir eğitim döngüsü kullanıyorsanız, kayıp ölçeklendirmeyi kullanmak için özel optimize edici sarmalayıcı tf.keras.mixed_precision.LossScaleOptimizer
açıkça kullanmanız gerekir. Bu bir sonraki bölümde açıklanmaktadır.
Modeli özel bir eğitim döngüsüyle eğitme
Şimdiye kadar, tf.keras.Model.fit kullanarak bir Keras modelini karışık hassasiyetle tf.keras.Model.fit
. Ardından, özel bir eğitim döngüsüyle karışık hassasiyet kullanacaksınız. Özel eğitim döngüsünün ne olduğunu henüz bilmiyorsanız, lütfen önce Özel eğitim kılavuzunu okuyun.
Özel bir eğitim döngüsünü karışık hassasiyetle çalıştırmak, onu float32'de çalıştırmak yerine iki değişiklik gerektirir:
- Modeli karışık hassasiyetle oluşturun (bunu zaten yaptınız)
-
mixed_float16
kullanılıyorsa, kayıp ölçeklemeyi açıkça kullanın.
Adım (2) için, bir optimize ediciyi saran ve kayıp ölçeklemeyi uygulayan tf.keras.mixed_precision.LossScaleOptimizer
sınıfını kullanacaksınız. Varsayılan olarak, kayıp ölçeğini dinamik olarak belirler, böylece birini seçmek zorunda kalmazsınız. Aşağıdaki gibi bir LossScaleOptimizer
.
optimizer = keras.optimizers.RMSprop()
optimizer = mixed_precision.LossScaleOptimizer(optimizer)
İsterseniz, açık bir kayıp ölçeği seçebilir veya kayıp ölçekleme davranışını başka bir şekilde özelleştirebilirsiniz, ancak bilinen tüm modellerde iyi çalıştığı tespit edildiğinden varsayılan kayıp ölçekleme davranışını korumanız şiddetle tavsiye edilir. Kayıp ölçekleme davranışını özelleştirmek istiyorsanız tf.keras.mixed_precision.LossScaleOptimizer
belgelerine bakın.
Ardından, kayıp nesnesini ve tf.data.Dataset
s'yi tanımlayın:
loss_object = tf.keras.losses.SparseCategoricalCrossentropy()
train_dataset = (tf.data.Dataset.from_tensor_slices((x_train, y_train))
.shuffle(10000).batch(8192))
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(8192)
Ardından, eğitim adımı işlevini tanımlayın. Kaybı ölçeklendirmek ve gradyanların ölçeğini kaldırmak için kayıp ölçeği iyileştiricisinden iki yeni yöntem kullanacaksınız:
-
get_scaled_loss(loss)
: Kaybı, kayıp ölçeğiyle çarpar -
get_unscaled_gradients(gradients)
: Girdi olarak ölçeklenmiş degradelerin bir listesini alır ve ölçeklerini kaldırmak için her birini kayıp ölçeğine böler
Degradelerde alt akışı önlemek için bu işlevler kullanılmalıdır. LossScaleOptimizer.apply_gradients
, hiçbirinde Inf
s veya NaN
s yoksa degradeler uygular. Ayrıca, kayıp ölçeğini de günceller, gradyanlar Inf
s veya NaN
s içeriyorsa yarıya indirir ve aksi takdirde potansiyel olarak artırır.
@tf.function
def train_step(x, y):
with tf.GradientTape() as tape:
predictions = model(x)
loss = loss_object(y, predictions)
scaled_loss = optimizer.get_scaled_loss(loss)
scaled_gradients = tape.gradient(scaled_loss, model.trainable_variables)
gradients = optimizer.get_unscaled_gradients(scaled_gradients)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return loss
LossScaleOptimizer
muhtemelen eğitimin başlangıcındaki ilk birkaç adımı atlayacaktır. Kayıp ölçeği yüksek başlar, böylece optimal kayıp ölçeği hızlı bir şekilde belirlenebilir. Birkaç adımdan sonra kayıp ölçeği sabitlenecek ve çok az adım atlanacaktır. Bu süreç otomatik olarak gerçekleşir ve eğitim kalitesini etkilemez.
Şimdi, test adımını tanımlayın:
@tf.function
def test_step(x):
return model(x, training=False)
Modelin ilk ağırlıklarını yükleyin, böylece sıfırdan yeniden eğitebilirsiniz:
model.set_weights(initial_weights)
Son olarak, özel eğitim döngüsünü çalıştırın:
for epoch in range(5):
epoch_loss_avg = tf.keras.metrics.Mean()
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
name='test_accuracy')
for x, y in train_dataset:
loss = train_step(x, y)
epoch_loss_avg(loss)
for x, y in test_dataset:
predictions = test_step(x)
test_accuracy.update_state(y, predictions)
print('Epoch {}: loss={}, test accuracy={}'.format(epoch, epoch_loss_avg.result(), test_accuracy.result()))
tutucu39 l10n-yerEpoch 0: loss=4.869325160980225, test accuracy=0.7221999764442444 Epoch 1: loss=0.4893573224544525, test accuracy=0.878000020980835 Epoch 2: loss=0.36011582612991333, test accuracy=0.9440000057220459 Epoch 3: loss=0.27391332387924194, test accuracy=0.9318000078201294 Epoch 4: loss=0.247697651386261, test accuracy=0.933899998664856
GPU performans ipuçları
GPU'larda karışık hassasiyet kullanırken bazı performans ipuçları.
Parti boyutunu artırmak
Model kalitesini etkilemiyorsa, karışık hassasiyet kullanırken parti boyutunu iki katına çıkarmayı deneyin. Float16 tensörleri belleğin yarısını kullandığından, bu genellikle bellek tükenmeden toplu iş boyutunuzu iki katına çıkarmanıza olanak tanır. Toplu iş boyutunun arttırılması, genellikle eğitim verimini, yani modelinizin çalıştırabileceği saniye başına eğitim öğelerini artırır.
GPU Tensör Çekirdeklerinin kullanılmasını sağlama
Daha önce bahsedildiği gibi, modern NVIDIA GPU'ları, float16 matrislerini çok hızlı bir şekilde çoğaltabilen Tensor Cores adlı özel bir donanım birimi kullanır. Bununla birlikte, Tensör Çekirdekleri, belirli tensör boyutlarının 8'in katı olmasını gerektirir. Aşağıdaki örneklerde, yalnızca Tensör Çekirdeklerinin kullanılması için 8'in katı olması gerekiyorsa bir argüman kalındır.
- tf.keras.layers.Dense( birim=64 )
- tf.keras.layers.Conv2d( filtreler=48 , kernel_size=7, adım=3)
- Ve benzer şekilde tf.keras.layers.Conv3d gibi diğer evrişimli katmanlar için
- tf.keras.layers.LSTM( birim=64 )
- Ve tf.keras.layers.GRU gibi diğer RNN'ler için de benzerdir.
- tf.keras.Model.fit(epochs=2, batch_size=128 )
Mümkün olduğunda Tensör Çekirdeklerini kullanmaya çalışmalısınız. Daha fazla bilgi edinmek istiyorsanız, NVIDIA derin öğrenme performans kılavuzu , Tensör Çekirdeklerinin yanı sıra Tensör Çekirdeği ile ilgili diğer performans bilgilerinin kullanımına ilişkin tam gereksinimleri açıklar.
XLA
XLA, karma hassas performansı ve ayrıca float32 performansını daha az ölçüde artırabilen bir derleyicidir. Ayrıntılar için XLA kılavuzuna bakın.
Cloud TPU performans ipuçları
GPU'larda olduğu gibi, bfloat16 tensörleri belleğin yarısını kullandığından Cloud TPU'ları kullanırken toplu iş boyutunuzu iki katına çıkarmayı denemelisiniz. Parti boyutunun iki katına çıkarılması eğitim verimini artırabilir.
TPU'lar, optimum performans elde etmek için başka herhangi bir karışık hassaslığa özel ayar gerektirmez. Zaten XLA kullanımını gerektiriyorlar. TPU'lar, belirli boyutların \(128\)katları olmasından yararlanır, ancak bu, karışık hassasiyet için olduğu gibi float32 türü için de aynı şekilde geçerlidir. Karma hassasiyet ve float32 tensörler için geçerli olan genel TPU performans ipuçları için Cloud TPU performans kılavuzuna bakın.
Özet
- Performansı 3 kata kadar artıracağından, en az 7.0 hesaplama yeteneğine sahip TPU'lar veya NVIDIA GPU'lar kullanıyorsanız karma kesinlik kullanmalısınız.
Karışık hassasiyeti aşağıdaki satırlarla kullanabilirsiniz:
# On TPUs, use 'mixed_bfloat16' instead mixed_precision.set_global_policy('mixed_float16')
Modeliniz softmax ile bitiyorsa, float32 olduğundan emin olun. Ve modelinizin sonu ne olursa olsun, çıktının float32 olduğundan emin olun.
mixed_float16
ile özel bir eğitim döngüsü kullanıyorsanız, yukarıdaki satırlara ek olarak, optimize edicinizi birtf.keras.mixed_precision.LossScaleOptimizer
ile sarmanız gerekir. Ardından, kaybı ölçeklendirmek içinoptimizer.get_unscaled_gradients
ve degradelerin ölçeğini kaldırmak içinoptimizer.get_scaled_loss
çağırın.Değerlendirme doğruluğunu azaltmazsa eğitim grubu boyutunu ikiye katlayın
GPU'larda, performansı en üst düzeye çıkarmak için çoğu tensör boyutunun \(8\) katları olduğundan emin olun
tf.keras.mixed_precision
API'sini kullanan daha fazla karma kesinlik örneği için resmi modeller deposuna bakın. ResNet ve Transformer gibi çoğu resmi model, --dtype=fp16
karma kesinlik kullanılarak çalışacaktır.