الدرس 10 من 24

LoRA و QLoRA عملياً

تكوين LoRA

3 دقيقة للقراءة

فهم معاملات LoRA حاسم للضبط الدقيق الناجح. دعنا نستكشف كل معامل وتأثيره.

معاملات LoRA الأساسية

كائن LoraConfig

from peft import LoraConfig, TaskType

config = LoraConfig(
    r=16,                           # الرتبة
    lora_alpha=32,                  # قياس ألفا
    target_modules="all-linear",    # أي الطبقات
    lora_dropout=0.05,              # التسرب
    bias="none",                    # تدريب الانحياز
    task_type=TaskType.CAUSAL_LM    # نوع المهمة
)

الرتبة (r)

الرتبة تحدد حجم مصفوفات LoRA وتؤثر مباشرة على السعة.

الوزن الأصلي: W ∈ R^(d×k)
LoRA يضيف: A ∈ R^(d×r), B ∈ R^(r×k)
المخرج: W' = W + (A × B)

المعاملات القابلة للتدريب = 2 × r × (d + k)

دليل اختيار الرتبة

الرتبة المعاملات الذاكرة حالة الاستخدام
4 قليلة جداً الحد الأدنى تغييرات أسلوب بسيطة
8 قليلة منخفضة مهام أساسية
16 متوسطة متوسطة الخيار الافتراضي
32 كثيرة أعلى مهام معقدة
64+ كثيرة جداً عالية أقصى سعة
# رتبة منخفضة لمهام بسيطة
simple_config = LoraConfig(r=8, ...)

# رتبة أعلى لمعرفة مجال معقدة
complex_config = LoraConfig(r=32, ...)

ألفا (lora_alpha)

ألفا هو معامل قياس يتحكم في مقدار تأثير تحديث LoRA على المخرج.

القياس = alpha / r
المخرج = W + (alpha/r) × (A × B)

الأنماط الشائعة

# النمط 1: ألفا = الرتبة (قياس = 1)
config = LoraConfig(r=16, lora_alpha=16)

# النمط 2: ألفا = 2×الرتبة (قياس = 2)
config = LoraConfig(r=16, lora_alpha=32)

# النمط 3: ألفا ثابت (عدّل مع الرتبة)
config = LoraConfig(r=32, lora_alpha=16)  # قياس = 0.5

قاعدة عامة: ابدأ بـ alpha = rank (قياس = 1)، ثم عدّل بناءً على استقرار التدريب.

الوحدات المستهدفة

أي الطبقات نضيف لها محولات LoRA. هذا يؤثر بشكل كبير على السعة والذاكرة.

الخيارات الشائعة

# كل الطبقات الخطية (موصى لـ 2025)
config = LoraConfig(target_modules="all-linear")

# الانتباه فقط (النهج التقليدي)
config = LoraConfig(target_modules=["q_proj", "k_proj", "v_proj", "o_proj"])

# الانتباه + MLP
config = LoraConfig(target_modules=[
    "q_proj", "k_proj", "v_proj", "o_proj",
    "gate_proj", "up_proj", "down_proj"
])

إيجاد الوحدات المستهدفة

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-3B-Instruct")

# اطبع كل أسماء الطبقات الخطية
for name, module in model.named_modules():
    if isinstance(module, torch.nn.Linear):
        print(name)

المخرج لـ Llama:

model.embed_tokens
model.layers.0.self_attn.q_proj
model.layers.0.self_attn.k_proj
model.layers.0.self_attn.v_proj
model.layers.0.self_attn.o_proj
model.layers.0.mlp.gate_proj
model.layers.0.mlp.up_proj
model.layers.0.mlp.down_proj
...

التسرب

التنظيم لمنع الإفراط في التعلم.

# لا تسرب (لمجموعات البيانات الكبيرة)
config = LoraConfig(lora_dropout=0.0)

# تسرب خفيف (لمجموعات البيانات الأصغر)
config = LoraConfig(lora_dropout=0.05)

# تسرب أعلى (لمجموعات بيانات صغيرة جداً أو إفراط في التعلم)
config = LoraConfig(lora_dropout=0.1)

تدريب الانحياز

هل ندرّب حدود الانحياز مع LoRA.

# لا شيء (افتراضي، موصى)
config = LoraConfig(bias="none")

# كل الانحيازات
config = LoraConfig(bias="all")

# انحيازات LoRA فقط
config = LoraConfig(bias="lora_only")

التوصية: احتفظ بـ bias="none" ما لم يكن لديك سبب محدد لتدريب الانحيازات.

أمثلة تكوين كاملة

للأغراض العامة (الافتراضي الموصى)

from peft import LoraConfig

config = LoraConfig(
    r=16,
    lora_alpha=16,
    target_modules="all-linear",
    lora_dropout=0.0,
    bias="none",
    task_type="CAUSAL_LM"
)

الذاكرة المحدودة

config = LoraConfig(
    r=8,
    lora_alpha=16,
    target_modules=["q_proj", "v_proj"],  # وحدات أقل
    lora_dropout=0.0,
    bias="none",
    task_type="CAUSAL_LM"
)

أقصى سعة

config = LoraConfig(
    r=64,
    lora_alpha=128,
    target_modules="all-linear",
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

تطبيق LoRA على نموذج

from transformers import AutoModelForCausalLM
from peft import get_peft_model, LoraConfig

# حمّل النموذج الأساسي
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-3B-Instruct")

# أنشئ تكوين LoRA
config = LoraConfig(
    r=16,
    lora_alpha=16,
    target_modules="all-linear",
    lora_dropout=0.0,
    bias="none",
    task_type="CAUSAL_LM"
)

# طبّق LoRA
model = get_peft_model(model, config)

# تحقق من المعاملات القابلة للتدريب
model.print_trainable_parameters()
# المخرج: trainable params: 41,943,040 || all params: 3,255,044,096 || trainable%: 1.29%

نصائح الضبط

المشكلة الحل
نقص التعلم زد الرتبة، أضف المزيد من الوحدات المستهدفة
الإفراط في التعلم قلل الرتبة، أضف تسرب
مشاكل ذاكرة قلل الرتبة، وحدات مستهدفة أقل
تدريب بطيء رتبة أقل، استخدم QLoRA

بعد ذلك، سنضيف تكميم 4-bit مع QLoRA لتقليل متطلبات الذاكرة بشكل كبير. :::

اختبار

الوحدة 3: LoRA و QLoRA عملياً

خذ الاختبار