Presisi campuran

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

Ringkasan

Presisi campuran adalah penggunaan tipe titik-mengambang 16-bit dan 32-bit dalam model selama pelatihan untuk membuatnya berjalan lebih cepat dan menggunakan lebih sedikit memori. Dengan menjaga bagian-bagian tertentu dari model dalam tipe 32-bit untuk stabilitas numerik, model akan memiliki waktu langkah yang lebih rendah dan melatih sama baiknya dalam hal metrik evaluasi seperti akurasi. Panduan ini menjelaskan cara menggunakan API presisi campuran Keras untuk mempercepat model Anda. Menggunakan API ini dapat meningkatkan kinerja lebih dari 3 kali lipat pada GPU modern dan 60% pada TPU.

Saat ini, sebagian besar model menggunakan float32 dtype, yang membutuhkan memori 32 bit. Namun, ada dua tipe d dengan presisi lebih rendah, float16 dan bfloat16, yang masing-masing mengambil 16 bit memori. Akselerator modern dapat menjalankan operasi lebih cepat dalam tipe d 16-bit, karena mereka memiliki perangkat keras khusus untuk menjalankan komputasi 16-bit dan tipe d 16-bit dapat dibaca dari memori lebih cepat.

GPU NVIDIA dapat menjalankan operasi di float16 lebih cepat daripada di float32, dan TPU dapat menjalankan operasi di bfloat16 lebih cepat daripada float32. Oleh karena itu, tipe d presisi rendah ini harus digunakan bila memungkinkan pada perangkat tersebut. Namun, variabel dan beberapa komputasi harus tetap berada di float32 karena alasan numerik sehingga model dapat dilatih dengan kualitas yang sama. API presisi campuran Keras memungkinkan Anda menggunakan campuran float16 atau bfloat16 dengan float32, untuk mendapatkan manfaat kinerja dari float16/bfloat16 dan manfaat stabilitas numerik dari float32.

Mempersiapkan

import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras import mixed_precision

Perangkat keras yang didukung

Sementara presisi campuran akan berjalan di sebagian besar perangkat keras, itu hanya akan mempercepat model pada GPU NVIDIA dan Cloud TPU terbaru. Dukungan GPU NVIDIA menggunakan campuran float16 dan float32, sementara TPU mendukung campuran bfloat16 dan float32.

Di antara GPU NVIDIA, GPU dengan kemampuan komputasi 7.0 atau lebih tinggi akan merasakan manfaat kinerja terbesar dari presisi campuran karena mereka memiliki unit perangkat keras khusus, yang disebut Tensor Cores, untuk mempercepat perkalian dan konvolusi matriks float16. GPU yang lebih lama tidak menawarkan manfaat kinerja matematika untuk menggunakan presisi campuran, namun penghematan memori dan bandwidth dapat memungkinkan beberapa percepatan. Anda dapat mencari kemampuan komputasi untuk GPU Anda di halaman web CUDA GPU NVIDIA . Contoh GPU yang paling diuntungkan dari presisi campuran termasuk GPU RTX, V100, dan A100.

Anda dapat memeriksa jenis GPU Anda dengan yang berikut ini. Perintah hanya ada jika driver NVIDIA diinstal, jadi berikut ini akan menimbulkan kesalahan jika tidak.

nvidia-smi -L
GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-99e10c4d-de77-42ee-4524-6c41c4e5e47d)

Semua Cloud TPU mendukung bfloat16.

Bahkan pada CPU dan GPU yang lebih lama, di mana tidak ada percepatan yang diharapkan, API presisi campuran masih dapat digunakan untuk pengujian unit, debugging, atau hanya untuk mencoba API. Namun, pada CPU, presisi campuran akan berjalan jauh lebih lambat.

Menyetel kebijakan tipe d

Untuk menggunakan presisi campuran di Keras, Anda perlu membuat tf.keras.mixed_precision.Policy , biasanya disebut sebagai dtype policy . Kebijakan Dtype menentukan lapisan dtypes yang akan dijalankan. Dalam panduan ini, Anda akan membuat kebijakan dari string 'mixed_float16' dan menetapkannya sebagai kebijakan global. Ini akan menyebabkan lapisan yang dibuat selanjutnya menggunakan presisi campuran dengan campuran float16 dan float32.

policy = mixed_precision.Policy('mixed_float16')
mixed_precision.set_global_policy(policy)
INFO: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

Singkatnya, Anda dapat langsung meneruskan string ke set_global_policy , yang biasanya dilakukan dalam praktik.

# Equivalent to the two lines above
mixed_precision.set_global_policy('mixed_float16')

Kebijakan ini menetapkan dua aspek penting dari sebuah lapisan: tipe d tempat komputasi lapisan dilakukan, dan tipe variabel lapisan d. Di atas, Anda membuat kebijakan mixed_float16 (yaitu, kebijakan mixed_precision.Policy yang dibuat dengan meneruskan string 'mixed_float16' ke konstruktornya). Dengan kebijakan ini, lapisan menggunakan perhitungan float16 dan variabel float32. Perhitungan dilakukan di float16 untuk kinerja, tetapi variabel harus disimpan di float32 untuk stabilitas numerik. Anda dapat langsung menanyakan properti kebijakan ini.

print('Compute dtype: %s' % policy.compute_dtype)
print('Variable dtype: %s' % policy.variable_dtype)
Compute dtype: float16
Variable dtype: float32

Seperti yang disebutkan sebelumnya, kebijakan mixed_float16 akan meningkatkan kinerja secara signifikan pada GPU NVIDIA dengan kemampuan komputasi setidaknya 7.0. Kebijakan ini akan berjalan di GPU dan CPU lain, tetapi mungkin tidak meningkatkan performa. Untuk TPU, kebijakan mixed_bfloat16 harus digunakan sebagai gantinya.

Membangun model

Selanjutnya, mari kita mulai membangun model sederhana. Model mainan yang sangat kecil biasanya tidak mendapat manfaat dari presisi campuran, karena overhead dari runtime TensorFlow biasanya mendominasi waktu eksekusi, sehingga peningkatan kinerja apa pun pada GPU dapat diabaikan. Oleh karena itu, mari kita buat dua layer Dense besar dengan masing-masing 4096 unit jika GPU digunakan.

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)
The model will run with 4096 units on a GPU

Setiap lapisan memiliki kebijakan dan menggunakan kebijakan global secara default. Oleh karena itu, setiap lapisan Dense memiliki kebijakan mixed_float16 karena Anda telah menyetel kebijakan global ke mixed_float16 sebelumnya. Ini akan menyebabkan lapisan padat melakukan perhitungan float16 dan memiliki variabel float32. Mereka memasukkan input mereka ke float16 untuk melakukan perhitungan float16, yang menyebabkan output mereka menjadi float16 sebagai hasilnya. Variabelnya adalah float32 dan akan dilemparkan ke float16 ketika lapisan dipanggil untuk menghindari kesalahan dari ketidakcocokan dtype.

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)
<Policy "mixed_float16">
x.dtype: float16
dense1.kernel.dtype: float32

Selanjutnya, buat prediksi keluaran. Biasanya, Anda dapat membuat prediksi keluaran sebagai berikut, tetapi ini tidak selalu stabil secara numerik dengan float16.

# 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)
Outputs dtype: float16

Aktivasi softmax di akhir model harus float32. Karena kebijakan dtype adalah mixed_float16 , aktivasi softmax biasanya memiliki float16 compute dtype dan output float16 tensor.

Ini dapat diperbaiki dengan memisahkan lapisan Padat dan softmax, dan dengan meneruskan dtype='float32' ke lapisan softmax:

# 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)
Outputs dtype: float32

Meneruskan dtype='float32' ke konstruktor lapisan softmax mengesampingkan kebijakan dtype lapisan menjadi kebijakan float32 , yang melakukan perhitungan dan menyimpan variabel di float32. Secara setara, Anda bisa saja melewatkan dtype=mixed_precision.Policy('float32') ; lapisan selalu mengonversi argumen dtype menjadi kebijakan. Karena lapisan Activation tidak memiliki variabel, variabel dtype kebijakan diabaikan, tetapi dtype komputasi kebijakan float32 menyebabkan softmax dan output model menjadi float32.

Menambahkan softmax float16 di tengah model boleh saja, tetapi softmax di akhir model harus di float32. Alasannya adalah jika tensor menengah yang mengalir dari softmax ke loss adalah float16 atau bfloat16, masalah numerik dapat terjadi.

Anda dapat mengganti dtype dari setiap lapisan menjadi float32 dengan melewatkan dtype='float32' jika menurut Anda itu tidak akan stabil secara numerik dengan perhitungan float16. Tetapi biasanya, ini hanya diperlukan pada lapisan terakhir model, karena sebagian besar lapisan memiliki presisi yang cukup dengan mixed_float16 dan mixed_bfloat16 .

Bahkan jika model tidak diakhiri dengan softmax, outputnya harus tetap float32. Meskipun tidak diperlukan untuk model khusus ini, keluaran model dapat dilemparkan ke float32 dengan yang berikut:

# 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)

Selanjutnya, selesaikan dan kompilasi model, dan buat data input:

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

Contoh ini memasukkan data input dari int8 ke float32. Anda tidak melakukan cast ke float16 karena pembagian dengan 255 ada di CPU, yang menjalankan operasi float16 lebih lambat daripada operasi float32. Dalam hal ini, perbedaan kinerja dapat diabaikan, tetapi secara umum Anda harus menjalankan pemrosesan input matematika di float32 jika berjalan di CPU. Lapisan pertama model akan memberikan input ke float16, karena setiap lapisan memberikan input titik-mengambang ke tipe komputasinya.

Bobot awal model diambil. Ini akan memungkinkan pelatihan dari awal lagi dengan memuat beban.

initial_weights = model.get_weights()

Melatih model dengan Model.fit

Selanjutnya, latih model:

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])
Epoch 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

Perhatikan model mencetak waktu per langkah dalam log: misalnya, "25 ms/langkah". Epoch pertama mungkin lebih lambat karena TensorFlow menghabiskan beberapa waktu untuk mengoptimalkan model, tetapi setelah itu waktu per langkah akan stabil.

Jika Anda menjalankan panduan ini di Colab, Anda dapat membandingkan kinerja presisi campuran dengan float32. Untuk melakukannya, ubah kebijakan dari mixed_float16 menjadi float32 di bagian "Mengatur kebijakan dtype", lalu jalankan kembali semua sel hingga titik ini. Pada GPU dengan kemampuan komputasi 7.X, Anda akan melihat waktu per langkah meningkat secara signifikan, menunjukkan presisi campuran yang mempercepat model. Pastikan untuk mengubah kebijakan kembali ke mixed_float16 dan jalankan kembali sel sebelum melanjutkan dengan panduan.

Pada GPU dengan kemampuan komputasi minimal 8,0 (GPU Ampere ke atas), Anda mungkin tidak akan melihat peningkatan kinerja dalam model mainan dalam panduan ini saat menggunakan presisi campuran dibandingkan dengan float32. Ini karena penggunaan TensorFloat-32 , yang secara otomatis menggunakan matematika presisi lebih rendah di operasi float32 tertentu seperti tf.linalg.matmul . TensorFloat-32 memberikan beberapa keunggulan kinerja presisi campuran saat menggunakan float32. Namun, dalam model dunia nyata, Anda biasanya masih akan melihat peningkatan kinerja yang signifikan dari presisi campuran karena penghematan bandwidth memori dan operasi yang tidak didukung oleh TensorFloat-32.

Jika menjalankan presisi campuran pada TPU, Anda tidak akan melihat peningkatan kinerja sebanyak menjalankan presisi campuran pada GPU, terutama GPU pra-Ampere. Ini karena TPU melakukan operasi tertentu di bfloat16 di bawah tenda bahkan dengan kebijakan dtype default float32. Ini mirip dengan bagaimana GPU Ampere menggunakan TensorFloat-32 secara default. Dibandingkan dengan GPU Ampere, TPU biasanya melihat peningkatan kinerja yang lebih sedikit dengan presisi campuran pada model dunia nyata.

Untuk banyak model dunia nyata, presisi campuran juga memungkinkan Anda menggandakan ukuran batch tanpa kehabisan memori, karena tensor float16 mengambil setengah dari memori. Namun ini tidak berlaku untuk model mainan ini, karena Anda mungkin dapat menjalankan model dalam tipe d mana pun di mana setiap kumpulan terdiri dari seluruh kumpulan data MNIST yang terdiri dari 60.000 gambar.

Penskalaan kerugian

Penskalaan kerugian adalah teknik yang dilakukan secara otomatis oleh tf.keras.Model.fit dengan kebijakan mixed_float16 untuk menghindari underflow numerik. Bagian ini menjelaskan apa itu penskalaan kerugian dan bagian berikutnya menjelaskan cara menggunakannya dengan loop pelatihan kustom.

Arus bawah dan Luapan

Tipe data float16 memiliki rentang dinamis yang sempit dibandingkan dengan float32. Ini berarti nilai di atas \(65504\) akan meluap hingga tak terhingga dan nilai di bawah \(6.0 \times 10^{-8}\) akan mengalir ke nol. float32 dan bfloat16 memiliki rentang dinamis yang jauh lebih tinggi sehingga overflow dan underflow tidak menjadi masalah.

Sebagai contoh:

x = tf.constant(256, dtype='float16')
(x ** 2).numpy()  # Overflow
inf
x = tf.constant(1e-5, dtype='float16')
(x ** 2).numpy()  # Underflow
0.0

Dalam praktiknya, overflow dengan float16 jarang terjadi. Selain itu, underflow juga jarang terjadi selama forward pass. Namun, selama lintasan mundur, gradien dapat mengalir ke bawah hingga nol. Loss scaling adalah teknik untuk mencegah underflow ini.

Ikhtisar penskalaan kerugian

Konsep dasar penskalaan kerugian sederhana: cukup kalikan kerugian dengan sejumlah besar, katakanlah \(1024\), dan Anda mendapatkan nilai skala kerugian . Ini akan menyebabkan gradien menskalakan \(1024\) juga, sangat mengurangi kemungkinan underflow. Setelah gradien akhir dihitung, bagi dengan \(1024\) untuk mengembalikannya ke nilai yang benar.

Pseudocode untuk proses ini adalah:

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

Memilih skala kerugian bisa jadi rumit. Jika skala kerugian terlalu rendah, gradien mungkin masih underflow ke nol. Jika terlalu tinggi, masalah akan terjadi sebaliknya: gradien dapat meluap hingga tak terhingga.

Untuk mengatasi ini, TensorFlow secara dinamis menentukan skala kerugian sehingga Anda tidak perlu memilih salah satu secara manual. Jika Anda menggunakan tf.keras.Model.fit , penskalaan kerugian dilakukan untuk Anda sehingga Anda tidak perlu melakukan pekerjaan tambahan. Jika Anda menggunakan loop pelatihan khusus, Anda harus secara eksplisit menggunakan pembungkus pengoptimal khusus tf.keras.mixed_precision.LossScaleOptimizer untuk menggunakan penskalaan kerugian. Ini dijelaskan di bagian berikutnya.

Melatih model dengan loop pelatihan khusus

Sejauh ini, Anda telah melatih model Keras dengan presisi campuran menggunakan tf.keras.Model.fit . Selanjutnya, Anda akan menggunakan presisi campuran dengan loop pelatihan khusus. Jika Anda belum mengetahui apa itu custom training loop, silahkan baca panduan Custom training terlebih dahulu.

Menjalankan loop pelatihan khusus dengan presisi campuran memerlukan dua perubahan saat menjalankannya di float32:

  1. Bangun model dengan presisi campuran (Anda sudah melakukan ini)
  2. Secara eksplisit gunakan penskalaan kerugian jika mixed_float16 digunakan.

Untuk langkah (2), Anda akan menggunakan kelas tf.keras.mixed_precision.LossScaleOptimizer , yang menggabungkan pengoptimal dan menerapkan penskalaan kerugian. Secara default, ini secara dinamis menentukan skala kerugian sehingga Anda tidak harus memilih salah satu. Buat LossScaleOptimizer sebagai berikut.

optimizer = keras.optimizers.RMSprop()
optimizer = mixed_precision.LossScaleOptimizer(optimizer)

Jika Anda mau, dimungkinkan untuk memilih skala kerugian eksplisit atau menyesuaikan perilaku penskalaan kerugian, tetapi sangat disarankan untuk mempertahankan perilaku penskalaan kerugian default, karena telah terbukti berfungsi dengan baik pada semua model yang dikenal. Lihat dokumentasi tf.keras.mixed_precision.LossScaleOptimizer jika Anda ingin menyesuaikan perilaku penskalaan kerugian.

Selanjutnya, tentukan objek loss dan tf.data.Dataset s:

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)

Selanjutnya, tentukan fungsi langkah pelatihan. Anda akan menggunakan dua metode baru dari pengoptimal skala kerugian untuk menskalakan kerugian dan menghapus skala gradien:

  • get_scaled_loss(loss) : Mengalikan kerugian dengan skala kerugian
  • get_unscaled_gradients(gradients) : Mengambil daftar gradien yang diskalakan sebagai input, dan membagi masing-masing dengan skala kerugian untuk menghapus skalanya

Fungsi-fungsi ini harus digunakan untuk mencegah underflow di gradien. LossScaleOptimizer.apply_gradients kemudian akan menerapkan gradien jika tidak ada yang memiliki Inf s atau NaN s. Ini juga akan memperbarui skala kerugian, mengurangi separuhnya jika gradien memiliki Inf s atau NaN s dan berpotensi meningkatkannya sebaliknya.

@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 kemungkinan akan melewatkan beberapa langkah pertama di awal pelatihan. Skala kerugian mulai tinggi sehingga skala kerugian yang optimal dapat dengan cepat ditentukan. Setelah beberapa langkah, skala kerugian akan stabil dan sangat sedikit langkah yang akan dilewati. Proses ini terjadi secara otomatis dan tidak mempengaruhi kualitas pelatihan.

Sekarang, tentukan langkah pengujian:

@tf.function
def test_step(x):
  return model(x, training=False)

Muat bobot awal model, sehingga Anda dapat berlatih kembali dari awal:

model.set_weights(initial_weights)

Terakhir, jalankan loop pelatihan khusus:

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()))
Epoch 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

Kiat kinerja GPU

Berikut adalah beberapa tip kinerja saat menggunakan presisi campuran pada GPU.

Meningkatkan ukuran batch Anda

Jika tidak memengaruhi kualitas model, coba jalankan dengan menggandakan ukuran batch saat menggunakan presisi campuran. Karena tensor float16 menggunakan setengah dari memori, ini sering memungkinkan Anda untuk menggandakan ukuran batch Anda tanpa kehabisan memori. Meningkatkan ukuran batch biasanya meningkatkan throughput pelatihan, yaitu elemen pelatihan per detik yang dapat dijalankan model Anda.

Memastikan GPU Tensor Cores digunakan

Seperti disebutkan sebelumnya, GPU NVIDIA modern menggunakan unit perangkat keras khusus yang disebut Tensor Cores yang dapat mengalikan matriks float16 dengan sangat cepat. Namun, Tensor Cores memerlukan dimensi tensor tertentu untuk menjadi kelipatan 8. Dalam contoh di bawah, argumen dicetak tebal jika dan hanya jika perlu kelipatan 8 agar Tensor Cores dapat digunakan.

  • tf.keras.layers.Dense( unit=64 )
  • tf.keras.layers.Conv2d( filter=48 , kernel_size=7, stride=3)
    • Dan juga untuk lapisan konvolusi lainnya, seperti tf.keras.layers.Conv3d
  • tf.keras.layers.LSTM( unit=64 )
    • Dan serupa untuk RNN ​​lainnya, seperti tf.keras.layers.GRU
  • tf.keras.Model.fit(epochs=2, batch_size=128 )

Anda harus mencoba menggunakan Tensor Cores jika memungkinkan. Jika Anda ingin mempelajari lebih lanjut, panduan kinerja pembelajaran mendalam NVIDIA menjelaskan persyaratan yang tepat untuk menggunakan Tensor Cores serta informasi kinerja terkait Tensor Core lainnya.

XLA

XLA adalah kompiler yang dapat lebih meningkatkan kinerja presisi campuran, serta kinerja float32 pada tingkat yang lebih rendah. Lihat panduan XLA untuk detailnya.

Kiat kinerja Cloud TPU

Seperti halnya GPU, Anda harus mencoba menggandakan ukuran batch saat menggunakan Cloud TPU karena tensor bfloat16 menggunakan setengah dari memori. Menggandakan ukuran batch dapat meningkatkan throughput pelatihan.

TPU tidak memerlukan penyetelan khusus presisi campuran lainnya untuk mendapatkan kinerja yang optimal. Mereka sudah membutuhkan penggunaan XLA. TPU mendapat manfaat dari memiliki dimensi tertentu menjadi kelipatan dari \(128\), tetapi ini berlaku sama untuk tipe float32 seperti halnya untuk presisi campuran. Lihat panduan kinerja Cloud TPU untuk tip kinerja TPU umum, yang berlaku untuk presisi campuran serta tensor float32.

Ringkasan

  • Anda harus menggunakan presisi campuran jika Anda menggunakan TPU atau GPU NVIDIA dengan setidaknya kemampuan komputasi 7.0, karena akan meningkatkan kinerja hingga 3x.
  • Anda dapat menggunakan presisi campuran dengan baris berikut:

    # On TPUs, use 'mixed_bfloat16' instead
    mixed_precision.set_global_policy('mixed_float16')
    
  • Jika model Anda diakhiri dengan softmax, pastikan itu adalah float32. Dan terlepas dari apa model Anda berakhir, pastikan outputnya adalah float32.

  • Jika Anda menggunakan loop pelatihan khusus dengan mixed_float16 , selain baris di atas, Anda perlu membungkus pengoptimal Anda dengan tf.keras.mixed_precision.LossScaleOptimizer . Kemudian panggil optimizer.get_scaled_loss untuk menskalakan kerugian, dan optimizer.get_unscaled_gradients untuk menghapus skala gradien.

  • Gandakan ukuran batch pelatihan jika tidak mengurangi akurasi evaluasi

  • Pada GPU, pastikan sebagian besar dimensi tensor adalah kelipatan dari \(8\) untuk memaksimalkan kinerja

Untuk lebih banyak contoh presisi campuran menggunakan tf.keras.mixed_precision API, periksa repositori model resmi . Sebagian besar model resmi, seperti ResNet dan Transformer , akan berjalan menggunakan presisi campuran dengan melewatkan --dtype=fp16 .