PEFT documentation
OFT
OFT

التحسين المتعامد (OFT) و OFTv2 هي طريقة طُوّرت لتكييف نماذج الانتشار من النص إلى الصورة. تعمل عن طريق إعادة تمثيل مصفوفات الأوزان المُسبقة التدريب باستخدام مصفوفة متعامدة للحفاظ على المعلومات الموجودة في النموذج المُسبق التدريب. ولتقليل عدد المعاملات، تُدخل OFT بنية قطرية كتلية في المصفوفة المتعامدة. تركز الطريقة بشكل أساسي على الحفاظ على الأداء التوليدي لنموذج مُسبق التدريب في النموذج المُحسَّن. تحاول الحفاظ على نفس التشابه الجيبية (الطاقة فوق الكروية) بين جميع العصبونات الزوجية في طبقة ما، لأن ذلك يلتقط المعلومات الدلالية بين العصبونات بشكل أفضل. وهذا يعني أن OFT أكثر قدرة على الحفاظ على الموضوع، وهي أفضل للتوليد القابل للتحكم (مشابهة لـ ControlNet).
ملخص الورقة البحثية هو:
تمتاز نماذج الانتشار الكبيرة لتحويل النص إلى صورة بقدرات مبهرة في توليد صور واقعية من النصوص. وتصبح كيفية توجيه هذه النماذج القوية أو التحكم فيها بشكل فعال لأداء مهام لاحقة مختلفة مشكلة مفتوحة مهمة. لمعالجة هذا التحدي، نطرح طريقة مبدئية للضبط الدقيق — الضبط الدقيق المتعامد (OFT) — لتكييف نماذج الانتشار لتحويل النص إلى صورة مع المهام اللاحقة. وعلى عكس الأساليب الحالية، يمكن إثبات أن OFT يحافظ على الطاقة فوق الكروية التي تميز العلاقة العصبية الزوجية على الكرة فوق الوحدة. وجدنا أن هذه الخاصية حاسمة للحفاظ على قدرة التوليد الدلالية لنماذج الانتشار لتحويل النص إلى صورة. لتحسين استقرار الضبط الدقيق، نقترح أيضًا الضبط الدقيق المتعامد المقيد (COFT) الذي يفرض قيد نصف قطر إضافي على الكرة فوق الوحدة. على وجه التحديد، نعتبر مهمتين مهمتين لضبط نماذج تحويل النص إلى صورة: التوليد الموجّه بالموضوع حيث الهدف هو توليد صور خاصة بالموضوع بناءً على عدد قليل من صور الموضوع وموجّه نصي، والتوليد القابل للتحكم حيث الهدف هو تمكين النموذج من استقبال إشارات تحكم إضافية. نوضح تجريبيًا أن إطار OFT الخاص بنا يتفوق على الأساليب الحالية من حيث جودة التوليد وسرعة التقارب.
يحافظ OFT على الطاقة فوق الكروية من خلال تعلُّب تحويل متعامد للخلايا العصبية للحفاظ على تشابه جيب التمام بينها دون تغيير، مما قد يؤدي إلى تقليل نسيان المعرفة المُتعلَّمة سابقًا. عمليًا، يعني ذلك أخذ حاصل ضرب مصفوفة متعامدة في مصفوفة الأوزان المُسبقة التدريب. ومع ذلك، لكي يكون فعالًا من حيث المعلمات، يتم تمثيل المصفوفة المتعامدة كمصفوفة قطرية كتلية ذات كتل بترتيب r. بينما يقلل LoRA عدد المعلمات القابلة للتدريب باستخدام هياكل منخفضة الترتيب، يقلل OFT عدد المعلمات القابلة للتدريب باستخدام هيكل مصفوفة قطرية كتلية متناثرة.
نظرة عامة على الاختبارات
دمج أوزان OFT في النموذج الأساسي
بشكل مشابه لـ LoRA، يمكن دمج الأوزان التي تعلّمها OFT في مصفوفات الأوزان المُسبقة التدريب باستخدام دالة ~OFTModel.merge_and_unload(). تدمج هذه الدالة أوزان المُكيّف مع النموذج الأساسي، مما يتيح لك استخدام النموذج المُدمج الجديد بفعالية كنموذج مستقل.
مثال على استخدام OFT
لاستخدام OFT للضبط الدقيق الكمّي باستخدام TRL لـ SFT أو PPO أو DPO، اتبع الخطوط العريضة التالية:
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from trl import SFTTrainer
from peft import OFTConfig
if use_quantization:
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_storage=torch.bfloat16,
)
model = AutoModelForCausalLM.from_pretrained(
"model_name",
quantization_config=bnb_config
)
tokenizer = AutoTokenizer.from_pretrained("model_name")
# Configure OFT
peft_config = OFTConfig(
oft_block_size=32,
use_cayley_neumann=True,
target_modules="all-linear",
bias="none",
task_type="CAUSAL_LM"
)
trainer = SFTTrainer(
model=model,
train_dataset=ds['train'],
peft_config=peft_config,
processing_class=tokenizer,
args=training_arguments,
data_collator=collator,
)
trainer.train()واجهة برمجة التطبيقات
OFTConfig
فئة peft.OFTConfig
< source >( 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 = 0oft_block_size: int = 32module_dropout: float = 0.0target_modules: Optional[Union[list[str], str]] = Nonefan_in_fan_out: bool = Falsebias: Literal['none', 'all', 'oft_only'] = 'none'exclude_modules: Optional[Union[list[str], str]] = Noneinit_weights: bool = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Nonemodules_to_save: Optional[list[str]] = Nonecoft: bool = Falseeps: float = 6e-05block_share: bool = Falseuse_cayley_neumann: bool = Truenum_cayley_neumann_terms: int = 5 )
المعاملات
- r (
int) — رتبة OFT، وعدد كتل OFT لكل طبقة مُحقنة. كلما زادت قيمةr، أصبحت مصفوفات التحديث المتناثرة أكثر، مع عدد أقل من المعاملات القابلة للتدريب. يمكنك تحديدrأوoft_block_sizeفقط، وليس كلاهما في الوقت نفسه، لأنr×oft_block_size= بُعد الطبقة. من أجل البساطة، نسمح لك بتحديدrأوoft_block_sizeونستنتج الآخر. القيمة الافتراضية هيr = 0، ويُنصح المستخدم بتعيينoft_block_sizeبدلاً من ذلك لوضوح أفضل. - oft_block_size (
int) — حجم كتلة OFT عبر الطبقات المختلفة. يؤدي اختيارoft_block_sizeأكبر إلى مصفوفات تحديث أكثر كثافة مع عدد أكبر من المعاملات القابلة للتدريب. اخترoft_block_sizeبحيث يكون قابلاً للقسمة على بُعد مدخلات الطبقة (in_features)، مثل 4 أو 8 أو 16. يمكنك تحديدrأوoft_block_sizeفقط، وليس كلاهما في الوقت نفسه، لأنr×oft_block_size= بُعد الطبقة. وبسبب البساطة، نسمح لك بتحديدrأوoft_block_sizeوالاستدلال على الآخر. القيمة الافتراضية هيoft_block_size = 32. - use_cayley_neumann (bool) — يحدد ما إذا كان سيتم استخدام معادلة Cayley-Neumann (فعّالة لكنها تقريبية) أم معادلة Cayley الأساسية (دقيقة لكنها مكلفة حسابياً بسبب عكس المصفوفة). ننصح بإعدادها على
Trueلتحسين الكفاءة، لكن الأداء قد يكون أقل قليلاً بسبب خطأ التقريب. يُرجى اختبار كلا الإعدادين (TrueوFalse) حسب احتياجاتك. القيمة الافتراضية هيFalse. - module_dropout (
float) — احتمالية الإسقاط الضربي، من خلال ضبط كتل OFT على الهوية أثناء التدريب، على غرار طبقة الإسقاط في LoRA. - target_modules (
Optional[Union[list[str], str]]) — أسماء الوحدات التي سيتم تطبيق المُكيّف عليها. إذا تم تحديد هذا، فسيتم استبدال الوحدات التي تحمل الأسماء المحددة فقط. عند تمرير نص، سيتم إجراء مطابقة باستخدام تعبير نمطي. عند تمرير قائمة من النصوص، سيتم إجراء مطابقة دقيقة أو يتم التحقق مما إذا كان اسم الوحدة ينتهي بأي من النصوص الممررة. إذا تم تحديده على أنه ‘all-linear’، فسيتم اختيار جميع الوحدات الخطية، باستثناء طبقة الإخراج. إذا لم يتم تحديده، فسيتم اختيار الوحدات وفقًا لبنية النموذج. إذا لم تكن البنية معروفة، فسيتم رفع خطأ — في هذه الحالة، يجب عليك تحديد الوحدات المستهدفة يدويًا. - fan_in_fan_out (
bool) — اضبط هذا على True إذا كانت الطبقة التي سيتم استبدالها تخزن الأوزان على شكل (fan_in, fan_out). - bias (
str) — نوع الانحياز لـ OFT. يمكن أن يكون ‘none’ أو ‘all’ أو ‘oft_only’. إذا كان ‘all’ أو ‘oft_only’، فسيتم تحديث الانحيازات المقابلة أثناء التدريب. انتبه إلى أن هذا يعني أنه حتى عند تعطيل المحوِّلات، لن ينتج النموذج نفس المخرجات التي كان سينتجها النموذج الأساسي دون تكييف. - exclude_modules (
Optional[Union[List[str], str]]) — أسماء الوحدات التي لا يُطبَّق عليها المُكيّف. عند تمرير نص، يتم إجراء مطابقة باستخدام تعبير نمطي. عند تمرير قائمة من النصوص، يتم إجراء مطابقة دقيقة أو يُتحقق مما إذا كان اسم الوحدة ينتهي بأي من النصوص المُمرَّرة. - init_weights (
bool) — ما إذا كان سيتم تنفيذ تهيئة أوزان OFT. - layers_to_transform (
Union[List[int], int]) — فهارس الطبقات المراد تحويلها. إذا تم تمرير قائمة من الأعداد الصحيحة، فسيتم تطبيق المُكيّف على فهارس الطبقات المحددة في هذه القائمة. أما إذا تم تمرير عدد صحيح واحد، فسيتم تطبيق التحويلات على الطبقة الموجودة عند هذا الفهرس. - layers_pattern (
Optional[Union[List[str], str]]) — اسم نمط الطبقة، يُستخدم فقط إذا كانlayers_to_transformمختلفاً عنNone. يجب أن يستهدف هذاnn.ModuleListالخاص بالنموذج، والذي يُسمى غالباً'layers'أو'h'. - modules_to_save (
List[str]) — قائمة بالوحدات، بخلاف طبقات المُكيِّف (adapter)، التي يجب تعيينها قابلة للتدريب وحفظها في نقطة الفحص النهائية. - coft (
bool) — ما إذا كان سيتم استخدام النسخة المقيدة من OFT أم لا، وهي معطلة افتراضيًا. - eps (
float) — قوة التحكم في COFT. حرية الدوران. لا يكون له تأثير إلا إذا تم ضبطcoftعلى True. - block_share (
bool) — ما إذا كان سيتم مشاركة معاملات OFT بين الكتل أم لا. القيمة الافتراضية هيFalse.
هذه هي فئة الإعدادات لتخزين إعدادات OFTModel.
check_kwargs
< source >( **kwargs )
تحقق من صحة kwargs للتكوين.
OFTModel
فئة peft.OFTModel
< source >( 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 (
torch.nn.Module) — النموذج الذي ستُربط به طبقات مُعدِّل المُكيّف (adapter tuner). - config (OFTConfig) — إعدادات نموذج OFT.
- adapter_name (
str) — اسم المُكيّف، القيمة الافتراضية هي"default". - low_cpu_mem_usage (
bool,optional, defaults toFalse) — إنشاء أوزان مُكيّف فارغة على جهاز meta. مفيد لتسريع عملية التحميل.
يعيد
torch.nn.Module
نموذج OFT.
ينشئ نموذج Orthogonal Finetuning من نموذج مُدرَّب مسبقًا. يتم وصف الطريقة في https://huggingface.co/papers/2306.07280
مثال:
>>> from diffusers import StableDiffusionPipeline
>>> from peft import OFTConfig, get_peft_model
>>> config_te = OFTConfig(
... oft_block_size=32,
... target_modules=["k_proj", "q_proj", "v_proj", "out_proj", "fc1", "fc2"],
... module_dropout=0.0,
... init_weights=True,
... )
>>> config_unet = OFTConfig(
... oft_block_size=32,
... target_modules=[
... "proj_in",
... "proj_out",
... "to_k",
... "to_q",
... "to_v",
... "to_out.0",
... "ff.net.0.proj",
... "ff.net.2",
... ],
... module_dropout=0.0,
... init_weights=True,
... )
>>> model = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
>>> model.text_encoder = get_peft_model(model.text_encoder, config_te)
>>> model.unet = get_peft_model(model.unet, config_unet)الخصائص:
- النموذج (
~torch.nn.Module) — النموذج الذي سيتم تكييفه. - peft_config (OFTConfig): إعدادات نموذج OFT.