Transformers documentation

ضبط دقيق فعّال من حيث المعلمات

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

ضبط دقيق فعّال من حيث المعلمات

تعتمد طرق الضبط الدقيق الفعال من حيث المعاملات (PEFT) على ضبط عدد صغير من معاملات النموذج الإضافية (المُكيِّفات) فوق نموذج مُدرَّب مسبقًا. وبما أن معاملات المُكيِّفات فقط هي التي تُحدَّث، فإن المُحسِّن يتتبع عددًا أقل بكثير من التدرجات والحالات، مما يقلل من استهلاك الذاكرة بشكل كبير. كما أن المُكيِّفات خفيفة الوزن، مما يجعلها مريحة للمشاركة والتخزين والتحميل.

يتكامل Transformers مباشرةً مع مكتبة PEFT من خلال PeftAdapterMixin، الذي أُضيف إلى جميع فئات PreTrainedModel. يمكنك تحميل المكيّفات (adapters) وإضافتها وتدريبها والتبديل بينها وحذفها دون الحاجة إلى تغليف نموذجك داخل PeftModel منفصل. جميع طرق PEFT غير المعتمدة على التعلّم بالموجّهات مدعومة (LoRA، IA3، AdaLoRA). أما الطرق المعتمدة على الموجّهات مثل ضبط الموجّهات وضبط البادئات فتتطلّب استخدام مكتبة PEFT مباشرةً.

قم بتثبيت PEFT للبدء. تتطلب عملية التكامل peft >= 0.20.0.

pip install -U peft

إضافة مُكيّف

أنشئ إعداد PEFT، مثل LoraConfig على سبيل المثال، وأرفقه بنموذج باستخدام add_adapter().

from peft import LoraConfig, TaskType
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("google/gemma-2-2b")

lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    inference_mode=False,
    r=8,
    lora_alpha=32,
    lora_dropout=0.1,
)

model.add_adapter(lora_config, adapter_name="my_adapter")

ضبط كامل لطبقات محددة

لتدريب وحدات إضافية إلى جانب المُكيّف (adapter) (على سبيل المثال، رأس نموذج اللغة)، حدّدها في modules_to_save. يحدد modules_to_save الطبقات التي يتم ضبطها بالكامل إلى جانب المُكيّف، لذا يتم تحديث جميع معاملاتها. وهذا مفيد عندما تحتاج طبقات معينة إلى تحديثات، على سبيل المثال رأس نموذج اللغة (lm_head)، عند تكييف نموذج لغوي سببي (causal LM) لتصنيف التسلسلات.

lora_config = LoraConfig(
    modules_to_save=["lm_head"],
    ...
)
model.add_adapter(lora_config)

اختيار الطبقات التي يجب تكييفها

بالنسبة للهندسات الشائعة (مثل Llama وGemma وQwen وغيرها)، يحتوي PEFT على أهداف افتراضية محددة مسبقًا (مثل q_proj وv_proj)، لذا لا حاجة إلى تحديد target_modules. إذا كنت ترغب في استهداف طبقات مختلفة، أو إذا لم يكن للنموذج أهداف محددة مسبقًا، فمرّر target_modules صراحةً كقائمة من أسماء الوحدات أو كنمط تعبير نمطي (regex).

lora_config = LoraConfig(
    target_modules=["q_proj", "k_proj"],
    ...
)
model.add_adapter(lora_config)

التدريب

مرّر النموذج مع المُكيّف المرفق إلى Trainer واستدعِ train(). يقوم Trainer بتحديث معاملات المُكيّف فقط (تلك التي تحمل requires_grad=True) لأن النموذج الأساسي مجمّد.

from transformers import Trainer, TrainingArguments

training_args = TrainingArguments(
    output_dir="./output",
    num_train_epochs=3,
    per_device_train_batch_size=4,
)

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

trainer.train()

أثناء التدريب، تحتوي نقاط التفتيش الخاصة بـ Trainer على أوزان المحوّل (adapter_model.safetensors) وإعداداته (adapter_config.json) فقط، مما يحافظ على صغر حجم نقاط التفتيش. ولا يتم تضمين النموذج الأساسي.

بعد التدريب، احفظ المحوّل النهائي باستخدام save_pretrained().

model.save_pretrained("./my_adapter")

الاستئناف من نقطة تفتيش

يتعرّف Trainer تلقائيًا على نقاط التفتيش الخاصة بالمُكيِّفات عند الاستئناف. يفحص Trainer مجلد نقطة التفتيش بحثًا عن مجلدات فرعية تحتوي على أوزان المُكيِّفات، ويعيد تحميل كل مُكيِّف مع حالة قابلة للتدريب الصحيحة.

trainer.train(resume_from_checkpoint="./output/checkpoint-1000")

التدريب الموزّع

تعمل محوِّلات PEFT مع التدريب الموزَّع دون أي إعداد مسبق.

في حالة ZeRO-3، يمرّر Trainer القيمة exclude_frozen_parameters=True عند حفظ نقاط التفتيش مع نموذج PEFT. يتم تجاوز أوزان النموذج الأساسي المجمّد. تُحفظ فقط معاملات المُكيّف القابلة للتدريب، مما يقلّل من حجم نقطة التفتيش ووقت الحفظ.

في حالة FSDP، يقوم Trainer بتحديث سياسة التفاف FSDP التلقائي للتعامل مع طبقات LoRA بشكل صحيح. أما في حالة QLoRA (نموذج أساسي مُكمَّم + LoRA)، فيقوم Trainer أيضاً بضبط سياسة الدقة المختلطة لتتوافق مع نوع التخزين (dtype) الخاص بالكمّ.

يمكنك تحميل مُكيّفات PEFT على نموذج أساسي متوازٍ على مستوى الموترات، ودع PEFT يتولى تقسيم أوزان المُكيّف. يتطلب تحميل المُكيّف peft >= 0.21.1. راجع التوازي على مستوى الموترات للتدريب باستخدام TP.

تحميل مُكيّف

لتحميل مُكيّف، يجب أن يحتوي مستودع Hub أو المجلد المحلي على ملف adapter_config.json وأوزان المُكيّف.

from_pretrained
load_adapter

يتعرّف from_pretrained() على المُكيّفات تلقائيًا. عند العثور على adapter_config.json، يقرأ حقل base_model_name_or_path لتحميل النموذج الأساسي الصحيح، ثم يحمّل المُكيّف فوقه.

from transformers import AutoModelForCausalLM

# Automatically loads the base model and attaches the adapter
model = AutoModelForCausalLM.from_pretrained("klcsp/gemma7b-lora-alpaca-11-v1")

بالنسبة إلى النماذج الكبيرة، حمّل نسخة مُكمّاة بدقة 8 بت أو 4 بت باستخدام bitsandbytes لتوفير الذاكرة. أضف device_map="auto" لتوزيع النموذج على الأجهزة المتاحة.

from transformers import AutoModelForCausalLM, BitsAndBytesConfig

model = AutoModelForCausalLM.from_pretrained(
    "klcsp/gemma7b-lora-alpaca-11-v1",
    quantization_config=BitsAndBytesConfig(load_in_8bit=True),
    device_map="auto",
)

إدارة عدة محوِّلات

يمكن أن يحتفظ النموذج بعدة محوِّلات (adapters) في وقت واحد. أضف المحوِّلات بأسماء فريدة، وتبديل بينها عند الحاجة.

from peft import LoraConfig

model.add_adapter(LoraConfig(r=8, lora_alpha=32), adapter_name="adapter_1")
model.add_adapter(LoraConfig(r=16, lora_alpha=64), adapter_name="adapter_2")

استخدم set_adapter() لتفعيل مُكيّف محدد. يتم تعطيل المُكيّفات الأخرى لكنها تبقى في الذاكرة.

model.set_adapter("adapter_2")

تُفعّل enable_adapters() جميع المكيّفات المرفقة، بينما تُعطّل disable_adapters() جميعها.

# Disable all adapters for base model inference
model.disable_adapters()

# Re-enable all adapters
model.enable_adapters()

استخدم active_adapters() لمعرفة المُكيّفات النشطة حاليًا.

model.active_adapters()
# ["adapter_1"]

احذف المُكيّفات التي لم تعد بحاجة إليها باستخدام delete_adapter() لتحرير الذاكرة.

model.delete_adapter("adapter_1")

تبديل المحولات

تحميل مُكيّف جديد في كل مرة تخدم فيها طلبًا يؤدي إلى تخصيص ذاكرة جديدة. إذا كان النموذج مُجمَّعًا باستخدام torch.compile، فإن كل مُكيّف جديد يُطلق إعادة تجميع. يستبدل تبديل التشغيل الساخن أوزان المُكيّف في مكانه، مما يتجنب كلا المشكلتين. لا يتم دعم مُكيّفات LoRA فقط.

مرّر hotswap=True عند تحميل مُكيّف LoRA لاستبدال أوزانه في خانة مُكيّف موجودة مسبقًا. اضبط adapter_name على اسم المُكيّف الذي تريد استبداله (اسم المُكيّف الافتراضي هو "default").

model = AutoModel.from_pretrained(...)
# Load the first adapter normally
model.load_adapter(adapter_path_1)
# Generate outputs with adapter 1
...
# Hotswap the second adapter in-place
model.load_adapter(adapter_path_2, hotswap=True, adapter_name="default")
# Generate outputs with adapter 2

torch.compile

بالنسبة إلى النماذج المُجمَّعة، استدعِ enable_peft_hotswap() قبل تحميل أول مُكيِّف وقبل عملية التجميع.

model = AutoModel.from_pretrained(...)
max_rank = ...  # highest rank among all LoRAs you'll load
model.enable_peft_hotswap(target_rank=max_rank)
model.load_adapter(adapter_path_1, adapter_name="default")
model = torch.compile(model, ...)
output_1 = model(...)

# Hotswap without recompilation
model.load_adapter(adapter_path_2, adapter_name="default")
output_2 = model(...)

يحدد الحُجّة target_rank الحد الأقصى للرتبة بين جميع مُكيّفات LoRA التي ستُحمّلها. إذا كان لديك مُكيّفات برتبة 8 وأخرى برتبة 16، فمرّر target_rank=16. القيمة الافتراضية هي 128.

بعد استدعاء enable_peft_hotswap، تصبح جميع استدعاءات load_adapter اللاحقة تبديلاً ساخناً افتراضياً. مرّر hotswap=False صراحةً لتعطيل التبديل الساخن.

قد يحدث إعادة تجميع (Recompilation) إذا كان المُكيّف (adapter) المُستبدل ساخناً يستهدف طبقات أكثر من المُكيّف الأولي. حمّل المُكيّف الذي يستهدف أكبر عدد من الطبقات أولاً لتجنب إعادة التجميع.

قم بتغليف كودك بـ with torch._dynamo.config.patch(error_on_recompile=True) للكشف عن إعادة التجميع غير المتوقعة. إذا اكتشفت إعادة تجميع رغم اتباع الخطوات المذكورة أعلاه، فافتح مشكلة لدى PEFT مع مثال قابل للتكرار.

الخطوات التالية

  • يتناول الوثائق الخاصة بـ PEFT طيفًا كاملًا من طرق PEFT وخياراته.
  • تفصّل مرجع تبديل PEFT القيود والحالات الحدّية.
  • تُقيّم منشور مدونة كيف يحسّن torch.compile مع تبديل الساخن زمن التشغيل.
Update on GitHub