ضبط النماذج اللغوية الكبيرة بـ LoRA وQLoRA في 2026: دليل عملي شامل

دليل عملي شامل لضبط النماذج اللغوية الكبيرة بتقنيتي LoRA وQLoRA في 2026، مع كود بايثون كامل باستخدام Unsloth. اضبط نموذج 8B بذاكرة 8 جيجابايت وبتكلفة أقل من 10 دولارات.

ضبط LLM بـ LoRA وQLoRA: دليل 2026

صراحةً، كنت أعتقد أن ضبط النماذج اللغوية الكبيرة (Fine-tuning) يستلزم ميزانيةً ضخمةً وفريقًا بحثيًا متكاملًا — حتى جرّبت LoRA للمرة الأولى على Google Colab المجاني، وتغيّر كل شيء. ضبط النماذج اللغوية الكبيرة كان حكرًا على المؤسسات الكبرى التي تمتلك مئات وحدات GPU. في عام 2026، تغيّر المشهد جذريًا — يمكنك الآن تكييف نموذج بحجم 8 مليار معامل على بطاقة رسومية منزلية بسعة 8 جيجابايت، بتكلفة لا تتجاوز 10 دولارات على السحابة. السبب؟ تقنيتان ثوريتان: LoRA (Low-Rank Adaptation) وQLoRA (Quantized LoRA).

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

لماذا تضبط نموذجًا لغويًا كبيرًا؟

قبل أن تبدأ، اسأل نفسك سؤالًا جوهريًا: هل الضبط الدقيق هو الحل الصحيح لمشكلتك؟ هناك أربع طرق لتخصيص النموذج اللغوي:

  1. هندسة الأوامر (Prompt Engineering) — تعديل الـ prompt دون لمس النموذج
  2. أمثلة في السياق (Few-shot) — إضافة أمثلة ضمن الـ prompt مباشرةً
  3. الاسترجاع المعزز بالتوليد (RAG) — ربط النموذج بقاعدة معرفية خارجية
  4. الضبط الدقيق (Fine-tuning) — تدريب إضافي على بياناتك الخاصة

القاعدة العملية: جرّب الثلاثة الأولى أولًا — 80% من حالات "نحتاج ضبطًا دقيقًا" تُحَل بتحسين الاسترجاع أو الـ prompt (ونعم، رأيت هذا بنفسي مرارًا). إذا كنت تبني أنظمة RAG إنتاجية، فقد يكفيك ذلك دون الحاجة إلى الضبط الدقيق الذي يكلّف وقتًا وموارد أكبر.

الضبط الدقيق هو الخيار الأمثل عندما:

  • تحتاج النموذج إلى أسلوب أو لهجة معينة لا يمكن تحقيقها بالـ prompt وحده
  • تريد تحسين الأداء على مجال متخصص جدًا (طب، قانون، كود، لهجة عربية محددة)
  • تريد نموذجًا أصغر وأسرع يُنجز مهمة النموذج الكبير بكفاءة أعلى وتكلفة أقل
  • لديك بيانات حساسة لا يجب إرسالها لخوادم خارجية
  • تريد تقليل تكلفة الاستدلال على المدى الطويل عبر نموذج محلي متخصص

ما هو LoRA؟ التكيف عبر الرتبة المنخفضة

الضبط الكامل (Full Fine-tuning) لنموذج 7 مليار معامل يتطلب تحديث كل المعاملات، مما يستلزم ذاكرة GPU تتجاوز 28 جيجابايت وتكاليف هائلة. LoRA يحل هذه المعضلة بذكاء رياضي أنيق — وأنا شخصيًا أجد هذا الحل أجمل من أن يكون مجرد تقنية عملية:

بدلًا من تحديث المصفوفة الأصلية W بالكامل، يُضيف LoRA مصفوفتين صغيرتين A وB — يُسمّيان "المحولات" (adapters) — ويدرّب فقط هاتين المصفوفتين بينما يبقى النموذج الأصلي مجمّدًا تمامًا:

W_new = W_frozen + ΔW
حيث: ΔW = B × A
أبعاد A: (r × k)، أبعاد B: (d × r)، r << min(d, k)

النتيجة المذهلة: بدلًا من تدريب مليارات المعاملات، تدرّب فقط 0.5% إلى 1% منها. قيمة r (الرتبة) هي المفتاح — تتحكم في حجم المحولات وقدرتها التعبيرية على التكيف.

النموذج المُضبَّط يُخزَّن كملف صغير (50–200 ميجابايت) بدلًا من نسخة كاملة من النموذج (14–140 جيجابايت). يمكن تبادل هذه المحولات وتطبيقها على أي نسخة من النموذج الأساسي. هذا وحده غيّر طريقة مشاركة النماذج في مجتمع المطورين.

ما هو QLoRA؟ ضبط النماذج الضخمة بذاكرة 8 جيجابايت

QLoRA (Quantized LoRA) يأخذ فكرة LoRA خطوة أبعد: يُكمّم النموذج الأساسي المجمّد إلى دقة 4-bit، مما يخفض استهلاك الذاكرة بمقدار 4 أضعاف تقريبًا، بينما تُدرَّب المحولات بدقة bf16 أو fp16 للحفاظ على الجودة.

المكونات التقنية التي تجعل QLoRA ممكنًا:

  • NF4 (Normal Float 4-bit) — صيغة تكميم تحافظ على التوزيع الإحصائي للأوزان بشكل أمثل مقارنة بـ INT4 العادية، مما يُقلل فقدان الدقة
  • Double Quantization — تكميم ثانوي لثوابت التكميم نفسها، يوفر 0.37 بت إضافيًا لكل معامل (تقريبًا 0.5 جيجابايت لنموذج 65B)
  • Paged Optimizers — إدارة ذكية للذاكرة بين GPU وRAM لتجنب أخطاء Out-of-Memory أثناء التدريب

LoRA مقابل QLoRA: دليل الاختيار

فيما يلي مقارنة عملية تساعدك على اختيار الطريقة المناسبة لأجهزتك وأهدافك:

المعيار LoRA (16-bit) QLoRA (4-bit)
الذاكرة لنموذج 7B 16–24 جيجابايت 8–12 جيجابايت
الذاكرة لنموذج 13B 28–40 جيجابايت 14–18 جيجابايت
الذاكرة لنموذج 70B يتطلب multi-GPU 46 جيجابايت (A100 واحد)
جودة النتائج أعلى بفارق طفيف قريبة جدًا (فارق أقل من 1%)
سرعة التدريب أسرع أبطأ بنسبة 10–20%
متى تستخدمه؟ GPU بـ 24+ جيجابايت GPU بـ 8–16 جيجابايت

القاعدة البسيطة: إذا كانت بطاقة GPU لديك بسعة 24 جيجابايت وتضبط نموذج 7B، استخدم LoRA للحصول على أفضل جودة. إذا كنت على RTX 3080/4070 (12 جيجابايت) أو Google Colab T4 (15 جيجابايت)، فـ QLoRA هو خيارك العملي الوحيد — وصدّقني، النتائج أفضل بكثير مما تتوقع.

الخطوة 1: إعداد البيئة مع Unsloth

Unsloth هي المكتبة الأسرع للضبط الدقيق في 2026 — تُقلل استهلاك الذاكرة بنسبة 70% وتضاعف سرعة التدريب مقارنة بـ LoRA العادية عبر Hugging Face PEFT وحدها. تدعم Llama 3.x، Mistral، Qwen 2.5، Phi-3، وGemma 2 خارج الصندوق. إنها الأداة التي أعتمد عليها في كل مشاريعي.

# تثبيت Unsloth والمكتبات المطلوبة
pip install --no-deps bitsandbytes accelerate xformers peft trl unsloth
pip install sentencepiece protobuf datasets huggingface_hub

تحقق من إعداد CUDA قبل البدء:

import torch
print(f"CUDA متاح: {torch.cuda.is_available()}")
print(f"إصدار CUDA: {torch.version.cuda}")
print(f"اسم GPU: {torch.cuda.get_device_name(0)}")
print(f"الذاكرة الكلية: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")

الخطوة 2: تحميل النموذج الأساسي

نستخدم Llama-3.1-8B-Instruct كمثال. تغيير load_in_4bit يُفعّل/يُعطّل وضع QLoRA:

from unsloth import FastLanguageModel
import torch

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="unsloth/Meta-Llama-3.1-8B-Instruct",
    max_seq_length=2048,       # حد طول التسلسل — اضبطه حسب بياناتك
    load_in_4bit=True,         # True = QLoRA | False = LoRA عادي 16-bit
    dtype=None,                # اكتشاف تلقائي: bf16 لـ Ampere فما فوق
)

# مراقبة استهلاك الذاكرة
used_gb = torch.cuda.memory_allocated() / 1e9
total_gb = torch.cuda.get_device_properties(0).total_memory / 1e9
print(f"الذاكرة المستخدمة: {used_gb:.2f} GB / {total_gb:.1f} GB")

الخطوة 3: إضافة محولات LoRA

هنا تُحدد بنية المحولات والـ hyperparameters الرئيسية. هذا هو قلب الأمر كله — خصّص بعض الوقت لفهم كل معامل:

model = FastLanguageModel.get_peft_model(
    model,
    r=16,                        # الرتبة: ابدأ بـ 16، جرّب 32–64 للمهام المعقدة
    target_modules=[
        "q_proj", "k_proj",      # طبقات Query وKey في الانتباه
        "v_proj", "o_proj",      # طبقات Value والإخراج
        "gate_proj", "up_proj", "down_proj"  # طبقات MLP
    ],
    lora_alpha=16,               # معامل التحجيم — عادةً = r كنقطة بداية
    lora_dropout=0,              # 0 يعطي أداءً أفضل مع Unsloth
    use_dora=True,               # DoRA: تحسين 2026 يُحلّل التحديث إلى Magnitude + Direction
    use_gradient_checkpointing="unsloth",  # يوفر 30%+ ذاكرة إضافية
)

model.print_trainable_parameters()
# النتيجة النموذجية:
# trainable params: 41,943,040 || all params: 8,072,204,288 (0.52%)

دليل اختيار قيمة الرتبة (r)

  • r=8 — للمهام البسيطة جدًا: تغيير صيغة الرد أو أسلوب التحية
  • r=16 — نقطة البداية المثالية لمعظم الحالات
  • r=32 — للضبط العام على مجال كامل
  • r=64 — للمهام المعقدة جدًا: الكود متعدد المراحل، الاستدلال المنطقي المعقد

الخطوة 4: تحضير مجموعة البيانات

صيغة JSONL مع مخطط ChatML هي معيار 2026. كل مثال يمثّل محادثة كاملة:

{"messages": [
  {"role": "system", "content": "أنت محامٍ متخصص في القانون التجاري السعودي."},
  {"role": "user", "content": "ما الفرق بين عقد الإيجار والتأجير التمويلي؟"},
  {"role": "assistant", "content": "الفرق الجوهري يكمن في ملكية الأصل..."}
]}
{"messages": [
  {"role": "system", "content": "أنت محامٍ متخصص في القانون التجاري السعودي."},
  {"role": "user", "content": "كيف أُسجّل شركة ذات مسؤولية محدودة في السعودية؟"},
  {"role": "assistant", "content": "لتسجيل شركة ذات مسؤولية محدودة..."}
]}

تحميل البيانات وتجهيزها للتدريب:

from datasets import load_dataset

# تحميل من ملف JSONL محلي
dataset = load_dataset("json", data_files="my_training_data.jsonl", split="train")

# تقسيم 90% تدريب / 10% تحقق
split_data = dataset.train_test_split(test_size=0.1, seed=42)
train_dataset = split_data["train"]
eval_dataset  = split_data["test"]

print(f"بيانات التدريب: {len(train_dataset)} مثال")
print(f"بيانات التحقق:  {len(eval_dataset)} مثال")
print(f"مثال على البيانات: {train_dataset[0]}")

قاعدة ذهبية عن جودة البيانات: 1,000 مثال مُنقَّح يدويًا يتفوق في الغالب على 100,000 مثال مولَّد آليًا بدون تصفية — نتيجة أثبتها بحث LIMA (Less Is More for Alignment) ولا تزال صحيحة في 2026. الجودة تفوق الكمية دائمًا، وهذا درس تعلمته بالطريقة الصعبة.

الخطوة 5: التدريب مع SFTTrainer

حسنًا، لنصل إلى الجزء الفعلي — التدريب نفسه:

from trl import SFTTrainer
from transformers import TrainingArguments
import torch

trainer = SFTTrainer(
    model=model,
    tokenizer=tokenizer,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    dataset_text_field="messages",
    max_seq_length=2048,
    packing=False,           # False أكثر استقرارًا للمحادثات غير المتساوية الطول
    args=TrainingArguments(
        output_dir="./finetuning-outputs",
        # حجم الدفعة والتراكم: الدفعة الفعلية = batch × accumulation = 8
        per_device_train_batch_size=2,
        gradient_accumulation_steps=4,
        # معدل التعلم والجدولة
        learning_rate=2e-4,
        lr_scheduler_type="cosine",
        warmup_steps=50,
        # دقة الحساب (bf16 أفضل على GPU حديثة)
        fp16=not torch.cuda.is_bf16_supported(),
        bf16=torch.cuda.is_bf16_supported(),
        # عدد الـ epochs — 1–3 للأسلوب، 3–5 للمجال المتخصص
        num_train_epochs=3,
        # حفظ وتقييم دوري
        save_strategy="steps",
        save_steps=200,
        evaluation_strategy="steps",
        eval_steps=100,
        load_best_model_at_end=True,
        metric_for_best_model="eval_loss",
        # المحسّن والتنظيم
        optim="adamw_8bit",
        weight_decay=0.01,
        logging_steps=10,
        report_to="none",
    ),
)

# ابدأ التدريب وتتبع التقدم
trainer_stats = trainer.train()
print(f"وقت التدريب: {trainer_stats.metrics['train_runtime'] / 60:.1f} دقيقة")

تقدير وقت التدريب لنموذج 8B مع 5,000 مثال

  • A100 80GB (GPU سحابي): 2–4 ساعات — التكلفة ~5–10 دولارات
  • RTX 4090 24GB (محلي): 6–8 ساعات — الكهرباء فقط
  • RTX 4070 Ti 12GB (QLoRA): 8–12 ساعة
  • Google Colab T4 15GB (QLoRA): 10–16 ساعة — مجاني أو رمزي

الخطوة 6: التقييم وتشخيص الحفظ الآلي

لا تعتمد على خسارة التدريب (train loss) وحدها — انخفاضها قد يعني الحفظ الآلي (overfitting) وليس التعلم الحقيقي. استخدم ثلاثة مستويات من التقييم:

import json

# 1. مراقبة الفجوة بين train_loss وeval_loss
print("تحليل منحنى التعلم:")
for log in trainer.state.log_history:
    if "eval_loss" in log:
        train_l = log.get("loss", "N/A")
        eval_l  = log["eval_loss"]
        step    = log["step"]
        print(f"خطوة {step:4d}: تدريب={train_l:.4f} | تحقق={eval_l:.4f}")
# إذا ارتفع eval_loss بينما انخفض loss → أوقف التدريب فورًا

# 2. اختبار نوعي على أمثلة جديدة
FastLanguageModel.for_inference(model)
test_prompt = tokenizer.apply_chat_template(
    [
        {"role": "system",  "content": "أنت محامٍ متخصص في القانون التجاري السعودي."},
        {"role": "user",    "content": "ما عقوبة الغش التجاري في السعودية؟"}
    ],
    tokenize=False,
    add_generation_prompt=True
)
inputs = tokenizer([test_prompt], return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=300, temperature=0.7, do_sample=True)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

تذكر دائمًا التحقق من أن النموذج لم يفقد قدراته العامة بعد الضبط. يمكنك الاطلاع على مبادئ هندسة السياق لأنظمة الذكاء الاصطناعي لفهم كيفية تصميم بيانات تدريب تحافظ على التوازن بين التخصص والقدرات العامة.

الخطوة 7: التصدير والنشر

الخيار أ: التشغيل المحلي مع Ollama (GGUF)

# دمج المحولات مع النموذج الأساسي
merged_model = model.merge_and_unload()
merged_model.save_pretrained("./my-model-merged")
tokenizer.save_pretrained("./my-model-merged")
# تحويل إلى GGUF (يتطلب llama.cpp)
python llama.cpp/convert.py ./my-model-merged \
    --outtype q4_k_m \
    --outfile my-model-q4km.gguf

# إنشاء Modelfile لـ Ollama
cat > Modelfile << 'EOF'
FROM ./my-model-q4km.gguf
PARAMETER temperature 0.7
PARAMETER top_p 0.9
SYSTEM "أنت مساعد ذكاء اصطناعي متخصص."
EOF

ollama create my-custom-arabic-model -f Modelfile
ollama run my-custom-arabic-model "اختبر نموذجك هنا"

الخيار ب: النشر الإنتاجي مع vLLM

# نشر عدة محولات على نموذج أساسي واحد
# يُقلل تكاليف GPU بشكل كبير في الإنتاج
vllm serve unsloth/Meta-Llama-3.1-8B-Instruct \
    --enable-lora \
    --lora-modules \
        legal-ar=./legal-arabic-adapter \
        medical-ar=./medical-arabic-adapter \
        style-formal=./formal-style-adapter \
    --max-lora-rank 64

هذا النهج يُمكّنك من تشغيل عشرات المحولات المتخصصة على نموذج أساسي واحد في الذاكرة — vLLM يُبدّل بينها تلقائيًا حسب الطلب — مما يوفر تكاليف GPU ضخمة مقارنة بنشر نماذج كاملة منفصلة لكل حالة استخدام.

الخيار ج: رفع المحول إلى Hugging Face Hub

from huggingface_hub import HfApi

# رفع المحول فقط (50–200 MB) — أسرع بكثير من رفع النموذج الكامل
model.push_to_hub("username/my-arabic-lora-adapter", token="hf_...")
tokenizer.push_to_hub("username/my-arabic-lora-adapter", token="hf_...")

أخطاء شائعة وحلولها

1. CUDA Out of Memory (OOM)

نفّذ الحلول بالترتيب حتى يُحَل الخطأ:

  1. اخفض per_device_train_batch_size من 2 إلى 1
  2. زد gradient_accumulation_steps للتعويض (من 4 إلى 8)
  3. تحقق من تفعيل use_gradient_checkpointing="unsloth"
  4. اخفض max_seq_length إلى 512 أو 1024
  5. حوّل إلى QLoRA: load_in_4bit=True

2. النسيان الكارثي (Catastrophic Forgetting)

النموذج يُتقن المجال المتخصص لكنه يفشل في المهام العامة. الحلول: أضف 5–10% من بيانات التعليمات العامة لمجموعة التدريب، اخفض الرتبة (r=8)، وقلّل عدد الـ epochs إلى 1–2.

3. الحفظ الآلي (Overfitting)

eval_loss يرتفع بينما train_loss ينخفض — علامة خطر واضحة. الحلول: استخدم load_best_model_at_end=True، أضف بيانات أكثر تنوعًا وعددًا، وخفّض num_train_epochs.

4. Loss = NaN أو انفجار المتدرجات

غالبًا بسبب معدل تعلم مرتفع جدًا أو بيانات تالفة. الحلول: اخفض lr إلى 1e-4، تحقق من بياناتك بحثًا عن أمثلة فارغة أو بتنسيق خاطئ، وأضف max_grad_norm=0.3 للـ TrainingArguments.

الأسئلة الشائعة

ما الفرق بين LoRA وQLoRA ببساطة؟

LoRA يُضيف محولات صغيرة للنموذج المجمّد ويدرّبها فقط (0.5% من المعاملات). QLoRA يفعل نفس الشيء لكنه يُكمّم النموذج المجمّد إلى 4-bit أيضًا لتوفير الذاكرة. الفارق العملي: QLoRA يحتاج 8–12 جيجابايت بدلًا من 16–24 جيجابايت لنموذج 7B، مع فقدان أقل من 1% في الجودة.

كم عدد الأمثلة التدريبية الكافية للضبط الدقيق؟

200–1,000 مثال مُنقَّح يدويًا تكفي للضبط على مهمة محددة أو أسلوب معين. 5,000–10,000 مثال للضبط على مجال كامل. الجودة تتفوق دائمًا على الكمية — بحث LIMA أثبت أن 1,000 مثال ممتاز يتفوق على 50,000 مثال متوسط.

هل يمكنني ضبط نموذج بدون GPU قوي؟

نعم. Google Colab المجاني يمنحك GPU T4 (15 جيجابايت) يكفي لـ QLoRA على نماذج 7B–8B. للنماذج الأكبر، استخدم RunPod أو Lambda Labs بتكلفة 1–5 دولارات للساعة — جلسة تدريب كاملة لنموذج 8B تكلف 10–30 دولارًا فقط.

هل أحتاج ضبطًا دقيقًا أم RAG لمشروعي؟

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

ما أفضل النماذج الأساسية للضبط الدقيق باللغة العربية في 2026؟

Llama 3.1/3.2 (8B) يدعم العربية بشكل معقول ويعمل مع Unsloth. Qwen 2.5 (7B) ممتاز للكود والمهام متعددة اللغات. AraLLaMA وJais هي نماذج متخصصة للعربية. Phi-3.5 Mini (3.8B) للأجهزة المحدودة. جميعها تعمل مع QLoRA على GPU بـ 8 جيجابايت.

Article changelog (1)
  • — SEO meta refreshed (title and description updated)
Editorial Team
عن الكاتب Editorial Team

Our team of expert writers and editors.