Das Training und das Schließen großer Modelle beinhalten oft das Konzept der Genauigkeit, und es gibt viele Typen, die ebenfalls in verschiedene Formate auf gleichem Genauigkeitsniveau unterteilt sind. Darüber hinaus gibt es auch die Konzepte von Multi-Präzision und Mixed-Precision in praktischen Anwendungsszenarien.
Gemeinsame Präzision
Gleitkommagenauigkeit: Doppelte Präzision (FP64), Enkelgenauigkeit (FP32, TF32), Halbpräzision (FP16, BF16), 8-Bit-Genauigkeit (FP8), 4-Bit-Genauigkeit (FP4, NF4) Quantifizierungsgenauigkeit: INT8, INT4 (auch INT3/INT5/INT6)
Eine Gleitkommazahl besteht aus drei Teilen: Vorzeichen-, Exponential- und Mantissenbits. Je größer das Exponentialbit, desto größer ist der Zahlenbereich, der dargestellt werden kann. Je größer die Mantissenziffer, desto höher ist die Genauigkeit der Zahl.
Die Tabelle fasst es wie folgt zusammen.
| Format | Symbolbit | Exponentielles Bit | Stelle | Gesamtstellen | | FP64 | 1 | 11 | 52 | 64 | | FP32 | 1 | 8 | 23 | 32 | | TF32 | 1 | 8 | 10 | 19 | | BF16 | 1 | 8 | 7 | 16 | | FP16 | 1 | 5 | 10 | 16 | | FP8 E4M3 | 1 | 4 | 3 | 8 | | FP8 E5M2 | 1 | 5 | 2 | 8 | | FP4 | 1 | 2 | 1 | 4 |
FP32: 32-Bit-Gleitkommazahl, 4 Bytes pro Daten TF32: 19-Bit-Gleitkommazahl, jede Daten sind 2 Bytes FP16: 16-Bit-Gleitkommazahl, 2 Bytes pro Daten BF16: 16-Bit-Gleitkommazahl, jede Daten sind 2 Bytes Int8: 8-Bit-Ganzzahl, jede Datenmenge umfasst 1 Byte Int4: 4-Bit-Ganzzahlen, jede Daten sind 0,5 Byte
Warum so viel Präzision
Wegen Kosten und Genauigkeit. Wir wissen alle, dass hohe Genauigkeit definitiv genauer ist, aber sie bringt auch höhere Rechen- und Speicherkosten mit sich. Eine geringere Präzision verringert die Berechnungsgenauigkeit, kann aber die Recheneffizienz und Leistung verbessern. Verschiedene Präzisionen ermöglichen es dir, in verschiedenen Situationen die am besten geeignete auszuwählen. Doppelte Präzision ist genauer als Einzelpräzisionsausdruck, benötigt aber doppelt so viel Speicherplatz und die Berechnung ist länger.
Warum müssen große Modelle quantifiziert werden?
1. Speicherverbrauch reduzieren Große Modelle verwenden üblicherweise 32-Bit-Gleitkommazahlen (FP32) oder 16-Bit-Gleitkommazahlen (FP16), um Gewichte und Aktivierungswerte darzustellen. Durch Quantisierung können diese hochpräzisen Werte in Darstellungen mit geringerer Genauigkeit (z. B. 8-Bit-Ganzzahlen, INT8) umgewandelt werden, was den Speicherplatz des Modells erheblich verringert. Dies ist wichtig für die Bereitstellung auf ressourcenbegrenzten Geräten wie mobilen Geräten, Embedded-Systemen usw.
2. Beschleunigen Sie die Denkgeschwindigkeit Quantisierte Modelle können auf Hardware effizienter laufen. Viele moderne Hardware (wie GPUs, TPUs, NPUs usw.) verfügt über spezialisierte Optimierungsunterstützung für Low-Precision-Computing, was schnellere Quantisierungsoperationen ermöglicht. Außerdem erfordern niedrigpräzise Berechnungen oft weniger Bitoperationen, was die Rechenkomplexität reduziert und somit die Inferenz beschleunigt.
3. Stromverbrauch reduzieren Das quantisierte Modell reduziert nicht nur den Bedarf an Rechenressourcen, sondern senkt auch den Energieverbrauch. Dies ist besonders wichtig für batteriebetriebene Geräte wie Smartphones, IoT-Geräte usw., bei denen ein geringer Stromverbrauch eine längere Akkulaufzeit bedeutet.
4. Einfach zu installierende Edge-Geräte Viele große Modelle wurden zunächst in der Cloud trainiert und bereitgestellt, aber mit der Entwicklung von Edge Computing erfordern immer mehr Anwendungsszenarien, dass Modelle auf Edge-Geräten bereitgestellt werden. Mit begrenzter Rechenleistung und Speicherressourcen auf Edge-Geräten kann Quantisierung diesen Modellen helfen, auf Edge-Geräten effizienter zu laufen.
5. Reduzierung der Bandbreitenanforderungen Im Prozess verteilter Inferenz oder Modellupdates kann Quantisierung die für den Modelltransfer benötigte Bandbreite reduzieren. Dies ist nützlich für Umgebungen mit begrenzter Netzwerkbandbreite, wie IoT-Geräte in abgelegenen Gebieten.
6. Modellleistung erhalten Obwohl Quantisierung einen gewissen Verlust an Präzision mit sich bringt, kann die ursprüngliche Leistung des Modells weitgehend durch geeignete Quantisierungsmethoden erhalten werden (wie Mixed-Precision-Quantisierung, Post-Training-Quantisierung, quantitative Wahrnehmungstraining usw.). Daher kann die Quantifizierung in praktischen Anwendungen ein gutes Gleichgewicht zwischen Leistung und Effizienz erreichen.
Speicherreferenz
| Art | Jede Milliarde Parameter muss das Gedächtnis einnehmen | | float32 | 4G | | FP16/BF16 | 2G | | int8 | 1G | | int4 | 0,5G |
FP64 (Doppelte Präzision)
64-Bit-Gleitkomma, typischerweise ein doppelpräzises binäres Gleitkomma-Format, definiert von IEEE 754, besitzt:
1-stelliges Symbol 11-stelliger Index 52 Dezimalstellen
Reichweite: ~2,23e-308 ... ~1,80e308 mit voller 15-17 Dezimalgenauigkeit.
Verwendung:
Dieses Format wird für wissenschaftliche Berechnungen verwendet, die eine hohe Präzision erfordern. Es wird typischerweise nicht für Deep-Learning-Berechnungen verwendet. Softwareunterstützung: Repräsentiert den Doppeltyp bei den meisten C/C++-Systemen. Unterstützt in TensorFlow (z. B. tf.float64) / PyTorch (z. B. torch.float64 oder torch.double). Hardware-Unterstützung: Wird typischerweise in x86-CPUs unterstützt. Die meisten GPUs, insbesondere Gaming-GPUs, einschließlich der RTX-Serie, sind in der FP64-Leistung stark eingeschränkt (meist 1/32 der FP32-Leistung statt 1/2). Zu den kürzlich uneingeschränkten FP64-unterstützten GPUs gehören GP100/100/102/104 in Tesla P40/P4 und Quadro GP100, GV100 in Tesla V100/Quadro GV100/Titan V sowie die kürzlich angekündigte GA100 in A100 (interessanterweise hat die neue Ampere-Architektur eine dritte Generation) im Vergleich zu den FP64-fähigen Tensor-Cores Die neue, IEEE-konforme FP64-Verarbeitung ist jetzt enthalten, die 2,5-mal so viel FP64-Leistung wie V100 liefert.
FP32 (Volle Genauigkeit)
Dieses Format ist seit langem ein Arbeitstier für Deep Learning. Ein weiteres IEEE 754-Format, das Gleitkomma-Single-Precision-Format, hat:
1-stelliges Symbol 8-stelliger Index 23 Dezimalstellen Idealerweise sollten sowohl Training als auch Inferenz in FP32 erfolgen, aber FP32 ist doppelt so langsam wie FP16/BF16, daher werden in der Praxis oft gemischte Präzisionsmethoden verwendet, bei denen FP32-Gewichte als exakte "Master-Gewichte" verwendet werden, FP16/BF16-Gewichte für Vorwärts- und Rückwärtsausbreitungsberechnungen zur Verbesserung der Trainingsgeschwindigkeit verwendet werden, und schließlich werden FP32-Sovereign-Gewichte in der Gradienten-Aktualisierungsphase mit FP16/BF16-Gradienten aktualisiert.
Während des Trainings ist das souveräne Gewicht immer FP32. In der Praxis liefern halbpräzise Gewichte oft eine ähnliche Genauigkeit wie FP32 bei der Inferenz – da exakte FP32-Gewichte nur benötigt werden, wenn der Modellgradient aktualisiert wird. Das bedeutet, dass wir bei der Inferenz halbpräzise Gewichte verwenden können, sodass wir mit nur der Hälfte des GPU-Speichers dasselbe Ergebnis erzielen.
Reichweite: ~1,18e–38 ... ~3,40e38 mit einer Genauigkeit von 6–9 signifikanten Dezimalzahlen.
Verwendung:
Die Standardform der neuronalen Netzwerk-Berechnung für lange Zeit. Gewichte, Aktivierungen und andere Werte in neuronalen Netzen sind seit langem standardmäßig auf FP32 beschränkt. Bei vielen wissenschaftlichen Berechnungen, insbesondere iterativen, reicht die Genauigkeit nicht aus, was zu Fehleransammlung führt. Softwareunterstützung: Repräsentiert den Float-Typ bei den meisten C/C++-Systemen. Unterstützt in TensorFlow (z. B. tf.float32) / PyTorch (z. B. torch.float32 oder torch.float). Hardware-Unterstützung: Wird typischerweise in x86-CPUs unterstützt. Wird typischerweise von NVIDIA/AMD-GPU unterstützt.
FP16 (Halbgenauigkeit)
Ähnlich besitzt das IEEE 754-Standardformat, das halbpräzise Gleitkommaformat:
1-stelliges Symbol 5-stelliger Index 10 Dezimalstellen Die FP16-Zahl hat einen deutlich geringeren Zahlenbereich als FP32. Daher ist FP16 einem Überlaufrisiko ausgesetzt (wenn es zur Darstellung sehr großer Zahlen verwendet wird) und Unterlauf (wenn es sehr kleine Zahlen repräsentiert). Wenn du zum Beispiel 10k * 10k machst, sollte das Endergebnis 100M sein, was FP16 nicht darstellen kann, weil die maximale Zahl, die FP16 repräsentieren kann, 64k ist. So erhält man NaN (Not a Number) bei neuronalen Netzberechnungen, weil die Berechnungen in Schichten und Batch-Reihenfolge durchgeführt werden, sodass sobald NaN erscheint, alle vorherigen Berechnungen vernichtet werden. Im Allgemeinen kann dies durch Verlustskalierung gemildert werden, aber dieser Ansatz funktioniert nicht immer.
Reichweite: ~5,96e−8 (6,10e−5) ... 65504, mit einer Genauigkeit von 4 signifikanten Dezimalstellen.
Verwendung:
Deep Learning verwendet tendenziell FP16 statt FP32, da Berechnungen mit geringerer Präzision für neuronale Netzwerke scheinbar keine Rolle spielen. Die zusätzliche Präzision bringt nichts, und gleichzeitig ist es langsamer, erfordert mehr Speicher und verlangsamt die Kommunikation. Kann für das Training verwendet werden, meist mit gemischtem Präzisionstraining (TensorFlow/PyTorch). Kann für die Quantisierung nach dem Training verwendet werden, um die Inferenz zu beschleunigen (TensorFlow Lite). Weitere für die Quantisierung nach dem Training verwendete Formate sind Ganzzahlen INT8 (8-Bit-Ganzzahlen), INT4 (4-Bit) und sogar INT1 (Binärwerte). Softwareunterstützung: Derzeit nicht im C/C++-Standard (aber es gibt einen Vorschlag für kurze Floats). Einige C/C++-Systeme unterstützen __fp16 Typen. Andernfalls kann es mit speziellen Bibliotheken verwendet werden. Unterstützt in TensorFlow (z. B. tf.float16) / PyTorch (z. B. torch.float16 oder torch.half). Hardware-Unterstützung: x86-CPUs werden nicht unterstützt (als einzigartiger Typ). Die Unterstützung bei älteren Gaming-GPUs ist schlecht (32/1 Leistung für FP64, siehe den Beitrag zu GPUs für weitere Details). Derzeit wird es auf modernen GPUs, wie der NVIDIA RTX-Serie, gut unterstützt.
BFLOAT16 (Halbpräzision)
Ein weiteres 16-Bit-Format, das ursprünglich von Google entwickelt wurde, heißt "Brain Floating Point Format" oder kurz "bfloat16". Der Name stammt von Google Brain.
Das ursprüngliche IEEE FP16 wurde ohne Deep-Learning-Anwendungen entwickelt, und sein Dynamikumfang war zu eng. BFLOAT16 löst dieses Problem und bietet denselben Dynamikumfang wie der FP32.
Daher haben BFLOAT16:
1-stelliges Symbol 8-stelliger Index 7 Dezimalstellen
Das bfloat16-Format ist auf IEEE 754 FP32 abgekürzt, was eine schnelle Umwandlung zu und von IEEE 754 FP32 ermöglicht. Bei der Umwandlung in das bfloat16-Format bleiben exponentielle Bits erhalten, während die Mantissenfelder durch Trunkierung reduziert werden können.
Reichweite: ~1,18e-38 ... ~3,40e38 mit 3 signifikanten Dezimalstellen. Verwendung:
Jetzt scheint es FP16 zu ersetzen. Im Gegensatz zu FP16, das oft spezielle Verarbeitung durch Techniken wie Verlustskalierung erfordert, ist BF16 nahezu ein direkter Ersatz für FP32 beim Training und Betrieb tiefer neuronaler Netzwerke. Softwareunterstützung: Nicht im C/C++-Standard. Kann mit speziellen Bibliotheken verwendet werden. Unterstützt in TensorFlow (z. B. tf.bfloat16) / PyTorch (z. B. torch.bfloat16).
TF32
TensorFloat-32 oder TF32 ist der neue Mathematikmodus in NVIDIA A100 GPUs.
Mit denselben 10-Bit-Mantissen wie Halbpräzisions-(FP16)-Mathematik erweist sich der TF32 als ausreichend Spielraum, um die Präzisionsanforderungen von KI-Arbeitslasten zu erfüllen. Und TF32 verwendet denselben 8-Bit-Index wie FP32, sodass es denselben numerischen Bereich unterstützen kann.
Technisch gesehen handelt es sich um ein 19-Bit-Format. Man kann es sich als eine erweiterte Präzisions-BFLOAT16 vorstellen, wie zum Beispiel "BFLOAT19" oder eine verringerte Präzision wie FP32.
TF32 hat also:
1-stelliges Symbol 8-stelliger Index 10 Dezimalstellen Der Vorteil von TF32 ist, dass es dasselbe Format wie FP32 hat. Bei der Berechnung des Innenprodukts mit TF32 wird die Mantisse des Eingabeoperandens von 23 auf 10 Bit gerundet. Die Rundungsoperanden werden im normalen FP32 exakt multipliziert und akkumuliert.
Der TF32 Tensor Core läuft mit FP32-Eingängen und erzeugt Ergebnisse in FP32 ohne Codeänderungen. Nicht-Matrix-Operationen verwenden weiterhin FP32. Dies bietet eine einfache Möglichkeit, FP32-Ein- und Ausgabedaten in Deep-Learning-Frameworks und HPC zu beschleunigen.
Reichweite: ~1,18e-38 ... ~3,40e38 mit einer Genauigkeit von 4 signifikanten Dezimalstellen. Verwendung:
Eines der großartigen Dinge an TF32 ist, dass es nur auf der tiefsten Ebene Compiler-Unterstützung benötigt, also innerhalb des CUDA-Compilers. Der Rest des Codes zeigt FP32 nur mit weniger Präzision, aber mit dem gleichen Dynamikumfang. Die Verwendung von TF32 dient hauptsächlich dazu, die Bibliothek anzurufen, um zu zeigen, ob sie richtig funktioniert. Das Vorhandensein des TF32 ermöglicht schnelle Plug-ins und nutzt die Geschwindigkeit der Tensor-Kerne ohne große Arbeit. Formate wie FP16 und BFLOAT16 erfordern mehr Anpassungen, da sie unterschiedliche Bit-Layouts verwenden. Die Verwendung dieser Formate reduziert jedoch die Speicherbandbreite und ermöglicht eine schnellere Ausführung. Zum Vergleich: Die Spitzenleistung des A100 ist:
FP32 ohne Tensorkerne: 19,5 TFLOPS TF32 Tensorkerne: 156 TFLOPS (daher macht die Verwendung von TF32 statt FP32 das Erhöhen der Geschwindigkeit einfach). FP16/BF16 Tensorkerne: 312 TFLOPS (daher kann ein vernünftiger Wechsel auf FP16/BF16 mehr Geschwindigkeitsgewinne bringen, aber zu höheren Kosten). Softwareunterstützung: Nicht im C/C++-Standard. CUDA 11 unterstützt. Hardware-Unterstützung: GPU: NVIDIA A100 ist das erste Modell, das unterstützt wird
FP8
Eingeführt durch die H100-GPU, ermöglicht sie eine größere Matrixmultiplikation und -faltung, jedoch mit geringerer Präzision.
Die von H8 unterstützten FP100-Datentypen sind tatsächlich zwei verschiedene Datentypen, die für unterschiedliche Teile des Trainings von neuronalen Netzwerken verwendet werden können:
E4M3 – besteht aus 1 symbolischem Bit, 4 Exponentialbits und 3 Dezimalstellen. Es kann bis zu +/-448 und Nan speichern. E5M2 – besteht aus 1 Vorzeichenbit, 5 Exponentialbits und 2 Dezimalstellen. Er kann Werte bis zu +/-57344, +/-inf und nan speichern. Der Nachteil eines zunehmenden Dynamikumfangs ist, dass die gespeicherten Werte weniger genau sind.
Struktur der Gleitkomma-Datentypen. Alle angezeigten Werte (in FP16, BF16, FP8 E4M3 und FP8 E5M2) sind die nächstliegende Darstellung des Wertes 0,3952.
Beide Typen können beim Training eines neuronalen Netzwerks verwendet werden. Im Allgemeinen erfordern Vorwärtsaktivierung und Gewichte eine höhere Präzision, daher ist es am besten, den Datentyp E4M3 beim Vorwärtspass zu verwenden. Bei der Rückpropagation hingegen ist der durch das Netzwerk fließende Gradient im Allgemeinen weniger anfällig für Präzisionsverluste, erfordert aber einen höheren Dynamikbereich. Daher ist es am besten, sie im E5M2-Datenformat zu speichern. Der H100 TensorCore unterstützt jede Kombination dieser Typen als Eingabe, sodass wir jeden Tensor mit seiner bevorzugten Präzision speichern können.
Referenz:
Der Hyperlink-Login ist sichtbar.
Der Hyperlink-Login ist sichtbar. |