Článek

Nižší latence a vyšší propustnost s nasazením Multi-Node DeepSeek

Zářící velryba, odkazující na DeepSeek

Ve většině systémů jsou latence a propustnost často protichůdnými cíli, které vyžadují kompromisy během návrhu a nasazení. Například u hustých modelů velkých jazyků může zvětšení velikosti dávky zlepšit propustnost, ale také zvýší latenci; zvýšení tensorové paralelizace na jednom stroji může snížit latenci, ale sníží počet replik, což vede k nižší propustnosti.

Modely typu Mixture of Experts (MoE), například DeepSeek-V3/R1, nedávno prokázaly výborné schopnosti modelování a efektivitu provozu. Například model DeepSeek-V3/R1 má celkem 671 miliard parametrů, avšak během inferenční fáze každý token využije pouze 37 miliard parametrů. Tato architektura modelu představuje výzvy i příležitosti pro inferenční systémy.

Tento článek demonstruje, že na rozdíl od konvenčních systémů mohou modely MoE jako DeepSeek-V3/R1 současně dosáhnout vyšší propustnosti a nižší latence při využívání více GPU v nasazeních na vícero uzlech ve většině scénářů.


Architektura nasazení

Vzhledem k velkému počtu malých expertů, které model má, musí být nasazení rozprostřeno na více zařízení. Zvažovali jsme jak nasazení na jediném uzlu s 8xH200 GPU, tak nasazení na více uzlech s 8xH100 GPU.

Obě architektury nasazení využívají datovou paralelizaci, kterou organizuje náš interní plánovač požadavků. Implementace datové paralelizace zahrnuje spuštění více instancí inferenčního enginu, přičemž každá z nich pracuje nezávisle na obsluhování a udržování požadavků. Plánovač požadavků, který komunikuje s enginem přes GRPC, je zodpovědný za co nejrovnoměrnější rozprostření požadavků a rovněž umožňuje opětovné použití KV, zasíláním požadavků s částečně shodným předponou na servery obsahující cache. Instance enginu nepřesahují více uzlů. Volitelně mohou používat tensorovou paralelizaci k rozložení pozornosti na více zařízení. Instance jsou propojeny pomocí NVLink v případě jednoho uzlu nebo InfiniBand v případě vícero uzlů, kde skládají a sbírají experty.

Konfigurace nasazení na jednom uzlu poskytuje vynikající latenci s malými velikostmi dávek; avšak výkon se rychle zhoršuje při zvýšeném zatížení.

Pro nasazení obslužného enginu spouštíme jeden pod na uzel, který hostí více instancí enginu. PyTorch je zodpovědný za zřízení distribuované komunikace a vyjednávání inicializace NVSHMEM. Pro komunikaci spoléháme na vlastní CUDA jádra popsaná v dřívějším blogovém příspěvku. Implementace těchto dvou nasazení je prakticky identická, přičemž model vybírá správná jádra k použití na základě infrastruktury implementující expertní paralelizaci.


Techniky paralelizace

Před ponořením se do našich porovnání výkonu je zásadní pochopit klíčové strategie paralelizace, které umožňují nasazení masivních MoE modelů jako DeepSeek-V3/R1.

Tensorová paralelizace

Při inferenci LLM se Tensorová paralelizace (TP) běžně používá ke snížení využití paměti a výpočtů na GPU, což tedy snižuje latenci. Obvykle můžeme rozdělit Lineární Projekce v Pozornost a MLP vrstvách podle řádků nebo sloupců a rozdělit operace Pozornosti podle dimenze hlavy pozornosti.

S TP architektura Llama-3 nemá duplicitu výpočtů pro operace Lineární Projekce a Pozornosti mezi GPU, což je ideální způsob shardingu. Nicméně, ve modelech DeepSeek-V3/R1 toho TP nemůže dosáhnout.

Modely DeepSeek-V3/R1 používají Multi-Latent Attention (MLA). MLA vrstva nejprve používá Lineární Projekci kv_a_proj, aby vypočítala latentní vektor, a poté používá další Lineární Projekci kv_b_proj, aby ho transformovala do prostoru každé hlavy pozornosti. Vzhledem k tomu, že všechny hlavy pozornosti sdílejí stejný latentní vektor, TP nemůže shardovat latentní vektor, takže všechny TP Ranky musí replikovat parametry a výpočty kv_a_proj a kv_b_proj. Podobně, protože MLA ukládá latentní vektor do KV Cache, každý TP Rank ukládá identickou kopii KV Cache.

Navzdory nějaké duplicitě v MLA, Tensorová Paralelizace stále poskytuje částečné snížení požadavků na výpočty, což je cenné pro scénáře vyžadující vysoké rychlosti výstupu.

Expertní paralelizace

Modely DeepSeek-V3/R1 nahrazují MLP vrstvy MoE vrstvami. MoE vrstva má 256 řízených expertů a jednoho sdíleného experta. Každý token je vyslán k 8 různým řízeným expertům k výpočtu a výsledky jsou vážené součty. Každý token se také vypočítává ve sdíleném expertu a výsledek je přidán k výsledku od řízených expertů.

Expertní paralelizace (EP) funguje jako typický přístup k shardování MoE vrstev, kde každý GPU spravuje 256 / EP řízených expertů, zatímco udržuje kopii sdíleného experta. Ve srovnání s TP má EP výhodu v tom, že může distribuovat výpočty na více GPU, což snižuje výpočty a využití paměti na GPU.

Před provedením expertních výpočtů musí všechny GPU provést AllToAll komunikaci k poslání tokenů na GPU, kde se nachází odpovídající experti; po expertní kalkulaci je potřeba další AllToAll komunikace k sběru výsledků výpočtů z různých GPU a provést vážené sčítání. Implementovali jsme optimalizovanou verzi těchto dvou AllToAll komunikačních Kernels, Dispatch a Combine, pomocí NVSHMEM. V našem předchozím blogovém příspěvku jsme popsali implementaci, a naše jádra byla open-source na GitHubu.

Datová paralelizace

S EP můžeme distribuovat MoE výpočty na 128 nebo více GPU. Nicméně MLA výpočty nelze u EP rozdělit. V tomto bodě můžeme zavést Datovou Paralelizaci (DP). Každá DP skupina má kompletní kopii MLA vrstvy. Každá DP skupina přijímá různé vstupy a provádí MLA vrstvu nezávisle.

DP a TP MLA vrstvy lze kombinovat, čímž je jedna DP skupina rozdělena do více TP hodností. EP MoE vrstv lze kombinovat s DP/TP MLA vrstvy. EP = DP * TP. Například na 16 strojích znamená EP128 DP32 TP4, že rozdělení řízených expertů je na 128 GPU, s každými 4 GPU tvořícími DP skupinu, což je celkově 32 nezávislých DP skupin.


Jednou uzel vs Více uzlů

671 miliard parametrů DeepSeek přesahuje kapacitu paměti jediného 8-GPU H100 stroje (80 GB * 8), ale jeden 8-GPU H200 stroj může plně pojmout celý model (141 GB * 8). Použitím konfigurace EP8 DP8 TP1 model využívá přibližně 100 GB paměti na GPU, zanechávajíc přibližně 40 GB pro KV Cache a další střední výsledky. Jeden token zabírá 70 272 bajtů KV Cache. Předpokládáme, že každý požadavek má 5 000 tokenů, každý GPU se může vejít zhruba na 100 požadavků.

Chtěli jsme pochopit rozdíly v výkonu mezi nasazeními na jednom uzlu a více uzlech pod různými konfiguracemi. Použili jsme jeden H200 stroj pro nasazení na jednom uzlu a až 16 H100 strojů pro nasazení na více uzlech. Pro každé nasazovací prostředí jsme použili kombinace TP 1, 2, 4, 8 a velikostí dávky na GPU 1, 2, 4, 8, 16, 32, 64, 128. Předpokládali jsme, že každý požadavek má délku KV Cache 5 000 tokenů. Předpokládali jsme také, že Speculativní Predikce Multi-Tokenů (MTP) předpovídá 1 další token (tj. délka dotazu každého požadavku je 2) a konzervativně předpokládali přijímací sazbu 60 %. Následující figura ukazuje propustnost a rychlost výstupu pro různé konfigurace.

Horizontální osa představuje rychlost výstupu na požadavek v tokeny/s. Vertikální osa využívá logaritmickou škálu k zobrazení propustnosti na stroj v tokeny/s. Označili jsme Pareto Frontier pro každou konfiguraci EP různými barevnými čarami.

Ve scénářích s extrémně vysokými požadavky na rychlost výstupu může použití nasazení na jednom uzlu EP8 DP1 TP8 s velikostí dávky 1 dosáhnout rychlosti výstupu přesahující 100 tokenů/s, ale propustnost je extrémně nízká, odpovídající rychlosti výstupu. V tomto scénáři má celá dávka pouze 2 tokeny, které lze vyslat nejvíce na 2*8=16 expertů, aktivujících celkově nejvíce 57 miliard parametrů.

V rozsahu rychlosti výstupu 80-40 tokenů/s, jak se propustnost zvyšuje, rychlost výstupu se výrazně snižuje. Naproti tomu má EP128 asi 5x vyšší propustnost než nasazení na jednom uzlu při stejné rychlosti výstupu.

Tento jev lze vysvětlit zkoumáním pozorování jak se chovají nasazení na jednom uzlu: zvýšení velikosti dávky přímo koreluje se zvýšením aktivovaných expertů. Když je velikost dávky 1, průměrný počet aktivovaných expertů na GPU je 2 * 8 / 8 = 2. Když je dávka dostatečně velká, všichni experti jsou aktivováni, což znamená, že každý GPU aktivuje 256 / 8 = 32 expertů. Aktivování více expertů znamená, že GPU musí číst více parametrů z paměti, což významně zvyšuje tlak na paměťovou šířku pásma. Vzhledem k tomu, že fáze dekódování modelů velkých jazyků je již zavřená kvůli paměťové šířce pásma než výkonu výpočtů, zvýšení velikosti dávky při nasazení na jednom uzlu výrazně snižuje rychlost výstupu.

Porovnání čtyř konfigurací nasazení na více uzlech (EP16, EP32, EP64 a EP128) odhaluje, že vyšší hodnoty EP posouvají Pareto Frontier směrem k souběžným zlepšením propustnosti a rychlosti výstupu.

Použití vyššího čísla EP znamená, že každý GPU je přidružen k menšímu počtu expertů. Například EP128 znamená, že každý GPU je zodpovědný za 256 / 128 = 2 expertů, takže tlak na paměťovou šířku pásma je významně snížen. Jinými slovy, použitím většího čísla EP efektivně získáváme více paměťové šířky pásma. Když na GPU je menší než 64, zvýšení velikosti dávky významně neovlivňuje rychlost expertních výpočtů, protože zvýšení počtu vstupů významně nezvyšuje tlak na paměťovou šířku pásma. Proto pozorujeme, že když používáme EP128, zvýšení velikosti dávky neovlivňuje rychlost výstupu tak výrazně.

Zajímavé je, že u větších velikostí dávek (64 požadavků na GPU) jsme pozorovali nový jev: propustnost nasazení na jednom uzlu je mírně vyšší než nasazení na více uzlech. Částečně důvodem je to, že intra-node NVLink má vyšší šířku pásma než inter-node InfiniBand. Další část je kvůli omezením v naší implementaci. Tento jev budeme později podrobněji analyzovat.

Vzhledem k limitům paměťové kapacity nemůže konfigurace EP8 DP8 TP1 dosáhnout velikosti dávky 128 na GPU, takže nasazení na více uzlech je stále lepší volbou v scénářích, které sledují vyšší propustnost.


Překrývání výpočtů a komunikace

Jak bylo stručně uvedeno výše ohledně Expertní paralelizace, GPU jsou nečinné během komunikace s MoE vrstvou. Aby se snížila nevyrovnanost a snížila se latence, je třeba najít úkoly výpočtů neovlivněné daty, které by vyplnily tento nečinný čas.

Horní část výše uvedené figure ukazuje tok výpočtů jedné vrstvy. MoE výpočty závisí na odesílání Dispatch a výpočty další vrstvy závisí na výsledku Combine.

Umístíme sdílený expert na každý GPU. Tímto způsobem výpočty sdíleného experta nevyžadují AllToAll komunikaci. Proto můžeme provést výpočty sdíleného experta okamžitě po dispatch send, pak čekat, dokud se inzerý přijímání dispatch neukončí. Nazýváme tuto metodu překrývání "Dispatch Overlap".

Dispatch Overlap poskytuje přímou implementaci a širokou aplikovatelnost. Tato technika skryje čas výpočtů sdíleného experta napříč všemi EP velikostmi a velikostmi dávek.

Abychom dále zvýšili překrývání výpočtů a komunikace, použili jsme minibatch uvedené v technické zprávě DeepSeek k přerušení závislosti na datech. Jak je ukázáno v dolní části figure, rozdělili jsme výpočty jedné Transformer Layers do 5 fází:

  • Fáze 1: InputNorm, QKVProj, AppendKV, BMM

  • Fáze 2: BMM, Attn, OProj, PostNorm, Gate

  • Fáze 3: Odeslání Dispatch, Sdílený expert

  • Fáze 4: Inzerce zpracování Dispatch, MoE, Combine odesílání

  • Fáze 5: Zpracování Combine

V prvních 3 hustých transformátorských vrstvách používáme celou dávku. V následujících 58 MoE transplantátorských vrstvách rovnoměrně rozdělíme dávku na dvě mikro dávky. Dvě mikro dávky se provádí střídavě, s offsetem o 3 fáze. Protože mezi těmito dvěma mikrodávkami neexistuje závislost na datech, můžeme po dispatch send a po combine send přepnout na výpočty další mikro dávky.


Přehled o latenci

Dále srovnáme efekty překrývání skrze experiment, dále porovnáme rozdíly v výkonu mezi nasazením na jednom uzlu EP8 a nasazením na více uzlech EP128. Aby bylo srovnání snadné, použili jsme následující experiment GPU H100. Použili jsme TP1, velikost dávky 128 na GPU, délku dotazu 2 na požadavek a délku KV Cache 5000.

Horní obrázek ukazuje celkový čas strávený na jedné MoE Transformer Layer a procentuální část latence různých typů jader. Kromě dispatch, combine a groupGEMM by měl být čas provádění u jiných jader stejný v sériích EP8, EP128 NoOverlap a EP128 DispatchOverlap, protože velikost dávky je stejná.

Překrývání

Porovnáme nejprve efekty tří metod překrývání. NoOverlap trvalo 2667 µs, DispatchOverlap trvalo 2651 µs, úspora 16 µs nebo jen 0,6 %. MikroBatch ukázal velmi významné zlepšení, trvající 1896 µs, což je zrychlení o 29 %. Oba časy pro Dispatch a Combine byly výrazně sníženy. Dispatch kleslo z 593 µs na 367 µs a Combine z 1012 µs na 237 µs.

Všimněte si, že u jader výpočtů rozdělení dávky o velikosti 128 na dvě dávky o velikosti 64 zvyšuje celkový čas provádění výpočtů. Proto, i když čas strávený na komunikaci byl snížen o 1001 µs, celkový čas byl snížen pouze o 771 µs. V následující části budeme vysvětlovat důvod pomocí modelu Roofline.

Proto mikro dávkování ne vždy zlepší se výkon.

Následující obrázek ukazuje zlepšení výkonu mikro dávkování ve srovnání s DispatchOverlap pro velikosti dávek 4-128. Když je velikost dávky menší než 32, mikro dávkování snížilo výkon o 5%-40%. Když je velikost dávky větší než nebo rovna 32, mikro dávkování může zlepšit výkon o 10%-35%.

EP8 vs EP128

Vrátíme se k předchozímu obrázku a porovnáme EP8 a EP128 Microbatch. EP8 v celku trvalo 1802 µs, což je nepatrně méně než EP128's 1896 µs. Kromě zvýšeného času provádění jader přineseného Mikrobatch, hlavní rozdíly jsou v groupGEMM použitých pro MoE výpočty a dvou komunikačních jader, Dispatch a Combine.

GroupGEMM EP8 trvalo 555 µs, zatímco GroupGEMM EP128 trvalo 270 µs, zkráceno na polovinu. To je základní výhoda nasazení na více uzlech.

Bohužel, čas strávený na komunikaci se zvýšil o 213 µs, což významně kompenzovalo výhody GroupGEMM. V samostatných výkonnostních testech našich komunikačních jader jsme zjistili, že mohou dosáhnout pouze poloviny šířky pásma Infiniband. Budeme pokračovat v optimalizaci našich komunikačních jader.

Další jádro, které výrazně zaostává, je GEMM. Microbatch zvýšil GEMM o 95 µs. GEMM analyzujeme důkladněji v sekci Roofline níže. Věříme, že současná implementace GEMM ještě nedosáhla optimálního výkonu.

Roofline

Roofline model je dobrý nástroj pro analýzu výkonu jader. Jeho horizontální osa je aritmetická intenzita, poměr FLOP k bajtům paměti I/O. Hodnota na horizontální ose lze vypočítat přímo z semantiky jádra. Vertikální osa představuje dosažený výkon, vypočítaný dělením FLOP podle benchmark latence.

Teoretická horní hranice výkonu jádra je přímo určena specifikací GPU. Vrcholový výkon FP8 H100 je 1979 TFLOP/s, co představuje vodorovnou čáru v Roofline modelu. Paměťová šířka pásma H100 je 3,35 TB/s, co představuje svah čáry procházející počátkem. Tyto dvě čáry poskytují hranice výkonu pro výpočtem omezená a pamětí omezená jádra.

Následně diskutujeme výkon jader GroupGEMM a GEMM.

GroupGEMM

GroupGEMM jádro v MoE vykonává následující výpočet: Existují g skupin celkem, i-tá skupina má m_i tokenů, vykonávající maticovou násobení [m_i, k] x [k, n] -> [m_i, n]. V testování výkonu předpokládáme, že počet tokenů v každé skupině je stejný, označený jako m_i = m. Pak je počet FLOP pro GroupGEMM 2 * g * m * k * n, a paměť IO bajty je g * (m * k + n * k + m * n).

V modelu DeepSeek-V3/R1 existuje 256 expertů a každý token je vyslán k 8 expertům ke zpracování. Předpokládáme-li velikost dávky 128, délku dotazu 2, použití konfigurace EP128 DP128, průměrný počet tokenů obdržených každým expertem (tj. m) je 128 * 2 * 8 * 128 / 256 = 1024. Podobně můžeme vypočítat m pro jiné konfigurace a velikosti dávek.

Pro testování výkonu jsme použili implementaci GroupGEMM DeepGEMM. Testovací body pokryly kombinace konfigurací EP8, EP16, EP32, EP64, EP128 s TP1 a velikostmi dávky 1-128.

Obrázek výše ukazuje Roofline model pro GroupGEMM pod různými konfiguracemi EP. Různý EP odpovídá různému počtu skupin. Na obrázku jsou téměř se vzájemně překrývající výkony čar, což naznačuje, že výkon GroupGEMM je převážně určen celkovým počtem tokenů (označen jako g * m).

Hvězdy označují datové body odpovídající velikosti dávky 128 na GPU pro každou konfiguraci EP. Porovnáním těchto bodů s hvězdičkami vidíme, že jak EP roste (a DP roste synchronně), počet tokenů na experta m roste. Na EP8 je m=128, zatímco na EP128 je m=2048.

Jak hodnota m roste, Arithmetic Intensity také roste. Ve většině konfigurací je GroupGEMM omezený paměťovou šířkou pásma, takže zvýšení m zlepšuje výkon.

GEMM

Jádro GEMM odpovídá Lineárním Projekcím v modelu, jako Q/K/V/O Projekce. Pro násobení matice [m, k] x [k, n] -> [m, n], počet FLOP je 2 * m * k * n, a paměť IO bajty jsou m * k + n * k + m * n. Můžeme také testovat latenci pro velikosti dávek 1-128.

Obrázek výše ukazuje Roofline model pro GEMM pod různými konfiguracemi EP. Vidíme, že výkon GEMM je omezený paměťovou šířkou pásma. Jak se velikost dávky zvětšuje, Arithmetic Intensity se také zvětšuje, zlepšující tedy výkon.

Microbatch

Při použití mikrobatchingu rozdělíme dávku rovnoměrně na dvě části. Z obou obrázků výše můžeme vidět, že když hodnota m se stane m/2, efektivita násobení matice klesá. Provádění tedy dvou násobení matic o velikosti m/2 trvá déle než provádění jednoho násobení matic o velikosti m.

Multi-Token Predikce

V celém tomto článku jsme předpokládali použití Multi-Token Predikce (MTP) pro spekulativní dekódování. MTP změní délku dotazu na požadavku z 1 na 2. Pro násobení matice je to ekvivalentní změně m na m * 2, čímž se zvýší efektivita násobení matic. Na druhou stranu, pokud nakreslíme Roofline model pro MLA, zjistili bychom, že zvýšení délky dotazu významně zvyšuje efektivitu jádra MLA.

Použití MTP tedy hraje důležitou roli v efektivitě modelu.

Implementace & Optimalizace

V této sekci představíme některé implementační a optimalizační detaily pro náš DeepSeek-V3/R1 model.

Kvantizace

DeepSeek-V3/R1 byl nativně trénován na FP8 s peri-block kvantizačním schématem, při kterém jsou váhy kvantizovány staticky a aktivace kvantizovány on-the-fly. Místo počítání scalingového faktoru per kanál nebo per matice staticky se scalingové faktory počítají přes vektory o 128 prvcích pro aktivace a dlaždice o 128x128 prvcích pro matice, omezené na degradaci přesnosti kvantizace.

V Perplexity se spoléháme na kombinaci CUDA a Triton jader pro podporu inference, přičemž CUDA se používá pro nejvíce výkonnostně citlivá a zřídka modifikovaná jádra (jako pozornost a GEMM), přičemž Triton implementuje širokou škálu aktivačních, normalizačních a utilitních jader. Triton nám umožnil rychle přizpůsobit jádra blokovému kvantizačnímu schématu.

Pro lineární a MoE vrstvy, mícháme Deep GEMM jádra s našimi vlastními Triton GEMM jádry, protože jsme si všimli, že pro určité rozměry matic a malé velikosti dávek Split-K poskytuje nižší latenci. Pokud nevide kvantizovaná vrstva provádí multiplikaci (M, K) x (K, N), potřebuje (M x ceil_div(K, 128)) x (ceil_div(K, 128), ceil_div(N, 128)) scalingový faktor pro blokovou kvantizaci. Pro blokovou kvantizaci, scalingové faktory pro aktivace se počítají on-the-fly, místo předkalibrované. Vzhledem k tomu, že scalingové faktory pro aktivace se agregují pouze podél dimenze K a ne podél dimenze M, jádra vyžadují pouze malé úpravy k podpoře schématu.

Aktivační funkce SiLU používaná DeepSeek-V3/R1 vyžadovala zásadní změny k podpoře CUDA grafů, blokové kvantizace a dynamicky směrovány počet tokenů. Bloková kvantizace může být problematická, protože zavádí horizontální redukce, avšak jádro již blokuje aktivace podél jejich ukryté dimenze do bloků o 1024 prvcích. V rámci jednoho blokuje byly datové tensor ke kvantizaci dále rozdělené do bloků o 128 ke zjištění největší absolutní hodnoty, přičemž Triton generoval efektivní cross-warp max redukce s minimálním přetížením.

K podpoře MoE směrování pod CUDA grafy jádra musí být vědoma směrovacích informací naznačujících počet tokenů na experta, místo plánování práce na základě rozměrů vstupního tensoru, který byl alokován k držení horní hranice počtu tokenů. Nemůžeme rozdělit problém podle rozměrů vstupního tensoru, takže spouštíme pevný počet perzistentních jader, která čtou směrovací informace k určení, kolik tokenů je osázeno a rozdělí práci na zpracování aktivací mezi ně dynamicky.

Už jsme upstreamovali některá naše jádra k projektu FlashInfer a v budoucnosti otevřeme více našeho kódu.

MLA Vrstva

Pro výpočty MLA používáme FlashInfer. FlashInfer podporuje flexibilní nastavení Page Table a velmi vysoký výkon.

Slili jsme q_a_proj a kv_a_proj do jednoho qkv_a_proj. Latence klesla z 15,4 µs + 14,8 µs = 30,2 µs na 16,7 µs.

Rozložili jsme kv_b_proj na dvě matice, k_b_proj a v_b_proj. Napsali jsme FP8 blokově kvantizovanou BMM jádro pro výpočty související s těmito dvěma maticemi.

Cuda Graf

Cuda Graf může významně snížit přetížení při spouštění jader, což je rozhodující pro výkon. Vytváříme Cuda Graf pro každou velikost dávky.

Před vývojem našeho AllToAll jádra jsme používali torch.all_to_all_single() pro AllToAll komunikaci. Tato operace vyžaduje, aby všechny GPU používaly stejnou velikost dávky. Nicméně, různé DP skupiny mohou běžet různé velikosti dávky.

K zajištění, že all_to_all_single() je kompatibilní s různými DP skupinami používajícími různé velikosti dávky, jsme nejprve použili allreduce() operaci před každým během modelu ke získání největší velikosti dávky mezi všemi DP skupinami. Pak jsme všechny DP skupiny přinutili použít tuto velikost dávky k běhu.

I když tento přístup zajišťuje, že můžeme použít Cuda Graf, má tři nevýhody. Za prvé, vyžaduje dodatečnou allreduce() operaci. Za druhé, DP skupiny s menšími velikostmi dávky jsou nuceny k vyplnění. Za třetí, činí náš implementační kód komplexním.

Po implementaci našich vlastních AllToAll jader už nevyžadujeme, aby všechny GPU používaly stejnou velikost dávky. Proto již nepotřebujeme provádět dodatečné allreduce() operace nebo vyplňovat velikosti dávky.

MoE Router

MoE router je implementován v Tritonu, vyrábějící se modifikovaného třídění odvodeného ze standardní knihovny, která také sleduje indexy tříděných prvků. Implementace je sdílená přes všech MoE modely, protože routing Mixtral je zvláštní případ DeepSeek směrování, kde Top-K skupina je stejná jako skupina všech expertů. Principy sparse jádra používají Top-K indexy a skóre přímo, zatímco dense dispatch/combine schémata spoléhající na all-to-all vyžadují, aby směrovací informace byly agregovány na expertní základě místo na základě tokenu.

Budoucí práce

V budoucí práci plánujeme další optimalizaci výkonu DeepSeek modelu.

Nejvýznamnější další optimalizací je Disaggregace Prefill. Prefill fáze a dekódovací fáze DeepSeek-V3/R1 modelu mají velmi odlišné charakteristiky výpočtů. Obě mohou používat různé optimalizační strategie a schémata nasazení.

Pro MLA vrstvu, v dekódovací fázi, používáme Absorbci matice ke snížení počtu FLOP pro výpočty MLA. V Prefill fázi, nejprve projekce latentního vektoru do K/V prostoru a následné výpočty v podobě MHA by vykonávaly lépe.

Pokud Prefill a Decode běží na stejném GPU, aby se snížil dopad Prefill na dekódovací rychlost výstupu, obvykle používáme chunked prefill k rozdělení dotazu na více chunks pro Prefill. Protože KV Cache ukládá latentní vektor, stává se obtížné převést MLA do MHA formy.

Pro MoE vrstvu, v dekódovací fázi, používáme co největší EP a DP, abychom zvýšili počet vstupních tokenů na experta, čímž se zlepšuje výkon GroupGEMM. V Prefill fázi, protože počet tokenů je již dost velký, GroupGEMM je již omezený výpočtem. Proto pro Prefill můžeme používat menší EP a DP.

Pokud Prefill a Decode běží na stejném GPU, pokud nějaká DP skupina provádí Prefill, latence MoE vrstev na všech GPU se zvýší, což významně ovlivní dekódovací rychlost výstupu.

Kromě Disaggregace Prefill, také plánujeme optimalizovat následující aspekty:

  • Výkon AllToAll: Naše jádro AllToAll aktuálně může dosáhnout pouze 1/3 šířky pásma Infiniband. Budeme pokračovat v optimalizaci tohoto jádra.

  • Spekulativní dekódování ve stylu EAGLE: V datech výše jsme předpokládali použití spekulativního dekódování k predikování 1 tokenu. EAGLE může použít stromovou strukturu k predikování více tokenů, což zlepší přijímací délku, což může výrazně zvýšit rychlost výstupu.

  • GEMM Jádro: V Roofline Modelu ukázaného dříve můžeme zjistit, že účinnost jádra GEMM je stále daleko od teoretického limitu. Budeme pokračovat v optimalizaci tohoto jádra.

  • GB200 NVL72: V nejnovějším řešení NVIDIA GB200 NVL72 je 72 Blackwell GPU propojeno přes vysokorychlostní NVLink. Pro modely s architekturou MoE je to velmi velká příležitost a výzva.

Závěr

Nasazení na více uzlech u modelů MoE DeepSeek dosáhne toho, co je obvykle nemožné s hustými LLM: současné zlepšení jak propustnosti, tak latence. Rozdělením expertů na více GPU snižujeme tlak na paměťovou šířku pásma na zařízení, umožňující rychlejší zpracování a vyšší propustnost systému. Naše experimenty ukazují konfigurace EP128 dosahující až 5x vyšší propustnosti při ekvivalentních rychlostech výstupu ve srovnání s nasazením na jednom uzlu.

Techniky překrývání výpočtů a komunikace jako mikro dávkování výrazně snižují komunikační přetížení na více uzlech, s naší implementací ukazující až 40% zrychlení. Naše vlastní jádra AllToAll pro komunikaci a optimalizované implementace jader umožnily efektivní nasazení modelu s 671 miliardami parametrů.

Jako si MoE architektury získávají popularitu pro své schopnosti, tyto strategie nasazení poskytují cenné informace pro škálování takových modelů efektivně.

Reference

Máte zájem o formování budoucnosti naší API platformy? Hledáme nové lidi.

Připojte se k naší komunitě vývojářů a buďte v obraze ohledně nových verzí, funkcí a aktualizací.

Máte zájem o formování budoucnosti naší API platformy? Hledáme nové lidi.

Připojte se k naší komunitě vývojářů a buďte v obraze ohledně nových verzí, funkcí a aktualizací.

Máte zájem o formování budoucnosti naší API platformy? Hledáme nové lidi.

Připojte se k naší komunitě vývojářů a buďte v obraze ohledně nových verzí, funkcí a aktualizací.