ضغط النماذج2022متوسط10 دقيقة قراءة

GPTQ: تكميم دقيق بعد التدريب للمحوِّلات التوليدية المُدرَّبة مسبقاً

GPTQ: Accurate Post-Training Quantization for Generative Pre-Trained Transformers

Frantar, E. · Ashkboos, S. · Hoefler, T. · Alistarh, D. — ICLR

المشكلة

بحلول نهاية 2022، كانت أكبر النماذج اللغوية — مثل GPT-3 بمعاملاته البالغة 175 مليار وOPT-175B — تستهلك مئات الغيغابايتات لمجرد تخزين أوزانها، وتحتاج عدة بطاقات رسوميات فائقة حتى لتشغيل وحده. تقنيات كانت متوفرة، لكن الدقيقة منها تستلزم إعادة تدريب باهظة الكلفة، أما السريعة التي تعمل بعد التدريب مباشرة — — فكانت تُجدي نفعاً عند 8 بتات فقط وتنهار تماماً عند 4 أو 3 بتات. لم يكن أحد قد نجح في نموذج بـ175 مليار معامل إلى 3–4 بتات دون خسارة كارثية في الأداء.

الإسهام

GPTQ هي طريقة تكميم تُطبَّق دفعةً واحدة بعد التدريب، وتستند إلى تقريب من الرتبة الثانية عبر مصفوفة هسّ. ثلاثة ابتكارات جوهرية جعلتها قابلة للتوسيع إلى أكبر النماذج: أولاً، تكميم جميع صفوف بترتيب أعمدة ثابت بحيث تُحسَب معكوسة هسّ مرة واحدة فقط. ثانياً، التحديثات بالدُّفعات الكسولة التي تُعالج 128 عموداً في كل مرة لاستغلال بطاقة الرسوميات بكفاءة. ثالثاً، استخدام تفكيك تشوليسكي لمعكوسة هسّ لضمان الاستقرار العددي. بهذه الآلية، تُكمّم GPTQ نموذج OPT-175B إلى 3–4 بتات في نحو أربع ساعات على بطاقة واحدة مع ارتفاع شبه معدوم في الحيرة، ما أتاح لأول مرة تشغيل نموذج بـ175 مليار معامل على بطاقة رسوميات واحدة. كما حققت تسريعاً في الاستدلال بمقدار 3.25× على A100 و4.5× على A6000.

الأثر

أثبتت GPTQ أن التكميم العنيف بعد التدريب — وصولاً إلى 3–4 بتات — ممكن فعلاً حتى لأضخم النماذج اللغوية، وبذلك فتحت الباب أمام باحثين ومطوّرين كانت هذه النماذج بعيدة المنال عنهم بسبب تكلفة الأجهزة. سرعان ما أصبحت GPTQ المعيار الفعلي لتكميم الأوزان في منظومة النماذج مفتوحة المصدر، وتقف خلف أدوات واسعة الانتشار مثل AutoGPTQ وتكامل Hugging Face Transformers. أثّر إطارها القائم على هسّ طبقةً بطبقة بصورة مباشرة في طرق لاحقة كـAWQ وSqueezeLLM وQuIP، وباتت أفكارها حول التكميم بترتيب ثابت والتحديثات بالدُّفعات الكسولة تقنيات مرجعية في أدبيات المجال. ومهّدت GPTQ الطريق أيضاً أمام QLoRA التي تجمع بين التكميم بـ4 بتات والضبط الدقيق الكفء بالمعاملات.

تخيّل نحّاتة بارعة أمامها تمثال رخامي يزن عشرة أطنان، وتحتاج إلى إدخاله قاعة عرض مدخلُها أضيق من أن يمرّ منه التمثال. لا تستطيع ببساطة أن تقطع أجزاءً عشوائية منه — سيفقد جماله. الحل أن تُنعّم كل منحنًى بعناية فائقة، وبعد كل قطع تتراجع خطوة وتتفحّص: هل لا يزال التمثال متناسقاً؟ وإذا أخلّ قطعٌ في الذراع اليسرى بالتوازن، عوّضته بتعديل دقيق في الكتف اليمنى.

GPTQ تفعل الشيء نفسه لكن مع الأرقام. كل في يشبه أثر إزميل على التمثال. تُقرّب GPTQ كل وزن إلى قيمة أخشن — أي بتات أقل — لكنها بعد كل تقريب تُعدّل الأوزان المجاورة بحيث يظل مخرج شبه ثابت. أداتها المحورية هي ، وهي بمنزلة خريطة رياضية تُخبرك أيّ الأوزان حسّاسة لا تحتمل العبث، وأيّها مرنة بما يكفي لامتصاص الخطأ نيابةً عن جاراتها.

جدار الذاكرة: لماذا تحتاج النماذج الكبيرة إلى التكميم

يضمّ GPT-3 نحو 175 مليار . حين تُخزَّن هذه المعاملات بصيغة FP16 — أي 16 بتاً لكل عدد — تحتلّ قرابة 326 غيغابايت من الذاكرة، وهذا أكبر مما تتسع له أيّ بطاقة رسوميات منفردة. لتشغيل الاستدلال لا بدّ إذاً من توزيع النموذج على عدة بطاقات باهظة الثمن، وهو ما يضعه خارج متناول معظم الباحثين والمطوّرين.

لكن لاحظ أن العنق الحقيقي هنا ليس سرعة الحساب، بل . أثناء يحتاج كل رمز جديد إلى تحميل النموذج بأكمله من الذاكرة، فسرعة التوليد محكومة بسرعة قراءة الأوزان لا بسرعة ضربها. لو تمكّنت من تخزين كل وزن في 4 بتات بدلاً من 16، لقلّت حاجتك للذاكرة أربع مرات ولتحمّلت الأوزان أسرع بأربع مرات — وهذا يعني تسريعاً مباشراً في التوليد.

من هنا تأتي أهمية التكميم: الفكرة ببساطة هي استبدال الأعداد عالية الدقة (عوامات 16 بت) بأعداد أخشن بكثير (أعداد صحيحة من 3–4 بتات). التحدي الحقيقي هو كيف تفعل ذلك دون أن تُدمّر أداء النموذج.

افتح في المختبر
جرّب تغيير حجم النموذج وعرض البتات لترى كيف يُقلّص التكميم حجم الذاكرة المطلوبة. لاحظ كيف يسمح التكميم بـ4 بتات بتشغيل نموذج 175 مليار معامل على بطاقة رسوميات واحدة.
تستيقظ التجربة عند وصولك…

الفكرة المحورية: كمِّم طبقةً بطبقة وقلِّل خطأ إعادة البناء

بدلاً من محاولة تكميم النموذج بأكمله دفعة واحدة، تتبع GPTQ استراتيجية أبسط وأذكى: تُعالج كل طبقة على حدة. لكل طبقة خطية لدينا مصفوفة أوزان W\mathbf{W} ومجموعة صغيرة من X\mathbf{X} — مجرد 128 عيّنة تكفي. المطلوب هو إيجاد أوزان مُكمَّمة W^\hat{\mathbf{W}} تجعل مخرج الطبقة أقرب ما يمكن من مخرجها الأصلي. صياغة ذلك رياضياً:

argminW^  WXW^X22\text{argmin}_{\hat{\mathbf{W}}} \; \|\mathbf{W}\mathbf{X} - \hat{\mathbf{W}}\mathbf{X}\|_2^2
هدف إعادة البناء طبقةً بطبقةنبحث عن أوزان مُكمَّمة W^\hat{\mathbf{W}} تُصغِّر مربع الفرق بين مخرج الطبقة قبل التكميم وبعده، وذلك بقياس الفرق على بيانات المعايرة X\mathbf{X}. لاحظ أن الهدف ليس تحسين دالة الخسارة النهائية للنموذج بأكمله — بل الحفاظ على سلوك كل طبقة من حيث علاقة المدخل بالمخرج. المنطق بسيط: إذا تغيّرت كل طبقة بمقدار ضئيل فقط، فإن النموذج ككل يتغيّر بمقدار ضئيل.

فكّر في الأمر كسباق تتابع: لو حافظ كل عدّاء على إيقاع يقارب إيقاع الفريق الأصلي، فإن الزمن الكلي يظل شبه ثابت. تباطؤ عدّاء واحد بمقدار طفيف لن يُفسد السباق — لكن لو انهار الجميع معاً لكانت كارثة. هذا هو جوهر النهج طبقةً بطبقة: ضمان أن كل «عدّاء» يحافظ على سرعته.

السلف: التكميم الأمثل للدماغ (OBQ)

بُنيت GPTQ على عمل سابق يُعرف بـ«التكميم الأمثل للدماغ» (OBQ)، وهو بدوره امتداد لإطار الجراح الأمثل للدماغ الكلاسيكي الذي كان يُستخدم في ، لكن OBQ وسّعه ليشمل التكميم. الفكرة الجوهرية: كمِّم الأوزان واحداً تلو الآخر، وبعد كل عملية تكميم عدِّل جميع الأوزان المتبقية — التي ما زالت بدقّتها الكاملة — لتعويض خطأ التقريب الذي حدث. اتجاه هذا التعديل تُرشده معكوسة مصفوفة هسّ H1\mathbf{H}^{-1}.

عملياً، حين تُكمّم الوزن wqw_q الواقع في الموضع qq، يكون خطأ التكميم هو wqquant(wq)w_q - \text{quant}(w_q)، والتعديل الأمثل لبقية الأوزان يأخذ الشكل التالي:

δF=wqquant(wq)[HF1]qq(HF1):,q\boldsymbol{\delta}_F = -\frac{w_q - \text{quant}(w_q)}{[\mathbf{H}_F^{-1}]_{qq}} \cdot (\mathbf{H}_F^{-1})_{:,q}
تحديث أوزان OBQ — توزيع خطأ التكميم عبر مصفوفة هسّيُقسَم خطأ تكميم wqw_q على العنصر القطري المقابل في هسّ — وهو مقياس لأهمية ذلك الوزن — ثم يُوزَّع على طول العمود qq من معكوسة هسّ ليصل إلى كل الأوزان المتبقية. الأوزان الأكثر ترابطاً مع wqw_q وفق ما تصفه هسّ تحصل على تعديلات تعويضية أكبر.

المشكلة أن OBQ تُعالج كل صف من مصفوفة الأوزان W\mathbf{W} باستقلالية تامة، وتختار ترتيباً جشعاً مختلفاً لكل صف. ماذا يعني ذلك عملياً؟ أن معكوسة هسّ يجب أن تُحدَّث من جديد لكل صف في كل طبقة. لمصفوفة بأبعاد drow×dcold_{\text{row}} \times d_{\text{col}} يصبح زمن التنفيذ O(drowdcol3)O(d_{\text{row}} \cdot d_{\text{col}}^3) — أي مكعّب في بُعد الأعمدة. على نموذج بحجم ResNet-50 (25 مليون معامل) يستغرق ذلك نحو ساعة. أما على OPT-175B فسيحتاج سنوات.

ابتكارات GPTQ الثلاثة: من سنوات إلى ساعات

أجرت GPTQ ثلاثة تعديلات على OBQ أدّت مجتمعةً إلى خفض زمن التنفيذ بأكثر من ثلاث مراتب من المقادير (أي أكثر من ألف ضعف) — وهذا كافٍ لتكميم OPT-175B في نحو أربع ساعات على بطاقة رسوميات واحدة.

افتح في المختبر
تتبّع الابتكارات الثلاثة التي جعلت GPTQ سريعة بما يكفي لنماذج بـ175 مليار معامل. فعِّل كل خطوة لتشاهد أثرها على زمن التنفيذ.
تستيقظ التجربة عند وصولك…

الابتكار الأول — ترتيب ثابت للأعمدة. اكتشف الباحثون أنه في الطبقات الكبيرة كثيفة المعاملات، لا يُقدّم الترتيب الجشع الذي يتّبعه OBQ سوى تحسّن هامشي مقارنة بترتيب ثابت عشوائي. والسبب بديهي حين تفكّر فيه: في طبقة تحتوي آلاف الأوزان، قرارات التقريب «السيئة» القليلة الناتجة عن ترتيب غير مثالي تذوب وسط آلاف التعويضات «الجيدة». الفائدة العملية الكبرى هنا هي أنه بتكميم جميع الصفوف بـترتيب أعمدة واحد ثابت، تصبح معكوسة هسّ HF1\mathbf{H}_F^{-1} مشتركة بين كل الصفوف. لم يعد ضرورياً تحديث المعكوسة إلا dcold_{\text{col}} مرة بدلاً من drow×dcold_{\text{row}} \times d_{\text{col}} مرة — أي أنك وفّرت عامل drowd_{\text{row}} بالكامل من زمن التنفيذ.

الابتكار الثاني — التحديثات بالدُّفعات الكسولة. حتى مع الترتيب الثابت تبقى مشكلة: تحديث مصفوفة الأوزان المتبقية بالكامل بعد كل وزن منفرد هو عملية مقيّدة بـعرض حزمة الذاكرة — قراءات وكتابات كثيرة جداً مقابل عمليات حسابية قليلة. الحل أن تُجمّع GPTQ التحديثات في كُتل: تُعالج B=128B = 128 عموداً معاً وتحتفظ بالتحديثات الوسيطة محلياً داخل الكتلة، وعند الانتهاء منها فقط تُطبّق تحديثاً مصفوفياً كبيراً واحداً على بقية الأوزان. بهذا تتحوّل عشرات العمليات الصغيرة المقيّدة بالذاكرة إلى عمليات ضرب مصفوفي كبيرة — وهي بالضبط نوع العمليات التي تتفوّق فيها بطاقات الرسوميات.

الابتكار الثالث — معكوسة هسّ عبر . في OBQ يُحذف من معكوسة هسّ صف وعمود بعد كل خطوة باستخدام الحذف الغاوسي، وهذا يُراكم أخطاءً عددية مع تقدّم العملية. GPTQ تحلّ المشكلة بحساب تفكيك تشوليسكي لـH1\mathbf{H}^{-1} مرة واحدة مسبقاً، ثم تقرأ عناصر المعكوسة المطلوبة صفاً بصف من التفكيك مباشرة. النتيجة أسرع وأكثر استقراراً عددياً، مع إضافة حدّ تخميد صغير λI\lambda \mathbf{I} للتعامل مع الحالات التي تكون فيها هسّ شبه منفردة.

الخوارزمية: عموداً بعمود، كتلةً بكتلة

فيما يلي الإجراء الكامل لخوارزمية GPTQ على طبقة واحدة. المدخل هو مصفوفة الأوزان W\mathbf{W} إلى جانب مصفوفة هسّ H=2XX\mathbf{H} = 2\mathbf{X}\mathbf{X}^\top المحسوبة من بيانات المعايرة، والمخرج هو المصفوفة المُكمَّمة W^\hat{\mathbf{W}}.

خوارزمية GPTQ — شبه شيفرة مبسّطةpython

مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.

# المدخل: W (مصفوفة الأوزان)، H (هسّ)، B (حجم الكتلة = 128) # المخرج: Q (مصفوفة الأوزان المُكمَّمة)
H_inv = cholesky(inverse(H + λI))   # الخطوة 3: معكوسة مستقرة Q = copy(W)
for block_start in range(0, num_cols, B):
    block = columns[block_start : block_start + B]
    error_accumulator = zeros(num_rows, B)

    for j in block:                   # حلقة داخل الكتلة
        q_j = quantize(Q[:, j])       # قرّب إلى أقرب نقطة على الشبكة
        error = Q[:, j] - q_j         # خطأ التكميم
        Q[:, j] = q_j                 # ثبِّت العمود المُكمَّم

        # عوِّض: عدِّل أعمدة الكتلة المتبقية
        # باستخدام معكوسة هسّ (رؤية الخطوة 1: مشتركة لكل الصفوف)
        Q[:, j+1:block_end] -= (error / H_inv[j,j]) * H_inv[j, j+1:block_end]

        error_accumulator[:, j - block_start] = error / H_inv[j,j]

    # الخطوة 2: تحديث بالدُّفعة الكسولة — عملية ضرب مصفوفي كبيرة واحدة
    Q[:, block_end:] -= error_accumulator @ H_inv[block, block_end:]
افتح في المختبر
شاهد GPTQ وهي تُكمّم مصفوفة الأوزان عموداً بعمود. لاحظ كيف يُعوَّض كل خطأ تقريب بتعديل الأوزان المتبقية، وكيف تُوجّه مصفوفة هسّ مسار تدفّق الخطأ.
تستيقظ التجربة عند وصولك…

النتائج: أوزان بـ4 بتات بدقة شبه خالية من الفاقد

النتيجة الأبرز: تُكمّم GPTQ نموذجي OPT-175B وBLOOM-176B إلى 4 بتات مع ارتفاع في لا يتجاوز 0.05 نقطة على مجموعة WikiText-2. قارن ذلك بطريقة التقريب لأقرب قيمة (RTN) التي ترفع الحيرة عادةً بمقدار 1–2 نقطة أو أكثر. والأهم أنه عند 3 بتات — وهو مستوى ضغط شديد — لا تزال GPTQ تُنتج نماذج صالحة للاستخدام، بينما ينهار RTN تماماً وتنفجر الحيرة بمراتب من المقادير.

النقطة المحورية هنا أن الفجوة بين GPTQ وRTN تتّسع كلما كبر النموذج. على النماذج الصغيرة (125 مليون معامل) يبقى RTN منافساً بشكل مقبول. لكن حين تنتقل إلى OPT-175B، يُعطي RTN عند 4 بتات حيرة تبلغ 10.54 في مقابل 8.37 لـGPTQ (بينما خط الأساس بصيغة FP16 هو 8.34). بعبارة أخرى: كلما كبر النموذج ازدادت أهمية GPTQ — وهذا بالتحديد النطاق الذي نحتاج فيه إلى ضغط النماذج أكثر من أي نطاق آخر.

افتح في المختبر
قارن بين GPTQ وRTN وخط الأساس FP16 عبر أحجام نماذج مختلفة. لاحظ كيف تبقى GPTQ قريبة من خط الأساس بينما يبتعد RTN بوضوح مع النماذج الأكبر وعروض البتات الأدنى.
تستيقظ التجربة عند وصولك…

الأثر العملي: 175 مليار معامل على بطاقة رسوميات واحدة

الفائدة لا تقتصر على الحفاظ على الدقة — بل تمتد إلى تسريع حقيقي في الاستدلال. طوّر الباحثون نوى مخصصة تُجري أثناء الضرب المصفوفي مباشرة دون الحاجة لتحويل مسبق. ولأن التوليد التراجعي مقيّد بـعرض حزمة الذاكرة وليس بالقدرة الحسابية، فإن قراءة ربع عدد البايتات لكل وزن تتحوّل مباشرة إلى توليد أسرع.

النتائج الملموسة: تسريع بنحو 3.25 ضعف على بطاقة NVIDIA A100 و4.5 ضعف على NVIDIA A6000 في الاستدلال التوليدي الشامل. والأهم من ذلك أن نموذج OPT-175B بـ4 بتات يسع بالكامل في 80 غيغابايت من بطاقة A100 واحدة — وهذه أول مرة يعمل فيها نموذج بـ175 مليار معامل على بطاقة رسوميات واحدة في مهام التوليد.

القيود والأسئلة المفتوحة

من المهم أن ندرك حدود GPTQ. أولاً، هي تُكمّم الأوزان فقط — أما التنشيطات فتبقى بصيغة FP16. في معظم سيناريوهات التوليد هذا مقبول تماماً لأن العنق هو تحميل الأوزان لا حساب التنشيطات. لكن حين تنتقل إلى الاستدلال بالدُّفعات مع عشرات الطلبات المتزامنة، يصبح تكميم التنشيطات ضرورياً أيضاً، وGPTQ لا تتناول هذا الجانب.

ثانياً، الطريقة لا تُسرّع عمليات الضرب ذاتها لأن العتاد الحالي يفتقر إلى دعم أصلي لعمليات الدقة المختلطة من نوع FP16 × INT4. التسريع بأكمله مصدره تقليل حركة البيانات من الذاكرة وإليها. وأخيراً، عند الدفع نحو التكميم بـ2 بت أو التكميم الثلاثي، تبدأ الدقة بالتراجع بشكل ملحوظ — GPTQ تدفع الحدود بعيداً لكنها لا تُلغي المفاضلة الجوهرية بين الدقة والضغط.

الإرث: منظومة التكميم

  1. 1989

    إتلاف الدماغ الأمثل (لوكون وآخرون)

    أول من استخدم معلومات الرتبة الثانية (هسّ) لتقرير أيّ الأوزان يمكن حذفها من الشبكة العصبية. التقريب القطري لهسّ حوّل قرارات التقليم من عشوائية إلى منهجية مبنية على أساس رياضي.

  2. 1993

    الجراح الأمثل للدماغ (حسيبي وستورك)

    وسّع العمل السابق باستخدام معكوسة هسّ الكاملة (وليس القطرية فحسب) عند إزالة الأوزان، ما أتاح للأوزان المتبقية تعويض أثر الإزالة. يُعدّ السلف المباشر لآلية تعويض الخطأ التي تعتمدها GPTQ.

  3. 2022

    LLM.int8() (ديتمرز وآخرون)

    كشف أن التكميم بـ8 بتات للنماذج الكبيرة يستلزم معالجة خاصة للقيم الشاذة في التنشيطات. قدّم تفكيكاً بدقة مختلطة يُبقي الأبعاد ذات القيم الشاذة بصيغة FP16 ويُكمّم الباقي.

  4. 2022

    OBQ / الضغط الأمثل للدماغ (فرانتار وأليستار)

    عمّم إطار الجراح الأمثل للدماغ ليشمل التكميم بعد التدريب. حقق أعلى دقة في حينه، لكن زمن تنفيذه المكعّب حصر استخدامه في نماذج لا تتجاوز 100 مليون معامل.

  5. 2022

    GPTQ (هذه الورقة)

    جعلت التكميم المبني على هسّ عملياً لنماذج بـ175 مليار معامل. الترتيب الثابت للأعمدة والتجميع الكسول وتفكيك تشوليسكي خفّضت الزمن ألف ضعف. أول من شغّل OPT-175B على بطاقة رسوميات واحدة.

  6. 2023

    QLoRA (ديتمرز وآخرون)

    جمعت بين التكميم بـ4 بتات على طريقة GPTQ والتكيّف منخفض الرتبة للضبط الدقيق. أتاحت ضبط نموذج بـ65 مليار معامل دقيقاً على بطاقة واحدة بـ48 غيغابايت، عبر إبقاء النموذج الأساسي مُكمَّماً بـ4 بتات وتدريب محوّلات منخفضة الرتبة فقط بدقة أعلى.

  7. 2023

    AWQ وSqueezeLLM وQuIP

    طرق لاحقة انطلقت من إطار GPTQ. تحمي AWQ الأوزان البارزة عبر تحجيم واعٍ بالتنشيطات. وتتعامل SqueezeLLM مع القيم الشاذة بتخزين مُتناثر. ويُضيف QuIP معالجة لعدم التماسك تُحسّن حدود الخطأ.

المرجعFrantar, Ashkboos, Hoefler, Alistarh. GPTQ: Accurate Post-Training Quantization for Generative Pre-Trained Transformers. ICLR, 2023.

مصطلحات هذه الورقة