HUOXIU

浮動小数点数の起源と演算解析

数学は自然科学の女王であり、コンピュータはもともと科学計算のために設計されました。コンピュータの最も基本的な機能は、整数と実数を格納し、整数と実数に対して算術演算を実行することです。

しかし、コンピュータの専門家の観点から見ると、私たちが知っている基本的な数学的データ型は、通常、整数、浮動小数点数、ブール値です。整数はさらに、int8(8ビットで表される整数)、uint8(8ビットで表される符号なし整数)、int16、uint16、int32、uint32に分類され、浮動小数点数はfloat16(半精度、FP16)、float32(単精度)、float64(倍精度)に分類されます。今日は浮動小数点数についてお話しします。

#1

なぜ浮動小数点数と呼ばれるのでしょうか?


実数はコンピュータ内で浮動小数点を使用して表現されるため、浮動小数点数と呼ばれます。

1. コンピュータにおける整数表現

ご存知の通り、コンピューターは基本的に2進法を採用しています。整数を2進数で表現するのは簡単です(この記事では、符号・絶対値、1の補数、2の補数、ビッグエンディアンとリトルエンディアンについては扱いません)。最上位ビットは符号ビットを表し、0は正の数、1は負の数を表します。残りのビットは2進値を表します。

`int8` は8ビットで整数を表します。最上位ビットは符号(正負)を表し、残りの7ビットで数字を表します。その範囲は [-128, 127] です。00000000 が正の 0、10000000 が負の 0 を表すので、`int8` の範囲は [-128, 127] ではないかと思う人もいるかもしれません。しかし、同じ数を2つのシーケンスで表すのは、本質的に無駄が多いです。もしコンピューターが最初からこのように無駄遣いされていたら、一体どうなるでしょうか?ですから、資源節約は私から始まります。

2. 固定小数点数を用いた実数の表現

最上位ビットは符号を表し、整数部のビット数は慣例によって決定され、残りのビットは小数部を表します。つまり、小数点の位置は固定です。計算が便利になるという利点がありますが、格納できるデータの範囲が限られるという欠点があります。

3. 浮動小数点数を使用して実数を表します。

最上位ビットは符号を表し、2進ビットの一部は指数部、残りは数値部を表します。この方式の利点は、非常に広い範囲のデータを表現できることですが、欠点は計算速度が遅いことです。しかし、80286の登場と浮動小数点コプロセッサ(FPU)の導入により、浮動小数点表現が主流となりました。

IEEE-754は、IEEE(Institute of Electrical and Electronics Engineersの略で、コンピュータサイエンス分野の多くの標準規格を策定する)によって開発された2進浮動小数点演算規格です。また、コンピュータにおける浮動小数点数の表現に関する業界標準でもあります。1985年に正式に採用され、2008年と2019年にそれぞれ改良と改訂が行われました。


余談

当社の主任科学者である金耀初教授は、IEEE計算知能学会(Computational Intelligence Society)の現会長を務めています。計算知能学会は、IEEE傘下の39の専門学会の一つで、現在約9,000名の会員を擁しています。人工知能と計算知能を主な研究分野とするIEEE傘下の学会です。


次の図に示すように、最も一般的な 64 ビット、32 ビット、および 16 ビットの浮動小数点数を例に挙げてみましょう。

FP64は倍精度浮動小数点数と呼ばれ、合計64ビットで構成されます。符号ビット1ビット、指数ビット11ビット、小数ビット52ビットです。精度の範囲は以下のとおりです。

FP32は最も一般的に使用される浮動小数点数形式であり、単精度浮動小数点数とも呼ばれます。32ビットで構成され、符号に1ビット、指数に8ビット、小数部に23ビットが割り当てられています。表現可能な精度範囲は以下のとおりです。

FP16(半精度浮動小数点数)は16ビットで構成され、符号に1ビット、指数に5ビット、小数に10ビットが割り当てられています。表現できるデータの範囲は以下のとおりです。

次の図に示すように、最も単純な 16 ビット浮動小数点数を例に挙げてみましょう。

インターネット上には、浮動小数点数についてより深く理解するのに役立つ興味深いウェブページがいくつかあります。ここでは、ニューヨーク市立大学コンピュータサイエンス学部が提供しているウェブページ(https://babbage.cs.qc.cuny.edu/ieee-754.old/decimal.html)を取り上げます(または、https://baseconvert.com/ieee-754-floating-point を開くこともできます)。

次に、38.375 などの浮動小数点数をランダムに入力し、「丸め」をクリックして、それがコンピューターでどのように表現されるかを確認します。

  • 最上位ビットは 31 (ビット順序は 0 から始まります) で、ここでは 0 であり、正の数を示します。
  • 次は指数フィールドで、30 から 23 までの 8 ビットがあります。これが表すことができる最大の数字は 256 で、表すことができる最小の数字は 0 です。
  • 指数フィールドの値から 127 を減算する必要があります。ここで、指数フィールドは 10000100 なので、132 - 127 = 5 となります。
  • 残りのビットは仮数フィールドで、ビット 22 からビット 0 までの 23 ビットで構成されます。ここでは 1.00110011 です (小数点の前の 1 は、データの最後の 32 ビットには存在しません。仮数は 1 から始まるように正規化されるため、この 1 は省略されます)。

最上位ビットは分かりやすいのですが、指数部5と仮数部1.00110011を合わせると、なぜ38.375になるのでしょうか?下の計算過程を見る前に、よく考えてみてください。

数値フィールドで小数点を移動するというのは、浮動小数点数の操作でしょうか?これが浮動小数点数の起源だと思います。

次に、浮動小数点の精度に関する興味深い質問があります。0.3 という数値を例に挙げると、0.3 を入力し、「丸めなし」と「丸め」をそれぞれクリックすると(これは2進数なので「丸め」という用語は適切ではないため、元の用語を使用しています)、次の2つの画像が表示されます。


丸めモードなし

丸めなしモードでは、数値フィールドは 1.00110011001100110011001 になり、最終的に計算される小数は 0.299999 となり、常に 0.3 よりわずかに小さくなります。

なぜでしょうか?有限の10進数0.3は、2進数に変換すると無限数(1001が無限に繰り返される)になるからです。桁を省略すると、最終的な10進数はわずかに小さくなり、0.29999999になります。


丸めモード

丸めモードでは、数値フィールドは1.00110011001100110011010となり、1桁繰り上がります。したがって、最終的な数値は0.30000001となり、実際の小数点0.3よりもわずかに大きくなります。

したがって、実際のプログラミングでは、浮動小数点数を直接比較することは推奨されません。浮動小数点数は精度の問題があるため、一般的には範囲比較が使用されます。C/C++プログラマーが遭遇する問題(0.1 + 0.2 = 0.30000000000000004)も、この理由によるものです。



#2

BF16(ブレインフロート)

BF16は、人工知能(AI)とディープラーニング向けに特別に設計された全く新しい浮動小数点形式です。当初はGoogle Brainによって開発され、TPUに適用されましたが、その後、Intel、Armをはじめとする多くの大手企業に広く採用されました。

BF16も浮動小数点数を表すのに16ビットを使用しますが、指数部を表すのに8ビット、小数部を表すのに7ビットを使用します。この場合、BF16で表現できる整数の範囲はFP32と同じですが、小数部に大きな誤差が生じます。

これまで、AIトレーニングのほとんどはFP32を使用していましたが、関連論文では、ディープラーニングにおいて数値の精度を下げることで、結果に大きな影響を与えることなくテンソル乗算の消費電力を削減できることが実証されています。さらに、仮数部の数が少なくなるため、チップ面積も小さくなります。そのため、BF16は、モデルの大規模化と計算負荷の増大が進む人工知能分野で広く応用されています。



#3

モデル量子化とINT8

コンピュータ上のデータ表現の観点から見ると、整数演算は浮動小数点演算よりもはるかに高速です。しかし、ディープニューラルネットワークモデルの学習から得られるパラメータは通常、FP32型です。これを端末NPUに展開する際には、通常、8ビット整数(つまり、int8またはuint8)に量子化する必要があります。

なぜ人工ニューラルネットワークモデルを量子化するのでしょうか?端末の計算能力とリソースには限りがあり、量子化には次のような利点があるからです。

  • モデルサイズが縮小されました。パラメータが元々32ビット実数であった場合、量子化して8ビット整数で表現できるため、モデルサイズは元の4分の1に縮小されます。
  • メモリとストレージの使用量を削減します。
  • 消費電力の削減
  • 計算速度が向上しました。

これらの機能は、モデルを端末デバイスに効果的に展開するのに役立ちます。量子化によって精度は多少低下しますが、優れた量子化アルゴリズムと適切に設計された演算子を使用することで、量子化モデルは端末上でクラウドモデルに近い精度を実現し、クラウドコンピューティングの電力とネットワーク伝送コストを大幅に節約できます。