tf.bfloat16
truncated 16-bit floating point
TensorFlow
machine learning
floating point precision

What is tf.bfloat16 truncated 16-bit floating point?

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

tf.bfloat16 is TensorFlow's Brain Floating Point 16 format, a 16-bit number type designed for fast machine learning workloads. It keeps the wide numeric range of float32 but cuts precision, which makes it especially useful on hardware that accelerates low-precision math.

How bfloat16 Is Different From float16

All three common floating-point formats use a sign bit, exponent bits, and fraction bits. The important difference is how those bits are allocated.

  • 'float32: 1 sign, 8 exponent, 23 fraction bits'
  • IEEE float16: 1 sign, 5 exponent, 10 fraction bits
  • 'bfloat16: 1 sign, 8 exponent, 7 fraction bits'

The key observation is that bfloat16 keeps the same 8-bit exponent as float32. That means its representable range is much closer to float32 than to IEEE float16.

In practice, that wide exponent range helps reduce underflow and overflow during training. The tradeoff is coarser precision because only 7 fraction bits remain.

Why Machine Learning Systems Use It

Deep learning workloads often care more about range and throughput than about exact decimal precision at every intermediate step. Gradients, activations, and matrix multiplications can often tolerate reduced mantissa precision as long as accumulations or master weights stay in float32.

That is why mixed-precision training often works well. TensorFlow can store or compute many intermediate values in bfloat16 while still keeping sensitive state in float32.

Here is a simple TensorFlow example showing the dtype:

python
1import tensorflow as tf
2
3x = tf.constant([1.0, 2.5, 1000.0], dtype=tf.float32)
4y = tf.cast(x, tf.bfloat16)
5z = tf.cast(y, tf.float32)
6
7print(y)
8print(z)

The round-trip back to float32 does not recover lost precision. The truncation already happened when casting to bfloat16.

Mixed Precision in Keras

A common way to use bfloat16 is through a mixed-precision policy.

python
1import tensorflow as tf
2from tensorflow import keras
3
4keras.mixed_precision.set_global_policy('mixed_bfloat16')
5
6model = keras.Sequential([
7    keras.layers.Input(shape=(4,)),
8    keras.layers.Dense(16, activation='relu'),
9    keras.layers.Dense(3)
10])
11
12x = tf.random.normal((8, 4))
13y = model(x)
14print(y.dtype)

On supported hardware, TensorFlow will run many operations in bfloat16 automatically. Variables are often still kept in float32 for stability.

Why It Is Sometimes Better Than IEEE float16

Standard float16 has more fraction bits than bfloat16, so it can represent nearby values more precisely. However, it has a much smaller exponent range. That means float16 is more likely to overflow on large values or underflow on very small ones.

For training large neural networks, that range issue can be more painful than the loss of mantissa precision. bfloat16 was designed around that reality.

A useful rule of thumb is:

  • choose bfloat16 when hardware support exists and training stability matters
  • choose float16 mainly when hardware is optimized for it and your workload behaves well with scaling

Hardware and Performance Considerations

bfloat16 is strongly associated with TPUs, but support has expanded to some CPUs and accelerators as well. The benefit depends on the device. On unsupported hardware, TensorFlow may insert casts or emulate behavior, which reduces the performance advantage.

So the right question is not only "what is bfloat16?" but also "does my target hardware execute it efficiently?"

You can inspect dtypes inside a model and verify whether important kernels are running in mixed precision during profiling.

Numerical Tradeoffs

Because bfloat16 has only 7 fraction bits, nearby values can collapse to the same representation. This makes it inappropriate for tasks that need high-precision accumulation, strict scientific reproducibility, or exact small-difference comparisons.

That does not make it inaccurate for all machine learning. Most successful use cases rely on the fact that training is already noisy and that some computations remain in float32.

Common Pitfalls

A common misconception is that bfloat16 is simply a smaller float16. It is not. Its exponent layout is the important feature.

Another mistake is assuming every operation will safely run in bfloat16. Some reductions, losses, or custom ops should remain in float32 to avoid numerical problems.

Developers also enable mixed precision without checking hardware support. If the device does not accelerate bfloat16, the model may become more complex without becoming faster.

Summary

  • 'tf.bfloat16 uses 16 bits with the same exponent width as float32.'
  • It preserves range better than IEEE float16 but sacrifices precision.
  • Mixed-precision training commonly uses bfloat16 for compute and float32 for sensitive state.
  • It is especially useful on hardware with native bfloat16 support.
  • Always validate both performance and numerical stability on your real workload.

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.