„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Was ist der Unterschied zwischen FP und BF? Hier eine gute Erklärung für Sie

Was ist der Unterschied zwischen FP und BF? Hier eine gute Erklärung für Sie

Veröffentlicht am 17.08.2024
Durchsuche:184

What is the difference between FPand BF Here a good explanation for you

Gleitkommadarstellung:

FP16 (Half Precision): In FP16 wird eine Gleitkommazahl mit 16 Bit dargestellt. Es besteht aus 1 Vorzeichenbit, 5 Bits für den Exponenten und 10 Bits für den Bruch (Mantisse). Dieses Format bietet eine höhere Präzision für die Darstellung von Bruchwerten innerhalb seines Bereichs.

BF16 (BFloat16): BF16 verwendet ebenfalls 16 Bit, jedoch mit einer anderen Verteilung. Es verfügt über 1 Vorzeichenbit, 8 Bits für den Exponenten und 7 Bits für die Mantisse. Dieses Format opfert eine gewisse Präzision im Bruchteil, um einen größeren Bereich von Exponenten zu berücksichtigen.

Numerischer Bereich:

FP16 hat einen kleineren Bereich, aber eine höhere Präzision innerhalb dieses Bereichs aufgrund seiner 10-Bit-Mantisse.
BF16 hat einen größeren Bereich, aber eine geringere Präzision für Bruchwerte aufgrund seines 8-Bit-Exponenten und seiner 7-Bit-Mantisse.

Beispiele:

Veranschaulichen wir anhand von Beispielen die Unterschiede zwischen FP16 und BF16 anhand von drei Beispielfällen. TensorFlow wird verwendet, um die Tests und den unten geteilten Code zu erstellen:

Originalwert: 0,0001 – Beide Methoden können darstellen
FP16: 0,00010001659393 (Binär: 0|00001|1010001110, Hex: 068E) – 10 Mantissen und 5 Exponenten
BF16: 0.00010013580322 (Binär: 0|01110001|1010010, Hex: 38D2) – 7 Mantisse und 8 Exponenten

Wie Sie sehen können, haben sie unterschiedliche Exponenten und Mantissen und können daher unterschiedlich dargestellt werden. Aber wir können sehen, dass FP16 es genauer und näher dargestellt hat.

Ursprünglicher Wert: 1e-08 (0,00000001)
FP16: 0,00000000000000 (Binär: 0|00000|0000000000, Hex: 0000)
BF16: 0,00000001001172 ( Binär: 0|01100100| 0101100, Hex: 322C)

Das ist ein sehr interessanter Fall. FP16 schlägt fehl und ergibt das Ergebnis 0, aber BF16 kann es mit einer speziellen Formatierung darstellen.

Ursprünglicher Wert: 100000,00001
FP16: inf (Binär: 0|11111|0000000000, Hex: 7C00)
BF16: 99840,00000000000000 (Binär: 0|10001111|1 000011, Hex: 47C3 )

Im obigen Fall schlägt FP16 fehl, da alle Exponentenbits voll werden und nicht ausreichen, um den Wert darzustellen. Allerdings funktioniert BF16

Anwendungsfälle:

FP16 wird häufig für Deep-Learning-Training und Inferenz verwendet, insbesondere für Aufgaben, die eine hohe Präzision bei der Darstellung kleiner Bruchwerte innerhalb eines begrenzten Bereichs erfordern.

BF16 erfreut sich zunehmender Beliebtheit in Hardwarearchitekturen, die für maschinelle Lernaufgaben entwickelt wurden und von einem größeren Bereich darstellbarer Werte profitieren, selbst auf Kosten einer gewissen Präzision im Bruchteil. Dies ist besonders nützlich, wenn es um große Gradienten geht oder wenn die numerische Stabilität über einen weiten Bereich wichtiger ist als die Präzision kleiner Werte.

Zusammenfassung

FP16 bietet eine höhere Präzision für Bruchwerte innerhalb eines kleineren Bereichs und eignet sich daher für Aufgaben, die eine genaue Darstellung kleiner Zahlen erfordern. BF16 hingegen bietet einen größeren Bereich auf Kosten einer gewissen Präzision, was es vorteilhaft für Aufgaben macht, die ein breiteres Wertespektrum umfassen oder bei denen numerische Stabilität über einen weiten Bereich von entscheidender Bedeutung ist. Die Wahl zwischen FP16 und BF16 hängt von den spezifischen Anforderungen der jeweiligen maschinellen Lernaufgabe ab.

Abschließendes Fazit

Aus allen oben genannten Gründen erfordern FP16 und BF16 beim Stable Diffusion XL (SDXL)-Training leicht unterschiedliche Lernraten und ich finde, dass BF16 besser funktioniert.

Der Code, der zum Generieren der obigen Beispiele verwendet wird

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))
Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/furkangozukara/what-is-the-difference-between-fp16-and-bf16-here-a-good-explanation-for-you-gag?1Falls vorhanden Verstoß, wenden Sie sich zum Löschen bitte an [email protected]
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3