TensorFlow
float16
bug
machine learning
software issue

TensorFlow float16 support is broken

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

When people say TensorFlow float16 support is "broken", the usual problem is not that half precision is unusable. The real issue is that pure float16 training is fragile unless you use the right hardware, mixed precision policies, and numerically safe output layers.

Why float16 Feels Unstable

float16 uses less memory and can run much faster on GPUs that have native half-precision support. The tradeoff is reduced numeric range and precision.

That reduced range causes two common problems:

  • Very small gradients can underflow to zero.
  • Large activations or losses can overflow and become inf or nan.

If you convert an entire model to raw float16 without any extra safeguards, training can fail even though the same model works in float32.

This is why modern TensorFlow guidance focuses on mixed precision rather than manually forcing every tensor to half precision.

Use Mixed Precision Instead Of Pure float16

Mixed precision keeps most compute-heavy layers in float16 while preserving numerically sensitive parts in float32. TensorFlow handles much of this automatically through a global policy.

python
1import tensorflow as tf
2from tensorflow import keras
3from tensorflow.keras import mixed_precision
4
5mixed_precision.set_global_policy("mixed_float16")
6
7model = keras.Sequential([
8    keras.layers.Input(shape=(784,)),
9    keras.layers.Dense(256, activation="relu"),
10    keras.layers.Dense(128, activation="relu"),
11    keras.layers.Dense(10, activation="softmax", dtype="float32")
12])
13
14model.compile(
15    optimizer=keras.optimizers.Adam(),
16    loss="sparse_categorical_crossentropy",
17    metrics=["accuracy"]
18)
19
20print(model.dtype_policy)

The final layer is explicitly set to float32. That detail matters because softmax and loss calculations are exactly the places where reduced precision often becomes unstable.

With this setup, TensorFlow also applies loss scaling when needed, which helps preserve small gradient values during backpropagation.

Hardware Matters More Than People Expect

Another source of confusion is hardware support. float16 is most useful on GPUs and accelerators designed for it. On CPUs, half precision may be slower, partially unsupported for some kernels, or silently cast back to float32.

That can make the feature look inconsistent:

  • On one machine, training is faster and stable.
  • On another, it is slower or certain ops fall back to a different dtype.

So before blaming TensorFlow alone, check the execution device:

python
import tensorflow as tf

print(tf.config.list_physical_devices("GPU"))

If no compatible GPU is available, mixed precision may provide little benefit and can sometimes complicate debugging.

Debugging nan And Overflow Problems

When a model blows up after enabling half precision, simplify the problem first. Keep the training loop the same and only change the precision policy. If the failure appears immediately, inspect the model for numerically sensitive steps.

Common hot spots include:

  • Very large learning rates.
  • Unbounded activations.
  • Softmax or exponential calculations in float16.
  • Custom loss functions that assume float32.

You can also inspect dtypes layer by layer:

python
for layer in model.layers:
    print(layer.name, layer.dtype_policy)

If a custom layer manually creates tensors with mismatched dtypes, TensorFlow may spend time casting back and forth or raise dtype-related errors.

Keep Sensitive Operations In float32

Some operations are better left in full precision even when the rest of the model uses mixed precision. Output heads, reductions, normalization steps, and custom losses are common examples.

A safe pattern is:

  • Use mixed precision globally.
  • Leave the final output in float32.
  • Cast inside custom losses if needed.

Example:

python
1import tensorflow as tf
2
3def stable_mse(y_true, y_pred):
4    y_true = tf.cast(y_true, tf.float32)
5    y_pred = tf.cast(y_pred, tf.float32)
6    return tf.reduce_mean(tf.square(y_true - y_pred))

That small cast is often enough to avoid mysterious instability in custom training code.

When It Really Is An Unsupported Op

Sometimes the complaint is valid in a narrower sense: a specific TensorFlow op or third-party layer may not have a good float16 implementation on the target device. In those cases, the fix is usually to isolate that operation and keep it in float32.

Not every model needs end-to-end half precision to benefit. If one layer forces fallback or instability, localizing the precision choice is usually better than abandoning mixed precision entirely.

Common Pitfalls

The biggest mistake is forcing the whole model to pure float16 and expecting float32 behavior. Half precision needs more care around losses, output activations, and optimizer behavior.

Another mistake is evaluating half-precision performance on unsupported hardware. If the device does not accelerate float16, the feature may add overhead instead of speed.

Developers also sometimes forget that custom layers and losses inherit the precision policy too. A custom op that was stable in float32 can become unstable if it uses exponentials, divisions, or reductions without casts.

Finally, do not judge the feature by a single nan loss. Most failures come from how the model uses float16, not from TensorFlow being unable to represent the dtype at all.

Summary

  • 'float16 issues usually come from numeric range limits, not from the dtype being fundamentally unusable.'
  • Mixed precision is the recommended TensorFlow approach, not manual pure float16 everywhere.
  • Keep output and loss-sensitive computations in float32 when needed.
  • Hardware support strongly affects speed and stability.
  • If a specific layer breaks, isolate that part instead of abandoning mixed precision for the entire model.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.