मल्टी-नोड DeepSeek परिनियोजन के साथ कम विलंबता और उच्च थ्रूपुट
मल्टी-GPU परिनियोजन MoE मॉडल के प्रदर्शन को गति और पैमाने दोनों मोर्चों पर एक साथ बढ़ाता है
अधिकांश प्रणालियों में, विलंबता (latency) और थ्रूपुट अक्सर परस्पर विरोधी लक्ष्य होते हैं जिनके लिए डिज़ाइन और परिनियोजन के दौरान ट्रेड-ऑफ़ की आवश्यकता होती है। उदाहरण के लिए, सघन बड़े भाषा मॉडल में, बैच का आकार बढ़ाने से थ्रूपुट में सुधार हो सकता है लेकिन विलंबता भी बढ़ जाती है; एक ही मशीन के भीतर टेंसर समानता (tensor parallelism) बढ़ाने से विलंबता कम हो सकती है लेकिन प्रतिकृतियों की संख्या कम हो जाती है, जिससे थ्रूपुट कम हो जाता है।
DeepSeek-V3/R1 जैसे मिक्सचर ऑफ़ एक्सपर्ट्स (MoE) मॉडल ने हाल ही में उत्कृष्ट मॉडल क्षमताएं और परिचालन दक्षता प्रदर्शित की है। उदाहरण के लिए, DeepSeek-V3/R1 मॉडल में कुल 671B पैरामीटर हैं, लेकिन इंफरेंस के दौरान प्रत्येक टोकन केवल 37B पैरामीटर का उपयोग करता है। यह मॉडल आर्किटेक्चर इंफरेंस प्रणालियों के लिए चुनौतियां और अवसर दोनों प्रस्तुत करता है।
यह लेख प्रदर्शित करता है कि, पारंपरिक प्रणालियों के विपरीत, DeepSeek-V3/R1 जैसे MoE मॉडल अधिकांश परिदृश्यों में मल्टी-नोड परिनियोजन में अधिक GPU का उपयोग करने पर एक साथ उच्च थ्रूपुट और कम विलंबता प्राप्त कर सकते हैं।
परिनियोजन आर्किटेक्चर
मॉडल में छोटे विशेषज्ञों की बड़ी संख्या के कारण, परिनियोजन को कई उपकरणों में फैलाया जाना चाहिए। हमने 8xH200 GPU वाली एक एकल नोड पर सिंगल-नोड परिनियोजन और 8xH100 GPU पर मल्टी-नोड परिनियोजन दोनों पर विचार किया।
दोनों परिनियोजन आर्किटेक्चर डेटा समानता का लाभ उठाते हैं, जिसे हमारे इन-हाउस अनुरोध शेड्यूलर के माध्यम से व्यवस्थित किया जाता है। डेटा समानता कार्यान्वयन में कई इंफरेंस इंजन इंस्टेंस को लॉन्च करना शामिल है, जिनमें से प्रत्येक अनुरोधों को पूरा करने और बनाए रखने के लिए स्वतंत्र रूप से संचालित होता है। अनुरोध शेड्यूलर, जो GRPC के माध्यम से इंजन के साथ इंटरैक्ट करता है, अनुरोधों को यथासंभव समान रूप से फैलाने के लिए जिम्मेदार है, साथ ही KV पुनः उपयोग की सुविधा भी देता है, और आंशिक रूप से मेल खाने वाले प्रीफिक्स वाले अनुरोधों को उन सर्वरों पर भेजता है जिनमें कैश मौजूद है। इंजन इंस्टेंस कई नोड्स में नहीं फैलते हैं। वे वैकल्पिक रूप से कई उपकरणों में अटेंशन को शार्ड करने के लिए टेंसर समानता का उपयोग कर सकते हैं। इंस्टेंस एकल-नोड मामले में NVLink या मल्टी-नोड मामले में InfiniBand के माध्यम से आपस में जुड़े होते हैं, जो विशेषज्ञों को डिस्पैच और कलेक्ट करते हैं।
सिंगल-नोड परिनियोजन कॉन्फ़िगरेशन छोटे बैच आकारों के साथ बेहतर विलंबता प्रदान करता है; हालाँकि, बढ़े हुए लोड की स्थिति में प्रदर्शन तेजी से गिरता है।
सर्विंग इंजन को तैनात करने के लिए, हम प्रति नोड एक पॉड लॉन्च करते हैं जो कई इंजन इंस्टेंस को होस्ट करता है। PyTorch वितरित संचार स्थापित करने और NVSHMEM आरंभीकरण पर बातचीत करने के लिए जिम्मेदार है। संचार के लिए, हम पिछले ब्लॉग पोस्ट में वर्णित कस्टम CUDA कर्नल पर निर्भर हैं। दो परिनियोजन का कार्यान्वयन लगभग समान है, जिसमें मॉडल एक्सपर्ट पैरेललिज्म को लागू करने वाले फैब्रिक के आधार पर उपयोग करने के लिए सही कर्नल चुनता है।
समांतरता तकनीकें
प्रदर्शन तुलना में जाने से पहले, उन प्रमुख पैरेललाइजेशन रणनीतियों को समझना आवश्यक है जो DeepSeek-V3/R1 जैसे विशाल MoE मॉडल को तैनात करना संभव बनाती हैं।
टेंसर समानता
LLM इंफरेंस में, टेंसर समानता (TP) का उपयोग आमतौर पर प्रति GPU मेमोरी उपयोग और गणना को कम करने के लिए किया जाता है, जिससे विलंबता कम हो जाती है। आमतौर पर, हम अटेंशन और MLP परतों में Linear प्रोजेक्शन को पंक्ति या कॉलम आयामों के साथ शार्ड कर सकते हैं, और अटेंशन हेड आयाम के साथ अटेंशन संचालन को शार्ड कर सकते हैं।
TP के साथ, Llama-3 आर्किटेक्चर में GPU के बीच Linear प्रोजेक्शन और अटेंशन संचालन के लिए कोई डुप्लिकेट गणना नहीं होती है, जो एक आदर्श शार्डिंग विधि है। हालाँकि, DeepSeek-V3/R1 मॉडल में, TP इसे प्राप्त नहीं कर सकता है।
DeepSeek-V3/R1 मॉडल मल्टी-लेटेंट अटेंशन (MLA) का उपयोग करते हैं। एक MLA परत पहले लेटेंट वेक्टर की गणना करने के लिए एक Linear प्रोजेक्शन kv_a_proj का उपयोग करती है, फिर इसे प्रत्येक अटेंशन हेड के स्पेस में बदलने के लिए एक और Linear प्रोजेक्शन kv_b_proj का उपयोग करती है। चूंकि सभी अटेंशन हेड एक ही लेटेंट वेक्टर साझा करते हैं, TP लेटेंट वेक्टर को शार्ड नहीं कर सकता है, इसलिए सभी TP रैंक्स को kv_a_proj और kv_b_proj के पैरामीटर और गणना को दोहराने की आवश्यकता होती है। इसी तरह, चूंकि MLA लेटेंट वेक्टर को KV कैश में संग्रहीत करता है, प्रत्येक TP रैंक KV कैश की एक समान प्रतिलिपि संग्रहीत करती है।
MLA में कुछ दोहराव के बावजूद, टेंसर समानता अभी भी गणना की मांगों में आंशिक कमी प्रदान करती है, जो इसे उच्च आउटपुट गति की आवश्यकता वाले परिदृश्यों के लिए मूल्यवान बनाती है।
एक्सपर्ट पैरेललिज्म
DeepSeek-V3/R1 मॉडल MLP परतों को MoE परतों से बदलते हैं। एक MoE परत में 256 रूटेड एक्सपर्ट्स और एक साझा एक्सपर्ट होता है। प्रत्येक टोकन को गणना के लिए 8 अलग-अलग रूटेड एक्सपर्ट्स के पास भेजा जाता है, और परिणामों को भारित योग किया जाता है। प्रत्येक टोकन साझा एक्सपर्ट में भी गणना करता है, और परिणाम को रूटेड एक्सपर्ट्स से प्राप्त परिणाम में जोड़ा जाता है।
एक्सपर्ट पैरेललिज्म (EP) MoE परतों के लिए विशिष्ट शार्डिंग दृष्टिकोण के रूप में कार्य करता है, जिसमें प्रत्येक GPU साझा एक्सपर्ट की एक प्रति बनाए रखते हुए 256 / EP रूटेड एक्सपर्ट्स का प्रबंधन करता है। TP की तुलना में, EP का लाभ यह है कि यह अधिक GPU में गणना वितरित कर सकता है, जिससे प्रति GPU गणना और मेमोरी उपयोग कम हो जाता है।
एक्सपर्ट गणना करने से पहले, सभी GPU को टोकन को उन GPU पर भेजने के लिए AllToAll संचार करने की आवश्यकता होती है जहाँ संबंधित एक्सपर्ट्स स्थित हैं; एक्सपर्ट गणना के बाद, विभिन्न GPU से गणना परिणामों को इकट्ठा करने और भारित योग करने के लिए एक और AllToAll संचार की आवश्यकता होती है। हमने NVSHMEM का उपयोग करके इन दो AllToAll संचार कर्नलों, डिस्पैच और कम्बाइन का एक अनुकूलित संस्करण लागू किया है। हमारे पिछले ब्लॉग पोस्ट में, हमने कार्यान्वयन का विवरण दिया है, और हमारे कर्नल GitHub पर ओपन-सोर्स किए गए हैं।
डेटा समानता
EP के साथ, हम 128 या उससे अधिक GPU में MoE गणना वितरित कर सकते हैं। हालाँकि, MLA गणना को EP के साथ विभाजित नहीं किया जा सकता है। इस बिंदु पर, हम डेटा समानता (DP) पेश कर सकते हैं। प्रत्येक DP समूह में MLA परत की एक पूर्ण प्रतिलिपि होती है। प्रत्येक DP समूह अलग-अलग इनपुट स्वीकार करता है और स्वतंत्र रूप से MLA परत की गणना करता है।
MLA परत की DP और TP को जोड़ा जा सकता है, जिसमें एक DP समूह को कई TP रैंक्स में विभाजित किया जाता है। MoE परत की EP को MLA परत की DP/TP के साथ जोड़ा जा सकता है। EP = DP * TP। उदाहरण के लिए, 16 मशीनों पर, EP128 DP32 TP4 का अर्थ है रूटेड एक्सपर्ट्स को 128 GPU में वितरित करना, जिसमें प्रत्येक 4 GPU एक DP समूह बनाते हैं, कुल 32 स्वतंत्र DP समूहों के लिए।
सिंगल-नोड बनाम मल्टी-नोड
DeepSeek के 671B पैरामीटर एक एकल 8-GPU H100 मशीन (80 GB * 8) की मेमोरी क्षमता से अधिक हैं, लेकिन एक एकल 8-GPU H200 मशीन पूरे मॉडल (141 GB * 8) को पूरी तरह से समायोजित कर सकती है। EP8 DP8 TP1 कॉन्फ़िगरेशन का उपयोग करके, मॉडल प्रति GPU लगभग 100 GB मेमोरी का उपयोग करता है, जिससे KV कैश और अन्य मध्यवर्ती परिणामों के लिए लगभग 40 GB बचता है। एक टोकन 70,272 बाइट्स KV कैश लेता है। यह मानते हुए कि प्रत्येक अनुरोध में 5,000 टोकन हैं, प्रत्येक GPU लगभग 100 अनुरोधों को समायोजित कर सकता है।
हम विभिन्न कॉन्फ़िगरेशन के तहत सिंगल-नोड और मल्टी-नोड परिनियोजन के बीच प्रदर्शन अंतर को समझना चाहते थे। हमने सिंगल-नोड परिनियोजन के लिए एक H200 मशीन और मल्टी-नोड परिनियोजन के लिए 16 H100 मशीनों तक का उपयोग किया। प्रत्येक परिनियोजन वातावरण के लिए, हमने TP 1, 2, 4, 8 और प्रति GPU 1, 2, 4, 8, 16, 32, 64, 128 के बैच आकारों के संयोजनों का उपयोग किया। हमने माना कि प्रत्येक अनुरोध में 5,000 टोकन की KV कैश लंबाई थी। हमने यह भी माना कि मल्टी-टोकन प्रेडिक्शन (MTP) 1 अतिरिक्त टोकन की भविष्यवाणी करता है (अर्थात, प्रत्येक अनुरोध की क्वेरी लंबाई 2 है), और रूढ़िवादी रूप से 60% की स्वीकृति दर मानी। नीचे दिया गया चित्र विभिन्न कॉन्फ़िगरेशन के लिए थ्रूपुट और आउटपुट गति दिखाता है।
क्षैतिज अक्ष टोकन/सेकंड में प्रति अनुरोध आउटपुट गति का प्रतिनिधित्व करता है। लंबवत अक्ष टोकन/सेकंड में प्रति मशीन थ्रूपुट दिखाने के लिए लॉगरिदमिक पैमाने का उपयोग करता है। हमने विभिन्न रंगीन रेखाओं के साथ प्रत्येक EP कॉन्फ़िगरेशन के लिए परेटो फ्रंटियर को चिह्नित किया।
अत्यधिक उच्च आउटपुट गति आवश्यकताओं वाले परिदृश्यों में, 1 के बैच आकार के साथ सिंगल-नोड EP8 DP1 TP8 का उपयोग करके 100 टोकन/सेकंड से अधिक की आउटपुट गति प्राप्त की जा सकती है, लेकिन थ्रूपुट बहुत कम है, जो आउटपुट गति के बराबर है। इस परिदृश्य में, पूरे बैच में केवल 2 टोकन हैं, जिन्हें अधिकतम 2*8=16 एक्सपर्ट्स तक भेजा जा सकता है, जिससे कुल मिलाकर अधिकतम 57B पैरामीटर सक्रिय होते हैं।
80-40 टोकन/सेकंड की आउटपुट गति सीमा में, जैसे-जैसे थ्रूपुट बढ़ता है, आउटपुट गति काफी कम हो जाती है। इसके विपरीत, EP128 में समान आउटपुट गति पर सिंगल-नोड परिनियोजन की तुलना में लगभग 5 गुना अधिक थ्रूपुट होता है।
इस घटना को सिंगल-नोड परिनियोजन के व्यवहार की जांच करके समझाया जा सकता है: बैच का आकार बढ़ाने का सीधा संबंध सक्रिय एक्सपर्ट्स में वृद्धि से है। जब बैच का आकार 1 होता है, तो प्रति GPU सक्रिय एक्सपर्ट्स की औसत संख्या 2 * 8 / 8 = 2 होती है। जब बैच पर्याप्त बड़ा होता है, तो सभी एक्सपर्ट्स सक्रिय हो जाते हैं, जिसका अर्थ है कि प्रत्येक GPU 256 / 8 = 32 एक्सपर्ट्स को सक्रिय करता है। अधिक एक्सपर्ट्स को सक्रिय करने का मतलब है कि GPU को मेमोरी से अधिक पैरामीटर पढ़ने की आवश्यकता होती है, जिससे मेमोरी बैंडविड्थ पर दबाव काफी बढ़ जाता है। चूंकि बड़े भाषा मॉडल का डिकोड चरण पहले से ही गणना प्रदर्शन के बजाय मेमोरी बैंडविड्थ द्वारा बाधित है, सिंगल-नोड परिनियोजन में बैच का आकार बढ़ाने से आउटपुट गति काफी कम हो जाती है।
चार मल्टी-नोड परिनियोजन कॉन्फ़िगरेशन (EP16, EP32, EP64, और EP128) की तुलना से पता चलता है कि उच्च EP मान परेटो फ्रंटियर को थ्रूपुट और आउटपुट गति में एक साथ सुधार की ओर ले जाते हैं।
उच्च EP संख्या का उपयोग करने का अर्थ है कि प्रत्येक GPU को कम एक्सपर्ट्स आवंटित किए जाते हैं। उदाहरण के लिए, EP128 का मतलब है कि प्रत्येक GPU 256 / 128 = 2 एक्सपर्ट्स के लिए जिम्मेदार है, इसलिए मेमोरी बैंडविड्थ का दबाव काफी कम हो जाता है। दूसरे शब्दों में, बड़ी EP संख्या का उपयोग करके, हम प्रभावी रूप से अधिक मेमोरी बैंडविड्थ प्राप्त करते हैं। जब प्रति-GPU बैच का आकार 64 से कम होता है, तो बैच का आकार बढ़ाने से एक्सपर्ट गणना की गति पर महत्वपूर्ण प्रभाव नहीं पड़ता है क्योंकि इनपुट की संख्या बढ़ाने से मेमोरी बैंडविड्थ का दबाव काफी नहीं बढ़ता है। इसलिए, हम देखते हैं कि EP128 का उपयोग करते समय, बैच का आकार बढ़ाने से आउटपुट गति इतनी महत्वपूर्ण रूप से प्रभावित नहीं होती है।
दिलचस्प बात यह है कि बड़े बैच आकारों (प्रति GPU 64 अनुरोध) पर, हमने एक नई घटना देखी: सिंगल-नोड परिनियोजन थ्रूपुट मल्टी-नोड परिनियोजन की तुलना में थोड़ा अधिक है। इसका एक कारण यह है कि इंट्रा-नोड NVLink में इंटर-नोड InfiniBand की तुलना में अधिक बैंडविड्थ है। दूसरा हिस्सा हमारे कार्यान्वयन में सीमाओं के कारण है। हम बाद में इस घटना का अधिक विस्तार से विश्लेषण करेंगे।
मेमोरी क्षमता की सीमाओं के कारण, EP8 DP8 TP1 कॉन्फ़िगरेशन प्रति GPU 128 के बैच आकार तक नहीं पहुँच सकता है, इसलिए उच्च थ्रूपुट का पीछा करने वाले परिदृश्यों में मल्टी-नोड परिनियोजन अभी भी एक बेहतर विकल्प है।
गणना और संचार ओवरलैपिंग
एक्सपर्ट पैरेललिज्म के बारे में ऊपर संक्षेप में प्रस्तुत किए अनुसार, MoE परत संचार के दौरान GPU निष्क्रिय रहते हैं। बर्बादी को कम करने और विलंबता को कम करने के लिए, हमें इस निष्क्रिय समय को भरने के लिए डेटा-स्वतंत्र गणना कार्यों को खोजने की आवश्यकता है।
उपरोक्त चित्र का ऊपरी भाग एक परत के गणना प्रवाह को दिखाता है। MoE गणना डिस्पैच पर निर्भर करती है, और अगली परत की गणना कम्बाइन के परिणाम पर निर्भर करती है।
हम साझा एक्सपर्ट को प्रत्येक GPU पर रखते हैं। इस तरह, साझा एक्सपर्ट गणना के लिए AllToAll संचार की आवश्यकता नहीं होती है। इसलिए, हम डिस्पैच सेंड के तुरंत बाद साझा एक्सपर्ट गणना कर सकते हैं, फिर डिस्पैच रिसीव के पूरा होने की प्रतीक्षा कर सकते हैं। हम इस ओवरलैप योजना को "डिस्पैच ओवरलैप" कहते हैं।
डिस्पैच ओवरलैप सीधा कार्यान्वयन और व्यापक प्रयोज्यता प्रदान करता है। यह तकनीक सभी EP आकारों और बैच आकारों में साझा एक्सपर्ट गणना समय को छिपाती है।
गणना और संचार ओवरलैप को और बढ़ाने के लिए, हमने डेटा निर्भरता को तोड़ने के लिए DeepSeek तकनीकी रिपोर्ट में उल्लिखित माइक्रो बैचिंग का उपयोग किया। जैसा कि चित्र के निचले भाग में दिखाया गया है, हमने एक ट्रांसफार्मर परत की गणना को 5 चरणों में विभाजित किया:
चरण 1: InputNorm, QKVProj, AppendKV, BMM
चरण 2: BMM, Attn, OProj, PostNorm, Gate
चरण 3: डिस्पैच सेंड, साझा एक्सपर्ट
चरण 4: डिस्पैच रिसीव, MoE, कम्बाइन सेंड
चरण 5: कम्बाइन रिसीव
पहली 3 सघन ट्रांसफार्मर परतों में, हम पूरे बैच का उपयोग करते हैं। निम्नलिखित 58 MoE ट्रांसफार्मर परतों में, हम बैच को समान रूप से दो माइक्रो बैचों में विभाजित करते हैं। दो माइक्रो बैच बारी-बारी से निष्पादित होते हैं, जो 3 चरणों से ऑफसेट होते हैं। चूंकि इन दो माइक्रो बैचों के बीच कोई डेटा निर्भरता नहीं है, इसलिए हम डिस्पैच सेंड के बाद और कम्बाइन सेंड के बाद दूसरे माइक्रो बैच की गणना पर स्विच कर सकते हैं।
विलंबता विश्लेषण
अगला, हम एक प्रयोग के माध्यम से ओवरलैपिंग के प्रभावों की तुलना करते हैं, और सिंगल-नोड परिनियोजन EP8 और मल्टी-नोड परिनियोजन EP128 के बीच प्रदर्शन अंतर की तुलना करते हैं। तुलना में आसानी के लिए, हमने निम्नलिखित प्रयोग के लिए H100 GPU का उपयोग किया। हमने TP1, प्रति GPU 128 का बैच आकार, प्रति अनुरोध 2 की क्वेरी लंबाई और 5000 की KV कैश लंबाई का उपयोग किया।
उपरोक्त चित्र एक MoE ट्रांसफार्मर परत पर खर्च किए गए कुल समय और विभिन्न प्रकार के कर्नलों के विलंबता अनुपात को दिखाता है। डिस्पैच, कम्बाइन और GroupGEMM को छोड़कर, अन्य कर्नलों का निष्पादन समय EP8, EP128 नो-ओवरलैप, और EP128 डिस्पैच-ओवरलैप श्रृंखला में समान होना चाहिए क्योंकि बैच का आकार समान है।
ओवरलैपिंग
आइए पहले तीन ओवरलैपिंग विधियों के प्रभावों की तुलना करें। नो-ओवरलैप ने कुल 2667µs लिए, डिस्पैच-ओवरलैप ने 2651µs लिए, जिससे 16µs या केवल 0.6% की बचत हुई। माइक्रो-बैच ने बहुत महत्वपूर्ण सुधार दिखाया, 1896µs लिए, 29% की गति में वृद्धि। डिस्पैच और कम्बाइन दोनों समय में काफी कमी आई। डिस्पैच 593µs से घटकर 367µs हो गया, और कम्बाइन 1012µs से घटकर 237µs हो गया।
ध्यान दें कि गणना कर्नलों के लिए, 128 के आकार के बैच को 64 के दो बैचों में विभाजित करने से कुल निष्पादन समय बढ़ जाता है। इसलिए, हालांकि संचार पर खर्च किया गया समय 1001µs कम हो गया, कुल समय केवल 771µs कम हुआ। हम अगले भाग में रूफलाइन मॉडल का उपयोग करके इसका कारण समझाएंगे।
इस कारण से, माइक्रो-बैचिंग हमेशा प्रदर्शन में सुधार नहीं करती है।
उपरोक्त चित्र बैच आकार 4-128 के लिए डिस्पैच-ओवरलैप की तुलना में माइक्रो-बैच का प्रदर्शन सुधार दिखाता है। जब बैच का आकार 32 से कम होता है, तो माइक्रो-बैच प्रदर्शन को 5%-40% तक कम कर देता है। जब बैच का आकार 32 से अधिक या उसके बराबर होता है, तो माइक्रो-बैच प्रदर्शन को 10%-35% तक सुधार सकता है।
EP8 बनाम EP128
आइए पिछले चित्र पर वापस चलें और EP8 और EP128 माइक्रो-बैच की तुलना करें। EP8 ने कुल 1802µs लिए, जो EP128 के 1896µs से थोड़ा कम है। ऊपर उल्लिखित माइक्रो-बैच द्वारा लाए गए बढ़े हुए कर्नल निष्पादन समय के अलावा, मुख्य अंतर MoE गणना के लिए उपयोग किए गए GroupGEMM और दो संचार कर्नलों, डिस्पैच और कम्बाइन में हैं।
EP8 के GroupGEMM ने 555µs लिए, जबकि EP128 के GroupGEMM ने 270µs लिए, जो आधा कम हो गया। यह मल्टी-नोड परिनियोजन का मुख्य लाभ है।
दुर्भाग्य से, संचार पर खर्च किए गए समय में 213µs की वृद्धि हुई, जिसने GroupGEMM के लाभ को काफी हद तक ऑफसेट कर दिया। हमारे संचार कर्नलों के अलग-अलग प्रदर्शन परीक्षणों में, हमने पाया कि वे Infiniband बैंडविड्थ का केवल आधा ही प्राप्त कर सकते हैं। हम अपने संचार कर्नलों को अनुकूलित करना जारी रखेंगे।
एक और कर्नल जो काफी पीछे है, वह GEMM है। माइक्रो-बैच ने GEMM को 95µs तक बढ़ा दिया। हम नीचे रूफलाइन अनुभाग में GEMM का अधिक गहराई से विश्लेषण करेंगे। हमारा मानना है कि वर्तमान GEMM कार्यान्वयन ने अभी तक इष्टतम प्रदर्शन प्राप्त नहीं किया है।
रूफलाइन
रूफलाइन मॉडल कर्नल प्रदर्शन का विश्लेषण करने के लिए एक अच्छा उपकरण है। इसका क्षैतिज अक्ष अंकगणितीय तीव्रता है, जो FLOP का मेमोरी I/O बाइट्स से अनुपात है। क्षैतिज अक्ष मान की गणना सीधे कर्नल के अर्थशास्त्र से की जा सकती है। लंबवत अक्ष प्राप्त प्रदर्शन का प्रतिनिधित्व करता है, जिसकी गणना FLOP को बेंचमार्क विलंबता से विभाजित करके की जाती है।
कर्नल प्रदर्शन की सैद्धांतिक ऊपरी सीमा सीधे GPU के विनिर्देशों द्वारा निर्धारित की जाती है। H100 का FP8 चरम प्रदर्शन 1979 TFLOP/s है, जिसे रूफलाइन मॉडल में एक क्षैतिज रेखा के रूप में दर्शाया गया है। H100 की मेमोरी बैंडविड्थ 3.35 TB/s है, जिसे मूल से गुजरने वाली रेखा के ढलान के रूप में दर्शाया गया है। दो रेखाएं क्रमशः कंप्यूट-बाउंड और मेमोरी-बाउंड कर्नलों के लिए प्रदर्शन सीमाएं देती हैं।
नीचे, हम GroupGEMM और GEMM कर्नलों के प्रदर्शन पर चर्चा करते हैं।
GroupGEMM
MoE में GroupGEMM कर्नल निम्नलिखित गणना करता है: कुल मिलाकर g समूह हैं, i-th समूह में m_i टोकन हैं, जो [m_i, k] x [k, n] -> [m_i, n] का मैट्रिक्स गुणन करते हैं। प्रदर्शन परीक्षण में, हम मानते हैं कि प्रत्येक समूह में टोकन की संख्या समान है, जिसे m_i = m के रूप में दर्शाया गया है। तो GroupGEMM के लिए FLOP गणना 2 * g * m * k * n है, और मेमोरी I/O बाइट्स g * (m * k + n * k + m * n) हैं।
DeepSeek-V3/R1 मॉडल में, 256 एक्सपर्ट्स हैं, और प्रत्येक टोकन को गणना के लिए 8 एक्सपर्ट्स के पास भेजा जाता है। 128 के बैच आकार, 2 की क्वेरी लंबाई, EP128 DP128 कॉन्फ़िगरेशन का उपयोग करते हुए, प्रत्येक एक्सपर्ट द्वारा प्राप्त टोकन की औसत संख्या (अर्थात m) 128 * 2 * 8 * 128 / 256 = 1024 है। इसी तरह, हम अन्य कॉन्फ़िगरेशन और बैच आकारों के लिए m की गणना कर सकते हैं।
हमने प्रदर्शन परीक्षण के लिए DeepGEMM के GroupGEMM कार्यान्वयन का उपयोग किया। परीक्षण बिंदुओं में TP1 और 1-128 बैच आकारों के साथ EP8, EP16, EP32, EP64, EP128 कॉन्फ़िगरेशन के संयोजन शामिल थे।
उपरोक्त चित्र विभिन्न EP कॉन्फ़िगरेशन के तहत GroupGEMM के लिए रूफलाइन मॉडल दिखाता है। अलग EP समूहों की अलग संख्या के अनुरूप है। चित्र लगभग ओवरलैपिंग प्रदर्शन लाइनों को दर्शाता है, जो यह संकेत देता है कि GroupGEMM प्रदर्शन मुख्य रूप से कुल टोकन गणना (जिसे g * m के रूप में दर्शाया गया है) द्वारा निर्धारित किया जाता है।
सितारे प्रत्येक EP कॉन्फ़िगरेशन के लिए प्रति GPU 128 के बैच आकार के अनुरूप डेटा बिंदुओं को चिह्नित करते हैं। इन तारांकित डेटा बिंदुओं की तुलना करने पर, हम देख सकते हैं कि जैसे-जैसे EP बढ़ता है (और DP समकालिक रूप से बढ़ता है), प्रति एक्सपर्ट टोकन की संख्या m भी बढ़ती है। EP8 पर, m=128, जबकि EP128 पर, m=2048।
जैसे-जैसे m बढ़ता है, अंकगणितीय तीव्रता भी बढ़ती है। अधिकांश कॉन्फ़िगरेशन में, GroupGEMM मेमोरी बैंडविड्थ द्वारा सीमित होता है, इसलिए m बढ़ाने से प्रदर्शन में सुधार होता है।
GEMM
GEMM कर्नल मॉडल में Linear प्रोजेक्शन के अनुरूप है, जैसे Q/K/V/O प्रोजेक्शन। [m, k] x [k, n] -> [m, n] के मैट्रिक्स गुणन के लिए, FLOP गणना 2 * m * k * n है, और मेमोरी I/O बाइट्स m * k + n * k + m * n हैं। हम बैच आकार 1-128 के लिए भी विलंबता का परीक्षण कर सकते हैं।
उपरोक्त चित्र विभिन्न EP कॉन्फ़िगरेशन के तहत GEMM के लिए रूफलाइन मॉडल दिखाता है। हम देख सकते हैं कि GEMM प्रदर्शन मेमोरी बैंडविड्थ द्वारा सीमित है। जैसे-जैसे बैच का आकार बढ़ता है, अंकगणितीय तीव्रता भी बढ़ती है, जिससे प्रदर्शन में सुधार होता है।
माइक्रो-बैच
माइक्रो-बैचिंग का उपयोग करते समय, हम बैच को समान रूप से दो भागों में विभाजित करते हैं। उपरोक्त दो चित्रों से, हम देख सकते हैं कि जब m, m/2 बन जाता है, तो मैट्रिक्स गुणन की दक्षता कम हो जाती है। इसलिए, m/2 आकार के दो मैट्रिक्स गुणन को निष्पादित करने में m आकार के एक मैट्रिक्स गुणन को निष्पादित करने की तुलना में अधिक समय लगता है।
मल्टी-टोकन प्रेडिक्शन
इस पूरे लेख में, हमने सट्टा डिकोडिंग के लिए मल्टी-टोकन प्रेडिक्शन (MTP) के उपयोग को माना है। MTP प्रति अनुरोध क्वेरी लंबाई को 1 से बदलकर 2 कर देता है। मैट्रिक्स गुणन के लिए, यह m को m * 2 में बदलने के बराबर है, जिससे मैट्रिक्स गुणन दक्षता बढ़ती है। दूसरी ओर, यदि हम MLA के लिए रूफलाइन मॉडल तैयार करते हैं, तो हम पाएंगे कि क्वेरी लंबाई बढ़ाने से MLA कर्नल दक्षता काफी बढ़ जाती है।
इसलिए, MTP का उपयोग मॉडल दक्षता में एक महत्वपूर्ण भूमिका निभाता है।
कार्यान्वयन और अनुकूलन
इस अनुभाग में, हम अपने DeepSeek-V3/R1 मॉडल के लिए कुछ कार्यान्वयन और अनुकूलन विवरण पेश करेंगे।
क्वांटाइजेशन
DeepSeek-V3/R1 को स्वाभाविक रूप से FP8 पर प्रति-ब्लॉक क्वांटाइजेशन योजना का उपयोग करके प्रशिक्षित किया गया था, जिसमें वेट स्थिर रूप से क्वांटाइज्ड थे और एक्टिवेशन ऑन-द-फ्लाई क्वांटाइज्ड थे। प्रति चैनल या प्रति मैट्रिक्स स्थिर रूप से स्केलिंग कारक की गणना करने के बजाय, स्केलिंग कारकों की गणना एक्टिवेशन के लिए 128-तत्व वैक्टर और मैट्रिक्स के लिए 128x128 तत्व टाइलों पर की जाती है, जो क्वांटाइजेशन के कारण सटीकता में गिरावट को सीमित करता है।
Perplexity में, हम इंफरेंस का समर्थन करने के लिए CUDA और Triton कर्नलों के मिश्रण पर भरोसा करते हैं, जिसमें CUDA का उपयोग सबसे प्रदर्शन-संवेदनशील और कम संशोधित कर्नलों (जैसे अटेंशन और GEMM) के लिए किया जाता है, जबकि Triton एक्टिवेशन, सामान्यीकरण और उपयोगिता कर्नलों की एक विस्तृत श्रृंखला को लागू करता है। Triton ने हमें कर्नलों को ब्लॉक क्वांटाइजेशन योजना के अनुकूल जल्दी से ढालने की अनुमति दी।
Linear और MoE परतों के लिए, हम Deep GEMM कर्नलों को अपने स्वयं के Triton GEMM कर्नलों के साथ मिलाते हैं, क्योंकि हमने देखा है कि कुछ मैट्रिक्स आयामों और कम बैच आकारों के लिए स्प्लिट-K कम विलंबता प्रदान करता है। यदि असंबद्ध परत (M, K) x (K, N) गुणन करती है, तो उसे ब्लॉक क्वांटाइजेशन के लिए (M x ceil_div(K, 128)) x (ceil_div(K, 128), ceil_div(N, 128)) स्केलिंग कारक की आवश्यकता होती है। ब्लॉक क्वांटाइजेशन के लिए, एक्टिवेशन के लिए स्केलिंग कारकों की गणना ऑन-द-फ्लाई की जाती है, न कि पहले से कैलिब्रेट किए जाने के। चूंकि एक्टिवेशन स्केलिंग कारक केवल K आयाम के साथ एकत्रित किए जाते हैं न कि M आयाम के साथ, कर्नलों को योजना का समर्थन करने के लिए केवल मामूली बदलावों की आवश्यकता होती है।
DeepSeek-V3/R1 द्वारा उपयोग किए गए SiLU एक्टिवेशन फ़ंक्शन को CUDA ग्राफ, ब्लॉक क्वांटाइजेशन और गतिशील रूप से रूट किए गए टोकन गणनाओं का समर्थन करने के लिए पर्याप्त परिवर्तनों की आवश्यकता थी। ब्लॉक क्वांटाइजेशन समस्याग्रस्त हो सकता है क्योंकि यह क्षैतिज कटौती पेश करता है, हालाँकि कर्नल पहले से ही एक्टिवेशन को उनके छिपे हुए आयाम के साथ 1024 तत्वों के ब्लॉकों में विभाजित करता था। एक ब्लॉक के भीतर, क्वांटाइज किए जाने वाले टेंसर को सबसे बड़े पूर्ण मान की गणना करने के लिए 128 के ब्लॉकों में और विभाजित किया गया था, जिसमें Triton ने कुशल क्रॉस-वार्प अधिकतम कटौती उत्पन्न की, जिससे न्यूनतम ओवरहेड जोड़ा गया।
CUDA ग्राफ के तहत MoE रूटिंग का समर्थन करने के लिए, कर्नलों को उस रूटिंग जानकारी के बारे में पता होना चाहिए जो प्रति एक्सपर्ट टोकन की संख्या को इंगित करती है, न कि उन बफ़र्स के आकार के आधार पर काम को निर्धारित करने के बजाय जो टोकन गणनाओं की ऊपरी सीमा को पकड़ने के लिए आवंटित किए गए थे। हम इनपुट टेंसर आयामों के आधार पर समस्या को विभाजित नहीं कर सकते हैं, इसलिए हम स्थायी कर्नलों की एक निश्चित संख्या लॉन्च करते हैं जो यह निर्धारित करने के लिए रूटिंग जानकारी को पढ़ते हैं कि कितने टोकन पॉप्युलेटेड हैं और उनके बीच एक्टिवेशन को संसाधित करने के काम को गतिशील रूप से विभाजित करते हैं।
हमने पहले ही अपने कुछ कर्नलों को FlashInfer प्रोजेक्ट में अपस्ट्रीम कर दिया है और भविष्य में हम अपने और अधिक कोड को ओपन-सोर्स करेंगे।
MLA परत
हम MLA गणना के लिए FlashInfer का उपयोग करते हैं। FlashInfer लचीली पेज टेबल सेटिंग्स और अत्यधिक उच्च प्रदर्शन का समर्थन करता है।
हमने q_a_proj और kv_a_proj को एक एकल qkv_a_proj में फ़्यूज़ कर दिया। विलंबता 15.4 µs + 14.8 µs = 30.2 µs से घटकर 16.7 µs हो गई।
हमने kv_b_proj को दो मैट्रिसेस, k_b_proj और v_b_proj में विघटित कर दिया। हमने इन दो मैट्रिसेस से संबंधित गणनाओं के लिए एक FP8 ब्लॉक क्वांटाइज्ड BMM कर्नल लिखा।
Cuda ग्राफ
Cuda ग्राफ कर्नल लॉन्चिंग ओवरहेड को काफी कम कर सकता है, जो प्रदर्शन के लिए महत्वपूर्ण है। हम प्रत्येक बैच आकार के लिए एक Cuda ग्राफ बनाते हैं।
अपने AllToAll कर्नल को विकसित करने से पहले, हमने AllToAll संचार के लिए torch.all_to_all_single() का उपयोग किया। इस ऑपरेशन के लिए सभी GPU को समान बैच आकार का उपयोग करने की आवश्यकता होती है। हालाँकि, विभिन्न DP समूह अलग-अलग बैच आकारों को चला सकते हैं।
यह सुनिश्चित करने के लिए कि all_to_all_single() अलग-अलग बैच आकारों का उपयोग करने वाले विभिन्न DP समूहों के साथ संगत है, हमने पहले सभी DP समूहों के बीच अधिकतम बैच आकार प्राप्त करने के लिए प्रत्येक मॉडल रन से पहले एक allreduce() ऑपरेशन का उपयोग किया। फिर हमने सभी DP समूहों को चलने के लिए इस बैच आकार का उपयोग करवाया।
हालाँकि यह दृष्टिकोण सुनिश्चित करता है कि हम Cuda ग्राफ का उपयोग कर सकते हैं, इसके तीन नुकसान हैं। पहला, इसके लिए एक अतिरिक्त allreduce() ऑपरेशन की आवश्यकता होती है। दूसरा, छोटे बैच आकारों वाले DP समूहों को पैड करने के लिए मजबूर किया जाता है। तीसरा, यह हमारे कार्यान्वयन कोड को जटिल बनाता है।
अपना स्वयं का AllToAll कर्नल लागू करने के बाद, अब हमें सभी GPU को समान बैच आकार का उपयोग करने की आवश्यकता नहीं है। इसलिए, अब हमें अतिरिक्त allreduce() ऑपरेशन करने या बैच आकारों को पैड करने की आवश्यकता नहीं है।
MoE राउटर
MoE राउटर को Triton में लागू किया गया है, जो मानक लाइब्रेरी से प्राप्त एक संशोधित सॉर्ट पर निर्भर करता है जो सॉर्ट किए गए तत्वों के सूचकांकों का भी ट्रैक रखता है। कार्यान्वयन सभी MoE मॉडल में साझा किया जाता है, क्योंकि Mixtral रूटिंग DeepSeek रूट्स का एक विशेष मामला है जहाँ Top-K समूह सभी एक्सपर्ट्स के समूह के समान है। स्पार्स कर्नल सीधे Top-K सूचकांकों और स्कोर का उपभोग करते हैं, जबकि all-to-all पर निर्भर सघन डिस्पैच/कम्बाइन योजनाओं के लिए रूटिंग जानकारी को प्रति-टोकन आधार के बजाय प्रति-एक्सपर्ट आधार पर एकत्रित करने की आवश्यकता होती है।
भविष्य का कार्य
भविष्य के कार्य में, हम DeepSeek मॉडल के प्रदर्शन को और अधिक अनुकूलित करने की योजना बना रहे हैं।
सबसे महत्वपूर्ण अगला अनुकूलन प्रीफिल डिसएग्रीगेशन है। DeepSeek-V3/R1 मॉडल के प्रीफिल चरण और डिकोड चरण की गणना विशेषताएं बहुत अलग हैं। दोनों अलग-अलग अनुकूलन रणनीतियों और परिनियोजन योजनाओं का उपयोग कर सकते हैं।
MLA परत के लिए, डिकोड चरण में, हम MLA गणना की FLOP गणना को कम करने के लिए मैट्रिक्स एब्जॉर्प्शन का उपयोग करते हैं। प्रीफिल चरण में, पहले लेटेंट वेक्टर को K/V स्पेस में प्रोजेक्ट करना और फिर मल्टी-हेड अटेंशन (MHA) रूप में गणना करना बेहतर प्रदर्शन करेगा।
यदि प्रीफिल और डिकोड एक ही GPU पर चलते हैं, तो डिकोड आउटपुट गति पर प्रीफिल के प्रभाव को कम करने के लिए, हम आमतौर पर प्रीफिल के लिए क्वेरी को कई टुकड़ों में विभाजित करने के लिए चंक्ड प्रीफिल का उपयोग करते हैं। चूंकि KV कैश लेटेंट वेक्टर को संग्रहीत करता है, इसलिए MLA को MHA रूप में बदलना मुश्किल हो जाता है।
MoE परत के लिए, डिकोड चरण में, हम प्रति एक्सपर्ट इनपुट टोकन की संख्या बढ़ाने के लिए यथासंभव बड़े EP और DP का उपयोग करते हैं, जिससे GroupGEMM प्रदर्शन में सुधार होता है। प्रीफिल चरण में, क्योंकि टोकन की संख्या पहले से ही पर्याप्त बड़ी है, GroupGEMM पहले से ही कंप्यूट-बाउंड है। इसलिए, प्रीफिल के लिए, हम छोटे EP और DP का उपयोग कर सकते हैं।
यदि प्रीफिल और डिकोड एक ही GPU पर चलते हैं, जब तक कोई DP समूह प्रीफिल कर रहा है, सभी GPU पर MoE परतों की विलंबता बढ़ जाएगी, जो डिकोड आउटपुट गति को काफी प्रभावित करेगी।
प्रीफिल डिसएग्रीगेशन के अलावा, हम निम्नलिखित पहलुओं को अनुकूलित करने की भी योजना बना रहे हैं:
AllToAll प्रदर्शन: हमारा AllToAll कर्नल वर्तमान में केवल Infiniband बैंडविड्थ का 1/3 प्राप्त कर सकता है। हम इस कर्नल को अनुकूलित करना जारी रखेंगे।
EAGLE-शैली सट्टा डिकोडिंग: उपरोक्त डेटा में, हमने 1 टोकन की भविष्यवाणी करने के लिए सट्टा डिकोडिंग का उपयोग करने की कल्पना की। EAGLE कई टोकनों की भविष्यवाणी करने के लिए एक ट्री संरचना का उपयोग कर सकता है, जिससे स्वीकृति लंबाई में सुधार होता है, जो आउटपुट गति को काफी बढ़ा सकता है।
GEMM कर्नल: पहले दिखाए गए रूफलाइन मॉडल में, हम पा सकते हैं कि GEMM कर्नल की दक्षता अभी भी सैद्धांतिक सीमा से दूर है। हम इस कर्नल को अनुकूलित करना जारी रखेंगे।
GB200 NVL72: NVIDIA के नवीनतम GB200 NVL72 समाधान में, 72 ब्लैकवेल GPU हाई-स्पीड NVLink के माध्यम से आपस में जुड़े हुए हैं। MoE आर्किटेक्चर मॉडल के लिए, यह एक बहुत बड़ा अवसर और चुनौती है।
निष्कर्ष
DeepSeek MoE मॉडल का मल्टी-नोड परिनियोजन वह हासिल करता है जो सघन LLM के साथ आमतौर पर असंभव है: थ्रूपुट और विलंबता दोनों में एक साथ सुधार करना। विशेषज्ञों को अधिक GPU में वितरित करके, हम प्रति उपकरण मेमोरी बैंडविड्थ दबाव को कम करते हैं, जिससे तेज़ प्रसंस्करण और उच्च सिस्टम थ्रूपुट सक्षम होता है। हमारे प्रयोग दिखाते हैं कि EP128 कॉन्फ़िगरेशन सिंगल-नोड परिनियोजन की तुलना में समान आउटपुट गति पर 5 गुना तक उच्च थ्रूपुट प्राप्त करते हैं।
माइक्रो-बैचिंग जैसी गणना-संचार ओवरलैपिंग तकनीकें मल्टी-नोड संचार ओवरहेड को काफी कम करती हैं, जिसमें हमारा कार्यान्वयन 40% तक की गति में वृद्धि दिखाता है। हमारे कस्टम AllToAll संचार कर्नलों और अनुकूलित कर्नल कार्यान्वयनों ने 671B पैरामीटर मॉडल के कुशल परिनियोजन को सक्षम किया है।
जैसे-जैसे MoE आर्किटेक्चर अपनी क्षमता के लिए लोकप्रियता हासिल कर रहे हैं, ये परिनियोजन रणनीतियां ऐसे मॉडलों को कुशलतापूर्वक स्केल करने के लिए मूल्यवान अंतर्दृष्टि प्रदान करती हैं।
संदर्भ
DeepSeek-V3/R1 इंफरेंस सिस्टम अवलोकन
Megatron-LM: मॉडल समानता का उपयोग करके बहु-अरब पैरामीटर भाषा मॉडल को प्रशिक्षित करना
EAGLE: सट्टा नमूनाकरण को फीचर अनिश्चितता पर पुनर्विचार करने की आवश्यकता है
उद्धरण
@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}
}