क्या आपने कभी सोचा है कि अपना खुद का ChatGPT सीधे अपने लैपटॉप पर चलाएँ?
बड़े भाषा मॉडल (LLMs) में तीव्र प्रगति के साथ, इन शक्तिशाली मॉडलों को उपभोक्ता हार्डवेयर तक लाने की संभावना अब हक़ीक़त बन रही है।
इस क्षमता को खोलने की कुंजी है क्वांटाइज़ेशन, एक तकनीक जो इन लगातार बड़े होते मॉडलों के आकार को घटाकर उन्हें रोजमर्रा के डिवाइसों पर न्यूनतम प्रदर्शन हानि के साथ चलने देती है— यदि सही तरह से लागू किया जाए!
इस गाइड में, हम क्वांटाइज़ेशन की अवधारणा, उसके काम करने के तरीके, और LLMs को क्वांटाइज़ करने के अलग-अलग विकल्प समझेंगे। अंत में, हम Hugging Face की Quanto लाइब्रेरी का उपयोग करके दो सरल चरणों में अपने मॉडल को क्वांटाइज़ करेंगे।
चलिए गहराई में उतरते हैं! आप DataCamp DataLab का उपयोग करके साथ चल सकते हैं।
बड़े भाषा मॉडलों की बढ़ती वृद्धि
जैसे-जैसे LLMs विकसित हुए हैं, उनकी जटिलता घातीय रूप से बढ़ी है, जिससे उनके पैरामीटर्स की संख्या में भारी इज़ाफ़ा हुआ है। उदाहरण के लिए, 2018 में लॉन्च हुए पहले GPT मॉडल में 0.11 बिलियन पैरामीटर थे। 2019 के अंत तक, GPT-2 यह संख्या 1.5 बिलियन तक ले गया, और 2020 के अंत में जारी GPT-3 175 बिलियन पैरामीटर्स तक पहुँच गया।
आज, GPT-4 में 1 ट्रिलियन से अधिक पैरामीटर हैं। यह बड़ा उछाल एक चुनौती पेश करता है: जैसे-जैसे मॉडल बढ़ते हैं, उनकी मेमोरी आवश्यकताएँ भी बढ़ती हैं, जो अक्सर GPUs जैसे उन्नत हार्डवेयर एक्सेलेरेटर्स की क्षमता से अधिक हो जाती हैं।
मेमोरी की यह बढ़ती माँग मॉडल के प्रशिक्षण और इन्फ़ेरेंस होस्टिंग—दोनों—को सीमित करती है, जिससे LLM-आधारित समाधानों की उपलब्धता और अपनाने में बाधा आती है।
यह वृद्धि मॉडलों का आकार घटाकर उन्हें अधिक सुलभ बनाने की ज़रूरत को जन्म देती है। मॉडल के कुछ घटकों की प्रिसीजन बदलकर, क्वांटाइज़ेशन मॉडल के मेमोरी फ़ुटप्रिंट को घटाता है, जबकि प्रदर्शन को समान स्तर पर बनाए रखने का प्रयास करता है।
क्वांटाइज़ेशन क्या है?
क्वांटाइज़ेशन एक मॉडल कंप्रेशन तकनीक है जो बड़े भाषा मॉडल के वेट्स और एक्टिवेशन्स को उच्च-प्रिसीजन मानों से निम्न-प्रिसीजन मानों में बदलती है। इसका अर्थ है ऐसे डेटा प्रकार से दूसरे प्रकार में बदलना जो कम सूचना रखता हो। एक सामान्य उदाहरण है 32-बिट फ़्लोटिंग-पॉइंट संख्या को 8-बिट इंटीजर में बदलना।
मॉडल के प्रत्येक वेट या एक्टिवेशन के लिए आवश्यक बिट्स की संख्या कम करने से उसके कुल आकार में उल्लेखनीय कमी आती है। नतीजतन, क्वांटाइज़ेशन LLMs को कम मेमोरी उपयोग, कम स्टोरेज स्पेस की आवश्यकता और अधिक ऊर्जा-कुशल बनाता है।
क्वांटाइज़ेशन को समझने के लिए एक प्रभावी उपमा है इमेज कंप्रेशन। उच्च-रिज़ॉल्यूशन छवियाँ अक्सर वेबसाइटों पर उपयोग के लिए कंप्रेस की जाती हैं। इसमें कुछ डेटा या बिट्स हटाकर छवि का आकार घटाया जाता है। इससे आमतौर पर छवि की गुणवत्ता कुछ हद तक कम होती है, लेकिन आयाम और फ़ाइल आकार भी घट जाते हैं, जिससे वेब पेज तेज़ी से लोड होते हैं और फिर भी संतोषजनक दृश्य अनुभव मिलता है।
तेज़ लोडिंग के लिए इमेज कंप्रेशन की रूपरेखा, वेबपेज जैसी एप्लिकेशनों के लिए।
इसी तरह, किसी LLM को क्वांटाइज़ करने से उसकी संगणनात्मक आवश्यकताएँ कम हो जाती हैं, जिससे वह कम शक्तिशाली हार्डवेयर पर भी उपयुक्त प्रदर्शन देते हुए चल सकता है। जैसे कंप्रेस्ड छवियों को संभालना आसान होता है, वैसे ही क्वांटाइज़्ड मॉडल विविध प्लेटफ़ॉर्म पर अधिक आसानी से डिप्लॉय होते हैं, भले ही विवरण या प्रिसीजन में थोड़ा समझौता करना पड़े। जैसा कि हम देखेंगे, क्वांटाइज़ेशन प्रक्रिया कुछ शोर भी लाती है।
क्वांटाइज़ेशन का सिद्धांत
क्वांटाइज़ेशन सामान्यतः बड़े भाषा मॉडल के वेट्स पर लागू किया जाता है, हालाँकि इसे एक्टिवेशन्स पर भी लागू किया जा सकता है। मॉडल वेट्स एक न्यूरल नेटवर्क के पैरामीटर्स होते हैं जो अलग-अलग लेयर्स में न्यूरॉन्स के बीच कनेक्शन्स की ताकत निर्धारित करते हैं। वेट्स मूल रूप से वे सीखे हुए गुणांक हैं जो नेटवर्क से गुजरते समय इनपुट डेटा को रूपांतरित करते हैं।
वेट्स शुरू में यादृच्छिक, निरर्थक मानों पर सेट होते हैं और प्रशिक्षण के दौरान भविष्यवाणी और वास्तविक लक्ष्यों के बीच त्रुटि के आधार पर समायोजित किए जाते हैं। यह समायोजन प्रक्रिया ग्रेडिएंट डीसेंट जैसे ऑप्टिमाइज़ेशन एल्गोरिद्म द्वारा निर्देशित होती है।
मॉडल को क्वांटाइज़ करने का एक विकल्प है उसके वेट्स की प्रिसीजन घटाना। इसे स्पष्ट करने के लिए, नीचे दी गई छवि में बाईं ओर की मैट्रिक्स पर ध्यान दें, जो चार-डेसिमल प्रिसीजन वाली 3x3 वेट्स मैट्रिक्स दर्शाती है:
चार-डेसिमल प्रिसीजन वाली यादृच्छिक वेट्स मैट्रिक्स (बाएँ) और एक-डेसिमल प्रिसीजन तक राउंडिंग द्वारा उसकी क्वांटाइज़्ड फ़ॉर्म (दाएँ) का उदाहरण।
दाईं ओर की मैट्रिक्स मूल मैट्रिक्स का क्वांटाइज़्ड संस्करण है। यह “क्वांटाइज़्ड” मैट्रिक्स मूल मैट्रिक्स के अवयवों को एक दशमलव तक राउंड करके प्राप्त की जाती है।
हम देख सकते हैं कि उपर्युक्त मैट्रिक्स पूरी तरह समान नहीं हैं, परंतु बहुत मिलती-जुलती हैं। मान-दर-मान जो अंतर आता है उसे क्वांटाइज़ेशन त्रुटि कहा जाता है, जिसे हम मैट्रिक्स रूप में भी दर्शा सकते हैं:
मैट्रिक्स में क्वांटाइज़ेशन त्रुटि। रंग जितना गहरा, त्रुटि उतनी अधिक।
क्वांटाइज़ेशन में मौजूदा शोध इस अंतर को यथासंभव कम करने पर केंद्रित है ताकि प्रदर्शन पर कोई प्रभाव न पड़े।
इस सरल उदाहरण में, हम केवल मैट्रिक्स अवयवों को राउंड कर रहे हैं। व्यावहारिक रूप में, क्वांटाइज़ेशन संख्यात्मक मानों को एक अलग डेटा प्रकार में बदलकर किया जाता है, जैसे उच्च प्रिसीजन वाले प्रकार से निम्न प्रिसीजन वाले प्रकार में। उदाहरण के लिए, अधिकतर मॉडलों के लिए डिफ़ॉल्ट स्टोरेज डेटा प्रकार float32 होता है।
इस स्थिति में, प्रति पैरामीटर 4 बाइट (8-बिट प्रिसीजन का 4 गुना) आवंटित करने पड़ते हैं। अतः, उदाहरण में दी गई 3x3 मैट्रिक्स के लिए कुल मेमोरी फ़ुटप्रिंट 36 बाइट होगा।
डेटा प्रकार बदलकर— जिसे डाउनकास्टिंग भी कहते हैं— int8 में करने पर, प्रति पैरामीटर केवल 1 बाइट लगेगा। इसलिए, मैट्रिक्स का कुल फ़ुटप्रिंट 9 बाइट रह जाएगा।
ब्रेन फ़्लोटिंग पॉइंट — BF16
मॉडल के वेट्स के लिए चुना गया डेटा प्रकार यह निर्धारित करता है कि हम मॉडल को कितना घटा सकते हैं। परंपरागत फ़्लोटिंग-पॉइंट प्रकार, जैसे float32 और float16, कई मशीन लर्निंग अनुप्रयोगों में मानक रहे हैं, जो शुद्धता और संगणनात्मक दक्षता के बीच संतुलन देते हैं। विशेष रूप से, float32 उच्च प्रिसीजन और व्यापक डायनामिक रेंज देता है लेकिन अधिक मेमोरी और कंप्यूट शक्ति लेता है। इसके विपरीत, float16 कम प्रिसीजन और रेंज के साथ गणनाओं को काफ़ी तेज़ करता है।
2018 में, Google ने ऐसे फ़्लोटिंग-पॉइंट फ़ॉर्मेट की आवश्यकता पहचानी जो float32 की व्यापक डायनामिक रेंज और float16 की दक्षता के बीच मध्यम मार्ग दे सके।
इससे ब्रेन फ़्लोटिंग पॉइंट (bfloat16) का निर्माण हुआ, जो float32 की डायनामिक रेंज बनाए रखता है, पर प्रिसीजन घटा देता है।
डाउनकास्टिंग
डाउनकास्टिंग उच्च-प्रिसीजन डेटा प्रकार को निम्न-प्रिसीजन डेटा प्रकार में बदलने का औपचारिक शब्द है। डाउनकास्टिंग का उपयोग करके, हम मेमोरी फ़ुटप्रिंट घटाते हैं और गति बढ़ाते हैं क्योंकि निम्न प्रिसीजन की गणनाएँ भी कम मेमोरी लेती हैं।
इस खंड में, हम देखेंगे कि कैसे float32— जो अधिकांश मॉडलों का डिफ़ॉल्ट स्टोरेज प्रकार है— से Google के bfloat16 में डाउनकास्टिंग होती है, और यह आमतौर पर कुछ डेटा हानि का कारण कैसे बनती है।
आइए PyTorch में float32 प्रकार के अवयवों वाला एक यादृच्छिक टेन्सर परिभाषित करके शुरू करें और पहले पाँच अवयव दिखाएँ:
import torch
# random pytorch tensor: float32, size=1000
tensor_fp32 = torch.rand(1000, dtype = torch.float32)print(tensor_fp32[:5])>> tensor([0.2257,0.0480,0.8520,0.3115,0.1373])संचालित द्वारा
अब हम bfloat16 में .to(dtype) मेथड से टेन्सर को डाउनकास्ट कर सकते हैं और पहले 5 नए अवयव देखें:
# downcast the tensor to bfloat16 using the "to" method
tensor_fp32_to_bf16 = tensor_fp32.to(dtype = torch.bfloat16)print(tensor_fp32_to_bf16[:5])>> tensor([0.2256,0.0481,0.8516,0.3105,0.1377], dtype=torch.bfloat16)संचालित द्वारा
जैसा कि हम देख सकते हैं, मान काफ़ी क़रीब हैं, हालांकि समान नहीं। अंतर तब अधिक दिखता है जब हम इन मानों पर ऑपरेशन करते हैं। उदाहरण के लिए, मूल टेन्सर को स्वयं से गुणा करने पर:
# tensor_fp32 x tensor_fp32
m_float32 = torch.dot(tensor_fp32, tensor_fp32)print(m_float32)>> tensor(322.1082)संचालित द्वारा
यदि हम वही गणना क्वांटाइज़्ड टेन्सर के साथ करें, तो अंतर अधिक दिखेगा:
# tensor_fp32_to_bf16 x tensor_fp32_to_bf16
m_bfloat16 = torch.dot(tensor_fp32_to_bf16, tensor_fp32_to_bf16)print(m_bfloat16)>> tensor(256., dtype=torch.bfloat16)संचालित द्वारा
त्रुटि संचय (एरर प्रोपेगेशन) के कारण अंतिम परिणामों में स्पष्ट अंतर देखा जा सकता है।
क्वांटाइज़्ड टेन्सरों पर ऑपरेशन करने पर यही त्रुटि संचय का प्रभाव LLMs को डाउनकास्ट करने में भी होता है, जिससे सूचना की हानि होती है। जैसा कि हमने देखा, कम मेमोरी का उपयोग करने का अर्थ है कि गणना कम सटीक हो सकती है। गुणा का यह प्रभाव परत-दर-परत होने वाले वास्तविक त्रुटि संचय जैसा है, जो इकट्ठा होकर अंततः कुछ टोकन पूर्वानुमानों को प्रभावित करता है।
डाउनकास्टिंग के साथ, bfloat16 प्रकार का उपयोग करते समय प्रदर्शन स्वीकार्य रहता है, लेकिन छोटे डेटा प्रकारों के लिए यह सही नहीं रहता।
डेटा प्रकार की इस पाबंदी के कारण डाउनकास्टिंग आमतौर पर प्रभावी क्वांटाइज़ेशन तकनीक के रूप में उपयोग नहीं होती। इसके बजाय, अन्य विधियों का उपयोग होता है जो इन्फ़ेरेंस के दौरान वापस float32 में बदलकर मूल मॉडल के प्रदर्शन के नज़दीक बनी रहती हैं।
क्वांटाइज़ेशन के प्रकार
क्वांटाइज़ेशन के कई प्रकार होते हैं, और हमने उन्हें नीचे विस्तार से बताया है:
रैखिक (लीनियर) क्वांटाइज़ेशन
रैखिक क्वांटाइज़ेशन LLMs के लिए सबसे लोकप्रिय स्कीमाओं में से एक है। सरल शब्दों में, यह मूल वेट्स के फ़्लोटिंग-पॉइंट मानों की रेंज को समान रूप से एक निश्चित-बिंदु (फ़िक्स्ड-पॉइंट) रेंज में मैप करना शामिल करता है, और इन्फ़ेरेंस के लिए हाई-प्रिसीजन डेटा प्रकार का उपयोग करता है।
इसे यथासंभव सरल रखने के लिए, आइए उस मॉडल पर रैखिक क्वांटाइज़ेशन लागू करने के लिए आवश्यक चरणों की समीक्षा करें। ध्यान दें कि वास्तविक सूत्र नीचे दी गई छवि में दिखाए गए हैं:
न्यूनतम और अधिकतम मानों की गणना: प्रत्येक टेन्सर के लिए, हमें क्वांटाइज़ किए जाने वाले फ़्लोटिंग-पॉइंट मानों की रेंज परिभाषित करने हेतु न्यूनतम और अधिकतम मान प्राप्त करने होते हैं। जिस डेटा प्रकार में हम बदलना चाहते हैं, वह क्वांटाइज़्ड रेंज का न्यूनतम और अधिकतम देगा। उदाहरण के लिए, अनसाइनड इंटीजर के मामले में, 8-बिट के लिए रेंज 0 से 255 होगी।
स्केल (s) और ज़ीरो-पॉइंट (s) की गणना: स्केल फ़्लोटिंग-पॉइंट मानों की रेंज को इंटीजर रेंज में फिट करता है। ज़ीरो-पॉइंट यह सुनिश्चित करता है कि फ़्लोटिंग-पॉइंट रेंज में शून्य को एक इंटीजर द्वारा ठीक से दर्शाया जा सके, खासकर शून्य के क़रीब मानों के लिए संख्यात्मक सटीकता और स्थिरता बनाए रखते हुए।
मानों का क्वांटाइज़ेशन (q): इस चरण में पिछले चरण में गणना किए गए स्केल फैक्टर s और ज़ीरो-पॉइंट s का उपयोग करके फ़्लोटिंग-पॉइंट मानों को निम्न प्रिसीजन की इंटीजर रेंज में मैप किया जाता है। राउंडिंग ऑपरेशन यह सुनिश्चित करता है कि अंतिम परिणाम एक असतत इंटीजर हो, जो निम्न प्रिसीजन फ़ॉर्मैट में स्टोरेज और गणना के लिए उपयुक्त हो।
डीक्वांटाइज़: इन्फ़ेरेंस के दौरान, उच्च प्रिसीजन पाने हेतु गणनाओं में डीक्वांटाइज़्ड मानों का उपयोग किया जाता है, जबकि मेमोरी में केवल क्वांटाइज़्ड वेट्स संग्रहीत रहते हैं। यह चरण आपको क्वांटाइज़ेशन त्रुटि की गणना करने की भी अनुमति देता है।
आइए ऊपर वर्णित प्रत्येक चरण को उसके संबंधित सूत्र से जोड़ें:
किसी भी वेट्स मैट्रिक्स पर रैखिक क्वांटाइज़ेशन लागू करने के लिए समीकरण।
क्या आपको इन सूत्रों को लागू करना कठिन लग रहा है? चलिए हाथ गंदे करते हैं!
यदि हम इन सूत्रों को नीचे दी गई छवि में बाईं ओर के 3x3 वेट टेन्सर पर लागू करें, तो हमें दाईं ओर दिखाई गई क्वांटाइज़्ड मैट्रिक्स मिलेगी। मैं सुझाव दूँगा कि कुछ मिनट लेकर क्वांटाइज़्ड रेंज के अधिकतम और न्यूनतम मान तथा कुछ क्वांटाइज़्ड मानों की गणना करें:
दो-डेसिमल प्रिसीजन वाली यादृच्छिक वेट्स मैट्रिक्स (बाएँ) और उसकी int8 डेटा प्रकार में क्वांटाइज़्ड फ़ॉर्म (दाएँ) का उदाहरण।
हम देख सकते हैं कि int8 का निचला बाउंड मूल टेन्सर के निचले मान के अनुरूप है (-0.40 → 0), जबकि ऊपरी बाउंड मूल टेन्सर के ऊँचे मान से मेल खाता है (0.50 → 255)।
यदि हम अब सूत्र (4) का उपयोग करके मानों को डीक्वांटाइज़ करें, तो देखेंगे कि डीक्वांटाइज़्ड मान मूल मानों (बाईं मैट्रिक्स) के क़रीब हैं। हम बिंदु-दर-बिंदु अंतर (दाईं मैट्रिक्स) की गणना करके क्वांटाइज़ेशन त्रुटि निकाल सकते हैं:
क्वांटाइज़्ड वेट्स और स्केल व ज़ीरो-पॉइंट मानों का उपयोग करके मानों को डीक्वांटाइज़ किया जा सकता है (बाएँ)। बिंदु-दर-बिंदु अंतर या क्वांटाइज़ेशन त्रुटि (दाएँ) की गणना की जा सकती है।
रैखिक क्वांटाइज़ेशन केवल क्वांटाइज़्ड वेट्स और स्केल व ज़ीरो-पॉइंट मानों को मेमोरी में संग्रहीत करके मॉडल का आकार घटाता है, जबकि इन्फ़ेरेंस के लिए मूल वेट्स की गणना में इनका उपयोग कर प्रदर्शन बनाए रखता है।
ब्लॉकवाइज़ क्वांटाइज़ेशन
रैखिक क्वांटाइज़ेशन सादगी के कारण लोकप्रिय है, पर मैपिंग बनाने के कई तरीके हैं। आजकल एक और काफ़ी लोकप्रिय तरीका है ब्लॉकवाइज़ क्वांटाइज़ेशन, जो गैर-एकरूप वेट वितरण वाले मॉडलों के लिए रैखिक क्वांटाइज़ेशन से अधिक सटीक होता है।
ब्लॉकवाइज़ क्वांटाइज़ेशन एक अधिक परिष्कृत पद्धति है जिसमें पूरे रेंज की बजाय छोटे ब्लॉक्स में वेट्स को क्वांटाइज़ किया जाता है। यह पद्धति दो मुख्य अवधारणाओं पर निर्भर करती है:
ब्लॉकवाइज़ क्वांटाइज़ेशन: वेट्स को छोटे-छोटे ब्लॉक्स में बाँटा जाता है और प्रत्येक ब्लॉक पर अलग से क्वांटाइज़ेशन लागू होता है। इससे मॉडल के अलग-अलग भागों में विविधताओं को बेहतर तरीक़े से संभाला जा सकता है।
डिस्ट्रिब्यूशन-अवेयर ब्लॉक्स: क्वांटाइज़ेशन प्रक्रिया प्रत्येक ब्लॉक के भीतर वेट्स की आपेक्षिक आवृत्ति को ध्यान में रखती है, जिससे वेट वितरण के अनुरूप ब्लॉक्स बनते हैं। इससे मानों का मैपिंग अधिक कुशल होता है।
वेट क्वांटाइज़ेशन बनाम एक्टिवेशन क्वांटाइज़ेशन
हमारे मैट्रिक्स उदाहरणों में, हमने मुख्य रूप से मॉडल के वेट्स को क्वांटाइज़ करने की प्रक्रिया पर ध्यान दिया है। वेट क्वांटाइज़ेशन मॉडल अनुकूलन के लिए महत्वपूर्ण है, लेकिन यह भी ध्यान रखना आवश्यक है कि मॉडल के एक्टिवेशन्स को भी क्वांटाइज़ किया जा सकता है।
एक्टिवेशन क्वांटाइज़ेशन नेटवर्क की प्रत्येक लेयर के मध्यवर्ती आउटपुट की प्रिसीजन घटाने की प्रक्रिया है। वेट्स के विपरीत, जो मॉडल के प्रशिक्षण के बाद स्थिर (कॉनस्टेंट) रहते हैं, एक्टिवेशन्स डायनेमिक होते हैं। इसका मतलब है कि प्रत्येक इनपुट के साथ एक्टिवेशन्स बदलते हैं, जिससे उनकी रेंज का अनुमान लगाना कठिन हो जाता है।
आम तौर पर, एक्टिवेशन क्वांटाइज़ेशन को लागू करना वेट क्वांटाइज़ेशन की तुलना में कठिन होता है। इसके लिए सावधानीपूर्वक कैलिब्रेशन आवश्यक है, ताकि एक्टिवेशन्स की डायनामिक रेंज ठीक से कैप्चर हो सके।
वेट क्वांटाइज़ेशन और एक्टिवेशन क्वांटाइज़ेशन पूरक तकनीकें हैं। दोनों तकनीकों को लागू करके, हम मॉडल के आकार में महत्वपूर्ण सुधार कर सकते हैं, बिना प्रदर्शन से बहुत अधिक समझौता किए।
क्वांटाइज़ेशन विभिन्न समय पर भी किया जा सकता है। यदि हम एक प्री-ट्रेंड मॉडल लेते हैं और इन्फ़ेरेंस चरण के दौरान मॉडल पैरामीटर्स को क्वांटाइज़ करते हैं, तो हम पोस्ट-ट्रेनिंग क्वांटाइज़ेशन (PTQ) कर रहे होते हैं।
इस पद्धति में प्रशिक्षण प्रक्रिया में कोई बदलाव शामिल नहीं होता। पैरामीटर्स की डायनामिक रेंज को रनटाइम पर पुनर्गणित किया जाता है, ठीक वैसे ही जैसे हमने उदाहरण मैट्रिक्स के साथ किया।
दूसरी ओर, क्वांटाइज़ेशन-अवेयर ट्रेनिंग (QAT) लागू करने का विकल्प भी है। इसमें प्रशिक्षण प्रक्रिया को इस तरह संशोधित किया जाता है कि प्रशिक्षण के दौरान क्वांटाइज़ेशन के प्रभावों का अनुकरण हो। मॉडल क्वांटाइज़ेशन शोर के प्रति मज़बूत बनने के लिए प्रशिक्षित होता है, जिससे बेहतर शुद्धता मिलती है।
QAT के दौरान, प्रशिक्षण की मध्यवर्ती अवस्थाएँ वेट्स के क्वांटाइज़्ड संस्करण और मूल अनक्वांटाइज़्ड वेट्स—दोनों—को (मेमोरी में भी!) रखती हैं। इसलिए, इन्फ़ेरेंस के लिए हम मॉडल के क्वांटाइज़्ड संस्करण का उपयोग करते हैं, पर बैकप्रोपेगेशन के दौरान मॉडल के अनक्वांटाइज़्ड वेट्स अपडेट होते हैं।
जैसा अपेक्षित है, हालाँकि अधिक जटिल और समय लेने वाली, QAT आमतौर पर PTQ की तुलना में अधिक शुद्धता देती है।
कैलिब्रेशन तकनीकें
कुछ क्वांटाइज़ेशन विधियों में कैलिब्रेशन चरण की आवश्यकता होती है। उदाहरण के लिए, क्वांटाइज़ेशन से पहले हमें किसी मॉडल की मूल एक्टिवेशन रेंज निर्धारित करनी होती है। सामान्य कैलिब्रेशन में आमतौर पर प्रतिनिधि डेटासेट पर इन्फ़ेरेंस चलाकर क्वांटाइज़ेशन पैरामीटर्स का अनुकूलन और क्वांटाइज़ेशन त्रुटि को न्यूनतम करना शामिल है।
इस कैलिब्रेशन प्रक्रिया के दौरान, क्वांटाइज़ेशन एल्गोरिद्म मॉडल के एक्टिवेशन्स और वेट्स के वितरण और रेंज के बारे में आँकड़े इकट्ठा करता है। ये आँकड़े सर्वोत्तम क्वांटाइज़ेशन पैरामीटर्स निर्धारित करने में मदद करते हैं। वेट्स को क्वांटाइज़ करते समय स्केल और ज़ीरो-पॉइंट की गणना भी एक तरह का कैलिब्रेशन ही है, पर इसके अन्य प्रकार भी हैं:
परसेंटाइल कैलिब्रेशन: वेट्स के निर्दिष्ट परसेंटाइल रेंज पर केंद्रित रहता है, चरम बाह्य मानों (आउटलायर्स) को नज़रअंदाज़ करके क्वांटाइज़ेशन को अधिक मज़बूत बनाता है।
मीन और स्टैंडर्ड डिविएशन कैलिब्रेशन: वेट्स के मीन और स्टैंडर्ड डिविएशन जैसी सांख्यिकीय मापों के आधार पर क्वांटाइज़ेशन रेंज परिभाषित करता है।
हालाँकि, QLoRA जैसी क्वांटाइज़ेशन विधियाँ किसी भी कैलिब्रेशन चरण के बिना इस्तेमाल की जा सकती हैं।
ये विधियाँ आमतौर पर मॉडल की सभी रैखिक लेयर्स को क्वांटाइज़्ड रैखिक लेयर्स (QLinear) से बदल देती हैं। QLinear लेयर्स आंतरिक रूप से क्वांटाइज़ेशन को संभालने के लिए डिज़ाइन की गई हैं, जिससे अतिरिक्त कैलिब्रेशन चरण की आवश्यकता समाप्त हो जाती है। यह क्वांटाइज़ेशन प्रक्रिया को लागू करना अधिक सरल बनाता है, जबकि मॉडल के प्रदर्शन को भी बनाए रखता है।
क्वांटाइज़ेशन के उपकरण
Python में कई टूल्स और लाइब्रेरीज़ क्वांटाइज़ेशन का समर्थन करती हैं, जो PTQ और QAT—दोनों—के लिए टूल्स देती हैं। उदाहरण के लिए, pytorchऔर tensorflow क्वांटाइज़ेशन विधियाँ प्रदान करते हैं, हालांकि मौजूदा मॉडलों में क्वांटाइज़ेशन को सहजता से एकीकृत करने के लिए लाइब्रेरीज़ और मॉडल आंतरिकों की गहरी समझ चाहिए। आधिकारिक PyTorch दस्तावेज़ में क्वांटाइज़ेशन विकल्प देखें।
यदि आप इन शक्तिशाली फ्रेमवर्क्स को सीखने में रुचि रखते हैं, तो मैं Deep Learning in Python पाठ्यक्रम की सिफ़ारिश करता/करती हूँ।
अब तक क्वांटाइज़ेशन को आसान चरणों में लागू करने का मेरा पसंदीदा विकल्प Hugging Face की Quanto लाइब्रेरी है, जिसे PyTorch मॉडलों के लिए क्वांटाइज़ेशन प्रक्रिया को सरल बनाने हेतु डिज़ाइन किया गया है।
मॉडल को क्वांटाइज़ करने के व्यावहारिक चरण
Hugging Face की Quanto लाइब्रेरी का उपयोग करते हुए एक विशिष्ट क्वांटाइज़ेशन वर्कफ़्लो निम्नलिखित चरणों से बनेगा:
1. प्री-ट्रेंड मॉडल और उसके अनुरूप टोकनाइज़र का चयन और लोड करना। इस मामले में, हम EuletherAI का Pythia 410M मॉडल का उपयोग करेंगे:
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name ="EleutherAI/pythia-410m"
model = AutoModelForCausalLM.from_pretrained(model_name,
low_cpu_mem_usage=True)
tokenizer = AutoTokenizer.from_pretrained(model_name)संचालित द्वारा
लोड किए गए मॉडल की विभिन्न लेयर्स को विज़ुअलाइज़ करने में model.gpt_neoxमेथड मदद कर सकता है:
मूल मॉडल की लेयर-दर-लेयर रूपरेखा। मॉडल रैखिक लेयर्स और नॉर्मलाइज़ेशन लेयर्स जैसी विभिन्न प्रकार की लेयर्स से बना है।
हम कुछ परीक्षण इन्फ़ेरेंस चलाकर जाँच सकते हैं कि मॉडल सही तरह काम कर रहा है या नहीं। उदाहरण के लिए,
text ="Once upon a time, there was a"
inputs = tokenizer(text, return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=10)print(tokenizer.decode(outputs[0], skip_special_tokens=True))संचालित द्वारा
इसके अलावा, चूँकि मॉडल को क्वांटाइज़ करने से हम उसका आकार घटा पाएँगे, इसलिए प्रक्रिया शुरू करने से पहले मूल मॉडल का आकार जाँचना भी रोचक है:
import torch
module_sizes = compute_module_sizes(model)print(f"The model size is {module_sizes['']*1e-9} GB")संचालित द्वारा
नोट:DataCamp DataLab पर हमें compute_module_sizes() मेथड लागू मिला हुआ है।
अंत में, हम मूल मॉडल के डेंस टेन्सर्स को निम्न प्रकार देख सकते हैं:
print(model.gpt_neox.layers[0].attention.dense.weight)संचालित द्वारा
जैसा कि हम देख सकते हैं, यह वैसा ही दिखता है जैसा इस लेख में हमने अनक्वांटाइज़्ड मैट्रिक्स के साथ काम किया।
2. क्वांटाइज़ करें।quantize() मेथड डिफ़ॉल्ट स्टैंडर्ड फ़्लोट मॉडल को सीधे क्वांटाइज़्ड मॉडल में बदलने देता है।
from quanto import quantize, freeze
quantize(model, weights=torch.int8, activations=None)संचालित द्वारा
इस मामले में, हम केवल मॉडल के वेट्स को int8 डेटा प्रकार में क्वांटाइज़ कर रहे हैं। यह मेथड कैलिब्रेशन चरण सहित मॉडल को निम्न प्रिसीजन एरिथमेटिक के उपयोग में परिवर्तित करता है।
यदि हम अब मॉडल की लेयर्स प्रिंट करें, तो देखेंगे कि मूल रैखिक लेयर्स (Linear) को क्वांटाइज़्ड रैखिक लेयर्स (QLinear) से बदल दिया गया है:
यह मेथड क्वांटाइज़ेशन पैरामीटर्स को मॉडल में एंबेड कर देता है, जिससे वेट्स प्रभावी रूप से लक्ष्य डेटा प्रकार में बदल जाते हैं। अब क्वांटाइज़्ड मॉडल पैरामीटर्स देखें:
print(model.gpt_neox.layers[0].attention.dense.weight)संचालित द्वारा
जैसा कि हम देख सकते हैं, अब वेट्स Pytorch के int8 डेटा प्रकार की रेंज में हैं।
4. अंतिम जाँचें। एक बार मॉडल क्वांटाइज़ हो जाने पर, हम उसका नया घटा हुआ आकार जाँच सकते हैं:
module_sizes = compute_module_sizes(model)print(f"The model size is {module_sizes['']*1e-9} GB")संचालित द्वारा
हमने मूल आकार के केवल 35% का मॉडल हासिल कर लिया है!
अंत में, एक सरल इन्फ़ेरेंस के साथ मॉडल के नए प्रदर्शन की जाँच करें:
outputs = model.generate(**inputs, max_new_tokens=10)print(tokenizer.decode(outputs[0], skip_special_tokens=True))संचालित द्वारा
बेशक, केवल एक इन्फ़ेरेंस से प्रदर्शन जाँचना सार्थक नहीं, इसलिए इसका मूल्यांकन करने के लिए कोई परिमाणात्मक विधि परिभाषित करना अच्छा अभ्यास होगा।
अब आपकी बारी है आज़माने की!
निष्कर्ष
LLMs की बढ़ती मेमोरी आवश्यकताएँ उनके प्रशिक्षण और इन्फ़ेरेंस होस्टिंग—दोनों—को सीमित करती हैं, जिससे LLM-आधारित अनुप्रयोगों की पहुँच और अपनाने में बाधा आती है।
इस लेख में, हमने क्वांटाइज़ेशन की अवधारणा प्रस्तुत की, जिसमें मॉडल के वेट्स और एक्टिवेशन्स की प्रिसीजन घटाकर उसके मेमोरी फ़ुटप्रिंट और संगणनात्मक आवश्यकताओं को कम किया जाता है। यह प्रक्रिया मॉडलों को अधिक कुशल और सुलभ बनाने में मदद करती है, विशेष रूप से संसाधन-सीमित डिवाइसों पर डिप्लॉयमेंट के लिए।
हमने इस तकनीक को कुछ उदाहरणों के माध्यम से अपनाया, जिनमें वेट्स के संख्यात्मक मानों को राउंड किया। फिर हम डाउनकास्टिंग नामक एक सरल क्वांटाइज़ेशन प्रकार की ओर बढ़े। किसी मॉडल को डाउनकास्ट करते समय, पैरामीटर्स को bfloat16 जैसे अधिक कॉम्पैक्ट डेटा प्रकार में बदला जाता है, इन्फ़ेरेंस के लिए। यद्यपि यह मॉडल को इस छोटे डेटा प्रकार में गणनाएँ और एक्टिवेशन्स करने में सक्षम बनाता है, लेकिन डेटा प्रकार के आकार के साथ प्रदर्शन घटता है, और int8 जैसे इंटीजर प्रकारों के साथ यह अप्रभावी रहता है।
इसका समाधान करने के लिए, हमने रैखिक क्वांटाइज़ेशन प्रस्तुत किया, जो इन्फ़ेरेंस के दौरान वापस float32 में बदलकर मूल मॉडल के प्रदर्शन के क़रीब रहता है। इससे int8 जैसे और भी छोटे डेटा प्रकारों का उपयोग सक्षम होता है।
हमने रैखिक क्वांटाइज़ेशन लागू करने के संख्यात्मक चरणों से गुज़रे और Hugging Face की Quanto लाइब्रेरी का उपयोग करके अपना वेट क्वांटाइज़ेशन लागू किया। ख़ास बात यह है कि Quanto लाइब्रेरी के साथ, हम किसी भी PyTorch मॉडल—हगिंग फेस पर उपलब्ध मॉडलों सहित—को क्वांटाइज़ कर सकते हैं।
जो लोग LLaMa 2 या Mistral जैसे भारी मॉडलों को आज़माना चाहते हैं, वे अधिक कंप्यूटिंग शक्ति के लिए अपने DataCamp स्पेस को प्रीमियम में अपग्रेड करने पर विचार करें।
बड़े मॉडलों के लिए, हमें DataCamp Premium Plan में उपलब्ध अतिरिक्त संसाधनों की आवश्यकता हो सकती है।
क्वांटाइज़ेशन तकनीकों में पारंगत होकर, हम कम संसाधनों के साथ बड़े भाषा मॉडलों की पूरी क्षमता खोल सकते हैं, जिससे उन्नत AI अधिक कुशल, सुलभ और बहुमुखी बनता है।
आशा है यह लेख आपको LLMs के लिए क्वांटाइज़ेशन पर हाथों-हाथ मार्गदर्शन देगा!
LLM क्वांटाइज़ेशन FAQs
क्या QAT, PTQ से बेहतर है?⌄
QAT सामान्यतः बेहतर प्रदर्शन देता है क्योंकि मॉडल क्वांटाइज़ेशन शोर के प्रति मज़बूत होना सीखता है। हालांकि, इसमें प्रशिक्षण के दौरान अधिक मेमोरी लगती है क्योंकि यह क्वांटाइज़्ड और अनक्वांटाइज़्ड—दोनों—वेट्स को रखता है।
क्या Quanto लाइब्रेरी केवल पोस्ट-ट्रेनिंग क्वांटाइज़ेशन की अनुमति देती है?⌄
नहीं, Quanto लाइब्रेरी क्वांटाइज़ेशन-अवेयर ट्रेनिंग के उन्नत तरीकों का भी समर्थन करती है।
क्या Quanto लाइब्रेरी कैलिब्रेशन चरण से बचती है?⌄
नहीं, quantize() फ़ंक्शन एक अप्रत्यक्ष कैलिब्रेशन चरण करता है। Quanto लाइब्रेरी कस्टम कैलिब्रेशन के लिए calibration() मेथड भी प्रदान करती है।
क्या हम int8 से कम प्रिसीजन डेटा प्रकारों का उपयोग करके मॉडलों को क्वांटाइज़ कर सकते हैं?⌄
हाँ, int4 या यहाँ तक कि int2 में क्वांटाइज़ किए गए भी उच्च-प्रदर्शन वाले मॉडल मौजूद हैं।
हम Hugging Face पर अन्य मॉडलों तक कैसे पहुँच सकते हैं?⌄
अन्य मॉडलों तक पहुँचने के लिए, Hugging Face पेज से मनचाहा मॉडल नाम बस बदल दें। ध्यान दें कि कुछ मॉडलों तक पहुँचने के लिए आपको Hugging Face पेज पर नियम व शर्तें स्वीकृत करनी पड़ सकती हैं।
एंड्रिया वेलेंज़ुएला वर्तमान में जेनेवा, स्विट्ज़रलैंड में स्थित कण त्वरक (CERN) पर CMS प्रयोग में कार्यरत हैं। पिछले छह वर्षों से डेटा इंजीनियरिंग और विश्लेषण में विशेषज्ञता के साथ, उनकी जिम्मेदारियों में डेटा विश्लेषण और सॉफ्टवेयर विकास शामिल हैं। वह फिलहाल Medium प्रकाशन ForCode'Sake के माध्यम से डेटा-संबंधित तकनीकों के सीखने को लोकतांत्रिक बनाने की दिशा में काम कर रही हैं।
उन्होंने पॉलीटेक्निक यूनिवर्सिटी ऑफ कैटालोनिया से इंजीनियरिंग फ़िज़िक्स में बीएस और पोम्पेउ फ़ाब्रा यूनिवर्सिटी से इंटेलिजेंट इंटरेक्टिव सिस्टम्स में एमएस किया है। उनके शोध अनुभव में छवि जनरेशन के लिए Normalizing Flows जैसे पूर्व OpenAI एल्गोरिदम पर व्यावसायिक कार्य शामिल है।
क्या आपने कभी सोचा है कि अपना खुद का ChatGPT सीधे अपने लैपटॉप पर चलाएँ?
बड़े भाषा मॉडल (LLMs) में तीव्र प्रगति के साथ, इन शक्तिशाली मॉडलों को उपभोक्ता हार्डवेयर तक लाने की संभावना अब हक़ीक़त बन रही है।
इस क्षमता को खोलने की कुंजी है क्वांटाइज़ेशन, एक तकनीक जो इन लगातार बड़े होते मॉडलों के आकार को घटाकर उन्हें रोजमर्रा के डिवाइसों पर न्यूनतम प्रदर्शन हानि के साथ चलने देती है— यदि सही तरह से लागू किया जाए!
इस गाइड में, हम क्वांटाइज़ेशन की अवधारणा, उसके काम करने के तरीके, और LLMs को क्वांटाइज़ करने के अलग-अलग विकल्प समझेंगे। अंत में, हम Hugging Face की Quanto लाइब्रेरी का उपयोग करके दो सरल चरणों में अपने मॉडल को क्वांटाइज़ करेंगे।
चलिए गहराई में उतरते हैं! आप DataCamp DataLab का उपयोग करके साथ चल सकते हैं।
बड़े भाषा मॉडलों की बढ़ती वृद्धि
जैसे-जैसे LLMs विकसित हुए हैं, उनकी जटिलता घातीय रूप से बढ़ी है, जिससे उनके पैरामीटर्स की संख्या में भारी इज़ाफ़ा हुआ है। उदाहरण के लिए, 2018 में लॉन्च हुए पहले GPT मॉडल में 0.11 बिलियन पैरामीटर थे। 2019 के अंत तक, GPT-2 यह संख्या 1.5 बिलियन तक ले गया, और 2020 के अंत में जारी GPT-3 175 बिलियन पैरामीटर्स तक पहुँच गया।
आज, GPT-4 में 1 ट्रिलियन से अधिक पैरामीटर हैं। यह बड़ा उछाल एक चुनौती पेश करता है: जैसे-जैसे मॉडल बढ़ते हैं, उनकी मेमोरी आवश्यकताएँ भी बढ़ती हैं, जो अक्सर GPUs जैसे उन्नत हार्डवेयर एक्सेलेरेटर्स की क्षमता से अधिक हो जाती हैं।
मेमोरी की यह बढ़ती माँग मॉडल के प्रशिक्षण और इन्फ़ेरेंस होस्टिंग—दोनों—को सीमित करती है, जिससे LLM-आधारित समाधानों की उपलब्धता और अपनाने में बाधा आती है।
यह वृद्धि मॉडलों का आकार घटाकर उन्हें अधिक सुलभ बनाने की ज़रूरत को जन्म देती है। मॉडल के कुछ घटकों की प्रिसीजन बदलकर, क्वांटाइज़ेशन मॉडल के मेमोरी फ़ुटप्रिंट को घटाता है, जबकि प्रदर्शन को समान स्तर पर बनाए रखने का प्रयास करता है।
क्वांटाइज़ेशन क्या है?
क्वांटाइज़ेशन एक मॉडल कंप्रेशन तकनीक है जो बड़े भाषा मॉडल के वेट्स और एक्टिवेशन्स को उच्च-प्रिसीजन मानों से निम्न-प्रिसीजन मानों में बदलती है। इसका अर्थ है ऐसे डेटा प्रकार से दूसरे प्रकार में बदलना जो कम सूचना रखता हो। एक सामान्य उदाहरण है 32-बिट फ़्लोटिंग-पॉइंट संख्या को 8-बिट इंटीजर में बदलना।
मॉडल के प्रत्येक वेट या एक्टिवेशन के लिए आवश्यक बिट्स की संख्या कम करने से उसके कुल आकार में उल्लेखनीय कमी आती है। नतीजतन, क्वांटाइज़ेशन LLMs को कम मेमोरी उपयोग, कम स्टोरेज स्पेस की आवश्यकता और अधिक ऊर्जा-कुशल बनाता है।
क्वांटाइज़ेशन को समझने के लिए एक प्रभावी उपमा है इमेज कंप्रेशन। उच्च-रिज़ॉल्यूशन छवियाँ अक्सर वेबसाइटों पर उपयोग के लिए कंप्रेस की जाती हैं। इसमें कुछ डेटा या बिट्स हटाकर छवि का आकार घटाया जाता है। इससे आमतौर पर छवि की गुणवत्ता कुछ हद तक कम होती है, लेकिन आयाम और फ़ाइल आकार भी घट जाते हैं, जिससे वेब पेज तेज़ी से लोड होते हैं और फिर भी संतोषजनक दृश्य अनुभव मिलता है।
तेज़ लोडिंग के लिए इमेज कंप्रेशन की रूपरेखा, वेबपेज जैसी एप्लिकेशनों के लिए।
इसी तरह, किसी LLM को क्वांटाइज़ करने से उसकी संगणनात्मक आवश्यकताएँ कम हो जाती हैं, जिससे वह कम शक्तिशाली हार्डवेयर पर भी उपयुक्त प्रदर्शन देते हुए चल सकता है। जैसे कंप्रेस्ड छवियों को संभालना आसान होता है, वैसे ही क्वांटाइज़्ड मॉडल विविध प्लेटफ़ॉर्म पर अधिक आसानी से डिप्लॉय होते हैं, भले ही विवरण या प्रिसीजन में थोड़ा समझौता करना पड़े। जैसा कि हम देखेंगे, क्वांटाइज़ेशन प्रक्रिया कुछ शोर भी लाती है।
क्वांटाइज़ेशन का सिद्धांत
क्वांटाइज़ेशन सामान्यतः बड़े भाषा मॉडल के वेट्स पर लागू किया जाता है, हालाँकि इसे एक्टिवेशन्स पर भी लागू किया जा सकता है। मॉडल वेट्स एक न्यूरल नेटवर्क के पैरामीटर्स होते हैं जो अलग-अलग लेयर्स में न्यूरॉन्स के बीच कनेक्शन्स की ताकत निर्धारित करते हैं। वेट्स मूल रूप से वे सीखे हुए गुणांक हैं जो नेटवर्क से गुजरते समय इनपुट डेटा को रूपांतरित करते हैं।
वेट्स शुरू में यादृच्छिक, निरर्थक मानों पर सेट होते हैं और प्रशिक्षण के दौरान भविष्यवाणी और वास्तविक लक्ष्यों के बीच त्रुटि के आधार पर समायोजित किए जाते हैं। यह समायोजन प्रक्रिया ग्रेडिएंट डीसेंट जैसे ऑप्टिमाइज़ेशन एल्गोरिद्म द्वारा निर्देशित होती है।
यदि आप LLMs के आंतरिक पहलुओं के बारे में और जानना चाहते हैं, तो Developing Large Language Models पाठ्यक्रम आपके लिए है!
मॉडल को क्वांटाइज़ करने का एक विकल्प है उसके वेट्स की प्रिसीजन घटाना। इसे स्पष्ट करने के लिए, नीचे दी गई छवि में बाईं ओर की मैट्रिक्स पर ध्यान दें, जो चार-डेसिमल प्रिसीजन वाली 3x3 वेट्स मैट्रिक्स दर्शाती है:
चार-डेसिमल प्रिसीजन वाली यादृच्छिक वेट्स मैट्रिक्स (बाएँ) और एक-डेसिमल प्रिसीजन तक राउंडिंग द्वारा उसकी क्वांटाइज़्ड फ़ॉर्म (दाएँ) का उदाहरण।
दाईं ओर की मैट्रिक्स मूल मैट्रिक्स का क्वांटाइज़्ड संस्करण है। यह “क्वांटाइज़्ड” मैट्रिक्स मूल मैट्रिक्स के अवयवों को एक दशमलव तक राउंड करके प्राप्त की जाती है।
हम देख सकते हैं कि उपर्युक्त मैट्रिक्स पूरी तरह समान नहीं हैं, परंतु बहुत मिलती-जुलती हैं। मान-दर-मान जो अंतर आता है उसे क्वांटाइज़ेशन त्रुटि कहा जाता है, जिसे हम मैट्रिक्स रूप में भी दर्शा सकते हैं:
मैट्रिक्स में क्वांटाइज़ेशन त्रुटि। रंग जितना गहरा, त्रुटि उतनी अधिक।
क्वांटाइज़ेशन में मौजूदा शोध इस अंतर को यथासंभव कम करने पर केंद्रित है ताकि प्रदर्शन पर कोई प्रभाव न पड़े।
इस सरल उदाहरण में, हम केवल मैट्रिक्स अवयवों को राउंड कर रहे हैं। व्यावहारिक रूप में, क्वांटाइज़ेशन संख्यात्मक मानों को एक अलग डेटा प्रकार में बदलकर किया जाता है, जैसे उच्च प्रिसीजन वाले प्रकार से निम्न प्रिसीजन वाले प्रकार में। उदाहरण के लिए, अधिकतर मॉडलों के लिए डिफ़ॉल्ट स्टोरेज डेटा प्रकार
float32होता है।इस स्थिति में, प्रति पैरामीटर 4 बाइट (8-बिट प्रिसीजन का 4 गुना) आवंटित करने पड़ते हैं। अतः, उदाहरण में दी गई 3x3 मैट्रिक्स के लिए कुल मेमोरी फ़ुटप्रिंट 36 बाइट होगा।
डेटा प्रकार बदलकर— जिसे डाउनकास्टिंग भी कहते हैं—
int8में करने पर, प्रति पैरामीटर केवल 1 बाइट लगेगा। इसलिए, मैट्रिक्स का कुल फ़ुटप्रिंट 9 बाइट रह जाएगा।ब्रेन फ़्लोटिंग पॉइंट — BF16
मॉडल के वेट्स के लिए चुना गया डेटा प्रकार यह निर्धारित करता है कि हम मॉडल को कितना घटा सकते हैं। परंपरागत फ़्लोटिंग-पॉइंट प्रकार, जैसे
float32औरfloat16, कई मशीन लर्निंग अनुप्रयोगों में मानक रहे हैं, जो शुद्धता और संगणनात्मक दक्षता के बीच संतुलन देते हैं। विशेष रूप से,float32उच्च प्रिसीजन और व्यापक डायनामिक रेंज देता है लेकिन अधिक मेमोरी और कंप्यूट शक्ति लेता है। इसके विपरीत,float16कम प्रिसीजन और रेंज के साथ गणनाओं को काफ़ी तेज़ करता है।float32की व्यापक डायनामिक रेंज और float16 की दक्षता के बीच मध्यम मार्ग दे सके।इससे ब्रेन फ़्लोटिंग पॉइंट (
bfloat16) का निर्माण हुआ, जोfloat32की डायनामिक रेंज बनाए रखता है, पर प्रिसीजन घटा देता है।डाउनकास्टिंग
डाउनकास्टिंग उच्च-प्रिसीजन डेटा प्रकार को निम्न-प्रिसीजन डेटा प्रकार में बदलने का औपचारिक शब्द है। डाउनकास्टिंग का उपयोग करके, हम मेमोरी फ़ुटप्रिंट घटाते हैं और गति बढ़ाते हैं क्योंकि निम्न प्रिसीजन की गणनाएँ भी कम मेमोरी लेती हैं।
इस खंड में, हम देखेंगे कि कैसे
float32— जो अधिकांश मॉडलों का डिफ़ॉल्ट स्टोरेज प्रकार है— से Google केbfloat16में डाउनकास्टिंग होती है, और यह आमतौर पर कुछ डेटा हानि का कारण कैसे बनती है।आइए PyTorch में
float32प्रकार के अवयवों वाला एक यादृच्छिक टेन्सर परिभाषित करके शुरू करें और पहले पाँच अवयव दिखाएँ:अब हम
bfloat16में.to(dtype)मेथड से टेन्सर को डाउनकास्ट कर सकते हैं और पहले 5 नए अवयव देखें:जैसा कि हम देख सकते हैं, मान काफ़ी क़रीब हैं, हालांकि समान नहीं। अंतर तब अधिक दिखता है जब हम इन मानों पर ऑपरेशन करते हैं। उदाहरण के लिए, मूल टेन्सर को स्वयं से गुणा करने पर:
यदि हम वही गणना क्वांटाइज़्ड टेन्सर के साथ करें, तो अंतर अधिक दिखेगा:
त्रुटि संचय (एरर प्रोपेगेशन) के कारण अंतिम परिणामों में स्पष्ट अंतर देखा जा सकता है।
क्वांटाइज़्ड टेन्सरों पर ऑपरेशन करने पर यही त्रुटि संचय का प्रभाव LLMs को डाउनकास्ट करने में भी होता है, जिससे सूचना की हानि होती है। जैसा कि हमने देखा, कम मेमोरी का उपयोग करने का अर्थ है कि गणना कम सटीक हो सकती है। गुणा का यह प्रभाव परत-दर-परत होने वाले वास्तविक त्रुटि संचय जैसा है, जो इकट्ठा होकर अंततः कुछ टोकन पूर्वानुमानों को प्रभावित करता है।
डाउनकास्टिंग के साथ,
bfloat16प्रकार का उपयोग करते समय प्रदर्शन स्वीकार्य रहता है, लेकिन छोटे डेटा प्रकारों के लिए यह सही नहीं रहता।डेटा प्रकार की इस पाबंदी के कारण डाउनकास्टिंग आमतौर पर प्रभावी क्वांटाइज़ेशन तकनीक के रूप में उपयोग नहीं होती। इसके बजाय, अन्य विधियों का उपयोग होता है जो इन्फ़ेरेंस के दौरान वापस
float32में बदलकर मूल मॉडल के प्रदर्शन के नज़दीक बनी रहती हैं।क्वांटाइज़ेशन के प्रकार
क्वांटाइज़ेशन के कई प्रकार होते हैं, और हमने उन्हें नीचे विस्तार से बताया है:
रैखिक (लीनियर) क्वांटाइज़ेशन
रैखिक क्वांटाइज़ेशन LLMs के लिए सबसे लोकप्रिय स्कीमाओं में से एक है। सरल शब्दों में, यह मूल वेट्स के फ़्लोटिंग-पॉइंट मानों की रेंज को समान रूप से एक निश्चित-बिंदु (फ़िक्स्ड-पॉइंट) रेंज में मैप करना शामिल करता है, और इन्फ़ेरेंस के लिए हाई-प्रिसीजन डेटा प्रकार का उपयोग करता है।
इसे यथासंभव सरल रखने के लिए, आइए उस मॉडल पर रैखिक क्वांटाइज़ेशन लागू करने के लिए आवश्यक चरणों की समीक्षा करें। ध्यान दें कि वास्तविक सूत्र नीचे दी गई छवि में दिखाए गए हैं:
s) और ज़ीरो-पॉइंट (s) की गणना: स्केल फ़्लोटिंग-पॉइंट मानों की रेंज को इंटीजर रेंज में फिट करता है। ज़ीरो-पॉइंट यह सुनिश्चित करता है कि फ़्लोटिंग-पॉइंट रेंज में शून्य को एक इंटीजर द्वारा ठीक से दर्शाया जा सके, खासकर शून्य के क़रीब मानों के लिए संख्यात्मक सटीकता और स्थिरता बनाए रखते हुए।q): इस चरण में पिछले चरण में गणना किए गए स्केल फैक्टर s और ज़ीरो-पॉइंट s का उपयोग करके फ़्लोटिंग-पॉइंट मानों को निम्न प्रिसीजन की इंटीजर रेंज में मैप किया जाता है। राउंडिंग ऑपरेशन यह सुनिश्चित करता है कि अंतिम परिणाम एक असतत इंटीजर हो, जो निम्न प्रिसीजन फ़ॉर्मैट में स्टोरेज और गणना के लिए उपयुक्त हो।आइए ऊपर वर्णित प्रत्येक चरण को उसके संबंधित सूत्र से जोड़ें:
किसी भी वेट्स मैट्रिक्स पर रैखिक क्वांटाइज़ेशन लागू करने के लिए समीकरण।
क्या आपको इन सूत्रों को लागू करना कठिन लग रहा है? चलिए हाथ गंदे करते हैं!
यदि हम इन सूत्रों को नीचे दी गई छवि में बाईं ओर के 3x3 वेट टेन्सर पर लागू करें, तो हमें दाईं ओर दिखाई गई क्वांटाइज़्ड मैट्रिक्स मिलेगी। मैं सुझाव दूँगा कि कुछ मिनट लेकर क्वांटाइज़्ड रेंज के अधिकतम और न्यूनतम मान तथा कुछ क्वांटाइज़्ड मानों की गणना करें:
दो-डेसिमल प्रिसीजन वाली यादृच्छिक वेट्स मैट्रिक्स (बाएँ) और उसकी int8 डेटा प्रकार में क्वांटाइज़्ड फ़ॉर्म (दाएँ) का उदाहरण।
हम देख सकते हैं कि
int8का निचला बाउंड मूल टेन्सर के निचले मान के अनुरूप है (-0.40 → 0), जबकि ऊपरी बाउंड मूल टेन्सर के ऊँचे मान से मेल खाता है (0.50 → 255)।यदि हम अब सूत्र (4) का उपयोग करके मानों को डीक्वांटाइज़ करें, तो देखेंगे कि डीक्वांटाइज़्ड मान मूल मानों (बाईं मैट्रिक्स) के क़रीब हैं। हम बिंदु-दर-बिंदु अंतर (दाईं मैट्रिक्स) की गणना करके क्वांटाइज़ेशन त्रुटि निकाल सकते हैं:
क्वांटाइज़्ड वेट्स और स्केल व ज़ीरो-पॉइंट मानों का उपयोग करके मानों को डीक्वांटाइज़ किया जा सकता है (बाएँ)। बिंदु-दर-बिंदु अंतर या क्वांटाइज़ेशन त्रुटि (दाएँ) की गणना की जा सकती है।
रैखिक क्वांटाइज़ेशन केवल क्वांटाइज़्ड वेट्स और स्केल व ज़ीरो-पॉइंट मानों को मेमोरी में संग्रहीत करके मॉडल का आकार घटाता है, जबकि इन्फ़ेरेंस के लिए मूल वेट्स की गणना में इनका उपयोग कर प्रदर्शन बनाए रखता है।
ब्लॉकवाइज़ क्वांटाइज़ेशन
रैखिक क्वांटाइज़ेशन सादगी के कारण लोकप्रिय है, पर मैपिंग बनाने के कई तरीके हैं। आजकल एक और काफ़ी लोकप्रिय तरीका है ब्लॉकवाइज़ क्वांटाइज़ेशन, जो गैर-एकरूप वेट वितरण वाले मॉडलों के लिए रैखिक क्वांटाइज़ेशन से अधिक सटीक होता है।
ब्लॉकवाइज़ क्वांटाइज़ेशन एक अधिक परिष्कृत पद्धति है जिसमें पूरे रेंज की बजाय छोटे ब्लॉक्स में वेट्स को क्वांटाइज़ किया जाता है। यह पद्धति दो मुख्य अवधारणाओं पर निर्भर करती है:
वेट क्वांटाइज़ेशन बनाम एक्टिवेशन क्वांटाइज़ेशन
हमारे मैट्रिक्स उदाहरणों में, हमने मुख्य रूप से मॉडल के वेट्स को क्वांटाइज़ करने की प्रक्रिया पर ध्यान दिया है। वेट क्वांटाइज़ेशन मॉडल अनुकूलन के लिए महत्वपूर्ण है, लेकिन यह भी ध्यान रखना आवश्यक है कि मॉडल के एक्टिवेशन्स को भी क्वांटाइज़ किया जा सकता है।
एक्टिवेशन क्वांटाइज़ेशन नेटवर्क की प्रत्येक लेयर के मध्यवर्ती आउटपुट की प्रिसीजन घटाने की प्रक्रिया है। वेट्स के विपरीत, जो मॉडल के प्रशिक्षण के बाद स्थिर (कॉनस्टेंट) रहते हैं, एक्टिवेशन्स डायनेमिक होते हैं। इसका मतलब है कि प्रत्येक इनपुट के साथ एक्टिवेशन्स बदलते हैं, जिससे उनकी रेंज का अनुमान लगाना कठिन हो जाता है।
आम तौर पर, एक्टिवेशन क्वांटाइज़ेशन को लागू करना वेट क्वांटाइज़ेशन की तुलना में कठिन होता है। इसके लिए सावधानीपूर्वक कैलिब्रेशन आवश्यक है, ताकि एक्टिवेशन्स की डायनामिक रेंज ठीक से कैप्चर हो सके।
वेट क्वांटाइज़ेशन और एक्टिवेशन क्वांटाइज़ेशन पूरक तकनीकें हैं। दोनों तकनीकों को लागू करके, हम मॉडल के आकार में महत्वपूर्ण सुधार कर सकते हैं, बिना प्रदर्शन से बहुत अधिक समझौता किए।
पोस्ट-ट्रेनिंग क्वांटाइज़ेशन (PTQ) बनाम क्वांटाइज़ेशन-अवेयर ट्रेनिंग (QAT)
क्वांटाइज़ेशन विभिन्न समय पर भी किया जा सकता है। यदि हम एक प्री-ट्रेंड मॉडल लेते हैं और इन्फ़ेरेंस चरण के दौरान मॉडल पैरामीटर्स को क्वांटाइज़ करते हैं, तो हम पोस्ट-ट्रेनिंग क्वांटाइज़ेशन (PTQ) कर रहे होते हैं।
इस पद्धति में प्रशिक्षण प्रक्रिया में कोई बदलाव शामिल नहीं होता। पैरामीटर्स की डायनामिक रेंज को रनटाइम पर पुनर्गणित किया जाता है, ठीक वैसे ही जैसे हमने उदाहरण मैट्रिक्स के साथ किया।
दूसरी ओर, क्वांटाइज़ेशन-अवेयर ट्रेनिंग (QAT) लागू करने का विकल्प भी है। इसमें प्रशिक्षण प्रक्रिया को इस तरह संशोधित किया जाता है कि प्रशिक्षण के दौरान क्वांटाइज़ेशन के प्रभावों का अनुकरण हो। मॉडल क्वांटाइज़ेशन शोर के प्रति मज़बूत बनने के लिए प्रशिक्षित होता है, जिससे बेहतर शुद्धता मिलती है।
QAT के दौरान, प्रशिक्षण की मध्यवर्ती अवस्थाएँ वेट्स के क्वांटाइज़्ड संस्करण और मूल अनक्वांटाइज़्ड वेट्स—दोनों—को (मेमोरी में भी!) रखती हैं। इसलिए, इन्फ़ेरेंस के लिए हम मॉडल के क्वांटाइज़्ड संस्करण का उपयोग करते हैं, पर बैकप्रोपेगेशन के दौरान मॉडल के अनक्वांटाइज़्ड वेट्स अपडेट होते हैं।
जैसा अपेक्षित है, हालाँकि अधिक जटिल और समय लेने वाली, QAT आमतौर पर PTQ की तुलना में अधिक शुद्धता देती है।
कैलिब्रेशन तकनीकें
कुछ क्वांटाइज़ेशन विधियों में कैलिब्रेशन चरण की आवश्यकता होती है। उदाहरण के लिए, क्वांटाइज़ेशन से पहले हमें किसी मॉडल की मूल एक्टिवेशन रेंज निर्धारित करनी होती है। सामान्य कैलिब्रेशन में आमतौर पर प्रतिनिधि डेटासेट पर इन्फ़ेरेंस चलाकर क्वांटाइज़ेशन पैरामीटर्स का अनुकूलन और क्वांटाइज़ेशन त्रुटि को न्यूनतम करना शामिल है।
इस कैलिब्रेशन प्रक्रिया के दौरान, क्वांटाइज़ेशन एल्गोरिद्म मॉडल के एक्टिवेशन्स और वेट्स के वितरण और रेंज के बारे में आँकड़े इकट्ठा करता है। ये आँकड़े सर्वोत्तम क्वांटाइज़ेशन पैरामीटर्स निर्धारित करने में मदद करते हैं। वेट्स को क्वांटाइज़ करते समय स्केल और ज़ीरो-पॉइंट की गणना भी एक तरह का कैलिब्रेशन ही है, पर इसके अन्य प्रकार भी हैं:
हालाँकि, QLoRA जैसी क्वांटाइज़ेशन विधियाँ किसी भी कैलिब्रेशन चरण के बिना इस्तेमाल की जा सकती हैं।
ये विधियाँ आमतौर पर मॉडल की सभी रैखिक लेयर्स को क्वांटाइज़्ड रैखिक लेयर्स (
QLinear) से बदल देती हैं। QLinear लेयर्स आंतरिक रूप से क्वांटाइज़ेशन को संभालने के लिए डिज़ाइन की गई हैं, जिससे अतिरिक्त कैलिब्रेशन चरण की आवश्यकता समाप्त हो जाती है। यह क्वांटाइज़ेशन प्रक्रिया को लागू करना अधिक सरल बनाता है, जबकि मॉडल के प्रदर्शन को भी बनाए रखता है।क्वांटाइज़ेशन के उपकरण
Python में कई टूल्स और लाइब्रेरीज़ क्वांटाइज़ेशन का समर्थन करती हैं, जो PTQ और QAT—दोनों—के लिए टूल्स देती हैं। उदाहरण के लिए,
pytorchऔरtensorflowक्वांटाइज़ेशन विधियाँ प्रदान करते हैं, हालांकि मौजूदा मॉडलों में क्वांटाइज़ेशन को सहजता से एकीकृत करने के लिए लाइब्रेरीज़ और मॉडल आंतरिकों की गहरी समझ चाहिए। आधिकारिक PyTorch दस्तावेज़ में क्वांटाइज़ेशन विकल्प देखें।यदि आप इन शक्तिशाली फ्रेमवर्क्स को सीखने में रुचि रखते हैं, तो मैं Deep Learning in Python पाठ्यक्रम की सिफ़ारिश करता/करती हूँ।
अब तक क्वांटाइज़ेशन को आसान चरणों में लागू करने का मेरा पसंदीदा विकल्प Hugging Face की Quanto लाइब्रेरी है, जिसे PyTorch मॉडलों के लिए क्वांटाइज़ेशन प्रक्रिया को सरल बनाने हेतु डिज़ाइन किया गया है।
मॉडल को क्वांटाइज़ करने के व्यावहारिक चरण
Hugging Face की Quanto लाइब्रेरी का उपयोग करते हुए एक विशिष्ट क्वांटाइज़ेशन वर्कफ़्लो निम्नलिखित चरणों से बनेगा:
1. प्री-ट्रेंड मॉडल और उसके अनुरूप टोकनाइज़र का चयन और लोड करना। इस मामले में, हम EuletherAI का Pythia 410M मॉडल का उपयोग करेंगे:
लोड किए गए मॉडल की विभिन्न लेयर्स को विज़ुअलाइज़ करने में
model.gpt_neoxमेथड मदद कर सकता है:मूल मॉडल की लेयर-दर-लेयर रूपरेखा। मॉडल रैखिक लेयर्स और नॉर्मलाइज़ेशन लेयर्स जैसी विभिन्न प्रकार की लेयर्स से बना है।
हम कुछ परीक्षण इन्फ़ेरेंस चलाकर जाँच सकते हैं कि मॉडल सही तरह काम कर रहा है या नहीं। उदाहरण के लिए,
इसके अलावा, चूँकि मॉडल को क्वांटाइज़ करने से हम उसका आकार घटा पाएँगे, इसलिए प्रक्रिया शुरू करने से पहले मूल मॉडल का आकार जाँचना भी रोचक है:
नोट: DataCamp DataLab पर हमें
compute_module_sizes()मेथड लागू मिला हुआ है।अंत में, हम मूल मॉडल के डेंस टेन्सर्स को निम्न प्रकार देख सकते हैं:
जैसा कि हम देख सकते हैं, यह वैसा ही दिखता है जैसा इस लेख में हमने अनक्वांटाइज़्ड मैट्रिक्स के साथ काम किया।
2. क्वांटाइज़ करें।
quantize()मेथड डिफ़ॉल्ट स्टैंडर्ड फ़्लोट मॉडल को सीधे क्वांटाइज़्ड मॉडल में बदलने देता है।इस मामले में, हम केवल मॉडल के वेट्स को
int8डेटा प्रकार में क्वांटाइज़ कर रहे हैं। यह मेथड कैलिब्रेशन चरण सहित मॉडल को निम्न प्रिसीजन एरिथमेटिक के उपयोग में परिवर्तित करता है।यदि हम अब मॉडल की लेयर्स प्रिंट करें, तो देखेंगे कि मूल रैखिक लेयर्स (
Linear) को क्वांटाइज़्ड रैखिक लेयर्स (QLinear) से बदल दिया गया है:क्वांटाइज़्ड मॉडल की लेयर-दर-लेयर रूपरेखा। देखें कि सभी मूल रैखिक लेयर्स क्वांटाइज़्ड रैखिक लेयर्स (QLinear) बन गई हैं।
फिर भी, यदि हम वेट्स की मैट्रिक्स प्रिंट करें, तो दिखेगा कि वे परिवर्तित नहीं हुई हैं:
3. फ़्रीज़ करें। वेट्स पर क्वांटाइज़ेशन प्रभाव लागू करने के लिए, हमें
freeze()मेथड का उपयोग करना होगा।यह मेथड क्वांटाइज़ेशन पैरामीटर्स को मॉडल में एंबेड कर देता है, जिससे वेट्स प्रभावी रूप से लक्ष्य डेटा प्रकार में बदल जाते हैं। अब क्वांटाइज़्ड मॉडल पैरामीटर्स देखें:
जैसा कि हम देख सकते हैं, अब वेट्स Pytorch के
int8डेटा प्रकार की रेंज में हैं।4. अंतिम जाँचें। एक बार मॉडल क्वांटाइज़ हो जाने पर, हम उसका नया घटा हुआ आकार जाँच सकते हैं:
हमने मूल आकार के केवल 35% का मॉडल हासिल कर लिया है!
अंत में, एक सरल इन्फ़ेरेंस के साथ मॉडल के नए प्रदर्शन की जाँच करें:
बेशक, केवल एक इन्फ़ेरेंस से प्रदर्शन जाँचना सार्थक नहीं, इसलिए इसका मूल्यांकन करने के लिए कोई परिमाणात्मक विधि परिभाषित करना अच्छा अभ्यास होगा।
अब आपकी बारी है आज़माने की!
निष्कर्ष
LLMs की बढ़ती मेमोरी आवश्यकताएँ उनके प्रशिक्षण और इन्फ़ेरेंस होस्टिंग—दोनों—को सीमित करती हैं, जिससे LLM-आधारित अनुप्रयोगों की पहुँच और अपनाने में बाधा आती है।
इस लेख में, हमने क्वांटाइज़ेशन की अवधारणा प्रस्तुत की, जिसमें मॉडल के वेट्स और एक्टिवेशन्स की प्रिसीजन घटाकर उसके मेमोरी फ़ुटप्रिंट और संगणनात्मक आवश्यकताओं को कम किया जाता है। यह प्रक्रिया मॉडलों को अधिक कुशल और सुलभ बनाने में मदद करती है, विशेष रूप से संसाधन-सीमित डिवाइसों पर डिप्लॉयमेंट के लिए।
हमने इस तकनीक को कुछ उदाहरणों के माध्यम से अपनाया, जिनमें वेट्स के संख्यात्मक मानों को राउंड किया। फिर हम डाउनकास्टिंग नामक एक सरल क्वांटाइज़ेशन प्रकार की ओर बढ़े। किसी मॉडल को डाउनकास्ट करते समय, पैरामीटर्स को
bfloat16जैसे अधिक कॉम्पैक्ट डेटा प्रकार में बदला जाता है, इन्फ़ेरेंस के लिए। यद्यपि यह मॉडल को इस छोटे डेटा प्रकार में गणनाएँ और एक्टिवेशन्स करने में सक्षम बनाता है, लेकिन डेटा प्रकार के आकार के साथ प्रदर्शन घटता है, औरint8जैसे इंटीजर प्रकारों के साथ यह अप्रभावी रहता है।इसका समाधान करने के लिए, हमने रैखिक क्वांटाइज़ेशन प्रस्तुत किया, जो इन्फ़ेरेंस के दौरान वापस
float32में बदलकर मूल मॉडल के प्रदर्शन के क़रीब रहता है। इससेint8जैसे और भी छोटे डेटा प्रकारों का उपयोग सक्षम होता है।हमने रैखिक क्वांटाइज़ेशन लागू करने के संख्यात्मक चरणों से गुज़रे और Hugging Face की Quanto लाइब्रेरी का उपयोग करके अपना वेट क्वांटाइज़ेशन लागू किया। ख़ास बात यह है कि Quanto लाइब्रेरी के साथ, हम किसी भी PyTorch मॉडल—हगिंग फेस पर उपलब्ध मॉडलों सहित—को क्वांटाइज़ कर सकते हैं।
जो लोग LLaMa 2 या Mistral जैसे भारी मॉडलों को आज़माना चाहते हैं, वे अधिक कंप्यूटिंग शक्ति के लिए अपने DataCamp स्पेस को प्रीमियम में अपग्रेड करने पर विचार करें।
बड़े मॉडलों के लिए, हमें DataCamp Premium Plan में उपलब्ध अतिरिक्त संसाधनों की आवश्यकता हो सकती है।
क्वांटाइज़ेशन तकनीकों में पारंगत होकर, हम कम संसाधनों के साथ बड़े भाषा मॉडलों की पूरी क्षमता खोल सकते हैं, जिससे उन्नत AI अधिक कुशल, सुलभ और बहुमुखी बनता है।
आशा है यह लेख आपको LLMs के लिए क्वांटाइज़ेशन पर हाथों-हाथ मार्गदर्शन देगा!