PEFT documentation

OFT

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

OFT

Controlling Text-to-Image Diffusion by Orthogonal Finetuning

التحسين المتعامد (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

< >

( 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

< >

( **kwargs )

المعاملات

  • kwargs (معلمات إضافية، اختيارية) — معلمات إضافية تُمرَّر إلى تهيئة الفئة الفرعية.

تحقق من صحة kwargs للتكوين.

OFTModel

فئة peft.OFTModel

< >

( 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 to False) — إنشاء أوزان مُكيّف فارغة على جهاز 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.
Update on GitHub