COE 592Lecture 5.2المحاضرة 5.2Full guideالشرح الكامل
Quantization (II): Linear Quantization and Integer-Only Inferenceالتكميم (Quantization) الجزء الثاني: التكميم الخطي والاستدلال بالأعداد الصحيحة فقط
The whole lecture on one page, taught concept by concept. Work through the parts in order, mark each concept once you understand it, and open the slide chips when you want the original slides.المحاضرة كاملة في صفحة واحدة، مشروحة مفهومًا مفهومًا. امشِ على الأجزاء بالترتيب، وعلّم كل مفهوم بعد أن تفهمه، وافتح أزرار الشرائح عندما تريد الرجوع إلى الشرائح الأصلية.
- Partsالأجزاء
- 5
- Conceptsالمفاهيم
- 19
- Slidesالشرائح
- 26
- Readingمدة القراءة
- 114 min114 دقيقة
Part 01: Linear Quantization: From Codebooks to an Affine Gridالتكميم الخطي: من دفاتر الترميز إلى شبكة أفينية (affine)
Places linear quantization next to K-means quantization by asking what is stored and what is computed in each. It then works the lecture's 4x4 FP32 weight matrix through 2-bit linear quantization from start to finish: integer codes, zero point -1, scale 1.07, reconstruction and quantization error.يضع التكميم الخطي بجانب تكميم K-means بالسؤال عما يُخزَّن وما يُحسَب في كل منهما. ثم يحل مصفوفة أوزان FP32 بحجم 4x4 من المحاضرة عبر تكميم خطي بـ2 بت من البداية إلى النهاية: الرموز الصحيحة، ونقطة الصفر -1، والمقياس 1.07، وإعادة البناء، وخطأ التكميم.
3 concepts3 مفاهيم, ، slides 1-4الشرائح 1-4
Why this part mattersلماذا يهمّ هذا الجزء
Lecture 05-1 ended with K-means quantization: cluster the weights, store a tiny integer index per weight, and keep a small table of float centroids. The model shrinks, but the arithmetic never leaves floating point. This part introduces the scheme that fixes that: Linear quantization, which stores integers and also computes with them.
Three ideas build on each other. First, the storage and computation table that frames the whole lecture. Second, the forward step that turns FP32 weights into 2-bit codes on an evenly spaced grid. Third, the backward step that rebuilds approximate weights and measures what was lost. Every number in the running example is worked out below, because the midterm is likely to hand you S and Z and ask you to do exactly this by hand.
انتهت المحاضرة 05-1 بتكميم K-means: نجمّع الأوزان في عناقيد (clusters)، ونخزّن لكل وزن فهرسًا صحيحًا صغيرًا، ونحتفظ بجدول صغير من المراكز (centroids) العشرية. يصغر حجم النموذج، لكن الحساب لا يغادر الأعداد العشرية (floating point) أبدًا. يقدّم هذا الجزء الطريقة التي تعالج ذلك: linear quantization، التي تخزّن أعدادًا صحيحة وتحسب بها أيضًا.
ثلاث أفكار يبني بعضها على بعض. الأولى: جدول التخزين والحساب الذي يؤطّر المحاضرة كلها. الثانية: الخطوة الأمامية التي تحوّل أوزان FP32 إلى رموز بطول 2 بت على شبكة متساوية التباعد. الثالثة: الخطوة العكسية التي تعيد بناء أوزان تقريبية وتقيس ما فُقد. كل رقم في المثال المستمر محسوب بالتفصيل أدناه، لأن امتحان منتصف الفصل على الأرجح سيعطيك S وZ ويطلب منك أن تفعل هذا بالضبط يدويًا.
By the end you canفي نهاية هذا الجزء ستستطيع
- Fill in the storage and computation table for FP32, K-means and linear quantization, and justify every cell.تملأ جدول التخزين والحساب لكل من FP32 وتكميم K-means والتكميم الخطي (linear quantization)، وتبرّر كل خانة فيه.
- Explain why an affine grid lets a layer compute with integers while a K-means codebook does not.تشرح لماذا تسمح شبكة affine للطبقة بأن تحسب بالأعداد الصحيحة (integers)، بينما لا يسمح بذلك codebook الخاص بـ K-means.
- Quantize a value with q = clamp(round(r / S) + Z, q_min, q_max) and read its 2-bit two's complement code.تكمّم قيمة باستخدام q = clamp(round(r / S) + Z, q_min, q_max) وتقرأ رمزها بطول 2 بت بصيغة two's complement.
- Reconstruct weights with S(q - Z), compute the error matrix, and check every error against the S/2 bound.تعيد بناء الأوزان باستخدام S(q - Z)، وتحسب مصفوفة الخطأ، وتتحقق من أن كل خطأ لا يتجاوز الحد S/2.
Take the 4×4 weight matrix from last lecture and quantize it two ways to 2 bits. With K-means, each weight becomes an index between 0 and 3, and a four-entry table says index 3 means 2.00, index 2 means 1.50, and so on. With linear quantization, each weight becomes a signed code between -2 and 1, and one formula, (q - (-1)) × 1.07, turns any code back into a real number. Both versions use 2 bits per weight. The difference shows up only when the layer runs.
خذ مصفوفة الأوزان 4×4 من المحاضرة السابقة وكمّمها بطريقتين إلى 2 بت. مع K-means، يصبح كل وزن فهرسًا بين 0 و3، وجدول من أربعة مدخلات يقول إن الفهرس 3 يعني 2.00، والفهرس 2 يعني 1.50، وهكذا. ومع التكميم الخطي، يصبح كل وزن رمزًا بإشارة (signed) بين -2 و1، وصيغة واحدة هي (q - (-1)) × 1.07 تعيد أي رمز إلى عدد حقيقي. كلا النسختين تستخدم 2 بت لكل وزن. الفرق لا يظهر إلا عندما تعمل الطبقة.
The table that frames the lectureالجدول الذي يؤطّر المحاضرة
Slide 2 compares the schemes on two rows: what sits in memory, and what kind of arithmetic the processor performs. Learn it as a grid, because it is an easy short-answer question.
تقارن الشريحة 2 بين الطرق على صفّين: ما الذي يقبع في الذاكرة، وأي نوع من الحساب ينفّذه المعالج. احفظه على شكل شبكة، لأنه سؤال سهل من نوع الإجابة القصيرة.
| Schemeالطريقة | Storageالتخزين | Computationالحساب |
|---|---|---|
| FP32 (no quantization)FP32 | Floating-point weightsأعداد عشرية (floating-point) للأوزان | Floating-point arithmeticحساب بالأعداد العشرية (floating-point) |
| K-means-basedK-means | Integer indices plus a floating-point codebookفهارس صحيحة (integer indices) مع codebook من الأعداد العشرية | Floating-point arithmeticحساب بالأعداد العشرية (floating-point) |
| Linearخطي (Linear) | Integer weights (plus one S and one Z per tensor)أوزان صحيحة (مع S واحدة وZ واحدة لكل tensor) | Integer arithmeticحساب بالأعداد الصحيحة (integer) |
| Binary/TernaryBinary/Ternary | Covered in a later lectureيُشرح في محاضرة لاحقة | Covered in a later lectureيُشرح في محاضرة لاحقة |
K-means-based quantization wins on storage but not on compute. Before a multiply can happen, every index must be looked up in the Codebook, and what comes out is a float. The multiply-accumulate (MAC) that follows is a floating-point MAC, exactly as in the original model. K-means saves memory and memory traffic, and that is all it saves.
K-means quantization يتفوق في التخزين لكن ليس في الحساب. قبل أن يحدث أي ضرب، يجب البحث عن كل فهرس في الـ codebook، وما يخرج من هذا البحث عدد عشري (float). وعملية الضرب والجمع التراكمي (MAC) التي تليه هي MAC عشرية، تمامًا كما في النموذج الأصلي. K-means يوفّر الذاكرة وحركة البيانات من الذاكرة وإليها، وهذا كل ما يوفّره.
Linear quantization changes the second row too. The reason is algebraic. Every real value in a tensor is written as r = S(q - Z) with the same Scale (S) S and the same Zero point (Z) Z. In a dot product of weights and inputs, the common scale factors out of the whole sum:
التكميم الخطي يغيّر الصف الثاني أيضًا. والسبب جبري. كل قيمة حقيقية في الـ tensor تُكتب على الصورة r = S(q - Z) بنفس الـ scale S ونفس الـ zero point Z. وفي حاصل الضرب النقطي (dot product) بين الأوزان والمدخلات، يخرج الـ scale المشترك عاملًا من المجموع كله:
Everything inside the sum is integer subtraction, multiplication and addition. The floats S_W S_X are applied once per output, not once per MAC, and part 3 shows that even that single rescale can be done as an integer multiply and a bit shift. That is what makes Integer-only inference possible. A codebook gives no such shortcut: its centroids are arbitrary floats like 2.00, 1.50, 0.00 and -1.00, with no common factor and offset to pull out.
كل ما داخل المجموع عمليات طرح وضرب وجمع على أعداد صحيحة. أما القيم العشرية S_W S_X فتُطبَّق مرة واحدة لكل مخرج، لا مرة لكل MAC، والجزء 3 يبيّن أن حتى إعادة التحجيم (rescale) الوحيدة هذه يمكن تنفيذها بضرب صحيح وإزاحة بتات (bit shift). وهذا ما يجعل integer-only inference ممكنًا. أما الـ codebook فلا يقدّم اختصارًا كهذا: مراكزه أعداد عشرية عشوائية مثل 2.00 و1.50 و0.00 و-1.00، ليس لها عامل مشترك ولا إزاحة (offset) مشتركة يمكن إخراجهما.
| Questionالسؤال | K-means-basedK-means | Linearالخطي (Linear) |
|---|---|---|
| How a code becomes a real valueكيف يتحول الرمز إلى قيمة حقيقية | Table lookup: r = codebook[i]بحث في جدول: r = codebook[i] | Formula: r = S(q - Z)صيغة: r = S(q - Z) |
| Where the levels sitأين تقع المستويات | Anywhere: centroids follow the dataفي أي مكان: المراكز (centroids) تتبع البيانات | On a uniform grid of step Sعلى شبكة منتظمة خطوتها S |
| Extra storageالتخزين الإضافي | One float per centroidعدد عشري (float) واحد لكل مركز | One float S and one integer Zعدد عشري واحد S وعدد صحيح واحد Z |
| Multiply-accumulateالضرب والجمع التراكمي (MAC) | Floating-point MACs on looked-up valuesعمليات MAC عشرية على القيم المستخرجة من الجدول | Integer MACs on the codes, one rescale at the endعمليات MAC صحيحة على الرموز، وإعادة تحجيم (rescale) واحدة في النهاية |
| Needs a floating-point unit at runtimeيحتاج وحدة أعداد عشرية (floating-point unit) وقت التشغيل | Yesنعم | No, the rescale can be fixed-pointلا، يمكن تنفيذ إعادة التحجيم بالفاصلة الثابتة (fixed-point) |
| Best atيتفوق في | Accuracy at very low bit widths for storageالدقة عند أعداد بتات منخفضة جدًا لأجل التخزين | Speed and energy on integer hardwareالسرعة والطاقة على العتاد الصحيح (integer hardware) |
Storage also differs a little, even at the same bit width. For the 16 example weights:
ويختلف التخزين قليلًا أيضًا، حتى عند نفس عدد البتات (bit width). بالنسبة لأوزان المثال الـ 16:
| Schemeالطريقة | Codesالرموز | Side informationالمعلومات الجانبية | Totalالمجموع |
|---|---|---|---|
| FP32FP32 | 16 × 32 = 512 bits16 × 32 = 512 bits | nothingلا شيء | 512 bits512 bits |
| K-means, 4 clustersK-means بأربعة عناقيد (clusters) | 16 × 2 = 32 bits16 × 2 = 32 bits | 4 × 32 = 128 bits (codebook)4 × 32 = 128 bits (codebook) | 160 bits160 bits |
| Linear, 2 bitsخطي (Linear) بطول 2 بت | 16 × 2 = 32 bits16 × 2 = 32 bits | 32 bits (S) + 2 bits (Z)32 bits (S) + 2 bits (Z) | 66 bits66 bits |
For a real layer with millions of weights the side information is negligible in both schemes, so the storage row is roughly a tie. The computation row decides the matter. Integer adders and multipliers cost far less energy and silicon area than floating-point ones (recall the energy table from Lecture 05-1), and many microcontrollers and NPUs have no floating-point unit at all.
في طبقة حقيقية فيها ملايين الأوزان تكون المعلومات الجانبية (side information) مهملة في الطريقتين، لذا يكون صف التخزين متعادلًا تقريبًا. صف الحساب هو الذي يحسم الأمر. وحدات الجمع والضرب الصحيحة تستهلك طاقة ومساحة سيليكون أقل بكثير من نظيراتها العشرية (تذكّر جدول الطاقة من المحاضرة 05-1)، وكثير من المتحكمات الدقيقة (microcontrollers) ووحدات NPU لا تحتوي على وحدة أعداد عشرية (floating-point unit) أصلًا.
Quick checkاختبار سريع
A K-means quantized layer must run on a microcontroller with no floating-point unit. What is the problem?طبقة مكمّمة بـ K-means يجب أن تعمل على متحكم دقيق (microcontroller) لا يحتوي على وحدة أعداد عشرية (floating-point unit). ما المشكلة؟
Recall
Without looking, fill in the storage and computation cells for FP32, K-means and linear quantization.دون النظر، املأ خانات التخزين والحساب لكل من FP32 وK-means والتكميم الخطي.
Start with one weight, 1.48, and a ruler whose marks are 1.07 apart. Divide by the mark spacing: 1.48 / 1.07 = 1.383. The nearest whole mark is 1. Now shift every mark number down by one so that the mark sitting on real zero is called -1. The weight lands on mark 1 + (-1) = 0. That is the whole of the forward step.
ابدأ بوزن واحد، 1.48، ومسطرة تفصل بين علاماتها مسافة 1.07. اقسم على المسافة بين العلامات: 1.48 / 1.07 = 1.383. أقرب علامة صحيحة هي 1. الآن أنقص رقم كل علامة بواحد بحيث تُسمّى العلامة الواقعة على الصفر الحقيقي -1. يقع الوزن على العلامة 1 + (-1) = 0. وهذه هي الخطوة الأمامية بكاملها.
The affine mappingالتحويل الـ affine
Linear quantization ties every integer code q to a real value r with an Affine mapping: a multiply by a scale plus a fixed offset.
يربط التكميم الخطي كل رمز صحيح q بقيمة حقيقية r عبر affine mapping: ضرب في scale مع إزاحة (offset) ثابتة.
- Scale (S) S is a floating-point number: the real distance between two neighbouring codes. In the example S = 1.07.الـ scale S عدد عشري (floating-point): هو المسافة الحقيقية بين رمزين متجاورين. في المثال S = 1.07.
- Zero point (Z) Z is an integer of the same type as the codes: the code that means real 0, since S(Z - Z) = 0 for any S. In the example Z = -1; part 2 derives it as round(q_min - r_min / S) = round(-2 + 1.08 / 1.07) = round(-0.99) = -1.الـ zero point Z عدد صحيح من نفس نوع الرموز: هو الرمز الذي يعني الصفر الحقيقي 0، لأن S(Z - Z) = 0 لأي قيمة S. في المثال Z = -1، والجزء 2 يشتقّه على أنه round(q_min - r_min / S) = round(-2 + 1.08 / 1.07) = round(-0.99) = -1.
- The codes are signed Bit width (N) integers. With N = 2, q_min and q_max are -2 and 1, so there are only 4 levels.الرموز أعداد صحيحة بإشارة (signed) بعدد بتات يحدده الـ bit width. عندما N = 2، تكون قيمتا q_min, q_max هما -2 و1، فلا يوجد إلا 4 مستويات.
The mapping is called affine rather than linear in the strict sense because of the offset Z. Its job is to give real zero an exact code. Zero padding, ReLU outputs and pruned weights are all exactly zero, and Jacob et al. require that they quantize with no error at all. Part 2 shows how to derive S and Z from r_min and r_max. Here, take them as given.
يُسمّى هذا التحويل affine وليس خطيًا (linear) بالمعنى الدقيق بسبب الإزاحة Z. مهمتها أن تعطي الصفر الحقيقي رمزًا دقيقًا (exact code). الحشو بالأصفار (zero padding) ومخرجات ReLU والأوزان المقلّمة (pruned) كلها أصفار تامة، وJacob et al. يشترطون أن تُكمَّم دون أي خطأ على الإطلاق. الجزء 2 يبيّن كيف نشتق S وZ من r_min, r_max. هنا، اعتبرهما معطيين.
The forward formula the slides leave outالصيغة الأمامية التي تتجاهلها الشرائح
Slide 4 shows the weights turning into codes, but it never writes down how. Inverting r = S(q - Z) gives q = r / S + Z, which is usually not a whole number. So round it, and clamp anything that falls outside the integer range:
تعرض الشريحة 4 الأوزان وهي تتحول إلى رموز، لكنها لا تكتب أبدًا كيف يحدث ذلك. عكس الصيغة r = S(q - Z) يعطي q = r / S + Z، وهي في العادة ليست عددًا صحيحًا. لذا نقرّبها (round)، ونقصّ (clamp) أي قيمة تقع خارج مدى الأعداد الصحيحة:
Rounding r / S before adding Z works because Z is already an integer, and it keeps real 0 landing exactly on code Z. This is the form given in the Nagel et al. white paper on neural network quantization.
تقريب r / S قبل إضافة Z يصحّ لأن Z عدد صحيح أصلًا، وهو يضمن أن يقع الصفر الحقيقي 0 تمامًا على الرمز Z. هذه هي الصيغة الواردة في الورقة البيضاء (white paper) لـ Nagel et al. عن تكميم الشبكات العصبية.
Worked exampleمثال محلول
Quantize three weights with S = 1.07 and Z = -1كمّم ثلاثة أوزان باستخدام S = 1.07 وZ = -1
r = 1.48r = 1.48
1.48 / 1.07 = 1.383, which rounds to 1. Add Z: 1 + (-1) = 0. Inside [-2, 1], so q = 0, stored as binary 00.1.48 / 1.07 = 1.383، ويُقرَّب إلى 1. أضف Z: 1 + (-1) = 0. القيمة داخل [-2, 1]، إذن q = 0، ويُخزَّن بالثنائي 00.r = -0.98r = -0.98
-0.98 / 1.07 = -0.916, which rounds to -1. Add Z: -2. Stored as 10.-0.98 / 1.07 = -0.916، ويُقرَّب إلى -1. أضف Z: -2. ويُخزَّن على أنه 10.r = 2.12, the largest weightr = 2.12، أكبر وزن
2.12 / 1.07 = 1.981, which rounds to 2. Add Z: 1, exactly q_max. Stored as 01. No clamping needed.2.12 / 1.07 = 1.981، ويُقرَّب إلى 2. أضف Z: 1، وهي بالضبط q_max. ويُخزَّن على أنه 01. لا حاجة إلى القصّ (clamping).Resultالنتيجة
Doing this for all 16 weights gives the code matrix on slide 4: [[1, -2, 0, -1], [-1, -1, -2, 1], [-2, 1, -1, -2], [1, -1, 0, 0]].تطبيق ذلك على الأوزان الـ 16 كلها يعطي مصفوفة الرموز في الشريحة 4: [[1, -2, 0, -1], [-1, -1, -2, 1], [-2, 1, -1, -2], [1, -1, 0, 0]].
Reading the 2-bit codesقراءة الرموز بطول 2 بت
The codes are stored in Two's complement. With two bits the leading bit carries weight -2 and the trailing bit carries +1, which gives the table on slide 4. The slides colour each level: blue for 1, pink for 0, orange for -1, green for -2. The simulator below also gives each of the four levels its own colour, using the site palette, with a legend under the matrices.
تُخزَّن الرموز بصيغة two's complement. مع بتين، يحمل البت الأول وزن -2 ويحمل البت الأخير وزن +1، وهذا يعطي الجدول في الشريحة 4. تلوّن الشرائح كل مستوى: الأزرق لـ 1، والوردي لـ 0، والبرتقالي لـ -1، والأخضر لـ -2. والمحاكي أدناه يعطي كذلك كل مستوى من المستويات الأربعة لونه الخاص، باستخدام ألوان الموقع، مع مفتاح ألوان تحت المصفوفات.
| Binaryالثنائي | Code qالرمز q | Real value S(q - Z)القيمة الحقيقية S(q - Z) |
|---|---|---|
| 0101 | 11 | (1 + 1) × 1.07 = 2.14(1 + 1) × 1.07 = 2.14 |
| 0000 | 00 | (0 + 1) × 1.07 = 1.07(0 + 1) × 1.07 = 1.07 |
| 1111 | -1-1 | (-1 + 1) × 1.07 = 0(-1 + 1) × 1.07 = 0 |
| 1010 | -2-2 | (-2 + 1) × 1.07 = -1.07(-2 + 1) × 1.07 = -1.07 |
Recall
Quantize r = -0.14 and r = 1.87 with S = 1.07 and Z = -1. Give the codes in decimal and binary.كمّم r = -0.14 وr = 1.87 باستخدام S = 1.07 وZ = -1. أعطِ الرموز بالنظامين العشري والثنائي.
Recall
Why must the zero point Z be an integer while the scale S is a float?لماذا يجب أن يكون الـ zero point Z عددًا صحيحًا بينما الـ scale S عدد عشري؟
Slide 4 turns 16 weights into codes, then back into numbers. What comes back has only four distinct values: -1.07, 0, 1.07 and 2.14. The weights 1.48, 1.53 and 1.49 all come back as 1.07. That collapse is the price of using 2 bits.
تحوّل الشريحة 4 الأوزان الـ 16 إلى رموز، ثم تعيدها إلى أعداد. ما يعود ليس فيه إلا أربع قيم مختلفة: -1.07 و0 و1.07 و2.14. الأوزان 1.48 و1.53 و1.49 كلها تعود على أنها 1.07. هذا الانهيار هو ثمن استخدام 2 بت.
Reconstruct with the affine mapإعادة البناء بالتحويل الـ affine
The Reconstructed weights are just S(q - Z) applied to each Quantized value (q). With Z = -1, that is (q + 1) × 1.07:
الـ reconstructed weights ما هي إلا S(q - Z) مطبّقة على كل quantized value. ومع Z = -1، تصبح (q + 1) × 1.07:
- q = 1 gives 2.14, and q = 0 gives 1.07.q = 1 يعطي 2.14، وq = 0 يعطي 1.07.
- q = -1 gives 0 exactly, and q = -2 gives -1.07.q = -1 يعطي 0 بالضبط، وq = -2 يعطي -1.07.
The reconstructed matrix is [[2.14, -1.07, 1.07, 0], [0, 0, -1.07, 2.14], [-1.07, 2.14, 0, -1.07], [2.14, 0, 1.07, 1.07]]. In a real integer pipeline this matrix is never built in memory. It is the meaning of the codes, which is what we compare against the original to measure the damage.
المصفوفة المعاد بناؤها هي [[2.14, -1.07, 1.07, 0], [0, 0, -1.07, 2.14], [-1.07, 2.14, 0, -1.07], [2.14, 0, 1.07, 1.07]]. في خط معالجة صحيح حقيقي (integer pipeline) لا تُبنى هذه المصفوفة في الذاكرة أبدًا. إنها معنى الرموز، وهي ما نقارنه بالأصل لقياس حجم الضرر.
Quantization error and the S/2 boundخطأ التكميم والحد S/2
The Quantization error of each cell is the original minus the reconstruction, e = r - S(q - Z):
الـ quantization error لكل خانة هو القيمة الأصلية ناقص القيمة المعاد بناؤها، e = r - S(q - Z):
Round-to-nearest picks the closest level, and neighbouring levels are S apart, so a value that is not clipped is never more than half a step from its level. For every such value, |e| ≤ S/2 = 0.535. The worst cell is 1.53: it divides to 1.430, rounds down to code 0, and comes back as 1.07, an error of 0.46. That is close to the bound, because 1.53 sits near the midpoint 1.605 between 1.07 and 2.14. The two zeros have error 0, as promised by the exact zero point.
التقريب إلى الأقرب (round-to-nearest) يختار أقرب مستوى، والمستويات المتجاورة تفصل بينها مسافة S، لذا فالقيمة التي لم تُقصّ (not clipped) لا تبعد أبدًا عن مستواها أكثر من نصف خطوة. لكل قيمة كهذه، |e| ≤ S/2 = 0.535. أسوأ خانة هي 1.53: قسمتها تعطي 1.430، فتُقرَّب للأسفل إلى الرمز 0، وتعود على أنها 1.07، بخطأ قدره 0.46. وهذا قريب من الحد، لأن 1.53 تقع قرب نقطة المنتصف 1.605 بين 1.07 و2.14. والصفران خطؤهما 0، كما يضمن الـ zero point الدقيق.
More than half a step beyond either end level, clamping takes over and the error grows with the distance. Nagel et al. call this clipping error, as opposed to rounding error. A wider range means less clipping but a larger S and more rounding error. Choosing the range is the central trade-off in linear quantization.
عندما تبتعد القيمة أكثر من نصف خطوة خارج أيّ من المستويين الطرفيين، يتولى القصّ (clamping) الأمر ويكبر الخطأ مع المسافة. يسمّي Nagel et al. هذا خطأ القصّ (clipping error)، في مقابل خطأ التقريب (rounding error). المدى الأوسع يعني قصًّا أقل، لكنه يعني S أكبر وخطأ تقريب أكبر. اختيار المدى هو المفاضلة (trade-off) المحورية في التكميم الخطي.
Why the top level is 2.14 and not 2.12لماذا المستوى الأعلى 2.14 وليس 2.12
The largest weight is r_max = 2.12, yet the top level is 2.14, and the bottom level -1.07 sits just above r_min = -1.08. Two roundings cause this. The exact scale is 3.20 / 3 = 1.0667, which the slides round to 1.07. The exact offset would be -0.99, but the zero point must be an integer so that real zero stays exact, so it is rounded to -1. Together these shift and stretch the grid slightly, so it covers [-1.07, 2.14] instead of [-1.08, 2.12]. The cost is tiny: -1.08 still reconstructs with an error of only -0.01, well within S/2.
أكبر وزن هو r_max = 2.12، ومع ذلك فالمستوى الأعلى هو 2.14، والمستوى الأدنى -1.07 يقع فوق r_min = -1.08 بقليل. السبب عمليتا تقريب. الـ scale الدقيق هو 3.20 / 3 = 1.0667، وتقرّبه الشرائح إلى 1.07. والإزاحة الدقيقة كانت ستكون -0.99، لكن الـ zero point يجب أن يكون عددًا صحيحًا ليبقى الصفر الحقيقي دقيقًا، لذا يُقرَّب إلى -1. معًا، تُزيح هاتان العمليتان الشبكة وتمطّانها قليلًا، فتغطي [-1.07, 2.14] بدلًا من [-1.08, 2.12]. والكلفة ضئيلة: -1.08 ما زالت تُعاد بناؤها بخطأ قدره -0.01 فقط، وهو أقل بكثير من S/2.
Try it at other bit widthsجرّبه بأعداد بتات أخرى
The simulator below runs the same matrix through the same formulas. At 2 bits it reproduces slide 4 cell for cell. Slide up to 8 bits, the INT8 format used in deployment, and watch S shrink by roughly half per extra bit, the levels multiply, and the error heatmap fade.
المحاكي أدناه يمرّر المصفوفة نفسها عبر الصيغ نفسها. عند 2 بت يعيد إنتاج الشريحة 4 خانةً بخانة. حرّك المؤشر حتى 8 بت، وهي صيغة INT8 المستخدمة في النشر (deployment)، وراقب S وهي تتقلص إلى النصف تقريبًا مع كل بت إضافي، والمستويات وهي تتضاعف، وخريطة الخطأ الحرارية (heatmap) وهي تبهت.
Each code is q = clamp(round(r / S) + Z, q_min, q_max). The range is [-1.08, 2.12], and S is rounded up to three significant figures, which is how the slide gets 1.07 at 2 bits. Clipped values this run: 0. Hover a cell for its exact numbers.يُحسب كل رمز بالعلاقة q = clamp(round(r / S) + Z, q_min, q_max). المدى هو [-1.08, 2.12]، وتُقرَّب S إلى الأعلى لثلاثة أرقام معنوية، وبهذا تحصل الشريحة على 1.07 عند 2 بت. عدد القيم المقصوصة في هذا التشغيل: 0. مرّر المؤشر فوق أي خلية لترى أرقامها الدقيقة.
Quick checkاختبار سريع
With S = 1.07 and Z = -1, what does the weight 1.53 reconstruct to?مع S = 1.07 وZ = -1، ما القيمة التي يُعاد بناء الوزن 1.53 إليها؟
Quick checkاختبار سريع
What is the largest possible error for an in-range weight when S = 1.07?ما أكبر خطأ ممكن لوزن داخل المدى عندما S = 1.07؟
Recall
Why does the reconstructed matrix contain only four distinct values, and what are they?لماذا لا تحتوي المصفوفة المعاد بناؤها إلا على أربع قيم مختلفة، وما هي؟
Recapالخلاصة
If you remember nothing elseإن لم تتذكر شيئاً آخر فتذكّر هذا
- FP32 stores floats and computes in floats. K-means stores integer indices plus a float codebook, but still computes in floats. Linear quantization stores integers and computes with integers.FP32 يخزّن أعدادًا عشرية (floats) ويحسب بها. K-means يخزّن فهارس صحيحة (integer indices) مع codebook من الأعداد العشرية، لكنه ما زال يحسب بالأعداد العشرية. التكميم الخطي يخزّن أعدادًا صحيحة ويحسب بالأعداد الصحيحة.
- Linear quantization is an affine map r = S(q - Z): S is a float step size, Z is an integer code that stands for real 0.التكميم الخطي هو تحويل affine صيغته r = S(q - Z): حيث S حجم خطوة عشري (float)، وZ رمز صحيح يمثّل الصفر الحقيقي.
- Because one S and one Z serve a whole tensor, S factors out of every dot product, leaving pure integer multiply-accumulates. A codebook of arbitrary centroids has no such common factor.لأن قيمة S واحدة وقيمة Z واحدة تخدمان الـ tensor كله، تخرج S عاملًا مشتركًا من كل حاصل ضرب نقطي (dot product)، فلا يبقى إلا عمليات ضرب وجمع تراكمي (MAC) صحيحة خالصة. أما codebook من مراكز (centroids) عشوائية فليس له عامل مشترك كهذا.
- Forward: q = clamp(round(r / S) + Z, q_min, q_max). Backward: r ≈ S(q - Z). The slides only show the backward direction.الاتجاه الأمامي: q = clamp(round(r / S) + Z, q_min, q_max). الاتجاه العكسي: r ≈ S(q - Z). الشرائح تعرض الاتجاه العكسي فقط.
- Running example: 2-bit codes in [-2, 1], Z = -1, S = 1.07. The 16 weights collapse onto four values: -1.07, 0, 1.07 and 2.14.المثال المستمر: رموز بطول 2 بت في المدى [-2, 1]، وZ = -1، وS = 1.07. تنهار الأوزان الـ 16 إلى أربع قيم فقط: -1.07 و0 و1.07 و2.14.
- Error = r - S(q - Z). For any in-range value it is at most S/2 = 0.535 in size. The worst cell in the example is 1.53, with error 0.46.الخطأ = r - S(q - Z). لأي قيمة داخل المدى لا يتجاوز حجمه S/2 = 0.535. أسوأ خانة في المثال هي 1.53، وخطؤها 0.46.
- The top level 2.14 sits above r_max = 2.12 because Z was rounded to an integer (so 0 stays exact) and S was rounded up to 1.07.المستوى الأعلى 2.14 يقع فوق r_max = 2.12 لأن Z قُرّبت إلى عدد صحيح (ليبقى الصفر دقيقًا)، ولأن S قُرّبت للأعلى إلى 1.07.
Sourcesالمصادر
- Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference (Jacob et al.)PaperCVPR 2018, arXiv:1712.05877Equation 1 defines r = S(q - Z), with Z an integer chosen so that real 0 is exactly representable, and builds integer-only inference on it.المعادلة 1 تعرّف r = S(q - Z)، حيث Z عدد صحيح يُختار بحيث يُمثَّل الصفر الحقيقي 0 بدقة، وتبني الورقة عليها الاستدلال بالأعداد الصحيحة فقط (integer-only inference).(opens in a new tab)(يفتح في تبويب جديد)
- A White Paper on Neural Network Quantization (Nagel et al.)PaperQualcomm AI Research, arXiv:2106.08295Section 2.2 gives the forward formula clamp(round(x / s) + z) and the rounding error range [-s/2, s/2], and separates rounding from clipping error.القسم 2.2 يعطي الصيغة الأمامية clamp(round(x / s) + z) ومدى خطأ التقريب [-s/2, s/2]، ويفصل بين خطأ التقريب (rounding error) وخطأ القصّ (clipping error).(opens in a new tab)(يفتح في تبويب جديد)
- Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding (Han, Mao, Dally)PaperICLR 2016, arXiv:1510.00149The K-means weight sharing scheme: only the codebook of shared weights and the indices are stored.طريقة مشاركة الأوزان (weight sharing) بـ K-means: لا يُخزَّن إلا الـ codebook الذي يحوي الأوزان المشتركة، والفهارس.(opens in a new tab)(يفتح في تبويب جديد)
- MIT 6.5940 EfficientML.ai, Lecture 6: Quantization (Part II)DocsMIT HAN LabThe course these slides follow, with lecture videos and slides on linear quantization.المقرر الذي تتبعه هذه الشرائح، مع فيديوهات المحاضرات وشرائح عن التكميم الخطي (linear quantization).(opens in a new tab)(يفتح في تبويب جديد)
Part 02: Scale and Zero Point: Deriving S and Zالمقياس (Scale) ونقطة الصفر (Zero Point): اشتقاق S وZ
Defines the affine map r = S(q - Z), where the scale S is a float and the zero point Z is an integer, along with the signed N-bit integer range. Both parameters are then derived by matching the endpoints of the float range to the endpoints of the integer range, and computed for the running example.يعرّف الربط الأفيني r = S(q - Z)، حيث المقياس S عدد عائم ونقطة الصفر Z عدد صحيح، مع مدى العدد الصحيح ذي الإشارة من N بت. ثم يُشتق المعاملان بمطابقة طرفي مدى الأعداد العائمة مع طرفي مدى الأعداد الصحيحة، ويُحسبان للمثال الجاري.
4 concepts4 مفاهيم, ، slides 5-10الشرائح 5-10
Why this part mattersلماذا يهمّ هذا الجزء
Part 1 gave the idea: store small integers and recover real numbers with a straight line. This part finds the two numbers that define that line. One is the scale S and the other is the zero point Z. Every later formula in this lecture assumes you can produce both from a range in under a minute. That covers the quantized matrix multiply, the symmetric shortcut and the integer-only layer.
The chain is short. First, what each symbol in r = S(q - Z) is and what type it has. Second, the integer range an N-bit code can hold. Third, the derivation of S from the two ends of the range. Fourth, the derivation of Z and the reason it must be an integer. For the COE 592 midterm on Wed 28 Oct 2026, expect three question shapes: derive S and Z, compute them for given numbers, and explain why zero must be exactly representable.
أعطانا الجزء 1 الفكرة: نخزّن أعدادًا صحيحة صغيرة ونستعيد الأعداد الحقيقية بخط مستقيم. هذا الجزء يجد العددين اللذين يحددان ذلك الخط. الأول هو المقياس S (scale) والثاني هو نقطة الصفر Z (zero point). كل صيغة لاحقة في هذه المحاضرة تفترض أنك تستطيع حسابهما من مدى معين في أقل من دقيقة. ويشمل ذلك ضرب المصفوفات المكمّمة، والاختصار المتماثل (symmetric)، والطبقة التي تعمل بالأعداد الصحيحة فقط.
السلسلة قصيرة. أولًا: ما معنى كل رمز في r = S(q - Z) وما نوعه. ثانيًا: مدى الأعداد الصحيحة الذي يستوعبه رمز من N بت. ثالثًا: اشتقاق S من طرفي المدى. رابعًا: اشتقاق Z وسبب وجوب أن يكون عددًا صحيحًا. في اختبار منتصف الفصل لمقرر COE 592 يوم Wed 28 Oct 2026، توقّع ثلاثة أشكال من الأسئلة: اشتقاق S وZ، وحسابهما لأعداد معطاة، وشرح لماذا يجب أن يكون الصفر قابلًا للتمثيل بدقة تامة.
By the end you canفي نهاية هذا الجزء ستستطيع
- State the affine map r = S(q - Z) and say which symbols are integers and which are floating point.تكتب الدالة التآلفية r = S(q - Z) وتحدد أي الرموز أعداد صحيحة وأيها أعداد عشرية (floating point).
- Write the signed N-bit range q_min = -2^(N-1), q_max = 2^(N-1) - 1 for any N without a table.تكتب مدى الأعداد الصحيحة ذات الإشارة بعدد N من البتات، q_min = -2^(N-1) و q_max = 2^(N-1) - 1، لأي قيمة N دون الرجوع إلى جدول.
- Derive S = (r_max - r_min) / (q_max - q_min) by subtracting the two endpoint equations, and explain why Z cancels.تشتق S = (r_max - r_min) / (q_max - q_min) بطرح معادلتي الطرفين، وتشرح لماذا يختفي Z.
- Derive Z = round(q_min - r_min / S) and explain why Z must be an integer.تشتق Z = round(q_min - r_min / S) وتشرح لماذا يجب أن يكون Z عددًا صحيحًا.
- Compute S, Z, a quantized code and its reconstruction for any given range and bit width.تحسب S و Z والرمز المكمّم (quantized code) والقيمة المعاد بناؤها منه لأي مدى وأي عدد بتات.
Take the top-left weight of the slide's 4 x 4 matrix, 2.09. After quantization, the chip stores the 2-bit code 1. It also keeps two numbers for the whole matrix: Z = -1 and S = 1.07. To get a real number back it computes (1 - (-1)) x 1.07 = 2.14. That is close to 2.09 but not equal to it.
خذ الوزن في الزاوية العليا اليسرى من مصفوفة الشريحة ذات الحجم 4 x 4، وقيمته 2.09. بعد التكميم تخزّن الشريحة الإلكترونية الرمز ذا البتين 1. وتحتفظ أيضًا بعددين للمصفوفة كلها: Z = -1 وS = 1.07. ولكي تستعيد عددًا حقيقيًا تحسب (1 - (-1)) x 1.07 = 2.14. هذه القيمة قريبة من 2.09 لكنها لا تساويها.
The map and the types of its symbolsالدالة وأنواع رموزها
That recovery rule is Linear quantization written as an Affine mapping: a scale times a shifted integer.
قاعدة الاستعادة هذه هي linear quantization (التكميم الخطي) مكتوبًا على شكل affine mapping (دالة تآلفية): مقياس مضروب في عدد صحيح مُزاح.
Read the map from right to left. Start from the stored integer Quantized value (q), subtract the Zero point (Z), then multiply by the Scale (S). The types matter as much as the formula, and they are a favourite exam detail:
اقرأ الدالة من اليمين إلى اليسار. ابدأ من العدد الصحيح المخزّن quantized value (q)، واطرح منه zero point (Z)، ثم اضرب الناتج في scale (S). الأنواع مهمة بقدر أهمية الصيغة نفسها، وهي تفصيل يحب الامتحان أن يسأل عنه:
| Symbolالرمز | Meaningالمعنى | Typeالنوع | How manyالعدد |
|---|---|---|---|
| rr | Real value (weight or activation)القيمة الحقيقية (وزن أو تفعيل) | Floating point (FP32)عدد عشري (FP32) | Given by the modelيعطيه النموذج |
| Stored codeالرمز المخزّن | Integer (N-bit signed)عدد صحيح (بإشارة من N بت) | Computed per valueيُحسب لكل قيمة | |
| ZZ | Zero point: the code for real 0نقطة الصفر: الرمز الذي يمثل الصفر الحقيقي 0 | Integer (same type as q)عدد صحيح (من نفس نوع q) | One per tensor, derivedواحدة لكل موتر، مشتقة |
| SS | Scale: real step between neighbouring codesالمقياس: الخطوة الحقيقية بين رمزين متجاورين | Floating point (FP32)عدد عشري (FP32) | One per tensor, derivedواحد لكل موتر، مشتق |
The two quantities that live with each value (r and q) are a float and an integer. The two quantization parameters (S and Z) are also a float and an integer. Z has the same type as q, so in the slide example it is a 2-bit signed integer. That is no accident: the paper the slides come from, Jacob et al. (CVPR 2018), defines Z as the quantized value that corresponds to real 0. A value can only be a code if it is an integer in the code's type.
الكميتان المرتبطتان بكل قيمة (r وq) هما عدد عشري وعدد صحيح. ومعاملا التكميم (S وZ) هما أيضًا عدد عشري وعدد صحيح. نوع Z هو نفس نوع q، لذلك في مثال الشرائح هو عدد صحيح بإشارة من بتين. وهذا ليس صدفة: الورقة التي أُخذت منها الشرائح، Jacob et al. (CVPR 2018)، تعرّف Z بأنه القيمة المكمّمة التي تقابل الصفر الحقيقي 0. ولا يمكن لقيمة أن تكون رمزًا إلا إذا كانت عددًا صحيحًا من نوع الرموز.
The picture shows the two operations in order. Subtracting Z slides the integer grid so the code Z sits on zero. Multiplying by S stretches the spacing from 1 to S. The Reconstructed weights therefore always lie on a uniform grid of spacing S. The gap between an original value and its grid point is the Quantization error, at most S/2 for in-range values.
يعرض الشكل العمليتين بالترتيب. طرح Z يزيح شبكة الأعداد الصحيحة بحيث يقع الرمز Z على الصفر. والضرب في S يمدّ المسافة بين النقاط من 1 إلى S. لذلك تقع reconstructed weights (الأوزان المعاد بناؤها) دائمًا على شبكة منتظمة المسافة بين نقاطها S. والفرق بين القيمة الأصلية ونقطة الشبكة الخاصة بها هو quantization error (خطأ التكميم)، ولا يتجاوز S/2 للقيم الواقعة داخل المدى.
Worked exampleمثال محلول
Check two cells of slide 5 by hand (S = 1.07, Z = -1)تحقّق يدويًا من خليتين في الشريحة 5 (S = 1.07، Z = -1)
Quantize r = 2.09كمّم r = 2.09
q = round(2.09 / 1.07) + Z = round(1.953) - 1 = 2 - 1 = 1. The slide shows 1.q = round(2.09 / 1.07) + Z = round(1.953) - 1 = 2 - 1 = 1. والشريحة تعرض 1.Reconstructأعد البناء
1.07 x (1 - (-1)) = 2.14. The error is 0.05, well under S/2 = 0.535.1.07 x (1 - (-1)) = 2.14. الخطأ يساوي 0.05، وهو أقل بكثير من S/2 = 0.535.Quantize r = 0كمّم r = 0
q = round(0 / 1.07) + Z = -1. Real zero becomes exactly the code Z, and 1.07 x (-1 - (-1)) = 0 decodes back to exactly zero.q = round(0 / 1.07) + Z = -1. الصفر الحقيقي يصبح الرمز Z بالضبط، و1.07 x (-1 - (-1)) = 0 يُفك ترميزه ليعود صفرًا تمامًا.Resultالنتيجة
Forward: q = round(r / S) + Z, clamped to the code range. Backward: r = S(q - Z). Zero goes in and comes out with no error.الاتجاه الأمامي: q = round(r / S) + Z، مع حصر الناتج (clamp) داخل مدى الرموز. الاتجاه العكسي: r = S(q - Z). الصفر يدخل ويخرج دون أي خطأ.
Recall
In r = S(q - Z), which two symbols are integers and which two are floating point?في r = S(q - Z)، أي رمزين عددان صحيحان وأي رمزين عددان عشريان؟
With 2 bits you can write exactly four patterns: 00, 01, 10, 11. Read as signed numbers they are 0, 1, -2 and -1. So a 2-bit code lives in [-2, 1], and quantization must squeeze the whole real range of the matrix onto those four points.
باستخدام بتين يمكنك كتابة أربعة أنماط فقط: 00 و01 و10 و11. وإذا قرأتها كأعداد بإشارة فهي 0 و1 و-2 و-1. إذن الرمز ذو البتين يقع في [-2, 1]، وعلى التكميم أن يضغط المدى الحقيقي الكامل للمصفوفة على هذه النقاط الأربع.
Two number linesخطّا أعداد
Picture two parallel lines. The top line is the real axis r. On it, the tensor occupies an interval from r_min and r_max (here -1.08 to 2.12). The bottom line holds the integer codes from q_min and q_max. Quantization ties the two lines at their ends: q_min maps to r_min and q_max maps to r_max. Somewhere between them, the code Z points straight up at real 0. Every derivation in this part is just algebra on that picture.
تخيّل خطين متوازيين. الخط العلوي هو المحور الحقيقي r. وعليه يشغل الموتر فترة تمتد بين r_min and r_max (هنا من -1.08 إلى 2.12). والخط السفلي يحمل الرموز الصحيحة بين q_min and q_max. التكميم يربط الخطين عند طرفيهما: q_min يقابل r_min وq_max يقابل r_max. وفي مكان ما بينهما يشير الرمز Z مباشرة إلى الصفر الحقيقي 0. كل اشتقاق في هذا الجزء هو مجرد جبر على هذه الصورة.
The signed N-bit rangeمدى الأعداد ذات الإشارة بعدد N من البتات
The codes use Two's complement, the standard signed encoding. With a Bit width (N) of N there are 2^N codes. Half of them are negative and the other half are zero plus the positives. That is why the range is lopsided by one:
تستخدم الرموز two's complement (المتمم الثنائي)، وهو الترميز القياسي للأعداد ذات الإشارة. ومع bit width (N) (عرض بتات) يساوي N يوجد 2^N رمزًا. نصفها سالب، والنصف الآخر هو الصفر مع الأعداد الموجبة. لهذا يكون المدى غير متوازن بفارق واحد:
| Bit width Nعرض البتات N | Codesعدد الرموز | q_minq_min | q_maxq_max |
|---|---|---|---|
| 22 | 44 | -2-2 | 11 |
| 33 | 88 | -4-4 | 33 |
| 44 | 1616 | -8-8 | 77 |
| 88 | 256256 | -128-128 | 127127 |
| NN | 2^N2^N | -2^(N-1)-2^(N-1) | 2^(N-1) - 12^(N-1) - 1 |
| Binaryثنائي | Decimalعشري | Role in the exampleدوره في المثال |
|---|---|---|
| 0101 | 11 | q_maxq_max |
| 0000 | 00 | code 0, which is not real 0 hereالرمز 0، وهو هنا لا يمثل الصفر الحقيقي |
| 1111 | -1-1 | Z in the running exampleZ في المثال المستمر |
| 1010 | -2-2 | q_minq_min |
Quick checkاختبار سريع
What is the signed 5-bit integer range [q_min, q_max]?ما مدى الأعداد الصحيحة ذات الإشارة من 5 بتات [q_min, q_max]؟
The slide matrix spans -1.08 to 2.12, a real width of 3.20. The 2-bit codes -2, -1, 0, 1 have 3 gaps between them. Stretch three equal gaps over a width of 3.20 and each gap is 3.20 / 3 = 1.0667 real units. That number is the scale.
مصفوفة الشريحة تمتد من -1.08 إلى 2.12، أي بعرض حقيقي قدره 3.20. والرموز ذات البتين -2, -1, 0, 1 بينها 3 فجوات. إذا مددت ثلاث فجوات متساوية على عرض 3.20 فإن كل فجوة تساوي 3.20 / 3 = 1.0667 وحدة حقيقية. هذا العدد هو المقياس.
The derivation (slide 7)الاشتقاق (الشريحة 7)
Now turn the intuition into algebra. Demand that the affine map send each end of the integer range to the matching end of the real range. That gives two equations, both containing the unknowns S and Z:
الآن حوّل هذا الحدس إلى جبر. اشترط أن ترسل الدالة التآلفية كل طرف من مدى الأعداد الصحيحة إلى الطرف المقابل من المدى الحقيقي. هذا يعطي معادلتين، كل منهما تحتوي المجهولين S وZ:
Subtract the second from the first. Expanding gives S q_max - S Z - S q_min + S Z. The two S Z terms cancel, so the zero point disappears:
اطرح الثانية من الأولى. بعد فك الأقواس نحصل على S q_max - S Z - S q_min + S Z. الحدّان S Z يلغي أحدهما الآخر، فتختفي نقطة الصفر:
Worked exampleمثال محلول
Slide 8: the scale of the 2-bit exampleالشريحة 8: مقياس المثال ذي البتين
Read the range off the matrixاقرأ المدى من المصفوفة
The largest entry is r_max = 2.12 and the smallest is r_min = -1.08. These are the two cells highlighted on slide 8.أكبر عنصر هو r_max = 2.12 وأصغر عنصر هو r_min = -1.08. وهما الخليتان المظللتان في الشريحة 8.Read the integer rangeاقرأ مدى الأعداد الصحيحة
For N = 2: q_max = 1 and q_min = -2.عندما N = 2: q_max = 1 وq_min = -2.Divideاقسم
S = (2.12 - (-1.08)) / (1 - (-2)) = 3.20 / 3 = 1.0667.S = (2.12 - (-1.08)) / (1 - (-2)) = 3.20 / 3 = 1.0667.Resultالنتيجة
S = 1.0667, which the slides round to 1.07. One integer step is worth about 1.07 in real units.S = 1.0667، وتقرّبه الشرائح إلى 1.07. الخطوة الصحيحة الواحدة تساوي تقريبًا 1.07 بالوحدات الحقيقية.
Quick checkاختبار سريع
In the derivation on slide 7, why is S computed before Z?في الاشتقاق في الشريحة 7، لماذا يُحسب S قبل Z؟
Recall
Derive S from the two endpoint equations in two lines.اشتق S من معادلتي الطرفين في سطرين.
You now know one integer step is worth 1.0667. The smallest real value -1.08 sits at code -2. Walk up from there: -1.08 is about one step below zero, so real zero must sit about one code above -2, at code -1. That code is the zero point.
أنت تعرف الآن أن الخطوة الصحيحة الواحدة تساوي 1.0667. وأصغر قيمة حقيقية -1.08 تقع عند الرمز -2. اصعد من هناك: -1.08 تقع تحت الصفر بخطوة واحدة تقريبًا، إذن الصفر الحقيقي يجب أن يقع فوق -2 برمز واحد تقريبًا، أي عند الرمز -1. هذا الرمز هو نقطة الصفر.
The derivation (slide 9)الاشتقاق (الشريحة 9)
Take the bottom endpoint equation and solve it for Z, now that S is known:
خذ معادلة الطرف السفلي وحلّها لإيجاد Z، بعد أن أصبح S معروفًا:
Nothing forces that expression to be a whole number, but Z must be a code. So it is rounded:
لا شيء يجبر هذا التعبير على أن يكون عددًا صحيحًا، لكن Z يجب أن يكون رمزًا. لذلك نقرّبه:
Using the top equation instead gives Z = q_max - r_max / S. Before rounding it is the same number, because S was built to make both ends agree.
لو استخدمت المعادلة العليا بدلًا منها لحصلت على Z = q_max - r_max / S. وقبل التقريب هي العدد نفسه، لأن S بُني أصلًا ليجعل الطرفين متوافقين.
Worked exampleمثال محلول
Slide 10: the zero point of the 2-bit exampleالشريحة 10: نقطة الصفر في المثال ذي البتين
Divide r_min by Sاقسم r_min على S
r_min / S = -1.08 / 1.07 = -1.009.r_min / S = -1.08 / 1.07 = -1.009.Subtract from q_minاطرح من q_min
q_min - r_min / S = -2 - (-1.009) = -2 + 1.009 = -0.991.q_min - r_min / S = -2 - (-1.009) = -2 + 1.009 = -0.991.Roundقرّب
Z = round(-0.991) = -1. With the unrounded S = 1.0667 you get round(-0.9875) = -1, the same answer.Z = round(-0.991) = -1. ومع القيمة غير المقرّبة S = 1.0667 تحصل على round(-0.9875) = -1، أي الجواب نفسه.Resultالنتيجة
Z = -1, stored as the 2-bit pattern 11. Every zero in the matrix is stored as -1, which matches the quantized matrix on slide 5.Z = -1، ويُخزَّن بالنمط الثنائي ذي البتين 11. كل صفر في المصفوفة يُخزَّن على شكل -1، وهذا يطابق المصفوفة المكمّمة في الشريحة 5.
Why Z must be an integer: exact zeroلماذا يجب أن يكون Z عددًا صحيحًا: الصفر الدقيق
Rounding Z costs something. The ends of the range no longer land exactly. With the unrounded Z = -0.9875, code 1 would decode to 1.0667 x 1.9875 = 2.12. With Z = -1 it decodes to 1.0667 x 2 = 2.13, and code -2 to -1.07 rather than -1.08. The whole grid slides by 0.0125S, never more than S/2. The design accepts that small shift to buy something more valuable, the Exact representation of zero. If Z is an integer, then the code q = Z exists, and r = S(Z - Z) = 0 exactly.
تقريب Z له ثمن. طرفا المدى لم يعودا يقعان في مكانهما بالضبط. مع القيمة غير المقرّبة Z = -0.9875 كان الرمز 1 سيُفك إلى 1.0667 x 1.9875 = 2.12. ومع Z = -1 يُفك إلى 1.0667 x 2 = 2.13، والرمز -2 يُفك إلى -1.07 بدلًا من -1.08. الشبكة كلها تنزاح بمقدار 0.0125S، ولا يتجاوز ذلك أبدًا S/2. يقبل التصميم هذه الإزاحة الصغيرة ليكسب شيئًا أثمن، وهو exact representation of zero (التمثيل الدقيق للصفر). إذا كان Z عددًا صحيحًا فإن الرمز q = Z موجود، وr = S(Z - Z) = 0 تمامًا.
Real zero is not a rare value in a neural network. It appears all the time:
الصفر الحقيقي ليس قيمة نادرة في الشبكة العصبية. إنه يظهر طوال الوقت:
- Zero padding. Convolutions pad feature maps with zeros at the borders. Jacob et al. give this as the motivation for exact zero.الحشو بالأصفار (zero padding). الالتفافات (convolutions) تحشو خرائط الخصائص بأصفار عند الحواف. ويذكر Jacob et al. هذا بوصفه الدافع لتمثيل الصفر بدقة.
- ReLU outputs. Every negative pre-activation becomes exactly zero, so a large share of the activations after a ReLU are zero.مخرجات ReLU. كل قيمة سالبة قبل التفعيل تصبح صفرًا تمامًا، لذلك تكون نسبة كبيرة من التفعيلات بعد ReLU أصفارًا.
- Pruned weights. The pruning lectures (04-1 and 04-2) set many weights to exactly zero, and quantizing them must keep them zero.الأوزان المقلّمة (pruned weights). محاضرتا التقليم (04-1 و04-2) تجعلان كثيرًا من الأوزان صفرًا تمامًا، ويجب أن يحافظ تكميمها على كونها صفرًا.
Now suppose Z were fractional, say -0.6. No stored integer decodes to zero. The best the hardware can do is the nearest code -1, which decodes to S(-1 - (-0.6)) = -0.4S. Every padded cell then carries the same -0.4S error. It is systematic rather than random, so it does not average out. It adds up in every convolution window that touches the border, which biases the layer output. A fractional zero point would also need a float subtraction inside the integer pipeline, which part 3 works hard to avoid.
افترض الآن أن Z كسري، مثلًا -0.6. لا يوجد عدد صحيح مخزّن يُفك إلى الصفر. أفضل ما يستطيعه العتاد هو أقرب رمز -1، الذي يُفك إلى S(-1 - (-0.6)) = -0.4S. عندها تحمل كل خلية محشوة الخطأ نفسه -0.4S. هذا الخطأ منهجي (systematic) وليس عشوائيًا، لذلك لا يُلغى بالمتوسط. بل يتراكم في كل نافذة التفاف تلامس الحافة، فينحاز خرج الطبقة. كما أن نقطة الصفر الكسرية تتطلب عملية طرح عشرية داخل خط المعالجة الصحيح (integer pipeline)، وهذا ما يجتهد الجزء 3 في تجنّبه.
Try the explorer below. Drag the ends of the shaded range and watch S and Z update, with the teal arrow always running from code Z to real 0. The small ticks above the real axis are the representable values S(q - Z). One of them always sits exactly on zero, while the range ends drift slightly once Z is rounded. The presets load the slide example and both drills below.
جرّب المستكشف أدناه. اسحب طرفي المدى المظلل وراقب S وZ وهما يتحدّثان، مع السهم الأخضر المزرق الذي يمتد دائمًا من الرمز Z إلى الصفر الحقيقي 0. العلامات الصغيرة فوق المحور الحقيقي هي القيم القابلة للتمثيل S(q - Z). إحداها تقع دائمًا على الصفر تمامًا، بينما ينزاح طرفا المدى قليلًا بعد تقريب Z. الإعدادات الجاهزة تحمّل مثال الشرائح والتمرينين أدناه.
Exam drillsتمارين الامتحان
Worked exampleمثال محلول
Drill 1: ReLU6 activations in [0, 6], 8-bit asymmetricالتمرين 1: تفعيلات ReLU6 في [0, 6]، تكميم غير متماثل بـ 8 بتات
Integer rangeمدى الأعداد الصحيحة
N = 8: q_min = -128, q_max = 127, so q_max - q_min = 255.N = 8: q_min = -128 وq_max = 127، إذن q_max - q_min = 255.Scaleالمقياس
S = (6 - 0) / 255 = 0.02353.S = (6 - 0) / 255 = 0.02353.Zero pointنقطة الصفر
Z = round(-128 - 0 / 0.02353) = round(-128) = -128.Z = round(-128 - 0 / 0.02353) = round(-128) = -128.Resultالنتيجة
S = 0.02353, Z = -128. Real 0 is code -128 and real 6 is code 127. No codes are wasted on negative values that ReLU6 can never produce.S = 0.02353 وZ = -128. الصفر الحقيقي 0 هو الرمز -128، والقيمة الحقيقية 6 هي الرمز 127. لا يُهدر أي رمز على قيم سالبة لا يمكن أن تنتجها ReLU6 أصلًا.
Worked exampleمثال محلول
Drill 2: r in [-1, 3], N = 4, then quantize r = 1.0التمرين 2: r في [-1, 3] و N = 4، ثم كمّم r = 1.0
Integer rangeمدى الأعداد الصحيحة
N = 4: q_min = -8, q_max = 7, so q_max - q_min = 15.N = 4: q_min = -8 وq_max = 7، إذن q_max - q_min = 15.Scaleالمقياس
S = (3 - (-1)) / 15 = 4 / 15 = 0.2667.S = (3 - (-1)) / 15 = 4 / 15 = 0.2667.Zero pointنقطة الصفر
r_min / S = -1 / 0.2667 = -3.75, so Z = round(-8 + 3.75) = round(-4.25) = -4.r_min / S = -1 / 0.2667 = -3.75، إذن Z = round(-8 + 3.75) = round(-4.25) = -4.Quantize r = 1.0كمّم r = 1.0
q = round(1.0 / 0.2667) + Z = round(3.75) + (-4) = 4 - 4 = 0.q = round(1.0 / 0.2667) + Z = round(3.75) + (-4) = 4 - 4 = 0.Reconstructأعد البناء
r = 0.2667 x (0 - (-4)) = 1.067. The error 0.067 is below S/2 = 0.133.r = 0.2667 x (0 - (-4)) = 1.067. الخطأ 0.067 أقل من S/2 = 0.133.Resultالنتيجة
S = 0.2667, Z = -4, q = 0, r = 1.067. Note the trap: the code 0 here means real 1.067, not real zero. Real zero is code -4.S = 0.2667 وZ = -4 وq = 0 وr = 1.067. انتبه للفخ: الرمز 0 هنا يعني القيمة الحقيقية 1.067 وليس الصفر الحقيقي. الصفر الحقيقي هو الرمز -4.
Quick checkاختبار سريع
For r in [-0.5, 1.5] with N = 2, what is the zero point Z?للمدى r في [-0.5, 1.5] مع N = 2، ما قيمة نقطة الصفر Z؟
Quick checkاختبار سريع
A tool stores Z = -0.6 as a float. What breaks when the layer zero-pads?أداة تخزّن Z = -0.6 كعدد عشري. ما الذي يتعطل عندما تحشو الطبقة بالأصفار (zero padding)؟
Recall
Compute S and Z for r in [-1.08, 2.12] with 2 bits, showing each line.احسب S و Z للمدى r في [-1.08, 2.12] مع بتين، واكتب كل سطر.
Recall
Give the 8-bit asymmetric S and Z for ReLU6 activations in [0, 6].أعطِ قيمتي S و Z للتكميم غير المتماثل بـ 8 بتات لتفعيلات ReLU6 في [0, 6].
Recall
Why must Z be an integer? Name three places real zero shows up.لماذا يجب أن يكون Z عددًا صحيحًا؟ اذكر ثلاثة مواضع يظهر فيها الصفر الحقيقي.
Recapالخلاصة
If you remember nothing elseإن لم تتذكر شيئاً آخر فتذكّر هذا
- Linear quantization maps an integer code back to a real number with r = S(q - Z).التكميم الخطي (linear quantization) يعيد الرمز الصحيح q إلى عدد حقيقي بالعلاقة r = S(q - Z).
- r and S are floating point. q and Z are integers of the same type, for example 2-bit or 8-bit signed.r و S أعداد عشرية (floating point). أما q و Z فهما عددان صحيحان من النوع نفسه، مثل عدد صحيح بإشارة من 2 بت أو 8 بت.
- Signed N-bit codes run from q_min = -2^(N-1) to q_max = 2^(N-1) - 1: [-2, 1], [-4, 3], [-8, 7], [-128, 127].الرموز ذات الإشارة بعدد N من البتات تمتد من q_min = -2^(N-1) إلى q_max = 2^(N-1) - 1: أي [-2, 1] و [-4, 3] و [-8, 7] و [-128, 127].
- Pin the range ends: r_max = S(q_max - Z) and r_min = S(q_min - Z). Subtracting cancels Z and gives S = (r_max - r_min) / (q_max - q_min).ثبّت طرفي المدى: r_max = S(q_max - Z) و r_min = S(q_min - Z). الطرح يلغي Z ويعطي S = (r_max - r_min) / (q_max - q_min).
- Substitute S back into the r_min equation: Z = q_min - r_min / S, then round so Z is an integer.عوّض S في معادلة r_min فتحصل على Z = q_min - r_min / S، ثم قرّب الناتج حتى يصبح Z عددًا صحيحًا.
- Running example: S = 3.20 / 3 = 1.0667 (slides write 1.07) and Z = round(-0.991) = -1.المثال المستمر: S = 3.20 / 3 = 1.0667 (الشرائح تكتب 1.07) و Z = round(-0.991) = -1.
- Z is the code for real 0, so 0 is stored exactly. Zero padding, ReLU zeros and pruned weights stay exact. A fractional Z would bias every padded cell.Z هو الرمز الذي يمثل الصفر الحقيقي، لذلك يُخزَّن الصفر بدقة تامة. الحشو بالأصفار (zero padding) وأصفار ReLU والأوزان المقلّمة (pruned) تبقى صفرًا تمامًا. لو كان Z كسريًا لانحازت كل خلية محشوة.
Sourcesالمصادر
- Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only InferencePaperJacob et al., CVPR 2018 (arXiv)Section 2.1 defines r = S(q - Z), states Z has the type of q and is the code for real 0, and gives zero padding as the reason.القسم 2.1 يعرّف r = S(q - Z)، وينص على أن Z من نوع q وأنه الرمز الذي يمثل الصفر الحقيقي 0، ويذكر الحشو بالأصفار (zero padding) سببًا لذلك.(opens in a new tab)(يفتح في تبويب جديد)
- A White Paper on Neural Network QuantizationPaperNagel et al., Qualcomm AI Research (arXiv)Section 2.2 on uniform affine quantization: scale is a float step size, and the integer zero point quantizes real zero without error, which matters for zero padding and ReLU.القسم 2.2 عن التكميم التآلفي المنتظم (uniform affine quantization): المقياس حجم خطوة عشري، ونقطة الصفر الصحيحة تكمّم الصفر الحقيقي دون خطأ، وهذا مهم للحشو بالأصفار ولـ ReLU.(opens in a new tab)(يفتح في تبويب جديد)
- A Survey of Quantization Methods for Efficient Neural Network InferencePaperGholami et al. (arXiv)Survey of uniform, asymmetric and symmetric quantization and their trade-offs.مسح لأنواع التكميم المنتظم وغير المتماثل والمتماثل والموازنات بينها.(opens in a new tab)(يفتح في تبويب جديد)
- QuantizeLinear operatorDocsONNX documentationReal deployment formula: y = saturate(round(x / y_scale) + y_zero_point), rounding half to even, int8 range [-128, 127].صيغة النشر الفعلية: y = saturate(round(x / y_scale) + y_zero_point)، مع التقريب عند النصف إلى العدد الزوجي (round half to even)، ومدى int8 هو [-128, 127].(opens in a new tab)(يفتح في تبويب جديد)
- MIT 6.5940 TinyML and Efficient Deep Learning Computing, Lectures 5 and 6: QuantizationVideoMIT HAN LabThe course these slides follow. Lecture 5 (Quantization Part I) introduces linear quantization with this same running example.المقرر الذي تتبعه هذه الشرائح. المحاضرة 5 (Quantization Part I) تقدّم التكميم الخطي بالمثال المستمر نفسه.(opens in a new tab)(يفتح في تبويب جديد)
Part 03: Linear Quantized Matrix Multiplicationضرب المصفوفات المكمّم خطيًا
Substitutes r = S(q - Z) into Y = WX and expands the result. The terms then sort into runtime N-bit integer MACs, offline precomputation, a single rescale by S_W S_X / S_Y (done as a fixed-point multiply plus a bit shift) and an N-bit addition of Z_Y. The section ends by asking whether Z_W can be 0.يعوّض r = S(q - Z) في Y = WX ويفك الناتج. ثم تنقسم الحدود إلى عمليات MAC بأعداد صحيحة من N بت وقت التشغيل، وحسابات مسبقة خارج التشغيل (offline)، وإعادة قياس واحدة بـS_W S_X / S_Y (تُنفَّذ بضرب بالفاصلة الثابتة مع إزاحة بت)، وجمع Z_Y بـN بت. ويختتم القسم بالسؤال عما إذا كان Z_W يمكن أن يساوي 0.
4 concepts4 مفاهيم, ، slides 11-14الشرائح 11-14
Why this part mattersلماذا يهمّ هذا الجزء
Parts 01 and 02 told you how to store a tensor as integers: pick a scale and a zero point, and every real value becomes r = S(q - Z). Storage is only half the win. The other half, the half that makes a microcontroller or a phone DSP fast, is doing the arithmetic on those integers directly, without ever turning them back into floats. This part answers one question: if the inputs and weights of a layer are integers, what exactly does the chip have to compute to get the integer output?
The answer is a single equation with four inner terms and two outer operations, and the exam will almost certainly ask you to derive it, label which terms are precomputed, and explain how the one floating-point factor is applied with integer hardware. Everything in the next two parts (symmetric weights, bias folding, integer-only layers) is a consequence of the cost map you build here.
أخبرك الجزآن 01 و02 كيف تخزّن مصفوفة (tensor) على شكل أعداد صحيحة: اختر scale وzero point، فتصبح كل قيمة حقيقية r = S(q - Z). لكن التخزين نصف المكسب فقط. النصف الآخر، وهو الذي يجعل المتحكم الدقيق (microcontroller) أو معالج DSP في الهاتف سريعاً، هو إجراء الحساب على هذه الأعداد الصحيحة مباشرة دون إعادتها إلى أعداد عشرية أبداً. يجيب هذا الجزء عن سؤال واحد: إذا كانت مدخلات الطبقة وأوزانها أعداداً صحيحة، فما الذي يجب على الشريحة أن تحسبه بالضبط لتحصل على المخرج على شكل عدد صحيح؟
الجواب معادلة واحدة فيها أربعة حدود داخلية وعمليتان خارجيتان، والامتحان سيطلب منك على الأرجح أن تشتقها، وأن تحدد الحدود التي تُحسب مسبقاً، وأن تشرح كيف يُطبَّق المعامل العشري الوحيد باستخدام عتاد الأعداد الصحيحة. كل ما في الجزأين التاليين (الأوزان المتماثلة، ودمج الانحياز bias، والطبقات التي تعمل بالأعداد الصحيحة فقط) نتيجة لخريطة التكلفة التي تبنيها هنا.
By the end you canفي نهاية هذا الجزء ستستطيع
- Derive q_Y = (S_W S_X / S_Y)(q_W - Z_W)(q_X - Z_X) + Z_Y from Y = WX and r = S(q - Z), one line at a time.اشتق q_Y = (S_W S_X / S_Y)(q_W - Z_W)(q_X - Z_X) + Z_Y من Y = WX ومن r = S(q - Z)، سطراً بسطر.
- Expand the product into its four terms and say, for each, whether it runs at inference time or offline, and why.افتح حاصل الضرب إلى حدوده الأربعة، وحدّد لكل حد هل يُحسب وقت الاستدلال (inference) أم مسبقاً (offline)، ولماذا.
- Translate the slide's scalar shorthand into real matrix terms: column sums of q_X, row sums of q_W, and the factor K.حوّل الاختصار العددي المفرد في الشريحة إلى حدود مصفوفية حقيقية: مجاميع أعمدة q_X، ومجاميع صفوف q_W، والعامل K.
- Convert any rescale factor M in (0, 1) into M0 in [0.5, 1) and a right shift n, and apply it to an int32 accumulator.حوّل أي معامل إعادة قياس M في (0, 1) إلى M0 في [0.5, 1) وإزاحة يمينية n، وطبّقه على مراكم int32.
- Justify the 32-bit accumulator with a bit count, and explain why weights are quantized with Z_W = 0.برّر المراكم ذا 32 بت بعدّ البتات، واشرح لماذا تُكمَّم الأوزان مع Z_W = 0.
Start with something tiny: one weight and one input. Say the real weight is w = 0.5 and the real input is x = 1.5, so the real output is y = 0.75. In a quantized network none of these floats exist on the chip. What exists is three integer codes and, written next to each tensor, a scale and a zero point. The question is: given the codes q_w and q_x, which integer q_y should the chip write out, so that S_y(q_y - Z_y) is as close as possible to 0.75?
ابدأ بشيء صغير جداً: وزن واحد ومدخل واحد. لنقل إن الوزن الحقيقي w = 0.5 والمدخل الحقيقي x = 1.5، فيكون المخرج الحقيقي y = 0.75. في الشبكة المكمّمة لا يوجد أي من هذه الأعداد العشرية على الشريحة. الموجود هو ثلاثة رموز صحيحة (integer codes)، ومع كل مصفوفة scale وzero point مكتوبان بجانبها. والسؤال: بمعرفة الرمزين q_w وq_x، ما العدد الصحيح q_y الذي يجب أن تكتبه الشريحة كي تكون S_y(q_y - Z_y) أقرب ما يمكن إلى 0.75؟
The trick is to stop thinking about the codes and think about what they mean. Under Linear quantization, every tensor obeys the same Affine mapping: the real value equals its Scale (S) times the code minus its Zero point (Z). So wherever the real equation has a real number, you may substitute S(q - Z). The layer is Y = WX, and it is the source of the whole derivation.
الحيلة أن تتوقف عن التفكير في الرموز وتفكر في معناها. في Linear quantization تخضع كل مصفوفة للتحويل نفسه، Affine mapping: القيمة الحقيقية تساوي scale مضروباً في الرمز بعد طرح zero point منه. لذلك أينما ظهر عدد حقيقي في المعادلة الحقيقية يمكنك أن تعوّض مكانه S(q - Z). الطبقة هي Y = WX، وهي منطلق الاشتقاق كله.
Symbols used in this partالرموز المستخدمة في هذا الجزء
- Y = WX
- The real layer: weights W (M x K) times input X (K x N)الطبقة الحقيقية: الأوزان W (M x K) مضروبة في المدخل X (K x N)
- S_W, S_X, S_Y
- Float scales of the three tensors, fixed after calibrationمعاملات scale العشرية (float) للمصفوفات الثلاث، وتُثبَّت بعد المعايرة
- Z_W, Z_X, Z_Y
- Integer zero points of the three tensors, also fixed after calibrationنقاط الصفر (zero points) الصحيحة للمصفوفات الثلاث، وتُثبَّت هي أيضاً بعد المعايرة
- q_W, q_X, q_Y
- The stored N-bit integer codes (typically INT8)الرموز الصحيحة المخزّنة بـ N بت (عادةً INT8)
- M
- Shorthand for the combined factor S_W S_X / S_Yاختصار للمعامل المركّب S_W S_X / S_Y
Three lines of algebraثلاثة أسطر من الجبر
Substitute the affine map for all three tensors. The left side is the output, the right side the product of the two inputs:
عوّض التحويل affine للمصفوفات الثلاث. الطرف الأيسر هو المخرج، والطرف الأيمن حاصل ضرب المدخلين:
The scales are scalars, so they slide out of the product. Divide both sides by S_Y and move Z_Y to the right. This is the form to remember; it says the output code is a rescaled product of zero-shifted input codes, shifted by the output's zero point:
معاملات scale أعداد مفردة (scalars)، لذا تخرج من حاصل الضرب. اقسم الطرفين على S_Y وانقل Z_Y إلى الطرف الأيمن. هذه هي الصيغة التي يجب أن تحفظها؛ فهي تقول إن رمز المخرج هو حاصل ضرب رموز المدخلات بعد طرح نقاط الصفر منها، مُعاداً قياسه، ثم مُزاحاً بنقطة الصفر الخاصة بالمخرج:
Finally, multiply out the brackets. Nothing new happens mathematically, but this expanded form is the one that exposes the cost of each piece, which is what slides 12 to 14 are about:
أخيراً، افتح الأقواس. لا يحدث شيء جديد رياضياً، لكن هذه الصيغة المفكوكة هي التي تكشف تكلفة كل جزء، وهذا موضوع الشرائح 12 إلى 14:
That is the Quantized matrix multiplication. Notice what it buys. Every quantity inside the big bracket is an integer: codes and zero points. The only non-integer in the whole equation is the single factor S_W S_X / S_Y, a constant for the layer that you know before inference begins. So the expensive part, the inner products with millions of multiply-accumulates, can run on integer hardware, and the float only shows up once per output element at the very end. The construction comes from Jacob et al. (CVPR 2018), which is the source cited on every slide in this part.
هذا هو Quantized matrix multiplication. لاحظ ما يمنحك إياه. كل كمية داخل القوس الكبير عدد صحيح: رموز ونقاط صفر. والعدد غير الصحيح الوحيد في المعادلة كلها هو المعامل المفرد S_W S_X / S_Y، وهو ثابت للطبقة تعرفه قبل أن يبدأ الاستدلال. لذلك يمكن تنفيذ الجزء المكلف، أي الضرب الداخلي بملايين عمليات الضرب والجمع التراكمي (multiply-accumulate)، على عتاد الأعداد الصحيحة، ولا يظهر العدد العشري إلا مرة واحدة لكل عنصر من المخرج في النهاية تماماً. هذا البناء مأخوذ من Jacob et al. (CVPR 2018)، وهو المصدر المذكور في كل شريحة من هذا الجزء.
Worked exampleمثال محلول
One output element, end to endعنصر واحد من المخرج، من البداية إلى النهاية
Choose parametersاختر المعاملات
Let S_W = 0.5, Z_W = 1, S_X = 0.25, Z_X = 2, S_Y = 0.3125, Z_Y = -3. The real weight 0.5 is code q_W = 2 (since 0.5(2 - 1) = 0.5) and the real input 1.5 is code q_X = 8 (since 0.25(8 - 2) = 1.5).لتكن S_W = 0.5 وZ_W = 1 وS_X = 0.25 وZ_X = 2 وS_Y = 0.3125 وZ_Y = -3. الوزن الحقيقي 0.5 رمزه q_W = 2 (لأن 0.5(2 - 1) = 0.5)، والمدخل الحقيقي 1.5 رمزه q_X = 8 (لأن 0.25(8 - 2) = 1.5).Integer coreاللب الصحيح العددي
(q_W - Z_W)(q_X - Z_X) = (2 - 1)(8 - 2) = 6. Expanded, the same number is q_W q_X - Z_W q_X - Z_X q_W + Z_W Z_X = 16 - 8 - 4 + 2 = 6. Pure integer arithmetic.(q_W - Z_W)(q_X - Z_X) = (2 - 1)(8 - 2) = 6. وبعد فك الأقواس نحصل على العدد نفسه: q_W q_X - Z_W q_X - Z_X q_W + Z_W Z_X = 16 - 8 - 4 + 2 = 6. حساب بالأعداد الصحيحة فقط.Rescaleإعادة القياس
M = S_W S_X / S_Y = 0.125 / 0.3125 = 0.4, so M x 6 = 2.4, which rounds to 2.M = S_W S_X / S_Y = 0.125 / 0.3125 = 0.4، إذن M x 6 = 2.4، ويُقرَّب إلى 2.Add the output zero pointأضف نقطة الصفر للمخرج
q_Y = 2 + (-3) = -1.q_Y = 2 + (-3) = -1.Resultالنتيجة
Decoding gives S_Y(q_Y - Z_Y) = 0.3125 x 2 = 0.625 against the true 0.75. The error, 0.125, is below half an output step (S_Y / 2 = 0.156), exactly the rounding error part 01 promised.فك الترميز يعطي S_Y(q_Y - Z_Y) = 0.3125 x 2 = 0.625 مقابل القيمة الحقيقية 0.75. الخطأ، 0.125، أقل من نصف خطوة في المخرج (S_Y / 2 = 0.156)، وهو بالضبط خطأ التقريب الذي وعد به الجزء 01.
Recall
Starting from Y = WX and r = S(q - Z), derive q_Y. What are the two key moves?انطلاقاً من Y = WX و r = S(q - Z)، اشتق q_Y. ما الخطوتان الأساسيتان؟
Look at the four terms inside the bracket and ask one question of each: does it change when the input image changes? q_W q_X obviously does: it is the matrix product itself. Z_W q_X does too, because it contains q_X. But Z_X q_W involves only the weights and the input zero point, both frozen after calibration, and Z_W Z_X is two constants. Those last two are the same for every image the model will ever see, so there is no reason to compute them more than once.
انظر إلى الحدود الأربعة داخل القوس واسأل كل حد سؤالاً واحداً: هل يتغير عندما تتغير صورة المدخل؟ q_W q_X يتغير بالطبع، فهو ضرب المصفوفات نفسه. وZ_W q_X يتغير أيضاً لأنه يحتوي على q_X. لكن Z_X q_W يتضمن الأوزان ونقطة الصفر للمدخل فقط، وكلاهما مُثبَّت بعد المعايرة، وZ_W Z_X عبارة عن ثابتين. هذان الحدان الأخيران متطابقان لكل صورة سيراها النموذج، لذلك لا داعي لحسابهما أكثر من مرة.
That is the logic of slide 12. The amber box marks -Z_X q_W + Z_W Z_X as precomputed: it is evaluated offline, when the model is converted, and stored as a constant per output. The big red box marks the whole bracket as N-bit integer multiplications with 32-bit integer additions and subtractions. The blue box on the left is the rescale, and the small box on the right is +Z_Y, an integer addition. Slide 14 adds the last label: the rescale converts back to an N-bit integer.
هذا منطق الشريحة 12. الصندوق الكهرماني (amber) يحدد -Z_X q_W + Z_W Z_X على أنه precomputed (محسوب مسبقاً): يُقيَّم offline عند تحويل النموذج، ويُخزَّن ثابتاً لكل مخرج. والصندوق الأحمر الكبير يحدد القوس كله على أنه عمليات ضرب صحيحة بـ N بت مع عمليات جمع وطرح صحيحة بـ 32 بت. الصندوق الأزرق على اليسار هو إعادة القياس، والصندوق الصغير على اليمين هو +Z_Y، وهو جمع صحيح. وتضيف الشريحة 14 التسمية الأخيرة: إعادة القياس تُرجع القيمة إلى عدد صحيح بـ N بت.
| Termالحد | Depends onيعتمد على | Whenمتى | Costالتكلفة |
|---|---|---|---|
| q_W q_Xq_W q_X | Weights and inputالأوزان والمدخل | Every inferenceفي كل استدلال | N-bit multiplies, int32 adds: the main MAC loopعمليات ضرب بـ N بت وعمليات جمع بـ int32: حلقة MAC الرئيسية |
| -Z_W q_X-Z_W q_X | Input (and Z_W)المدخل (وZ_W) | Every inferenceفي كل استدلال | Column sums of q_X, one extra pass over the inputمجاميع أعمدة q_X، أي مرور إضافي واحد على المدخل |
| -Z_X q_W-Z_X q_W | Weights (and Z_X)الأوزان (وZ_X) | Offlineمسبقاً (offline) | Row sums of q_W, computed once at conversion timeمجاميع صفوف q_W، تُحسب مرة واحدة وقت تحويل النموذج |
| +Z_W Z_X+Z_W Z_X | Constants onlyثوابت فقط | Offlineمسبقاً (offline) | One constant, K Z_W Z_X, added to every outputثابت واحد، K Z_W Z_X، يُضاف إلى كل مخرج |
| x S_W S_X / S_Yx S_W S_X / S_Y | Constants onlyثوابت فقط | Every inferenceفي كل استدلال | One fixed-point multiply and a shift per outputعملية ضرب واحدة بفاصلة ثابتة وإزاحة واحدة لكل مخرج |
| +Z_Y+Z_Y | Constantثابت | Every inferenceفي كل استدلال | One integer add per output, then clamp to the N-bit rangeعملية جمع صحيحة واحدة لكل مخرج، ثم قص إلى مدى N بت |
What the scalar notation hidesما تخفيه الكتابة بالأعداد المفردة
The slides write the terms as if q_W and q_X were single numbers. In a real layer they are matrices, and each output entry is a sum over the inner dimension K:
تكتب الشرائح الحدود كأن q_W وq_X عددان مفردان. في الطبقة الحقيقية هما مصفوفتان، وكل عنصر في المخرج مجموع على البعد الداخلي K:
Read it term by term. Z_W q_X is really Z_W times the column sum of q_X (one number per output column). Z_X q_W is really Z_X times the row sum of q_W (one number per output row). And Z_W Z_X is added once per k, so it appears multiplied by K. This is exactly how production kernels such as gemmlowp organize the computation: they compute the row and column sums during packing and add them as a correction afterwards.
اقرأها حداً حداً. Z_W q_X هو في الحقيقة Z_W مضروباً في مجموع عمود q_X (عدد واحد لكل عمود في المخرج). وZ_X q_W هو في الحقيقة Z_X مضروباً في مجموع صف q_W (عدد واحد لكل صف في المخرج). أما Z_W Z_X فيُضاف مرة لكل k، لذلك يظهر مضروباً في K. وهذا بالضبط ما تفعله النوى (kernels) المستخدمة في الإنتاج مثل gemmlowp: تحسب مجاميع الصفوف والأعمدة أثناء التعبئة (packing) ثم تضيفها تصحيحاً بعد ذلك.
Worked exampleمثال محلول
A 2x2 example that makes the notation honestمثال 2x2 يكشف المعنى الحقيقي للترميز
Set upالإعداد
q_W = [[3, 1], [4, 2]], q_X = [[5, 1], [3, 6]], Z_W = 1, Z_X = 2, so K = 2.q_W = [[3, 1], [4, 2]] وq_X = [[5, 1], [3, 6]] وZ_W = 1 وZ_X = 2، إذن K = 2.Ground truthالقيمة المرجعية الصحيحة
q_W - Z_W = [[2, 0], [3, 1]] and q_X - Z_X = [[3, -1], [1, 4]]. Their product is [[6, -2], [10, 1]].q_W - Z_W = [[2, 0], [3, 1]] وq_X - Z_X = [[3, -1], [1, 4]]. حاصل ضربهما [[6, -2], [10, 1]].The four termsالحدود الأربعة
q_W q_X = [[18, 9], [26, 16]]. Column sums of q_X are 8 and 7, so Z_W times them gives 8 in column 0 and 7 in column 1. Row sums of q_W are 4 and 6, so Z_X times them gives 8 in row 0 and 12 in row 1. The constant is K Z_W Z_X = 2 x 1 x 2 = 4.q_W q_X = [[18, 9], [26, 16]]. مجاميع أعمدة q_X هي 8 و7، فضربها في Z_W يعطي 8 في العمود 0 و7 في العمود 1. مجاميع صفوف q_W هي 4 و6، فضربها في Z_X يعطي 8 في الصف 0 و12 في الصف 1. والثابت هو K Z_W Z_X = 2 x 1 x 2 = 4.Assembleالتجميع
Entry (0,0) is 18 - 8 - 8 + 4 = 6. All four entries match the ground truth (table below).العنصر (0,0) هو 18 - 8 - 8 + 4 = 6. والعناصر الأربعة كلها تطابق القيمة المرجعية (الجدول أدناه).Resultالنتيجة
The correct correction is a column vector, a row vector and the constant K Z_W Z_X. Dropping the K and adding Z_W Z_X = 2 instead makes every entry wrong by 2.التصحيح الصحيح هو متجه عمودي ومتجه صفي والثابت K Z_W Z_X. إسقاط K وإضافة Z_W Z_X = 2 بدلاً منه يجعل كل عنصر خاطئاً بمقدار 2.
| Outputالمخرج | With K Z_W Z_X = 4مع K Z_W Z_X = 4 | Resultالنتيجة | Forgetting Kعند نسيان K |
|---|---|---|---|
| Entry (0,0)العنصر (0,0) | 18 - 8 - 8 + 418 - 8 - 8 + 4 | 66 | 18 - 8 - 8 + 2 = 418 - 8 - 8 + 2 = 4 |
| Entry (0,1)العنصر (0,1) | 9 - 7 - 8 + 49 - 7 - 8 + 4 | -2-2 | 9 - 7 - 8 + 2 = -49 - 7 - 8 + 2 = -4 |
| Entry (1,0)العنصر (1,0) | 26 - 8 - 12 + 426 - 8 - 12 + 4 | 1010 | 26 - 8 - 12 + 2 = 826 - 8 - 12 + 2 = 8 |
| Entry (1,1)العنصر (1,1) | 16 - 7 - 12 + 416 - 7 - 12 + 4 | 11 | 16 - 7 - 12 + 2 = -116 - 7 - 12 + 2 = -1 |
Why the accumulator is 32 bitsلماذا المراكم 32 بت
The red box's label pairs N-bit multiplies with 32-bit additions, and the reason is a bit count. Two INT8 codes multiply to at most (-128) x (-128) = 16,384, which needs 16 signed bits. A dot product adds K of these, and each doubling of K can add one more bit, so the sum needs about 16 + log2(K) bits. That is why products go into an 32-bit accumulator: the width has room for the worst case of more than a hundred thousand terms, far more than any real layer has.
تسمية الصندوق الأحمر تقرن عمليات ضرب بـ N بت مع عمليات جمع بـ 32 بت، والسبب عدٌّ للبتات. حاصل ضرب رمزين من نوع INT8 لا يتجاوز (-128) x (-128) = 16,384، ويحتاج 16 بت بإشارة. الضرب النقطي (dot product) يجمع K من هذه النواتج، وكل مضاعفة لـ K قد تضيف بتاً واحداً، لذلك يحتاج المجموع نحو 16 + log2(K) بت. ولهذا تذهب النواتج إلى 32-bit accumulator: فعرضه يتسع لأسوأ حالة تزيد على مئة ألف حد، وهذا أكثر بكثير مما تملكه أي طبقة حقيقية.
Counting accumulator bitsعدّ بتات المراكم
- One int8 x int8 productحاصل ضرب واحد int8 x int8
- at most (-128) x (-128) = 16,384 = 2^14, so 16 signed bitsلا يتجاوز (-128) x (-128) = 16,384 = 2^14، إذن 16 بت بإشارة
- Sum of K productsمجموع K من النواتج
- at most K x 2^14, so about 16 + log2(K) bitsلا يتجاوز K x 2^14، إذن نحو 16 + log2(K) بت
- K = 4,608 (a 3 x 3 conv over 512 channels)K = 4,608 (التفاف 3 x 3 على 512 قناة)
- at most 4,608 x 2^14, about 2^26.2, so 28 signed bits: fits int32, overflows int16 after two termsلا يتجاوز 4,608 x 2^14، أي نحو 2^26.2، إذن 28 بت بإشارة: يتسع في int32، ويفيض في int16 بعد حدّين فقط
- Worst-case K for int32أسوأ حالة لـ K مع int32
- (2^31 - 1) / 2^14, about 131,071 terms(2^31 - 1) / 2^14، أي نحو 131,071 حداً
Recall
For W of size M x K and X of size K x N, what does Z_X q_W really mean, and how many distinct numbers does it produce?إذا كانت W بحجم M x K و X بحجم K x N، فما المعنى الحقيقي لـ Z_X q_W، وكم عدداً مختلفاً ينتج؟
Quick checkاختبار سريع
Which term of the expanded product must be recomputed for every new input?أي حد من حدود حاصل الضرب المفكوك يجب إعادة حسابه مع كل مدخل جديد؟
Quick checkاختبار سريع
An int8 dot product sums K = 4096 terms. Roughly how many bits can its worst-case sum need?ضرب نقطي بـ int8 يجمع K = 4096 حداً. كم بتاً تقريباً قد يحتاج مجموعه في أسوأ حالة؟
Suppose the accumulator for one output holds 5,000 and the layer's rescale factor is M = S_W S_X / S_Y = 0.0072. The output code before adding Z_Y is 5,000 x 0.0072 = 36. Easy on a laptop. On a microcontroller with no floating-point unit, that multiply by 0.0072 is the one operation left in the equation that is not an integer operation. If it stays a float multiply, the promise of Integer-only inference breaks at the last step.
افترض أن المراكم لمخرج واحد يحمل 5,000 وأن معامل إعادة القياس للطبقة هو M = S_W S_X / S_Y = 0.0072. رمز المخرج قبل إضافة Z_Y هو 5,000 x 0.0072 = 36. أمر سهل على حاسوب محمول. لكن على متحكم دقيق بلا وحدة فاصلة عائمة (floating-point unit)، يكون الضرب في 0.0072 هو العملية الوحيدة المتبقية في المعادلة التي ليست عملية أعداد صحيحة. وإذا بقي ضرباً عشرياً، ينكسر وعد Integer-only inference في الخطوة الأخيرة.
The fix is to rewrite M so that it uses only things integer hardware does cheaply. Keep doubling 0.0072 until it lands in [0.5, 1): 0.0144, 0.0288, 0.0576, 0.1152, 0.2304, 0.4608, 0.9216. Seven doublings. So 0.0072 = 2^(-7) x 0.9216. Multiplying by 0.9216 is a Fixed-point multiplication, and multiplying by 2^(-7) is a right shift by seven bits. That is the M0 and bit shift decomposition of slide 13:
الحل أن نعيد كتابة M بحيث لا تستخدم إلا ما ينفذه عتاد الأعداد الصحيحة بتكلفة رخيصة. استمر في مضاعفة 0.0072 حتى تقع في [0.5, 1): 0.0144، 0.0288، 0.0576، 0.1152، 0.2304، 0.4608، 0.9216. سبع مضاعفات. إذن 0.0072 = 2^(-7) x 0.9216. الضرب في 0.9216 هو Fixed-point multiplication (ضرب بفاصلة ثابتة)، والضرب في 2^(-7) هو إزاحة يمينية بسبع بتات. هذا هو تفكيك M0 and bit shift في الشريحة 13:
How M0 becomes an integerكيف يصبح M0 عدداً صحيحاً
M0 is still a real number, so it is stored as a fixed-point integer. With a 32-bit word, Jacob et al. store the int32 nearest to 2^31 M0, which is the Q31 format: the integer represents the fraction value / 2^31. For M0 = 0.9216 that integer is 1,979,120,930. The chip multiplies the accumulator by this integer into a 64-bit product and keeps the top bits (a right shift by 31 with rounding), then shifts right by n with rounding. Because M0 >= 0.5, the stored integer is at least 2^30, so it always uses about 30 significant bits. That is the point of normalizing: a tiny M stored directly in Q31 would waste most of its bits on leading zeros.
M0 ما زال عدداً حقيقياً، لذلك يُخزَّن عدداً صحيحاً بفاصلة ثابتة. مع كلمة من 32 بت، يخزّن Jacob et al. أقرب عدد int32 إلى 2^31 M0، وهذه صيغة Q31: العدد الصحيح يمثل الكسر value / 2^31. بالنسبة لـ M0 = 0.9216 يكون هذا العدد 1,979,120,930. تضرب الشريحة المراكم في هذا العدد لتحصل على حاصل ضرب من 64 بت وتحتفظ بالبتات العليا (إزاحة يمينية بمقدار 31 مع تقريب)، ثم تزيح يميناً بمقدار n مع تقريب. ولأن M0 >= 0.5، يكون العدد المخزّن 2^30 على الأقل، فيستخدم دائماً نحو 30 بتاً ذات دلالة. هذا هو الهدف من التطبيع (normalizing): لو خُزّن M صغير مباشرة بصيغة Q31 لأهدر معظم بتاته على أصفار بادئة.
| MM | Doubling to [0.5, 1)المضاعفة حتى [0.5, 1) | nn | M0M0 | M0 as Q31 int32M0 بصيغة Q31 في int32 |
|---|---|---|---|---|
| 0.30.3 | 0.3 x 2 = 0.60.3 x 2 = 0.6 | 11 | 0.60.6 | 1,288,490,1891,288,490,189 |
| 0.0450.045 | 0.045 x 16 = 0.720.045 x 16 = 0.72 | 44 | 0.720.72 | 1,546,188,2271,546,188,227 |
| 0.00720.0072 | 0.0072 x 128 = 0.92160.0072 x 128 = 0.9216 | 77 | 0.92160.9216 | 1,979,120,9301,979,120,930 |
Worked exampleمثال محلول
Rescale 5,000 by M = 0.0072 with integers onlyأعد قياس 5,000 بـ M = 0.0072 باستخدام الأعداد الصحيحة فقط
Normalize offlineطبِّع مسبقاً (offline)
n = 7, M0 = 0.9216, stored as M0_q31 = 1,979,120,930.n = 7 وM0 = 0.9216، ويُخزَّن على صورة M0_q31 = 1,979,120,930.Fixed-point multiplyضرب بفاصلة ثابتة
5,000 x 1,979,120,930 gives a 64-bit product; a rounding right shift by 31 leaves 4,608, which is 5,000 x 0.9216.5,000 x 1,979,120,930 يعطي حاصل ضرب من 64 بت؛ وإزاحة يمينية مع تقريب بمقدار 31 تترك 4,608، وهو 5,000 x 0.9216.Bit shiftإزاحة البتات
4,608 >> 7 with rounding is 36.4,608 >> 7 مع التقريب يساوي 36.Resultالنتيجة
36, the same as the float computation, with no floating-point instruction. Adding Z_Y and clamping to the N-bit range finishes the Requantization (rescale).36، النتيجة نفسها التي يعطيها الحساب العشري، دون أي تعليمة فاصلة عائمة. وإضافة Z_Y ثم القص إلى مدى N بت تُكمل requantization (إعادة التكميم).
5000 x 0.0072 = 5000 x 2^-7 x 0.9216
Try M = 0.3 in the calculator: one doubling gives 0.6, so n = 1 and M0 = 0.6. Try M = 0.5: it is already in range, so n = 0 and M0 = 0.5. The rule is mechanical: n is the number of doublings needed to reach 0.5, and M0 = M x 2^n.
جرّب M = 0.3 في الحاسبة: مضاعفة واحدة تعطي 0.6، إذن n = 1 وM0 = 0.6. جرّب M = 0.5: هي أصلاً داخل المدى، إذن n = 0 وM0 = 0.5. القاعدة آلية: n هو عدد المضاعفات اللازمة للوصول إلى 0.5، وM0 = M x 2^n.
Why M is below 1, and why that is only an observationلماذا M أقل من 1، ولماذا هذه مجرد ملاحظة
S_W S_X is the value of one unit in the accumulator, and the accumulator sums many products, so it spans a far wider range than one output code. S_Y must cover that whole output range in only 2^N levels, so it is usually much larger than S_W S_X, which makes M small. Jacob et al. report that they empirically find it to always be in (0, 1). That is a finding about trained networks, not a theorem: nothing in the algebra forbids S_Y < S_W S_X. The gemmlowp documentation is more careful and says the multiplier is typically less than one.
S_W S_X هو قيمة الوحدة الواحدة في المراكم، والمراكم يجمع نواتج كثيرة، لذلك يمتد على مدى أوسع بكثير من رمز مخرج واحد. يجب أن يغطي S_Y مدى المخرج كله في 2^N مستوى فقط، لذلك يكون عادة أكبر بكثير من S_W S_X، وهذا يجعل M صغيراً. ويذكر Jacob et al. أنهم وجدوه تجريبياً دائماً في (0, 1). هذه نتيجة عن الشبكات المدرّبة، لا نظرية رياضية: لا شيء في الجبر يمنع S_Y < S_W S_X. ووثائق gemmlowp أكثر حذراً، إذ تقول إن المضاعِف يكون عادةً أقل من واحد.
Recall
Why is M0 restricted to [0.5, 1) rather than stored as M directly?لماذا يُقيَّد M0 بالمدى [0.5, 1) بدلاً من تخزين M مباشرة؟
Quick checkاختبار سريع
A layer has M = 0.045. What are n and M0 in M = 2^(-n) M0?طبقة فيها M = 0.045. ما قيمتا n و M0 في M = 2^(-n) M0؟
Go back to the cost map and look at the one term that is neither the core product nor precomputable: Z_W q_X. Slide 14 shades it light blue for that reason. Every inference, before or alongside the main multiply, the kernel has to sum each column of the input codes, multiply by Z_W and subtract. That is an extra pass over X, every inference, for every layer. The extra work is smaller than the matrix product itself (Jacob et al. count it as order N^2 additions against 2N^3 for the product), but it costs memory traffic, kernel complexity and energy, and on a tiny device none of that is free.
عد إلى خريطة التكلفة وانظر إلى الحد الوحيد الذي ليس هو حاصل الضرب الأساسي ولا يمكن حسابه مسبقاً: Z_W q_X. لهذا السبب تظلله الشريحة 14 باللون الأزرق الفاتح. في كل استدلال، قبل الضرب الرئيسي أو بالتوازي معه، يجب على النواة (kernel) أن تجمع كل عمود من رموز المدخل، وتضربه في Z_W، ثم تطرحه. هذا مرور إضافي على X، في كل استدلال، ولكل طبقة. العمل الإضافي أصغر من ضرب المصفوفات نفسه (يحسبه Jacob et al. بعدد عمليات جمع من رتبة N^2 مقابل 2N^3 لحاصل الضرب)، لكنه يكلّف حركة ذاكرة وتعقيداً في النواة وطاقة، وعلى جهاز صغير لا شيء من ذلك مجاني.
The slide's question, Z_W = 0?, is the obvious way out. If the weight zero point is zero, the term Z_W q_X vanishes, and so does Z_W Z_X. What remains is
سؤال الشريحة، Z_W = 0?، هو المخرج الواضح. إذا كانت نقطة الصفر للأوزان صفراً، يختفي الحد Z_W q_X، ويختفي معه Z_W Z_X. والمتبقي هو
Now the only runtime work inside the bracket is the integer matrix product, and the only correction is precomputed. This choice is Z_W = 0, and in practice it means quantizing weights with Symmetric quantization, the topic of the next part.
الآن العمل الوحيد وقت التشغيل داخل القوس هو ضرب المصفوفات الصحيح، والتصحيح الوحيد محسوب مسبقاً. هذا الاختيار هو Z_W = 0، ويعني عملياً تكميم الأوزان بـ Symmetric quantization (التكميم المتماثل)، وهو موضوع الجزء التالي.
Why weights can afford itلماذا تستطيع الأوزان تحمّل ذلك
Forcing Z = 0 means real 0 sits in the middle of the integer range, so the scheme is only efficient when the data is spread roughly evenly on both sides of zero. The histogram on slide 14 shows that weights are: the Weight distribution of a trained layer is a narrow bell, peaked at 0, falling off almost symmetrically by about -0.05 and +0.05. Centering the grid at zero wastes almost no levels. Activations after a ReLU are the opposite case, all non-negative, so a symmetric grid would waste half its codes on values that never occur. That is why activations keep a free zero point and weights do not.
فرض Z = 0 يعني أن الصفر الحقيقي 0 يقع في منتصف مدى الأعداد الصحيحة، لذلك لا يكون هذا الأسلوب فعالاً إلا عندما تنتشر البيانات بشكل متوازن تقريباً على جانبي الصفر. ويُظهر المدرج التكراري (histogram) في الشريحة 14 أن الأوزان كذلك: Weight distribution لطبقة مدرّبة جرس ضيق قمته عند 0، ويتلاشى بشكل شبه متماثل عند نحو -0.05 و+0.05. توسيط الشبكة عند الصفر لا يكاد يهدر أي مستوى. أما التنشيطات (activations) بعد ReLU فهي الحالة المعاكسة، كلها غير سالبة، فالشبكة المتماثلة ستهدر نصف رموزها على قيم لا تظهر أبداً. لهذا تحتفظ التنشيطات بنقطة صفر حرة ولا تحتفظ الأوزان بها.
Recall
Why does Z_W = 0 help more than Z_X = 0 would?لماذا يفيد Z_W = 0 أكثر مما قد يفيده Z_X = 0؟
Quick checkاختبار سريع
After setting Z_W = 0, which zero-point correction term is still left inside the bracket?بعد جعل Z_W = 0، أي حد تصحيح لنقطة الصفر يبقى داخل القوس؟
Recapالخلاصة
If you remember nothing elseإن لم تتذكر شيئاً آخر فتذكّر هذا
- Substitute r = S(q - Z) into Y = WX for all three tensors, divide by S_Y, add Z_Y: q_Y = (S_W S_X / S_Y)(q_W - Z_W)(q_X - Z_X) + Z_Y.عوّض r = S(q - Z) في Y = WX للمصفوفات الثلاث، ثم اقسم على S_Y وأضف Z_Y: q_Y = (S_W S_X / S_Y)(q_W - Z_W)(q_X - Z_X) + Z_Y.
- Expanded: q_Y = M(q_W q_X - Z_W q_X - Z_X q_W + Z_W Z_X) + Z_Y with M = S_W S_X / S_Y.بعد فك الأقواس: q_Y = M(q_W q_X - Z_W q_X - Z_X q_W + Z_W Z_X) + Z_Y حيث M = S_W S_X / S_Y.
- q_W q_X and Z_W q_X run every inference (they touch the input). -Z_X q_W + Z_W Z_X depends only on weights and fixed parameters, so it is precomputed offline.الحدّان q_W q_X و Z_W q_X يُحسبان في كل استدلال (لأنهما يتعاملان مع المدخل). أما -Z_X q_W + Z_W Z_X فيعتمد فقط على الأوزان والمعاملات الثابتة، لذلك يُحسب مسبقاً offline.
- In a real matrix product, Z_W q_X means Z_W times the column sums of q_X, Z_X q_W means Z_X times the row sums of q_W, and Z_W Z_X is multiplied by the inner dimension K.في ضرب المصفوفات الحقيقي، Z_W q_X تعني Z_W مضروباً في مجاميع أعمدة q_X، و Z_X q_W تعني Z_X مضروباً في مجاميع صفوف q_W، و Z_W Z_X يُضرب في البعد الداخلي K.
- An int8 x int8 product needs 16 bits and a sum of K products needs about 16 + log2(K) bits, so products are summed in an int32 accumulator.حاصل ضرب int8 x int8 يحتاج 16 بت، ومجموع K من هذه النواتج يحتاج نحو 16 + log2(K) بت، لذلك تُجمع النواتج في مراكم int32.
- M is a float, empirically in (0, 1). Write M = 2^(-n) M0 with M0 in [0.5, 1): M0 becomes an int32 fixed-point multiplier (Q31) and 2^(-n) a rounding right shift. Example: M = 0.0072 gives n = 7, M0 = 0.9216.M عدد عشري (float)، ويقع تجريبياً في (0, 1). اكتب M = 2^(-n) M0 حيث M0 في [0.5, 1): يصبح M0 مضاعِفاً بفاصلة ثابتة من نوع int32 (بصيغة Q31)، ويصبح 2^(-n) إزاحة يمينية مع تقريب. مثال: M = 0.0072 يعطي n = 7 و M0 = 0.9216.
- Z_W q_X cannot be precomputed and costs an extra pass over X. Weights are bell-shaped around 0, so symmetric quantization with Z_W = 0 removes that term for free.لا يمكن حساب Z_W q_X مسبقاً، وهو يكلّف مروراً إضافياً على X. الأوزان على شكل جرس حول 0، لذلك يزيل التكميم المتماثل مع Z_W = 0 هذا الحد مجاناً.
Sourcesالمصادر
- Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only InferencePaperJacob et al., CVPR 2018Section 2.2: M empirically in (0, 1), M = 2^(-n) M0 with M0 in [0.5, 1), int32 nearest 2^31 M0. Section 2.3: the N Z1 Z2 term and row and column sums. Section 2.4: 32-bit accumulatorالقسم 2.2: M يقع تجريبياً في (0, 1)، و M = 2^(-n) M0 حيث M0 في [0.5, 1)، و int32 الأقرب إلى 2^31 M0. القسم 2.3: الحد N Z1 Z2 ومجاميع الصفوف والأعمدة. القسم 2.4: مراكم 32 بت(opens in a new tab)(يفتح في تبويب جديد)
- gemmlowp: the low-precision paradigmDocsGoogleFour-term expansion with offsets: row sums, column sums, and the constant offset product times depthفك الحدود الأربعة مع الإزاحات (offsets): مجاميع الصفوف، ومجاميع الأعمدة، وحاصل ضرب الإزاحتين الثابت مضروباً في العمق (depth)(opens in a new tab)(يفتح في تبويب جديد)
- gemmlowp: quantizationDocsGoogleMultiplier typically less than one, applied as a fixed-point multiply in [1/2, 1) and a right shiftالمضاعِف عادةً أقل من واحد، ويُطبَّق على شكل ضرب بفاصلة ثابتة في [1/2, 1) ثم إزاحة يمينية(opens in a new tab)(يفتح في تبويب جديد)
- LiteRT 8-bit quantization specificationDocsGoogleSymmetric weights with zero point 0, asymmetric activations, and why the activation cross term runs every inferenceأوزان متماثلة بنقطة صفر 0، وتنشيطات غير متماثلة، ولماذا يُحسب الحد المتقاطع مع التنشيط في كل استدلال(opens in a new tab)(يفتح في تبويب جديد)
Part 04: Symmetric Quantization and Bias Handlingالتكميم المتماثل ومعالجة الانحياز (Bias)
Symmetric quantization fixes Z = 0 and uses the range [-|r|max, |r|max], which makes the S formula simpler and removes the runtime Z_W q_X term. Bias then enters the fully-connected layer and is quantized with Z_b = 0 and S_b = S_W S_X, so that it shares the accumulator's scale.التكميم المتماثل يثبّت Z = 0 ويستخدم المدى [-|r|max, |r|max]، مما يبسّط صيغة S ويزيل الحد Z_W q_X وقت التشغيل. ثم يدخل الانحياز (bias) في الطبقة المتصلة كليًا ويُكمَّم بـZ_b = 0 وS_b = S_W S_X، ليشارك المُجمِّع (accumulator) مقياسه نفسه.
4 concepts4 مفاهيم, ، slides 15-19الشرائح 15-19
Why this part mattersلماذا يهمّ هذا الجزء
The previous part ended with a question: the matrix multiply has a term, Z_W q_X, that depends on the input and so must be computed at every inference. Can we make it vanish? This part answers yes, by choosing a weight zero point of exactly 0. That one choice is called symmetric quantization, and it changes the scale formula, the integer pipeline, and how the bias gets folded in.
These slides are dense with exam material. Expect to compute a symmetric scale for a given bit width, to defend why weights get Z_W = 0 while activations do not, and to explain why the bias is stored as a 32-bit integer with scale S_W S_X. The running 4x4 weight matrix from slide 8, with values from -1.08 to 2.12, carries every worked number.
انتهى الجزء السابق بسؤال: في ضرب المصفوفات حدّ هو Z_W q_X يعتمد على المُدخل، ولذلك يجب حسابه في كل عملية استدلال. هل يمكن أن نجعله يختفي؟ يجيب هذا الجزء بنعم، وذلك باختيار نقطة صفر للأوزان تساوي 0 تمامًا. هذا الاختيار الواحد يسمى التكميم المتماثل (symmetric quantization)، وهو يغيّر صيغة المقياس، ومسار الحساب بالأعداد الصحيحة، وطريقة دمج الانحياز (bias).
هذه الشرائح مليئة بمادة الامتحان. توقّع أن يُطلب منك حساب مقياس متماثل لعرض بتات معيّن، وأن تدافع عن سبب حصول الأوزان على Z_W = 0 بينما لا تحصل عليه مخرجات التنشيط، وأن تشرح لماذا يُخزَّن الانحياز كعدد صحيح بـ32 بت بمقياس S_W S_X. مصفوفة الأوزان المرافقة 4x4 من الشريحة 8، بقيمها من -1.08 إلى 2.12، تحمل كل الأرقام المحلولة.
By the end you canفي نهاية هذا الجزء ستستطيع
- State what symmetric quantization fixes (Z = 0, range [-|r|max, |r|max]) and when it fits the data.أن تذكر ما الذي يثبّته التكميم المتماثل (Z = 0، والمدى [-|r|max, |r|max]) ومتى يناسب البيانات.
- Compute the full range symmetric scale S = |r|max / 2^(N-1) for any bit width, and explain why +|r|max gets clipped.أن تحسب مقياس المدى الكامل المتماثل S = |r|max / 2^(N-1) لأي عرض بتات، وأن تشرح لماذا تُقصّ القيمة +|r|max.
- Contrast full range mode with restricted range mode and with asymmetric quantization on the same tensor.أن تقارن نمط المدى الكامل بنمط المدى المقيّد وبالتكميم غير المتماثل على نفس الموتر.
- Explain why weights use Z_W = 0 while ReLU activations keep Z_X different from 0.أن تشرح لماذا تستخدم الأوزان Z_W = 0 بينما تحتفظ مخرجات ReLU بقيمة Z_X لا تساوي 0.
- Derive the fully-connected layer with bias and justify Z_b = 0, S_b = S_W S_X and a 32-bit bias.أن تشتق الطبقة كاملة الاتصال مع الانحياز (bias) وتبرر اختيار Z_b = 0 وS_b = S_W S_X وتخزين الانحياز بـ32 بت.
Take two tensors. One is a layer of trained weights, with values scattered from about -2 to about +2 and most of them near 0. The other is the output of a ReLU, every value between 0 and 6. Both need to become 8-bit codes. Should both get the same kind of integer grid?
خذ موترين. الأول طبقة من الأوزان المدرّبة، قيمها منتشرة من حوالي -2 إلى حوالي +2 ومعظمها قريب من 0. والثاني مخرجات ReLU، كل قيمها بين 0 و6. كلاهما يجب أن يتحول إلى رموز بـ8 بت. فهل يجب أن يحصل الاثنان على نفس النوع من شبكة الأعداد الصحيحة؟
So far we have used asymmetric quantization: the float range [r_min, r_max] is stretched onto the code range [q_min, q_max], and the zero point Z lands wherever real 0 happens to fall. In the left half of slide 15 that is somewhere in the middle of the dots, and for the running matrix at 2 bits it was Z = -1. Symmetric quantization removes that freedom. It declares Z = 0 up front and, to make that consistent, quantizes a range centred on zero: [-|r|max, |r|max], where |r|max is the largest absolute value in the tensor.
حتى الآن استخدمنا asymmetric quantization (التكميم غير المتماثل): يُمدّ مدى القيم العشرية [r_min, r_max] على مدى الرموز [q_min, q_max]، وتقع zero point (نقطة الصفر) Z حيثما صادف أن وقع الصفر الحقيقي 0. في النصف الأيسر من الشريحة 15 يقع ذلك في مكان ما وسط النقاط، وفي المصفوفة المرافقة عند 2 بت كانت Z = -1. Symmetric quantization (التكميم المتماثل) يلغي هذه الحرية. فهو يعلن Z = 0 مسبقًا، ولكي يكون ذلك متسقًا يكمّم مدى متمركزًا حول الصفر: [-|r|max, |r|max]، حيث |r|max هي أكبر قيمة مطلقة في الموتر.
The integer side does not change. The codes are still signed N-bit integers with q_min and q_max taken from the table on the slide:
جانب الأعداد الصحيحة لا يتغير. الرموز ما زالت أعدادًا صحيحة بإشارة من N-bit، وقيمتا q_min and q_max مأخوذتان من الجدول الموجود في الشريحة:
| Bit width Nعرض البتات N | q_min = -2^(N-1)q_min = -2^(N-1) | q_max = 2^(N-1) - 1q_max = 2^(N-1) - 1 | Levelsعدد المستويات |
|---|---|---|---|
| 22 | -2-2 | 11 | 44 |
| 33 | -4-4 | 33 | 88 |
| 44 | -8-8 | 77 | 1616 |
| 88 | -128-128 | 127127 | 256256 |
Notice the range is already lopsided: there is one more negative code than positive. Keep that in mind; it is the root of the clipping problem in the next concept.
لاحظ أن المدى غير متوازن أصلًا: فيه رمز سالب واحد زيادة على عدد الرموز الموجبة. تذكّر هذا، فهو أصل مشكلة القصّ (clipping) في المفهوم التالي.
Who should be symmetric?من الذي يجب أن يكون متماثلًا؟
The answer depends on the shape of the data. Trained weights have a bell-shaped distribution centred near 0, so a range centred on 0 fits them well and almost no codes go to waste. ReLU outputs are the opposite: every value is 0 or positive. A symmetric grid would reserve the entire negative half of its codes for values that never occur.
الإجابة تعتمد على شكل البيانات. الأوزان المدرّبة لها bell-shaped distribution (توزيع على شكل جرس) متمركز قرب 0، لذلك يناسبها مدى متمركز حول 0، ولا يكاد يضيع أي رمز. مخرجات ReLU عكس ذلك: كل قيمة إما 0 أو موجبة. الشبكة المتماثلة ستحجز النصف السالب كله من رموزها لقيم لا تظهر أبدًا.
Worked exampleمثال محلول
ReLU6 activations in [0, 6] as INT8مخرجات ReLU6 في المدى [0, 6] بصيغة INT8
Symmetric, full rangeمتماثل، بالمدى الكامل
|r|max = 6, so S = 6 / 128 = 0.0469. Only codes 0 to 127 are ever used; the 128 negative codes are dead.|r|max = 6، إذن S = 6 / 128 = 0.0469. الرموز من 0 إلى 127 فقط هي التي تُستخدم فعليًا، أما الرموز السالبة وعددها 128 فميتة.Asymmetricغير متماثل
S = (6 - 0) / (127 - (-128)) = 6 / 255 = 0.0235 and Z = round(q_min - r_min / S) = round(-128 - 0) = -128. All 256 codes cover real data.S = (6 - 0) / (127 - (-128)) = 6 / 255 = 0.0235 و Z = round(q_min - r_min / S) = round(-128 - 0) = -128. كل الرموز وعددها 256 تغطي بيانات حقيقية.Resultالنتيجة
Asymmetric gives a step about half as large (0.0235 versus 0.0469), so the worst-case rounding error S / 2 is halved. That is why activations keep a zero point.غير المتماثل يعطي خطوة بحجم النصف تقريبًا (0.0235 مقابل 0.0469)، لذلك ينخفض أسوأ خطأ تقريب S / 2 إلى النصف. ولهذا تحتفظ مخرجات التنشيط بنقطة صفر.
Recall
Why is Z_W = 0 a good choice for weights but Z_X = 0 a poor choice for ReLU activations?لماذا يكون Z_W = 0 اختيارًا جيدًا للأوزان بينما يكون Z_X = 0 اختيارًا سيئًا لمخرجات ReLU؟
Run the running matrix through a symmetric quantizer. Its largest magnitude is 2.12, so the range is [-2.12, 2.12]. How big is one step?
مرّر المصفوفة المرافقة عبر مكمِّم متماثل. أكبر قيمة مطلقة فيها هي 2.12، لذلك المدى هو [-2.12, 2.12]. فكم حجم الخطوة الواحدة؟
Slide 16 puts the two scale formulas side by side. The asymmetric one is the familiar endpoint match from part two:
الشريحة 16 تضع صيغتي المقياس جنبًا إلى جنب. صيغة غير المتماثل هي مطابقة الطرفين المألوفة من الجزء الثاني:
The symmetric one comes from matching only the negative end. With Z = 0, the endpoint equation r_min = S(q_min - Z) becomes -|r|max = S q_min, and q_min = -2^(N-1):
أما صيغة المتماثل فتأتي من مطابقة الطرف السالب فقط. مع Z = 0 تصبح معادلة الطرف r_min = S(q_min - Z) هي -|r|max = S q_min، وq_min = -2^(N-1):
This is full range mode: it uses every code from -2^(N-1) up to 2^(N-1) - 1. For the running matrix in INT8, S = 2.12 / 128 = 0.01656.
هذا هو full range mode (نمط المدى الكامل): يستخدم كل الرموز من -2^(N-1) حتى 2^(N-1) - 1. للمصفوفة المرافقة بصيغة INT8 يكون S = 2.12 / 128 = 0.01656.
The value at the top does not fitالقيمة في الأعلى لا تتسع
The scale was fixed by the negative end. Now quantize the positive end: q = round(2.12 / 0.01656) = 128. But q_max = 127. Code 128 does not exist, so the value is clamped to 127 and comes back as 127 x 0.01656 = 2.103. In general, +|r|max maps to 2^(N-1), one step past q_max, because the signed range has one more negative code than positive.
المقياس حُدّد بواسطة الطرف السالب. الآن كمّم الطرف الموجب: q = round(2.12 / 0.01656) = 128. لكن q_max = 127. الرمز 128 غير موجود، لذلك تُحصر القيمة (clamp) إلى 127 وتعود بقيمة 127 x 0.01656 = 2.103. وبشكل عام، تُحوَّل +|r|max إلى 2^(N-1)، أي خطوة واحدة بعد q_max، لأن المدى ذا الإشارة فيه رمز سالب واحد زيادة على الرموز الموجبة.
Restricted range modeنمط المدى المقيّد
Many deployed toolchains give up the lonely -128 code instead. In restricted range mode the codes run from -(2^(N-1) - 1) to 2^(N-1) - 1, which is [-127, 127] for INT8, and the scale divides by q_max instead:
كثير من سلاسل الأدوات المستخدمة فعليًا تتخلى بدلًا من ذلك عن الرمز الوحيد -128. في restricted range mode (نمط المدى المقيّد) تمتد الرموز من -(2^(N-1) - 1) إلى 2^(N-1) - 1، أي [-127, 127] في INT8، ويُقسم المقياس على q_max بدلًا من ذلك:
Now both +|r|max and -|r|max land exactly on a code, and nothing clips. The cost is one code out of 2^N. TensorFlow Lite stores int8 weights in [-127, 127] with zero point 0, and NVIDIA's int8 workflow (Wu et al.) makes the same choice, noting that losing one value of 256 is insignificant at 8 bits but must be reconsidered at lower bit widths.
الآن تقع كل من +|r|max و-|r|max على رمز بالضبط، ولا يُقصّ شيء. الثمن رمز واحد من أصل 2^N. يخزّن TensorFlow Lite أوزان int8 في [-127, 127] مع نقطة صفر 0، وسير عمل int8 من NVIDIA (Wu et al.) يتخذ الاختيار نفسه، مع ملاحظة أن خسارة قيمة واحدة من 256 لا تُذكر عند 8 بت، لكن يجب إعادة النظر فيها عند عروض بتات أقل.
Worked exampleمثال محلول
Three symmetric grids for the running matrix (|r|max = 2.12)ثلاث شبكات متماثلة للمصفوفة المرافقة (|r|max = 2.12)
INT8, full rangeINT8، بالمدى الكامل
S = 2.12 / 128 = 0.01656. 2.12 clips to 2.103.S = 2.12 / 128 = 0.01656. تُقصّ 2.12 إلى 2.103.INT8, restricted rangeINT8، بالمدى المقيّد
S = 2.12 / 127 = 0.01669. Slightly coarser, but 2.12 is code 127 exactly.S = 2.12 / 127 = 0.01669. أخشن قليلًا، لكن 2.12 هي الرمز 127 بالضبط.2-bit, full range2 بت، بالمدى الكامل
S = 2.12 / 2^1 = 1.06. Codes -2, -1, 0, 1 give the levels {-2.12, -1.06, 0, 1.06}. Quantize the top-left weight 2.09: 2.09 / 1.06 = 1.97, which rounds to 2, clips to q_max = 1, and comes back as 1.06.S = 2.12 / 2^1 = 1.06. الرموز -2, -1, 0, 1 تعطي المستويات {-2.12, -1.06, 0, 1.06}. كمّم الوزن في أعلى اليسار 2.09: 2.09 / 1.06 = 1.97، وهي تُقرّب إلى 2، ثم تُقصّ إلى q_max = 1، وتعود بقيمة 1.06.Resultالنتيجة
At 8 bits the two modes differ by less than one percent in S. At 2 bits the clipped weight is off by 2.09 - 1.06 = 1.03, about half its value. Compare the asymmetric 2-bit grid from part two (S = 1.07, Z = -1), which brings 2.09 back as 1.07 x (1 - (-1)) = 2.14, an error of only 0.05.عند 8 بت يختلف النمطان بأقل من واحد بالمئة في S. وعند 2 بت يبتعد الوزن المقصوص بمقدار 2.09 - 1.06 = 1.03، أي حوالي نصف قيمته. قارن ذلك بالشبكة غير المتماثلة بـ2 بت من الجزء الثاني (S = 1.07، Z = -1)، التي تعيد 2.09 بقيمة 1.07 x (1 - (-1)) = 2.14، بخطأ قدره 0.05 فقط.
The trade-off, on the same tensorالمقايضة على نفس الموتر
The running matrix is skewed: its values reach +2.12 but only -1.08. Asymmetric INT8 fits that exactly with S = 3.20 / 255 = 0.01255. Symmetric must cover [-2.12, 2.12] and uses S = 0.01656, about 32% coarser, and the codes below round(-1.08 / 0.01656) = -65 are never used: 63 of 256 codes, roughly a quarter, are wasted. Drag the slider below from a balanced range to a fully one-sided one and watch the symmetric grid stay frozen while the asymmetric one follows the data.
المصفوفة المرافقة منحرفة: قيمها تصل إلى +2.12 لكنها لا تنزل إلا إلى -1.08. التكميم غير المتماثل بـINT8 يطابق ذلك تمامًا بـS = 3.20 / 255 = 0.01255. أما المتماثل فيجب أن يغطي [-2.12, 2.12] ويستخدم S = 0.01656، أي أخشن بحوالي 32%، والرموز الأقل من round(-1.08 / 0.01656) = -65 لا تُستخدم أبدًا: 63 رمزًا من 256، أي ربع الرموز تقريبًا، تضيع. حرّك المنزلق أدناه من مدى متوازن إلى مدى في جهة واحدة بالكامل، وراقب كيف تبقى الشبكة المتماثلة ثابتة بينما تتبع الشبكة غير المتماثلة البيانات.
| Asymmetricغير متماثل | Symmetric (full range)متماثل (بالمدى الكامل) | |
|---|---|---|
| Zero pointنقطة الصفر | Z = round(q_min - r_min / S)Z = round(q_min - r_min / S) | Z = 0Z = 0 |
| Range quantizedالمدى المكمَّم | [r_min, r_max][r_min, r_max] | [-|r|max, |r|max][-|r|max, |r|max] |
| Scaleالمقياس | (r_max - r_min) / (q_max - q_min)(r_max - r_min) / (q_max - q_min) | |r|max / 2^(N-1)|r|max / 2^(N-1) |
| Skewed dataالبيانات المنحرفة | Uses every codeيستخدم كل الرموز | Wastes the empty sideيضيّع الجهة الفارغة |
| Runtime cost in matmulكلفة وقت التشغيل في ضرب المصفوفات | Extra input-dependent termحدّ إضافي يعتمد على المُدخل | Noneلا شيء |
| Typical useالاستخدام المعتاد | ReLU activationsمخرجات ReLU | Weightsالأوزان |
Quick checkاختبار سريع
With N = 4 bits and |r|max = 2.4, what is the full range symmetric scale S?إذا كان N = 4 بت و |r|max = 2.4، فما قيمة المقياس المتماثل بالمدى الكامل S؟
Recall
In full range mode, what code does +|r|max map to, and what happens to it?في نمط المدى الكامل، إلى أي رمز تتحول +|r|max، وماذا يحدث لها؟
Here is the payoff. Recall the full expansion of a quantized matrix multiplication from part three, with its four terms inside the bracket:
هنا تأتي الفائدة. تذكّر المفكوك الكامل لـquantized matrix multiplication (ضرب المصفوفات المكمّم) من الجزء الثالث، بحدوده الأربعة داخل القوس:
Sort the terms by what they depend on. q_W q_X is the real work: integer multiply-accumulates. Z_X q_W and Z_W Z_X involve only weights and fixed parameters, so they are precomputed offline. That leaves Z_W q_X: it contains the input, so it has to be recomputed for every new input, as an extra sum over the activations. Set Z_W = 0 and both Z_W q_X and Z_W Z_X disappear:
رتّب الحدود بحسب ما تعتمد عليه. q_W q_X هو العمل الحقيقي: عمليات ضرب وتجميع بالأعداد الصحيحة. Z_X q_W وZ_W Z_X لا تتضمنان إلا الأوزان ومعاملات ثابتة، لذلك تُحسبان مسبقًا (precomputed) خارج وقت التشغيل. يبقى Z_W q_X: فهو يحتوي على المُدخل، لذلك يجب إعادة حسابه لكل مُدخل جديد، كمجموع إضافي على قيم التنشيط. اجعل Z_W = 0 فيختفي كل من Z_W q_X وZ_W Z_X:
At inference time the only work inside the bracket is the N-bit integer product q_W q_X, summed in a 32-bit accumulator. The term Z_X q_W is a constant per output, added once. Outside the bracket, the rescale by S_W S_X / S_Y and the addition of Z_Y are unchanged from part three.
وقت الاستدلال، العمل الوحيد داخل القوس هو حاصل الضرب الصحيح بـN بت q_W q_X، الذي يُجمع في 32-bit accumulator (مجمّع بـ32 بت). الحد Z_X q_W ثابت لكل مخرج، ويُضاف مرة واحدة. وخارج القوس، تبقى rescale (إعادة القياس) بـS_W S_X / S_Y وإضافة Z_Y دون تغيير عن الجزء الثالث.
Worked exampleمثال محلول
One output of a two-term dot productمخرج واحد لضرب نقطي من حدّين
Set upالإعداد
Weights q_W = [3, -2] (symmetric, Z_W = 0), activations q_X = [10, 4] with Z_X = 2.الأوزان q_W = [3, -2] (متماثلة، Z_W = 0)، ومخرجات التنشيط q_X = [10, 4] مع Z_X = 2.Runtimeوقت التشغيل
q_W q_X = 3 x 10 + (-2) x 4 = 22.q_W q_X = 3 x 10 + (-2) x 4 = 22.Offlineمسبقًا خارج وقت التشغيل
Z_X q_W = 2 x (3 + (-2)) = 2, known before any input arrives.Z_X q_W = 2 x (3 + (-2)) = 2، وهو معروف قبل وصول أي مُدخل.Resultالنتيجة
Accumulator = 22 - 2 = 20. Check directly: 3 x (10 - 2) + (-2) x (4 - 2) = 24 - 4 = 20. Had the weights used Z_W = 1, the term Z_W (10 + 4) = 14 would also be needed, and its 10 + 4 changes with every input.المجمّع = 22 - 2 = 20. تحقّق مباشرة: 3 x (10 - 2) + (-2) x (4 - 2) = 24 - 4 = 20. لو استخدمت الأوزان Z_W = 1 لاحتجنا أيضًا إلى الحد Z_W (10 + 4) = 14، والجزء 10 + 4 فيه يتغير مع كل مُدخل.
Recall
Why ask for Z_W = 0 but not Z_X = 0?لماذا نطلب Z_W = 0 ولا نطلب Z_X = 0؟
Recapالخلاصة
If you remember nothing elseإن لم تتذكر شيئاً آخر فتذكّر هذا
- Symmetric quantization fixes Z = 0 and quantizes the range [-|r|max, |r|max]; asymmetric keeps a free Z and fits [r_min, r_max].التكميم المتماثل يثبّت Z = 0 ويكمّم المدى [-|r|max, |r|max]، أما غير المتماثل فيترك Z حرًّا ويطابق المدى [r_min, r_max].
- Asymmetric: S = (r_max - r_min) / (q_max - q_min). Symmetric full range: S = r_min / (q_min - Z) = -|r|max / q_min = |r|max / 2^(N-1).غير المتماثل: S = (r_max - r_min) / (q_max - q_min). المتماثل بالمدى الكامل: S = r_min / (q_min - Z) = -|r|max / q_min = |r|max / 2^(N-1).
- Full range maps +|r|max to code 2^(N-1), one step past q_max = 2^(N-1) - 1, so the largest positive value is clipped.المدى الكامل يحوّل +|r|max إلى الرمز 2^(N-1)، أي خطوة واحدة بعد q_max = 2^(N-1) - 1، لذلك تُقصّ أكبر قيمة موجبة.
- Restricted range (not on the slides) uses S = |r|max / (2^(N-1) - 1) and codes [-127, 127] for INT8, giving up one code to stay symmetric.المدى المقيّد (غير موجود في الشرائح) يستخدم S = |r|max / (2^(N-1) - 1) والرموز [-127, 127] في INT8، فيتنازل عن رمز واحد ليبقى متماثلًا.
- Running matrix (|r|max = 2.12): INT8 full range S = 0.01656, restricted S = 0.01669, 2-bit S = 1.06 with levels {-2.12, -1.06, 0, 1.06}.المصفوفة المرافقة (|r|max = 2.12): INT8 بالمدى الكامل S = 0.01656، وبالمدى المقيّد S = 0.01669، وبـ2 بت S = 1.06 مع المستويات {-2.12, -1.06, 0, 1.06}.
- At 2 bits, 2.09 / 1.06 = 1.97 rounds to 2, clips to 1 and comes back as 1.06: an error of 1.03.عند 2 بت: 2.09 / 1.06 = 1.97 تُقرّب إلى 2، ثم تُقصّ إلى 1، وتعود بقيمة 1.06، أي بخطأ قدره 1.03.
- Weights are bell-shaped around 0, so they go symmetric. ReLU activations are one-sided, so they stay asymmetric with Z_X not 0.الأوزان على شكل جرس حول 0، لذلك تُكمَّم تكميمًا متماثلًا. مخرجات ReLU في جهة واحدة، لذلك تبقى غير متماثلة مع Z_X لا يساوي 0.
- With Z_W = 0: q_Y = (S_W S_X / S_Y)(q_W q_X - Z_X q_W) + Z_Y. Only q_W q_X runs at inference; Z_X q_W is precomputed.مع Z_W = 0: q_Y = (S_W S_X / S_Y)(q_W q_X - Z_X q_W) + Z_Y. وحده q_W q_X يُحسب أثناء الاستدلال، أما Z_X q_W فيُحسب مسبقًا.
- Bias uses Z_b = 0 and S_b = S_W S_X so q_b adds straight into the int32 accumulator: S_Y(q_Y - Z_Y) = S_W S_X(q_W q_X - Z_X q_W + q_b).الانحياز يستخدم Z_b = 0 وS_b = S_W S_X حتى يُضاف q_b مباشرة إلى المجمّع int32: S_Y(q_Y - Z_Y) = S_W S_X(q_W q_X - Z_X q_W + q_b).
- S_b is tiny, so q_b is large: S_W = 0.01, S_X = 0.05, b = 0.37 gives q_b = 740, which needs 32 bits.S_b صغير جدًا، لذلك يكون q_b كبيرًا: S_W = 0.01 وS_X = 0.05 وb = 0.37 تعطي q_b = 740، وهذا يحتاج 32 بت.
Sourcesالمصادر
- Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only InferencePaperJacob et al., CVPR 2018Section 2.4: int32 bias with S_bias = S1 S2 and Z_bias = 0, and why bias error acts as a systematic offset.القسم 2.4: انحياز int32 مع S_bias = S1 S2 و Z_bias = 0، ولماذا يعمل خطأ الانحياز كإزاحة منهجية.(opens in a new tab)(يفتح في تبويب جديد)
- LiteRT 8-bit quantization specificationDocsGoogle AI EdgeWeights symmetric in [-127, 127] with zero point 0, activations asymmetric, bias int32 with scale input_scale x weight_scale.الأوزان متماثلة في [-127, 127] مع نقطة صفر 0، ومخرجات التنشيط غير متماثلة، والانحياز int32 بمقياس input_scale x weight_scale.(opens in a new tab)(يفتح في تبويب جديد)
- Integer Quantization for Deep Learning Inference: Principles and Empirical EvaluationPaperWu, Judd, Zhang, Isaev, Micikevicius (NVIDIA), 2020Scale quantization with the restricted range [-127, 127], and why affine weights add an input-dependent term.تكميم المقياس (scale quantization) بالمدى المقيّد [-127, 127]، ولماذا تضيف الأوزان المُزاحة (affine) حدًّا يعتمد على المُدخل.(opens in a new tab)(يفتح في تبويب جديد)
- A White Paper on Neural Network QuantizationPaperNagel et al. (Qualcomm AI Research), 2021Section 2.4.1: symmetric weights and asymmetric activations avoid the data-dependent term; bias kept at 32 bits.القسم 2.4.1: الأوزان المتماثلة ومخرجات التنشيط غير المتماثلة تتجنب الحد المعتمد على البيانات، ويبقى الانحياز بـ 32 بت.(opens in a new tab)(يفتح في تبويب جديد)
- MIT 6.5940 TinyML and Efficient Deep Learning Computing, Lecture 6: Quantization (Part II)ArticleSong Han, MITThe lecture these slides are adapted from.المحاضرة التي اقتُبست منها هذه الشرائح.(opens in a new tab)(يفتح في تبويب جديد)
Part 05: Integer-Only FC and Conv Layers, and INT8 Resultsطبقات FC وConv بالأعداد الصحيحة فقط، ونتائج INT8
Folds the precomputed -Z_X q_W into a single 32-bit q_bias to give the final integer-only FC formula. The same pattern is then applied to convolution and drawn as an int8 to int32 to int8 dataflow. INT8 accuracy and latency evidence from Jacob et al. follows, and the lecture closes by returning to the storage/computation table.يدمج الحد المحسوب مسبقًا -Z_X q_W في q_bias واحد من 32 بت ليعطي صيغة FC النهائية بالأعداد الصحيحة فقط. ثم يُطبَّق النمط نفسه على الالتفاف ويُرسم كتدفق بيانات int8 إلى int32 إلى int8. تليه أدلة الدقة وزمن الاستجابة لـINT8 من Jacob et al.، وتُختتم المحاضرة بالعودة إلى جدول التخزين مقابل الحساب.
4 concepts4 مفاهيم, ، slides 20-26الشرائح 20-26
Why this part mattersلماذا يهمّ هذا الجزء
Everything so far in this lecture was preparation. You have the affine map, the scale and zero point, the quantized matrix product and the decision to quantize weights symmetrically and bias at the accumulator’s scale. This part puts those pieces into one real layer, shows that the layer runs on integer hardware from input to output, and then asks the question that matters on an embedded board: what does it cost in accuracy, and what does it buy in speed?
For the COE 592 midterm this is the part most likely to become a long question. Expect to write the integer-only expression, label the bit width of each operation, draw the dataflow, explain q_bias and interpret the results slide. For your own embedded work, this is the exact recipe that TensorFlow Lite, now LiteRT, uses for its INT8 kernels.
كل ما سبق في هذه المحاضرة كان تمهيدًا. لديك الآن التحويل الأفيني (affine map)، وscale وzero point، وضرب المصفوفات المكمَّم، وقرار تكميم الأوزان تكميمًا متماثلًا وتكميم الانحياز (bias) على مقياس المُراكِم (accumulator). هذا الجزء يجمع هذه القطع في طبقة حقيقية واحدة، ويبيّن أن الطبقة تعمل على عتاد الأعداد الصحيحة من المدخل حتى المخرج، ثم يطرح السؤال الذي يهمّ فعلًا على لوحة مدمجة: كم تكلّف من الدقة، وكم تمنح من السرعة؟
في اختبار منتصف الفصل لمقرر COE 592 هذا هو الجزء الأرجح أن يأتي منه سؤال طويل. توقّع أن تكتب التعبير الصحيح بالأعداد الصحيحة فقط، وتكتب عرض البتات لكل عملية، وترسم مسار البيانات، وتشرح q_bias، وتفسّر شريحة النتائج. وفي عملك الخاص على الأنظمة المدمجة، هذه هي بالضبط الوصفة التي يستخدمها TensorFlow Lite (واسمه الآن LiteRT) في نوى INT8 الخاصة به.
By the end you canفي نهاية هذا الجزء ستستطيع
- Derive the integer-only fully-connected layer q_Y = (S_W S_X / S_Y)(q_W q_X + q_bias) + Z_Y from Y = WX + b.تشتق الطبقة المتصلة كليًا بالأعداد الصحيحة فقط q_Y = (S_W S_X / S_Y)(q_W q_X + q_bias) + Z_Y انطلاقًا من Y = WX + b.
- Explain what q_bias is, why it is 32 bits wide, and why it can be computed before deployment.تشرح ما هو q_bias، ولماذا عرضه 32 بت، ولماذا يمكن حسابه قبل النشر على الجهاز.
- Extend the same expression to a convolution layer and explain what Conv(q_W, Z_X) reduces to.توسّع التعبير نفسه ليشمل طبقة الالتفاف (convolution) وتشرح إلامَ يختزل Conv(q_W, Z_X).
- Draw the integer dataflow and label the bit width of every edge and the cost of every operation.ترسم مسار البيانات (dataflow) بالأعداد الصحيحة وتكتب عرض البتات على كل حافة وتكلفة كل عملية.
- Read the INT8 accuracy table and the MobileNet latency plot, and state what each one does and does not show.تقرأ جدول دقة INT8 ورسم زمن استجابة MobileNet، وتذكر ما يُظهره كل منهما وما لا يُظهره.
Take one output neuron with three inputs. Its float weights are 0.5, -0.3 and 0.2, its inputs are 2.0, 1.0 and 4.0, and its bias is 0.27. In float it computes 1.0 - 0.3 + 0.8 + 0.27 = 1.77. The goal is to get the same answer, to within one output step, without a single floating-point operation at run time.
خذ عصبونًا واحدًا في المخرج له ثلاثة مدخلات. أوزانه العائمة هي 0.5 و-0.3 و0.2، ومدخلاته 2.0 و1.0 و4.0، وانحيازه 0.27. بالفاصلة العائمة يحسب 1.0 - 0.3 + 0.8 + 0.27 = 1.77. الهدف أن نحصل على الجواب نفسه، بفارق لا يتجاوز خطوة مخرج واحدة، دون عملية فاصلة عائمة واحدة وقت التشغيل.
From Y = WX + b to integersمن Y = WX + b إلى الأعداد الصحيحة
Every tensor in the layer is stored with Linear quantization, so each one is replaced by its Affine mapping r = S(q - Z). Three choices from the previous parts make the algebra small. Weights use Symmetric quantization, so Z_W = 0 holds. The bias follows Bias quantization: Z_b = 0 and S_b = S_W S_X, which puts it on exactly the same scale as the products q_W q_X. Activations keep a general Zero point (Z) Z_X, because ReLU outputs are one-sided and suit Asymmetric quantization.
كل موتّر (tensor) في الطبقة مخزَّن بـLinear quantization، لذلك يُستبدل كل واحد منها بـAffine mapping r = S(q - Z). ثلاثة اختيارات من الأجزاء السابقة تجعل الجبر قصيرًا. الأوزان تستخدم Symmetric quantization، فيتحقق Z_W = 0. والانحياز يتبع Bias quantization: Z_b = 0 وS_b = S_W S_X، وهذا يضعه على المقياس نفسه تمامًا الذي عليه حواصل الضرب q_W q_X. أما التنشيطات (activations) فتحتفظ بـZero point (Z) عام Z_X، لأن مخرجات ReLU أحادية الجانب وتناسبها Asymmetric quantization.
This is the Linear quantized fully-connected layer. Read the notation Z_X q_W carefully: it is the weight matrix times a vector whose every entry is Z_X. For output row i it equals , the zero point times that row’s weight sum. Nothing in it depends on the input image.
هذه هي Linear quantized fully-connected layer. اقرأ الترميز Z_X q_W بعناية: إنه مصفوفة الأوزان مضروبة في متجه كل عناصره تساوي Z_X. في صف المخرج i يساوي ، أي نقطة الصفر مضروبة في مجموع أوزان ذلك الصف. لا شيء فيه يعتمد على صورة المدخل.
Why q_bias can be precomputed, and why it is 32 bitsلماذا يمكن حساب q_bias مسبقًا، ولماذا عرضه 32 بت
q_bias contains three things: q_b, the weights and Z_X. All three are fixed once the model is quantized and calibrated, so the subtraction is done once on the laptop, not once per inference on the device. That is precomputation in the strongest sense: the zero-point correction costs zero run-time operations, because it has been folded into a number the layer has to add anyway.
يحتوي q_bias على ثلاثة أشياء: q_b والأوزان وZ_X. الثلاثة كلها ثابتة بمجرد تكميم النموذج ومعايرته، لذلك يُجرى الطرح مرة واحدة على الحاسوب المحمول، لا مرة مع كل استدلال على الجهاز. هذا هو الحساب المسبق بأقوى معانيه: تصحيح نقطة الصفر لا يكلّف أي عملية وقت التشغيل، لأنه دُمج في عدد على الطبقة أن تجمعه في كل الأحوال.
It must be stored in 32 bits for two reasons. First, its scale S_W S_X is tiny, so its integer values are large: in the example below q_b = 540, already far outside [-128, 127]. Second, it is added straight into the 32-bit accumulator, so it must live in the same format. Jacob et al. add a reason that is easy to miss: each bias entry is added to many output activations, so any rounding error in it acts as a systematic offset rather than noise that averages out. Biases are a tiny fraction of the parameters, so the extra width is nearly free.
يجب أن يُخزَّن بـ32 بت لسببين. أولًا، مقياسه S_W S_X صغير جدًا، فتكون قيمه الصحيحة كبيرة: في المثال أدناه q_b = 540، وهذا بعيد جدًا خارج [-128, 127]. ثانيًا، يُجمع مباشرة داخل 32-bit accumulator، فلا بد أن يكون بالصيغة نفسها. ويضيف Jacob et al. سببًا يسهل أن يفوتك: كل عنصر من الانحياز يُضاف إلى عدد كبير من تنشيطات المخرج، فأي خطأ تقريب فيه يعمل كإزاحة منهجية ثابتة، لا كضجيج يتلاشى بالمتوسط. والانحيازات نسبة ضئيلة من المعاملات، فالعرض الإضافي يكاد يكون مجانيًا.
What each operation costsكم تكلّف كل عملية
Slide 21 boxes the three pieces of the expression and labels their cost.
تحيط الشريحة 21 القطع الثلاث من التعبير بمربعات وتكتب تكلفة كل منها.
- Inside the bracket, q_W q_X is a dot product: N-bit integer multiplies whose products are summed in 32 bits, followed by one 32-bit add of q_bias. This is almost all of the work. The label is “N-bit Int Mult., 32-bit Int Add.”داخل القوس، q_W q_X هو ضرب نقطي (dot product): ضربات أعداد صحيحة بعرض N بت تُجمع حواصلها بعرض 32 بت، يليها جمع واحد بعرض 32 بت لـq_bias. هذا هو تقريبًا كل العمل. التسمية هي «N-bit Int Mult., 32-bit Int Add.».
- The factor S_W S_X / S_Y is the only real number left. It is applied once per output as a Requantization (rescale), implemented by Fixed-point multiplication and a shift (M0 and bit shift). The label is “Rescale to N-bit Int.”المعامل S_W S_X / S_Y هو العدد الحقيقي الوحيد المتبقي. يُطبَّق مرة واحدة لكل مخرج على هيئة Requantization (rescale)، ويُنفَّذ بـFixed-point multiplication وإزاحة (M0 and bit shift). التسمية هي «Rescale to N-bit Int.».
- Finally Z_Y is added. The label is “N-bit Int Add.” In practice the result is then clamped to the output range, which is also where a fused ReLU or ReLU6 is applied.أخيرًا يُضاف Z_Y. التسمية هي «N-bit Int Add.». عمليًا تُقصّ (clamp) النتيجة بعد ذلك إلى مدى المخرج، وهذا أيضًا هو الموضع الذي تُطبَّق فيه ReLU أو ReLU6 المدمجة.
Why 32 bits for the sum? An int8 product is at most 128 × 128 = 16,384 = 2^14 in magnitude, so it needs 16 bits with sign. Summing K of them adds about log2 K bits. A signed 32-bit register holds up to about 2^31, so even a worst-case dot product of about 2^17 = 131,072 terms cannot overflow.
لماذا 32 بت للمجموع؟ حاصل ضرب قيمتين int8 لا تتجاوز قيمته المطلقة 128 × 128 = 16,384 = 2^14، فيحتاج 16 بت مع الإشارة. جمع K من هذه الحواصل يضيف نحو log2 K بت. والسجل الموقَّع بعرض 32 بت يتسع لقيم حتى نحو 2^31، لذلك حتى ضرب نقطي في أسوأ الحالات بنحو 2^17 = 131,072 حدًا لا يمكن أن يفيض.
Worked exampleمثال محلول
One neuron, start to finish, in integersعصبون واحد من البداية إلى النهاية بالأعداد الصحيحة
Quantization parametersمعاملات التكميم
Activations: S_X = 0.05, Z_X = -10. Weights (symmetric): S_W = 0.01, Z_W = 0. Output: S_Y = 0.1, Z_Y = -5. Bias: S_b = S_W S_X = 0.0005, Z_b = 0.التنشيطات: S_X = 0.05، Z_X = -10. الأوزان (متماثلة): S_W = 0.01، Z_W = 0. المخرج: S_Y = 0.1، Z_Y = -5. الانحياز: S_b = S_W S_X = 0.0005، Z_b = 0.Codesالرموز الصحيحة
q_W = [50, -30, 20] (so W = [0.5, -0.3, 0.2]). q_X = [30, 10, 70] (so X = 0.05 × [40, 20, 80] = [2.0, 1.0, 4.0]). q_b = 0.27 / 0.0005 = 540.q_W = [50, -30, 20] (إذن W = [0.5, -0.3, 0.2]). q_X = [30, 10, 70] (إذن X = 0.05 × [40, 20, 80] = [2.0, 1.0, 4.0]). q_b = 0.27 / 0.0005 = 540.Offline: q_biasمسبقًا (offline): حساب q_bias
Σ q_W = 50 - 30 + 20 = 40, so Z_X Σ q_W = -10 × 40 = -400 and q_bias = 540 - (-400) = 940. Stored as int32.Σ q_W = 50 - 30 + 20 = 40، إذن Z_X Σ q_W = -10 × 40 = -400 وq_bias = 540 - (-400) = 940. يُخزَّن بصيغة int32.Run time: int8 multiplies, int32 accumulateوقت التشغيل: ضرب int8 ومراكمة int32
q_W · q_X = 1500 - 300 + 1400 = 2600, then 2600 + 940 = 3540. Check: 0.0005 × 3540 = 1.77, exactly the float result.q_W · q_X = 1500 - 300 + 1400 = 2600، ثم 2600 + 940 = 3540. للتحقق: 0.0005 × 3540 = 1.77، وهي نتيجة الفاصلة العائمة بالضبط.Rescaleإعادة التحجيم
M = S_W S_X / S_Y = 0.005 = 2^(-7) × 0.64, so M0 = 0.64 and n = 7. 3540 × 0.64 = 2265.6, and shifting right by 7 bits gives 17.7, which rounds to 18.M = S_W S_X / S_Y = 0.005 = 2^(-7) × 0.64، إذن M0 = 0.64 وn = 7. 3540 × 0.64 = 2265.6، والإزاحة لليمين بـ7 بتات تعطي 17.7، التي تُقرَّب إلى 18.Add the output zero pointجمع نقطة الصفر للمخرج
18 + (-5) = 13, inside [-128, 127], so no clamping.18 + (-5) = 13، وهي داخل [-128, 127]، فلا حاجة إلى القصّ.Resultالنتيجة
q_Y = 13, which decodes to 0.1 × (13 + 5) = 1.8. The float answer was 1.77; the error 0.03 is below half an output step (0.05). Every run-time operation was an integer multiply, add or shift.q_Y = 13، وفكّ ترميزها يعطي 0.1 × (13 + 5) = 1.8. كان جواب الفاصلة العائمة 1.77؛ والخطأ 0.03 أقل من نصف خطوة مخرج (0.05). كل عملية وقت التشغيل كانت ضربًا أو جمعًا أو إزاحة لأعداد صحيحة.
Recall
Starting from Y = WX + b with Z_W = 0, Z_b = 0 and S_b = S_W S_X, write the integer-only expression for q_Y and define q_bias.انطلاقًا من Y = WX + b مع Z_W = 0 و Z_b = 0 و S_b = S_W S_X، اكتب تعبير q_Y بالأعداد الصحيحة فقط وعرّف q_bias.
Quick checkاختبار سريع
Why can q_bias = q_b - Z_X q_W be computed before deployment?لماذا يمكن حساب q_bias = q_b - Z_X q_W قبل النشر؟
Picture one 3 × 3 filter sliding over an image whose activations have zero point Z_X = -10. At every position the integer convolution computes . The -Z_X part of that sum is the same at every position, because the filter is the same and Z_X is the same. That repetition is the whole trick.
تخيّل مرشّحًا واحدًا بحجم 3 × 3 ينزلق فوق صورة تنشيطاتها لها نقطة صفر Z_X = -10. في كل موضع يحسب الالتفاف الصحيح . الجزء -Z_X من هذا المجموع هو نفسه في كل موضع، لأن المرشّح نفسه وZ_X نفسه. هذا التكرار هو الحيلة كلها.
The same expression with Conv in place of a productالتعبير نفسه مع Conv بدل حاصل الضرب
A convolution is linear in its input, exactly like a matrix product, so the fully-connected derivation goes through unchanged. Write Y = Conv(W, X) + b, substitute the affine maps with the same three choices, and use .
الالتفاف خطي في مدخله، تمامًا مثل ضرب المصفوفات، لذلك يصلح اشتقاق الطبقة المتصلة كليًا دون تغيير. اكتب Y = Conv(W, X) + b، وعوّض بالتحويلات الأفينية مع الاختيارات الثلاثة نفسها، واستخدم .
This is the Linear quantized convolution layer. The cost labels are identical to the fully-connected case: the convolution is N-bit multiplies with 32-bit adds, the rescale produces N-bit integers, and Z_Y is an N-bit add. Again both q_b and q_bias are32 bits.
هذه هي Linear quantized convolution layer. تسميات التكلفة مطابقة لحالة الطبقة المتصلة كليًا: الالتفاف ضربات بعرض N بت مع جمع بعرض 32 بت، وإعادة التحجيم تنتج أعدادًا صحيحة بعرض N بت، وZ_Y جمع بعرض N بت. ومرة أخرى كلٌّ من q_b وq_bias بعرض 32 بت.
What Conv(q_W, Z_X) actually isما هو Conv(q_W, Z_X) فعلًا
Conv(q_W, Z_X) means convolving the weights with an input tensor in which every entry equals Z_X. Every window of that tensor looks the same, so for output channel k the result is one number repeated at every position:
Conv(q_W, Z_X) يعني التفاف الأوزان مع موتّر مدخل كل عناصره تساوي Z_X. كل نافذة في هذا الموتّر متطابقة، لذلك تكون النتيجة لقناة المخرج k عددًا واحدًا يتكرر في كل موضع:
With the numbers in the figure, the filter’s weights sum to 5, so the correction is -10 × 5 = -50 and q_bias = q_b + 50 for that channel. One subtraction per output channel, done once, replaces a correction that would otherwise be paid at every pixel of every image.
بأرقام الشكل، مجموع أوزان المرشّح 5، فيكون التصحيح -10 × 5 = -50 وq_bias = q_b + 50 لتلك القناة. طرح واحد لكل قناة مخرج، يُجرى مرة واحدة، يحلّ محل تصحيح كان سيُدفع ثمنه عند كل بكسل من كل صورة.
The dataflow, edge by edgeمسار البيانات حافةً بحافة
Slide 23 draws the layer as a small circuit. Follow one output value from the bottom up: integer inputs and integer weights enter the convolution, which emits an int32 sum; q_bias (int32) is added; the result (int32) is multiplied by the scale factor S_W S_X / S_Y; Z_Y (int) is added; out come the quantized outputs.
ترسم الشريحة 23 الطبقة على هيئة دائرة صغيرة. تتبّع قيمة مخرج واحدة من الأسفل إلى الأعلى: المدخلات الصحيحة والأوزان الصحيحة تدخل الالتفاف، الذي يُخرج مجموعًا بصيغة int32؛ ثم يُضاف q_bias (int32)؛ ثم تُضرب النتيجة (int32) في معامل المقياس S_W S_X / S_Y؛ ثم يُضاف Z_Y (int)؛ فتخرج المخرجات المكمَّمة.
| Operationالعملية | Inputsالمدخلات | Outputالمخرج | Slide labelتسمية الشريحة |
|---|---|---|---|
| Multiply-accumulate (Conv or q_W q_X)ضرب ومراكمة (Conv أو q_W q_X) | int8 × int8int8 × int8 | int32int32 | N-bit Int Mult., 32-bit Int Add.ضرب أعداد صحيحة بعرض N بت، وجمع أعداد صحيحة بعرض 32 بت (N-bit Int Mult., 32-bit Int Add.) |
| Add q_biasجمع q_bias | int32 + int32int32 + int32 | int32int32 | Same box (32-bit Int Add.)المربع نفسه (جمع أعداد صحيحة بعرض 32 بت، 32-bit Int Add.) |
| Multiply by S_W S_X / S_Yالضرب في S_W S_X / S_Y | int32 × fixed-point M0, then shift by nint32 × M0 بالفاصلة الثابتة، ثم إزاحة بمقدار n | N-bit intعدد صحيح بعرض N بت | Rescale to N-bit Intإعادة تحجيم إلى أعداد صحيحة بعرض N بت (Rescale to N-bit Int) |
| Add Z_Y, then clampجمع Z_Y ثم القصّ (clamp) | int + intint + int | int8int8 | N-bit Int Addجمع أعداد صحيحة بعرض N بت (N-bit Int Add) |
The shape to remember is narrow, wide, narrow. Values are stored and moved in 8 bits, which is where the memory and bandwidth savings come from. They are summed in 32 bits so nothing overflows. One rescale per output brings them back to 8 bits for the next layer, which is exactly the input format that layer expects. That is why a whole network can be chained with no float in between: this is Integer-only inference.
الشكل الذي يجب تذكّره هو: ضيّق، عريض، ضيّق. القيم تُخزَّن وتُنقل بعرض 8 بت، ومن هنا يأتي توفير الذاكرة وعرض النطاق. وتُجمع بعرض 32 بت حتى لا يفيض شيء. وإعادة تحجيم واحدة لكل مخرج تعيدها إلى 8 بت للطبقة التالية، وهي بالضبط صيغة المدخل التي تتوقعها تلك الطبقة. لهذا يمكن ربط شبكة كاملة دون أي فاصلة عائمة بين الطبقات: هذا هو Integer-only inference.
Recall
What is Conv(q_W, Z_X), and why can it be folded into q_bias?ما هو Conv(q_W, Z_X)، ولماذا يمكن دمجه في q_bias؟
Recall
Draw the slide 23 dataflow from memory and write the bit width on each edge.ارسم مسار البيانات في الشريحة 23 من الذاكرة واكتب عرض البتات على كل حافة.
Quick checkاختبار سريع
For one output channel of a convolution, what does Conv(q_W, Z_X) reduce to?لقناة مخرج واحدة في الالتفاف، إلامَ يختزل Conv(q_W, Z_X)؟
Quick checkاختبار سريع
Which part of the integer-only layer runs at 32-bit width?أي جزء من الطبقة ذات الأعداد الصحيحة فقط يعمل بعرض 32 بت؟
Suppose a phone app must classify a camera frame in 33 ms to keep up with 30 frames per second. You can pick any MobileNet size you like. The question is not “which format is more accurate?” but “which format gives the best accuracy inside 33 ms?” Slide 24 answers both questions, and they have different answers.
افترض أن تطبيقًا على الهاتف يجب أن يصنّف إطار الكاميرا خلال 33 ms ليواكب 30 إطارًا في الثانية. يمكنك اختيار أي حجم تريده من MobileNet. السؤال ليس «أي صيغة أدق؟» بل «أي صيغة تعطي أفضل دقة ضمن 33 ms؟». الشريحة 24 تجيب عن السؤالين، وجواباهما مختلفان.
The accuracy table: the price on a fixed networkجدول الدقة: الثمن على شبكة ثابتة
The left half of slide 24 takes two large networks, keeps the architecture fixed and compares float with INT8 top-1 accuracy on ImageNet, from Jacob et al. (CVPR 2018).
يأخذ النصف الأيسر من الشريحة 24 شبكتين كبيرتين، ويثبّت البنية، ويقارن دقة top-1 على ImageNet بين float وINT8، نقلًا عن Jacob et al. (CVPR 2018).
- ResNet-50 drops from 76.4% to 74.9%: 1.5 percentage points, about 2% of its accuracy in relative terms.تنخفض ResNet-50 من 76.4% إلى 74.9%: أي 1.5 نقطة مئوية، وهذا نحو 2% من دقتها بالقيمة النسبية.
- Inception-V3 drops from 78.4% to 75.4%: 3.0 points, about 3.8% relative.تنخفض Inception-V3 من 78.4% إلى 75.4%: أي 3.0 نقاط، ونحو 3.8% بالقيمة النسبية.
So on a fixed network, INT8 is slightly less accurate. That is expected: every tensor now lives on a grid of step S, and the rounding errors add up through dozens of layers. Two details make these numbers better than naive rounding would give. The models were trained with simulated quantization, so the weights adapted to the grid. And the Inception-V3 row is the ReLU6 version; in the paper, plain ReLU loses more (78.3% to 74.2%), because a bounded activation range is easier to quantize finely.
إذن على شبكة ثابتة، INT8 أقل دقة بقليل. وهذا متوقع: كل موتّر يعيش الآن على شبكة خطوتها S، وأخطاء التقريب تتراكم عبر عشرات الطبقات. وتفصيلان يجعلان هذه الأرقام أفضل مما يعطيه التقريب الساذج. النماذج دُرّبت مع تكميم محاكى (simulated quantization)، فتكيّفت الأوزان مع الشبكة. وصف Inception-V3 هو نسخة ReLU6؛ ففي الورقة تخسر ReLU العادية أكثر (من 78.3% إلى 74.2%)، لأن مدى التنشيط المحدود أسهل في التكميم الدقيق.
The latency plot: what the price buysرسم زمن الاستجابة: ماذا يشتري هذا الثمن
The right half plots top-1 accuracy against latency for many MobileNets (different widths and input resolutions) on the big cores of a Snapdragon 835, the chip in the Google Pixel 2. Circles are float models; squares are 8-bit integer-only models. Latency is on a log axis with ticks from 5 ms to 120 ms; the slowest float models lie past the last tick.
يرسم النصف الأيمن دقة top-1 مقابل زمن الاستجابة لعدد كبير من شبكات MobileNet (بعروض ودقّات مدخل مختلفة) على الأنوية الكبيرة لمعالج Snapdragon 835، وهو الشريحة الموجودة في Google Pixel 2. الدوائر نماذج float؛ والمربعات نماذج أعداد صحيحة فقط بعرض 8 بت. زمن الاستجابة على محور لوغاريتمي بعلامات من 5 ms إلى 120 ms؛ وأبطأ نماذج float تقع بعد آخر علامة.
The squares sit up and to the left of the circles. Read it in either direction. Draw a vertical line at any latency budget: the best 8-bit model under it is more accurate than the best float model under it, because the integer version of a larger MobileNet fits where only a smaller float one would. Draw a horizontal line at any accuracy target: the 8-bit model reaches it sooner. This is the Latency-accuracy trade-off, and INT8 moves the whole frontier.
المربعات تقع أعلى ويسار الدوائر. اقرأ ذلك في أي من الاتجاهين. ارسم خطًا عموديًا عند أي ميزانية لزمن الاستجابة: أفضل نموذج 8 بت تحته أدق من أفضل نموذج float تحته، لأن النسخة الصحيحة من MobileNet أكبر تتسع حيث لا يتسع إلا نموذج float أصغر. وارسم خطًا أفقيًا عند أي هدف للدقة: نموذج 8 بت يبلغه أسرع. هذه هي Latency-accuracy trade-off، وINT8 تُزيح الحدّ كله.
The paper also stresses that the gain depends on the hardware. It reports a gap of about 10% top-1 at the 33 ms real-time budget on Snapdragon 835 LITTLE cores, and a smaller effect on the Snapdragon 821, whose floating-point path is better optimized. INT8 wins where integer arithmetic is much cheaper than float, which is exactly the situation on microcontrollers and mobile DSPs.
وتؤكد الورقة أيضًا أن المكسب يعتمد على العتاد. فهي تذكر فجوة نحو 10% في دقة top-1 عند ميزانية الزمن الحقيقي 33 ms على الأنوية الصغيرة (LITTLE) في Snapdragon 835، وأثرًا أصغر على Snapdragon 821 الذي مسار الفاصلة العائمة فيه أفضل تحسينًا. تفوز INT8 حيث تكون حسابات الأعداد الصحيحة أرخص بكثير من float، وهذا بالضبط الوضع في المتحكمات الدقيقة ومعالجات DSP في الهواتف.
Recall
Give the float and INT8 accuracies on slide 24 and the drop for each network. Then state in one sentence what the latency plot shows.اذكر دقة float ودقة INT8 في الشريحة 24 ومقدار الانخفاض لكل شبكة. ثم اذكر في جملة واحدة ما يُظهره رسم زمن الاستجابة.
Quick checkاختبار سريع
What does the MobileNet latency-versus-accuracy plot on slide 24 show?ماذا يُظهر رسم زمن الاستجابة مقابل الدقة لشبكات MobileNet في الشريحة 24؟
Go back to the 4 × 4 weight matrix used earlier in this lecture, with values such as 2.09 and -0.98. You have now seen it stored three ways, and slide 25 sets them side by side with one question for each: what is stored, and what is computed?
عُد إلى مصفوفة الأوزان 4 × 4 التي استُخدمت سابقًا في هذه المحاضرة، بقيم مثل 2.09 و-0.98. رأيتها الآن مخزَّنة بثلاث طرق، والشريحة 25 تضعها جنبًا إلى جنب مع سؤال واحد لكل منها: ما الذي يُخزَّن، وما الذي يُحسب؟
| Schemeالمخطط | Storageالتخزين | Computationالحساب |
|---|---|---|
| Original networkالشبكة الأصلية | Floating-point weightsأوزان بالفاصلة العائمة (float) | Floating-point arithmeticحساب بالفاصلة العائمة |
| K-means-based quantizationالتكميم المبني على K-means | Integer indices plus a floating-point codebookفهارس صحيحة مع دفتر رموز (codebook) بالفاصلة العائمة | Floating-point arithmeticحساب بالفاصلة العائمة |
| Linear quantizationالتكميم الخطي | Integer weights (plus a few scales and zero points)أوزان صحيحة (مع عدد قليل من قيم scale و zero point) | Integer arithmeticحساب بالأعداد الصحيحة |
K-means-based quantization stores small integer indices, but each index points into a float Codebook, and the arithmetic is still done in float after looking the value up. It saves memory but not compute. Linear quantization stores integers and, as this part has shown, also computes with integers: the only real-valued constant, S_W S_X / S_Y, is turned into a fixed-point multiply and a shift. That second property is what lets a model run on hardware with no floating-point unit at all.
K-means-based quantization يخزّن فهارس صحيحة صغيرة، لكن كل فهرس يشير إلى Codebook بالفاصلة العائمة، والحساب ما زال يُجرى بالفاصلة العائمة بعد البحث عن القيمة. إنه يوفّر الذاكرة لا الحساب. أما التكميم الخطي فيخزّن أعدادًا صحيحة، وكما بيّن هذا الجزء، يحسب أيضًا بأعداد صحيحة: الثابت الحقيقي الوحيد S_W S_X / S_Y يتحوّل إلى ضرب بالفاصلة الثابتة وإزاحة. هذه الخاصية الثانية هي ما يسمح للنموذج بالعمل على عتاد لا يحتوي وحدة فاصلة عائمة إطلاقًا.
The red arrow and question mark on slide 25 point at the next step: Binary/Ternary quantization, which pushes the Bit width (N) down to one or two bits so that multiplies become sign flips or skips. The same storage-versus-computation question will be the right lens for judging it.
السهم الأحمر وعلامة الاستفهام في الشريحة 25 يشيران إلى الخطوة التالية: Binary/Ternary quantization، الذي يخفض Bit width (N) إلى بت واحد أو بتين بحيث تصبح عمليات الضرب مجرد قلب إشارة أو تخطٍّ. وسؤال التخزين مقابل الحساب نفسه سيكون العدسة الصحيحة للحكم عليه.
Recall
Fill in slide 25: for the original network, K-means quantization and linear quantization, what is stored and what is computed?أكمل الشريحة 25: للشبكة الأصلية، ولتكميم K-means، وللتكميم الخطي، ما الذي يُخزَّن وما الذي يُحسب؟
Recapالخلاصة
If you remember nothing elseإن لم تتذكر شيئاً آخر فتذكّر هذا
- With Z_W = 0, Z_b = 0 and S_b = S_W S_X, the FC layer becomes q_Y = (S_W S_X / S_Y)(q_W q_X + q_bias) + Z_Y.مع Z_W = 0 و Z_b = 0 و S_b = S_W S_X تصبح طبقة FC هي q_Y = (S_W S_X / S_Y)(q_W q_X + q_bias) + Z_Y.
- q_bias = q_b - Z_X q_W depends only on weights, the bias and Z_X, so it is computed once, offline, and stored as int32.q_bias = q_b - Z_X q_W يعتمد فقط على الأوزان والانحياز (bias) و Z_X، لذلك يُحسب مرة واحدة مسبقًا (offline) ويُخزَّن بصيغة int32.
- Cost labels: N-bit integer multiplies with 32-bit adds inside the bracket, one rescale to N-bit integers, one N-bit add of Z_Y.تسميات التكلفة: داخل القوس ضربات أعداد صحيحة بعرض N بت مع جمع بعرض 32 بت، ثم إعادة تحجيم (rescale) واحدة إلى أعداد صحيحة بعرض N بت، ثم جمع واحد بعرض N بت لـ Z_Y.
- Convolution: q_Y = (S_W S_X / S_Y)(Conv(q_W, q_X) + q_bias) + Z_Y with q_bias = q_b - Conv(q_W, Z_X), which is Z_X times each filter's weight sum.الالتفاف: q_Y = (S_W S_X / S_Y)(Conv(q_W, q_X) + q_bias) + Z_Y حيث q_bias = q_b - Conv(q_W, Z_X)، وهذا يساوي Z_X مضروبًا في مجموع أوزان كل مرشّح (filter).
- That per-channel constant is exact at the borders only if padding uses the code Z_X, which is real 0.هذا الثابت الخاص بكل قناة يبقى دقيقًا عند الحواف فقط إذا كانت الحشوة (padding) بالرمز Z_X، الذي يمثّل الصفر الحقيقي.
- Dataflow: int8 inputs and weights, int32 accumulator, int32 bias add, rescale by M = 2^(-n) M0, add Z_Y, saturate to int8.مسار البيانات: مدخلات وأوزان int8، ومُراكِم int32، وجمع الانحياز بصيغة int32، ثم إعادة تحجيم بـ M = 2^(-n) M0، ثم جمع Z_Y، ثم تشبّع (saturate) إلى int8.
- INT8 costs 1.5 points on ResNet-50 (76.4% to 74.9%) and 3.0 points on Inception-V3 (78.4% to 75.4%).تكلّف INT8 نقطة ونصفًا (1.5) على ResNet-50 (من 76.4% إلى 74.9%) وثلاث نقاط (3.0) على Inception-V3 (من 78.4% إلى 75.4%).
- On Snapdragon 835 big cores, INT8 MobileNets sit up and to the left of float ones: a better latency-accuracy frontier, not a more accurate network.على الأنوية الكبيرة في Snapdragon 835 تقع شبكات MobileNet بصيغة INT8 أعلى ويسار شبكات float: أي حدّ أفضل للمقايضة بين زمن الاستجابة والدقة، لا شبكة أدق.
- Linear quantization stores integers and computes with integers; K-means stores integers but computes in float.التكميم الخطي يخزّن أعدادًا صحيحة ويحسب بأعداد صحيحة؛ أما K-means فيخزّن أعدادًا صحيحة لكنه يحسب بالفاصلة العائمة (float).
Sourcesالمصادر
- Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only InferencePaperJacob et al., CVPR 2018 (arXiv)The source of this lecture: int32 bias with S_bias = S1 S2, the M = 2^(-n) M0 rescale, zero padding as the reason for an exact zero, Table 4.1 (ResNet), Table 4.3 (Inception v3) and the Snapdragon 835 MobileNet plots.مصدر هذه المحاضرة: انحياز int32 مع S_bias = S1 S2، وإعادة التحجيم M = 2^(-n) M0، والحشو بالأصفار بوصفه سبب اشتراط صفر دقيق، والجدول 4.1 (ResNet)، والجدول 4.3 (Inception v3)، ورسوم MobileNet على Snapdragon 835.(opens in a new tab)(يفتح في تبويب جديد)
- LiteRT 8-bit quantization specificationDocsGoogle AI EdgeSymmetric int8 weights with zero point 0, int32 bias with scale input_scale × weight_scale, and precomputable zero-point terms.أوزان int8 متماثلة بنقطة صفر 0، وانحياز int32 بمقياس input_scale × weight_scale، وحدود نقطة الصفر القابلة للحساب المسبق.(opens in a new tab)(يفتح في تبويب جديد)
- A White Paper on Neural Network QuantizationPaperNagel et al., Qualcomm AI Research (arXiv 2021)Section 2: 32-bit accumulators and bias, and how the weight-only zero-point terms are precomputed and added to the bias.القسم 2: المُراكِمات والانحياز بعرض 32 بت، وكيف تُحسب مسبقًا حدود نقطة الصفر التي تعتمد على الأوزان فقط وتُضاف إلى الانحياز.(opens in a new tab)(يفتح في تبويب جديد)