Mixed precision

Keras · Advanced · 10 min

Mixed precision can roughly double training speed on modern GPUs and TPUs on every Keras backend.

Keras controls numeric precision with dtype policies. A mixed policy computes in 16-bit floats while storing variables in float32:

keras.config.set_dtype_policy("mixed_bfloat16")

Every layer created afterwards gets compute_dtype bfloat16 and variable_dtype float32. Use "mixed_bfloat16" on TPUs and recent GPUs (NVIDIA Ampere and newer); use "mixed_float16" on older tensor-core GPUs.

Guidelines:

  • Keep the model's output in float32 by giving the last layer dtype="float32" (often a final Activation("softmax", dtype="float32")).
  • With mixed_float16, small gradients underflow, so a LossScaleOptimizer is needed; compile() wraps your optimizer automatically. In a custom train step, call optimizer.scale_loss(loss) before computing gradients.
  • bfloat16 has float32's exponent range and does not need loss scaling.
  • Individual layers can override the policy with dtype=....

Set the policy before building the model, and reset it with keras.config.set_dtype_policy("float32") if later code should run in full precision. Measure: on CPUs and older GPUs mixed precision can be slower.

Example

import keras
from keras import layers

keras.config.set_dtype_policy("mixed_bfloat16")    # or "mixed_float16" on older GPUs

model = keras.Sequential([
    keras.Input((512,)),
    layers.Dense(1024, activation="relu"),
    layers.Dense(10),
    layers.Activation("softmax", dtype="float32"),  # numerically sensitive output
])
d = model.layers[0]
print(d.dtype_policy.name, d.compute_dtype, d.variable_dtype)
# mixed_bfloat16 bfloat16 float32
print(model.layers[-1].compute_dtype)              # float32

model.compile(optimizer="adam", loss="sparse_categorical_crossentropy")
# with "mixed_float16", compile() wraps the optimizer in a LossScaleOptimizer

keras.config.set_dtype_policy("float32")           # reset the global policy

Remember

  • Mixed policies: 16-bit compute, float32 variables
  • Keep the final output layer in float32
  • float16 needs loss scaling (automatic in compile); bfloat16 does not

Watch out for

  • Setting the policy after the model was built, so existing layers keep float32.

Check yourself

  1. Under the mixed_bfloat16 policy, what are a Dense layer's compute and variable dtypes?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: keras.io/api/mixed_precision/

Builds on

Unlocks

Nothing builds on this yet.