# OFT

    

التحكم في انتشار النص إلى الصورة من خلال الضبط الدقيق المتعامد

[التحسين المتعامد (OFT)](https://hf.co/papers/2306.07280) و [OFTv2](https://huggingface.co/papers/2506.19847) هي طريقة طُوّرت لتكييف نماذج الانتشار من النص إلى الصورة. تعمل عن طريق إعادة تمثيل مصفوفات الأوزان المُسبقة التدريب باستخدام مصفوفة متعامدة للحفاظ على المعلومات الموجودة في النموذج المُسبق التدريب. ولتقليل عدد المعاملات، تُدخل OFT بنية قطرية كتلية في المصفوفة المتعامدة. تركز الطريقة بشكل أساسي على الحفاظ على الأداء التوليدي لنموذج مُسبق التدريب في النموذج المُحسَّن. تحاول الحفاظ على نفس التشابه الجيبية ([الطاقة فوق الكروية](https://huggingface.co/papers/1805.09298)) بين جميع العصبونات الزوجية في طبقة ما، لأن ذلك يلتقط المعلومات الدلالية بين العصبونات بشكل أفضل. وهذا يعني أن OFT أكثر قدرة على الحفاظ على الموضوع، وهي أفضل للتوليد القابل للتحكم (مشابهة لـ [ControlNet](https://huggingface.co/docs/diffusers/using-diffusers/controlnet)).

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

*تمتاز نماذج الانتشار الكبيرة لتحويل النص إلى صورة بقدرات مبهرة في توليد صور واقعية من النصوص. وتصبح كيفية توجيه هذه النماذج القوية أو التحكم فيها بشكل فعال لأداء مهام لاحقة مختلفة مشكلة مفتوحة مهمة. لمعالجة هذا التحدي، نطرح طريقة مبدئية للضبط الدقيق -- الضبط الدقيق المتعامد (OFT) -- لتكييف نماذج الانتشار لتحويل النص إلى صورة مع المهام اللاحقة. وعلى عكس الأساليب الحالية، يمكن إثبات أن OFT يحافظ على الطاقة فوق الكروية التي تميز العلاقة العصبية الزوجية على الكرة فوق الوحدة. وجدنا أن هذه الخاصية حاسمة للحفاظ على قدرة التوليد الدلالية لنماذج الانتشار لتحويل النص إلى صورة. لتحسين استقرار الضبط الدقيق، نقترح أيضًا الضبط الدقيق المتعامد المقيد (COFT) الذي يفرض قيد نصف قطر إضافي على الكرة فوق الوحدة. على وجه التحديد، نعتبر مهمتين مهمتين لضبط نماذج تحويل النص إلى صورة: التوليد الموجّه بالموضوع حيث الهدف هو توليد صور خاصة بالموضوع بناءً على عدد قليل من صور الموضوع وموجّه نصي، والتوليد القابل للتحكم حيث الهدف هو تمكين النموذج من استقبال إشارات تحكم إضافية. نوضح تجريبيًا أن إطار OFT الخاص بنا يتفوق على الأساليب الحالية من حيث جودة التوليد وسرعة التقارب*.

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

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

<iframe src="https://peft-internal-testing-peft-method-comparison-embed.hf.space/?highlight[type]=OFT" frameborder="0" width="850" height="1000"
>

## دمج أوزان OFT في النموذج الأساسي

بشكل مشابه لـ LoRA، يمكن دمج الأوزان التي تعلّمها OFT في مصفوفات الأوزان المُسبقة التدريب باستخدام دالة `~OFTModel.merge_and_unload()`. تدمج هذه الدالة أوزان المُكيّف مع النموذج الأساسي، مما يتيح لك استخدام النموذج المُدمج الجديد بفعالية كنموذج مستقل.

## مثال على استخدام OFT

لاستخدام OFT للضبط الدقيق الكمّي باستخدام [TRL](https://github.com/huggingface/trl) لـ `SFT` أو `PPO` أو `DPO`، اتبع الخطوط العريضة التالية:

```py
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]]

#### peft.OFTConfig[[peft.OFTConfig]]

```python
peft.OFTConfig(task_type: Optional[Union[str, TaskType]] = None, peft_type: Optional[Union[str, PeftType]] = None, auto_mapping: Optional[dict] = None, peft_version: Optional[str] = None, base_model_name_or_path: Optional[str] = None, revision: Optional[str] = None, inference_mode: bool = False, r: int = 0, oft_block_size: int = 32, module_dropout: float = 0.0, target_modules: Optional[Union[list[str], str]] = None, fan_in_fan_out: bool = False, bias: Literal['none', 'all', 'oft_only'] = 'none', exclude_modules: Optional[Union[list[str], str]] = None, init_weights: bool = True, layers_to_transform: Optional[Union[list[int], int]] = None, layers_pattern: Optional[Union[list[str], str]] = None, modules_to_save: Optional[list[str]] = None, coft: bool = False, eps: float = 6e-05, block_share: bool = False, use_cayley_neumann: bool = True, num_cayley_neumann_terms: int = 5)
```

[المصدر](https://github.com/huggingface/peft/blob/main/src/peft/tuners/oft/config.py#L28)

**المعاملات:**

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) : يحدد ما إذا كان سيتم استخدام معادلة كايلي-نيومان (فعّالة لكنها تقريبية) أم معادلة كايلي الأساسية (دقيقة لكنها مكلفة حسابيًا بسبب عكس المصفوفة). ننصح بإعدادها على `True` لتحسين الكفاءة، لكن الأداء قد يكون أقل قليلاً بسبب خطأ التقريب. يُرجى اختبار كلا الإعدادين (`True` و`False`) حسب احتياجاتك. القيمة الافتراضية هي `False`.

module_dropout (`float`) : احتمال الإسقاط الضربي (multiplicative dropout)، من خلال ضبط كتل OFT على الهوية أثناء التدريب، على غرار طبقة الإسقاط (dropout) في 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]`) : قائمة بالوحدات التي يجب ضبطها لتكون قابلة للتدريب وحفظها في نقطة الفحص النهائية، باستثناء طبقات المحوّل.

coft (`bool`) : ما إذا كان سيتم استخدام النسخة المقيدة من OFT أم لا، وهي معطلة افتراضيًا.

eps (`float`) : قوة التحكم في COFT. حرية الدوران. لا يكون له تأثير إلا إذا تم تعيين `coft` إلى True.

block_share (`bool`) : ما إذا كان سيتم مشاركة معاملات OFT بين الكتل أم لا. القيمة الافتراضية هي `False`.

هذه هي فئة الإعدادات لتخزين إعدادات [OFTModel](/docs/peft/main/ar/package_reference/oft#peft.OFTModel).

#### check_kwargs[[peft.OFTConfig.check_kwargs]]

```python
check_kwargs(**kwargs)
```

[المصدر](https://github.com/huggingface/peft/blob/main/src/peft/tuners/oft/config.py#L198)

**المعاملات:**

kwargs (حجج كلمات مفتاحية إضافية، *اختيارية*) : حجج كلمات مفتاحية إضافية تُمرَّر إلى تهيئة الفئة الفرعية.

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

## OFTModel[[peft.OFTModel]]

#### peft.OFTModel[[peft.OFTModel]]

```python
peft.OFTModel(model, peft_config: Union[PeftConfig, dict[str, PeftConfig]], adapter_name: str, low_cpu_mem_usage: bool = False, state_dict: Optional[dict[str, torch.Tensor]] = None)
```

[المصدر](https://github.com/huggingface/peft/blob/main/src/peft/tuners/oft/model.py#L44)

**المعاملات:**

model (`torch.nn.Module`) : النموذج الذي سيتم إرفاق طبقات مُعدِّل المُكيّف (adapter tuner) به.

config ([OFTConfig](/docs/peft/main/ar/package_reference/oft#peft.OFTConfig)) : إعدادات نموذج OFT.

adapter_name (`str`) : اسم المُكيِّف، القيمة الافتراضية هي `"default"`.

low_cpu_mem_usage (`bool`، `optional`، القيمة الافتراضية `False`) : إنشاء أوزان مكيّف فارغة على جهاز meta. مفيد لتسريع عملية التحميل.

**يعيد:** `torch.nn.Module`

نموذج OFT.

ينشئ نموذج Orthogonal Finetuning من نموذج مُدرَّب مسبقًا. يتم وصف الطريقة في https://huggingface.co/papers/2306.07280

مثال:
```py
>>> 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](/docs/peft/main/ar/package_reference/oft#peft.OFTConfig)): إعدادات نموذج OFT.

