انتقل إلى المحتوى الرئيسي

الوحدة 9 — دمج المحوّلات والتصدير

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

هل الدمج ضروري دائمًا؟

الجواب المختصر: لا. يمكن استعمال المحوّل مباشرة عبر مكتبة peft عند الاستدلال:

from peft import PeftModel
from transformers import AutoModelForCausalLM

base = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B")
model = PeftModel.from_pretrained(base, "./meeting-adapter")

هذه الطريقة مرنة: يمكن تبديل المحوّل ديناميكيًّا، وحفظ عشرات المحوّلات (بضعة ميغا لكلّ واحد) على نموذج أساس مشترك في الذاكرة. مثالية لبيئة تُخدَم فيها مهامّ متعدّدة من نموذج واحد.

لكن هذا يُضيف زمن استدلال إضافي لأنّ الحساب يمرّ في المسارين: النموذج الأصلي ومسار LoRA الجانبي. للإنتاج المتطلّب لسرعة قصوى، أو للتوزيع على محرّكات لا تدعم PEFT (llama.cpp مثلًا)، الدمج ضروري.

آلية الدمج

الدمج ينفّذ رياضيًّا:

Wمدموج=Wأصلي+αrBAW_{\text{مدموج}} = W_{\text{أصلي}} + \frac{\alpha}{r} \cdot B \cdot A

النتيجة: مصفوفة واحدة بحجم النموذج الأصلي، بلا آثار للمحوّل. النموذج يصبح غير قابل للتمييز عن أيّ نموذج قياسي.

في مكتبة peft، الدمج بسطر:

from peft import PeftModel

model = PeftModel.from_pretrained(base_model, "./meeting-adapter")
merged = model.merge_and_unload()
merged.save_pretrained("./meeting-model-merged")
tokenizer.save_pretrained("./meeting-model-merged")

merge_and_unload() يحسب الدمج ويُعيد نموذجًا عاديًّا بلا طبقات PEFT إضافية. الحفظ ينتج مجلّدًا كاملًا بنفس بنية النموذج الأصلي.

قيد الدمج مع QLoRA

في QLoRA، النموذج الأصلي مُكمَّم إلى 4 بتّات. الدمج المباشر مع محوّل في BF16 يتطلّب فكّ التكميم أوّلًا:

from transformers import AutoModelForCausalLM

# إعادة تحميل النموذج الأصلي بدون تكميم
base = AutoModelForCausalLM.from_pretrained(
"meta-llama/Meta-Llama-3-8B",
torch_dtype=torch.bfloat16,
device_map="auto",
)
model = PeftModel.from_pretrained(base, "./meeting-adapter")
merged = model.merge_and_unload()

النموذج الناتج بحجمه الأصلي (16 غيغا مثلًا في BF16). للإنتاج، يُعاد تكميمه بأدوات مخصّصة (llama.cpp أو AutoGPTQ) بحسب هدف الاستدلال.

صيغة GGUF: المعيار المحلّي

GGUF (GGML Universal Format) هي الصيغة المستعملة من llama.cpp، و Ollama، وLM Studio، وغيرها. مصمَّمة للاستدلال المحلّي، تدعم أنماط تكميم متنوّعة (Q4_0, Q4_K_M, Q5_K_M, Q8_0)، وتعمل على CPU وGPU معًا.

للتحويل من نموذج مدموج إلى GGUF:

# استنساخ llama.cpp
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
pip install -r requirements.txt

# تحويل النموذج إلى GGUF (FP16)
python convert-hf-to-gguf.py ../meeting-model-merged \
--outfile meeting-model.f16.gguf

# تكميم إلى Q4_K_M (متوازن)
./llama-quantize meeting-model.f16.gguf \
meeting-model.q4_k_m.gguf Q4_K_M

النتيجة: ملفّ واحد بحجم يتراوح بين 4 و5 غيغا (بدل 16 في BF16)، جاهز للاستدلال على أي جهاز يشغّل llama.cpp.

أنماط التكميم في GGUF

اختيار نمط التكميم مقايضة بين الحجم والجودة:

النمطالحجم لنموذج 8Bالجودة
Q8_0~8.5 غيغاشبه مطابق للأصل
Q6_K~6.6 غيغافجوة صغيرة جدًّا
Q5_K_M~5.7 غيغافجوة محدودة، توازن جيّد
Q4_K_M~4.9 غيغاالتوصية الأشيع
Q3_K_S~3.7 غيغاتدهور ملموس

القاعدة العملية: Q4_K_M هو الخيار الافتراضي في 2026 لأنّه يجمع الحجم الصغير مع جودة قريبة جدًّا من الأصل.

النشر على Hugging Face Hub

الخطوة الأخيرة الشائعة هي نشر المحوّل (لا النموذج الكامل، حفاظًا على حقوق ووضوح الأصل) على Hub:

from huggingface_hub import login

login() # يطلب رمز API

model.push_to_hub("your-username/meeting-adapter-llama3-8b")
tokenizer.push_to_hub("your-username/meeting-adapter-llama3-8b")

هذا يُنشئ مستودعًا يمكن للآخرين استعماله بسطر واحد:

model = PeftModel.from_pretrained(base_model, "your-username/meeting-adapter-llama3-8b")

في حالة الشركات، يمكن استعمال مستودع خاصّ (private=True) أو مستضاف داخليًّا عبر text-generation-inference أو Ollama داخلي.

مسألة الرخصة

قبل النشر أو حتّى الاستعمال التجاري، رخصة النموذج الأصلي حاكمة. أمثلة في 2026:

  • Llama 3: رخصة مجّانية للاستعمال حتّى 700 مليون مستخدم شهريًّا، مع شروط توزيع محدّدة.
  • Mistral 7B: Apache 2.0، أوسع حرّية.
  • Qwen 2.5: Apache 2.0 لأغلب الإصدارات.
  • Gemma: رخصة خاصّة بشروط استعمال محدودة.

عند نشر محوّل، صرِّح بوضوح بالنموذج الأصلي واحترم شروطه. توزيع نموذج مدموج قد يعني توزيع الأصلي، وهو ما تخضع رخصته للاختبار.

وثيقة النموذج (Model Card)

على Hub، README.md هو بطاقة النموذج. يجب أن يذكر:

  • النموذج الأصلي والرخصة
  • طبيعة الضبط ومجموعة البيانات
  • طريقة الاستعمال بمثال كود
  • حدود النموذج والاستعمالات غير الموصى بها

هذا معيار أخلاقي وأصبح أيضًا شرطًا قانونيًّا في بعض الولايات (قانون الذكاء الاصطناعي الأوروبي).

دمج ثمّ استعمال في Ollama

بعد تحويل النموذج إلى GGUF، أنشئ Modelfile بسيط:

FROM ./meeting-model.q4_k_m.gguf
TEMPLATE "{{ .System }}\n\n{{ .Prompt }}"

ثمّ: ollama create meetings -f Modelfile && ollama run meetings. النموذج جاهز للاستدلال المحلّي من سطر الأوامر.

حجم القرص عند التصدير

النموذج المدموج بـBF16 (16 غيغا) + نسخة GGUF FP16 (16 غيغا) + عدّة أنماط تكميم (5-8 غيغا لكلّ نمط) تلتهم بسرعة 60 غيغا من القرص. خطّط للمساحة مسبقًا.

الخلاصة

  • الدمج اختياري: للمرونة، احتفظ بمحوّل PEFT جانبي. للسرعة والتوافق، ادمج.
  • merge_and_unload() يُنتج نموذجًا عاديًّا يمكن تحويله لصيغ إنتاج قياسية.
  • GGUF مع تكميم Q4_K_M هو المعيار الفعلي للاستدلال المحلّي عبر llama.cpp وOllama.
  • رخصة النموذج الأصلي حاكمة للنشر التجاري؛ بطاقة نموذج واضحة معيار أخلاقي وقانوني.

في الوحدة الأخيرة: تقييم النموذج قبل الضبط وبعده، والتحقّق من عدم انحدار كفاءاته العامّة.