Alacsonyabb késleltetés és nagyobb áteresztőképesség többcsomópontos DeepSeek telepítéssel

A több-GPU-s telepítés egyszerre növeli a MoE modell sebességét és méretét

SzerzőkPerplexity Research

A legtöbb rendszerben a késleltetés és az áteresztőképesség gyakran egymásnak ellentmondó célok, amelyek kompromisszumokat igényelnek a tervezés és a telepítés során. Például a sűrű nagy nyelvi modellek esetében a kötegméret növelése javíthatja az áteresztőképességet, de növeli a késleltetést is; az egyetlen gépen belüli tenzor-paralelizmus növelése csökkentheti a késleltetést, de csökkenti a replikák számát, ami alacsonyabb áteresztőképességhez vezet.

Az olyan MoE (Mixture of Experts) modellek, mint a DeepSeek-V3/R1, a közelmúltban kiváló modellképességeket és operatív hatékonyságot mutattak be. Például a DeepSeek-V3/R1 modell összesen 671B paraméterrel rendelkezik, de a következtetés (inference) során minden token csak 37B paramétert használ. Ez a modellarchitektúra egyszerre jelent kihívásokat és lehetőségeket a következtetési rendszerek számára.

Ez a cikk bemutatja, hogy a hagyományos rendszerekkel ellentétben az olyan MoE modellek, mint a DeepSeek-V3/R1, a legtöbb forgatókönyvben képesek egyszerre magasabb áteresztőképességet és alacsonyabb késleltetést elérni több GPU használatakor a csomópontok közötti (multi-node) telepítések során.

Telepítési architektúrák

Egyetlen csomópontos telepítés NVLinken, ahol a figyelem és a szakértői számítások elosztva futnak a GPU-k között.
Több csomópontos telepítés InfiniBanden, ahol a GPU-csoportok a csomópontokon belül és a csomópontok között is össze vannak kötve.

A modell kis szakértőinek nagy száma miatt a telepítéseket több eszközön kell elosztani. Megfontoltuk az egynomás (single-node) telepítéseket egyetlen, 8 db H200 GPU-val rendelkező csomóponton, valamint a többcsomópontos (multi-node) telepítéseket 8 db H100 GPU-val.

Mindkét telepítési architektúra adatinformatikai párhuzamosságot (Data Parallelism) alkalmaz, amelyet a saját fejlesztésű kérésütemezőnk koordinál. Az adatpárhuzamosság megvalósítása több következtetési motor (inference engine) példány elindítását foglalja magában, amelyek mindegyike függetlenül működik a kérések kiszolgálásáért és fenntartásáért. A kérésütemező, amely a GRPC-n keresztül lép kapcsolatba a motorral, felelős a kérések lehetőség szerinti legegyenletesebb elosztásáért, miközben elősegíti a KV-újrafelhasználást is, és a részben egyező előtaggal rendelkező kéréseket a gyorsítótárat tartalmazó szerverekre küldi. A motorpéldányok nem terjednek ki több csomópontra. Opcionálisan tenzor-paralelizmust használhatnak a figyelem (attention) több eszközön történő shardolásához. A példányok NVLinken keresztül (egycsomópontos eset) vagy InfiniBand révén (többcsomópontos eset) kapcsolódnak egymáshoz, elosztva és összegyűjtve a szakértőket.

Az egycsomópontos telepítési konfiguráció kiváló késleltetést biztosít kis kötegméretek mellett; a teljesítmény azonban gyorsan romlik fokozott terhelési feltételek mellett.

A kiszolgálómotor telepítéséhez csomópontonként egy podot indítunk el, amely több motorpéldányt fogad. A PyTorch felelős elosztott kommunikáció beállításáért és az NVSHMEM inicializálás tárgyalásáért. A kommunikációhoz egy korábbi blogbejegyzésben leírt egyedi CUDA-kernelekre támaszkodunk. A két telepítés megvalósítása gyakorlatilag azonos, a modell kiválasztja a megfelelő kerneleket a szakértői párhuzamosságot megvalósító szövet alapján.

Párhuzamosítási technikák

Mielőtt belevetnénk magunkat a teljesítmény-összehasonlításokba, alapvetően fontos megérteni azokat a kulcsfontosságú párhuzamossági stratégiákat, amelyek lehetővé teszik az olyan hatalmas MoE modellek telepítését, mint a DeepSeek-V3/R1.

Tenzor-paralelizmus

A LLM-következtetésben a tenzor-paralelizmust (TP) általában a GPU-nkénti memóriahasználat és számítás csökkentésére használják, ezáltal csökkentve a késleltetést. Általában a Lineáris projekciókat (Linear Projections) az Attention és MLP rétegekben sor vagy oszlop dimenziók mentén shardták, és az Attention műveleteket a figyelemfej (attention head) dimenziója mentén.

A TP-vel a Llama-3 architektúrának nincsenek duplikált számításai a Lineáris projekciókra és az Attention műveletekre vonatkozóan a GPU-k között, ami ideális shardolási módszer. A DeepSeek-V3/R1 modellekben azonban a TP ezt nem tudja elérni.

A DeepSeek-V3/R1 modellek Multi-Latent Attention-t (MLA) használnak. Egy MLA réteg először egy kv_a_proj Linear Projekciót használ a látens vektor kiszámításához, majd egy másik kv_b_proj Linear Projekciót használ, hogy azt az egyes figyelemfejek terébe (space) alakítsa át. Mivel az összes figyelemfej ugyanazt a látens vektort osztja meg, a TP nem tudja shardolni a látens vektort, így az összes TP Ranknek replikálnia kell a kv_a_proj és kv_b_proj paramétereit és számításait. Hasonlóképpen, mivel az MLA a látens vektort a KV Cache-ben tárolja, minden TP Rank a KV Cache azonos másolatát tárolja.

Az MLA-beli némi duplikáció ellenére a tenzor-paralelizmus továbbra is részlegesen csökkenti a számítási igényeket, így értékes a magas kimeneti sebességet igénylő forgatókönyvek számára.

Szakértői párhuzamosság

A DeepSeek-V3/R1 modellek az MLP rétegeket MoE rétegekkel váltják fel. Egy MoE réteg 256 útvonalas (routed) szakértővel és egy megosztott szakértővel rendelkezik. Minden tokent 8 különböző útvonalas szakértőhöz küldenek számítás céljából, és az eredményeket súlyozott összegzéssel összesítik. Minden token a megosztott szakértőben is kiszámításra kerül, és az eredmény hozzáadódik az útvonalas szakértőktől kapott eredményhez.

A szakértői párhuzamosság (EP) a MoE rétegek tipikus shardolási megközelítéseként szolgál, ahol minden GPU 256 / EP útvonalas szakértőt kezel, miközben fenntartja a megosztott szakértő egy másolatát. A TP-hez képest az EP előnye, hogy több GPU között tudja elosztani a számítást, csökkentve a GPU-nkénti számítási és memóriahasználatot.

A szakértői számítás elvégzése előtt az összes GPU-nak el kell végeznie egy AllToAll kommunikációt, hogy a tokeneket elküldje arra a GPU-ra, ahol a megfelelő szakértők találhatók; a szakértői számítás után egy másik AllToAll kommunikációra van szükség a különböző GPU-król származó számítási eredmények összegyűjtéséhez és a súlyozott összegzés elvégzéséhez. Ezen két AllToAll kommunikációs kernel – a Dispatch és a Combine – egy optimalizált változatát valósítottuk meg az NVSHMEM használatával. Korábbi blogbejegyzésünkben részleteztük a megvalósítást, és kerneleink nyílt forrásúként elérhetők a GitHubon.

Adatpárhuzamosság

Az EP-vel a MoE számítást 128 vagy akár több GPU között is eloszthatjuk. Az MLA számítás azonban nem osztható fel az EP-vel. Ezen aponton bevezethetjük az adatpárhuzamosságot (DP). Minden DP csoport rendelkezik az MLA réteg teljes másolatával. Minden DP csoport különböző bemeneteket fogad, és függetlenül végzi el az MLA réteg számítását.

Az MLA réteg DP-je és TP-je kombinálható úgy, hogy egy DP csoport több TP Rankre oszlik fel. A MoE réteg EP-je kombinálható az MLA réteg DP/TP-jével. EP = DP * TP. Például 16 gépen az EP128 DP32 TP4 azt jelenti, hogy az útvonalas szakértőket 128 GPU között osztják el, minden 4 GPU egy DP csoportot alkot, összesen 32 független DP csoportot hozva létre.

Egycsomópontos vs. többcsomópontos

A DeepSeek 671B paramétere meghaladja egyetlen 8-GPU-s H100 gép memóriakapacitását (80 GB * 8), de egyetlen 8-GPU-s H200 gép teljes egészében befogadja a teljes modellt (141 GB * 8). Az EP8 DP8 TP1 konfigurációt használva a modell GPU-nként körülbelül 100 GB memóriát használ, így körülbelül 40 GB marad a KV Cache és más köztes eredmények számára. Egy token 70 272 bájtot foglal el a KV Cache-ben. Feltételezve, hogy minden kérés 5000 tokent tartalmaz, minden GPU hozzávetőleg 100 kérést tud befogadni.

Meg akartuk érteni a teljesítménybeli különbségeket az egycsomópontos és a többcsomópontos telepítések között különböző konfigurációk mellett. Egy H200 gépet használtunk az egycsomópontos telepítéshez, és legfeljebb 16 H100 gépet a többcsomópontos telepítésekhez. Minden telepítési környezethez a TP 1, 2, 4, 8 kombinációit és a GPU-nkénti 1, 2, 4, 8, 16, 32, 64, 128 kötegméreteket használtuk. Feltételeztük, hogy minden kérés KV Cache hossza 5000 token. Feltételeztük továbbá, hogy a Multi-Token Prediction (MTP) 1 további tokent jelez előre (azaz az egyes kérések lekérdezési hossza 2), és konzervatív módon 60%-os elfogadási aránnyal számoltunk. Az alábbi ábra a különböző konfigurációk áteresztőképességét és kimeneti sebességét mutatja.

Késleltetés–átbocsátás Pareto-határgörbék különböző szakértői párhuzamos konfigurációkhoz.

A vízszintes tengely a kérésenkénti kimeneti sebességet jelöli token/s-ban. A függőleges tengely logaritmikus skálát használ a gépenkénti áteresztőképesség megjelenítésére token/s-ban. A Pareto-határt minden EP-konfigurációhoz különböző színű vonalekkel jelöltük.

A rendkívül magas kimeneti sebességet igénylő forgatókönyvekben az egynomás EP8 DP1 TP8 használata 1-es kötegmérettel 100 token/s-ot meghaladó kimeneti sebességet érhet el, de az áteresztőképesség rendkívül alacsony, megegyezik a kimeneti sebességgel. Ebben a forgatókönyvben a teljes köteg mindössze 2 tokent tartalmaz, amelyek legfeljebb 2*8=16 szakértőhöz küldhetők ki, összesen legfeljebb 57B paramétert aktiválva.

A 80-40 token/s kimeneti sebességtartományban az áteresztőképesség növekedésével a kimeneti sebesség jelentősen csökken. Ezzel szemben az EP128 körülbelül 5-ször magasabb áteresztőképességgel rendelkezik, mint az egycsomópontos telepítés azonos kimeneti sebesség mellett.

Ez a jelenség az egycsomópontos telepítések viselkedésének vizsgálatával magyarázható: a kötegméret növelése közvetlenül összefügg az aktivált szakértők számának növekedésével. Ha a kötegméret 1, az aktivált szakértők átlagos száma GPU-nként 2 * 8 / 8 = 2. Ha a köteg elég nagy, az összes szakértő aktiválódik, ami azt jelenti, hogy minden GPU 256 / 8 = 32 szakértőt aktivál. Több szakértő aktiválása azt jelenti, hogy a GPU-nak több paramétert kell beolvasnia a memóriából, ami jelentősen növeli a memóriasávszélességre nehezedő nyomást. Mivel a nagy nyelvi modellek dekódolási fázisát már a memóriasávszélesség, nem pedig a számítási teljesítmény szűkíti, a kötegméret növelése az egycsomópontos telepítésben jelentősen csökkenti a kimeneti sebességet.

A négy többcsomópontos telepítési konfiguráció (EP16, EP32, EP64 és EP128) összehasonlítása azt mutatja, hogy a magasabb EP-értékek az áteresztőképesség és a kimeneti sebesség egyidejű javulása felé tolják el a Pareto-határt.

A magasabb EP-szám használata azt jelenti, hogy minden GPU-hoz kevesebb szakértő van rendelve. Például az EP128 azt jelenti, hogy minden GPU 256 / 128 = 2 szakértőért felelős, így a memóriasávszélesség nyomása jelentősen csökken. Más szóval, egy nagyobb EP-szám használatával hatékonyan több memóriasávszélességre teszünk szert. Ha a GPU-nkénti kötegméret kisebb, mint 64, a kötegméret növelése nem befolyásolja jelentősen a szakértői számítás sebességét, mivel a bemenetek számának növelése nem növeli jelentősen a memóriasávszélességre nehezedő nyomást. Ezért azt tapasztaljuk, hogy az EP128 használatakor a kötegméret növelése nem befolyásolja annyira jelentősen a kimeneti sebességet.

Érdekes módon nagyobb kötegméreteknél (GPU-nként 64 kérés) új jelenséget figyeltünk meg: az egycsomópontos telepítés áteresztőképessége valamivel magasabb, mint a többcsomópontosé. Ennek részben az az oka, hogy a csomóponton belüli NVLink sávszélessége magasabb, mint a csomópontok közötti InfiniBandé. Egy másik ok a megvalósításunk korlátaiban keresendő. Ezt a jelenséget később részletesebben elemezzük.

A memóriakapacitás korlátai miatt az EP8 DP8 TP1 konfiguráció nem éri el a GPU-nkénti 128-as kötegméretet, így a magasabb áteresztőképességet célzó forgatókönyvekben a többcsomópontos telepítés továbbra is jobb választás.

Számítás és kommunikáció átfedése (Overlapping)

Ahogy fentebb, a szakértői párhuzamosságnál röviden bemutattuk, a GPU-k tétlenek a MoE réteg kommunikációja során. A pazarlás csökkentése és a késleltetés csökkentése érdekében olyan adatinvariáns számítási feladatokat kell találnunk, amelyek kitöltik ezt a tétlen időt.

Számítási és kommunikációs ütemezések átfedés nélkül, küldési átfedéssel és ötszakaszos pipeline-nal.

A fenti ábra felső része az egyik réteg számítási folyamatát mutatja. A MoE számítás a Dispatch-től függ, a következő réteg számítása pedig a Combine eredményétől.

A megosztott szakértőt minden GPU-ra elhelyezzük. Így a megosztott szakértői számítás nem igényel AllToAll kommunikációt. Ezért közvetlenül a Dispatch Send után elvégezhetjük a megosztott szakértői számítást, majd megvárhatjuk a Dispatch Recv befejeződését. Ezt az átfedési sémát "Dispatch Overlap"-nak nevezzük.

A Dispatch Overlap egyszerű megvalósítást és széles körű alkalmazhatóságot kínál. Ez a technika elrejti a megosztott szakértői számítási időt az összes EP-méret és kötegméret mellett.

A számítási és kommunikációs átfedés további növelése érdekében a DeepSeek technikai jelentésében említett mikrokötegelést (micro batching) használtuk az adatfüggőség megtörésére. Ahogy az ábra alsó részén látható, az egyik Transformer réteg számítását 5 szakaszra osztottuk:

1. szakasz: InputNorm, QKVProj, AppendKV, BMM

2. szakasz: BMM, Attn, OProj, PostNorm, Gate

3. szakasz: Dispatch Send, megosztott szakértő (Shared Expert)

4. szakasz: Dispatch Recv, MoE, Combine Send

5. szakasz: Combine Recv

Az első 3 sűrű Transformer rétegben a teljes köteget használjuk. A ezt követő 58 MoE Transformer rétegben a köteget egyenlően két mikrokötegre osztjuk. A két mikroköteg felváltva hajtódik végre, 3 szakasz eltolással. Mivel e két mikroköteg között nincs adatfüggőség, a Dispatch Send után és a Combine Send után átválthatunk egy másik mikroköteg számítására.

Késleltetés lebontása (Latency Breakdown)

Következő lépésként kísérlettel hasonlítjuk össze az átfedés hatásait, valamint az EP8 egycsomópontos és az EP128 többcsomópontos telepítés teljesítménybeli különbségeit. Az összehasonlítás megkönnyítése érdekében H100 GPU-kat használtunk a következő kísérlethez. TP1-et, GPU-nkénti 128-as kötegméretet, kérésenkénti 2-es lekérdezési hosszt és 5000-es KV Cache hosszt használtunk.

A rétegszintű késleltetés kernelenként az összehasonlított szakértői párhuzamos és átfedő konfigurációk esetén.

A fenti ábra mutatja az egy MoE Transformer rétegre fordított teljes időt és a különböző típusú kernelek késleltetési arányát. A Dispatch, a Combine és a GroupGEMM kivételével a többi kernel végrehajtási idejének meg kell egyeznie az EP8, EP128 NoOverlap és EP128 DispatchOverlap sorozatokban, mivel a kötegméret azonos.

Átfedés (Overlapping)

Hasonlítsuk össze először a három átfedési módszer hatásait. A NoOverlap összesen 2667 µs-ot vett igénybe, a DispatchOverlap 2651 µs-ot, ezzel 16 µs-ot, azaz mindössze 0,6%-ot takarított meg. A MicroBatch nagyon jelentős javulást mutatott: 1896 µs-ot vett igénybe, ami 29%-os sebességnövekedést jelent. Mind a Dispatch, mind a Combine idő jelentősen csökkent. A Dispatch 593 µs-ról 367 µs-ra, a Combine pedig 1012 µs-ról 237 µs-ra csökkent.

Megjegyzendő, hogy a számítási kerneleknél egy 128-as méretű köteg két 64-es méretű kötegre való felosztása növeli a teljes végrehajtási időt. Ezért bár a kommunikációra fordított idő 1001 µs-mal csökkent, a teljes idő csak 771 µs-mal csökkent. Az okot a Roofline modell segítségével a következő szakaszban ismertetjük.

Ennek köszönhetően a mikrokötegelés nem mindig javítja a teljesítményt.

A kimeneti sebesség és a csomópontonkénti átviteli teljesítmény változásai mikro-batch-elés mellett, a GPU-nkénti batchméret függvényében ábrázolva.

A fenti ábra mutatja a Microbatch teljesítménynövekedését a DispatchOverlaphez képest 4–128-as kötegméretek esetén. Ha a kötegméret kisebb, mint 32, a Microbatch 5%-40%-kal csökkenti a teljesítményt. Ha a kötegméret nagyobb vagy egyenlő, mint 32, a Microbatch 10%-35%-kal javíthatja a teljesítményt.

EP8 vs. EP128

Térjünk vissza az előző ábrához, és hasonlítsuk össze az EP8-at és az EP128 Microbatch-et. Az EP8 összesen 1802 µs-ot vett igénybe, ami valamivel kevesebb, mint az EP128 1896 µs-a. A fenti Microbatch által hozott növekedett kernel-végrehajtási időn kívül a fő különbségek a MoE számításhoz használt GroupGEMM-ben, valamint a két kommunikációs kernelben, a Dispatch-ben és a Combine-ban rejlenek.

Az EP8 GroupGEMM-je 555 µs-ot vett igénybe, míg az EP128 GroupGEMM-je 270 µs-ot, ami a felére csökkent. Ez a többcsomópontos telepítés alapvető előnye.

Sajnos a kommunikációra fordított idő 213 µs-mal nőtt, ami nagymértékben ellensúlyozta a GroupGEMM előnyét. Kommunikációs kerneleink különálló teljesítménytesztjei során azt találtuk, hogy azok csak az InfiniBand sávszélesség felét képesek elérni. Továbbra is optimalizálni fogjuk kommunikációs kerneleinket.

Egy másik kernel, amely jelentősen lemarad, a GEMM. A Microbatch 95 µs-mal növelte a GEMM-et. A GEMM-et részletesebben az alábbi Roofline szakaszban elemezzük. Úgy véljük, hogy a jelenlegi GEMM megvalósítás még nem érte el az optimális teljesítményt.

Roofline

A Roofline modell kiváló eszköz a kernel teljesítményének elemzésére. Vízszintes tengelye az aritmetikai intenzitás (Arithmetic Intensity), a FLOP és a memória I/O bájtok aránya. A vízszintes tengely értéke közvetlenül kiszámítható a kernel szemantikájából. A függőleges tengely az elért teljesítményt jelöli, amelyet úgy számítanak ki, hogy a FLOP-ot elosztják a benchmark késleltetésével.

A kernel teljesítményének elméleti felső határát közvetlenül a GPU specifikációi határozzák meg. A H100 FP8 csúcsteljesítménye 1979 TFLOP/s, amelyet a Roofline modellben vízszintes vonal jelöl. A H100 memóriasávszélessége 3,35 TB/s, amelyet az origón áthaladó vonal meredeksége jelöl. A két vonal adja meg a számítás-köteles (compute-bound) és memória-köteles (memory-bound) kernelek teljesítményhatárait.

Az alábbiakban a GroupGEMM és a GEMM kernelek teljesítményét tárgyaljuk.

GroupGEMM

A MoE-ben lévő GroupGEMM kernel a következő számítást végzi el: Összesen g csoport van, az i-edik csoportnak m_i tokenje van, és [m_i, k] x [k, n] -> [m_i, n] mátrixszorzást hajt végre. A teljesítménytesztelés során feltételezzük, hogy az egyes csoportokban lévő tokenek száma azonos, jelölése m_i = m. Ekkor a GroupGEMM FLOP-száma 2 * g * m * k * n, és a memória I/O bájtok száma g * (m * k + n * k + m * n).

A DeepSeek-V3/R1 modellben 256 szakértő van, és minden tokent 8 szakértőhöz küldenek számítás céljából. 128-as kötegméretet, 2-es lekérdezési hosszat és az EP128 DP128 konfigurációt feltételezve az egyes szakértők által kapott tokenek átlagos száma (azaz m) 128 * 2 * 8 * 128 / 256 = 1024. Hasonlóképpen kiszámíthatjuk az m értéket más konfigurációkhoz és kötegméretekhez is.

A teljesítményteszteléshez a DeepGEMM GroupGEMM megvalósítását használtuk. A tesztpontok az EP8, EP16, EP32, EP64, EP128 konfigurációk kombinációit fedték le TP1-gyel és 1–128 közötti kötegméretekkel.

GroupGEMM teljesítmény a számítási és memóriasávszélesség-roofline-okhoz viszonyítva.

A fenti ábra a GroupGEMM Roofline modelljét mutatja különböző EP konfigurációk alatt. A különböző EP különböző számú csoportnak felel meg. Az ábra szinte átfedésben lévő teljesítményvonalakat mutat, ami azt jelzi, hogy a GroupGEMM teljesítményét elsősorban a tokenek teljes száma (g * m-ként jelölve) határozza meg.

A csillagok jelölik az egyes EP-konfigurációk GPU-nkénti 128-as kötegméretének megfelelő adatpontokat. Ezen csillagozott adatpontokat összehasonlítva láthatjuk, hogy az EP növekedésével (és a DP szinkron növekedésével) a szakértőnkénti tokenek száma (m) is nő. EP8-nál m=128, míg EP128-nál m=2048.

Ahogy m növekszik, az aritmetikai intenzitás is nő. A legtöbb konfigurációban a GroupGEMM-et a memóriasávszélesség korlátozza, így az m növelése javítja a teljesítményt.

GEMM

A GEMM kernel a modell Linear Projekcióinak felel meg, mint például a Q/K/V/O Projekció. [m, k] x [k, n] -> [m, n] mátrixszorzás esetén a FLOP-szám 2 * m * k * n, és a memória I/O bájtok száma m * k + n * k + m * n. Tesztelhetjük az 1–128 kötegméretek késleltetését is.

GEMM teljesítmény a számítási és memóriasávszélesség-roofline-okhoz viszonyítva.

A fenti ábra a GEMM Roofline modelljét mutatja különböző EP konfigurációk alatt. Láthatjuk, hogy a GEMM teljesítményét a memóriasávszélesség korlátozza. A kötegméret növekedésével az aritmetikai intenzitás is nő, ezáltal javítva a teljesítményt.

Mikroköteg (Microbatch)

Mikrokötegelés használatakor a köteget egyenlően két részre osztjuk. A fenti két ábrából láthatjuk, hogy amikor az m értéke m/2-re változik, a mátrixszorzás hatékonysága csökken. Ezért két m/2 méretű mátrixszorzás végrehajtása longer tart, mint egyetlen m méretű mátrixszorzás végrehajtása.

Multi-Token Prediction

A cikk során feltételeztük a Multi-Token Prediction (MTP) használatát a spekulatív dekódoláshoz. Az MTP a kérésenkénti lekérdezési hosszt 1-ről 2-re változtatja. Mátrixszorzás szempontjából ez egyenértékű azzal, hogy az m-et m * 2-re változtatjuk, ezáltal növelve a mátrixszorzás hatékonyságát. Másrészt, ha megrajzolnánk az MLA Roofline modelljét, azt találnánk, hogy a lekérdezési hossz növelése jelentősen növeli az MLA kernel hatékonyságát.

Ezért az MTP használata fontos szerepet játszik a modell hatékonyságában.

Megvalósítás és optimalizálások

Ebben a szakaszban bemutatjuk a DeepSeek-V3/R1 modellünk néhány megvalósítási és optimalizációs részletét.

Kvantálás (Quantization)

A DeepSeek-V3/R1 natív módon FP8-on lett betanítva, blokkonkénti kvantálási sémát használva, a súlyok statikusan, az aktiválások pedig menet közben (on-the-fly) kvantálódnak. Ahelyett, hogy csatornánkénti vagy mátrixonkénti skálázási tényezőt számítanának ki statikusan, a skálázási tényezők 128 elemes vektorokon keresztül kerülnek kiszámításra az aktiválásokhoz, és 128x128 elemes csempék (tiles) mentén a mátrixokhoz, ezzel korlátozva a kvantálás miatti pontosságromlást.

A Perplexitynél a CUDA- és Triton-kernelek keverékére támaszkodunk a következtetés támogatásához; a CUDA-t a legteljesítményérzékenyebb és legritkábban módosított kernelekhez (például attention és GEMM) használjuk, míg a Triton a aktiválási, normalizálási és segédkernelek széles skáláját valósítja meg. A Triton lehetővé tette számunkra, hogy gyorsan hozzáigazítsuk a kerneleket a blokkkvantálási sémához.

A lineáris és MoE rétegek esetében a Deep GEMM kerneleket saját Triton GEMM kernejeinkkel keverjük, mivel azt tapasztaltuk, hogy bizonyos mátrixdimenziók és alacsony kötegméretek esetén a Split-K alacsonyabb késleltetést biztosít. Ha a nem kvantált réteg (M, K) x (K, N) szorzást hajt végre, akkor (M x ceil_div(K, 128)) x (ceil_div(K, 128), ceil_div(N, 128)) skálázási tényezőre van szüksége a blokkkvantáláshoz. A blokkkvantálás esetében az aktiválások skálázási tényezői menet közben kerülnek kiszámításra ahelyett, hogy előre kalibrálnák őket. Mivel az aktiválási skálázási tényezők csak a K és nem az M dimenzió mentén aggregálódnak, a kerneleknek csak enyhe módosításokra van szükségük a séma támogatásához.

Batchelt SiLU- és szorzási számítás, amely a szakértői bemeneti tenzorokat, kimeneti tenzorokat és skálázási tényezőket mutatja.

A DeepSeek-V3/R1 által használt SiLU aktiválási függvény jelentős változtatásokat igényelt a CUDA gráfok, a blokkkvantálás és a dinamikusan útvonalas tokenszámok támogatásához. A blokkkvantálás problémás lehet, mivel vízszintes redukciókat vezet be, azonban a kernel már 1024 elemű blokkokra tördelte az aktiválásokat a rejtett dimenziójuk mentén. Egy blokkon belül a kvantálandó tenzor tovább tördelődött 128-as blokkokra a legnagyobb abszolút érték kiszámításához, így a Triton hatékony kereszt-warp (cross-warp) max-redukciókat generált, minimális többletterhelést (overhead) adva hozzá.

A MoE útvonalválasztás CUDA gráfok alatti támogatásához a kerneleknek ismerniük kell a tokenszámot jelző útvonalválasztási információkat ahelyett, hogy a feladatot a tokenszámok felső határának tárolására lefoglalt pufferek mérete alapján ütemeznék. Nem oszthatjuk fel a problémát a bemeneti tenzor dimenziói alapján, ezért rögzített számú perzisztens kernelt indítunk el, amelyek beolvassák az útvonalválasztási információkat annak meghatározására, hogy hány token van kitöltve, és dinamikusan megosztják közöttük az aktiválások feldolgozási feladatát.

Néhány kernelünket már feltöltöttük a FlashInfer projektbe, és a jövőben még több kódunkat tesszük nyílt forrásúvá.

MLA réteg

A FlashInfer-t használjuk az MLA számításhoz. A FlashInfer rugalmas Page Table beállításokat és rendkívül nagy teljesítményt támogat.

Egyesítettük a q_a_proj-t és a kv_a_proj-t egyetlen qkv_a_proj-má. A késleltetés 15,4 µs + 14,8 µs = 30,2 µs-ról 16,7 µs-ra csökkent.

Felbontottuk a kv_b_proj-t két mátrixra, a k_b_proj-ra és a v_b_proj-ra. Írtunk egy FP8 blokkkvantált BMM kernelt az e két mátrixhoz kapcsolódó számításokhoz.

Cuda gráf (Cuda Graph)

A Cuda Graph jelentősen csökkentheti a kernelindítási többletterhelést, ami kulcsfontosságú a teljesítmény szempontjából. Minden kötegmérethez létrehozunk egy Cuda gráfot.

AllToAll kernelünk fejlesztése előtt a torch.all_to_all_single()-t használtuk az AllToAll kommunikációhoz. Ez a művelet megköveteli, hogy minden GPU ugyanazt a kötegméretet használja. A különböző DP csoportok azonban különböző kötegméreteket futtathatnak.

Annak biztosítására, hogy az all_to_all_single() kompatibilis legyen a különböző kötegméreteket használó különböző DP csoportokkal, először egy allreduce() műveletet használtunk minden modellfuttatás előtt, hogy megkapjuk a maximális kötegméretet az összes DP csoport közül. Ezután minden DP csoporttal ezt a kötegméretet futtattuk.

Bár ez a megközelítés biztosítja a Cuda Graph használatát, három hátránya van. Először is, egy további allreduce() műveletet igényel. Másodszor, a kisebb kötegmérettel rendelkező DP csoportok kitöltésre (paddling) kényszerülnek. Harmadszor, összetetté teszi a megvalósítási kódunkat.

Saját AllToAll kernelünk megvalósítása után már nem követeljük meg, hogy minden GPU ugyanazt a kötegméretet használja. Ezért többé nem kell további allreduce() műveleteket végeznünk, sem kitöltenünk a kötegméreteket.

MoE Router

A MoE router Tritonban van implementálva, és a standard könyvtárból származó módosított rendezésre támaszkodik, amely a rendezett elemek indexeit is nyomon követi. A megvalósítás megosztott az összes MoE modell között, mivel a Mixtral útvonalválasztás a DeepSeek útvonalak speciális esete, ahol a Top-K csoport megegyezik az összes szakértő csoportjával. A ritka kernelek közvetlenül felhasználják a Top-K indexeket és pontszámokat, míg az all-to-all-ra támasztó sűrű dispatch/combine sémák megkövetelik, hogy az útvonalválasztási információk szakértőnként, és ne tokononként legyenek aggregálva.

Jövőbeli munkák

A jövőbeli munkák során terveink szerint tovább optimalizáljuk a DeepSeek modell teljesítményét.

A legfontosabb következő optimalizáció a Prefill Disaggregation (előkitöltési szétválasztás). A DeepSeek-V3/R1 modell Prefill és Decode fázisa nagyon eltérő számítási jellemzőkkel rendelkezik. Mindkettő különböző optimalizációs stratégiákat és telepítési sémákat használhat.

Az MLA réteg esetében a Decode fázisban mátrixabszorpciót (Matrix Absorption) használunk az MLA számítás FLOP-számának csökkentésére. A Prefill fázisban jobban teljesítene, ha a látens vektort először K/V térbe vetítenénk, majd Multi-Head Attention (MHA) formában számítanánk ki.

Ha a Prefill és a Decode ugyanazon a GPU-n fut, a Prefill Decode kimeneti sebességre gyakorolt hatásának csökkentése érdekében általában darabolt előkitöltést (chunked prefill) használunk, hogy a lekérdezést több darabra osszuk a Prefillhez. Mivel a KV Cache a látens vektort tárolja, nehézzé válik az MLA MHA formává alakítása.

A MoE réteg esetében a Decode fázisban a lehető legnagyobb EP-t és DP-t használjuk a szakértőnkénti bemeneti tokenek számának növelése érdekében, ezáltal javítva a GroupGEMM teljesítményét. A Prefill fázisban, mivel a tokenek száma már eleve elég nagy, a GroupGEMM már számítás-köteles. Ezért a Prefillhez kisebb EP-t és DP-t használhatunk.

Ha a Prefill és a Decode ugyanazon a GPU-n fut, amíg bármelyik DP csoport Prefillet hajt végre, az összes GPU-n a MoE rétegek késleltetése növekedni fog, ami jelentősen befolyásolja a Decode kimeneti sebességét.

A Prefill Disaggregation mellett a következő aspektusok optimalizálását is tervezzük:

AllToAll teljesítmény: Az AllToAll kernelünk jelenleg csak az InfiniBand sávszélesség 1/3-át képes elérni. Továbbra is optimalizálni fogjuk ezt a kernelt.

EAGLE stílusú spekulatív dekódolás: A fenti adatokban feltételeztük, hogy spekulatív dekódolást használunk 1 token előrejelzéséhez. Az EAGLE fa-struktúrát (tree structure) használhat több token előrejelzéséhez, javítva az elfogadási hosszt, ami jelentősen növelheti a kimeneti sebességet.

GEMM kernel: A korábban bemutatott Roofline modellben láthatjuk, hogy a GEMM kernel hatékonysága még messze van az elméleti határtól. Továbbra is optimalizálni fogjuk ezt a kernelt.

GB200 NVL72: Az NVIDIA legújabb GB200 NVL72 megoldásában 72 Blackwell GPU kapcsolódik egymáshoz nagy sebességű NVLinken keresztül. A MoE architektúrájú modellek számára ez nagyon nagy lehetőség és kihívás.

Következtetés

A DeepSeek MoE modellek többcsomópontos telepítése eléri azt, ami a sűrű LLM-ekkel általában lehetetlen: egyszerre javítja az áteresztőképességet és a késleltetést. A szakértők több GPU között történő elosztásával csökkentjük az eszközönkénti memóriasávszélességre nehezedő nyomást, ami gyorsabb feldolgozást és nagyobb rendszer-áteresztőképességet tesz lehetővé. Kísérleteink azt mutatják, hogy az EP128 konfigurációk akár ötször magasabb áteresztőképességet érnek el azonos kimeneti sebesség mellett az egycsomópontos telepítésekhez képest.

Az olyan számítás-kommunikáció átfedési technikák, mint a mikrokötegelés, jelentősen csökkentik a többcsomópontos kommunikációs többletterhelést, megvalósításunk akár 40%-os sebességnövekedést is mutat. Egyedi AllToAll kommunikációs kerneleink és optimalizált kernelmegvalósításaink lehetővé tették a 671B paraméteres modell hatékony telepítését.

Ahogy a MoE architektúrák képességeik miatt egyre népszerűbbé válnak, ezek a telepítési stratégiák értékes meglátásokat nyújtanak ilyen modellek hatékony skálázásához.

Hivatkozások

DeepSeek-V3 műszaki jelentés

DeepSeek-V3/R1 következtetési rendszer áttekintése

Megatron-LM: Többmilliárd paraméteres nyelvi modellek betanítása modell-paralelizmus használatával

EAGLE: A spekulatív mintavételezés megköveteli a jellembizonytalanság újragondolását

Idézet

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