Mažesnė delsa ir didesnis pralaidumas naudojant kelių mazgų „DeepSeek“ diegimą

Kelių GPU diegimas vienu metu padidina MoE modelio našumą greičio ir mastelio srityse.

AutoriaiPerplexity Research

Daugelyje sistemų delsa ir pralaidumas dažnai yra tarpusavyje konfliktuojantys tikslai, kuriuos pasiekiant projektuojant ir diegiant tenka daryti kompromisus. Pavyzdžiui, tankiuose dideliuose kalbos modeliuose paketo dydžio didinimas gali pagerinti pralaidumą, tačiau kartu padidina delsą; didinant tenzoriaus paralelizmą vienoje mašinoje galima sumažinti delsą, bet sumažėja replikų skaičius, o tai lemia mažesnį pralaidumą.

Ekspertų mišinio (angl. Mixture of Experts, MoE) modeliai, tokie kaip „DeepSeek-V3/R1“, neseniai pademonstravo puikias modelio galimybes ir eksploatacinį efektyvumą. Pavyzdžiui, „DeepSeek-V3/R1“ modelis iš viso turi 671 mlrd. parametrų, tačiau kiekvienas žetonas inferencijos metu naudoja tik 37 mlrd. parametrų. Ši modelio architektūra inferencijos sistemoms kelia tiek iššūkių, tiek galimybių.

Šis straipsnis parodo, kad, priešingai nei įprastose sistemose, „MoE“ modeliai, tokie kaip „DeepSeek-V3/R1“, daugelyje scenarijų vienu metu gali pasiekti didesnį pralaidumą ir mažesnę delsą, kai kelių mazgų diegimuose naudojama daugiau GPU.

Diegimo architektūros

Vieno mazgo diegimas per NVLink, kurio metu dėmesys ir ekspertų skaičiavimai paskirstomi tarp GPU.
Kelių mazgų diegimas per InfiniBand, kai GPU grupės sujungiamos mazgų viduje ir tarp mazgų.

Dėl didelio modelio turimų mažų ekspertų skaičiaus diegimai turi būti paskirstyti keliuose įrenginiuose. Nagrinėjome tiek vieno mazgo diegimus viename mazge su 8xH200 GPU, tiek kelių mazgų diegimus su 8xH100 GPU.

Abi diegimo architektūros išnaudoja duomenų paralelizmą, kurį orkestruoja mūsų vidinis užklausų planuoklis. Duomenų paralelizmo diegimas apima kelių inferencijos variklio egzempliorių paleidimą, kurių kiekvienas veikia nepriklausomai, kad aptarnautų ir palaikytų užklausas. Užklausas planuoklis, kuris su varikliu sąveikauja per GRPC, yra atsakingas už tai, kad užklausos būtų paskirstytos kuo tolygiau, kartu palengvinant KV pakartotinį naudojimą ir siunčiant užklausas su dalinai sutampančiu priešdėliu serveriams, kuriuose yra talpykla. Variklio egzemplioriai neapima kelių mazgų. Jie gali pasirinktinai naudoti tenzoriaus paralelizmą dėmesiui paskirstyti tarp kelių įrenginių. Egzemplioriai yra sujungti per NVLink vieno mazgo atveju arba InfiniBand kelių mazgų atveju, paskirstant ir surenkant ekspertus.

Vieno mazgo diegimo konfigūracija užtikrina pranašesnę delsą esant mažiems paketų dydžiams; tačiau esant didesnėms apkrovoms našumas sparčiai prastėja.

Kad paleistume aptarnavimo variklį, vienam mazgui, talpinančiam kelis variklio egzempliorius, paleidžiame vieną podą. „PyTorch“ yra atsakinga už paskirstytojo ryšio nustatymą ir NVSHMEM inicijavimo derinimą. Ryšiams pasikliaujame pasirinktiniais CUDA branduoliais, aprašytais ankstesniame tinklaraščio įraše. Abiejų diegimų įgyvendinimas yra praktiškai identiškas, o modelis parenka tinkamus naudoti branduolius pagal struktūrą, įgyvendinančią ekspertų paralelizmą.

Lygiagretinimo technikos

Prieš pasineriant į mūsų našumo palyginimus, būtina suprasti pagrindines paralelizavimo strategijas, kurios įgalina diegti didžiulius „MoE“ modelius, tokius kaip „DeepSeek-V3/R1“.

Tenzoriaus paralelizmas

LLM inferencijoje tenzoriaus paralelizmas (TP) paprastai naudojamas atminties naudojimui ir skaičiavimams vienam GPU sumažinti, taip sumažinant delsą. Paprastai galime skaidyti tiesines proskynos dėmesio ir MLP sluoksniuose išilgai eilučių arba stulpelių matmenų, o dėmesio operacijas – išilgai dėmesio galvutės matmens.

Naudojant TP, „Llama-3“ architektūra neturi dubliuotų skaičiavimų Linear proskyrai ir dėmesio operacijoms tarp GPU, o tai yra idealus skaidymo metodas. Tačiau „DeepSeek-V3/R1“ modeliuose TP to pasiekti negali.

„DeepSeek-V3/R1“ modeliai naudoja daugiaskleidžiamo dėmesio (angl. Multi-Latent Attention, MLA) mechanizmą. MLA sluoksnis pirmiausia naudoja Linear proskyną kv_a_proj paslėptajam vektoriui apskaičiuoti, o tada naudoja kitą Linear proskyną kv_b_proj, kad paverstų jį į kiekvienos dėmesio galvutės erdvę. Kadangi visos dėmesio galvutės dalijasi tuo pačiu paslėptuoju vektoriumi, TP negali padalinti paslėptojo vektoriaus, todėl visi TP rangai turi replikuoti kv_a_proj ir kv_b_proj parametrus bei skaičiavimus. Panašiai, kadangi MLA saugo paslėptąjį vektorių KV talpykloje, kiekvienas TP rangas saugo identišką KV talpyklos kopiją.

Nepaisant tam tikro dubliavimo MLA, tenzoriaus paralelizmas vis tiek užtikrina dalinį skaičiavimų poreikių sumažinimą, todėl jis yra vertingas scenarijuose, kuriuose reikalaujama didelio išvesties greičio.

Ekspertų paralelizmas

„DeepSeek-V3/R1“ modeliai pakeičia MLP sluoksnius „MoE“ sluoksniais. „MoE“ sluoksnis turi 256 nukreipiamus ekspertus ir vieną bendrą ekspertą. Kiekvienas žetonas skaičiavimams nukreipiamas į 8 skirtingus nukreipiamus ekspertus, o rezultatai sumuojami su svoriais. Kiekvienas žetonas taip pat atlieka skaičiavimus bendrajame eksperte, o rezultatas pridedamas prie nukreipiamų ekspertų rezultato.

Ekspertų paralelizmas (EP) tarnauja kaip įprastas „MoE“ sluoksnių skaidymo metodas, kai kiekvienas GPU valdo 256 / EP nukreipiamus ekspertus ir palaiko bendro eksperto kopiją. Palyginti su TP, EP pranašumas yra tas, kad jis gali paskirstyti skaičiavimus didesniam skaičiui GPU, sumažindamas skaičiavimus ir atminties naudojimą vienam GPU.

Prieš atliekant ekspertų skaičiavimus, visi GPU turi atlikti „AllToAll“ ryšį, kad nukreiptų žetonus į GPU, kuriuose yra atitinkami ekspertai; po ekspertų skaičiavimų reikalingas dar vienas „AllToAll“ ryšys skaičiavimo rezultatams iš įvairių GPU surinkti ir svorinei sumai atlikti. Naudodami NVSHMEM, įdiegėme optimizuotą šių dviejų „AllToAll“ ryšio branduolių – „Dispatch“ ir „Combine“ – versiją. Ankstesniame tinklaraščio įraše išsamiai aprašėme įgyvendinimą, o mūsų branduoliai yra atvirojo kodo „GitHub“ platformoje.

Duomenų paralelizmas

Naudodami EP, „MoE“ skaičiavimus galime paskirstyti tarp 128 ar net daugiau GPU. Tačiau MLA skaičiavimų negalima padalinti naudojant EP. Šiuo metu galime įdiegtas duomenų paralelizmą (DP). Kiekviena DP grupė turi pilną MLA sluoksnio kopiją. Kiekviena DP grupė priima skirtingas įvestis ir savarankiškai atlieka MLA sluoksnio skaičiavimus.

MLA sluoksnio DP ir TP gali būti derinami, o viena DP grupė padalijama į kelis TP rangus. „MoE“ sluoksnio EP galima derinti su MLA sluoksnio DP/TP. EP = DP * TP. Pavyzdžiui, 16-oje mašinų EP128 DP32 TP4 reiškia nukreipiamų ekspertų paskirstymą tarp 128 GPU, kai kas 4 GPU sudaro DP grupę, iš viso išdėstant 32 nepriklausomas DP grupes.

Vieno mazgo ir kelių mazgų palyginimas

„DeepSeek“ 671 mlrd. parametrų viršija vienos 8-GPU H100 mašinos atminties talpą (80 GB * 8), tačiau viena 8-GPU H200 mašina gali visiškai talpinti visą modelį (141 GB * 8). Naudojant EP8 DP8 TP1 konfigūraciją, modelis vienam GPU naudoja apie 100 GB atminties, o KV talpyklai ir kitiems tarpiniams rezultatams palieka maždaug 40 GB. Vienas žetonas užima 70 272 baitus KV talpyklos. Darant prielaidą, kad kiekviena užklausa turi 5 000 žetonų, kiekvienas GPU gali sutalpinti maždaug 100 užklausų.

Norėjome suprasti našumo skirtumus tarp vieno mazgo ir kelių mazgų diegimų esant skirtingoms konfigūracijoms. Vieno mazgo diegimui naudojome vieną H200 mašiną, o kelių mazgų diegimams – iki 16 H100 mašinų. Kiekvienai diegimo aplinkai naudojome TP 1, 2, 4, 8 derinius ir 1, 2, 4, 8, 16, 32, 64, 128 paketo dydžius vienam GPU. Padarėme prielaidą, kad kiekvienos užklausos KV talpyklos ilgis yra 5 000 žetonų. Taip pat padarėme prielaidą, kad kelių žetonų prognozavimas (MTP) nuspėja 1 papildomą žetoną (t. y. kiekvienos užklausos užklausos ilgis yra 2), ir konservatyviai numatėme 60 % priėmimo rodiklį. Žemiau esančiame paveikslėlyje parodytas pralaidumas ir išvesties greitis skirtingoms konfigūracijoms.

Latencijos ir pralaidumo Pareto frontai skirtingoms ekspertų lygiagrečiojo skaičiavimo konfigūracijoms.

Horizontalioji ašis rodo išvesties greitį vienai užklausai žetonais per sekundę (žeton./s). Vertikalioji ašis naudoja logaritminę skalę pralaidumui vienai mašinei žeton./s parodyti.skalę pralaidumui vienai mašinei žeton./s parodyti. Pareto ribą kiekvienai EP konfigūracijai pažymėjome skirtingų spalvų linijomis.

Scenarijuose, kur keliami itin dideli išvesties greičio reikalavimai, naudojant vieno mazgo EP8 DP1 TP8 su 1 paketo dydžiu galima pasiekti didesnį nei 100 žeton./s išvesties greitį, tačiau pralaidumas yra nepaprastai mažas, prilygstantis išvesties greičiui. Šiame scenarijuje visas paketas turi tik 2 žetonus, kurie gali būti nukreipti į daugiausiai 2*8=16 ekspertų, aktyvuojant iš viso daugiausiai 57 mlrd. parametrų.

Išvesties greičio diapazone nuo 80 iki 40 žeton./s, didėjant pralaidumui, išvesties greitis pastebimai mažėja. Priešingai, EP128 pralaidumas esant tokiam pat išvesties greičiui yra apie 5 kartus didesnis nei vieno mazgo diegimo.

Šį reiškinį galima paaiškinti išnagrinėjus vieno mazgo diegimų elgseną: paketo dydžio didinimas tiesiogiai koreliuoja su aktyvuotų ekspertų skaičiaus didėjimu. Kai paketo dydis yra 1, vidutinis aktyvuotų ekspertų skaičius vienam GPU yra 2 * 8 / 8 = 2. Kai paketas pakankamai didelis, aktyvuojami visi ekspertai, vadinasi, kiekvienas GPU aktyvuoja 256 / 8 = 32 ekspertus. Didesnis aktyvuotų ekspertų skaičius reiškia, kad GPU turi nuskaityti daugiau parametrų iš atminties, o tai smarkiai padidina atminties pralaidumo apkrovą. Kadangi didelių kalbos modelių dekodavimo fazėje jau kyla kliūčių dėl atminties pralaidumo, o ne skaičiavimo našumo, paketo dydžio didinimas vieno mazgo diegime pastebimai sumažina išvesties greitį.

Keturių kelių mazgų diegimo konfigūracijų (EP16, EP32, EP64 ir EP128) palyginimas atskleidžia, kad didesnės EP reikšmės perkelia Pareto ribą link vienalaikaus pralaidumo ir išvesties greičio pagerėjimo.

Didesnio EP skaičiaus naudojimas reiškia, kad kiekvienam GPU priskiriama mažiau ekspertų. Pavyzdžiui, EP128 reiškia, kad kiekvienas GPU atsakingas už 256 / 128 = 2 ekspertus, todėl atminties pralaidumo apkrova pastebimai sumažėja. Kitaip tariant, naudodami didesnį EP skaičių, efektyviai gauname daugiau atminties pralaidumo. Kai paketo dydis vienam GPU yra mažesnis nei 64, paketo dydžio didinimas neturi didelės įtakos ekspertų skaičiavimo greičiui, nes įvesčių skaičiaus didinimas reikšmingai nepadidina atminties pralaidumo apkrovos. Todėl pastebime, kad naudojant EP128 paketo dydžio didinimas taip smarkiai neveikia išvesties greičio.

Įdomu tai, kad esant didesniems paketų dydžiams (64 užklausos vienam GPU), pastebėjome naują reiškinį: vieno mazgo diegimo pralaidumas yra šiek tiek didesnis nei kelių mazgų diegimo. Viena iš priežasčių yra ta, kad mazgo vidinis NVLink turi didesnį pralaidumą nei tarptazginis InfiniBand. Kita dalis siejasi su mūsų diegimo apribojimais. Šį reiškinį išsamiau išanalizuosime vėliau.

Dėl atminties talpos apribojimų EP8 DP8 TP1 konfigūracija negali pasiekti 128 paketo dydžio vienam GPU, todėl kelių mazgų diegimas vis tiek yra geresnis pasirinkimas scenarijuose, kur siekiama didesnio pralaidumo.

Skaičiavimų ir ryšio persidengimas

Kaip trumpai pristatyta aukščiau kalbant apie ekspertų paralelizmą, „MoE“ sluoksnio ryšio metu GPU būna nenaudojami. Kad sumažintume švaistymą ir delsą, turime rasti duomenims nepriklausomų skaičiavimo užduočių, kurios užpildytų šį prastovos laiką.

Skaičiavimo ir ryšio tvarkaraščiai be persidengimo, su siuntimo persidengimu ir penkių etapų konvejeriu.

Viršutinėje aukščiau pateikto paveikslėlio dalyje parodyta vieno sluoksnio skaičiavimų eiga. „MoE“ skaičiavimai priklauso nuo „Dispatch“, o kito sluoksnio skaičiavimai priklauso nuo „Combine“ rezultato.

Bendrą ekspertą talpiname kiekviename GPU. Tokiu būdu bendro eksperto skaičiavimams nereikia „AllToAll“ ryšio. Todėl bendro eksperto skaičiavimus galime atlikti iš karto po „Dispatch Send“, o tada palaukti, kol bus baigtas „Dispatch Recv“. Šią persidengimo schemą vadiname „Dispatch Overlap“.

„Dispatch Overlap“ siūlo nesudėtingą įgyvendinimą ir plačiai pritaikomumą. Ši technika paslepia bendro eksperto skaičiavimo laiką visuose EP dydžiuose ir paketų dydžiuose.

Siekdami dar labiau padidinti skaičiavimų ir ryšio persidengimą, panaudojome „DeepSeek“ techninėje ataskaitoje minėtus mikro-paketus, kad nutrauktume duomenų priklausomybę. Kaip parodyta apatinėje paveikslėlio dalyje, vieno „Transformer“ sluoksnio skaičiavimus padalijome į 5 etapus:

1 etapas: InputNorm, QKVProj, AppendKV, BMM

2 etapas: BMM, Attn, OProj, PostNorm, Gate

3 etapas: Dispatch Send, bendras ekspertas

4 etapas: Dispatch Recv, MoE, Combine Send

5 etapas: Combine Recv

Pirmieji 3 tankūs „Transformer“ sluoksniai naudoja visą paketą. Likusiuose 58 „MoE Transformer“ sluoksniuose paketą tolygiai padalijame į du mikro-paketus. Abu mikro-paketai vykdomi pakaitomis, pasislinkę 3 etapais. Kadangi tarp šių dviejų mikro-paketų nėra duomenų priklausomybės, po „Dispatch Send“ ir po „Combine Send“ galime pereiti prie kito mikro-paketo skaičiavimų.

Delsos struktūra

Toliau eksperimento metu palyginame persidengimo poveikį, taip pat palyginame vieno mazgo diegimo EP8 ir kelių mazgų diegimo EP128 našumo skirtumus. Kad būtų lengviau palyginti, tolesniam eksperimentui naudojome H100 GPU. Naudojome TP1, 128 paketo dydį vienam GPU, 2 užklausos ilgį vienai užklausai ir 5000 KV talpyklos ilgį.

Sluoksnio delsos pagal branduolį lyginamose ekspertų lygiagrečiojo skaičiavimo ir persidengimo konfigūracijose.

Aukščiau pateiktame paveikslėlyje rodomas bendras laikas, sunaudotas vienam „MoE Transformer“ sluoksniui, ir skirtingų tipų branduolių delsos dalis. Išskyrus „Dispatch“, „Combine“ ir „GroupGEMM“, kitų branduolių vykdymo laikas EP8, EP128 „NoOverlap“ ir EP128 „DispatchOverlap“ serijose turėtų būti vienodas, nes paketo dydis yra toks pat.

Persidengimas

Pirmiausia palyginkime trijų persidengimo metodų poveikį. „NoOverlap“ iš viso užtruko 2667 µs, „DispatchOverlap“ – 2651 µs, sutaupant 16 µs arba tik 0,6 %. „MicroBatch“ parodė labai didelį pagerėjimą – užtruko 1896 µs, o tai yra 29 % pagreitėjimas. Tiek „Dispatch“, tiek „Combine“ laikas žymiai sutrumpėjo. „Dispatch“ sumažėjo nuo 593 µs iki 367 µs, o „Combine“ – nuo 1012 µs iki 237 µs.

Atkreipkite dėmesį, kad skaičiavimo branduoliams 128 dydžio paketo padalijimas į du 64 dydžio paketus padidina bendrą vykdymo laiką. Todėl, nors ryšiui sunaudotas laikas sumažėjo 1001 µs, bendras laikas sumažėjo tik 771 µs. Priežastį paaiškinsime naudodami „Roofline“ modelį kitame skyriuje.

Dėl šios priežasties mikro-paketavimas ne siempre pagerina našumą.

Išvesties spartos ir vienam mazgui tenkančio pralaidumo pokyčiai naudojant mikropartijavimą, vaizduojami pagal partiją vienam GPU.

Paveikslėlyje aukščiau parodytas „Microbatch“ našumo pagerėjimas, palyginti su „DispatchOverlap“, esant 4–128 paketų dydžiams. Kai paketo dydis mažesnis nei 32, „Microbatch“ sumažina našumą 5–40 %. Kai paketo dydis yra didesnis arba lygus 32, „Microbatch“ gali pagerinti našumą 10–35 %.

EP8 ir EP128 palyginimas

Grįžkime prie ankstesnio paveikslėlio ir palyginkime EP8 ir EP128 „Microbatch“. EP8 iš viso užtruko 1802 µs – šiek tiek mažiau nei EP128 užtrukti 1896 µs. Be aukščiau minėto „Microbatch“ padidinto branduolio vykdymo laiko, pagrindiniai skirtumai pasireiškia „GroupGEMM“, naudojamame „MoE“ skaičiavimams, ir dviejuose ryšio branduoliuose – „Dispatch“ bei „Combine“.

EP8 „GroupGEMM“ užtruko 555 µs, o EP128 „GroupGEMM“ – 270 µs, sumažėdamas per pusę. Tai yra pagrindinis kelių mazgų diegimo privalumas.

Deja, ryšiui sunaudotas laikas padidėjo 213 µs, o tai smarkiai atsveria „GroupGEMM“ privalumą. Atskiriems mūsų ryšio branduolių našumo testams paaiškėjo, kad jie gali pasiekti tik pusę „Infiniband“ pralaidumo. Tęsime savo ryšio branduolių optimizavimą.

Kitas branduolys, kuris pastebimai atsilieka, yra GEMM. „Microbatch“ padidino GEMM 95 µs. Išsamiau GEMM išanalizuosime toliau pateiktame „Roofline“ skyriuje. Manome, kad dabartinis GEMM įgyvendinimas dar nepasiekė optimalaus našumo.

„Roofline“

„Roofline“ modelis yra puikus įrankis branduolio našumui analizuoti. Jo horizontalioji ašis yra aritmetinis intensyvumas – slankiojo kablelio operacijų (FLOP) ir atminties I/O baitų santykis. Horizontaliosios ašies reikšmę galima tiesiogiai apskaičiuoti iš branduolio semantikos. Vertikalioji ašis atspindi pasiektą našumą, apskaičiuotą padalijant FLOP iš bazinio testavimo delsos.

Teorinę viršutinę branduolio našumo ribą tiesiogiai lemia GPU specifikacijos. H100 FP8 didžiausias našumas yra 1979 TFLOP/s, o „Roofline“ modelyje jis pavaizduotas kaip horizontali linija. H100 atminties pralaidumas yra 3,35 TB/s, pavaizduotas kaip per pradžią praeinančios linijos nuolydis. Šios dvi linijos nustato atitinkamai skaičiavimų ribojamų ir atminties ribojamų branduolių našumo ribas.

Toliau aptariame „GroupGEMM“ ir GEMM branduolių našumą.

„GroupGEMM“

„MoE“ esantis „GroupGEMM“ branduolys atlieka šį skaičiavimą: iš viso yra g grupių, i-toji grupė turi m_i žetonų, atliekant [m_i, k] x [k, n] -> [m_i, n] matricos daugybą. Atlikdami našumo testavimą darome prielaidą, kad žetonų skaičius kiekvienoje grupėje yra vienodas, žymimas kaip m_i = m. Tada „GroupGEMM“ FLOP skaičius yra 2 * g * m * k * n, o atminties I/O baitai yra g * (m * k + n * k + m * n).

„DeepSeek-V3/R1“ modelyje yra 256 ekspertai, ir kiekvienas žetonas skaičiavimams nukreipiamas į 8 ekspertus. Darant prielaidą, kad paketo dydis yra 128, užklausos ilgis – 2, naudojant EP128 DP128 konfigūraciją, vidutinis kiekvieno eksperto gaunamų žetonų skaičius (t. y. m) yra 128 * 2 * 8 * 128 / 256 = 1024. Panašiai galime apskaičiuoti m kitoms konfigūracijoms ir paketų dydžiams.

Našumo testavimui naudojome „DeepGEMM“ „GroupGEMM“ diegimą. Testavimo taškai apėmė EP8, EP16, EP32, EP64, EP128 konfigūracijų derinius su TP1 ir 1–128 paketų dydžiais.

GroupGEMM našumas, palyginti su skaičiavimo ir atminties pralaidumo ribinėmis linijomis.

Paveikslėlyje aukščiau parodytas „GroupGEMM“ „Roofline“ modelis esant skirtingoms EP konfigūracijoms. Skirtingi EP atitinka skirtingus grupių skaičius. Paveikslėlyje pavaizduotos beveik persidengiančios našumo linijos, nurodančios, kad „GroupGEMM“ našumą daugiausia lemia bendras žetonų skaičius (pavaizduotas kaip g * m).

Žvaigždutėmis pažymėti duomenų taškai, atitinkantys 128 paketo dydį vienam GPU kiekvienai EP konfigūracijai. Lyginant šiuos žvaigždutėmis pažymėtus duomenų taškus matyti, kad didėjant EP (ir sinchroniškai didėjant DP), žetonų skaičius vienam ekspertui m taip pat didėja. Esant EP8, m=128, o esant EP128, m=2048.

Didėjant m, aritmetinis intensyvumas taip pat didėja. Daugelyje konfigūracijų „GroupGEMM“ riboja atminties pralaidumas, todėl m didinimas pagerina našumą.

GEMM

GEMM branduolys atitinka Linear proskynas modelyje, tokias kaip Q/K/V/O proskyna. [m, k] x [k, n] -> [m, n] matricos daugybai FLOP skaičius yra 2 * m * k * n, o atminties I/O baitai yra m * k + n * k + m * n. Taip pat galime ištestuoti 1–128 paketų dydžių delsą.

GEMM našumas, palyginti su skaičiavimo ir atminties pralaidumo ribinėmis linijomis.

Paveikslėlyje aukščiau parodytas GEMM „Roofline“ modelis esant skirtingoms EP konfigūracijoms. Matome, kad GEMM našumą riboja atminties pralaidumas. Didėjant paketo dydžiui, aritmetinis intensyvumas taip pat didėja, taip pagerindamas našumą.

„Microbatch“

Naudodami mikro-paketavimą, paketą tolygiai padalijame į dvi dalis. Iš dviejų aukščiau pateiktų paveikslėlių matome, kad kai m tampa m/2, matricos daugybos efektyvumas sumažėja. Todėl dviejų m/2 dydžio matricos daugybų vykdymas užtrunka ilgiau nei vienos m dydžio matricos daugybos vykdymas.

Kelių žetonų prognozavimas

Visame straipsnyje darėme prielaidą, kad spėjamajam dekodavimui naudojamas kelių žetonų prognozavimas (MTP). MTP pakeičia užklausos ilgį vienai užklausai nuo 1 iki 2. Matricos daugybai tai prilygsta m pakeitimui į m * 2, taip padidinant matricos daugybos efektyvumą. Kita vertus, jei nubrėžtume MLA „Roofline“ modelį, pastebėtume, kad užklausos ilgio didinimas žymiai padidina MLA branduolio efektyvumą.

Todėl MTP naudojimas atlieka svarbų vaidmenį modelio efektyvumui.

Diegimas ir optimizavimas

Šiame skyriuje pristatysime kai kurias mūsų „DeepSeek-V3/R1“ modelio diegimo ir optimizavimo detales.

Kvantavimas

„DeepSeek-V3/R1“ buvo natūraliai apmokytas FP8 formatu, naudojant kvantavimo schemą blokams, kai svoriai kvantuojami statiškai, o aktyvacijos kvantuojamos skrydžio metu. Vietoj to, kad statiškai skaičiuotų mastelio koeficientą kiekvienam kanalui ar matricai, mastelio koeficientai skaičiuojami per 128 elementų vektorius aktyvacijoms ir 128x128 elementų tinklelius matricoms, taip apribojant tikslumo pablogėjimą dėl kvantavimo.

„Perplexity“ siekdami palaikyti inferenciją pasikliaujame CUDA ir „Triton“ branduolių deriniu: CUDA naudojama jautriausiems našumui ir rečiausiai modifikuojamiems branduoliams (tokiems kaip dėmesys ir GEMM), o „Triton“ įgyvendina platų aktyvacijos, normalizavimo ir pagalbinių branduolių spektrą. „Triton“ leido mums greitai pritaikyti branduolius blokinio kvantavimo schemai.

Tiesiniams ir „MoE“ sluoksniams „Deep GEMM“ branduolius maišome su savaisiais „Triton GEMM“ branduoliais, nes pastebėjome, kad tam tikriems matricos matmenims ir mažiems paketų dydžiams „Split-K“ užtikrina mažesnę delsą. Jei nekvantuotas sluoksnis atlieka (M, K) x (K, N) daugybą, jam blokiniam kvantavimui reikia (M x ceil_div(K, 128)) x (ceil_div(K, 128), ceil_div(N, 128)) mastelio koeficiento. Blokiniam kvantavimui aktyvacijų mastelio koeficientai apskaičiuojami skrydžio metu, o ne iš anksto kalibruojami. Kadangi aktyvacijos mastelio koeficientai kaupiami tik išilgai K, o ne išilgai M matmens, branduoliams schemai palaikyti tereikia nedidelių pakeitimų.

Sudėtinis SiLU ir daugybos skaičiavimas, rodantis ekspertų įvesties tenzorius, išvesties tenzorius ir mastelio koeficientus.

„DeepSeek-V3/R1“ naudojamai SiLU aktyvacijos funkcijai reikėjo esminių pakeitimų, kad palaikytų CUDA grafikus, blokini kvantavimą ir dinamiškai nukreipiamų žetonų skaičių. Blokinis kvantavimas gali kelti problemų, nes įveda horizontalius sumažinimus, tačiau branduolys jau suskaldė aktyvacijas išilgai jų paslėptojo matmens į 1024 elementų blokus. Vieno bloko ribose kvantuojamas tenzorius buvo papildomai suskaldytas į 128 elementų blokus, kad būtų apskaičiuota didžiausia absoliutinė vertė, o „Triton“ sugeneravo efektyvius srauto susiejimo maksimalius sumažinimus, pridedant minimalią papildomą apkrovą.

Kad būtų palaikomas „MoE“ nukreipimas esant CUDA grafikams, branduoliai turi žinoti nukreipimo informaciją, nurodančią žetonų skaičių ekspertui, o ne planuoti darbą pagal buferiškumo dydį, kurie buvo paskirstyti viršutinei žetonų skaičiaus ribai palaikyti. Negalime padalinti problemos pagal įvesties tenzoriaus matmenis, todėl paleidžiame fiksuotą skaičių nuolatinių branduolių, kurie nuskaito nukreipimo informaciją, kad nustatytų, kiek žetonų yra užpildyta, ir dinamiškai paskirstytų aktyvacijų apdorojimo darbą tarp jų.

Kai kuriuos savo branduolius jau perkėlėme į „FlashInfer“ projektą, o ateityje atversime daugiau savo kodo.

MLA sluoksnis

MLA skaičiavimams naudojame „FlashInfer“. „FlashInfer“ palaiko lanksčius puslapių lentelės nustatymus ir itin didelį našumą.

Sujungėme q_a_proj ir kv_a_proj į vieną qkv_a_proj. Delsa sumažėjo nuo 15,4 µs + 14,8 µs = 30,2 µs iki 16,7 µs.

Padalijome kv_b_proj į dvi matricas: k_b_proj ir v_b_proj. Parašėmė FP8 bloku kvantuotą BMM branduolį skaičiavimams, susijusiems su šiomis dviem matricomis.

„Cuda Graph“

„Cuda Graph“ gali pastebimai sumažinti branduolio paleidimo papildomą apkrovą, o tai itin svarbu našumui. Kiekvienam paketo dydžiui sukuriame „Cuda Graph“.

Prieš sukurdami savo „AllToAll“ branduolį, „AllToAll“ ryšiui naudojome torch.all_to_all_single(). Ši operacija reikalauja, kad visi GPU naudotų tokį patį paketo dydį. Tačiau skirtingos DP grupės gali vykdyti skirtingus paketų dydžius.

Kad užtikrintume all_to_all_single() suderinamumą su skirtingomis DP grupėmis, naudojančiomis skirtingus paketų dydžius, prieš kiekvieną modelio paleidimą iš pradžių naudojome allreduce() operaciją maksimaliam paketo dydžiui tarp visų DP grupių gauti. Tada privertėme visas DP grupes paleisti šį paketo dydį.

Nors šis požiūris užtikrina, kad galime naudoti „Cuda Graph“, jis turi tris trūkumus. Pirma, jam reikia papildomos allreduce() operacijos. Antra, DP grupės su mažesniais paketų dydžiais yra priverstos papildyti (padingas). Trečia, jis padaro mūsų diegimo kodą sudėtingą.

Įdiegę savąjį „AllToAll“ branduolį, nebereikalaujame, kad visi GPU naudotų tokį patį paketo dydį. Todėl mums nebereikia atlikti papildomų allreduce() operacijų ar daryti paketų dydžių padingo.

„MoE“ maršrutizatorius

„MoE“ maršrutizatorius įdiegtas naudojant „Triton“, pasikliaujant modifikuotu rikiavimu, kilusiu iš standartinės bibliotekos, kuri taip pat seka surūšiuotų elementų indeksus. Šis įgyvendinimas bendrinamas visuose „MoE“ modeliuose, nes „Mixtral“ maršrutizavimas yra specialus „DeepSeek“ maršrutų atvejis, kai „Top-K“ grupė yra tokia pati kaip visų ekspertų grupė. Reti branduoliai tiesiogiai naudoja „Top-K“ indeksus ir įverčius, o tankios paskirstymo / sujungimo schemos, besiremiančios „all-to-all“, reikalauja, kad maršrutizavimo informacija būtų sujungiama ekspertų, o ne žetonų pagrindu.

Ateities darbai

Būsimuose darbuose planuojame toliau optimizuoti „DeepSeek“ modelio našumą.

Svarbiausias kitas optimizavimas yra užpildymo disagregavimas (angl. Prefill Disaggregation). „DeepSeek-V3/R1“ modelio užpildymo (prefill) ir dekodavimo fazės pasižymi labai skirtingomis skaičiavimo charakteristikomis. Abidvi jos gali naudoti skirtingas optimizavimo strategijas ir diegimo schemas.

MLA sluoksniui dekodavimo fazėje naudojame matricos absorbciją, kad sumažintume MLA skaičiavimų FLOP skaičių. Užpildymo fazėje geriau veiktų pirmiausia paslėptojo vektoriaus projecija į K/V erdvę, o po to skaičiavimai daugiagalvio dėmesio (MHA) forma.

Jei užpildymas ir dekodavimas veikia tame pačiame GPU, siekiant sumažinti užpildymo poveikį dekodavimo išvesties greičiui, paprastai naudojame supjaustytą užpildymą (chunked prefill), kad užklausą padalytume į kelis gabalus užpildymui. Kadangi KV talpykla saugo paslėptąjį vektorių, MLA konvertavimas į MHA formą tampa sudėtingas.

„MoE“ sluoksniui dekodavimo fazėje naudojame kuo didesnius EP ir DP, kad padidintume įvesties žetonų skaičių ekspertui, taip pagerindami „GroupGEMM“ našumą. Užpildymo fazėje, kadangi žetonų skaičius jau yra pakankamai didelis, „GroupGEMM“ jau riboja skaičiavimai. Todėl užpildymui galime naudoti mažesnius EP ir DP.

Jei užpildymas ir dekodavimas veikia tame pačiame GPU, kol bent viena DP grupė atlieka užpildymą, „MoE“ sluoksnių delsa visuose GPU padidės, pastebimai paveikdama dekodavimo išvesties greitį.

Be užpildymo disagregavimo, taip pat planuojame optimizuoti šiuos aspektus:

„AllToAll“ našumas: Mūsų „AllToAll“ branduolys šiuo metu gali pasiekti tik 1/3 „Infiniband“ pralaidumo. Tęsime šio branduolio optimizavimą.

EAGLE stiliaus spėjamasis dekodavimas: Aukščiau pateiktuose duomenyse padarėme prielaidą, kad spėjamasis dekodavimas naudojamas 1 žetonui prognozuoti. EAGLE gali naudoti medžio struktūrą keliems žetonams prognozuoti, pagerindamas priėmimo ilgį, o tai gali žymiai padidinti išvesties greitį.

GEMM branduolys: Anksčiau parodytame „Roofline“ modelyje matome, kad GEMM branduolio efektyvumas vis dar toli gražu nesiekia teorinės ribos. Tęsime šio branduolio optimizavimą.

GB200 NVL72: Naujausiame „NVIDIA“ GB200 NVL72 sprendime 72 „Blackwell“ GPU yra sujungti per didelės spartos „NVLink“. „MoE“ architektūros modeliams tai yra didžiulė galimybė ir iššūkis.

Išvada

Kelių mazgų „DeepSeek MoE“ modelių diegimas pasiekia tai, kas paprastai neįmanoma su tankiais LLM: vienu metu pagerina ir pralaidumą, ir delsą. Paskirstydami ekspertus tarp daugiau GPU, sumažiname atminties pralaidumo apkrovą vienam įrenginiui, įgalindami greitesnį apdorojimą ir didesnį sistemos pralaidumą. Mūsų eksperimentai rodo, kad EP128 konfigūracijos pasiekia iki 5 kartų didesnį pralaidumą esant lygiaverčiam išvesties greičiui, lyginant su vieno mazgo diegimais.

Skaičiavimų ir ryšio persidengimo technikos, tokios kaip mikro-paketavimas, žymiai sumažina kelių mazgų ryšio papildomą apkrovą, o mūsų įgyvendinimas parodė iki 40 % pagreitėjimą. Mūsų pasirinktiniai „AllToAll“ ryšio branduoliai ir optimizuoti branduolių diegimai įgalino efektyvų 671 mlrd. parametrų modelio diegimą.

Kadangi „MoE“ architektūros įgyja populiarumą dėl savo galimybių, šios diegimo strategijos suteikia vertingų įžvalgų, kaip efektyviai mastelkeisti tokius modelius.

Literatūra

„DeepSeek-V3“ techninė ataskaita

„DeepSeek-V3/R1“ inferencijos sistemos apžvalga

„Megatron-LM“: daugiarūšių parametrų kalbos modelių mokymas naudojant modelio paralelizmą

„EAGLE“: spėjamasis parinkimas reikalauja iš naujo permąstyti požymių neapibrėžtumą

Citata

BibTeX
@online{perplexity2025LowerLatencyAndHigherThroughputWithMultiNodeDeepseekDeployment,
  author = {{Perplexity} and Lequn Chen and Nandor Licker and Erin McKnight},
  title = {{Lower latency and higher throughput with multi-node DeepSeek deployment}},
  date = {2025-04-18},
  url = {https://perplexity.coolkeypoint.com/hub/blog/lower-latency-and-higher-throughput-with-multi-node-deepseek-deployment}
}