الدرس 22 من 24

التقييم والنشر

المشاكل الشائعة وإصلاحها

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

الضبط الدقيق لا يسير دائماً بسلاسة. دعنا نشخص ونصلح المشاكل الأكثر شيوعاً.

مشاكل الخسارة

الخسارة تنفجر (NaN أو Inf)

الأعراض: الخسارة تصبح NaN أو لانهاية مبكراً في التدريب

الأسباب والإصلاحات:

# المشكلة: معدل التعلم عالي جداً
# الإصلاح: قلل معدل التعلم
learning_rate = 5e-6  # ابدأ منخفضاً، زد إذا لزم

# المشكلة: فيضان التدرجات
# الإصلاح: فعّل قص التدرجات
max_grad_norm = 1.0

# المشكلة: مشاكل الدقة المختلطة
# الإصلاح: استخدم bf16 بدل fp16
bf16 = True  # أكثر استقراراً من fp16
fp16 = False

# المشكلة: بيانات سيئة (نصوص فارغة، أحرف خاصة)
# الإصلاح: تحقق من مجموعة البيانات
def validate_example(example):
    if not example.get("text") or len(example["text"]) < 10:
        return False
    if "NaN" in example["text"] or "\x00" in example["text"]:
        return False
    return True

dataset = dataset.filter(validate_example)

الخسارة لا تتناقص

الأعراض: الخسارة تبقى ثابتة أو تتأرجح

الإصلاحات:

# المشكلة: معدل التعلم منخفض جداً
learning_rate = 2e-4  # جرب الزيادة

# المشكلة: رتبة LoRA منخفضة جداً
r = 32  # زد من 8 أو 16

# المشكلة: وحدات مستهدفة غير كافية
target_modules = [
    "q_proj", "k_proj", "v_proj", "o_proj",
    "gate_proj", "up_proj", "down_proj"
]  # ضمّن جميع الطبقات الخطية

# المشكلة: مجموعة البيانات صغيرة جداً أو متجانسة
# الإصلاح: أضف أمثلة أكثر تنوعاً

الخسارة تتناقص ثم تزيد

الأعراض: نمط الإفراط في التدريب الكلاسيكي

الإصلاحات:

# الحل 1: التوقف المبكر
from transformers import EarlyStoppingCallback

trainer = SFTTrainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    callbacks=[EarlyStoppingCallback(early_stopping_patience=3)]
)

# الحل 2: تنظيم أكثر
lora_dropout = 0.1  # أضف dropout
weight_decay = 0.01  # أضف تناقص الأوزان

# الحل 3: قلل epochs
num_train_epochs = 1  # غالباً 1-2 يكفي

# الحل 4: بيانات تدريب أكثر
# زد حجم مجموعة البيانات أو استخدم تعزيز البيانات

مشاكل الذاكرة

نفاد الذاكرة (OOM)

الأعراض: خطأ CUDA out of memory

إصلاحات سريعة:

# قلل حجم الدفعة
per_device_train_batch_size = 1  # ابدأ بـ 1

# زد تراكم التدرجات للحفاظ على حجم الدفعة الفعال
gradient_accumulation_steps = 8  # الدفعة الفعالة = 1 * 8 = 8

# قلل طول التسلسل
max_seq_length = 512  # تسلسلات أقصر تستخدم ذاكرة أقل

# فعّل نقاط فحص التدرجات
use_gradient_checkpointing = "unsloth"  # يستبدل الحساب بالذاكرة

# استخدم التكميم 4-bit
load_in_4bit = True

# امسح ذاكرة CUDA قبل التدريب
import torch
torch.cuda.empty_cache()

الذاكرة تنمو أثناء التدريب

الأعراض: استخدام الذاكرة يزيد كل خطوة

# الإصلاح: عطّل التخزين المؤقت أثناء التدريب
model.config.use_cache = False

# الإصلاح: امسح التدرجات بشكل صحيح (عادة يُدار بواسطة المدرّب)
optimizer.zero_grad(set_to_none=True)

# الإصلاح: تحقق من تسربات الذاكرة في callbacks
# تجنب تخزين tensors في قوائم

مشاكل جودة المخرجات

مخرجات متكررة

الأعراض: النموذج يكرر عبارات أو جمل

# أثناء الاستنتاج، اضبط معاملات التوليد
outputs = model.generate(
    **inputs,
    max_new_tokens=200,
    repetition_penalty=1.2,  # عاقب التكرار
    no_repeat_ngram_size=3,  # لا تكرر 3-grams
    temperature=0.7,  # أضف عشوائية
    top_p=0.9,  # أخذ العينات النووي
)

# أثناء التدريب، تحقق من بيانات التدريب المتكررة
from collections import Counter

def check_repetition(dataset):
    texts = [ex["text"] for ex in dataset]
    duplicates = [t for t, count in Counter(texts).items() if count > 1]
    print(f"وُجد {len(duplicates)} أمثلة مكررة")
    return duplicates

النسيان الكارثي

الأعراض: النموذج يفقد القدرات العامة

# الإصلاح 1: قلل معدل التعلم
learning_rate = 1e-6  # محافظ جداً

# الإصلاح 2: زد LoRA alpha نسبة للرتبة
r = 16
lora_alpha = 32  # 2x الرتبة

# الإصلاح 3: اخلط بيانات عامة
from datasets import concatenate_datasets

# أضف بعض بيانات التعليمات العامة
general_dataset = load_dataset("yahma/alpaca-cleaned", split="train[:1000]")
combined = concatenate_datasets([domain_dataset, general_dataset])
combined = combined.shuffle(seed=42)

# الإصلاح 4: استخدم beta أعلى في DPO (ابق أقرب للمرجع)
beta = 0.5  # أعلى = انحراف أقل

صيغة/أسلوب خاطئ

الأعراض: النموذج لا يتبع الصيغة المتوقعة

# الإصلاح: تأكد أن بيانات التدريب تطابق الصيغة المتوقعة بالضبط
def format_example(example):
    # استخدم قالب المحادثة الذي يتوقعه نموذجك بالضبط
    messages = [
        {"role": "system", "content": "أنت مساعد مفيد."},
        {"role": "user", "content": example["instruction"]},
        {"role": "assistant", "content": example["output"]}
    ]
    return {"text": tokenizer.apply_chat_template(messages, tokenize=False)}

# تحقق أن الصيغة صحيحة
sample = dataset[0]
print(format_example(sample)["text"])

عدم استقرار التدريب

مشاكل التدرجات

# راقب التدرجات
def log_gradients(model):
    total_norm = 0
    for p in model.parameters():
        if p.grad is not None:
            param_norm = p.grad.data.norm(2)
            total_norm += param_norm.item() ** 2
    total_norm = total_norm ** 0.5
    print(f"معيار التدرج: {total_norm}")

# إذا كانت التدرجات كبيرة جداً
max_grad_norm = 0.5  # اقص بقوة أكبر

# إذا كانت التدرجات صغيرة جداً (تتلاشى)
learning_rate = 5e-5  # زد معدل التعلم

تدريب DPO غير مستقر

# مشاكل خاصة بـ DPO
dpo_config = DPOConfig(
    # ابدأ بـ beta محافظ
    beta=0.1,

    # معدل تعلم أقل من SFT
    learning_rate=5e-7,

    # تأكد أن النموذج المرجعي مجمد
    # (يُدار تلقائياً بواسطة DPOTrainer)

    # راقب هوامش المكافأة
    logging_steps=10,
)

# إذا أصبحت الهوامش سالبة، تحقق من جودة البيانات
# المختار يجب أن يكون أفضل بوضوح من المرفوض

قائمة فحص التصحيح

عندما يفشل التدريب:

  1. تحقق من البيانات أولاً

    • لا أمثلة فارغة
    • صيغة صحيحة
    • أطوال معقولة
    • لا أحرف خاصة تسبب مشاكل
  2. تحقق من التكوين

    • معدل التعلم مناسب للمهمة
    • حجم الدفعة يناسب الذاكرة
    • وحدات مستهدفة صحيحة للنموذج
  3. راقب المقاييس

    • الخسارة تتجه للأسفل
    • لا قيم NaN
    • استخدام الذاكرة مستقر
  4. اختبر تدريجياً

    • درّب على 100 مثال أولاً
    • تحقق من المخرجات قبل التدريب الكامل
    • احفظ نقاط الفحص بشكل متكرر

نصيحة: عند التصحيح، قلل كل شيء للحد الأدنى (1 epoch، 100 مثال، حجم دفعة 1) وتحقق أن خط الأنابيب يعمل قبل التوسع.

بعد ذلك، لنتعلم كيفية نشر نموذجك المضبوط على Ollama. :::

اختبار

الوحدة 6: التقييم والنشر

خذ الاختبار