Het trainen en redeneren van grote modellen omvat vaak het concept van nauwkeurigheid, en er zijn veel soorten, en ze zijn ook onderverdeeld in verschillende formaten op hetzelfde nauwkeurigheidsniveau. Daarnaast zijn er ook de concepten van multi-precisie en gemengde precisie in praktische situaties.
Algemene precisie
Floating-point nauwkeurigheid: dubbele precisie (FP64), enkele precisie (FP32, TF32), halve precisie (FP16, BF16), 8-bit nauwkeurigheid (FP8), 4-bit nauwkeurigheid (FP4, NF4) Kwantificatienauwkeurigheid: INT8, INT4 (ook INT3/INT5/INT6)
Een floating-point getal bestaat uit drie delen: teken-, exponentiële en mantissabits. Hoe groter het exponentiële bit, hoe groter het bereik van getallen dat kan worden weergegeven. Hoe groter het bidsprinkhanencijfer, hoe nauwkeuriger het getal.
De tabel vat het als volgt samen
| formatteren | Symboolbit | Exponentiële bit | Decimale plaats | Totale cijfers | | 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-bits floating-point getal, 4 bytes per data TF32: 19-bits floating-point getal, elke data is 2 bytes FP16: 16-bits floating-point getal, 2 bytes per data BF16: 16-bits floating-point getal, elke data is 2 bytes Int8: 8-bits geheel getal, elke data is 1 byte Int4: 4-bits gehele getallen, elke data is 0,5 bytes
Waarom zoveel precisie
Vanwege de kosten en nauwkeurigheid. We weten allemaal dat hoge nauwkeurigheid zeker nauwkeuriger is, maar het brengt ook hogere reken- en opslagkosten met zich mee. Lagere precisie vermindert de nauwkeurigheid van berekeningen, maar kan de rekenefficiëntie en prestaties verbeteren. Dus een verscheidenheid aan precisie stelt je in staat om de meest geschikte te kiezen in verschillende situaties. Dubbele precisie is nauwkeuriger dan expressie met één precisie, maar het neemt twee keer zoveel opslag in beslag en duurt meer tijd om te berekenen.
Waarom moeten grote modellen gekwantificeerd worden?
1. Verminder het geheugengebruik Grote modellen gebruiken meestal 32-bits floating-point getallen (FP32) of 16-bits floating-point getallen (FP16) om gewichten en activatiewaarden weer te geven. Door te kwantiseren kunnen deze hoogprecisiewaarden worden omgezet in lagere precisie representaties (bijv. 8-bits gehele getallen, INT8), waardoor de opslagruimte van het model aanzienlijk wordt verminderd. Dit is belangrijk voor implementatie op apparaten met beperkte middelen zoals mobiele apparaten, embedded systemen, enzovoort.
2. Versnel de redeneersnelheid Gekwantiseerde modellen kunnen efficiënter draaien op hardware. Veel moderne hardware (zoals GPU's, TPU's, NPU's, enz.) beschikt over gespecialiseerde optimalisatieondersteuning voor laag-precisie computing, waardoor snellere kwantisatiebewerkingen mogelijk zijn. Bovendien bevatten berekeningen met lage precisie vaak minder bitbewerkingen, wat de rekencomplexiteit vermindert en zo de inferentie versnelt.
3. Verminder het energieverbruik Het gekwantiseerde model vermindert niet alleen de behoefte aan rekenkrachten, maar vermindert ook het energieverbruik. Dit is vooral belangrijk voor batterijvoedende apparaten zoals smartphones, IoT-apparaten, enzovoort, waar een laag stroomverbruik zorgt voor een langere batterijduur.
4. Gemakkelijk te implementeren randapparaten Veel grote modellen werden aanvankelijk in de cloud getraind en geïrtaleerd, maar met de ontwikkeling van edge computing vereisen steeds meer toepassingen dat modellen op edge-apparaten worden ingezet. Met beperkte rekenkracht en opslagmiddelen op edge-apparaten kan kwantisatie deze modellen helpen efficiënter te draaien op edge-apparaten.
5. Verminder de bandbreedtebehoefte In het proces van gedistribueerde inferentie of modelupdates kan kwantisatie de bandbreedte die nodig is voor modeloverdracht verminderen. Dit is nuttig voor omgevingen met beperkte netwerkbandbreedte, zoals IoT-apparaten in afgelegen gebieden.
6. Modelprestaties behouden Hoewel kwantisatie een zekere precisieverlies met zich meebrengt, kan de oorspronkelijke prestaties van het model grotendeels worden behouden door passende kwantisatiemethoden (zoals mixed-precision quantisatie, post-training kwantisatie, kwantitatieve waarnemingstraining, enz.). Daarom kan kwantificering in praktische toepassingen een goede balans vinden tussen prestaties en efficiëntie.
Geheugenreferentie
| type | Elke miljard parameters moet het geheugen beslaan | | float32 | 4G | | FP16/BF16 | 2G | | int8 | 1G | | int4 | 0,5G |
FP64 (Dubbele Precisie)
64-bits floating-point, doorgaans een dubbelprecisie binair floating-point formaat gedefinieerd door IEEE 754, heeft:
1-cijferig symbool 11-cijferige index 52 decimalen
Bereik: ~2,23e-308 ... ~1,80e308 met volledige 15-17 decimale precisie.
Gebruik:
Dit formaat wordt gebruikt voor wetenschappelijke berekeningen die hoge precisie vereisen. Het wordt doorgaans niet gebruikt voor deep learning-berekeningen. Softwareondersteuning: Vertegenwoordigt het dubbele type op de meeste C/C++-systemen. Ondersteund in TensorFlow (bijv. tf.float64) / PyTorch (bijv. torch.float64 of torch.double). Hardware-ondersteuning: Wordt meestal ondersteund in x86-CPU's. De meeste GPU's, vooral gaming-GPU's, waaronder de RTX-serie, zijn sterk beperkt in FP64-prestaties (meestal 1/32 van de FP32-prestaties in plaats van 1/2). Recente onbeperkte FP64-ondersteunde GPU's zijn onder andere GP100/100/102/104 in Tesla P40/P4 en Quadro GP100, GV100 in Tesla V100/Quadro GV100/Titan V, en de recent aangekondigde GA100 in A100 (interessant genoeg heeft de nieuwe Ampere-architectuur een derde generatie) vergeleken met de FP64-compatibele Tensor Cores De nieuwe IEEE-conforme FP64-verwerking is nu inbegrepen, die 2,5 keer de FP64-prestaties van de V100 levert.
FP32 (Volledige Nauwkeurigheid)
Dit format is al lange tijd een werkpaard voor deep learning. Een ander IEEE 754-formaat, enkelvoudige precisie floating-point, heeft:
1-cijferig symbool 8-cijferige index 23 decimalen Idealiter zouden zowel training als inferentie in FP32 moeten worden uitgevoerd, maar FP32 is twee keer zo traag als FP16/BF16, dus worden vaak methoden met gemengde precisie in de praktijk gebruikt, waarbij FP32-gewichten als exacte "mastergewicht" worden gebruikt, FP16/BF16-gewichten worden gebruikt voor vooruit- en achterwaartse propagatieberekeningen om de trainingssnelheid te verbeteren, en tenslotte worden FP32-soevereine gewichten bijgewerkt met FP16/BF16-gradiënten in de gradiëntupdatefase.
Tijdens de training is het soevereine gewicht altijd FP32. In de praktijk leveren halfprecisiegewichten vaak vergelijkbare nauwkeurigheid als FP32 bij inferentie - omdat exacte FP32-gewichten alleen nodig zijn wanneer de modelgradiënt wordt bijgewerkt. Dit betekent dat we half-precisie gewichten kunnen gebruiken bij inferentie, zodat we hetzelfde resultaat kunnen krijgen met slechts de helft van het GPU-geheugen.
Bereik: ~1,18e-38 ... ~3,40e38 met een nauwkeurigheid van 6-9 significante decimalen.
Gebruik:
Het standaardtype neuraal netwerkcomputing voor lange tijd. Gewichten, activaties en andere waarden in neurale netwerken zijn al lang standaard FP32. Voor veel wetenschappelijke berekeningen, vooral iteratieve, is de nauwkeurigheid niet voldoende, wat leidt tot foutopbouw. Softwareondersteuning: Geeft het vlottentype aan op de meeste C/C++-systemen. Ondersteund in TensorFlow (bijv. tf.float32) / PyTorch (bijv. torch.float32 of torch.float). Hardware-ondersteuning: Wordt meestal ondersteund in x86-CPU's. Wordt meestal ondersteund door NVIDIA/AMD GPU.
FP16 (Halve nauwkeurigheid)
Evenzo heeft het IEEE 754-standaardformaat, het half-precision floating-point-formaat:
1-cijferig symbool 5-cijferige index 10 decimalen Het FP16-nummer heeft een veel lager numeriek bereik dan FP32. Daarom loopt FP16 het risico op overloop (wanneer gebruikt om zeer grote getallen weer te geven) en onderloop (wanneer het zeer kleine getallen weergeeft). Als je bijvoorbeeld 10k * 10k doet, zou het eindresultaat 100M moeten zijn, wat FP16 niet kan weergeven omdat het maximale aantal dat FP16 kan vertegenwoordigen 64k is. Dus krijg je NaN (Niet een Getal) in neurale netwerkberekeningen, omdat de berekeningen in gelaagde en batchvolgorde worden uitgevoerd, dus zodra NaN verschijnt, worden alle eerdere berekeningen vernietigd. In het algemeen kan dit worden gemitigeerd door verliesschaal, maar deze aanpak werkt niet altijd.
Bereik: ~5,96e−8 (6,10e−5) ... 65504, met een nauwkeurigheid van 4 significante decimale cijfers.
Gebruik:
Deep learning gebruikt meestal FP16 in plaats van FP32, omdat berekeningen met lagere precisie voor neurale netwerken niet lijken uit te maken. De extra precisie doet niets, en tegelijkertijd is het langzamer, vereist meer geheugen en vertraagt de communicatie. Kan worden gebruikt voor training, meestal met mixed-precision training (TensorFlow/PyTorch). Kan worden gebruikt voor kwantisatie na training om inferentie te versnellen (TensorFlow Lite). Andere formaten die worden gebruikt voor kwantisatie na training zijn onder andere gehele getallen INT8 (8-bits gehele getallen), INT4 (4-bit) en zelfs INT1 (binaire waarden). Softwareondersteuning: Niet momenteel in de C/C++-standaard (maar er is wel een voorstel voor korte float). Sommige C/C++-systemen ondersteunen __fp16 types. Anders kan het worden gebruikt met speciale bibliotheken. Ondersteund in TensorFlow (bijv. tf.float16) / PyTorch (bijv. torch.float16 of torch.half). Hardware-ondersteuning: x86-CPU's worden niet ondersteund (als uniek type). De ondersteuning op oudere gaming-GPU's is slecht (32/1 prestaties voor FP64, zie het bericht over GPU's voor meer details). Het wordt momenteel goed ondersteund op moderne GPU's, zoals de NVIDIA RTX-serie.
BFLOAT16 (Half-Precisie)
Een ander 16-bits formaat dat oorspronkelijk door Google is ontwikkeld, heet "Brain Floating Point Format", of kortweg "bfloat16". De naam komt van Google Brain.
De oorspronkelijke IEEE FP16 was ontworpen zonder deep learning-toepassingen in gedachten, en het dynamisch bereik was te smal. BFLOAT16 lost dit probleem op en biedt hetzelfde dynamisch bereik als de FP32.
Daarom hebben BFLOAT16:
1-cijferig symbool 8-cijferige index 7 decimalen
Het bfloat16-formaat is ingekort tot IEEE 754 FP32, waardoor snelle conversie van en naar IEEE 754 FP32 mogelijk is. Bij het omzetten naar het bfloat16-formaat blijven exponentiële bits behouden, terwijl de mantissenvelden door afkapping kunnen worden verminderd.
Bereik: ~1,18e-38 ... ~3,40e38 met 3 significante decimalen. Gebruik:
Nu lijkt het FP16 te vervangen. In tegenstelling tot FP16, dat vaak speciale verwerking vereist via technieken zoals verliesopschaling, is BF16 bijna een directe vervanging van FP32 bij het trainen en uitvoeren van diepe neurale netwerken. Softwareondersteuning: Niet in de C/C++ standaard. Kan worden gebruikt met speciale bibliotheken. Ondersteund in TensorFlow (bijv. tf.bfloat16) / PyTorch (bijv. torch.bfloat16).
TF32
TensorFloat-32 of TF32 is de nieuwe wiskundemodus in NVIDIA A100 GPU's.
Met dezelfde 10-bit mantissen als half-precision (FP16) wiskunde bewijst de TF32 voldoende headroom te hebben om aan de precisie-eisen van AI-workloads te voldoen. En TF32 gebruikt dezelfde 8-bits index als FP32, dus het kan hetzelfde numerieke bereik ondersteunen.
Technisch gezien is het een 19-bit formaat. Zie het als een uitgebreide precisie-BFLOAT16, zoals "BFLOAT19" of een verminderde precisie zoals FP32.
Dus, TF32 heeft:
1-cijferig symbool 8-cijferige index 10 decimalen Het voordeel van TF32 is dat het hetzelfde format heeft als FP32. Bij het berekenen van het inwendig product met TF32 wordt de mantisse van de invoeroperand afgerond van 23 naar 10 bits. De afrondingsoperanden worden exact vermenigvuldigd en opgestapeld in normale FP32.
De TF32 Tensor Core draait op FP32-invoer en genereert resultaten in FP32 zonder codewijzigingen. Niet-matrixoperaties blijven FP32 gebruiken. Dit biedt een gemakkelijke manier om FP32 input/output-data te versnellen in deep learning-frameworks en HPC.
Bereik: ~1,18e-38 ... ~3,40e38 met een nauwkeurigheid van 4 significante decimalen. Gebruik:
Een van de mooie dingen aan TF32 is dat het alleen compilerondersteuning nodig heeft op het diepste niveau, dus binnen de CUDA-compiler. De rest van de code ziet FP32 gewoon met minder precisie, maar met hetzelfde dynamisch bereik. Het gebruik van TF32 is vooral bedoeld om de bibliotheek aan te roepen om te laten zien of het goed werkt. De aanwezigheid van de TF32 maakt snelle plug-ins mogelijk, waarbij optimaal gebruik wordt gemaakt van de snelheid van de Tensor Cores zonder veel werk. Formaten zoals FP16 en BFLOAT16 vereisen meer aanpassingen omdat ze verschillende bitlay-outs bevatten. Maar het gebruik van deze formaten vermindert de geheugenbandbreedte, waardoor snellere uitvoering mogelijk is. Ter vergelijking: de piekprestaties van de A100 zijn:
FP32 zonder tensorkernen: 19,5 TFLOPS TF32 tensorkernen: 156 TFLOPS (dus TF32 gebruiken in plaats van FP32 maakt het makkelijk om snelheid te verhogen). FP16/BF16 Tensorkernen: 312 TFLOPS (dus een redelijke overstap naar FP16/BF16 kan meer snelheidswinst opleveren, maar tegen hogere kosten). Softwareondersteuning: Niet in de C/C++ standaard. CUDA 11 wordt ondersteund. Hardware-ondersteuning: GPU: NVIDIA A100 is het eerste model dat wordt ondersteund
FP8
Geïntroduceerd door de H100 GPU, maakt het grotere matrixvermenigvuldiging en convolutie mogelijk, maar met een lagere precisie.
De FP100-datatypes die door H8 worden ondersteund, zijn eigenlijk 2 verschillende datatypes die gebruikt kunnen worden voor verschillende onderdelen van neurale netwerktraining:
E4M3 - bestaat uit 1 symbolische bit, 4 exponentiële bits en 3 decimalen. Het kan tot +/-448 en nan opslaan. E5M2 - bestaat uit 1 tekenbit, 5 exponentiële bits en 2 decimalen. Het kan waarden opslaan tot +/-57344, +/-inf en nan. Het nadeel van het toenemende dynamisch bereik is dat de opgeslagen waarden minder nauwkeurig zijn.
Structuur van drijvende-komma datatypes. Alle weergegeven waarden (in FP16, BF16, FP8 E4M3 en FP8 E5M2) zijn de dichtstbijzijnde weergave van de waarde 0,3952.
Beide typen kunnen worden gebruikt tijdens het trainen van een neuraal netwerk. Over het algemeen vereisen voorwaartse activatie en gewichten hogere precisie, dus het is het beste om het E4M3-datatype te gebruiken tijdens de voorwaartse pass. Bij backpropagatie is de gradiënt die door het netwerk stroomt over het algemeen minder gevoelig voor precisieverlies, maar vereist een hoger dynamisch bereik. Daarom is het het beste om ze op te slaan met het E5M2-dataformaat. De H100 TensorCore ondersteunt elke combinatie van deze typen als input, waardoor we elke tensor met de gewenste precisie kunnen opslaan.
Referentie:
De hyperlink-login is zichtbaar.
De hyperlink-login is zichtbaar. |