PEFT documentation

PaCA: تكييف الاتصال الجزئي

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

and get access to the augmented documentation experience

to get started

PaCA: تكييف الاتصال الجزئي

PaCA (ICLR 2025) هو أسلوب PEFT يستهدف سرعة التدريب وذاكرة التنشيط. يقوم بإعادة ضبط r من أعمدة المدخلات المختارة عشوائياً (والمعروفة بـ"الاتصالات الجزئية") لكل وزن مُسبق التدريب المستهدف. المعلمات القابلة للتدريب الوحيدة هي تحديثات هذه الأعمدة؛ وعلى عكس LoRA، لا يضيف PaCA أي مصفوفات منخفضة الرتبة إضافية.

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

  • عملية GEMM واحدة لكل طبقة. تُكتب الأعمدة المُعدَّلة في الأوزان المُسبقة التدريب مباشرةً قبل عملية الضرب المصفوفي الخاصة بها، ثم تُستعاد مباشرةً بعدها، بحيث تُنفَّذ كل من العملية الأمامية والعكسية عملية ضرب مصفوفي واحدة فقط، تمامًا كما في الطبقة الأساسية المجمَّدة.
  • تفعيلات جزئية. يعتمد تدرّج الأعمدة المُكيَّفة فقط على قنوات الإدخال r المطابقة، لذا تُحفظ تلك القنوات وحدها لمرحلة الرجوع بدلاً من الإدخال الكامل.

من حيث الأوزان الناتجة، يتكافئ مُكيّف PaCA مع مُكيّف LoRA من الرتبة r تكون مصفوفة A فيه مُحدِّد أعمدة ثابتًا: W' = W + delta @ S، حيث تختار S الأعمدة الـr. وبالتالي يمكن تحويله إلى مُكيّف LoRA من الرتبة r دون أي خسارة عبر convert_to_lora()، على سبيل المثال لخدمته عبر مجموعة أدوات استدلال LoRA.

متى تستخدم PaCA:

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

القيود الحالية:

  • يتم دعم طبقات nn.Linear فقط (بما في ذلك طبقات الخطية المُكمّاة).
  • تنفّذ PaCA عملية ضرب المصفوفات بنفسها بدلاً من استدعاء forward للطبقة الأساسية، لذا فإنّ الخطافات الأمامية المسجّلة على الطبقة الأساسية لا تُستدعى (يتم إصدار تحذير). سجّل الخطافات على طبقة PaCA بدلاً من ذلك.
  • لا يتم دعم دفعات المحوِّلات المختلطة (الحجة adapter_names).
  • لم يتم اختبار التدريب بأوزان مجزأة (FSDP، DeepSpeed ZeRO-3) بعد.
  • torch.compile مدعوم: أثناء التجميع، تُنفَّذ عمليات تبديل الأعمدة، وضرب المصفوفات، والاستعادة كعمليات مخصصة معتمة (torch.ops.peft.paca_linear_forward/_backward)، لذا لا ينسخ المُجمِّع الأوزان الأساسية. يتطلب هذا torch.library.custom_op (PyTorch >= 2.4)؛ وإلا فسيتم تتبع التنفيذ المباشر.
  • paca_alpha / r يضبط تحديث العمود، وبالتالي يعمل كمضاعف لمعدل التعلم الفعلي.
  • لأغراض الاستدلال، ادمج المُكيّف (merge_and_unload())؛ فالتنفيذ الأمامي غير المدمج لا يزال يقوم بتبديل الأعمدة داخلًا وخارجًا مع كل استدعاء.

الاستخدام

from transformers import AutoModelForCausalLM
from peft import PacaConfig, get_peft_model

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-3B")
config = PacaConfig(r=16, paca_alpha=16, target_modules="all-linear", random_seed=0)
model = get_peft_model(model, config)
model.print_trainable_parameters()

بشكل افتراضي، تُحسّن كل طبقة مستهدفة r من الأعمدة المختارة عشوائياً؛ وفي الورقة البحثية، كان هذا الأداء على قدم المساواة مع اختيار الأعمدة بناءً على معيار الوزن أو بناءً على التدرجات المتراكمة. لاختيار الأعمدة بنفسك، على سبيل المثال لتجربة استراتيجية اختيار أخرى أو لاستخدام عدد مختلف من الأعمدة لكل طبقة، مرّر paca_indices_pattern. مفاتيحه هي أسماء الطبقات أو تعبيرات منتظمة، كما في rank_pattern الخاص بـ LoRA:

config = PacaConfig(
    r=16,
    paca_alpha=16,
    target_modules=["q_proj", "v_proj"],
    paca_indices_pattern={"layers.0.self_attn.q_proj": [0, 2, 4, 6], "layers.1.self_attn.v_proj": list(range(32))},
)

تُعدّل الطبقات التي تطابق مفتاحًا الأعمدة المحددة، بينما تختار جميع الطبقات المستهدفة الأخرى r عمودًا عشوائيًا. تكون المعايَرة paca_alpha / r باستخدام قيمة r من الإعدادات في كل طبقة، لذا فإن paca_alpha تعني الشيء نفسه لجميع الطبقات.

ملخص الورقة البحثية هو:

تقلّل خوارزميات الضبط الدقيق الفعّال من حيث المعلمات (PEFT) السابقة من استهلاك الذاكرة والتكاليف الحسابية للضبط الدقيق لنماذج الشبكات العصبية الكبيرة من خلال تدريب عدد قليل فقط من معلمات المحوّلات الإضافية، بدلاً من تدريب النموذج بأكمله. ومع ذلك، فإن التقليل في التكاليف الحسابية الناتج عن PEFT لا يترجم بالضرورة إلى تقليل في وقت التدريب؛ فبينما تكون التكاليف الحسابية لطبقات المحوّل أصغر بكثير من الطبقات المُسبقة التدريب، إلا أنه من المعروف جيدًا أن هذين النوعين من الطبقات تتم معالجتهما بشكل تسلسلي على وحدات معالجة الرسوميات (GPUs)، مما يؤدي إلى زيادة كبيرة في زمن الاستجابة. تتجنّب LoRA ومتغيّراتها هذا العبء الزمني من خلال دمج مصفوفات المحوّل ذات الرتبة المنخفضة مع الأوزان المُسبقة التدريب أثناء الاستدلال. ومع ذلك، لا يمكن دمج تلك الطبقات أثناء التدريب، إذ يجب أن تبقى الأوزان المُسبقة التدريب مجمّدة بينما تُحدَّث مصفوفات المحوّل ذات الرتبة المنخفضة باستمرار على مدار التدريب. علاوة على ذلك، لا تقلّل LoRA ومتغيّراتها من ذاكرة التنشيطات، لأن مصفوفة المحوّل ذات الرتبة المنخفضة الأولى لا تزال تتطلب تنشيطات الإدخال للأوزان المُسبقة التدريب لحساب تدرّجات الأوزان. للتخفيف من هذه المشكلة، نقترح تكيّف الاتصال الجزئي (PaCA)، الذي يضبط بدقة اتصالات جزئية مختارة عشوائياً داخل الأوزان المُسبقة التدريب بدلاً من إدخال طبقات محوّل في النموذج. لا يعزّز PaCA سرعة التدريب فحسب، من خلال إزالة العبء الزمني الناتج عن المعالجة التسلسلية لطبقات المحوّل والطبقات المُسبقة التدريب، بل يقلّل أيضاً من ذاكرة التنشيطات، إذ لا حاجة لتخزين تنشيطات جزئية فقط، بدلاً من التنشيطات الكاملة، لحساب التدرّجات. مقارنةً بـ LoRA، يقلّل PaCA وقت التدريب بنسبة 22% واستهلاك الذاكرة الكلي بنسبة 16%، مع الحفاظ على دقة مماثلة عبر سيناريوهات ضبط دقيق متنوعة، مثل الضبط الدقيق على مجموعة بيانات MMLU والضبط التعليمي على مجموعة بيانات Oasst1. يمكن أيضاً دمج PaCA مع التكميم، مما يتيح ضبط نماذج كبيرة بدقة مثل LLaMA3.1-70B. بالإضافة إلى ذلك، يتيح PaCA التدريب مع تسلسلات أطول بنسبة 23% ويحسّن الإنتاجية بنسبة 16% على كل من وحدة معالجة الرسوميات NVIDIA A100 ووحدة المعالجة المتوازية INTEL Gaudi2 HPU مقارنةً بـ LoRA.

نظرة عامة على الاختبارات

واجهة برمجة التطبيقات

PacaConfig

فئة peft.PacaConfig

< >

( task_type: Optional[Union[str, TaskType]] = Nonepeft_type: Optional[Union[str, PeftType]] = Noneauto_mapping: Optional[dict] = Nonepeft_version: Optional[str] = Nonebase_model_name_or_path: Optional[str] = Nonerevision: Optional[str] = Noneinference_mode: bool = Falser: int = 8paca_alpha: int = 8target_modules: list[str] | str | None = Noneexclude_modules: list[str] | str | None = Nonelayers_to_transform: list[int] | int | None = Nonelayers_pattern: list[str] | str | None = Nonerandom_seed: int | None = Nonepaca_indices_pattern: dict | None = <factory>init_weights: bool = Truemodules_to_save: list[str] | None = None )

المعاملات

  • r (int، اختياري، القيمة الافتراضية 8) — عدد أعمدة الإدخال (الاتصالات الجزئية) التي يتم ضبطها الدقيق في كل طبقة مستهدفة. بالنسبة لوزن ذي شكل (out_features, in_features)، يدرب PaCA r * out_features من المعاملات، وهو العدد نفسه للمصفوفة B في مُكيّف LoRA ذي رتبة r. يجب ألا يتجاوز in_features.
  • paca_alpha (int، اختياري، القيمة الافتراضية 8) — معامل التوسيع. يتم تحديث الأعمدة المختارة عبر paca_alpha / r * delta. وكما هو الحال مع lora_alpha، يعمل هذا كمضاعف لمعدل التعلم الفعلي للمُكيّف.
  • target_modules (Union[list[str], str]، اختياري) — قائمة بأسماء الوحدات أو تعبير نمطي (regex) لأسماء الوحدات التي سيتم استبدالها بـ PaCA. على سبيل المثال، ['q_proj', 'v_proj'] أو '.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'. إذا تم تحديد هذا الحقل على أنه 'all-linear'، فسيتم اختيار جميع الوحدات الخطية باستثناء طبقة الإخراج. يتم دعم طبقات nn.Linear فقط.
  • exclude_modules (Union[list[str], str]، اختياري) — أسماء الوحدات التي لا يُطبَّق عليها المُكيّف. عند تمرير نص، يتم إجراء مطابقة باستخدام تعبير نمطي. عند تمرير قائمة من النصوص، يتم إجراء مطابقة دقيقة أو يُتحقق مما إذا كان اسم الوحدة ينتهي بأي من النصوص المُمرَّرة.
  • layers_to_transform (Union[list[int], int]، اختياري) — فهارس الطبقات المراد تحويلها. إذا تم تحديد هذا الحُجج، فإن PEFT سيحوّل فقط فهارس الطبقات المحددة داخل هذه القائمة. إذا تم تمرير عدد صحيح واحد، فإن PEFT سيحوّل فقط الطبقة الموجودة عند هذا الفهرس.
  • layers_pattern (Optional[Union[list[str], str]]، اختياري) — اسم نمط الطبقة، يُستخدم فقط إذا كان layers_to_transform مختلفًا عن None. يجب أن يستهدف هذا nn.ModuleList الخاص بالنموذج، والذي يُسمى غالبًا 'layers' أو 'h'.
  • random_seed (int، اختياري، القيمة الافتراضية None) — البذرة المستخدمة لاختيار الاتصالات الجزئية. يستخدم كل طبقة اختيارًا مختلفًا مشتقًا من هذه البذرة واسم الطبقة. إذا كانت None، يتم استخدام مولّد الأرقام العشوائية العام في torch. يتم تخزين الفهارس المختارة دائمًا في نقطة التفتيش الخاصة بالمكيّف، لذا لا تكون البذرة مطلوبة لتحميل مكيّف مدرَّب.
  • paca_indices_pattern (dict، اختياري) — تعيين اختياري من أسماء الطبقات أو تعبيرات نمطية منتظمة إلى فهارس أعمدة الإدخال التي يتم ضبطها الدقيق في الطبقات المطابقة بدلاً من r أعمدة مختارة عشوائياً، على سبيل المثال {'^model.layers.0.self_attn.q_proj': [0, 2, 4]}. يتيح هذا أيضاً استخدام عدد مختلف من الأعمدة لكل طبقة. يجب أن تكون فهارس الطبقة فريدة وأصغر من in_features. يكون التوسع paca_alpha / r مع r من هذا الإعداد في جميع الطبقات، بغض النظر عن عدد الفهارس المحددة. الطبقات المستهدفة التي لا تطابق أي مفتاح تستخدم r أعمدة مختارة عشوائياً.
  • init_weights (bool، اختياري، القيمة الافتراضية True) — إذا كانت True، يتم تهيئة تحديث الأعمدة المحددة إلى الصفر، أي أن النموذج المُكيَّف مطابق تمامًا للنموذج الأساسي عند التهيئة. اضبطها على False للتهيئة بقيم عشوائية؛ هذا مخصص للاختبار فقط.
  • modules_to_save (list[str]، اختياري) — قائمة بالوحدات غير طبقات PaCA التي يجب تعيينها قابلة للتدريب وحفظها في نقطة الفحص النهائية. على سبيل المثال، في مهام تصنيف التسلسل أو تصنيف الرموز، تكون الطبقة النهائية classifier/score مهيأة عشوائياً وبالتالي تحتاج إلى أن تكون قابلة للتدريب والحفظ.

هذه هي فئة الإعدادات لتخزين إعدادات PacaModel.

يُعدّل PaCA (Partial Connection Adaptation، https://huggingface.co/papers/2503.01905) r من أعمدة الإدخال المختارة عشوائياً (الاتصالات الجزئية) لكل وزن مُسبق التدريب المستهدف. المعاملات القابلة للتدريب الوحيدة هي تحديثات هذه الأعمدة؛ وعلى عكس LoRA، لا يضيف PaCA أي مصفوفات منخفضة الرتبة إضافية. مباشرة قبل عملية ضرب المصفوفات، تُستبدل الأعمدة المُعدّلة في الوزن المُسبق التدريب وتُستعاد مباشرة بعد العملية، بحيث تُنفذ كل من العملية الأمامية والعكسية عملية GEMM واحدة فقط، ولا يُحتفظ في الذاكرة إلا بقنوات الإدخال r المختارة لمرحلة الرجوع الخلفي.

PacaModel

فئة peft.PacaModel

< >

( modelpeft_config: Union[PeftConfig, dict[str, PeftConfig]]adapter_name: strlow_cpu_mem_usage: bool = Falsestate_dict: Optional[dict[str, torch.Tensor]] = None ) → torch.nn.Module

المعاملات

  • model (PreTrainedModel) — النموذج الذي سيتم تكييفه.
  • config (PacaConfig) — إعدادات نموذج PaCA.
  • adapter_name (str) — اسم المُكيّف، القيمة الافتراضية هي "default".
  • low_cpu_mem_usage (bool, optional, defaults to False) — إنشاء أوزان مُكيّف فارغة على جهاز meta. مفيد لتسريع عملية التحميل.

يعيد

torch.nn.Module

نموذج PaCA.

ينشئ نموذج تكييف اتصال جزئي (PaCA) من نموذج مُدرَّب مسبقًا. يتم وصف الطريقة في https://huggingface.co/papers/2503.01905.

مثال:

>>> from transformers import AutoModelForCausalLM
>>> from peft import PacaConfig, get_peft_model

>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = PacaConfig(r=16, paca_alpha=16, target_modules="all-linear")
>>> model = get_peft_model(base_model, config)

الخصائص:

  • model (PreTrainedModel) — النموذج الذي سيتم تكييفه.
  • peft_config (PacaConfig): إعدادات نموذج PaCA.
Update on GitHub