LoRA و QLoRA عملياً
أول ضبط دقيق لك
3 دقيقة للقراءة
دعنا نجمع كل شيء معاً ونشغّل مهمة ضبط دقيق كاملة باستخدام SFTTrainer من مكتبة TRL.
سكريبت التدريب الكامل
import torch
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
BitsAndBytesConfig,
TrainingArguments
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from trl import SFTTrainer
from datasets import load_dataset
# ============================================
# 1. التكوين
# ============================================
model_name = "meta-llama/Llama-3.2-3B-Instruct"
output_dir = "./outputs/my-first-finetune"
max_seq_length = 2048
# ============================================
# 2. تحميل وإعداد مجموعة البيانات
# ============================================
dataset = load_dataset("tatsu-lab/alpaca", split="train")
# اختياري: خذ مجموعة فرعية للاختبار
dataset = dataset.select(range(1000))
def format_instruction(example):
"""نسّق مجموعة البيانات لصيغة التعليمات."""
if example.get("input", ""):
text = f"""### التعليمة:
{example['instruction']}
### المدخل:
{example['input']}
### الاستجابة:
{example['output']}"""
else:
text = f"""### التعليمة:
{example['instruction']}
### الاستجابة:
{example['output']}"""
return {"text": text}
dataset = dataset.map(format_instruction)
# قسّم إلى تدريب/تحقق
dataset = dataset.train_test_split(test_size=0.1)
train_dataset = dataset["train"]
eval_dataset = dataset["test"]
print(f"حجم التدريب: {len(train_dataset)}")
print(f"حجم التقييم: {len(eval_dataset)}")
# ============================================
# 3. تحميل النموذج مع QLoRA
# ============================================
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True
)
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True
)
model = prepare_model_for_kbit_training(model)
# ============================================
# 4. تكوين LoRA
# ============================================
lora_config = LoraConfig(
r=16,
lora_alpha=16,
target_modules="all-linear",
lora_dropout=0.0,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# ============================================
# 5. تحميل المُرمّز
# ============================================
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"
# ============================================
# 6. معاملات التدريب
# ============================================
training_args = TrainingArguments(
output_dir=output_dir,
num_train_epochs=3,
per_device_train_batch_size=4,
per_device_eval_batch_size=4,
gradient_accumulation_steps=4,
gradient_checkpointing=True,
learning_rate=2e-4,
weight_decay=0.01,
warmup_ratio=0.03,
lr_scheduler_type="cosine",
logging_steps=10,
save_steps=100,
eval_strategy="steps",
eval_steps=100,
save_total_limit=3,
bf16=True,
max_grad_norm=0.3,
group_by_length=True,
report_to="none", # أو "wandb" لتتبع التجارب
)
# ============================================
# 7. تهيئة المدرّب
# ============================================
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
processing_class=tokenizer,
max_seq_length=max_seq_length,
dataset_text_field="text",
packing=False,
)
# ============================================
# 8. درّب!
# ============================================
print("بدء التدريب...")
trainer.train()
# ============================================
# 9. احفظ النموذج
# ============================================
trainer.save_model(f"{output_dir}/final")
tokenizer.save_pretrained(f"{output_dir}/final")
print(f"اكتمل التدريب! النموذج حُفظ في {output_dir}/final")
فهم معاملات التدريب
حجم الدفعة والتراكم
# حجم الدفعة الفعال = per_device * devices * accumulation
# مثال: 4 * 1 * 4 = 16 حجم دفعة فعال
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
جدولة معدل التعلم
learning_rate=2e-4, # معدل التعلم الذروة
warmup_ratio=0.03, # 3% من الخطوات للإحماء
lr_scheduler_type="cosine", # تناقص جيب تمام بعد الإحماء
تحسين الذاكرة
gradient_checkpointing=True, # استبدل الحساب بالذاكرة
bf16=True, # استخدم دقة BFloat16
max_grad_norm=0.3, # قص التدرج
اختبار نموذجك المضبوط
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# حمّل النموذج الأساسي والمحول
base_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-3B-Instruct",
torch_dtype=torch.bfloat16,
device_map="auto"
)
model = PeftModel.from_pretrained(
base_model,
"./outputs/my-first-finetune/final"
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-3B-Instruct")
# اختبر التوليد
prompt = """### التعليمة:
اكتب قصيدة قصيرة عن التعلم الآلي.
### الاستجابة:
"""
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(
**inputs,
max_new_tokens=200,
temperature=0.7,
do_sample=True
)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(response)
دمج المحولات (اختياري)
للنشر، يمكنك دمج محولات LoRA في النموذج الأساسي:
from peft import PeftModel
from transformers import AutoModelForCausalLM
import torch
# حمّل النموذج الأساسي (دقة كاملة للدمج)
base_model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-3B-Instruct",
torch_dtype=torch.float16,
device_map="auto"
)
# حمّل وادمج المحول
model = PeftModel.from_pretrained(base_model, "./outputs/my-first-finetune/final")
merged_model = model.merge_and_unload()
# احفظ النموذج المدمج
merged_model.save_pretrained("./outputs/merged-model")
نصائح التدريب
راقب منحنيات الخسارة
التدريب الجيد يُظهر:
- خسارة تدريب متناقصة
- خسارة تحقق تستقر (لا تزيد)
- لا قفزات مفاجئة
نقاط الحفظ
# احفظ نقاط الحفظ بشكل متكرر
save_steps=100,
save_total_limit=3, # احتفظ بآخر 3 نقاط حفظ فقط
استئناف التدريب
# استأنف من نقطة حفظ
trainer.train(resume_from_checkpoint="./outputs/checkpoint-500")
النتائج المتوقعة
لضبط دقيق بـ 1000 مثال على Llama 3.2 3B:
| المقياس | المتوقع |
|---|---|
| وقت التدريب | 30-60 دقيقة (A100) |
| الخسارة النهائية | 0.5-1.5 |
| استخدام VRAM | 8-12 GB |
| حجم نقطة الحفظ | ~100 MB (LoRA فقط) |
نصيحة: ابدأ بمجموعة بيانات صغيرة (100-1000 مثال) للتحقق أن كل شيء يعمل، ثم كبّر.
في الوحدة التالية، سنتعلم كيف يمكن لـ Unsloth جعل هذا أسرع مرتين مع 70% أقل ذاكرة. :::