FP16・bfloat16ビットパターン可視化ツール

半精度浮動小数点数(FP16、IEEE 754 binary16)とbfloat16のビットパターンを可視化する無料ツール。10進数からビットへ、ビットから10進数へ相互変換でき、符号・指数部・仮数部を色分け表示します。機械学習の量子化・推論高速化の学習に。

FP16とbfloat16の構造比較

どちらも合計16ビットですが、指数部と仮数部のビット配分が異なるため、表現できる値の範囲と精度がまったく違います。

項目 FP16(IEEE 754 半精度) bfloat16
合計ビット数 16 16
指数部のビット数 5 8
仮数部のビット数 10 7
表現できる値の範囲 約±6.1×10⁻⁵ 〜 ±65504(範囲は狭いが仮数部が多く精度が高い) 約±1.2×10⁻³⁸ 〜 ±3.4×10³⁸(float32と同じ広い範囲だが精度は低い)
主な用途 画像処理・グラフィックス、推論時の省メモリ化(半精度学習) ディープラーニングの学習(TPU・最新GPU)。float32からの変換時に指数部の桁あふれを気にしなくてよい

bfloat16は指数部がfloat32(単精度)と同じ8ビット・同じバイアス(127)であるため、float32の仮数部を単純に切り捨てるだけで変換できるという実装上の利点があります。

FP16とbfloat16のビットの並びを見る

同じ16ビットでも、FP16(IEEE 754 binary16)と bfloat16 ではビットの配り方がまったく違います。このツールは10進数とビットパターンを相互に変換し、符号・指数部・仮数部を色分けして示すことで、その違いを目で確かめられるようにしたものです。

**要点は配分の違いにあります。FP16 は指数に5ビット・仮数に10ビットを割り当てるのに対し、bfloat16 は指数に8ビット・仮数に7ビットを割り当てます。** 指数8ビットというのは単精度(FP32)とまったく同じで、ここから2つの性質が出てきます。ひとつは**表せる値の範囲が FP32 と同じになること**、もうひとつは**FP32 の上位16ビットを切り捨てるだけで変換できること**です。機械学習で bfloat16 が好まれるのはこのためで、学習中に値が範囲外へ飛んで壊れる心配が小さく済みます。代わりに仮数が7ビットしかないので**精度は FP16 より粗くなります。** 精度が要るなら FP16、範囲が要るなら bfloat16、という住み分けです。

使い方

  1. 変換の向きを選ぶ 10進数からビットへ、ビットから10進数へ、どちらも選べます。
  2. 値を入力する 10進数でも、0と1の並びでもかまいません。
  3. 色分けされたビットを読む **符号・指数部・仮数部がそれぞれ別の色で示されます。**
  4. FP16とbfloat16を見比べる **同じ値を両形式で表すと、どこに違いが出るかが分かります。**

使いこなすためのヒント

  • 同じ0.1という値でも、FP16と bfloat16 では丸め誤差の出方がまったく異なります。フォーマットを切り替えて仮数部のビット列を見比べてみてください。
  • bfloat16はfloat32と指数部のビット幅・バイアスが同じため、65504を超えるような大きな値でもオーバーフローしにくいのが特徴です。逆にFP16は65504を超えるとすぐに無限大になります。
  • 「70000」をFP16に変換するとオーバーフローして無限大になりますが、bfloat16では正常に(精度は落ちつつも)表現できます。
  • 機械学習フレームワーク(PyTorch・TensorFlow)でモデルの量子化を行う際、bfloat16はfloat32からの変換が容易な一方、FP16は表現範囲が狭いため事前のスケーリングが必要になることがあります。
  • ビットパターンからの逆変換では、`0x`接頭辞付きの4桁16進数か、16桁の2進数(`0b`接頭辞は任意)で入力する必要があります。

活用シーン

量子化の影響を理解する

**モデルを16ビットへ落としたとき、値がどこまで丸められるのかを具体的に確かめられます。**

形式の選択を判断する

範囲が要るのか精度が要るのかで、どちらを選ぶべきかを考える材料になります。

オーバーフローの境界を確かめる

**FP16 で表せる最大値を超えるとどうなるかを、実際の値で試せます。**

浮動小数点数の仕組みを学ぶ

指数と仮数がどう働いて1つの数を表すのかを、ビットを見ながら追えます。

浮動小数点数の用語

符号ビット
最上位の1ビットで、正負を表します。0が正、1が負です。
指数部
値の大きさの桁を表す部分です。**FP16 は5ビット、bfloat16 は8ビットを割り当てます。**
仮数部
有効数字にあたる部分です。**FP16 は10ビット、bfloat16 は7ビットで、この差がそのまま精度の差になります。**
bfloat16
**指数部を FP32 と同じ8ビットに保った16ビット形式**です。範囲を犠牲にせず容量を半分にできます。
非正規化数
指数部が最小のときに使われる表現で、0に極めて近い値を表せます。
量子化
モデルの重みをより少ないビット数で表す手法です。**容量と計算量が減る代わりに精度が落ちます。**

よくある質問

どちらも合計16ビットですが、FP16(IEEE 754半精度)は指数部5ビット・仮数部10ビット、bfloat16は指数部8ビット・仮数部7ビットという配分の違いがあります。FP16は仮数部が多い分精度が高いですが表現できる範囲が狭く、bfloat16はfloat32と同じ広い範囲を表現できる代わりに精度が低くなります。

ディープラーニングの学習では、勾配やパラメータが非常に大きい値・非常に小さい値のどちらにもなり得るため、float32と同じ広い表現範囲(オーバーフロー・アンダーフローしにくい)を保ちながらメモリと計算量を半分に抑えられるbfloat16が好まれます。FP16は表現範囲が狭くオーバーフローしやすいため、学習時には追加のスケーリング(loss scaling)が必要になることがあります。

約65504です。これを超える値をFP16に変換しようとすると、桁あふれ(オーバーフロー)により無限大(Infinity)になります。一方bfloat16はfloat32と同じ指数部の幅を持つため、約3.4×10³⁸まで表現できます。

指数部がすべて0のビットパターンのうち、仮数部が0でないものです。通常の(正規化された)浮動小数点数は仮数の先頭に暗黙の1が付きますが、非正規化数はこれを省略することで、通常表現できる最小値よりもさらにゼロに近い値を表現します(有効桁数は犠牲になります)。

bfloat16はfloat32と指数部のビット幅(8ビット)・バイアス(127)が完全に一致しているため、float32のビットパターンの仮数部を上位7ビットだけ残して切り捨てる(丸める)だけで変換できます。指数部の再計算や範囲チェックが不要なため、実装がシンプルになります。
ツールくん

余談ですが ― なぜ機械学習は「精度を落とした」数値表現を求めたのか

2018年前後、Googleが自社のTPU(Tensor Processing Unit)向けにbfloat16という新しい16ビット浮動小数点フォーマットを考案しました。それ以前から存在したFP16(IEEE 754の半精度)は画像処理やグラフィックス分野ですでに実用化されていましたが、指数部がわずか5ビットしかないため表現できる値の範囲が狭く、ディープラーニングの学習時に勾配が非常に小さくなったり大きくなったりする現象(勾配消失・勾配爆発)に対応しきれないという課題がありました。

bfloat16の設計思想は明快です。仮数部の精度を犠牲にする代わりに、指数部のビット幅をfloat32(単精度)とまったく同じ8ビットに保つことで、学習中に頻発する極端に大きい・小さい値を安全に扱えるようにしたのです。「Brain Floating Point」という名前は、Googleの機械学習研究部門「Google Brain」に由来します。

通常のコンピューター科学では、浮動小数点数の精度を落とすことは「バグの温床」として避けられてきました。しかしディープラーニングのモデルは、多少の数値誤差があっても最終的な予測精度にはほとんど影響しないという特殊な性質を持っています。この「多少不正確でも全体としては機能する」という性質を逆手に取り、メモリ使用量と計算コストを半分に抑えられる16ビット表現が広く普及した点は、コンピューター科学の常識とは一線を画す、機械学習分野ならではの最適化と言えるでしょう。