Hur vi byggde DeepL:s nästa generations LLM:er med FP8 för träning och inferens

När DeepL driftsatte vår nuvarande NVIDIA DGX SuperPOD med 544 NVIDIA H100 Tensor Core GPU:er fick vi inte bara en stor ökning av beräkningskraften. H100 introducerar också inbyggt stöd för 8-bitars flyttalsdatatyper (FP8) genom en ny generation av Tensor Cores, som gör det möjligt för GPU:n att utföra matrismultiplikationer och andra tensoroperationer med FP8-precision. Genom att beräkna matrismultiplikationer i FP8 kan vi öka genomströmningen när vi tränar och driftsätter våra stor språkmodeller (LLM), eftersom de flesta beräkningar som ingår i moderna LLM sker i form av matrismultiplikationer.

Övergången från 16-bitars till 8-bitars precision hade en stor inverkan på utvecklingen av DeepL:s nästa generations LLM:er. Det gör det möjligt för oss att bygga mycket större Språk-AI-modeller med betydligt fler parametrar som ger avsevärda kvalitetsförbättringar enligt språkexperter, men inom samma latensfönster för produktionsinferens. Det innebär översättningar som överträffar våra tidigare modeller med 1,4 gånger för europeiska språk och 1,7 gånger för mer komplexa språkpar som Engelska och Japanska, men som levererar resultat lika snabbt. Det innebär också att våra modeller kan hantera ett större antal förfrågningar över fler funktioner utan att kompromissa med användarupplevelse.

Med andra ord har FP8-träning och inferens spelat en central roll i skalningen av DeepL:s språk-AI.

I det här inlägget vill vi förklara den resa vi har gjort för att tillämpa FP8 för träning och inferens, dela med oss av några av de verktyg och tekniker som ligger till grund för denna framgång och ge dig en uppfattning om de resultat vi genererar i termer av tränings- och inferensprestanda längs vägen. 

Vad är skillnaden mellan formaten BF16 och FP8?

Den enkla förklaringen till skillnaden mellan BFloat16 (BF16) och FP8 är att den senare använder hälften så många bitar för att uttrycka värden. I praktiken använder BF16 de 16 tillgängliga positionerna i två byte om vardera 8 bitar. FP8 använder bara en byte. 

Antalet tillgängliga bitar avgör precisionen med vilken du kan driftsätta mantissa- och exponentelementen i flyttalsnummer i vetenskaplig notation. BF16 har 1 teckenbit, 8 bitar för exponenten och 7 bitar för mantissan. FP8 har hälften så många bitar att leka med, med 1 teckenbit och 7 bitar fördelade mellan exponenten och mantissan. På grund av detta har den mindre räckvidd och lägre precision än BF16. Det kan representera ett smalare intervall och färre siffror inom det intervallet.

Låt oss till exempel säga att vi vill representera jordens ålder i miljarder år (ungefär 4,543). I BF16 kan vi representera detta exakt som 0100000010010001.  

Vad sägs om att representera det talet i FP8? Det finns faktiskt två FP8-format att välja mellan: E4M3 och E5M2. Bokstäverna och siffrorna här representerar hur bitarna fördelas mellan exponenten (E) och mantissan (M). Ju fler bitar du använder för exponenten, desto större blir det talintervall du kan beskriva, och ju fler bitar du använder för mantissan, desto fler tal kan du beskriva inom det intervallet. 

Oavsett vilket FP8-format du väljer är det inte möjligt att återge 4,543 exakt. Om du väljer E4M3 med dess relativt högre precision kan du komma närmast (4,5). I E5M2 är det närmaste du kan komma 5.

Å andra sidan möjliggör FP8 snabbare beräkningar och kräver betydligt mindre minne jämfört med BF16, vilket kompenserar för bristen på omfång och precision. Detta är oerhört värdefullt för inferens, och med rätt tillvägagångssätt kan det också vara oerhört värdefullt för att påskynda träningen. Det handlar om hur stor räckvidd och precision LLM-träning faktiskt behöver. Behöver du ange jordens ålder exakt? Eller är det tillräckligt nära att komma inom 43 miljoner år? Om du är intresserad av universum som helhet skulle du förmodligen vara nöjd med den andra precisionsnivån. Avrundningsfelet motsvarar trots allt bara cirka 0,3 % av universums ålder.

DeepL:s resa bevisar att FP8 kan leverera det som krävs för högkvalitativ LLM-träning, och detta har öppnat upp nya möjligheter för vad vi tränar våra modeller att göra och hur vi driftsätter dem i praktiken.

Förträning för DeepL LLMs

Resan vi gör med FP8-träning och inferens börjar med förträning av våra LLM:er. Efter förträningen finjusterar vi våra modeller för vissa uppgifter, destillerar stora modeller till mindre modeller, tillämpar förstärkt inlärning och driftsätter en rad parallelliseringsstrategier så att vi kan utnyttja det stora antalet GPU:er som vi har.

Tillämpa FP8-formatet för träning med blandad precision

Vi överförde vår befintliga träningskod från BF16 till FP8 med hjälp av NVIDIA Transformer Engine: ett träningsbibliotek från NVIDIA som accelererar transformatormodeller och inkluderar stöd för FP8. Transformer Engine tillhandahåller viktiga komponenter som underlättar träning med blandad precision, som leder konverteringen mellan FP8- och BF16-format på ett smidigt sätt och hanterar skalningsfaktorer.

Vi använder Transformer Engine:s standardinställningar, enligt rekommendation från NVIDIA, med E4M3 i framåtpasset för att träna och sedan E5M2 i bakåtpasset. Detta innebär i praktiken att vi använder formatet med högre precision för att förutsäga sannolikhetsfördelningen för nästa token, och sedan formatet med lägre precision, men ett högre intervall, för att beräkna de gradienter som behövs för att uppdatera modellen, när precisionen är mindre viktig. Vi använder vart och ett av de två formaten för den uppgift som det passar bäst för.

I diagrammet nedan har vi plottat alla siffror som kan representeras med formatet E4M3. Som du ser är dessa siffror koncentrerade kring noll, med ett maximivärde på mindre än 500. Faktum är att antalet representerbara värden för FP8-format kan skrivas ut i en mycket kort tabell. Tricket för att få detta format att fungera för träning är att vara medveten om fördelningen av dessa värden och arbeta inom ramen för den. 

Detta innebär att ytterligare skalningsfaktorer lagras tillsammans med FP8-viktensor för att övervinna det begränsade intervallet och förhindra överflöde och underflöde. När du utför beräkningar med dina lågprecisions-tensorer måste du också ta hänsyn till skalningsfaktorerna. När du multiplicerar två tensorer använder du till exempel formeln: (A_fp8 * A_scale) x (B_fp8 * B_scale), där A_fp8 och B_fp8 är 8-bitars tensorer och skalorna är 32-bitars skalärer. Det finns specifikt hårdvarustöd till support för dessa operationer.

FP8 vs BF16 för prestanda när man tränar

När vi talar om träningsprestanda menar vi hur snabbt en modell kan tränas med den datorkraft som finns tillgänglig. För att jämföra träningsprestanda mellan FP8 och BF16 tittar vi på modellens FLOPS-utnyttjande (MFU), vilket är antalet flyttalsoperationer per sekund (FLOPS) som modellen utför, uttryckt i procent av de FLOPS som är tekniskt möjliga med den hårdvara du har tillgänglig.

För vår jämförelse använde vi antalet FLOPS som är möjliga med BF16-formatet som gemensam nämnare, trots att det tekniskt sett blir möjligt att uppnå fler FLOPS när man går över till FP8. Detta gjorde det möjligt för oss att mäta den ökade vinsten i användning av tillgänglig processorkraft som blir möjlig när man går från BF16 till FP8.

Som framgår av diagrammet nedan ökade effektiviteten med vilken vår modellträning använder den tillgängliga datorkraften från 44,6 % MFU till 67 % MFU med FP8, vilket effektivt påskyndade vår modellträning med 50 %.

Det är en imponerande prestandaförbättring i sig. För att uppnå detta har vi samarbetat med NVIDIA för att optimera vår användning av Transformer Engine-funktionerna. Baserat på en annan träningsuppställning lyckades vi öka träningsprestandan stegvis med 25 % under loppet av 15 månader, vilket tog oss upp till 80 % MFU.

FP8 vs BF16 för LLM-träningskvalitet

FP8:s förbättringar i termer av träningsprestanda är därför verkligen mycket imponerande. Det vi verkligen bryr oss om på DeepL är dock utbildningskvaliteten. Hur skulle detta jämföras med att träna med BF16-precision?

För att kontrollera kvaliteten som FP8 levererar testade vi att träna en av våra modeller i båda formaten. Detta gjorde det möjligt för oss att jämföra förlusterna från att träna och nedströms kvalitet. 

Vi tränade en 1,5B-modell på tre biljoner tokens och jämförde sedan kvaliteten på FP8-träningen med BF16. Den viktigaste måttstocken här var träningsförlust, vilket avser modellens förmåga att förutsäga nästa token.

Som du kan se i diagrammet nedan kunde vi upptäcka en liten överlägsenhet för BF16 jämfört med FP8, vilket framgår av att vår FP8-linje ligger strax ovanför den för BF16. Denna skillnad överskuggas dock av de mycket större fluktuationerna i träningsförlusten från ett steg till nästa som uppstår för båda formaten, och i båda fallen ser vi samma påtagliga förbättring när det gäller att minimera träningsförlusten över tid.

FP8 vs BF16 nedströms träningskvalitet

Vi gick sedan vidare till att testa kvaliteten som träning i FP8 jämfört med BF16 levererade i en praktisk, nedströmsapplikation.

I det här fallet testade vi hur modellen fungerade när den arbetade med engelska och tyska. Vi jämförde valideringsperplexitet, som kvantifierar osäkerheten som en modell upplever när den förutsäger nästa token i en sekvens. Återigen är förväntningen att förvirringen minskar med tiden. I detta praktiska scenario fann vi faktiskt ingen försämring av kvaliteten när man tränar med FP8 jämfört med BF16.

Nettoresultatet av övergången från BF16 till FP8 är att vi kan träna våra modeller snabbare, med minskade krav på minne, och uppnå samma träningskvalitet, med endast minimal försämring i termer av träningsförlust och jämförbar valideringsperplexitet. Detta innebär i praktiken att DeepL kan bygga mer sofistikerade modeller och hantera mer komplexa uppgifter genom att maximera utnyttjandet av processorkraften. Det breddar avsevärt omfattningen av vad vi kan göra med LLM-träning.

Från FP8-träning till inferens

Nästa steg i resan innebär att förbereda LLM:er för produktionsinferens. Här sköts det tunga arbetet med support av NVIDIA TensorRT-LLM, som är NVIDIAs lösning för skalbar LLM-inferens och som stöder FP8. Den hämtar vikterna från din modell från träningen och bygger en motor för att optimera modellens funktioner så att de blir så beräkningseffektiva som möjligt, med hjälp av optimeringstekniker som kärnfusion, optimerad C++/CUDA-kod, KV-caching och kontinuerlig batchning under körning. 

Fördelarna med FP8 för inferens

Inferens för LLM innebär alltid en interaktion mellan genomströmning (antalet token som kan bearbetas inom en viss tidsram) och latens. Det säger sig självt att för att kunna erbjuda bästa möjliga kundupplevelse måste man kontrollera latensen. Genomströmningen är dock också mycket viktig för DeepL, eftersom den avgör hur många förfrågningar vi kan hantera vid en given tidpunkt och därmed omfattningen av vad vår modell kan göra i praktiken.

Det är oundvikligt att latensen tenderar att öka i takt med att genomströmningen ökar. Att samla flera förfrågningar möjliggör högre genomströmning, men på bekostnad av ökad latens för varje individ förfrågan. Detta kan påverka kundupplevelsen. Emellertid ändrar inferensprestandan hos FP8 jämfört med BF16 denna balansgång avsevärt till vår fördel.

Som diagrammet nedan visar kan FP8 för de flesta batchstorlekar hantera dubbelt så hög genomströmning med samma latens som BF16. Om vi ställer in en specifik latensbudget som motsvarar den optimala upplevelsen för våra användare, kan vi se detta i praktiken. I praktiken har FP8 effektivt fördubblat den effektiva kapaciteten hos våra LLM:er i termer av genomströmning. 

Med andra ord har resan från BF16 till FP8 inte bara gjort det möjligt för oss att bygga mer kraftfulla och sofistikerade LLM:er för DeepL. Det säkerställer också att vi kan tillämpa dessa LLM effektivt, för att leverera optimala kundupplevelser och skala upp effekten av vår Språk-AI i praktiken. Vi får snabbare träning av större modeller, som sedan kan fungera inom samma latensparametrar, samtidigt som de hanterar dubbelt så många förfrågningar.

Vad händer nu? Vi har nyligen driftsatt den nya NVIDIA DGX SuperPOD med NVIDIA DGX GB200-system, vilket ger ytterligare en nästan exponentiell ökning av beräkningskraften. Det som är riktigt intressant för oss är att denna maskin kommer att introducera en ny generation av Tensor Cores som kan fungera som till support för FP4-tensoroperationer som matrismultiplikationer. Det är då vår resa börjar igen. Det har varit spännande att se vad vi kan göra med en enda byte när det gäller att träna och inferens. Håll utkik här för att se vad som är möjligt med en halv byte.


Om författarna

Markus Schnös, Staff Research HPC Engineer

Markus Schnös är forskningsingenjör inom HPC på DeepL, där han fokuserar på skalning av att träna LLM och inferens. Han har ett särskilt intresse för distribuerad träning och lågprecisionsberäkningar med flyttal.

www.linkedin.com/in/markus-schnoes-349300185

https://github.com/Marks101

Fabian Joswig, Staff Research HPC Engineer

Fabian Joswig är forskningsingenjör på DeepL och har en bakgrund inom maskininlärning, högpresterande databehandling och teoretisk partikelfysik. Han fokuserar på att skala upp AI-modeller och infrastruktur för världens mest exakta översättningsverktyg.

https://www.linkedin.com/in/fabianjoswig/

https://github.com/fjosw

Dela