छोटे और ऑन-डिवाइस मॉडल्समध्यमपाठ 2296 मिनट का पाठ

व्यवहार में Quantisation

Quantisation हर weight को कम bits में स्टोर करता है ताकि मॉडल को कम मेमोरी की ज़रूरत पड़े। एक छोटे numpy उदाहरण के साथ ठीक से समझें कि 8-bit और 4-bit का क्या मतलब है।

पाठ वीडियो में

60 सेकंड में

व्यवहार में Quantisation

Quantisation हर weight को कम bits में स्टोर करता है ताकि मॉडल को कम मेमोरी की ज़रूरत पड़े। एक छोटे numpy उदाहरण के साथ ठीक से समझें कि 8-bit और 4-bit का क्या मतलब है।

1/5
आसान शब्दों में
कल्पना करें कि आप अपनी कक्षा में हर किसी की लंबाई बिल्कुल मिलीमीटर तक नापते हैं, और फिर हर एक को नज़दीकी 5 सेमी में round कर देते हैं। लिस्ट लिखना बहुत छोटा हो जाता है, और आपको अभी भी पता रहता है कि कौन लंबा है और कौन छोटा। यही rounding दरअसल quantisation है।
किसी मॉडल के weights आमतौर पर 16-bit संख्याओं के रूप में स्टोर किए जाते हैं। Quantisation उन्हें कम bits में स्टोर करता है, जैसे कि 8 या 4। कम bits का मतलब है एक छोटी फ़ाइल, कम मेमोरी और अक्सर तेज़ generation, क्योंकि मेमोरी से डेटा को लाना काम का एक बड़ा हिस्सा होता है। इसकी कीमत हर weight में आने वाली थोड़ी सी rounding error है।

8-bit और 4-bit का असल में क्या मतलब है

फ़ॉर्मैटयह कितने अलग-अलग मान स्टोर कर सकता है16-bit के मुकाबले मेमोरी
16-bit65,5361×
8-bit integer (int8)256लगभग ½
4-bit16लगभग ¼
सिर्फ़ 16 संभावित मान बहुत कम लगते हैं। इसकी तरकीब एक scale है: आप छोटी पूर्ण संख्याएं (whole numbers) स्टोर करते हैं और साथ में एक scale नंबर रखते हैं जो बताता है कि हर कदम कितना बड़ा है। weight का उपयोग करने के लिए, आप पूर्ण संख्या को scale से गुणा करते हैं। इसे dequantising कहा जाता है।
  1. 1

    रेंज खोजें

    weights के एक समूह को देखें और सबसे बड़ा absolute मान खोजें।
  2. 2

    एक scale चुनें

    int8 के लिए, scale = सबसे बड़ा मान ÷ 127, ताकि सबसे बड़ा weight 127 पर मैप हो जाए।
  3. 3

    Round करें

    हर weight को scale से भाग दें, निकटतम पूर्ण संख्या में round करें, और इसे int8 के रूप में स्टोर करें।
  4. 4

    ज़रूरत पड़ने पर dequantise करें

    मूल मान के करीब का मान पाने के लिए वापस scale से गुणा करें।

एक छोटा उदाहरण जिसे आप चला सकते हैं

Python: quantise a small array to int8 and back (numpy)python
import numpy as np

x = np.array([0.82, -1.37, 0.05, 2.41, -0.66, 0.0, 1.10, -2.02], dtype=np.float32)

# 1. One scale for the whole array: the largest value maps to 127
scale = np.abs(x).max() / 127

# 2. Quantise: divide, round, clip to the int8 range, store as int8
q = np.clip(np.round(x / scale), -127, 127).astype(np.int8)

# 3. Dequantise: multiply back by the scale
x_back = q.astype(np.float32) * scale

print("scale     :", round(float(scale), 5))
print("int8      :", q)
print("restored  :", np.round(x_back, 3))
print("max error :", float(np.abs(x - x_back).max()))
print("bytes     : float32 =", x.nbytes, "| int8 =", q.nbytes, "+ one scale")
इसे चलाएं और आप देखेंगे कि वापस लाए गए नंबर मूल नंबरों के बहुत करीब हैं, जबकि हर मान अब 4 के बजाय 1 byte लेता है। सबसे बड़ी गड़बड़ी ज़्यादा से ज़्यादा आधा कदम (scale का आधा) होती है।

Outliers से नुकसान क्यों होता है, और blocks से मदद क्यों मिलती है

यदि कोई एक weight बाकी की तुलना में बहुत बड़ा है, तो scale बड़ा हो जाता है, और सभी छोटे weights round होकर उन्हीं कुछ मानों में सिमट जाते हैं। असली फ़ॉर्मैट इससे कई तरीकों से निपटते हैं। एक सामान्य तरीका छोटे blocks में quantise करना है, हर एक का अपना scale होता है, जिससे एक बड़ा मान केवल अपने ब्लॉक को प्रभावित करता है। कई GGUF फ़ॉर्मैट और अन्य 4-bit तरीके इसी तरह काम करते हैं। कुछ तरीके यह तय करने के लिए वास्तविक उदाहरण डेटा को भी देखते हैं कि कौन से weights सबसे ज़्यादा मायने रखते हैं।

क्वालिटी बनाम साइज़

  • 8-bit कई मॉडलों और कार्यों के लिए अक्सर मूल के बहुत करीब होता है।
  • 4-bit बहुत अधिक मेमोरी बचाता है और लैपटॉप व फ़ोन के लिए लोकप्रिय है, जिसमें क्वालिटी में थोड़ी ज़्यादा लेकिन अक्सर स्वीकार्य गिरावट आती है।
  • 4 bits से नीचे, क्वालिटी अक्सर तेज़ी से गिरती है। छोटे मॉडल बड़े मॉडलों की तुलना में ज़्यादा संवेदनशील हो सकते हैं।
  • आपके काम के लिए एकमात्र भरोसेमंद जवाब आपका अपना टेस्ट सेट है, जिसे हर वर्शन पर चलाकर देखा जाए।
जोखिम भरा
  • सबसे छोटी फ़ाइल चुनना क्योंकि यह तेज़ी से डाउनलोड होती है
  • दो या तीन चैट सवालों से क्वालिटी की जांच करना
  • 16-bit पर किसी दूसरे मॉडल से 4-bit मॉडल की तुलना करना
समझदारी भरा
  • सबसे कम bits चुनना जो अभी भी आपके टेस्ट सेट को पास कर लें
  • अपने वास्तविक काम पर, अपने यूज़र्स की भाषाओं में टेस्ट करना
  • एक ही टेस्ट पर अलग-अलग precisions वाले एक ही मॉडल की तुलना करना
नोट
Quantisation फ़ॉर्मैट की टेबल और GPTQ व AWQ जैसे तरीके "Step 17 · Evaluate, shrink, serve" में कवर किए गए हैं। यह पाठ संख्याओं के साथ क्या होता है, उसे समझने के बारे में है।
यह आज़माएं। कोड में, 2.41 को बदलकर 50.0 करें और इसे फिर से चलाएं। 0.05 और -0.66 जैसे छोटे मानों के साथ क्या होता है?

और देखें और पढ़ें

लैब

numpy में आपका अपना int8 और 4-bit quantiser, मापी गई त्रुटियों (errors) और एक outlier प्रयोग के साथ।

~30 min

समस्या

  1. शुरुआती कोड चलाएं। int8 की अधिकतम गड़बड़ी नोट करें।
  2. एक 4-bit वर्शन जोड़ें: -7 से 7 की रेंज का उपयोग करें, ताकि scale सबसे बड़ा मान ÷ 7 हो। int8 के साथ इसकी अधिकतम गड़बड़ी की तुलना करें।
  3. array में एक outlier (उदाहरण के लिए 50.0) जोड़ें। दोनों गड़बड़ियों को फिर से रिकॉर्ड करें। छोटे मानों के साथ क्या हुआ?
  4. अब 4 मानों के blocks में quantise करें, हर ब्लॉक का अपना scale हो। गड़बड़ियों को फिर से रिकॉर्ड करें। आपने क्या सीखा, इस पर तीन वाक्य लिखें।

प्रैक्टिस लैब

कोड में बदलाव करें और इसे रन करें। Python आपके ब्राउज़र में चलता है — हमारे सर्वर पर कुछ नहीं भेजा जाता।

आउटपुट

कोई आउटपुट नहीं। वैल्यूज़ देखने के लिए print(...) जोड़ें।

आपका काम तब पूरा होगा जब

कठिन सवाल

उत्तर देखने से पहले ख़ुद जवाब देने की कोशिश करें। अगर आप इनके जवाब दे सकते हैं, तो आप पाठ समझ गए हैं।

Q1अपने स्वयं के scales वाले blocks गड़बड़ी को कम करते हैं। तो हर ब्लॉक को सिर्फ़ एक मान का लंबा क्यों न बना दिया जाए?दिखाएं

हर ब्लॉक को अपने scale की ज़रूरत होती है, और scale भी मेमोरी लेता है, अक्सर खुद मान से भी ज़्यादा bits। प्रति ब्लॉक एक मान के साथ आप हर weight के लिए एक पूरा scale स्टोर करेंगे और कुछ भी नहीं बचा पाएंगे। वास्तविक फ़ॉर्मैट एक ऐसा ब्लॉक साइज़ चुनते हैं जो scales के लिए लगने वाली अतिरिक्त मेमोरी के साथ सटीकता का संतुलन बनाए रखता है।

Q2किसी मॉडल को 4-bit में quantise करने से यह 16-bit की तुलना में लगभग चार गुना छोटा हो जाता है। generation अक्सर सिर्फ़ छोटा ही नहीं, बल्कि तेज़ भी क्यों होता है?दिखाएं

जब कोई मॉडल टेक्स्ट जनरेट करता है, तो उसे हर नए token के लिए मेमोरी से अपने weights पढ़ने होते हैं। अक्सर चिप गणित की गणना उतनी तेज़ी से कर सकती है जितनी तेज़ी से मेमोरी नंबर डिलीवर नहीं कर पाती। छोटे weights का मतलब है कम डेटा को मूव करना, इसलिए हर token जल्दी तैयार हो सकता है। यह कितना तेज़ होगा, यह हार्डवेयर और रनटाइम पर निर्भर करता है।

जारी रखने के लिए कृपया साइन इन करें।

अक्सर पूछे जाने वाले सवाल

क्या quantisation मॉडल की जानकारी को बदल देता है?

यह जानबूझकर तथ्यों को नहीं हटाता है, लेकिन rounding हर weight में छोटी-छोटी गड़बड़ियां जोड़ देती है। अधिकांश समय जवाब समान रहते हैं। कभी-कभी, विशेष रूप से बहुत कम bits पर, जवाब ऐसे तरीकों से खराब हो जाते हैं जिनका अंदाज़ा लगाना मुश्किल होता है।

क्या मैं खुद किसी मॉडल को quantise कर सकता हूँ?

हाँ। llama.cpp में मॉडलों को GGUF में बदलने और quantise करने के टूल्स शामिल हैं, और अन्य फ़ॉर्मैट के लिए Python लाइब्रेरीज़ हैं। कई पब्लिशर और कम्युनिटी मेंबर्स पहले से तैयार quantised फ़ाइलें भी शेयर करते हैं, लेकिन यह जांच लें कि सोर्स भरोसेमंद हो।

क्या 4-bit हमेशा 8-bit से तेज़ होता है?

अक्सर होता है, क्योंकि मेमोरी से कम डेटा को मूव करना पड़ता है। लेकिन यह हार्डवेयर और रनटाइम पर निर्भर करता है। कुछ चिप्स में कुछ खास फ़ॉर्मैट के लिए तेज़ सपोर्ट होता है और दूसरों के लिए नहीं। अपनी खुद की मशीन पर माप कर देखें।

-128 के बजाय -127 पर clip क्यों करें?

int8 -128 को स्टोर कर सकता है, लेकिन -127 से 127 का उपयोग करने से दोनों तरफ रेंज समान रहती है, इसलिए पॉजिटिव और नेगेटिव मानों के साथ समान व्यवहार होता है। यह एक सामान्य और सरल चुनाव है, अकेला नहीं।

पाठ का टेस्ट

5 सवाल। पास होने और इस पाठ को पूरा करने के लिए 3 सही होने चाहिए (60%)।

टेस्ट देने और अपनी प्रोग्रेस सेव करने के लिए साइन इन करें