# AdaLoRA

[AdaLoRA](https://hf.co/papers/2303.10512) (LoRA التكيفي) هي طريقة لتحسين عدد المعاملات القابلة للتدريب المخصصة لمصفوفات الأوزان والطبقات، على عكس LoRA التي توزع المعاملات بالتساوي عبر جميع الوحدات. يتم تخصيص ميزانية أكبر من المعاملات لمصفوفات الأوزان والطبقات المهمة، بينما تحصل الأقل أهمية على عدد أقل من المعاملات. يمكنك التحكم في *الرتبة* المتوسطة المطلوبة أو `r` للمصفوفات، والوحدات التي سيتم تطبيق AdaLoRA عليها باستخدام `target_modules`. من بين المعاملات المهمة الأخرى التي يجب ضبطها `lora_alpha` (عامل التوسع)، و`modules_to_save` (الوحدات التي سيتم تدريبها وحفظها بخلاف طبقات AdaLoRA). جميع هذه المعاملات - وغيرها - موجودة في [AdaLoraConfig](/docs/peft/main/ar/package_reference/adalora#peft.AdaLoraConfig).

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

*أصبح ضبط النماذج اللغوية الكبيرة المُدرَّبة مسبقًا على المهام الفرعية نموذجًا مهمًا في معالجة اللغة الطبيعية. ومع ذلك، فإن الممارسة الشائعة تقوم بضبط جميع المعاملات في النموذج المُدرَّب مسبقًا، وهو أمر غير عملي عندما يكون هناك عدد كبير من المهام الفرعية. لذلك، تم اقتراح العديد من طرق الضبط لتعلم التحديثات التفاضلية للأوزان المُدرَّبة مسبقًا بطريقة فعالة من حيث المعاملات، مثل الزيادات ذات الرتبة المنخفضة. غالبًا ما توزّع هذه الطرق ميزانية التحديثات التفاضلية بالتساوي عبر جميع مصفوفات الأوزان المُدرَّبة مسبقًا، وتتجاهل الأهمية المتغيرة لمعاملات الأوزان المختلفة. ونتيجة لذلك، يكون أداء الضبط غير مثالي. لسد هذه الفجوة، نقترح AdaLoRA، الذي يوزّع ميزانية المعاملات بين مصفوفات الأوزان بشكل تكيفي وفقًا لدرجة أهميتها. على وجه التحديد، يُمثّل AdaLoRA التحديثات التفاضلية على شكل تحليل القيمة المفردة. يسمح هذا النهج الجديد لنا بقصّ القيم المفردة للتحديثات غير المهمة بفعالية، وهو ما يعني في جوهره تقليل ميزانية معاملاتها مع تجنّب حسابات SVD الدقيقة المكثفة. أجرينا تجارب موسّعة باستخدام عدة نماذج مُدرَّبة مسبقًا في معالجة اللغة الطبيعية، والإجابة على الأسئلة، وتوليد اللغة الطبيعية، للتحقق من فعالية AdaLoRA. تُظهر النتائج أن AdaLoRA يُحقق تحسينًا ملحوظًا مقارنةً بالأساسيات، خاصةً في إعدادات الميزانية المنخفضة. كودنا متاح علنًا على https://github.com/QingruZhang/AdaLoRA*.

> [!WARNING]
> يتميز AdaLoRA بطريقة [update_and_allocate()](/docs/peft/main/ar/package_reference/adalora#peft.AdaLoraModel.update_and_allocate) يجب استدعاؤها في كل خطوة تدريب لتحديث ميزانية المعلمات والقناع، وإلا فلن يتم تنفيذ خطوة التكيف. ويتطلب ذلك كتابة حلقة تدريب مخصصة أو إنشاء فئة فرعية من [Trainer](https://huggingface.co/docs/transformers/main/en/main_classes/trainer#transformers.Trainer) لدمج هذه الطريقة. كمثال، راجع هذه [حلقة التدريب المخصصة](https://github.com/huggingface/peft/blob/912ad41e96e03652cabf47522cd876076f7a0c4f/examples/conditional_generation/peft_adalora_seq2seq.py#L120).

تدير AdaLoRA ميزانية المعلمات المقدمة من LoRA من خلال تخصيص عدد أكبر من المعلمات - أو بعبارة أخرى، رتبة أعلى `r` - لمصفوفات الأوزان المهمة التي تتكيف بشكل أفضل مع المهمة، وقصّ تلك الأقل أهمية. يتم التحكم في الرتبة بطريقة مشابهة لتحليل القيم المفردة (SVD). يتم تمثيل $\Delta W$ بمعاملين متعامدين ومصفوفة قطرية تحتوي على القيم المفردة. تتجنب طريقة التمثيل هذه تطبيق SVD بشكل متكرر، وهو أمر مكلف حسابياً. بناءً على هذه الطريقة، يتم تعديل رتبة $\Delta W$ وفقاً لدرجة الأهمية. يتم تقسيم $\Delta W$ إلى ثلاثيات، وتُقيَّم كل ثلاثية وفقاً لمساهمتها في أداء النموذج. تُقصّ الثلاثيات ذات درجات الأهمية المنخفضة، وتُحتفظ بالثلاثيات ذات درجات الأهمية العالية للضبط الدقيق.

يتضمن التدريب باستخدام AdaLoRA ثلاث مراحل: مرحلة التهيئة، ومرحلة تخصيص الميزانية، والمرحلة النهائية. في مرحلة التهيئة، لا يُطبَّق تخصيص الميزانية، وبالتالي لا يتم تعديل الرتب. خلال مرحلة تخصيص الميزانية، يُطبَّق العملية الموصوفة أعلاه، وتُعاد توزيع الرتب وفقًا لميزانية محددة، بهدف منح المكيّفات (adapters) الأكثر أهمية رتبًا أعلى، والطبقات الأقل أهمية رتبًا أقل. عند الوصول إلى المرحلة النهائية، يكون تخصيص الميزانية قد انتهى، وتُعاد توزيع الرتب، لكن قد نواصل التدريب لبعض الوقت باستخدام الرتب المعاد توزيعها لتحسين الأداء بشكل أكبر.

> [!NOTE]
> **مساهماتكم مرحّب بها**: تحتاج هذه القسم إلى توضيح.
>
> غير واضح كيفية قياس الأهمية. كما أن الشرح مكرر إلى حد ما ويمكن أن يستفيد من التجميع. راجع [هنا](../developer_guides/contributing#documentation-improvements) لمعرفة كيفية المساهمة.

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

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

## الاستخدام

```py
from peft import AdaLoraConfig, get_peft_model

config = AdaLoraConfig(
    r=8,
    init_r=12,
    tinit=200,
    tfinal=1000,
    deltaT=10,
    target_modules=["query", "value"],
    modules_to_save=["classifier"],
)
model = get_peft_model(model, config)
model.print_healthcheck()

[... training code ...]

model.update_and_allocate(step_idx)
```

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

## AdaLoraConfig[[peft.AdaLoraConfig]]

#### peft.AdaLoraConfig[[peft.AdaLoraConfig]]

```python
peft.AdaLoraConfig(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 = 8, target_modules: Optional[Union[list[str], str]] = None, exclude_modules: Optional[Union[list[str], str]] = None, lora_alpha: int = 8, lora_dropout: float = 0.0, fan_in_fan_out: bool = False, bias: Literal['none', 'all', 'lora_only'] = 'none', use_rslora: bool = False, modules_to_save: Optional[list[str]] = None, init_lora_weights: bool | Literal['gaussian', 'eva', 'olora', 'pissa', 'pissa_niter_[number of iters]', 'corda', 'astra', 'loftq', 'orthogonal', 'mica', 'nora'] = True, layers_to_transform: Optional[Union[list[int], int]] = None, layers_pattern: Optional[Union[list[str], str]] = None, rank_pattern: dict | None = None, alpha_pattern: Optional[dict] = <factory>, megatron_config: Optional[dict] = None, megatron_core: Optional[str] = 'megatron.core', trainable_token_indices: Optional[Union[list[int], dict[str, list[int]]]] = None, loftq_config: Union[LoftQConfig, dict] = <factory>, eva_config: Optional[EvaConfig] = None, corda_config: Optional[CordaConfig] = None, astra_config: Optional[AstraConfig] = None, lora_ga_config: Optional[LoraGAConfig] = None, use_dora: bool = False, velora_config: Optional[Union[VeloraConfig, dict]] = None, alora_invocation_tokens: Optional[list[int]] = None, use_qalora: bool = False, qalora_group_size: int = 16, monteclora_config: Optional[MontecloraConfig] = None, layer_replication: Optional[list[tuple[int, int]]] = None, runtime_config: LoraRuntimeConfig = <factory>, lora_bias: bool = False, target_parameters: Optional[list[str]] = None, use_bdlora: Optional[BdLoraConfig] = None, arrow_config: Optional[ArrowConfig] = None, kasa_config: Optional[KasaConfig] = None, ensure_weight_tying: bool = False, target_r: int = 8, init_r: int = 12, tinit: int = 0, tfinal: int = 0, deltaT: int = 1, beta1: float = 0.85, beta2: float = 0.85, orth_reg_weight: float = 0.5, total_step: int | None = None)
```

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

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

target_r (`int`) : متوسط الرتبة المستهدف للمصفوفة التزايدية.

init_r (`int`) : الترتيب الأولي لكل مصفوفة تزايدية.

tinit (`int`) : خطوات الإحماء الأولية للتدريب الدقيق.

tfinal (`int`) : عدد خطوات الضبط الدقيق النهائي.

deltaT (`int`) : الفترة الزمنية بين تخصيصين للميزانية.

beta1 (`float`) : المعامل الفائق (Hyperparameter) الخاص بـ EMA لتنعيم الحساسية.

beta2 (`float`) : المعامل الفائق الخاص بـ EMA لقياس عدم اليقين.

orth_reg_weight (`float`) : معامل التنظيم المتعامد.

total_step (`int`) : إجمالي خطوات التدريب التي يجب تحديدها قبل بدء التدريب.

rank_pattern (`list`) : الرتبة المخصصة لكل مصفوفة أوزان بواسطة RankAllocator.

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

يتضمن AdaLoRA ثلاث مراحل يحددها `tinit` و`tfinal` و`total_step`.

يمكن فهم المرحلة الأولية كخطوة لتدريب المسارات (adapters) مسبقًا بحيث، عند تقليل رتبتها، تكون هناك بعض المعلومات المشفرة مسبقًا يمكن تقليلها بدلاً من مصفوفات عشوائية. تُعرَّف هذه المرحلة بتزويد `tinit`.

بعد انتهاء المرحلة الأولية (حيث مرّت `tinit` خطوات) وقبل بدء المرحلة النهائية، تُقلّل AdaLoRA الميزانية المخصصة لرتبة كل طبقة مع كل خطوة. هنا يحدث خفض الرتبة. وتستمر هذه العملية حتى بلوغ `total_step - tfinal` خطوة.

المرحلة الأخيرة، التي تبدأ عند بلوغ `total_step - tfinal` خطوة، لا تعدّل رتب الطبقات بعد الآن، بل تُحسّن الطبقات ذات الرتبة المُخفَّضة الناتجة عن المرحلة السابقة.

مثال عملي: `tinit` يساوي 10، و`tfinal` يساوي 20، و`total_step` يساوي 100. نقضي 10 خطوات في التدريب المسبق دون تقليل للرتبة لأن ميزانيتنا ثابتة (مرحلة init)، ثم نقضي 80 (100-20) خطوة في مرحلة التقليل حيث تنخفض ميزانيتنا تدريجياً خطوة بخطوة، وأخيراً 20 خطوة في مرحلة الضبط الدقيق النهائي دون تقليل.

## AdaLoraModel[[peft.AdaLoraModel]]

#### peft.AdaLoraModel[[peft.AdaLoraModel]]

```python
peft.AdaLoraModel(model, config, adapter_name, **kwargs)
```

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

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

model ([transformers.PreTrainedModel](https://huggingface.co/docs/transformers/main/en/main_classes/model#transformers.PreTrainedModel)) : النموذج الذي سيتم تكييفه.

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

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

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

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

نموذج AdaLora.

ينشئ نموذج AdaLoRA (LoRA التكيفي) من نموذج transformers مُدرَّب مسبقًا. الورقة البحثية: https://openreview.net/forum?id=lq62uWRJjiY

مثال:
```py
>>> from transformers import AutoModelForSeq2SeqLM
>>> from peft import AdaLoraConfig, get_peft_model

>>> config = AdaLoraConfig(
...     peft_type="ADALORA",
...     task_type="SEQ_2_SEQ_LM",
...     init_r=12,
...     lora_alpha=32,
...     target_modules=["q", "v"],
...     lora_dropout=0.01,
...     total_step=1000,
... )
>>> model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
>>> adalora_model = get_peft_model(model, config)
```

**الخصائص**:
- **النموذج** ([transformers.PreTrainedModel](https://huggingface.co/docs/transformers/main/en/main_classes/model#transformers.PreTrainedModel)) -- النموذج الذي سيتم تكييفه.
- **peft_config** ([AdaLoraConfig](/docs/peft/main/ar/package_reference/adalora#peft.AdaLoraConfig)): إعدادات نموذج AdaLora.

#### add_weighted_adapter[[peft.AdaLoraModel.add_weighted_adapter]]

```python
add_weighted_adapter(*args, **kwargs)
```

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

لا تدعم هذه الطريقة AdaLoRA، استخدم LoRA بدلاً منها.

#### update_and_allocate[[peft.AdaLoraModel.update_and_allocate]]

```python
update_and_allocate(global_step)
```

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

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

global_step (`int`) : خطوة التدريب الحالية، تُستخدم لحساب ميزانية adalora.

تحديث هذه الطريقة ميزانية Adalora والقناع.

يجب استدعاء هذا في كل خطوة تدريب بعد `loss.backward()` وقبل `zero_grad()`.

يتم التعامل مع `tinit` و`tfinal` و`deltaT` داخل الطريقة.

مثال:

```python
>>> loss = model(**input).loss
>>> loss.backward()
>>> optimizer.step()
>>> model.base_model.update_and_allocate(i_step)
>>> optimizer.zero_grad()
```

