¡Confirme su asistencia a su evento local de TensorFlow Everywhere hoy!
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Precisión mixta

Ver en TensorFlow.org Ejecutar en Google Colab Ver fuente en GitHub Descargar cuaderno

Visión general

La precisión mixta es el uso de tipos de punto flotante de 16 y 32 bits en un modelo durante el entrenamiento para que se ejecute más rápido y use menos memoria. Al mantener ciertas partes del modelo en los tipos de 32 bits para la estabilidad numérica, el modelo tendrá un tiempo de paso más bajo y se entrenará igualmente en términos de métricas de evaluación como la precisión. Esta guía describe cómo utilizar la API de precisión mixta de Keras para acelerar sus modelos. El uso de esta API puede mejorar el rendimiento en más de 3 veces en las GPU modernas y en un 60% en las TPU.

Hoy en día, la mayoría de los modelos usan el tipo dtype float32, que ocupa 32 bits de memoria. Sin embargo, hay dos dtypes de menor precisión, float16 y bfloat16, cada uno de los cuales ocupa 16 bits de memoria. Los aceleradores modernos pueden ejecutar operaciones más rápido en los tipos d de 16 bits, ya que tienen hardware especializado para ejecutar cálculos de 16 bits y los tipos d de 16 bits se pueden leer de la memoria más rápido.

Las GPU NVIDIA pueden ejecutar operaciones en float16 más rápido que en float32, y las TPU pueden ejecutar operaciones en bfloat16 más rápido que float32. Por lo tanto, estos tipos d de menor precisión deben usarse siempre que sea posible en esos dispositivos. Sin embargo, las variables y algunos cálculos aún deberían estar en float32 por razones numéricas para que el modelo se entrene con la misma calidad. La API de precisión mixta de Keras le permite utilizar una combinación de float16 o bfloat16 con float32, para obtener los beneficios de rendimiento de float16 / bfloat16 y los beneficios de estabilidad numérica de float32.

Preparar

import tensorflow as tf

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

Hardware compatible

Si bien la precisión mixta se ejecutará en la mayoría del hardware, solo acelerará los modelos en GPU NVIDIA y Cloud TPU recientes. Las GPU NVIDIA admiten el uso de una combinación de float16 y float32, mientras que las TPU admiten una combinación de bfloat16 y float32.

Entre las GPU NVIDIA, aquellas con capacidad de cómputo 7.0 o superior verán el mayor beneficio de rendimiento de la precisión mixta porque tienen unidades de hardware especiales, llamadas Tensor Cores, para acelerar las multiplicaciones y convoluciones de matrices float16. Las GPU más antiguas no ofrecen ningún beneficio de rendimiento matemático por usar precisión mixta; sin embargo, los ahorros de memoria y ancho de banda pueden permitir algunas aceleraciones. Puede buscar la capacidad de cómputo de su GPU en la página web CUDA GPU de NVIDIA. Entre los ejemplos de GPU que se beneficiarán más de la precisión mixta se incluyen las GPU RTX, la V100 y la A100.

Puede verificar su tipo de GPU con lo siguiente. El comando solo existe si los controladores NVIDIA están instalados, por lo que lo siguiente generará un error de lo contrario.

nvidia-smi -L
GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-3a80b512-ac47-0257-1c4d-c6966adf0f87)

Todas las TPU de Cloud admiten bfloat16.

Incluso en CPU y GPU más antiguas, donde no se espera una aceleración, las API de precisión mixta aún se pueden usar para pruebas unitarias, depuración o simplemente para probar la API. Sin embargo, en las CPU, la precisión mixta se ejecutará significativamente más lento.

Configuración de la política dtype

Para usar precisión mixta en Keras, debe crear una tf.keras.mixed_precision.Policy , generalmente conocida como política dtype . Las políticas de Dtype especifican las capas de dtypes en las que se ejecutarán. En esta guía, creará una política a partir de la cadena 'mixed_float16' y la establecerá como política global. Esto hará que las capas creadas posteriormente utilicen precisión mixta con una combinación de float16 y 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

En resumen, puede pasar directamente una cadena a set_global_policy , lo que normalmente se hace en la práctica.

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

La política especifica dos aspectos importantes de una capa: el tipo d en el que se realizan los cálculos de la capa y el tipo d de las variables de una capa. Arriba, creaste una política mixed_float16 (es decir, una mixed_precision.Policy creada pasando la cadena 'mixed_float16' a su constructor). Con esta política, las capas utilizan cálculos float16 y variables float32. Los cálculos se realizan en float16 para el rendimiento, pero las variables deben mantenerse en float32 para la estabilidad numérica. Puede consultar directamente estas propiedades de la política.

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

Como se mencionó anteriormente, la política mixed_float16 mejorará significativamente el rendimiento en las GPU NVIDIA con una capacidad de cómputo de al menos 7.0. La política se ejecutará en otras GPU y CPU, pero es posible que no mejore el rendimiento. Para las TPU, se debe usar la política mixed_bfloat16 en su lugar.

Construyendo el modelo

A continuación, comencemos a construir un modelo simple. Los modelos de juguetes muy pequeños generalmente no se benefician de la precisión mixta, porque la sobrecarga del tiempo de ejecución de TensorFlow generalmente domina el tiempo de ejecución, lo que hace que cualquier mejora de rendimiento en la GPU sea insignificante. Por lo tanto, construyamos dos capas Dense grandes con 4096 unidades cada una si se usa una GPU.

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

Cada capa tiene una política y utiliza la política global de forma predeterminada. Por lo tanto, cada una de las capas Dense tiene la política mixed_float16 porque mixed_float16 configuró la política global en mixed_float16 . Esto hará que las capas densas hagan cálculos de float16 y tengan variables float32. Lanzan sus entradas a float16 para hacer cálculos de float16, lo que hace que sus salidas sean float16 como resultado. Sus variables son float32 y se convertirán en float16 cuando se invoquen las capas para evitar errores por desajustes de tipo d.

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

A continuación, cree las predicciones de salida. Normalmente, puede crear las predicciones de salida de la siguiente manera, pero esto no siempre es numéricamente estable con 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

Una activación softmax al final del modelo debería ser float32. Debido a que la política dtype es mixed_float16 , la activación de softmax normalmente tendría un tipo de cálculo float16 y generaría tensores float16.

Esto se puede solucionar separando las capas Dense y softmax, y pasando dtype='float32' a la capa 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

Pasar dtype='float32' al constructor de la capa softmax anula la política dtype de la capa para que sea la política float32 , que realiza cálculos y mantiene las variables en float32. De manera equivalente, podríamos haber pasado dtype=mixed_precision.Policy('float32') ; Las capas siempre convierten el argumento dtype en una política. Debido a que la capa de Activation no tiene variables, la variable dtype de la política se ignora, pero el cálculo dtype de la política de float32 hace que softmax y la salida del modelo sean float32.

Agregar un softmax float16 en medio de un modelo está bien, pero un softmax al final del modelo debe estar en float32. La razón es que si el tensor intermedio que fluye desde el softmax a la pérdida es float16 o bfloat16, pueden ocurrir problemas numéricos.

Puede anular el dtype de cualquier capa para que sea float32 pasando dtype='float32' si cree que no será numéricamente estable con los cálculos de float16. Pero normalmente, esto solo es necesario en la última capa del modelo, ya que la mayoría de las capas tienen suficiente precisión con mixed_float16 y mixed_bfloat16 .

Incluso si el modelo no termina en un softmax, las salidas aún deben ser float32. Si bien no es necesario para este modelo específico, las salidas del modelo se pueden convertir a float32 con lo siguiente:

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

A continuación, finalice y compile el modelo y genere datos de entrada.

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
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step

Este ejemplo convierte los datos de entrada de int8 a float32. No lanzamos a float16 ya que la división por 255 está en la CPU, que ejecuta las operaciones float16 más lentamente que las operaciones float32. En este caso, la diferencia de rendimiento es insignificante, pero en general debe ejecutar las matemáticas de procesamiento de entrada en float32 si se ejecuta en la CPU. La primera capa del modelo emitirá las entradas a float16, ya que cada capa emitirá entradas de punto flotante a su tipo de cálculo.

Se recuperan los pesos iniciales del modelo. Esto permitirá volver a entrenar desde cero cargando las pesas.

initial_weights = model.get_weights()

Entrenamiento del modelo con Model.fit

A continuación, entrena el modelo.

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 102ms/step - loss: 3.8559 - accuracy: 0.3288 - val_loss: 0.7881 - val_accuracy: 0.7675
Epoch 2/5
6/6 [==============================] - 0s 33ms/step - loss: 0.8288 - accuracy: 0.7555 - val_loss: 0.3259 - val_accuracy: 0.9085
Epoch 3/5
6/6 [==============================] - 0s 33ms/step - loss: 0.3398 - accuracy: 0.8971 - val_loss: 0.2899 - val_accuracy: 0.9119
Epoch 4/5
6/6 [==============================] - 0s 31ms/step - loss: 0.2805 - accuracy: 0.9135 - val_loss: 0.1955 - val_accuracy: 0.9415
Epoch 5/5
6/6 [==============================] - 0s 32ms/step - loss: 0.2402 - accuracy: 0.9251 - val_loss: 0.2413 - val_accuracy: 0.9213
313/313 - 0s - loss: 0.2494 - accuracy: 0.9189
Test loss: 0.24936337769031525
Test accuracy: 0.9189000129699707

Observe que el modelo imprime el tiempo por paso en los registros: por ejemplo, "25ms / paso". La primera época puede ser más lenta ya que TensorFlow dedica algún tiempo a optimizar el modelo, pero luego el tiempo por paso debería estabilizarse.

Si está ejecutando esta guía en Colab, puede comparar el rendimiento de precisión mixta con float32. Para hacerlo, cambie la política de mixed_float16 a float32 en la sección "Configuración de la política dtype", luego vuelva a ejecutar todas las celdas hasta este punto. En GPU con capacidad informática 7.X, debería ver que el tiempo por paso aumenta significativamente, lo que indica que la precisión mixta aceleró el modelo. Asegúrese de volver a cambiar la política a mixed_float16 y vuelva a ejecutar las celdas antes de continuar con la guía.

En GPU con capacidad de cómputo de al menos 8.0 (GPU Ampere y superior), es probable que no vea ninguna mejora de rendimiento en el modelo de juguete de esta guía cuando utilice precisión mixta en comparación con float32. Esto se debe al uso de TensorFloat-32 , que automáticamente usa matemáticas de menor precisión en ciertas operaciones de tf.linalg.matmul como tf.linalg.matmul . TensorFloat-32 ofrece algunas de las ventajas de rendimiento de la precisión mixta cuando se usa float32. Sin embargo, en los modelos del mundo real, normalmente verá mejoras de rendimiento significativas debido a la precisión mixta debido al ahorro de ancho de banda de la memoria y las operaciones que TensorFloat-32 no admite.

Si ejecuta precisión mixta en una TPU, no verá tanta ganancia de rendimiento en comparación con la ejecución de precisión mixta en GPU, especialmente GPU pre-Ampere. Esto se debe a que las TPU realizan ciertas operaciones en bfloat16 bajo el capó incluso con la política dtype predeterminada de float32. Esto es similar a cómo las GPU Ampere usan TensorFloat-32 de forma predeterminada. En comparación con las GPU Ampere, las TPU suelen obtener menos ganancias de rendimiento con precisión mixta en modelos del mundo real.

Para muchos modelos del mundo real, la precisión mixta también le permite duplicar el tamaño del lote sin quedarse sin memoria, ya que los tensores float16 ocupan la mitad de la memoria. Sin embargo, esto no se aplica a este modelo de juguete, ya que es probable que pueda ejecutar el modelo en cualquier dtype donde cada lote consista en el conjunto de datos MNIST completo de 60.000 imágenes.

Escalado de pérdidas

El escalado de pérdidas es una técnica que tf.keras.Model.fit realiza automáticamente con la política mixed_float16 para evitar el subdesbordamiento numérico. Esta sección describe qué es el escalado de pérdidas y la siguiente sección describe cómo usarlo con un ciclo de entrenamiento personalizado.

Desbordamiento y desbordamiento

El tipo de datos float16 tiene un rango dinámico estrecho en comparación con float32. Esto significa que los valores por encima de $ 65504 $ se desbordarán hasta el infinito y los valores por debajo de $ 6.0 \ times 10 ^ {- 8} $ se desbordarán hasta cero. float32 y bfloat16 tienen un rango dinámico mucho más alto para que el desbordamiento y el desbordamiento no sean un problema.

Por ejemplo:

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

En la práctica, el desbordamiento con float16 rara vez ocurre. Además, el subdesbordamiento también ocurre raramente durante el pase hacia adelante. Sin embargo, durante el paso hacia atrás, los gradientes pueden desbordar hasta cero. El escalado de pérdidas es una técnica para prevenir este desbordamiento.

Resumen de escala de pérdidas

El concepto básico de escalado de pérdidas es simple: simplemente multiplique la pérdida por un número grande, digamos $ 1024 $. A este número lo llamamos escala de pérdidas . Esto hará que los gradientes también se escalen en $ 1024 $, lo que reducirá en gran medida la posibilidad de subdesbordamiento. Una vez que se hayan calculado los gradientes finales, divídalos entre $ 1024 $ para devolverlos a sus valores correctos.

El pseudocódigo para este proceso es:

loss_scale = 1024
loss = model(inputs)
loss *= loss_scale
# We assume `grads` are float32. We do not want to divide float16 gradients
grads = compute_gradient(loss, model.trainable_variables)
grads /= loss_scale

Elegir una escala de pérdidas puede resultar complicado. Si la escala de pérdida es demasiado baja, es posible que los gradientes aún se desborden hasta cero. Si es demasiado alto, ocurre el problema contrario: los gradientes pueden desbordarse hasta el infinito.

Para resolver esto, TensorFlow determina dinámicamente la escala de pérdida para que no tenga que elegir una manualmente. Si usa tf.keras.Model.fit , el escalado de pérdidas se realiza por usted para que no tenga que hacer ningún trabajo adicional. Si usa un bucle de entrenamiento personalizado, debe usar explícitamente el contenedor optimizador especial tf.keras.mixed_precision.LossScaleOptimizer para usar el escalado de pérdidas. Esto es descrito en la siguiente sección.

Entrenamiento del modelo con un ciclo de entrenamiento personalizado

Hasta ahora, entrenó un modelo de Keras con precisión mixta usando tf.keras.Model.fit . A continuación, utilizará precisión mixta con un ciclo de entrenamiento personalizado. Si aún no sabe qué es un ciclo de entrenamiento personalizado, lea primero la Guía de entrenamiento personalizado .

Ejecutar un ciclo de entrenamiento personalizado con precisión mixta requiere dos cambios sobre su ejecución en float32:

  1. Construye el modelo con precisión mixta (ya hiciste esto)
  2. Utilice explícitamente el escalado de pérdidas si se utiliza mixed_float16 .

Para el paso (2), utilizará la clase tf.keras.mixed_precision.LossScaleOptimizer , que envuelve un optimizador y aplica la escala de pérdidas. De forma predeterminada, determina dinámicamente la escala de pérdidas para que no tenga que elegir una. Construya un LossScaleOptimizer siguiente manera.

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

Si lo desea, es posible elegir una escala de pérdida explícita o personalizar el comportamiento de escala de pérdida, pero es muy recomendable mantener el comportamiento de escala de pérdida predeterminado, ya que se ha encontrado que funciona bien en todos los modelos conocidos. Consulte la documentación tf.keras.mixed_precision.LossScaleOptimizer si desea personalizar el comportamiento de escala de pérdidas.

A continuación, defina el objeto de pérdida y lostf.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)

A continuación, defina la función de paso de entrenamiento. Se utilizan dos nuevos métodos del optimizador de escala de pérdidas para escalar la pérdida y desescalar los gradientes:

  • get_scaled_loss(loss) : multiplica la pérdida por la escala de pérdida
  • get_unscaled_gradients(gradients) : toma una lista de gradientes escalados como entradas y divide cada uno por la escala de pérdida para desescalarlos

Estas funciones deben utilizarse para evitar el desbordamiento en los gradientes. LossScaleOptimizer.apply_gradients aplicará degradados si ninguno de ellos tiene Infs o NaNs. También actualizará la escala de pérdida, reduciéndola a la mitad si los gradientes tenían Infs o NaNs y potencialmente aumentándola de lo contrario.

@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 probable que LossScaleOptimizer omita los primeros pasos al comienzo del entrenamiento. La escala de pérdidas comienza alta para que se pueda determinar rápidamente la escala de pérdidas óptima. Después de algunos pasos, la escala de pérdidas se estabilizará y se omitirán muy pocos pasos. Este proceso ocurre automáticamente y no afecta la calidad del entrenamiento.

Ahora defina el paso de prueba.

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

Carga los pesos iniciales del modelo, para que puedas volver a entrenar desde cero.

model.set_weights(initial_weights)

Finalmente, ejecute el ciclo de entrenamiento personalizado.

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=3.2661855220794678, test accuracy=0.7788000106811523
Epoch 1: loss=0.4780425727367401, test accuracy=0.8751000165939331
Epoch 2: loss=0.3246038258075714, test accuracy=0.909600019454956
Epoch 3: loss=0.2638581097126007, test accuracy=0.9025999903678894
Epoch 4: loss=0.21085180342197418, test accuracy=0.9505000114440918

Consejos de rendimiento de la GPU

A continuación, se muestran algunos consejos de rendimiento al utilizar precisión mixta en GPU.

Aumentar el tamaño de su lote

Si no afecta la calidad del modelo, intente ejecutar con el doble del tamaño de lote cuando utilice precisión mixta. Como los tensores float16 usan la mitad de la memoria, esto a menudo le permite duplicar el tamaño de su lote sin quedarse sin memoria. El aumento del tamaño del lote normalmente aumenta el rendimiento del entrenamiento, es decir, los elementos de entrenamiento por segundo en los que se puede ejecutar su modelo.

Asegurarse de que se usen núcleos tensores de GPU

Como se mencionó anteriormente, las GPU NVIDIA modernas usan una unidad de hardware especial llamada Tensor Cores que puede multiplicar matrices float16 muy rápidamente. Sin embargo, Tensor Cores requiere que ciertas dimensiones de tensores sean múltiplos de 8. En los ejemplos siguientes, un argumento está en negrita si y solo si necesita ser un múltiplo de 8 para que se usen Tensor Cores.

  • tf.keras.layers.Dense ( unidades = 64 )
  • tf.keras.layers.Conv2d ( filtros = 48 , kernel_size = 7, stride = 3)
    • Y de manera similar para otras capas convolucionales, como tf.keras.layers.Conv3d
  • tf.keras.layers.LSTM ( unidades = 64 )
    • Y similar para otros RNN, como tf.keras.layers.GRU
  • tf.keras.Model.fit (épocas = 2, tamaño_lote = 128 )

Deberías intentar usar Tensor Cores cuando sea posible. Si desea obtener más información, la guía de rendimiento de aprendizaje profundo de NVIDIA describe los requisitos exactos para usar Tensor Cores, así como otra información de rendimiento relacionada con Tensor Core.

XLA

XLA es un compilador que puede aumentar aún más el rendimiento de precisión mixta, así como el rendimiento de float32 en menor medida. Consulte la guía XLA para obtener más detalles.

Consejos de rendimiento de Cloud TPU

Al igual que en las GPU, debería intentar duplicar el tamaño de su lote, ya que los tensores bfloat16 utilizan la mitad de la memoria. Duplicar el tamaño del lote puede aumentar el rendimiento del entrenamiento.

Las TPU no requieren ningún otro ajuste específico de precisión mixto para obtener un rendimiento óptimo. Las TPU ya requieren el uso de XLA. Se benefician de que ciertas dimensiones sean múltiplos de $ 128 $, pero esto se aplica tanto a float32 como a la precisión mixta. Consulta la Guía de rendimiento de Cloud TPU para obtener sugerencias generales sobre el rendimiento de TPU, que se aplican tanto a la precisión mixta como a float32.

Resumen

  • Debe usar precisión mixta si usa TPU o GPU NVIDIA con al menos capacidad de cómputo 7.0, ya que mejorará el rendimiento hasta 3 veces.
  • Puede utilizar precisión mixta con las siguientes líneas:

    # On TPUs, use 'mixed_bfloat16' instead
    mixed_precision.set_global_policy('mixed_float16')
    
  • Si su modelo termina en softmax, asegúrese de que sea float32. E independientemente de en qué termine su modelo, asegúrese de que la salida sea float32.

  • Si utiliza un ciclo de entrenamiento personalizado con mixed_float16 , además de las líneas anteriores, debe envolver su optimizador con un tf.keras.mixed_precision.LossScaleOptimizer . Luego, llame a optimizer.get_scaled_loss para escalar la pérdida y a optimizer.get_unscaled_gradients para cambiar la escala de los gradientes.

  • Duplique el tamaño del lote de entrenamiento si no reduce la precisión de la evaluación

  • En las GPU, asegúrese de que la mayoría de las dimensiones del tensor sean múltiplos de $ 8 $ para maximizar el rendimiento

Para obtener más ejemplos de precisión mixta utilizando la API tf.keras.mixed_precision , consulte el repositorio oficial de modelos . La mayoría de los modelos oficiales, como ResNet y Transformer, se ejecutarán con precisión mixta pasando --dtype=fp16 .