استخدام LoRA و QLoRA لتخفيف استهلاك كرت الشاشة أثناء تدريب النماذج

دقائق القراءة: 5

استخدام LoRA و QLoRA لتخفيف استهلاك كرت الشاشة أثناء تدريب النماذج

عند الوصول إلى مرحلة الضبط الدقيق للنماذج اللغوية الكبيرة، تظهر المشكلة الهندسية الأهم: استهلاك ذاكرة كرت الشاشة VRAM. فالتدريب الكامل Full Fine-Tuning يعني تحديث جميع أوزان النموذج، وهذا يرفع تكلفة الذاكرة بسبب تحميل المعاملات الأصلية، وتخزين التدرجات Gradients، وحالات المحسن Optimizer States. هنا ظهرت تقنيات مثل LoRA ونسختها الأكثر كفاءة QLoRA لتجعل تدريب النماذج الكبيرة ممكناً حتى على بطاقات متوسطة.

إذا كنت قد قرأت سابقاً مقال تجهيز مجموعة بيانات (Dataset) لتدريب نموذج مخصص لخدمة عملاء شركتك، فهذه المرحلة هي الامتداد العملي المباشر: كيف نستخدم البيانات مع أقل ضغط ممكن على العتاد.

ما المشكلة الفعلية في استهلاك الذاكرة أثناء التدريب؟

في أي نموذج Transformer، كل طبقة تحتوي مصفوفات أوزان ضخمة داخل وحدات مثل Attention و Feed Forward. عند التدريب الكامل، لا يكفي تخزين الأوزان فقط، بل يجب أيضاً حفظ:

  • نسخة الأوزان المستخدمة في المرور الأمامي Forward Pass.
  • التدرجات لكل وزن أثناء Backward Pass.
  • حالات المحسن مثل المتوسطات المتحركة في AdamW.
  • الـ Activations الوسيطة اللازمة لحساب الاشتقاقات.

لهذا قد يتطلب نموذج بحجم 7 مليار معلمة عشرات الجيجابايت من VRAM إذا تم تدريبه تقليدياً. هندسياً، هذا غير مناسب لمعظم المطورين، خصوصاً عند بناء حلول محلية مرتبطة بـ النماذج مفتوحة المصدر أو عند تشغيل النماذج مع Llama 3 أو Mistral محلياً.

ما هي فكرة LoRA هندسياً؟

LoRA اختصار Low-Rank Adaptation. الفكرة الأساسية ليست تحديث المصفوفة الضخمة الأصلية W مباشرة، بل تجميدها بالكامل، ثم إضافة تصحيح صغير قابل للتدريب يمثل فرق التخصيص المطلوب.

بدلاً من تعلم تحديث كامل ΔW بحجم ضخم، يتم تقريب هذا التحديث إلى حاصل ضرب مصفوفتين صغيرتين منخفضتي الرتبة:

ΔW = A × B

حيث تكون قيمة rank r صغيرة مثل 8 أو 16 أو 32. هذا يعني أننا لا ندرّب إلا عدداً قليلاً جداً من المعاملات مقارنة بالنموذج الكامل.

كيف يمر تدفق البيانات داخل الطبقة؟

في الوضع التقليدي، الطبقة تحسب:

y = W x

مع LoRA تصبح:

y = W x + (A × B) x

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

ما الذي يضيفه QLoRA فوق LoRA؟

QLoRA يذهب خطوة أبعد: لا يكتفي بتجميد الأوزان الأساسية، بل يقوم أيضاً بتحميل النموذج نفسه بشكل مكمم Quantized عادة بدقة 4-bit عبر مكتبة bitsandbytes. ثم يضيف طبقات LoRA القابلة للتدريب فوق هذا الأساس المضغوط.

معمارياً، التسلسل يكون كالتالي:

  • تحميل الأوزان الأساسية بصيغة مكممة لتقليل استهلاك الذاكرة.
  • إبقاء هذه الأوزان مجمدة.
  • حقن وحدات LoRA في طبقات مستهدفة مثل q_proj و v_proj.
  • تدريب هذه الإضافات الصغيرة فقط.

لهذا أصبح بالإمكان ضبط نماذج كانت تتطلب سابقاً عتاداً احترافياً باستخدام بطاقات مثل 16GB أو 24GB في كثير من الحالات.

متى أستخدم LoRA ومتى أستخدم QLoRA؟

  • استخدم LoRA إذا كانت لديك ذاكرة جيدة وتريد بساطة أعلى في التدريب.
  • استخدم QLoRA إذا كان هدفك الأقصى هو تقليل VRAM مع الاحتفاظ بأداء قوي.
  • في مشاريع الشركات الصغيرة أو المختبرات الفردية، غالباً يكون QLoRA الخيار العملي الأول.

خطوات تنفيذ QLoRA باستخدام transformers و peft

قبل التنفيذ، من المفيد مراجعة مقال إعداد بيئة العمل الذكية لأن نجاح التدريب يعتمد على توافق الإصدارات والمكتبات.

1) تثبيت المكتبات

pip install transformers datasets peft accelerate bitsandbytes trl

2) تحميل النموذج مع التكميم

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

model_name = "mistralai/Mistral-7B-v0.1"

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True,
    bnb_4bit_compute_dtype="bfloat16"
)

tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=bnb_config,
    device_map="auto"
)

3) حقن إعدادات LoRA

from peft import LoraConfig, get_peft_model

lora_config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

4) مثال تهيئة بيانات التدريب

from datasets import Dataset

data = {
    "text": [
        "السؤال: ما هي سياسة الإرجاع؟\nالإجابة: يمكن الإرجاع خلال 14 يوماً مع الفاتورة.",
        "السؤال: هل يوجد شحن دولي؟\nالإجابة: نعم، الشحن الدولي متاح لعدد محدد من الدول."
    ]
}

dataset = Dataset.from_dict(data)

5) صياغة نمط التعليمات

أنت مساعد متخصص في الردود المؤسسية. أجب بدقة وبأسلوب مهني مختصر، واعتمد فقط على نبرة خدمة العملاء المحددة داخل بيانات التدريب.

هذا النوع من التعليمات يرتبط بما شرحناه سابقاً في هندسة الأوامر داخل الكود، لكن هنا يتم ترسيخ السلوك عبر التدريب نفسه لا عبر البرومبت فقط.

6) إعداد التدريب

from transformers import TrainingArguments, Trainer

training_args = TrainingArguments(
    output_dir="./qlora-output",
    per_device_train_batch_size=2,
    gradient_accumulation_steps=8,
    num_train_epochs=3,
    learning_rate=2e-4,
    fp16=True,
    logging_steps=10,
    save_strategy="epoch",
    optim="paged_adamw_8bit"
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=dataset
)

trainer.train()

كيف نقلل الذاكرة أكثر أثناء التدريب؟

  • تقليل batch size مع استخدام gradient_accumulation_steps.
  • استهداف طبقات أقل داخل LoRA لتقليل المعاملات القابلة للتدريب.
  • استخدام sequence length مناسب، لأن طول السياق يرفع الذاكرة بشكل مباشر.
  • تفعيل gradient checkpointing إذا دعمه النموذج.

هل LoRA بديل عن RAG؟

ليس دائماً. إذا كانت المشكلة هي حقن معرفة متغيرة باستمرار، فغالباً يكون دمج المعلومات المسترجعة مع الـ LLM أفضل من تدريب النموذج على كل تحديث. أما إذا كنت تريد تعديل الأسلوب، النبرة، شكل الإجابة، أو تكييف النموذج مع تعليمات متكررة في مجال ضيق، فـ LoRA و QLoRA أكثر منطقية.

أخطاء شائعة يجب تجنبها

  • الاعتقاد أن QLoRA يلغي الحاجة إلى بيانات نظيفة؛ الحقيقة أن جودة Dataset ما زالت العامل الحاسم.
  • اختيار قيمة rank كبيرة جداً دون داعٍ، ما يرفع الذاكرة ويزيد خطر overfitting.
  • تدريب النموذج على نصوص غير متجانسة في الأسلوب أو المهمة.
  • عدم اختبار النموذج بعد التدريب باستخدام عينات تقييم منفصلة.

الخلاصة الهندسية

LoRA يقلل تكلفة الضبط الدقيق عبر تجميد الأوزان الأساسية وتدريب تحديثات منخفضة الرتبة فقط. أما QLoRA فيضيف فوق ذلك تكميم النموذج إلى 4-bit، ما يجعل تدريب نماذج كبيرة ممكناً على عتاد أقل بكثير. لهذه الأسباب أصبحت هاتان التقنيتان من أهم أدوات مهندس LLM الحديث، خصوصاً عند بناء أنظمة مخصصة أو نماذج محلية مرتبطة بتطبيقات LangChain، أو خطوط الذكاء الاصطناعي المحلية الخاصة، أو حلول هجينة تجمع بين التخصيص وEmbeddings وVector Databases.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *