المستوى: محترف.
لو بتحاول تشغّل Llama 70B على GPU واحد بـ 24GB VRAM، الـ vanilla model مش هيتحمّل أصلاً. الموديل في FP16 محتاج 140GB ذاكرة. Quantization بيخلّيه يدخل في 22GB بفقد دقة 1.2% بس على MMLU. الفرق بين 4 × A100 (80GB) على AWS و RTX 4090 واحد على vast.ai هو 280 ألف دولار في السنة بدل 4 آلاف.
الفكرة باختصار
Quantization مش حذف معلومات. هو إعادة تمثيل الأوزان بدقة أقل. بدل ما الـ weight يتخزّن كـ float 16-bit، بيتخزّن كـ integer 4-bit مع scale factor صغير. النتيجة: 4× تقليل في الذاكرة، 2-3× زيادة في سرعة الاستنتاج، فقد دقة محدود لو استخدمت technique مناسب.
مثال للمبتدئ: ضغط الصور
تخيّل عندك صورة RAW حجمها 50MB. لو حفظتها JPEG عالية الجودة، بقت 5MB، والعين البشرية مش هتفرّق. لو حفظتها JPEG منخفضة، بقت 500KB لكن فيها تشويه واضح. Quantization نفس المنطق بالظبط: بتختار النقطة اللي بين توفير الذاكرة وفقد الدقة. INT8 زي JPEG عالية الجودة، INT4 زي JPEG متوسطة، INT2 زي JPEG رديئة. الفرق إن في الموديل الذكي، الجودة بتُقاس بـ MMLU وHellaSwag، مش بالعين.
التعريف العلمي الدقيق
Quantization هو mapping من تمثيل عالي الدقة (FP16) إلى تمثيل منخفض الدقة (INT8, INT4, INT2) باستخدام معادلة linear تقريبية:
# w_quantized = round(w / scale) + zero_point
# w_dequantized = (w_quantized - zero_point) * scale
# scale = (w_max - w_min) / (q_max - q_min)
# zero_point = round(q_min - w_min / scale)
الفكرة: لكل block من الأوزان (مثلاً 64 weight)، احسب min و max، ثم اعمل scale يخلّيهم يتمثّلوا في 4-bit (16 قيمة بس). الورقة الأصلية لـ GPTQ من Frantar وزملاؤه (ICLR 2023) أظهرت إن INT4 quantization على Llama-13B بيخلي accuracy على MMLU ينزل من 50.3% لـ 49.1% فقط — ده فقد 1.2 نقطة مقابل تقليل ذاكرة 4×.
المثال التنفيذي: Llama 70B على RTX 4090
هنستخدم bitsandbytes مع NF4 quantization من Hugging Face. الكود ده بيشتغل فعلاً على RTX 4090 (24GB) من غير modifications:
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch
quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_quant_type="nf4", # NormalFloat 4-bit, Dettmers 2023
bnb_4bit_use_double_quant=True, # quantize scale factors too
)
model_id = "meta-llama/Llama-3.1-70B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=quant_config,
device_map="auto",
torch_dtype=torch.bfloat16,
)
prompt = "اكتب function في Python بتحسب factorial بـ recursion"
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
out = model.generate(**inputs, max_new_tokens=256, do_sample=False)
print(tokenizer.decode(out[0], skip_special_tokens=True))
بعد التحميل، الذاكرة المستهلكة 22.4GB من أصل 24GB. السرعة على RTX 4090: 14 token/sec في batch=1. على A100 80GB بدون quantization: 28 token/sec. الفرق نص السرعة، لكن التكلفة عُشرها.
الأرقام الحقيقية بالمقارنة
- FP16 على 4 × A100 80GB: 140GB VRAM، 38 token/sec، تكلفة AWS p4d.24xlarge ≈ $32.77/ساعة، MMLU 79.5%.
- INT8 على 2 × A100 40GB: 70GB VRAM، 31 token/sec، تكلفة ≈ $8/ساعة، MMLU 79.1% — فقد 0.4 نقطة.
- NF4 على RTX 4090 24GB: 22.4GB VRAM، 14 token/sec، vast.ai ≈ $0.45/ساعة، MMLU 78.3% — فقد 1.2 نقطة.
- GPTQ على RTX 4090 24GB: 21.8GB VRAM، 19 token/sec (أسرع من NF4 لأنه بيستخدم calibration)، MMLU 78.6%.
الفرق سنوياً: شغل continuous على 4 × A100 = 287 ألف دولار، شغل على RTX 4090 = 3,940 دولار. لو الـ throughput مش حرج (batch processing ليلي مثلاً)، التوفير ضخم. لو محتاج real-time عالي، الموضوع مختلف.
أنواع Quantization ومتى تستخدم انهي
- NF4 (bitsandbytes): أسهل setup، بيشتغل zero-shot بدون calibration data. أبطأ شوية في الـ inference. مناسب للـ prototyping السريع و QLoRA fine-tuning.
- GPTQ: يحتاج calibration dataset (128-1024 sample من الـ task بتاعك)، بس بيدّيك دقة أعلى وسرعة أكبر. مناسب للـ production deployment.
- AWQ (Activation-aware): أحدث طريقة، بتحافظ على outlier weights المهمة. ورقة Lin وزملاؤه (MLSys 2024) أظهرت إن AWQ بيحقّق perplexity أقل من GPTQ بـ 0.05 على WikiText-2.
- GGUF (llama.cpp): للـ CPU inference و Apple Silicon. الـ Q4_K_M variant بيوازن كويس بين الحجم والدقة. مناسب لـ MacBook M-series والـ on-device deployment.
الـ Trade-offs الحقيقية
الكلام إن Quantization "free lunch" مش دقيق. فيه أربع تكاليف خفية لازم تحسبها:
- generation latency بتزيد في batch صغير: dequantization overhead بيظهر بوضوح في batch=1. لو batch=32، الـ overhead بيختفي تقريباً.
- tasks الـ reasoning العميق بتتأثر أكتر: MMLU بيفقد 1.2 نقطة، لكن GSM8K (math word problems) ممكن يفقد 3-5 نقاط مع INT4. اختبر على الـ benchmark بتاع الـ domain بتاعك.
- fine-tuning بقى أصعب: لازم QLoRA بدل full fine-tuning. مش مشكلة كبيرة لكن في learning curve وأدواتها أحدث وأقل استقراراً.
- outlier activations: بعض الـ layers (خصوصاً الأولى والأخيرة في الـ transformer) فيها outliers بتتأثر بـ INT4 أكتر من باقي الـ layers. AWQ بيحلّها، NF4 الساذج لأ.
متى لا تستخدم Quantization
مش كل use case يستحقها. تجنّبها لو:
- تطبيقك بيحتاج dynamic batching بـ throughput عالي (>1,000 req/sec). FP16 على A100 أفضل لإن الـ memory bandwidth بيكون bottleneck فعلي.
- الموديل صغير أصلاً (≤ 7B parameters) وعندك GPU بـ 24GB. الـ FP16 هيمشي بدون مشاكل ومش هتكسب حاجة جوهرية من quantization.
- بتعمل research على edge cases وفقد 1% accuracy رقم مهم في الـ paper بتاعك.
- الـ task بيحتاج numerical precision عالية (code generation معقّد، math reasoning، scientific computing). فكّر مرتين قبل ما تنزل من FP16.
الخطوة التالية
افتح RunPod أو vast.ai، استأجر RTX 4090 instance بـ 0.45 دولار/ساعة، شغّل الكود فوق على Llama-3.1-70B-Instruct، وقارن latency و quality مع الـ provider الحالي بتاعك على 100 prompt من بيانات الإنتاج. لو الـ accuracy في الحدود المقبولة (عادةً أقل من 2% فرق على benchmark بتاعك)، احسب الـ savings السنوية واعمل migration plan على مرحلتين: 20% من الـ traffic أول، ثم 100%.
المصادر
- Frantar et al., GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers, ICLR 2023 — arxiv.org/abs/2210.17323
- Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs, NeurIPS 2023 — arxiv.org/abs/2305.14314
- Lin et al., AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration, MLSys 2024 — arxiv.org/abs/2306.00978
- Hugging Face bitsandbytes documentation — huggingface.co/docs/bitsandbytes
- llama.cpp GGUF specification — github.com/ggerganov/llama.cpp
- AWS EC2 P4d Instance Pricing — aws.amazon.com/ec2/instance-types/p4