FP16 (半精度): FP16 では、浮動小数点数が 16 ビットを使用して表現されます。符号ビット 1 ビット、指数部 5 ビット、小数部 (仮数部) 10 ビットで構成されます。この形式は、その範囲内の小数値をより高い精度で表現します。
BF16 (BFloat16): BF16 も 16 ビットを使用しますが、分布が異なります。 1 つの符号ビット、8 ビットの指数、7 ビットの仮数があります。この形式では、より広範囲の指数に対応するために、小数部分の精度がある程度犠牲になります。
FP16 の範囲は狭いですが、仮数部が 10 ビットであるため、その範囲内の精度は高くなります。
BF16 の範囲は広いですが、指数が 8 ビットで仮数が 7 ビットであるため、小数値の精度が低くなります。
3 つの例を使用して、FP16 と BF16 の違いを説明しましょう。 TensorFlow は、下部で共有されるテストとコードを作成するために使用されます:
元の値: 0.0001 — どちらのメソッドも
FP16: 0.00010001659393 (バイナリ: 0|00001|1010001110、16 進数: 068E) — 10 個の仮数と 5 個の指数
BF16: 0.00010013580322 (バイナリ: 0|01110001|1010010、16 進数: 38D2) — 7 つの仮数と 8 つの指数
ご覧のとおり、指数と仮数が異なるため、異なる方法で表現できます。 しかし、FP16 では、より近い値でより正確に表現されていることがわかります。
元の値: 1e-08 (0.00000001)
FP16: 0.00000000000000 (バイナリ: 0|00000|0000000000、16 進数: 0000)
BF16: 0.00000001001172 (バイナリ: 0|01100100| 0101100、16進数: 322C)
これは非常に興味深いケースです。 FP16 は失敗し、結果は 0 になりますが、BF16 は特別な形式でそれを表現できます。
元の値: 100000.00001
FP16: inf (バイナリ: 0|11111|0000000000、16 進数: 7C00)
BF16: 99840.00000000000000 (バイナリ: 0|10001111| 1000011、16 進数: 47C3 )
上記の場合、すべての指数ビットがいっぱいになり、値を表すのに十分ではないため、FP16 は失敗します。ただしBF16は動作します
FP16 は、ディープ ラーニングのトレーニングと推論、特に限られた範囲内で小さな小数値を表現する際に高精度が必要なタスクによく使用されます。
BF16 は、小数部分の精度が多少犠牲になっても、より広範囲の表現可能な値の恩恵を受ける機械学習タスク用に設計されたハードウェア アーキテクチャで人気が高まっています。これは、大きな勾配を扱う場合、または小さな値の精度よりも広範囲にわたる数値の安定性が重要な場合に特に役立ちます。
FP16 は、より狭い範囲内の分数値の精度が高いため、小さな数値を正確に表現する必要があるタスクに適しています。一方、BF16 は、ある程度の精度を犠牲にしてより広い範囲を提供するため、より広範囲の値を扱うタスクや、広範囲にわたる数値の安定性が重要なタスクに有利です。 FP16 と BF16 のどちらを選択するかは、当面の機械学習タスクの特定の要件によって異なります。
上記の理由により、安定拡散 XL (SDXL) トレーニングを行う場合、FP16 と BF16 ではわずかに異なる学習率が必要となり、BF16 の方が効果的であることがわかりました。
上記の例の生成に使用したコード
import tensorflow as tf import struct def float_to_binary(f): return ''.join(f'{b:08b}' for b in struct.pack('>f', f)) def display_fp16(value): fp16 = tf.cast(tf.constant(value, dtype=tf.float32), tf.float16) fp32 = tf.cast(fp16, tf.float32) binary = format(int.from_bytes(fp16.numpy().tobytes(), 'big'), '016b') sign = binary[0] exponent = binary[1:6] fraction = binary[6:] return f"FP16: {fp32.numpy():14.14f} (Binary: {sign}|{exponent}|{fraction}, Hex: {fp16.numpy().view('uint16'):04X})" def display_bf16(value): bf16 = tf.cast(tf.constant(value, dtype=tf.float32), tf.bfloat16) bf32 = tf.cast(bf16, tf.float32) binary = format(int.from_bytes(bf16.numpy().tobytes(), 'big'), '016b') sign = binary[0] exponent = binary[1:9] fraction = binary[9:] return f"BF16: {bf32.numpy():14.14f} (Binary: {sign}|{exponent}|{fraction}, Hex: {bf16.numpy().view('uint16'):04X})" values = [0.0001, 0.00000001, 100000.00001] for value in values: print(f"\nOriginal value: {value}") print(display_fp16(value)) print(display_bf16(value))
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3