Lagere latentie en hogere doorvoer met multi-node DeepSeek

Multi-GPU implementatie verhoogt MoE-modelprestaties simultaan

AuteursPerplexity Research

In de meeste systemen zijn latentie en doorvoer vaak tegenstrijdige doelstellingen die afwegingen vereisen tijdens het ontwerp en de implementatie. Bij dichte grote taalmodellen kan bijvoorbeeld het verhogen van de batchgrootte de doorvoer verbeteren, maar dit verhoogt ook de latentie; het verhogen van tensor-parallellisme binnen een enkele machine kan de latentie verminderen, maar verlaagt het aantal replica's, wat leidt tot een lagere doorvoer.

Mixture of Experts (MoE)-modellen zoals DeepSeek-V3/R1 hebben onlangs uitstekende modelmogelijkheden en operationele efficiëntie aangetoond. Het DeepSeek-V3/R1-model heeft bijvoorbeeld in totaal 671B parameters, maar elke token gebruikt slechts 37B parameters tijdens inferentie. Deze modelarchitectuur biedt zowel uitdagingen als kansen voor inferentiesystemen.

Dit artikel toont aan dat, in tegenstelling tot conventionele systemen, MoE-modellen zoals DeepSeek-V3/R1 tegelijkertijd een hogere doorvoer en lagere latentie kunnen bereiken bij gebruik van meer GPU's in multi-node implementaties in de meeste scenario's.

Implementatiearchitecturen

Single-node-implementatie via NVLink, met attention en expert-computatie verdeeld over GPU's.
Multi-node-implementatie via InfiniBand, met GPU-groepen verbonden binnen en tussen nodes.

Vanwege het grote aantal kleine experts in het model, moeten implementaties worden verspreid over meerdere apparaten. We hebben zowel single-node implementaties op één knooppunt met 8xH200 GPU's als multi-node implementaties op 8xH100 GPU's overwogen.

Beide implementatiearchitecturen maken gebruik van Dataparallellisme, georkestreerd door onze eigen verzoekplanner. De implementatie van dataparallellisme omvat het starten van meerdere inferentie-engine-instanties, die elk onafhankelijk werken om verzoeken te bedienen en te onderhouden. De verzoekplanner, die via GRPC met de engine communiceert, is verantwoordelijk voor het zo gelijkmatig mogelijk spreiden van verzoeken, terwijl hij ook KV-hergebruik faciliteert door verzoeken met een gedeeltelijk overeenkomend voorvoegsel naar de servers met de cache te sturen. Engine-instanties overspannen niet meerdere knooppunten. Ze kunnen optioneel tensor-parallellisme gebruiken om de aandacht over meerdere apparaten te verdelen. De instanties zijn onderling verbonden via NVLink in het geval van een enkel knooppunt of InfiniBand voor het geval van meerdere knooppunten, waarbij experts worden verzonden en verzameld.

De single-node implementatieconfiguratie levert superieure latentie bij kleine batchgroottes; de prestaties degraderen echter snel onder verhoogde belastingsomstandigheden.

Om de serving-engine te implementeren, starten we één pod per knooppunt die meerdere engine-instanties host. PyTorch is verantwoordelijk voor het opzetten van de gedistribueerde communicatie en het onderhandelen over de initialisatie van NVSHMEM. Voor communicatie vertrouwen we op aangepaste CUDA-kernels die worden beschreven in een eerdere blogpost. De implementatie van de twee implementaties is vrijwel identiek, waarbij het model de juiste kernels kiest op basis van de fabric die expertparallellisme implementeert.

Parallelisatietechnieken

Voordat we in onze prestatievergelijkingen duiken, is het essentieel om de belangrijkste parallellisatiestrategieën te begrijpen die het implementeren van enorme MoE-modellen zoals DeepSeek-V3/R1 mogelijk maken.

Tensor-parallellisme

Bij LLM-inferentie wordt Tensor-parallellisme (TP) doorgaans gebruikt om het geheugengebruik en de berekeningen per GPU te verminderen, waardoor de latentie wordt verlaagd. Meestal kunnen we Linear Projections in Attention- en MLP-lagen sharden langs rij- of kolomdimensies, en Attention-operaties sharden langs de dimensie van de attention-head.

Met TP heeft de Llama-3-architectuur geen dubbele berekeningen voor Linear Projection- en Attention-operaties over GPU's, wat een ideale shardingsmethode is. Bij DeepSeek-V3/R1-modellen kan TP dit echter niet bereiken.

DeepSeek-V3/R1-modellen gebruiken Multi-Latent Attention (MLA). Een MLA-laag gebruikt eerst een Linear Projection kv_a_proj om de latente vector te berekenen, en gebruikt vervolgens een andere Linear Projection kv_b_proj om deze om te zetten naar de ruimte van elke attention-head. Aangezien alle attention-heads dezelfde latente vector delen, kan TP de latente vector niet sharden, dus moeten alle TP Ranks de parameters en berekeningen van kv_a_proj en kv_b_proj repliceren. Omdat MLA de latente vector in de KV Cache opslaat, slaat elke TP Rank eveneens een identieke kopie van de KV Cache op.

Ondanks enige duplicatie in MLA, biedt Tensor-parallellisme nog steeds een gedeeltelijke vermindering van de rekenvereisten, waardoor het waardevol is voor scenario's die hoge uitvoersnelheden vereisen.

Expert-parallellisme

DeepSeek-V3/R1-modellen vervangen MLP-lagen door MoE-lagen. Een MoE-laag heeft 256 gerouteerde experts en één gedeelde expert. Elke token wordt naar 8 verschillende gerouteerde experts gestuurd voor berekening, en de resultaten worden gewogen opgeteld. Elke token berekent ook in de gedeelde expert, en het resultaat wordt opgeteld bij het resultaat van de gerouteerde experts.

Expert-parallellisme (EP) dient als de typische shardingsbenadering voor MoE-lagen, waarbij elke GPU 256 / EP gerouteerde experts beheert terwijl een kopie van de gedeelde expert behouden blijft. Vergeleken met TP is het voordeel van EP dat het berekeningen over meer GPU's kan verdelen, wat het reken- en geheugengebruik per GPU vermindert.

Voordat expertberekeningen worden uitgevoerd, moeten alle GPU's een AllToAll-communicatie uitvoeren om tokens naar de GPU's te sturen waar de bijbehorende experts zich bevinden; na de expertberekening is een andere AllToAll-communicatie nodig om berekeningsresultaten van verschillende GPU's te verzamelen en gewogen sommatie uit te voeren. We hebben een geoptimaliseerde versie van deze twee AllToAll-communicatiekernels, Dispatch en Combine, geïmplementeerd met NVSHMEM. In onze vorige blogpost hebben we de implementatie gedetailleerd beschreven, en onze kernels zijn open-sourced op GitHub.

Dataparallellisme

Met EP kunnen we MoE-berekeningen verdelen over 128 of zelfs meer GPU's. MLA-berekeningen kunnen echter niet worden gepartitioneerd met EP. Op dit punt kunnen we Dataparallellisme (DP) introduceren. Elke DP-groep heeft een volledige kopie van de MLA-laag. Elke DP-groep accepteert verschillende invoer en voert onafhankelijk MLA-laagberekeningen uit.

De DP en TP van de MLA-laag kunnen worden gecombineerd, waarbij één DP-groep wordt gesplitst in meerdere TP Ranks. Het EP van de MoE-laag kan worden gecombineerd met de DP/TP van de MLA-laag. EP = DP * TP. Bijvoorbeeld, op 16 machines betekent EP128 DP32 TP4 het verdelen van gerouteerde experts over 128 GPU's, waarbij elke 4 GPU's een DP-groep vormen, voor een totaal van 32 onafhankelijke DP-groepen.

Single-node versus Multi-node

De 671B parameters van DeepSeek overschrijden de geheugencapaciteit van één machine met 8 H100-GPU's (80 GB * 8), maar een enkele machine met 8 H200-GPU's kan het volledige model (141 GB * 8) volledig huisvesten. Met de EP8 DP8 TP1-configuratie gebruikt het model ongeveer 100 GB geheugen per GPU, waardoor er ongeveer 40 GB overblijft voor KV Cache en andere tussenresultaten. Eén token neemt 70.272 bytes aan KV Cache in beslag. Ervan uitgaande dat elk verzoek 5.000 tokens heeft, kan elke GPU ongeveer 100 verzoeken huisvesten.

We wilden de prestatieverschillen begrijpen tussen single-node en multi-node implementaties onder verschillende configuraties. We gebruikten één H200-machine voor single-node implementatie en maximaal 16 H100-machines voor multi-node implementaties. Voor elke implementatieomgeving gebruikten we combinaties van TP 1, 2, 4, 8 en batchgroottes per GPU van 1, 2, 4, 8, 16, 32, 64, 128. We gingen ervan uit dat elk verzoek een KV Cache-lengte van 5.000 tokens had. We gingen er ook van uit dat Multi-Token Prediction (MTP) 1 extra token voorspelt (d.w.z. de querylengte van elk verzoek is 2), en gingen conservatief uit van een acceptatiegraad van 60%. De onderstaande figuur toont de doorvoer en uitvoersnelheid voor verschillende configuraties.

Latency-doorvoersnelheid-Paretofronten voor verschillende expert-parallelconfiguraties.

De horizontale as vertegenwoordigt de uitvoersnelheid per verzoek in tokens/s. De verticale as gebruikt een logaritmische schaal om de doorvoer per machine in tokens/s weer te geven. We hebben de Pareto Frontier voor elke EP-configuratie gemarkeerd met gekleurde lijnen.

In scenario's met extreem hoge vereisten voor uitvoersnelheid kan het gebruik van single-node EP8 DP1 TP8 met een batchgrootte van 1 een uitvoersnelheid van meer dan 100 tokens/s bereiken, maar de doorvoer is extreem laag, equivalent aan de uitvoersnelheid. In dit scenario heeft de gehele batch slechts 2 tokens, die naar maximaal 2*8=16 experts kunnen worden gestuurd, wat in totaal maximaal 57B parameters activeert.

In het uitvoersnelheidsbereik van 80-40 tokens/s neemt de uitvoersnelheid aanzienlijk af naarmate de doorvoer toeneemt. Daarentegen heeft EP128 ongeveer 5x hogere doorvoer dan single-node implementatie bij dezelfde uitvoersnelheid.

Dit fenomeen kan worden verklaard door te kijken naar hoe single-node implementaties zich gedragen: het verhogen van de batchgrootte correleert direct met een toename van geactiveerde experts. Wanneer de batchgrootte 1 is, is het gemiddelde aantal geactiveerde experts per GPU 2 * 8 / 8 = 2. Wanneer de batch groot genoeg is, worden alle experts geactiveerd, wat betekent dat elke GPU 256 / 8 = 32 experts activeert. Het activeren van meer experts betekent dat de GPU meer parameters uit het geheugen moet lezen, wat de druk op de geheugenbandbreedte aanzienlijk verhoogt. Aangezien de decodeerfase van grote taalmodellen al wordt beperkt door geheugenbandbreedte in plaats van rekenprestaties, vermindert het verhogen van de batchgrootte bij single-node implementatie de uitvoersnelheid aanzienlijk.

Vergelijking van de vier multi-node implementatieconfiguraties (EP16, EP32, EP64 en EP128) onthult dat hogere EP-waarden de Pareto Frontier verschuiven naar gelijktijdige verbeteringen in doorvoer en uitvoersnelheid.

Het gebruik van een hoger EP-nummer betekent dat elke GPU wordt toegewezen aan minder experts. EP128 betekent bijvoorbeeld dat elke GPU verantwoordelijk is voor 256 / 128 = 2 experts, waardoor de druk op de geheugenbandbreedte aanzienlijk wordt verminderd. Met andere woorden, door een groter EP-nummer te gebruiken, winnen we effectief meer geheugenbandbreedte. Wanneer de batchgrootte per GPU kleiner is dan 64, beïnvloedt het verhogen van de batchgrootte de snelheid van expertberekeningen niet aanzienlijk, omdat het verhogen van het aantal invoeren de druk op de geheugenbandbreedte niet aanzienlijk verhoogt. Daarom zien we dat bij gebruik van EP128 het verhogen van de batchgrootte de uitvoersnelheid niet zo significant beïnvloedt.

Interessant genoeg zagen we bij grotere batchgroottes (64 verzoeken per GPU) een nieuw fenomeen: de doorvoer van single-node implementatie is iets hoger dan die van multi-node implementatie. Een deel van de reden is dat intra-node NVLink een hogere bandbreedte heeft dan inter-node InfiniBand. Een ander deel is te wijten aan beperkingen in onze implementatie. We zullen dit fenomeen later in meer detail analyseren.

Vanwege beperkingen in de geheugencapaciteit kan de EP8 DP8 TP1-configuratie geen batchgrootte van 128 per GPU bereiken, dus multi-node implementatie is nog steeds een betere keuze in scenario's die streven naar een hogere doorvoer.

Overlapping van berekening en communicatie

Zoals hierboven kort geïntroduceerd met betrekking tot Expert-parallellisme, zijn GPU's inactief tijdens MoE-laagcommunicatie. Om verspilling te verminderen en latentie te verlagen, moeten we gegevensonafhankelijke rekentaken vinden om deze inactieve tijd op te vullen.

Schema's voor berekening en communicatie zonder overlap, overlap van dispatch en een vijftraps pijplijn.

Het bovenste deel van de bovenstaande figuur toont de berekeningsstroom van één laag. MoE-berekening is afhankelijk van Dispatch, en de berekening van de volgende laag is afhankelijk van het resultaat van Combine.

We plaatsen de gedeelde expert op elke GPU. Op deze manier vereist berekening door de gedeelde expert geen AllToAll-communicatie. Daarom kunnen we direct na de Dispatch Send berekeningen door de gedeelde expert uitvoeren, en vervolgens wachten tot Dispatch Recv is voltooid. We noemen dit overlap-schema "Dispatch Overlap".

Dispatch Overlap biedt een eenvoudige implementatie en brede toepasbaarheid. Deze techniek verbergt de berekeningstijd van de gedeelde expert over alle EP-groottes en batchgroottes heen.

Om de overlapping van berekening en communicatie verder te vergroten, hebben we micro-batching gebruikt, zoals vermeld in het technische rapport van DeepSeek, om de gegevensafhankelijkheid te doorbreken. Zoals getoond in het onderste deel van de figuur, hebben we de berekening van één Transformer-laag verdeeld in 5 fasen:

Fase 1: InputNorm, QKVProj, AppendKV, BMM

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

Fase 3: Dispatch Send, Gedeelde Expert

Fase 4: Dispatch Recv, MoE, Combine Send

Fase 5: Combine Recv

In de eerste 3 Dense Transformer-lagen gebruiken we de hele batch. In de volgende 58 MoE Transformer-lagen verdelen we de batch gelijkmatig in twee micro-batches. De twee micro-batches worden afwisselend uitgevoerd, met een verschuiving van 3 fasen. Aangezien er geen gegevensafhankelijkheid is tussen deze twee micro-batches, kunnen we na Dispatch Send en na Combine Send overschakelen naar de berekening van een andere micro-batch.

Latentieanalyse

Vervolgens vergelijken we de effecten van overlapping door middel van een experiment, en vergelijken we de prestatieverschillen tussen single-node implementatie EP8 en multi-node implementatie EP128. Voor het gemak van vergelijking gebruikten we H100 GPU's voor het volgende experiment. We gebruikten TP1, een batchgrootte van 128 per GPU, een querylengte van 2 per verzoek en een KV Cache-lengte van 5000.

Laaglatentie per kernel voor de vergeleken expert-parallel- en overlappingsconfiguraties.

De bovenstaande figuur toont de totale tijd besteed aan één MoE Transformer-laag en het latentieaandeel van verschillende soorten kernels. Behalve voor Dispatch, Combine en GroupGEMM, zou de uitvoeringstijd van andere kernels gelijk moeten zijn in de series EP8, EP128 NoOverlap en EP128 DispatchOverlap, omdat de batchgrootte hetzelfde is.

Overlapping

Laten we eerst de effecten van de drie overlapmethoden vergelijken. NoOverlap duurde in totaal 2667µs, DispatchOverlap duurde 2651µs, wat 16µs of slechts 0,6% bespaart. MicroBatch vertoonde een zeer significante verbetering, met een duur van 1896µs, een versnelling van 29%. Zowel de Dispatch- als de Combine-tijd werden aanzienlijk verminderd. Dispatch daalde van 593µs naar 367µs, en Combine van 1012µs naar 237µs.

Merk op dat voor rekenkernels het splitsen van een batch van 128 in twee batches van 64 de totale uitvoeringstijd verhoogt. Daarom is, hoewel de tijd besteed aan communicatie met 1001µs werd verminderd, de totale tijd slechts met 771µs verminderd. We zullen de reden hiervoor in de volgende sectie uitleggen met behulp van het Roofline-model.

Om deze reden verbetert micro-batching de prestaties niet altijd.

Veranderingen in uitvoersnelheid en doorvoer per node met micro-batching, uitgezet tegen batchgrootte per GPU.

De bovenstaande figuur toont de prestatieverbetering van Microbatch in vergelijking met DispatchOverlap voor batchgroottes 4-128. Wanneer de batchgrootte kleiner is dan 32, vermindert Microbatch de prestaties met 5%-40%. Wanneer de batchgrootte groter dan of gelijk aan 32 is, kan Microbatch de prestaties met 10%-35% verbeteren.

EP8 versus EP128

Laten we terugkeren naar de vorige figuur en EP8 en EP128 Microbatch vergelijken. EP8 duurde in totaal 1802µs, iets minder dan de 1896µs van EP128. Naast de toegenomen kernelexecutietijd door Microbatch die hierboven werd vermeld, zijn de belangrijkste verschillen in GroupGEMM dat wordt gebruikt voor MoE-berekeningen, en de twee communicatiekernels, Dispatch en Combine.

GroupGEMM van EP8 duurde 555µs, terwijl GroupGEMM van EP128 270µs duurde, wat een halvering is. Dit is het kernvoordeel van multi-node implementatie.

Helaas nam de tijd besteed aan communicatie toe met 213µs, wat het voordeel van GroupGEMM grotendeels teniet deed. In afzonderlijke prestatietests van onze communicatiekernels ontdekten we dat ze slechts de helft van de Infiniband-bandbreedte kunnen bereiken. We zullen onze communicatiekernels blijven optimaliseren.

Een andere kernel die aanzienlijk achterblijft is GEMM. Microbatch verhoogde GEMM met 95µs. We zullen GEMM in de onderstaande Roofline-sectie dieper analyseren. Wij geloven dat de huidige GEMM-implementatie nog niet de optimale prestaties heeft bereikt.

Roofline

Het Roofline-model is een goed hulpmiddel voor het analyseren van kernelprestaties. De horizontale as is Arithmetic Intensity, de verhouding tussen FLOP en geheugen-I/O-bytes. De waarde van de horizontale as kan direct worden berekend op basis van de semantiek van de kernel. De verticale as vertegenwoordigt de behaalde prestaties, berekend door FLOP te delen door de benchmarklatentie.

De theoretische bovengrens van kernelprestaties wordt direct bepaald door de specificaties van de GPU. De FP8-piekprestaties van de H100 zijn 1979 TFLOP/s, weergegeven als een horizontale lijn in het Roofline-model. De geheugenbandbreedte van de H100 is 3,35 TB/s, weergegeven als de helling van een lijn die door de oorsprong gaat. De twee lijnen geven de prestatielimieten voor respectievelijk compute-bound en memory-bound kernels.

Hieronder bespreken we de prestaties van de GroupGEMM- en GEMM-kernels.

GroupGEMM

De GroupGEMM-kernel in MoE voert de volgende berekening uit: Er zijn in totaal g groepen, de i-de groep heeft m_i tokens, die een matrixvermenigvuldiging uitvoeren van [m_i, k] x [k, n] -> [m_i, n]. Bij prestatietests gaan we ervan uit dat het aantal tokens in elke groep hetzelfde is, aangeduid als m_i = m. Dan is het FLOP-aantal voor GroupGEMM 2 * g * m * k * n, en de geheugen-I/O-bytes zijn g * (m * k + n * k + m * n).

In het DeepSeek-V3/R1-model zijn er 256 experts en wordt elke token naar 8 experts gestuurd voor berekening. Ervan uitgaande dat een batchgrootte van 128, querylengte van 2, met behulp van EP128 DP128-configuratie, is het gemiddelde aantal tokens dat door elke expert wordt ontvangen (d.w.z. m) 128 * 2 * 8 * 128 / 256 = 1024. Op dezelfde manier kunnen we m berekenen voor andere configuraties en batchgroottes.

We hebben de GroupGEMM-implementatie van DeepGEMM gebruikt voor prestatietests. Testpunten betroffen combinaties van EP8, EP16, EP32, EP64, EP128 configuraties met TP1 en batchgroottes 1-128.

GroupGEMM-prestaties ten opzichte van rooflines voor compute en geheugenbandbreedte.

De bovenstaande figuur toont het Roofline-model voor GroupGEMM onder verschillende EP-configuraties. Verschillende EP's komen overeen met verschillende aantallen groepen. De figuur illustreert bijna overlappende prestatielijnen, wat aangeeft dat de prestaties van GroupGEMM grotendeels worden bepaald door het totale aantal tokens (weergegeven als g * m).

De sterren markeren de datapunten die overeenkomen met een batchgrootte van 128 per GPU voor elke EP-configuratie. Door deze ster-datapunten te vergelijken, kunnen we zien dat naarmate EP toeneemt (en DP synchroon toeneemt), het aantal tokens per expert m ook toeneemt. Bij EP8 is m=128, terwijl bij EP128 m=2048 is.

Naarmate m toeneemt, neemt ook Arithmetic Intensity toe. In de meeste configuraties wordt GroupGEMM beperkt door geheugenbandbreedte, dus het verhogen van m verbetert de prestaties.

GEMM

De GEMM-kernel komt overeen met Linear Projections in het model, zoals Q/K/V/O Projection. Voor een matrixvermenigvuldiging van [m, k] x [k, n] -> [m, n], is het FLOP-aantal 2 * m * k * n, en de geheugen-I/O-bytes zijn m * k + n * k + m * n. We kunnen ook de latentie testen voor batchgroottes 1-128.

GEMM-prestaties ten opzichte van rooflines voor compute en geheugenbandbreedte.

De bovenstaande figuur toont het Roofline-model voor GEMM onder verschillende EP-configuraties. We kunnen zien dat GEMM-prestaties worden beperkt door geheugenbandbreedte. Naarmate de batchgrootte toeneemt, neemt Arithmetic Intensity ook toe, waardoor de prestaties verbeteren.

Microbatch

Bij gebruik van micro-batching verdelen we de batch gelijkmatig in twee delen. Uit de twee bovenstaande figuren kunnen we zien dat wanneer m verandert in m/2, de efficiëntie van matrixvermenigvuldiging afneemt. Daarom duurt het uitvoeren van twee matrixvermenigvuldigingen van grootte m/2 langer dan het uitvoeren van één matrixvermenigvuldiging van grootte m.

Multi-Token Prediction

Door dit hele artikel heen zijn we uitgegaan van het gebruik van Multi-Token Prediction (MTP) voor speculatieve decodering. MTP verandert de querylengte per verzoek van 1 naar 2. Voor matrixvermenigvuldiging is dit equivalent aan het veranderen van m in m * 2, waardoor de efficiëntie van matrixvermenigvuldiging toeneemt. Aan de andere kant, als we het Roofline-model voor MLA zouden tekenen, zouden we ontdekken dat het verhogen van de querylengte de MLA-kernelefficiëntie aanzienlijk verhoogt.

Daarom speelt het gebruik van MTP een belangrijke rol bij modelefficiëntie.

Implementatie & optimalisaties

In deze sectie introduceren we enkele implementatie- en optimalisatiedetails voor ons DeepSeek-V3/R1-model.

Kwantisering

DeepSeek-V3/R1 was native getraind op FP8 met een kwantiseringsschema per blok, waarbij gewichten statisch werden gekwantiseerd en activaties on-the-fly. In plaats van statisch een schaalfactor per kanaal of per matrix te berekenen, worden schalfactoren berekend over vectoren van 128 elementen voor activaties en tegels van 128x128 elementen voor matrices, wat degradatie van de nauwkeurigheid door kwantisering beperkt.

Bij Perplexity vertrouwen we op een mix van CUDA- en Triton-kernels om inferentie te ondersteunen, waarbij CUDA wordt gebruikt voor de meest prestatiegevoelige en zelden gewijzigde kernels (zoals attention en GEMM), en Triton een breed scala aan activatie-, normalisatie- en utility-kernels implementeert. Triton stelde ons in staat om de kernels snel aan te passen aan het blokkwantiseringsschema.

Voor lineaire en MoE-lagen mixen we de Deep GEMM-kernels met onze eigen Triton GEMM-kernels, aangezien we hebben gemerkt dat voor bepaalde matrixdimensies en lage batchgroottes Split-K een lagere latentie oplevert. Als de ongekwantiseerde laag een (M, K) x (K, N)-vermenigvuldiging uitvoert, heeft deze een (M x ceil_div(K, 128)) x (ceil_div(K, 128), ceil_div(N, 128))-schaalfactor nodig voor blokkwantisering. Voor blokkwantisering worden de schaalfactoren voor activaties on-the-fly berekend, in plaats van vooraf gekalibreerd. Aangezien schaalfactoren voor activaties alleen worden geaggregeerd langs de K-dimensie en niet langs de M-dimensie, vereisen kernels slechts kleine wijzigingen om het schema te ondersteunen.

Gebatchede SiLU-en-vermenigvuldigingsberekening, met expert-invoertensors, uitvoertensors en schaalfactoren.

De SiLU-activatiefunctie die door DeepSeek-V3/R1 wordt gebruikt, vereiste aanzienlijke wijzigingen om CUDA-grafieken, blokkwantisering en dynamisch gerouteerde tokentellingen te ondersteunen. Blokkwantisering kan problematisch zijn omdat het horizontale reducties introduceert, maar de kernel had al activaties langs hun verborgen dimensie in blokken van 1024 elementen gechunked. Binnen één blok werd de te kwantiseren tensor verder gechunked in blokken van 128 om de grootste absolute waarde te berekenen, waarbij Triton efficiënte cross-warp max-reducties genereerde, wat voor minimale overhead zorgde.

Om MoE-routing onder CUDA-grafieken te ondersteunen, moeten de kernels op de hoogte zijn van de routeringsinformatie die het aantal tokens per expert aangeeft, in plaats van het werk in te plannen op basis van de grootte van de buffers die waren toegewezen om de bovengrens van de tokentellingen te bevatten. We kunnen het probleem niet splitsen op basis van de input-tensor-dimensies, dus starten we een vast aantal persistente kernels die de routeringsinformatie lezen om te bepalen hoeveel tokens zijn gevuld en het werk van het verwerken van de activaties dynamisch onder hen verdelen.

We hebben al een deel van onze kernels upstream naar het FlashInfer-project gebracht en in de toekomst zullen we meer van onze code open-sourcen.

MLA-laag

We gebruiken FlashInfer voor MLA-berekening. FlashInfer ondersteunt flexibele Page Table-instellingen en extreem hoge prestaties.

We hebben q_a_proj en kv_a_proj samengevoegd tot één qkv_a_proj. De latentie daalde van 15,4 µs + 14,8 µs = 30,2 µs naar 16,7 µs.

We hebben kv_b_proj gedecomponeerd in twee matrices, k_b_proj en v_b_proj. We hebben een FP8 Block Quantized BMM-kernel geschreven voor berekeningen gerelateerd aan deze twee matrices.

Cuda-grafiek

Cuda-grafiek kan de overhead van het opstarten van de kernel aanzienlijk verminderen, wat cruciaal is voor de prestaties. We maken een Cuda-grafiek voor elke batchgrootte.

Voordat we onze AllToAll-kernel ontwikkelden, gebruikten we torch.all_to_all_single() voor AllToAll-communicatie. Deze operatie vereist dat alle GPU's dezelfde batchgrootte gebruiken. Verschillende DP-groepen kunnen echter verschillende batchgroottes draaien.

Om ervoor te zorgen dat all_to_all_single() compatibel is met verschillende DP-groepen die verschillende batchgroottes gebruiken, hebben we eerst een allreduce()-operatie vóór elke modelrun gebruikt om de maximale batchgrootte onder alle DP-groepen te krijgen. Daarna hebben we alle DP-groepen deze batchgrootte laten gebruiken om te draaien.

Hoewel deze aanpak ervoor zorgt dat we Cuda Graph kunnen gebruiken, heeft hij drie nadelen. Ten eerste vereist hij een extra allreduce()-operatie. Ten tweede worden DP-groepen met kleinere batchgroottes gedwongen om te paddingen. Ten derde maakt het onze implementatiecode complex.

Na het implementeren van onze eigen AllToAll-kernel, vereisen we niet langer dat alle GPU's dezelfde batchgrootte gebruiken. Daarom hoeven we geen extra allreduce()-operaties uit te voeren of batchgroottes op te vullen.

MoE-router

De MoE-router is geïmplementeerd in Triton, vertrouwend op een aangepaste sort afgeleid van de standaardbibliotheek die ook de indexen van de gesorteerde elementen bijhoudt. De implementatie wordt gedeeld over alle MoE-modellen, aangezien Mixtral-routing een speciaal geval is van de DeepSeek-routes waarbij de Top-K-groep hetzelfde is als de groep van alle experts. De sparse kernels consumeren de Top-K-indexen en scores direct, terwijl dense dispatch/combine-schema's die vertrouwen op all-to-all vereisen dat routeringsinformatie per expert wordt geaggregeerd in plaats van op basis van een per-token basis.

Toekomstig werk

In toekomstig werk zijn we van plan om de prestaties van het DeepSeek-model verder te optimaliseren.

De belangrijkste volgende optimalisatie is Prefill Disaggregation. De Prefill-fase en de Decode-fase van het DeepSeek-V3/R1-model hebben zeer verschillende computationele kenmerken. Beide kunnen verschillende optimalisatiestrategieën en implementatieschema's gebruiken.

Voor de MLA-laag gebruiken we in de Decode-fase Matrix Absorption om het FLOP-aantal van de MLA-berekening te verminderen. In de Prefill-fase zou het eerst projecteren van de latente vector naar K/V-ruimte en vervolgens berekenen in Multi-Head Attention (MHA)-vorm beter presteren.

Als Prefill en Decode op dezelfde GPU draaien, gebruiken we doorgaans chunked prefill om de query in meerdere chunks te verdelen voor Prefill, om de impact van Prefill op de Decode-uitvoersnelheid te verminderen. Omdat de KV Cache de latente vector opslaat, wordt het moeilijk om MLA naar MHA-vorm om te zetten.

Voor de MoE-laag gebruiken we in de Decode-fase zo groot mogelijke EP en DP om het aantal invoertokens per expert te vergroten, waardoor de GroupGEMM-prestaties worden verbeterd. In de Prefill-fase, omdat het aantal tokens al groot genoeg is, is GroupGEMM al compute-bound. Daarom kunnen we voor Prefill kleinere EP en DP gebruiken.

Als Prefill en Decode op dezelfde GPU draaien, zal de latentie van MoE-lagen op alle GPU's toenemen zolang een DP-groep Prefill uitvoert, wat de Decode-uitvoersnelheid aanzienlijk beïnvloedt.

Naast Prefill Disaggregation zijn we ook van plan om de volgende aspecten te optimaliseren:

AllToAll-prestaties: Onze AllToAll-kernel kan momenteel slechts 1/3 van de Infiniband-bandbreedte bereiken. We zullen deze kernel blijven optimaliseren.

EAGLE-stijl speculatieve decodering: In de bovenstaande gegevens gingen we ervan uit dat speculatieve decodering werd gebruikt om 1 token te voorspellen. EAGLE kan een boomstructuur gebruiken om meerdere tokens te voorspellen, wat de acceptatielengte verbetert, wat de uitvoersnelheid aanzienlijk kan verhogen.

GEMM-kernel: In het eerder getoonde Roofline-model kunnen we zien dat de efficiëntie van de GEMM-kernel nog ver verwijderd is van de theoretische limiet. We zullen deze kernel blijven optimaliseren.

GB200 NVL72: In NVIDIA's nieuwste GB200 NVL72-oplossing zijn 72 Blackwell-GPU's onderling verbonden via high-speed NVLink. Voor MoE-architectuurmodellen is dit een zeer grote kans en uitdaging.

Conclusie

Multi-node implementatie van DeepSeek MoE-modellen bereikt wat doorgaans onmogelijk is met dichte LLM's: het tegelijkertijd verbeteren van zowel doorvoer als latentie. Door experts over meer GPU's te verdelen, verminderen we de druk op de geheugenbandbreedte per apparaat, wat snellere verwerking en hogere systeendoorvoer mogelijk maakt. Onze experimenten tonen aan dat EP128-configuraties tot 5x hogere doorvoer bereiken bij equivalente uitvoersnelheden in vergelijking met single-node implementaties.

Overlappingstechnieken voor berekening en communicatie, zoals micro-batching, verminderen de communicatieoverhead van meerdere knooppunten aanzienlijk, waarbij onze implementatie tot 40% versnelling laat zien. Onze aangepaste AllToAll-communicatiekernels en geoptimaliseerde kernelimplementaties hebben een efficiënte implementatie van het model met 671B parameters mogelijk gemaakt.

Naarmate MoE-architecturen aan populariteit winnen vanwege hun mogelijkheden, bieden deze implementatiestrategieën waardevolle inzichten voor het efficiënt schalen van dergelijke modellen.

Referenties

DeepSeek-V3 Technisch Rapport

DeepSeek-V3/R1 Inferentiesysteem Overzicht

Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism

EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty

Citaat

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}
}