مسار K-quant الحالي في Ember يقرأ التمثيل بشكل صحيح، لكنه يتخلص من فائدته وقت التشغيل. أوزان Q6_K وQ4_K_M تتحول من ملف GGUF إلى f32 وتبقى في الذاكرة، ثم تمر عبر generic f32 kernels. ما فيه حالياً native K-quant matmul أو packed execution path لها. يعني هذا reference loader، مو low-memory K-quant deployment.
وهذا يخلي المسار الحالي غير مناسب كـdeployment منخفض الذاكرة أو منخفض التأخير. الصفحة تثبت هذا الـbaseline قبل تنفيذ مسار native K-quant. النتيجة مو ادعاء أن Q4_K_M أو Q6_K غير فعالة بطبيعتها؛ هي ناتجة عن سياسة الـloader والـbackend الحالية في Ember، وما ينفع نعممها على GGUF أو K-quants أو low-bit quantization عموماً.
pre-optimization engineering baseline فقط. الجدول يغطي عائلتين صغيرتين على جهاز محلي واحد. هذه مو نتيجة جديدة في quantization، ولا ادعاء production deployment، ولا مقارنة تقول إن Ember أسرع من llama.cpp.
هل quantized checkpoint الأصغر ينتج بالضرورة deployment محلياً أصغر وأسرع؟
الـbenchmark المجمّد يقيس حجم الملف، ووقت التحميل مع prefill، وسرعة decode، وpeak RSS. العمود الأخير هو المفتاح: يسجل ما يحتفظ به Ember في الذاكرة ويشغله، مو فقط ما يقوله اسم الملف.
| النموذج | quantization | حجم الملف | load + prefill | decode tok/s | peak RSS | تمثيل runtime |
|---|---|---|---|---|---|---|
| Qwen2.5-1.5B-Instruct | Q8_0 | 1807 MB | 0.97 s | 40.6 | 1941 MB | compressed-resident |
| Qwen2.5-1.5B-Instruct | Q6_K | 1396 MB | 14.4 s | 2.5 | 8713 MB | persistent f32 expansion |
| Qwen2.5-1.5B-Instruct | Q4_K_M | 1066 MB | 13.0 s | 2.6 | 8712 MB | persistent f32 expansion |
| Llama-3.2-1B | Q8_0 | 1260 MB | 2.03 s | 149.6 | 2685 MB | compressed-resident |
| Llama-3.2-1B | Q6_K | 974 MB | 16.4 s | 2.9 | 6965 MB | persistent f32 expansion |
| Llama-3.2-1B | Q4_K_M | 770 MB | 15.9 s | 3.2 | 6965 MB | persistent f32 expansion |
في Qwen، ملف Q4_K_M أصغر من Q8_0 على القرص بنحو 41%، لكنه يستهلك تقريباً 4.49× من peak RSS ويكون decode أبطأ بنحو 15.6×. وفي Llama، يصغر الملف بنحو 39%، بينما ترتفع الذاكرة إلى 2.59× وتصبح السرعة أبطأ بنحو 46.8×.
عبر مقارنات Q4/Q6 الأربع، يصبح decode أبطأ بين 15.6× و51.6×، وترتفع peak RSS بين 2.59× و4.49×. الحد الأعلى 51.6× هو Llama Q6_K، والأدنى 15.6× هو Qwen Q4_K_M.
الصورة نفسها تتكرر في العائلتين: الشيء الوحيد الذي يصغر مع Q6/Q4 هو الملف على القرص. ووقت التحميل يرتفع أيضاً من نحو ثانية أو ثانيتين في Q8_0 إلى نحو 13–16 ثانية في Q6_K وQ4_K_M.
quantization في الـcheckpoint تصف طريقة ترميز الـtensors داخل الملف. ما تصف تلقائياً كيف يخزنها الـruntime أو أي kernels يشغلها. مسار Q8_0 في Ember يبقي الـblocks مكمّمة في الذاكرة ويستخدم مسار packed Q8.
مسار K-quant الحالي هو reference loader، مو native K-quant backend. الـloader يفك التكميم إلى f32 وقت التحميل، ويحتفظ بالـbuffers الموسعة، ثم يرسل العمل إلى تنفيذ f32 عام. ما فيه K-specific matmul أو packed kernel حالياً في Ember. الملف ما زال Q4 أو Q6 على القرص، لكن تمثيل الـdeployment داخل الذاكرة ليس كذلك.
Q8_0:
GGUF Q8 blocks
→ compressed-resident weights
→ packed Q8 kernels
Q4_K_M / Q6_K today (reference path):
GGUF K-quant blocks
→ full f32 expansion
→ generic f32 execution
إذا بقي compressed file mapping موجوداً في الذاكرة، فقد يعكس RSS التمثيل الأصلي والـbuffers الموسعة معاً. لذلك رقم RSS الواحد يحتاج تفكيكاً إلى file-backed وanonymous قبل ما نعامله كتفسير كامل للإقامة في الذاكرة.
لاحقة GGUF أو اسم الملف ما تحدد وحدها ذاكرة العملية، تكلفة البداية، سرعة decode، الـworkspace المؤقت، سلوك الـkernels، أو مدة بقاء الـsource mapping. هذه قرارات يحددها الـloader وتخطيط الـtensors وسياسة الـdispatch والـbackend.
الـquantized checkpoint مجرد storage format إلى أن يحدد الـruntime كيف يجهزه ويشغله.
هذا هو الحد المفاهيمي في المراجعة. قول إن الملف Q4 صحيح. لكنه ما يكفي لوصف الـdeployment كله.
llama.cpp هو الـexternal correctness and performance reference هنا. الـCPU backend المحسّن فيه يحافظ على أوزان K-quant مضغوطة في المسارات العادية، ويستخدم native quantized vector-dot kernels لـQ4_K وQ6_K وQ8_0، بدل الاحتفاظ بنسخة f32 كاملة من النموذج في التنفيذ العادي.
هذا هو الفرق المهم للمقارنة: الـreference يحافظ على تمثيل low-bit أثناء التشغيل، بينما مسار K-quant البحثي الحالي في Ember يحافظ على التخزين المكمّم ثم يحوله إلى أوزان f32.
استخدم الـbenchmark نفس CPU affinity وإعداد الـthreads بين التهيئات. هذا يحسن المقارنة داخل الجدول، لكنه ما يحول التشغيل إلى دراسة واسعة للأجهزة.
المهمة التالية في Ember هي مقارنة التوسيع الكامل المبكر إلى f32، وبديل بذاكرة محدودة، وتنفيذ K-quant أصلي يحتفظ بالتمثيل المضغوط، مع llama.cpp كـexternal baseline.
المسارات المحسّنة لازم تحافظ أيضاً على دلالات activation tracing وcapture وpatching في Ember. الذاكرة الأقل أو السرعة الأعلى ما تكفي إذا تغيّر الشيء الذي تقيسه أداة البحث أو تتدخل فيه.
مخرجات الـdeployment benchmark المجمدة والـrunner
موجودة محلياً في
research/pilots/arabic_quantization_001/deployment_benchmark.{json,csv}
على فرع pilot-001 المحلي. هذا الفرع مو مساراً عاماً،
لذلك ما أضيف رابطاً يوحي بعكس ذلك.
سياق التنفيذ العام موجود في
src/quant_k.rs،
src/loader.rs،
src/residency.rs،
ومذكرتي packed-Q8
packed-q8-research-memo.md
وpacked-q8-lifecycle.md.
الملف قال Q4. الـruntime اختار f32. وتكلفة الـdeployment تبعت تمثيل الـruntime.