# LoRA

> [!TIP]
> تُعد LoRA واحدة من أكثر طرق PEFT شيوعًا، وهي نقطة انطلاق جيدة إذا كنت تبدأ للتو في استخدام PEFT. تم تطويرها في الأصل للنماذج اللغوية الكبيرة، لكنها أصبحت طريقة تدريب شائعة للغاية لنماذج الانتشار (diffusion models) نظرًا لكفاءتها وفعاليتها.

التكيّف منخفض الرتبة ([LoRA](https://huggingface.co/papers/2106.09685)) هو أسلوب PEFT يقوم بتفكيك مصفوفة كبيرة إلى مصفوفتين أصغر منخفضتي الرتبة. وهذا يقلل بشكل كبير عدد المعلمات التي تحتاج إلى ضبط دقيق.

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

*يتألف نموذج مهم في معالجة اللغة الطبيعية من التدريب المسبق على نطاق واسع على بيانات عامة، ثم التكيّف مع مهام أو مجالات محددة. ومع تدريب نماذج أكبر حجمًا، يصبح الضبط الدقيق الكامل، الذي يعيد تدريب جميع معاملات النموذج، أقل قابلية للتطبيق. فباستخدام GPT-3 175B كمثال، فإن نشر نسخ مستقلة من النماذج المضبوطة بدقة، حيث تحتوي كل نسخة على 175 مليار معامل، مكلف للغاية. نقترح هنا التكيف منخفض الرتبة، أو LoRA، الذي يجمّد أوزان النموذج المدرَّب مسبقًا ويحقن مصفوفات تحليل رتبة قابلة للتدريب في كل طبقة من بنية Transformer، مما يقلل بشكل كبير عدد المعاملات القابلة للتدريب للمهام اللاحقة. مقارنةً بضبط GPT-3 175B بدقة باستخدام Adam، يمكن لـ LoRA تقليل عدد المعاملات القابلة للتدريب بمقدار 10,000 مرة، وتقليل متطلبات ذاكرة GPU بمقدار 3 مرات. يؤدي LoRA إلى جودة نموذج مماثلة أو أفضل من الضبط الدقيق على RoBERTa وDeBERTa وGPT-2 وGPT-3، على الرغم من امتلاكه عددًا أقل من المعاملات القابلة للتدريب، ومعدل إنتاجية تدريب أعلى، وبدون أي تأخير إضافي في الاستدلال، على عكس المحوِّلات. كما نقدم دراسة تجريبية حول نقص الرتبة في تكيّف نماذج اللغة، مما يسلّط الضوء على فعالية LoRA. ننشر حزمة تسهّل دمج LoRA مع نماذج PyTorch، ونوفر تطبيقاتنا ونقاط فحص النماذج لـ RoBERTa وDeBERTa وGPT-2 في [هذا الرابط](https://github.com/microsoft/LoRA).*

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

    

تتميز هذه الطريقة بعدد من المزايا:

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

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

يمكنك تهيئة المصفوفات منخفضة الرتبة مع وضع استخدامات مختلفة في الاعتبار - مثل الوعي بالمهمة (CorDA، EVA، Astra)، والتقارب الأسرع (PiSSA)، والتخفيف من آثار التكميم (LoftQ) - وذلك على سبيل المثال لا الحصر. اقرأ عن التهيئات المختلفة [فيما يلي](#initialization). التهيئة الافتراضية هي أن يكون LoRA عملية لا شيء (no-op)، ليتعلم سلوكًا جديدًا تدريجيًا دون التدخل كثيرًا في النموذج الموجود.

## الاستخدام

يُحدَّد حجم مصفوفات التحديث منخفضة الرتبة بواسطة *الرتبة* أو `r`. تعني الرتبة الأعلى أن النموذج يمتلك مزيدًا من المعاملات للتدريب، لكنها تعني أيضًا أن النموذج يتمتع بسعة تعلم أكبر. في المثال التالي، ستستهدف مصفوفات *الاستعلام* و*القيمة* في كتل الانتباه. من بين المعاملات المهمة الأخرى التي يجب ضبطها: `lora_alpha` (عامل التوسع)، و`bias` (ما إذا كان يجب تدريب `none` أو `all` أو معاملات انحياز LoRA فقط)، و`modules_to_save` (الوحدات التي يجب تدريبها وحفظها بخلاف طبقات LoRA). جميع هذه المعاملات - وغيرها - موجودة في [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig).

```py
from peft import LoraConfig, get_peft_model

config = LoraConfig(
    r=16,
    lora_alpha=16,
    target_modules=["query", "value"],
    lora_dropout=0.1,
    bias="none",
    modules_to_save=["classifier"],
)
model = get_peft_model(model, config)
model.print_healthcheck()
```

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

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

## التهيئة

يتم التحكم في تهيئة أوزان LoRA عبر المعامل `init_lora_weights` في [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig). افتراضياً، يهيّئ PEFT أوزان LoRA باستخدام Kaiming-uniform للوزن A وقيم صفرية للوزن B، مما يؤدي إلى تحويل هوية (identity transform) (نفس [التنفيذ](https://github.com/microsoft/LoRA) المرجعي).

لطبقات `transformers.Conv1D`، مثل الإسقاطات في GPT-2، استخدم `fan_in_fan_out=True` لأن أوزانها مخزنة على شكل `(in_features, out_features)` بدلاً من تخطيط `nn.Linear`. تستخدم مبادئات التهيئة القائمة على الأوزان المدعومة تخطيط Linear للتحليل، ثم تستعيد تخطيط التخزين عند تحديث الأوزان الأساسية. كما يستخدم تحجيم `"stable"` في LoRA-GA بُعد الإخراج بغض النظر عن تخطيط التخزين.

كما يمكن تمرير `init_lora_weights="gaussian"`. وكما يوحي الاسم، يقوم هذا بتبديل الأوزان A باستخدام توزيع غاوسي والأصفار للوزن B (وهو الطريقة التي يستخدم بها [Diffusers](https://huggingface.co/docs/diffusers/index) تهيئة أوزان LoRA).

```py
from peft import LoraConfig

config = LoraConfig(init_lora_weights="gaussian", ...)
```

يوجد أيضًا خيار لتعيين `init_lora_weights=False` وهو مفيد لأغراض التصحيح واختبار الأخطاء. ينبغي أن يكون هذا هو الوقت الوحيد الذي تستخدم فيه هذا الخيار. عند اختيار هذا الخيار، يتم تهيئة أوزان LoRA بحيث لا تؤدي إلى *تحويل* هوية.

```py
from peft import LoraConfig

config = LoraConfig(init_lora_weights=False, ...)
```

[التكيّف منخفض الرتبة المُطبَّع (NoRA)](https://huggingface.co/papers/2608.31036) يُطبِّع مصفوفات الإسقاط الهابط في LoRA. يطبّق PEFT هذا التطبيع فقط عند التهيئة من خلال `init_lora_weights="nora"` في [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig): إذ يُطبِّع أعمدة وزن LoRA A المُهيَّأ عشوائيًا ويهيّئ وزن LoRA B إلى الصفر. تبقى المصفوفتان قابلتين للتدريب، وتُترك الأوزان الأساسية دون تغيير.

في طبقة خطية، يكون تحديث وزن المكيّف $\Delta W = sBA$، حيث يكون شكل $A$ `(r, in_features)`، وشكل $B$ `(out_features, r)`، و$s$ هو معامل تحجيم LoRA. يبدأ NoRA من وزن A العشوائي الذي أنشأته الطبقة الخطية LoRA، ثم يعيّر كل عمود عبر بُعد الرتبة:

$$ A_{:,j} \leftarrow \frac{A_{:,j}}{\max(\lVert A_{:,j} \rVert_2, 10^{-6})}, \qquad B \leftarrow 0. $$

بما أن B تساوي صفرًا، فإن تحديث أوزان المُكيّف يكون صفرًا قبل التدريب. مع `bias="none"` و`lora_bias=False`، يحافظ المُكيّف في البداية على مخرجات النموذج الأساسي. ولا يتطلب NoRA مجموعة بيانات معايرة أو تفكيكًا للأوزان.

> [!IMPORTANT]
> في حالة NoRA، الإعداد الموصى به هو أن يكون `lora_alpha` مساوياً لـ `r` (نسبة ألفا/الرتبة 1:1)، على سبيل المثال، `r=8, lora_alpha=8`. مع الإعداد الافتراضي `use_rslora=False`، يبقى معامل التوسعة عند 1؛ أما عند تفعيل LoRA المستقر الرتبة فيتحول إلى `lora_alpha / sqrt(r)`.

يطبّق المثال التالي NoRA على طبقتين خطيتين في نموذج PyTorch صغير:

```py
from torch import nn

from peft import LoraConfig, get_peft_model

model = nn.Sequential(
    nn.Linear(32, 32),
    nn.ReLU(),
    nn.Linear(32, 16),
)

config = LoraConfig(
    r=8,
    lora_alpha=8,
    target_modules=["0", "2"],
    init_lora_weights="nora",
    bias="none",
    lora_bias=False,
    use_rslora=False,
)
model = get_peft_model(model, config)
model.print_healthcheck()
```

لنموذج Transformers، اضبط `target_modules` على أسماء الطبقات الخطية التي تريد تكييفها، مثل `["q_proj", "v_proj"]` عندما تكون تلك الأسماء موجودة في النموذج.

يستخدم NoRA إعدادات LoRA الحالية، وواجهات برمجة التطبيقات للتدريب والحفظ والتحميل، لذا لا توجد فئة منفصلة باسم `NoraConfig` أو `NoraModel`. للاطلاع على واجهات برمجة التطبيقات المشتركة للإعداد والنموذج، راجع [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig) و [LoraModel](/docs/peft/main/ar/package_reference/lora#peft.LoraModel).

يدعم NoRA وحدات الهدف `torch.nn.Linear` أو معاملات `nn.Parameter` المُمررة مباشرةً عبر `target_parameters`. ولا يُدعم في طبقات التضمين أو طبقات الالتفاف وما شابه ذلك.

يُهيّئ [PiSSA](https://huggingface.co/papers/2404.02948) مُكيّف LoRA باستخدام القيم المفردة الرئيسية والمتجهات المفردة. تتيح هذه التعديلة البسيطة لـ PiSSA أن يتقارب بشكل أسرع من LoRA ويحقق في النهاية أداءً متفوقاً. علاوة على ذلك، يقلل PiSSA من خطأ التكميم مقارنةً بـ QLoRA، مما يؤدي إلى تحسينات إضافية.

اضبط طريقة التهيئة على "pissa"، وقد يستغرق تنفيذ SVD على النموذج المُدرَّب مسبقًا عدة دقائق:
```python
from peft import LoraConfig
config = LoraConfig(init_lora_weights="pissa", ...)
```
بديلًا عن ذلك، نفّذ SVD السريع، والذي يستغرق بضع ثوانٍ فقط. يحدد عدد التكرارات التوازن بين الخطأ وزمن الحساب:
```python
lora_config = LoraConfig(init_lora_weights="pissa_niter_[number of iters]", ...)
```
للحصول على تعليمات تفصيلية حول استخدام PiSSA، يرجى اتباع [هذه التعليمات](https://github.com/huggingface/peft/tree/main/examples/pissa_finetuning).

[MiCA](https://arxiv.org/abs/2604.01694) (Minor Component Adaptation) هو مكمل لـ PiSSA: بدلاً من التهيئة من المكونات المفردة *الرئيسية*، يستخدم MiCA المكونات *الثانوية*. تحديداً، مع `W = U Σ V^T`، يحدد MiCA `B = U[:, -r:]` (وهي المتجهات المفردة اليسرى الـ `r` المرتبطة بأصغر القيم المفردة) و `A = 0`. أثناء التدريب، يتم تحديث `A` فقط؛ بينما يُجمَّد `B`. الفكرة الكامنة وراء ذلك هي أن الاتجاهات المفردة الثانوية غير مستخدمة إلى حد كبير في المهمة المُسبقة التدريب، وبالتالي فهي توفر فضاءً فرعيًا أكثر "مرونة" لحقن معرفة جديدة مع الحفاظ على القدرات المُسبقة التدريب.

بما أن `A == 0` عند التهيئة، فإن مساهمة المُكيّف `B · A == 0` ويُحافظ على مخرجات النموذج بدقة في الخطوة 0 — فلا حاجة لطرح أي بقايا على الوزن الأساسي (على عكس PiSSA). وبما أن `A` هو الوحيد القابل للتدريب، فإن عدد المعاملات القابلة للتدريب المطابق لـ `r` يكون تقريبًا نصف عدد معاملات LoRA.

```python
from peft import LoraConfig
config = LoraConfig(init_lora_weights="mica", r=16, target_modules=["q_proj", "v_proj"], ...)
```

يدعم MiCA حاليًا وحدات الهدف `nn.Linear` و`nn.Embedding`. يجب أن يحقق الرتبة المختارة الشرط `r <= min(in_features, out_features)` لطبقات الخطية، والشرط `r <= min(num_embeddings, embedding_dim)` لطبقات التضمين. للاستخدام التفصيلي، راجع [هذه التعليمات](https://github.com/huggingface/peft/tree/main/examples/mica_finetuning).

يُعد MiCA مخصصًا بشكل رئيسي للاستمرارية في التدريب المسبق / التدريب المسبق المتكيف مع المجال. في هذا السياق، استخدم النموذج الأساسي، وليس نقطة تحقق مُعدّة للتعليمات أو الدردشة، لتهيئة SVD وتدريب MiCA. بعد التدريب، ادمج المُكيّف (adapter) في أوزان النموذج الأساسي، واستخدم النموذج الأساسي المُكيّف الناتج كنقطة انطلاق للتدريب اللاحق على التعليمات/الدردشة.

يبني [CorDA](https://huggingface.co/papers/2406.05223) محوِّلات LoRA الواعية بالمهمة من خلال تفكيك الأوزان الموجه حسب سياق المهمة النهائية المراد تعلُّمها (وضع المعاينة المسبقة للتعليمات، IPM) أو المعرفة العالمية المراد الحفاظ عليها (وضع الحفاظ على المعرفة، KPM). لا يحقق وضع KPM أداءً أفضل من LoRA في مهام الضبط الدقيق فحسب، بل يخفف أيضًا من النسيان الكارثي للمعرفة العالمية المُدرَّبة مسبقًا. وعندما لا يُعدّ الحفاظ على المعرفة المُدرَّبة مسبقًا مصدر قلق، يُفضَّل وضع IPM لأنه يمكنه تسريع التقارب بشكل أكبر وتعزيز أداء الضبط الدقيق.

يجب عليك ضبط طريقة التهيئة على "corda"، وتحديد وضع IPM أو KPM ومجموعة البيانات لجمع مصفوفات التغاير.

```py
@torch.no_grad()
def run_model():
    # Assume `model` and `dataset` is in context...
    model.eval()
    for batch in dataset:
        model(**batch)

corda_config = CordaConfig(
    corda_method="kpm",
)
lora_config = LoraConfig(
    init_lora_weights="corda",
    corda_config=corda_config,
)
preprocess_corda(model, lora_config, run_model=run_model)
peft_model = get_peft_model(model, lora_config)
```

للحصول على تعليمات تفصيلية حول استخدام CorDA، يرجى اتباع [هذه التعليمات](https://github.com/huggingface/peft/tree/main/examples/corda_finetuning).

يُنشئ [Astra](https://huggingface.co/papers/2602.19111) محولات LoRA الواعية بالمهمة من متجهات الذاتية النهائية لمصفوفة التغاير لتفعيلات إخراج الوحدة، وذلك عبر تقديرها من مجموعة معايرة صغيرة للمهمة النهائية. يتم إسقاط الوزن المُدرَّب مسبقًا على الفضاء الجزئي الذي يولّده متجهات الذاتية النهائية لمبادرة المحول، مما يُقيّد التحديث على الفضاء الجزئي للتفعيلات الأكثر صلة بالمهمة النهائية ويسرّع من التقارب.

يجب عليك ضبط طريقة التهيئة على "astra"، وإعداد `target_modules` بشكل صريح، وتوفير مجموعة بيانات المعايرة لجمع مصفوفات التغاير.

```py
@torch.no_grad()
def run_model():
    # Assume `model` and `dataset` is in context...
    model.eval()
    for batch in dataset:
        model(**batch)

from peft.tuners.lora import AstraConfig, preprocess_astra

astra_config = AstraConfig()
lora_config = LoraConfig(
    init_lora_weights="astra",
    target_modules=["q_proj", "v_proj"],
    astra_config=astra_config,
)
preprocess_astra(model, lora_config, run_model=run_model)
peft_model = get_peft_model(model, lora_config)
```

للحصول على تعليمات تفصيلية حول استخدام Astra، يرجى اتباع [هذه التعليمات](https://github.com/huggingface/peft/tree/main/examples/astra_finetuning).

يعتمد [OLoRA](https://huggingface.co/papers/2406.01775) على تحليل QR لمبادِئ مُكيّفات LoRA. يقوم OLoRA بإزاحة الأوزان الأساسية للنموذج بمعامل تحليلاتها من نوع QR، أي أنه يعدّل الأوزان قبل إجراء أي تدريب عليها. تحسّن هذه الطريقة الاستقرار بشكل كبير، وتسرّع من سرعة التقارب، وتتحقق في النهاية من أداء متفوق.

كل ما عليك هو تمرير خيار إضافي واحد لاستخدام OLoRA:
```python
from peft import LoraConfig
config = LoraConfig(init_lora_weights="olora", ...)
```
للاستخدام الأكثر تقدماً، يُرجى الرجوع إلى [التوثيق](https://github.com/huggingface/peft/tree/main/examples/olora_finetuning) الخاص بنا.

يُجري [EVA](https://huggingface.co/papers/2410.07170) تحليل القيم المفردة (SVD) على تنشيطات الإدخال لكل طبقة، ويستخدم المتجهات المفردة اليمنى لتبديل أوزان LoRA. وبالتالي، فهو مخطط تهيئة يعتمد على البيانات. علاوة على ذلك، يوزّع EVA الرتب بين الطبقات بشكل تكيفي بناءً على "نسبة التباين المفسَّر" - وهي مقياس مشتق من تحليل SVD.

يمكنك استخدام EVA عن طريق تعيين `init_lora_weights="eva"` وتعريف [EvaConfig](/docs/peft/main/ar/package_reference/lora#peft.EvaConfig) في [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig):
```python
from peft import LoraConfig, EvaConfig
peft_config = LoraConfig(
    init_lora_weights = "eva",
    eva_config = EvaConfig(rho = 2.0),
    ...
)
```
يحدد المعامل `rho` (≥ 1.0) مقدار إعادة التوزيع المسموح به. عند `rho=1.0` و`r=16`، تكون محولات LoRA مقيدة بـ 16 رتبة بالضبط، مما يمنع حدوث أي إعادة توزيع. القيمة الموصى بها لـ EVA مع إعادة التوزيع هي 2.0، مما يعني أن الحد الأقصى للرتبة المسموح بها لطبقة هو 2r.

يُوصى بإجراء تهيئة EVA على مُسرِّع (مثل بطاقة CUDA GPU أو Intel XPU) نظراً لسرعتها الفائقة. ولتحسين كمية الذاكرة المتاحة لـ EVA، يمكنك استخدام علم `low_cpu_mem_usage` في [get_peft_model()](/docs/peft/main/ar/package_reference/peft_model#peft.get_peft_model):
```python
peft_model = get_peft_model(model, peft_config, low_cpu_mem_usage=True)
```
ثم، استدعِ [initialize_lora_eva_weights()](/docs/peft/main/ar/package_reference/lora#peft.initialize_lora_eva_weights) لموازنة أوزان EVA (في معظم الحالات، يمكن أن يكون مُحمِّل البيانات المستخدم لموازنة eva هو نفسه المستخدم للتدريب الدقيق):
```python
initialize_lora_eva_weights(peft_model, dataloader)
```
يعمل EVA مع bitsandbytes دون أي إعداد مسبق. ما عليك سوى تهيئة النموذج باستخدام `quantization_config` ثم استدعاء [initialize_lora_eva_weights()](/docs/peft/main/ar/package_reference/lora#peft.initialize_lora_eva_weights) كما هو معتاد.

> [!TIP]
> لمزيد من التعليمات حول استخدام EVA، يُرجى الرجوع إلى [التوثيق](https://github.com/huggingface/peft/tree/main/examples/eva_finetuning) الخاص بنا.

عند تكميم النموذج الأساسي لتدريب QLoRA، يُنصح باستخدام [تهيئة LoftQ](https://huggingface.co/papers/2310.08659)، حيث تبيّن أنها تحسّن الأداء عند تدريب النماذج المكمّمة. الفكرة هي أن أوزان LoRA تُهيّأ بحيث يُقلَّل خطأ التكميم إلى أدنى حد. لاستخدام LoftQ، اتبع [هذه التعليمات](https://github.com/huggingface/peft/tree/main/examples/loftq_finetuning).

> [!TIP]
> تعرّف على المزيد حول كيفية عمل PEFT مع التكميم وكيفية استخدام LoftQ في دليل [التكميم](../developer_guides/quantization).

طريقة أخرى لتهيئة [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig) هي استخدام طريقة [rank-stabilized LoRA (rsLoRA)](https://huggingface.co/papers/2312.03732). تقوم بنية LoRA بمضاعفة كل مُكيّف (adapter) خلال كل تمريرة أمامية (forward pass) بواسطة عدد قياسي ثابت يُضبط عند التهيئة ويعتمد على الرتبة `r`. يُعطى هذا العدد القياسي بواسطة `lora_alpha/r` في التنفيذ الأصلي، بينما يستخدم rsLoRA `lora_alpha/math.sqrt(r)` مما يُثبّت المُكيّفات ويزيد من إمكانات الأداء الناتجة عن استخدام قيمة أعلى لـ `r`.

```py
from peft import LoraConfig

config = LoraConfig(use_rslora=True, ...)
```

يبدأ [LoRA-GA](https://hf.co/papers/2407.05000) (التكيّف منخفض الرتبة مع تقريب التدرجات) أوزان المُكيِّف من خلال إجراء تحليل القيم المفردة (SVD) على التدرجات المقدّرة، بحيث تكون الأوزان أقرب إلى التكيّف الكامل (full-finetuning) لتحقيق تقارب أسرع.

يتطلب هذا الأسلوب دالة تهيئة لتقدير التدرجات قبل بدء التدريب الفعلي:

```python
from peft.tuners.lora import preprocess_loraga

def train_step():
    """Run forward and backward passes for gradient estimation."""
    dataloader_iter = iter(grad_dataloader)
    for _ in range(N):
        batch = next(dataloader_iter)
        batch = {k: v.to(device) for k, v in batch.items()}
        outputs = model(**batch)
        loss = outputs.loss
        loss.backward()

preprocess_loraga(model, lora_config, train_step)
```

**نصائح للاستخدام**

- **تقدير التدرّج**: تتطلب LoRA-GA مرحلة لتقدير التدرّج قبل تهيئة النموذج. استخدم `preprocess_loraga()` مع استدعاء `train_step` لحساب التدرّجات على عدد صغير من دفعات التدريب (عادةً 64-128 دفعة).

- **استراتيجيات التهيئة**: يدعم LoRA-GA أربع استراتيجيات اتجاه (`direction`): `"ArBr"`، `"A2rBr"`، `"ArB2r"` (الافتراضي)، و`"random"`، وأربع استراتيجيات تحجيم (`scale`): `"stable"` (الافتراضي)، `"weight_svd"`، `"gd_scale"`، و`"unit"`. يوفر التركيب الافتراضي أفضل توازن بين سرعة التقارب والاستقرار.

- **تعديل أوزان النموذج الأساسي**: على عكس LoRA القياسي، يعدّل LoRA-GA أوزان النموذج الأساسي أثناء التهيئة عن طريق طرح نسخة مُقيّمة من التقريب منخفض الرتبة. وهذا يتيح توافقًا أفضل مع تدرّجات الضبط الكامل. وبما أن أوزان النموذج الأساسي تُعدَّل، استخدم `save_pretrained()` مع الحجة `save_embedding_layers` أو مرّر `path_initial_model_for_weight_conversion`.

- **العبء الحسابي**: تُضيف عملية تقدير التدرّج عبئًا صغيرًا أثناء التهيئة (عادةً من 1 إلى 2 دقيقة لـ 64 دفعة)، لكن هذا العبء يُمتصّ بسرعة بفضل التقارب الأسرع أثناء التدريب.

- **التوافق**: يتطلب LoRA-GA أوزانًا بدقة كاملة ولا يدعم النماذج المُكمّاة. يمكن دمجه مع متغيرات LoRA الأخرى مثل DoRA.

## التدريب

تُظهر هذه القسم كيفية التعامل مع سيناريوهات تدريب أكثر تعقيدًا، بدلاً من مجرد تطبيق مُكيّف منخفض الرتبة على النموذج وإمداده بالبيانات.

### التدريب بأسلوب QLoRA

تضيف إعدادات LoRA الافتراضية في PEFT أوزانًا قابلة للتدريب إلى طبقات الاستعلام والقيمة في كل كتلة انتباه. لكن [QLoRA](https://hf.co/papers/2305.14314)، الذي يضيف أوزانًا قابلة للتدريب إلى جميع الطبقات الخطية في نموذج الترانسفورمر، يمكن أن يوفر أداءً مساويًا لنموذج مُعاد تدريبه بالكامل. لتطبيق LoRA على جميع الطبقات الخطية، كما في QLoRA، اضبط `target_modules="all-linear"` (وهو أسهل من تحديد الوحدات الفردية بالاسم، والتي قد تختلف اعتمادًا على البنية).

```py
config = LoraConfig(target_modules="all-linear", ...)
```

لمزيد من المعلومات حول كيفية تطبيق التكميم على محولات PEFT، يُرجى الرجوع إلى [دليل التكميم](../developer_guides/quantization).

### نسخ الطبقات بكفاءة في الذاكرة باستخدام LoRA

من الأساليب المستخدمة لتحسين أداء النماذج توسيع نموذج عن طريق تكرار طبقاته لبناء نموذج أكبر انطلاقًا من نموذج مُدرَّب مسبقًا بحجم محدد. على سبيل المثال، زيادة نموذج بحجم 7B ليصبح 10B كما هو موصوف في ورقة [SOLAR](https://huggingface.co/papers/2312.15166). يدعم PEFT LoRA هذا النوع من التوسيع بطريقة فعّالة من حيث الذاكرة، وتتيح إمكانية إجراء ضبط دقيق إضافي باستخدام محولات LoRA المربوطة بالطبقات بعد تكرارها. لا تستهلك الطبقات المكررة ذاكرة إضافية لأنها تتشارك الأوزان الأساسية، لذا فإن الذاكرة الإضافية المطلوبة هي فقط ذاكرة أوزان المحولات. لاستخدام هذه الميزة، أنشئ إعدادًا يحتوي على الحجة `layer_replication`.

```py
config = LoraConfig(layer_replication=[[0,4], [2,5]], ...)
```

بافتراض أن النموذج الأصلي كان يحتوي على 5 طبقات `[0, 1, 2 ,3, 4]`، فإن هذا سيؤدي إلى إنشاء نموذج يحتوي على 7 طبقات مرتبة على النحو التالي `[0, 1, 2, 3, 2, 3, 4]`. يتبع هذا أسلوب الدمج المار عبر [mergekit](https://github.com/arcee-ai/mergekit) حيث تُرصّ تسلسلات الطبقات المحددة كسلاسل تبدأ من قيمة شاملة وتنتهي بقيمة حصرية لبناء النموذج النهائي. تحصل كل طبقة في النموذج النهائي على مجموعة مميزة من محولات LoRA.

[Fewshot-Metamath-OrcaVicuna-Mistral-10B](https://huggingface.co/abacusai/Fewshot-Metamath-OrcaVicuna-Mistral-10B) هو مثال على نموذج تم تدريبه باستخدام هذه الطريقة على Mistral-7B الموسّع إلى 10B. يُظهر [adapter_config.json](https://huggingface.co/abacusai/Fewshot-Metamath-OrcaVicuna-Mistral-10B/blob/main/adapter_config.json) إعدادًا نموذجيًا لمُكيّف LoRA يطبّق هذه الطريقة للضبط الدقيق.

### تحكم دقيق في الرتب وألفا (المقياس)

بشكل افتراضي، ستتمتع جميع الطبقات المستهدفة بواسطة LoRA بنفس الرتبة `r` ونفس قيمة `lora_alpha` (والتي تحدد مقياس LoRA)، وذلك تبعاً لما تم تحديده في [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig). ومع ذلك، قد ترغب في بعض الحالات في تحديد قيم مختلفة لطبقات مختلفة. وهذا ممكن عن طريق تمرير الحججين `rank_pattern` و`alpha_pattern` إلى [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig). يجب أن تكون هذه الحجج قواميس يكون المفتاح فيها اسم الطبقة والقيمة فيها قيمة الرتبة/ألفا. يمكن أن تكون المفاتيح [تعبيرات منتظمة](https://docs.python.org/3/library/re.html) (regex). وستتخذ جميع طبقات LoRA التي لم يتم ذكرها صراحةً في `rank_pattern` و`alpha_pattern` قيم `r` و`lora_alpha` الافتراضية.

لإعطاء مثال، لنفترض أن لدينا نموذجاً له البنية التالية:

```python
>>> print(model)
Outer(
  (foo): Linear(...)
  (module): Middle(
    (foo): Linear(...)
    (foobar): Linear(...)
    (module): Inner(
      (foo): Linear(...)
      (barfoo): Linear(...)
    )
  )
)
```

- `rank_pattern={"foo": 42}` سيُطابق جميع طبقات `foo` الثلاث. ولا يُطابق أيٌّ من `foobar` أو `barfoo`.
- `rank_pattern={"^foo": 42}` سيُطابق طبقة `foo` في النموذج فقط، لكنه لن يطابق `module.foo` أو `module.module.foo`. والسبب في ذلك أن `^` تعني "بداية السلسلة" عند استخدام التعبيرات النمطية، ولا تبدأ سوى `foo` بـ `"foo"`، بينما تحمل أسماء الطبقات الأخرى بادئات.
- `rank_pattern={"^module.foo": 42}` يطابق `module.foo` فقط، لكنه لا يطابق `module.module.foo`، لنفس السبب.
- `rank_pattern={"module.foo": 42}` يطابق كلًا من `module.foo` و`module.module.foo`، لكنه لا يطابق `foo`.
- يطابق `rank_pattern={"^foo": 42, "^module.module.foo": 55}` `foo` و`module.module.foo` على التوالي، لكنه لا يطابق `module.foo`.
- لا حاجة إلى تحديد `$` لتمييز نهاية التطابق، حيث يضيف PEFT ذلك تلقائيًا.

تنطبق المنطقية نفسها على `alpha_pattern`. إذا كنت متردداً، فلا تحاول استخدام تعبيرات منتظمة معقدة -- بل مرر الاسم الكامل لكل وحدة ذات رتبة/ألفا مختلفة، مع وضع بادئة `^` قبله، وستكون النتيجة جيدة.

### كشف الوحدات المستهدفة القابلة للتطبيق تلقائيًا

يُنفّذ [peft.helpers.KappaTuneSelector](/docs/peft/main/ar/package_reference/helpers#peft.helpers.KappaTuneSelector) استراتيجية اختيار الأهداف القائمة على عدد الشرط (condition number) الواردة في [ورقة KappaTune](https://arxiv.org/abs/2506.16289). يقوم بفحص كل وحدة `nn.Linear`، وللموديلات التي تُخزَّن فيها أوزان خبراء MoE كمُتجهات `nn.Parameter` ثلاثية الأبعاد مدمجة (مثل Llama-4 وQwen3-MoE)، يفحص تلك المعاملات أيضاً، ويحسب عدد شرط المصفوفة κ = σ_max / σ_min لكل منها، ثم يختار الطبقات الأكثر أيزوتروبياً (أقل قيمة لـ κ). تعمل هذه الطبقات الأيزوتروبية كمرشحات مثالية للضبط الدقيق، لأن طبيعتها عالية الإنتروبيا تتيح لها امتصاص المعلومات الجديدة بسهولة أكبر، مع إبقاء الطبقات المتخصصة غير الأيزوتروبية كما هي للتخفيف من النسيان الكارثي أثناء التعلم المستمر.

استخدم [peft.helpers.find_kappa_target_modules()](/docs/peft/main/ar/package_reference/helpers#peft.find_kappa_target_modules) كسطر واحد للحصول على `target_modules` المثالية لـ `LoraConfig`:

```python
from peft import LoraConfig, get_peft_model
from peft.helpers import find_kappa_target_modules

model = AutoModelForCausalLM.from_pretrained("mistralai/Mixtral-8x7B-Instruct-v0.1")

targets = find_kappa_target_modules(model, top_p=0.2)
config = LoraConfig(
    target_modules=targets["target_modules"],
    target_parameters=targets["target_parameters"] if stable_modules_dic["target_parameters"] else None,
    r=64,
    lora_alpha=32,
    task_type="CAUSAL_LM",
)
peft_model = get_peft_model(model, config)
```

راجع مثالًا كاملًا [هنا](https://github.com/huggingface/peft/blob/main/examples/KappaTune/experiments_kappatune_peft.py).

### استهداف `nn.Parameter` مباشرة

بشكل عام، ينبغي استخدام `target_modules` لاستهداف الوحدة (مثل `nn.Linear`). ومع ذلك، في بعض الظروف، لا يكون ذلك ممكناً. على سبيل المثال، في العديد من طبقات خليط الخبراء (MoE) في HF Transformers، يتم استخدام `nn.Parameter` بدلاً من `nn.Linear`. عادةً ما يعيد PEFT كتابة طريقة `forward` الخاصة بـ LoRA، لكن في حالة `nn.Parameter`، لا توجد طريقة من هذا النوع. لذلك، لتطبيق LoRA على ذلك المعامل، يجب استهدافه باستخدام `target_parameters`. كمثال، بالنسبة إلى [Llama4](https://huggingface.co/collections/meta-llama/llama-4-67f0c30d9fe03840bc9d0164)، يمكنك تمرير: `target_parameters=['feed_forward.experts.gate_up_proj', 'feed_forward.experts.down_proj]`.

لاحظ أنه عند استهداف معاملات الخبراء، يمكن أن يضيف PEFT عبئًا تشغيليًا كبيرًا. والسبب في ذلك أن PEFT يُنشئ دائمًا مساهمة LoRA لكل _خبير_ حتى لو كان عدد الخبراء المطلوب صغيرًا. أثناء التدريب، يكون هذا الأمر أقل أهمية، لأن نسبة كبيرة من الخبراء تُفعَّل عادةً مرة واحدة على الأقل على مدار التسلسل. ومع ذلك، أثناء الاستدلال، يُستخدم عادةً ذاكرة KV، وبالتالي نحتاج إلى حساب الرمز الأخير فقط، مما يعني أن عددًا صغيرًا من الخبراء فقط يُفعَّل. لذلك، يمكن أن يؤدي استخدام LoRA على طبقات MoE إلى تباطؤ كبير في وقت الاستدلال. لذا، يُوصى بدمج الأوزان (`model.merge_adapter()` أو `model = model.merge_and_unload()`). وهذا يُزيل عبء PEFT.

يمكن العثور على تحقيق أكثر تفصيلاً في هذه المسألة في [طلب الدمج هذا الخاص بتحسين MoE](https://github.com/huggingface/peft/pull/3139).

#### ملاحظات

- حاليًا، يسمح هذا الحُجج باستهداف معاملات `nn.Parameter` ثنائية الأبعاد أو ثلاثية الأبعاد. ويُفترض أنه في حالة المعامل ثلاثي الأبعاد، فإن البُعد صفر هو بُعد الخبير.
- تُؤيَّد عدة محوِّلات LoRA (المُضافة عبر `model.add_adapter` أو `model.load_adapter`) التي تستخدم `target_parameters`، لكن يجب أن تستهدف جميعها نفس مجموعة المعاملات.

#### معاملات خبراء MoE وvLLM

تخزّن بعض نماذج MoE في Transformers أوزان الخبراء كمُتجهات `nn.Parameter` (غالبًا ثلاثية الأبعاد)، وليس كوحَدات `nn.Linear`. لتطبيق LoRA على تلك الخبراء، استخدم `target_parameters` واضبط رتبة لكل طبقة باستخدام `rank_pattern`:

```python
num_experts = getattr(model.config, "num_local_experts", None) or model.config.num_experts
effective_r = max(1, r // num_experts)
config = LoraConfig(
    r=r,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],
    target_parameters=[
        # Mixtral / Qwen3-MoE / GPT-OSS
        "mlp.experts.gate_up_proj",
        "mlp.experts.down_proj",
        # Llama4
        # "feed_forward.experts.gate_up_proj",
        # "feed_forward.experts.down_proj",
    ],
    rank_pattern={
        "experts.gate_up_proj": effective_r,
        "experts.down_proj": effective_r,
    },
)
```

يُبقي هذا الميزانية الإجمالية لمعاملات LoRA مماثلة لطبقات الكثافة (انظر [LoRA Without Regret](https://thinkingmachines.ai/blog/lora/) من Schulman وآخرون). وتستخدم وحدات غير الخبراء الترتيب الافتراضي `r`.

يمكن إجراء الاستدلال المُسرَّع باستخدام النموذج المُحسَّن، على سبيل المثال، عبر [vLLM](https://vllm.ai/) الذي يدعم طبقات خبراء MoE المدمجة منذ الإصدار v0.11.2.

### تدريب الرموز بكفاءة إلى جانب LoRA

تدعم محولات PEFT LoRA إضافة رموز جديدة عبر المعامل `trainable_token_indices`. وهذا يتيح ضبط رموز أخرى بالتوازي مع ضبط طبقات محددة. يتم تدريب الرموز المحددة فقط بينما تبقى جميع الرموز الأخرى دون تغيير. يوفر هذا الأسلوب الذاكرة ولا يتخلص من السياق المكتسب من تمثيلات الرموز الموجودة، على عكس تدريب مصفوفة التمثيل بأكملها. يستخدم هذا الأسلوب داخليًا طبقة [TrainableTokensModel](/docs/peft/main/ar/package_reference/trainable_tokens#peft.TrainableTokensModel).

```py
# for layer 'embed_tokens'
config = LoraConfig(trainable_token_indices=[idx_1, idx_2, ...], ...)

# specific embedding layer
config = LoraConfig(trainable_token_indices={'emb_tokens': [idx_1, idx_2, ...]}, ...)
```

في المقطع أدناه، نُظهر كيفية إضافة رموز جديدة إلى النموذج وكيفية تدريبه جنبًا إلى جنب مع الطبقات الأخرى في النموذج.

```py
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import get_peft_model, LoraConfig

base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")

# we define our new tokens and add them to the tokenizer as special tokens
special_tokens = ['<|start_think|>', '<|stop_think|>']
tokenizer.add_special_tokens({'additional_special_tokens': special_tokens})

# make room for new tokens in the embedding matrix if it isn't big enough already
base_model.resize_token_embeddings(max(len(tokenizer), base_model.model.embed_tokens.num_embeddings))

# typical LoRA config with `trainable_token_indices` targeting embedding layer `embed_tokens`
# and specifically our new tokens we just added
lora_config = LoraConfig(
    target_modules='all-linear',
    trainable_token_indices={'embed_tokens': tokenizer.convert_tokens_to_ids(special_tokens)},
)
peft_model = get_peft_model(base_model, lora_config)

# proceed to train the model like normal
[...]
```

تُحفظ أوزان الرموز كجزء من حالة القاموس (state dict) الخاص بالمُكيّف (adapter) إلى جانب أوزان LoRA. كان التدريب الكامل (Full fine-tuning) وحفظ مصفوفة التضمين (embedding matrix) سيؤديان إلى تخزين ملف أكبر بكثير.

لإعطاء فكرة تقريبية عن مقدار ذاكرة VRAM التي يمكن توفيرها، أُجري مقارنة أولية على المثال أعلاه بين تدريب مصفوفة التضمين بالكامل (`modules_to_save=["embed_tokens"]`)، واستخدام LoRA لمصفوفة التضمين (`target_modules=[..., "embed_tokens"]`، رتبة 32) والرموز القابلة للتدريب (`trainable_token_indices=[...]`، 6 رموز):

|           | رموز قابلة للتدريب |       LoRA | الضبط الدقيق الكامل |
| --------: | :--------------: | :--------: | :--------------: |
| VRAM      |        15,562 ميغابايت |   15,581ميغابايت |     ~16,500ميغابايت    |
| التأثير |         6 رموز | جميع الرموز |       جميع الرموز |

### ربط الأوزان

تستخدم العديد من نماذج اللغة السببية **ربط الأوزان**، حيث تتشارك وزنتان أو أكثر في نفس المعلمات الأساسية. في الحالة الأكثر شيوعاً، تتشارك أوزان التضمين المدخل (`embed_tokens`) وأوزان الإسقاط المخرج (`lm_head`) في نفس المصفوفة. والسبب في ذلك هو أنه يقلل من عدد المعلمات ويحافظ عادةً على جودة النموذج.

ليس من الواضح دائمًا كيف يتعامل PEFT مع هذه الأوزان المرتبطة عندما تكون مستهدفة للضبط الدقيق. فيما يتعلق بـ LoRA، يتحكم `ensure_weight_tying` في [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig) فيما إذا كان ينبغي لـ PEFT الحفاظ صراحةً على ارتباط تحديثات جانب المُكيّف (adapter) لتلك الطبقات. عمليًا، يمكن أن يؤثر ذلك على `modules_to_save` و`target_modules` و`trainable_token_indices`. لاحظ أن هذه المنطقية تعتمد جزئيًا على العرف فيما يتعلق بتسمية الطبقات (`"embed_tokens"`، `"lm_head"`) ولا يمكن ضمان عمل صحيح إذا لم تُستخدم تلك الأعراف.

تلخص الجداول أدناه السلوك المتوقع.

#### `modules_to_save`

| أوزان النموذج الأساسي مترابطة | `ensure_weight_tying` | شكل `LoraConfig`                                  | السلوك                                                     |
|-------------------------|-----------------------|-----------------------------------------------------|--------------------------------------------------------------|
| لا                      | `False`               | `modules_to_save=["embed_tokens"]` أو `["lm_head"]` | أضف `ModulesToSaveWrapper` على طبقة محددة فقط            |
| لا                      | `True`                | `modules_to_save=["embed_tokens"]` أو `["lm_head"]` | تحذير، ثم أضف `ModulesToSaveWrapper` على الطبقة المحددة فقط |
| نعم                     | `False`               | `modules_to_save=["embed_tokens"]` أو `["lm_head"]` | اعتبرها منفصلة                                            |
| نعم                     | `True`                | `modules_to_save=["embed_tokens"]` أو `["lm_head"]` | تغليف الطبقات المرتبطة والحفاظ على ارتباط الأغلفة                      |
| لا                      | `False`               | `modules_to_save=["embed_tokens", "lm_head"]`       | اعتبرها منفصلة                                            |
| لا                      | `True`                | `modules_to_save=["embed_tokens", "lm_head"]`       | تحذير، ثم التعامل كعناصر منفصلة                                 |
| نعم                     | `False`               | `modules_to_save=["embed_tokens", "lm_head"]`       | تحذير، ثم التعامل كعناصر منفصلة                                            |
| نعم                     | `True`                | `modules_to_save=["embed_tokens", "lm_head"]`       | حافظ على ارتباط `ModulesToSaveWrapper`s                            |

#### `target_modules`

| أوزان النموذج الأساسي مترابطة | `ensure_weight_tying` | شكل `LoraConfig`                                 | السلوك                                   |
|-------------------------|-----------------------|----------------------------------------------------|--------------------------------------------|
| لا                      | `False`               | `target_modules=["embed_tokens"]` أو `["lm_head"]` | إضافة LoRA على طبقة محددة فقط            |
| لا                      | `True`                | `target_modules=["embed_tokens"]` أو `["lm_head"]` | تحذير، ثم أضف LoRA على الطبقة المحددة فقط |
| نعم                     | `False`               | `target_modules=["embed_tokens"]` أو `["lm_head"]` | اعتبرها منفصلة                          |
| نعم                     | `True`                | `target_modules=["embed_tokens"]` أو `["lm_head"]` | إبقاء مُكيّفات LoRA مربوطة                    |
| لا                      | `False`               | `target_modules=["embed_tokens", "lm_head"]`       | اعتبرها منفصلة                          |
| لا                      | `True`                | `target_modules=["embed_tokens", "lm_head"]`       | تحذير، ثم التعامل كعناصر منفصلة               |
| نعم                     | `False`               | `target_modules=["embed_tokens", "lm_head"]`       | تحذير، ثم التعامل كعناصر منفصلة                          |
| نعم                     | `True`                | `target_modules=["embed_tokens", "lm_head"]`       | إبقاء مُكيّفات LoRA مربوطة                    |

#### `trainable_token_indices`

بالنسبة للرموز القابلة للتدريب، لدينا تعقيد إضافي يتمثل في أنه حتى لو كانت رأس النموذج اللغوي والتضمينات مرتبطة ببعضها، فقد أريد كمستخدم ضبط *رموز مختلفة* عليها. لذلك، في الجدول أدناه، نميّز بين ضبط الرموز نفسها وضبط رموز مختلفة.

| أوزان النموذج الأساسي مترابطة | `ensure_weight_tying` | شكل `LoraConfig`                                                    | السلوك                                       |
|-------------------------|-----------------------|-----------------------------------------------------------------------|------------------------------------------------|
| لا                      | `False`               | `trainable_token_indices=[1, 2, 3]`                                   | الرموز القابلة للتدريب على التضمينات فقط            |
| لا                      | `True`                | `trainable_token_indices=[1, 2, 3]`                                   | تحذير، ثم الرموز القابلة للتدريب على التضمينات فقط |
| نعم                     | `False`               | `trainable_token_indices=[1, 2, 3]`                                   | رموز قابلة للتدريب مترابطة                          |
| نعم                     | `True`                | `trainable_token_indices=[1, 2, 3]`                                   | رموز قابلة للتدريب مترابطة                          |
| لا                      | `False`               | `trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [1, 2]}` | اعتبرها منفصلة                              |
| لا                      | `True`                | `trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [1, 2]}` | تحذير، ثم التعامل كعناصر منفصلة                   |
| نعم                     | `False`               | `trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [1, 2]}` | رموز قابلة للتدريب مترابطة                          |
| نعم                     | `True`                | `trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [1, 2]}` | رموز قابلة للتدريب مترابطة                          |
| لا                      | `False`               | `trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [3, 4]}` | اعتبرها منفصلة                              |
| لا                      | `True`                | `trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [3, 4]}` | تحذير، ثم التعامل كعناصر منفصلة                   |
| نعم                     | `False`               | `trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [3, 4]}` | اعتبرها منفصلة                              |
| نعم                     | `True`                | `trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [3, 4]}` | خطأ                                          |

بالنسبة للمستخدمين، يعني هذا:

- بشكل عام، إذا كنت ترغب في ضبط الأوزان المرتبطة مع الحفاظ على ارتباطها، فمرّر `ensure_weight_tying=True`.
- إذا كانت أوزان النموذج الأساسي غير مترابطة، فلا يمكن لـ`ensure_weight_tying=True` فرض الترابط، بل يُصدر تحذيرًا فقط.
- بالنسبة إلى `trainable_token_indices`، يجب أن تستخدم الطبقات المرتبطة نفس فهارس الرموز عندما يكون `ensure_weight_tying=True`.

## المحسّنات

يمكن أن يتضمن تدريب LoRA اختيارياً محسّنات (Optimizers) مخصصة لأغراض خاصة. حالياً، يدعم PEFT كل من LoRA-FA وLoRA+ وLoRA المُسبَق الشرطية ريمانياً (Riemannian-preconditioned LoRA).

### مُحسِّن LoRA-FA

يمكن أن يكون تدريب LoRA أكثر فعالية وكفاءة باستخدام LoRA-FA، كما هو موصوف في [LoRA-FA](https://huggingface.co/papers/2308.03303). يقلل LoRA-FA من استهلاك ذاكرة التفعيل عن طريق تثبيت المصفوفة A وضبط المصفوفة B فقط. أثناء التدريب، يتم تحسين تدرج B لتقريب تدرج الضبط الدقيق الكامل للمعاملات. علاوة على ذلك، لا يتأثر استهلاك الذاكرة في LoRA-FA بالرتبة (بما أنه يمحو تفعيل $A$)، وبالتالي يمكنه تحسين الأداء عن طريق زيادة رتبة lora دون زيادة استهلاك الذاكرة.

```py
from peft import LoraConfig, get_peft_model
from peft.optimizers import create_lorafa_optimizer
from transformers import Trainer, get_cosine_schedule_with_warmup

base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")

config = LoraConfig(...)
model = get_peft_model(base_model, config)

optimizer = create_lorafa_optimizer(
    model=model,
    r=128,
    lora_alpha=32,
    lr=7e-5,
)

scheduler = get_cosine_schedule_with_warmup(
    optimizer,
    num_warmup_steps=100,
    num_training_steps=1000,
)

trainer = Trainer(
    ...,
    optimizers=(optimizer, scheduler),
)
```

### LoRA+ المحسّن لـ LoRA

يمكن تحسين تدريب LoRA باستخدام [LoRA+](https://huggingface.co/papers/2402.12354)، الذي يستخدم معدلات تعلم مختلفة لمصفوفات المحوّل A و B، وقد ثبت أنه يزيد سرعة الضبط الدقيق حتى مرتين والأداء بنسبة 1-2%.

```py
from peft import LoraConfig, get_peft_model
from peft.optimizers import create_loraplus_optimizer
from transformers import Trainer
import bitsandbytes as bnb

base_model = ...
config = LoraConfig(...)
model = get_peft_model(base_model, config)

optimizer = create_loraplus_optimizer(
    model=model,
    optimizer_cls=bnb.optim.Adam8bit,
    lr=5e-5,
    loraplus_lr_ratio=16,
)
scheduler = None

...
trainer = Trainer(
    ...,
    optimizers=(optimizer, scheduler),
)
```

### LoRA المُسبَق الشرط بطريقة ريمان

يمكن تحسين تدريب LoRA باستخدام مُهيِّئ ريمانّي، كما هو موصوف في [Riemannian Preconditioned LoRA](https://huggingface.co/papers/2402.02347). في كل خطوة من خطوات المُحسِّن، تُضرب تدرّجات مصفوفات LoRA $A$ و $B$ في مُهيِّئ بحجم $r \times r$ يعيد قياس التدرّج الإقليدي نحو الاتجاه الريمانّي (اتجاه التدرّج المُقيَّم) على متعدد الأشكال المصفوفي منخفض الرتبة، مما يحسّن شروط التحديث ويمكن أن يُحسّن التقارب. وبما أن المُهيِّئ بحجم $r \times r$، فإن تكاليفه من حيث الذاكرة والوقت التشغيلي صغيرة بالنسبة لرتبة LoRA. يغلّف `create_riemannian_optimizer` أي فئة مُحسِّن أساسية (مثل `torch.optim.AdamW` أو `torch.optim.SGD`): حيث تُحدَّث المعاملات غير LoRA بواسطة المُحسِّن الأساسي دون تغيير، ولا يُطبَّق التهيئة إلا على طبقات LoRA ذات شكل `nn.Linear` (`lora_A` / `lora_B`).

```py
from peft import LoraConfig, get_peft_model
from peft.optimizers import create_riemannian_optimizer
from transformers import Trainer, get_cosine_schedule_with_warmup
import torch

base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")

config = LoraConfig(...)
model = get_peft_model(base_model, config)

optimizer = create_riemannian_optimizer(
    model=model,
    optimizer_cls=torch.optim.AdamW,
    lr=5e-5,
    reg=1e-2,
)

scheduler = get_cosine_schedule_with_warmup(
    optimizer,
    num_warmup_steps=100,
    num_training_steps=1000,
)

trainer = Trainer(
    ...,
    optimizers=(optimizer, scheduler),
)
```

`reg` هو حد تخميد يُضاف إلى القطر المثلثي للمصفوفة $r \times r$ قبل عملية العكس؛ وهو يضمن استقرار المُسبِّق (preconditioner) عندما يكون عامل LoRA (قريبًا من) أن يكون ناقص الرتبة.

## التدريب اللاحق

تُظهر هذه القسم طرق المعالجة اللاحقة المحتملة للمُكيِّفات المُدرَّبة.

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

While LoRA is significantly smaller and faster to train, you may encounter latency issues during inference due to separately loading the base model and the LoRA adapter. To eliminate latency, use the [merge_and_unload()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.merge_and_unload) function to merge the adapter weights with the base model. This allows you to use the newly merged model as a standalone model. The [merge_and_unload()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.merge_and_unload) function doesn't keep the adapter weights in memory.

فيما يلي مخطط يوضح الحدس وراء دمج محوّل LoRA:

    

نُظهر في المقاطع أدناه كيفية تشغيل ذلك باستخدام PEFT.

```py
from transformers import AutoModelForCausalLM
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
peft_model_id = "alignment-handbook/zephyr-7b-sft-lora"
model = PeftModel.from_pretrained(base_model, peft_model_id)
model = model.merge_and_unload()
```

من المهم تعيين النموذج المُعاد إلى متغير واستخدامه، إذ إن [merge_and_unload()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.merge_and_unload) ليست عملية تتم في الموقع. إذا كنت بحاجة إلى الاحتفاظ بنسخة من الأوزان حتى تتمكن من إلغاء دمج المُكيّف لاحقًا أو حذفه وتحميل مُكيّفات أخرى، فيجب عليك استخدام دالة [merge_adapter()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.merge_adapter) بدلاً من ذلك. الآن لديك خيار استخدام [unmerge_adapter()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.unmerge_adapter) لإرجاع النموذج الأساسي.

```py
from transformers import AutoModelForCausalLM
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
peft_model_id = "alignment-handbook/zephyr-7b-sft-lora"
model = PeftModel.from_pretrained(base_model, peft_model_id)
model.merge_adapter()

# unmerge the LoRA layers from the base model
model.unmerge_adapter()
```

> [!TIP]
> في النموذج المُكمَّم، لا تكون عملية إلغاء الدمج دقيقة: فعملية الدمج تعيد تكميم الوزن الأساسي، وقد تتراكم أخطاء التقريب مع تكرار دورات الدمج وإلغاء الدمج. راجع [دمج المُكيّفات في الأوزان المُكمَّمة](../developer_guides/quantization#merging-adapters-into-quantized-weights).

> [!WARNING]
> إذا كانت عدة محوِّلات نشطة وتم دمج بعضها فقط، فإن المحوِّلات غير المدمجة لن تُطبَّق بصمت. سيتغير هذا السلوك في PEFT v1.0. راجع [دمج بعض المحوِّلات النشطة فقط](../developer_guides/troubleshooting#merging-only-some-of-the-active-adapters).

تُعدّ دالة [add_weighted_adapter()](/docs/peft/main/ar/package_reference/lora#peft.LoraModel.add_weighted_adapter) مفيدة لدمج عدة LoRAs في مُكيّف جديد بناءً على مخطط أوزان يحدده المستخدم في معامل `weights`. أدناه مثال شامل من البداية إلى النهاية.

First load the base model:

```python
from transformers import AutoModelForCausalLM
from peft import PeftModel
import torch

base_model = AutoModelForCausalLM.from_pretrained(
    "mistralai/Mistral-7B-v0.1", dtype=torch.float16, device_map="auto"
)
```

ثم نحمّل المُكيّف الأول:

```python
peft_model_id = "alignment-handbook/zephyr-7b-sft-lora"
model = PeftModel.from_pretrained(base_model, peft_model_id, adapter_name="sft")
```

ثم حمّل مُكيّفًا مختلفًا وادمجه مع الأول:

```python
weighted_adapter_name = "sft-dpo"
model.load_adapter("alignment-handbook/zephyr-7b-dpo-lora", adapter_name="dpo")
model.add_weighted_adapter(
    adapters=["sft", "dpo"],
    weights=[0.7, 0.3],
    adapter_name=weighted_adapter_name,
    combination_type="linear"
)
model.set_adapter(weighted_adapter_name)
```

> [!TIP]
> توجد عدة طرق مدعومة لـ`combination_type`. راجع [التوثيق](../package_reference/lora#peft.LoraModel.add_weighted_adapter) لمزيد من التفاصيل. لاحظ أن استخدام "svd" كـ`combination_type` غير مدعوم عند استخدام `torch.float16` أو `torch.bfloat16` كنوع البيانات.

الآن، قم بتنفيذ الاستدلال:

```python
device = torch.accelerator.current_accelerator().type if hasattr(torch, "accelerator") else "cuda"

tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")

prompt = "Hey, are you conscious? Can you talk to me?"
inputs = tokenizer(prompt, return_tensors="pt")
inputs = {k: v.to(device) for k, v in inputs.items()}

with torch.no_grad():
    generate_ids = model.generate(**inputs, max_length=30)
outputs = tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
print(outputs)
```

### استعادة أداء النموذج الأساسي عبر تقليل أبعاد المتسلل

تجادل الورقة [LoRA vs Full Fine-tuning: An Illusion of Equivalence](https://huggingface.co/papers/2410.21228) بأن تدريب LoRA يُدخل أبعادًا إضافية إلى الأوزان التي لا تشترك كثيرًا مع الأوزان المتعلمة مسبقًا، مما يؤدي إلى نسيان المعلومات المتعلمة بالفعل. تنفّذ PEFT الإجراء التخفيفي المقترح في [peft.tuners.lora.intruders.reduce_intruder_dimension()](/docs/peft/main/ar/package_reference/lora#peft.tuners.lora.intruders.reduce_intruder_dimension).

ستقوم آلية التخفيف بأخذ نموذج PEFT يحتوي على LoRA محمّل، وإنشاء مُكيّف جديد معدّل يُحمَّل إلى جانب المُكيّف الحالي ليصبح المُكيّف النشط.

مثال على الاستخدام:

```python
from peft.tuners.lora.intruders import reduce_intruder_dimension

peft_model = AutoPeftModelForCausalLM.from_pretrained('hubnemo/llama-3.2b-metamathqa-lora64')

reduce_intruder_dimension(
    peft_model,
    mitigation_lambda=0.75,
)

peft_model.generate(...)
```

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

في حين أن الإعدادات الافتراضية مُعدّة لتقديم توازن جيد بين العاملين، إلا أنه لا يُكفَل أن تبقى هذه الإعدادات مناسبة لمُكيّفك ونموذجك وبياناتك، لذا من الحكمة أن يكون لديك معيار مرجعي جاهز لقياس الأثر.

## تحميل المُكيّفات

يمكن تحميل المُكيّفات (Adapters) على نموذج مُدرَّب مسبقًا باستخدام [load_adapter()](/docs/peft/main/ar/package_reference/peft_model#peft.PeftModel.load_adapter)، وهو أمر مفيد لتجربة مُكيّفات مختلفة لم يتم دمج أوزانها. اضبط أوزان المُكيّف النشط باستخدام دالة [set_adapter()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.set_adapter).

```py
from transformers import AutoModelForCausalLM
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
peft_model_id = "alignment-handbook/zephyr-7b-sft-lora"
model = PeftModel.from_pretrained(base_model, peft_model_id)

# load different adapter
model.load_adapter("alignment-handbook/zephyr-7b-dpo-lora", adapter_name="dpo")

# set adapter as active
model.set_adapter("dpo")
```

لإرجاع النموذج الأساسي، يمكنك استخدام [unload()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.unload) لتفريغ جميع وحدات LoRA أو استخدام [delete_adapter()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.delete_adapter) لحذف المُكيّف بالكامل. لاحظ أن [unload()](/docs/peft/main/ar/package_reference/tuners#peft.tuners.tuners_utils.BaseTuner.unload) ليست عملية تتم في الموقع (in-place)، لذا تذكّر بتعيين النموذج المُعاد إلى متغير واستخدامه.

```py
# unload adapter
model = model.unload()

# delete adapter
model.delete_adapter("dpo")
```

## توازي الموتر

يدعم LoRA [توازي الموترات (TP)](https://huggingface.co/docs/transformers/main/en/perf_train_gpu_many#tensor-parallelism) كما يوفره Transformers. عند تحميل نموذج أساسي مع `tp_plan`، يكتشف PEFT تلقائياً إعدادات توازي الموترات لكل وحدة مستهدفة ويضيف الخطافات المناسبة إلى أوزان محوّل LoRA حتى تشارك بشكل صحيح في حساب توازي الموترات.

> [!WARNING]
> يتطلب دعم التوازي في الموترات (Tensor Parallelism) لـ LoRA `transformers >= 5.4.0`. ويتطلب واجهة برمجة التطبيقات (API) الخاصة بالتوازي في الموترات القائمة على DTensor `peft >= 0.21.1` و`transformers >= 5.17.0`.

يكون الاستخدام مطابقًا تمامًا لتدفق عمل LoRA القياسي — ما عليك سوى تحميل النموذج الأساسي مع `tp_plan` قبل تغليفه بواسطة PEFT:

```py
from transformers import AutoModelForCausalLM
from peft import get_peft_model, LoraConfig

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B", tp_plan="auto")
lora_config = LoraConfig(r=16, target_modules=["q_proj", "v_proj"])
model = get_peft_model(model, lora_config)
```

تعمل عمليات الحفظ والتحميل بشكل اعتيادي عبر `save_pretrained` / `from_pretrained`. يقوم PEFT بجمع أوزان المُكيِّف المقسَّم مرة أخرى إلى متجهات كاملة قبل الحفظ، مما يجعل نقاط التفتيش قابلة للنقل ومستقلة عن عدد الأجهزة المستخدمة أثناء التدريب.

إذا طبّقت توازي الموترات دون خطة TP، على سبيل المثال باستخدام `parallelize_module` الخاص بـ PyTorch، فإن PEFT يحدد حجم أوزان LoRA لطبقة `nn.Linear` المقسّمة إلى حجم شحنتها المحلية إذا كان لشبكة الموترات الخاصة بالوزن بُعداً باسم `"tp"`، وإلا فيُحددها إلى شكل الطبقة الكاملة (كما هو الحال مع FSDP2). لا يضيف PEFT خطافات TP إلى هذه أوزان LoRA ولا يجمعها عند الحفظ. إذا كان بُعد شبكة TP لديك يحمل اسماً مختلفاً، أضِفه قبل إنشاء نموذج PEFT:

```py
from peft.utils.integrations import TpMeshDimRegistry

TpMeshDimRegistry.register("tp_dim")
```

## الاستدلال

تُبرز هذه القسم ما يمكنك القيام به أثناء وقت الاستدلال باستخدام LoRA، مثل فك ارتباط المُكيّف.

### لورا المُفعَّلة (aLoRA)

LoRA المُفعَّل (aLoRA) هو معمارية مُكيِّف منخفض الرتبة لنماذج اللغة السببية يعيد استخدام ذاكرة KV الموجودة في النموذج الأساسي لتحقيق استدلال أكثر كفاءة. يناسب هذا النهج خطوط الأنابيب التي تعتمد على النموذج الأساسي لمعظم المهام/التوليدات، لكنها تستخدم مُكيِّف aLoRA أو أكثر لأداء مهام متخصصة ضمن السلسلة. على سبيل المثال، التحقق من مخرجات النموذج الأساسي المولَّدة أو تصحيحها. في هذه الإعدادات، يمكن تسريع أوقات الاستدلال بمقدار مرتبة أو أكثر. لمزيد من المعلومات حول aLoRA والعديد من حالات الاستخدام، راجع [ورقة](https://huggingface.co/papers/2504.12397) aLoRA.

تقوم هذه التقنية بمسح آخر ظهور لسلسلة الاستدعاء (`alora_invocation_tokens`) في كل مدخل (ويمكن أن تكون هذه السلسلة قصيرة حتى رمز واحد). وتفعّل أوزان المحوّل (adapter) على الرموز بدءًا من بداية سلسلة الاستدعاء. كما تخضع المدخلات اللاحقة لسلسلة الاستدعاء للتكييف، وستستخدم جميع الرموز المولّدة الأوزان المُكيَّفة. وتُترك الأوزان على الرموز السابقة دون تكييف، مما يجعل ذاكرة التخزين المؤقت (cache) لتلك الرموز قابلة للاستبدال مع ذاكرة التخزين المؤقت للنموذج الأساسي بسبب قناع الانتباه السببي في النماذج اللغوية السببية. طريقة الاستخدام مشابهة جدًا لـ LoRA القياسي. والفرق الجوهري هو أنه يجب تحديد سلسلة الاستدعاء عند إنشاء المحوّل:

```py
from peft import LoraConfig

config = LoraConfig(alora_invocation_tokens=alora_invocation_tokens, task_type="CAUSAL_LM", ...)
```

alora_invocation_tokens هو قائمة من معرفات الرموز الصحيحة. بالنظر إلى سلسلة استدعاء مرغوبة، يمكن الحصول عليها على النحو التالي:
```py
invocation_string = "placeholder"
alora_invocation_tokens = tokenizer.encode(invocation_string, add_special_tokens=False).
```
المُرمِّز هو مُرمِّز النموذج الأساسي. استخدم `add_special_tokens=False` لتجنّب إضافة رموز `SOS`/`EOS` في سلسلة البحث لدينا (وهو ما سيُسبّب على الأرجح فشل عملية البحث).

**ملاحظات**
* يُؤيَّد aLoRA فقط لمهام `task_type=CAUSAL_LM` بسبب تركيزه على إعادة استخدام ذاكرة التخزين المؤقت.
* بما أن الأوزان تُكيَّف على عدد أقل من الرموز، فإن aLoRA يتطلب غالبًا (وليس دائمًا) رتبة (`r`) أعلى من LoRA. يمكن أن يكون `r=32` نقطة بداية جيدة.
* لا يمكن دمج أوزان aLoRA في النموذج الأساسي بحكم التعريف، حيث تُطبَّق أوزان المُكيِّف بشكل انتقائي على مجموعة فرعية من الرموز. ستُصدر محاولات الدمج أخطاء.
* لا يُدعم البحث الشعاعي بعد.
* لا يُنصح عمومًا بإضافة رموز جديدة إلى مُجزّئ الرموز (tokenizer) غير الموجودة في النموذج الأساسي. فقد يُعقّد ذلك حالة الاستخدام المستهدفة التي يعمل فيها كل من النموذج الأساسي ونموذج المُكيّف (adapter) على سياق متداخل. يمكنك تجاوز هذه المشكلة عن طريق إضافة [رموز قابلة للتدريب](../package_reference/trainable_tokens) إلى النموذج الأساسي قبل تدريب المُكيّف.

#### اختيار تسلسل الاستدعاء وتصميم SFT

يجب عليك إضافة تسلسل `alora_invocation_tokens` لأنه لا يُضاف تلقائيًا. نوصي بتفعيل أوزان المُكيّف مبكرًا (في بداية أي تلميح خاص بالمُكيّف)، ولكن بعد أي مدخلات طويلة، لتعظيم أداء النموذج دون المساس بإعادة استخدام ذاكرة التخزين المؤقت. وكما هو الحال مع أي نموذج، يجب أن يكون التنسيق متسقًا بين التدريب والاختبار.

فكّر في المثال التالي، حيث يحتوي النموذج الأساسي على قالب محادثة، والهدف هو تدريب المُكيّف (adapter) على توليد مخرجات مرغوبة.

* الخيار 1: إذا لم يكن هناك موجه محدد للمهمة، أي أن الإدخال هو سجل محادثة مع موجه `assistant`، فإن موجه `assistant` في قالب المحادثة (مثل `<|start_of_role|>assistant<|end_of_role|>`) هو خيار طبيعي لسلسلة الاستدعاء. راجع قالب المحادثة الخاص بالنموذج للعثور على الموجه الخاص بالنموذج.
* الخيار 2: إذا كان هناك موجه محدد للمهمة للمكيّف يصف المهمة التي يتعلمها المكيّف، وتم وضع ذلك الموجه كدور `user` مباشرة قبل التوليد، فإن موجه `user` في قالب المحادثة (مثل `<|start_of_role|>user<|end_of_role|>`) هو خيار طبيعي لسلسلة الاستدعاء.

بعد تحديد سلسلة الاستدعاء، احصل على مُجزِّئ النموذج واحصل على `alora_invocation_tokens` على النحو التالي
```py
alora_invocation_tokens = tokenizer.encode(invocation_string, add_special_tokens=False).
```

مثال على إعداد الاستدلال موجود في [alora finetuning](https://github.com/huggingface/peft/blob/main/examples/alora_finetuning/alora_finetuning.py).

> [!NOTE]
> عند استخدام نصوص مخصصة لسلسلة الاستدعاء، تأكد من أن بداية ونهاية السلسلة هي رموز خاصة لتجنب المشكلات المتعلقة بالتجزئة عند الحدود.

للفهم، تخيّل أن الرموز 'a' و'b' و'c' و'ab' هي توكنز في مُجزّئ النصوص الخاص بك (والأرقام 1 و2 و3 و4 على التوالي). افترض أن alora_invocation_tokens = [2, 3]. الآن تخيّل أن نص الإدخال الخاص بك هو "abc". بما أن "ab" هو توكن، فإن هذا النص سيُجزَّأ إلى [4,3]. وبالتالي، سيفشل العثور على alora_invocation_tokens، على الرغم من أن النص "bc" موجود فيه. ومع ذلك، إذا كان بداية ونهاية سلسلة الاستدعاء توكنز خاصة، فلن يحدث هذا الفشل أبدًا، لأن التوكنز الخاصة لا تُجزَّأ أبدًا إلى توكن واحد مع أحرف أخرى.

#### Using (وإعادة استخدام) ذاكرة التخزين المؤقت للتوليد
الغرض الرئيسي من aLoRA هو جعل ذاكرة KV قابلة للتبديل بين النموذج الأساسي ونماذج محوّل aLoRA **قبل تسلسل الاستدعاء** لأن قيم KV الأساسية والمحوّلة غير متوافقة. على وجه التحديد، يمكن استخدام المفاتيح والقيم المخزنة أثناء توليد نموذج واحد في عمليات التوليد اللاحقة لتجنب عمليات التعبئة المسبقة المكلفة لرموز السياق. عند مشاركة ذاكرة التخزين المؤقت بين النموذج الأساسي ومحوّلات aLoRA، هناك نمطان رئيسيان:
1. لقد أنتج النموذج الأساسي شيئًا ما، ثم يُستدعى مُكيّف aLoRA لإجراء توليد تالٍ. على سبيل المثال، يجيب النموذج الأساسي على سؤال، ثم يفحص مُكيّف aLoRA المُدرَّب على كشف الهلوسة (الوهم) ردّ النموذج الأساسي.
2. يكون مُكيّف aLoRA قد أنتج شيئًا ما، ثم يُستدعى النموذج الأساسي أو مُكيّف aLoRA مختلف لإجراء توليد تالٍ يتداخل جزئيًا مع سياق aLoRA الأصلي. على سبيل المثال، يقدّم المستخدم استعلامًا، فيعيد مُكيّف aLoRA صياغة الاستعلام ليكون أكثر استقلالية لتحسين الاسترجاع في نظام RAG. ثم تُسترجع المستندات وتُحمَّل في السياق، ويتحقق aLoRA من مدى صلة هذه المستندات بالسؤال، ثم يولّد النموذج الأساسي إجابة.

لإظهار السلوكيات المذكورة أعلاه عند استخدام التخزين المؤقت، نستخدم [DynamicCache](https://huggingface.co/docs/transformers/en/kv_cache) من `transformers`. انتبه إلى ضمان عدم خلط قيم التخزين المؤقت المُكيّفة بقيم التخزين المؤقت الأساسية. وبشكل خاص، يتطلب مشاركة التخزين المؤقت خطوة إضافية عندما يكون هناك تداخل جزئي في السياق (النمط 2).

**النمط 1: النموذج الأساسي متبوعًا بـ aLoRA** هنا، يُدخل كامل مدخلات النموذج الأساسي ومخرجاته إلى مُكيّف aLoRA، إلى جانب تسلسل الاستدعاء:
```
from transformers import DynamicCache
...
cache = DynamicCache()
inputs_base = tokenizer(prompt_base, return_tensors="pt")
# Generate from base model and save cache
with model_alora.disable_adapter():
    output = model_alora.generate(inputs_base["input_ids"].to(device),attention_mask=inputs_base["attention_mask"].to(device),past_key_values = cache,return_dict_in_generate=True)
output_text_base = tokenizer.decode(output.sequences[0])
cache = output.past_key_values

# Generate with aLoRA adapter from cache
prompt_alora = output_text + INVOCATION_STRING
inputs_alora = tokenizer(prompt_alora, return_tensors="pt").to(device)
output = model_alora.generate(**inputs_alora, past_key_values=cache)
output_text_alora = tokenizer.decode(output[0])

# Note: cache is now tainted with adapter values and cannot be used in base model from here on!
```

**النمط 2: توليد aLoRA يليه النموذج الأساسي (أو aLoRA آخر) مع تداخل جزئي في السياق** هنا، نملأ السياق المشترك مسبقًا باستخدام النموذج الأساسي، ثم ننتج النص.

```
from transformers import DynamicCache
import copy
...
cache = DynamicCache()
inputs_shared = tokenizer(prompt_shared, return_tensors="pt").to(device)

# Prefill from base model and save cache
with model_alora.disable_adapter():
    with torch.no_grad():
        model_alora(**inputs_shared, past_key_values=cache)
cache_copy = copy.deepcopy(cache)

# Generate from aLoRA using prefilled cache
prompt_alora = prompt_shared + INVOCATION_STRING
inputs_alora = tokenizer(prompt_alora, return_tensors="pt").to(device)
output = model_alora.generate(**inputs_alora, past_key_values=cache)
output_text_alora = tokenizer.decode(output[0])

# Generate from base model using saved cache not tainted by aLoRA KV values
prompt_base = prompt_shared
inputs_base = tokenizer(prompt_base, return_tensors="pt").to(device)
with model_alora.disable_adapter():
    output = model_alora.generate(**inputs_base, past_key_values=cache_copy)
output_text_base = tokenizer.decode(output[0])
```

### الاستدلال باستخدام محولات LoRA مختلفة في نفس الدفعة

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

لحسن الحظ، يمكن خلط محولات LoRA المختلفة في نفس الدفعة باستخدام الحجة `adapter_name`. أدناه، نوضح مثالاً على كيفية عمل ذلك عملياً. أولاً، دعونا نحمّل النموذج الأساسي، والإنجليزية، والمحولين، الفرنسية والألمانية، على النحو التالي:

```python
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel

model_id = ...
tokenizer = AutoTokenizer.from_pretrained(model_id)

model = AutoModelForCausalLM.from_pretrained(model_id)
# load the LoRA adapter for French
peft_model = PeftModel.from_pretrained(model, <path>, adapter_name="adapter_fr")
# next, load the LoRA adapter for German
peft_model.load_adapter(<path>, adapter_name="adapter_de")
```

الآن، نريد توليد نص على عينة تحتوي على اللغات الثلاث: العيّنات الثلاث الأولى بالإنجليزية، والتالية الثلاث بالفرنسية، والأخيرة الثلاث بالألمانية. يمكننا استخدام الحجة `adapter_names` لتحديد المُكيّف (adapter) الذي سنستخدمه لكل عينة. بما أن النموذج الأساسي لدينا يُستخدم للإنجليزية، نستخدم السلسلة الخاصة `"__base__"` لهذه العيّنات. بالنسبة للعيّنات الثلاث التالية، نحدد اسم المُكيّف الخاص بالتدريب الدقيق LoRA للفرنسية، وفي هذه الحالة `"adapter_fr"`. وبالنسبة للعيّنات الثلاث الأخيرة، نحدد اسم المُكيّف الخاص بالتدريب الدقيق LoRA للألمانية، وفي هذه الحالة `"adapter_de"`. بهذه الطريقة، يمكننا استخدام النموذج الأساسي والمُكيّفين في دفعة واحدة.

```python
inputs = tokenizer(
    [
        "Hello, my dog is cute",
        "Hello, my cat is awesome",
        "Hello, my fish is great",
        "Salut, mon chien est mignon",
        "Salut, mon chat est génial",
        "Salut, mon poisson est super",
        "Hallo, mein Hund ist süß",
        "Hallo, meine Katze ist toll",
        "Hallo, mein Fisch ist großartig",
    ],
    return_tensors="pt",
    padding=True,
)

adapter_names = [
    "__base__", "__base__", "__base__",
    "adapter_fr", "adapter_fr", "adapter_fr",
    "adapter_de", "adapter_de", "adapter_de",
]
output = peft_model.generate(**inputs, adapter_names=adapter_names, max_new_tokens=20)
```

لاحظ أن الترتيب لا يهم هنا، أي أن العينات في الدفعة لا تحتاج إلى أن تكون مجمّعة حسب المُكيّف كما في المثال أعلاه. ما نحتاجه فقط هو التأكد من أن معامل `adapter_names` متوافق بشكل صحيح مع العينات.

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

#### ملاحظات

يوجد بعض العيوب لاستخدام هذه الميزة، وهي:

- يعمل للاستدلال فقط، وليس للتدريب.
- تتفوق عملية تعطيل المُكيّفات باستخدام سياق `with model.disable_adapter()` على `adapter_names`.
- لا يمكنك تمرير `adapter_names` إذا تم دمج بعض أوزان المحوّل مع الوزن الأساسي باستخدام طريقة `merge_adapter`. يرجى إلغاء دمج جميع المحوِّلات أولاً عن طريق استدعاء `model.unmerge_adapter()`. لاحظ أن دمج بعض المحوِّلات النشطة فقط يحمل [تحذيراً مماثلاً](../developer_guides/troubleshooting#merging-only-some-of-the-active-adapters) خارج نطاق `adapter_names`.
- لأسباب واضحة، لا يمكن استخدام هذا بعد استدعاء `merge_and_unload()`، حيث سيتم دمج جميع محولات LoRA في الأوزان الأساسية في هذه الحالة.
- لا تعمل هذه الميزة حاليًا مع DoRA، لذا اضبط `use_dora=False` في `LoraConfig` الخاص بك إذا كنت ترغب في استخدامها.
- ميزة `modules_to_save` مدعومة حاليًا فقط لطبقات الأنواع `Linear` و`Embedding` و`Conv2d` و`Conv1d`.
- يوجد عبء إضافي متوقع عند الاستدلال باستخدام `adapter_names`، خاصة إذا كان عدد المحوِّلات المختلفة في الدفعة مرتفعاً. والسبب في ذلك أن حجم الدفعة يُقلَّص فعلياً إلى عدد العينات لكل محوِّل. إذا كانت أداء وقت التشغيل أولويتك القصوى، فجرِّب ما يلي:
  - زيادة حجم الدفعة.
  - حاول تجنّب تضمين عدد كبير من المحوِّلات المختلفة في الدفعة الواحدة، وفضِّل الدفعات المتجانسة. يمكن تحقيق ذلك عن طريق تخزين العينات التي تستخدم المحوِّل نفسه في منطقة مؤقتة، ثم تنفيذ الاستدلال بعدد صغير فقط من المحوِّلات المختلفة.
  - اطّلع على تطبيقات بديلة مثل [LoRAX](https://github.com/predibase/lorax) و[punica](https://github.com/punica-ai/punica) أو [S-LoRA](https://github.com/S-LoRA/S-LoRA)، وهي مصممة خصيصًا للعمل مع عدد كبير من المحوِّلات المختلفة.

### تكوين مُكيّفات LoRA وإعادة استخدامها
#### Arrow
[Arrow](https://huggingface.co/papers/2405.11157) هي خوارزمية توجيه معيارية مصممة لدمج عدة محولات LoRA مسبقة التدريب ومخصصة لمهام محددة لحل مهمة معينة، على غرار [Polytropon](poly) لكن دون الحاجة إلى ضبط دقيق. وبدلا من دمج جميع المحولات بشكل ساذج، يقدم **آلية توجيه خالية من التدرجات على مستوى الرموز (token-wise) تعتمد على مزيج الخبراء (MoE)**. عند الاستدلال، يحسب أولاً _نموذجًا أوليًا (prototype)_ لكل محول LoRA من خلال استخراج متجه القيمة المفردة اليمنى الأعلى من تحليله باستخدام SVD. ثم تُقارن تمثيلات كل رمز مع هذه النماذج الأولية عبر التشابه الجيب التمامي (cosine similarity) للحصول على معاملات التوجيه. تُسند الرموز إلى محولات LoRA الأكثر صلة (top-k)، مع تطبيع المعاملات عبر softmax، وتُدمج مخرجاتها خطيًا. وهذا يتيح إعادة استخدام وحدات LoRA الموجودة بفعالية لمهام جديدة، مما يؤدي إلى تعميم أفضل في سيناريوهات الصفرية (zero-shot).

في PEFT، يتم تفعيل Arrow من خلال [`ArrowConfig]` و`create_arrow_model`. كما يمكنك ضبط معاملات مثل `top_k` (عدد محولات LoRA المُجمَّعة لكل رمز)، و`router_temperature` (درجة حرارة softmax المطبَّقة على معاملات التوجيه)، و`rng_seed` (لضمان قابلية إعادة الإنتاج).

```py
from peft import create_arrow_model, ArrowConfig
from transformers import AutoModelForCausalLM

# Loading the model
base_model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-3-mini-4k-instruct")

# Creating the Arrow config
arrow_config = ArrowConfig(
    top_k=3,
    router_temperature=1.0,
    rng_seed=42,
)

# The LoRA adapters below were trained on a clustered FLAN dataset.
# Task clustering was performed using the Model-Based Clustering (MBC) method,
# as described in the Arrow paper.
# While one could train a separate LoRA for each task and let Arrow route tokens among them,
# training LoRAs on clusters of tasks instead provides an indirect optimization for
# transfer across the multi-task dataset.
task_specific_adapter_paths = [
        f"TahaBa/phi3-mini-clustered-flan/ts_expert_{i}" for i in range(10)
    ]

# Creating the Arrow model
model = create_arrow_model(
        base_model=base_model,
        task_specific_adapter_paths=task_specific_adapter_paths,
        arrow_config=arrow_config,
    )

# Now the forward path could be called on this model, like a normal PeftModel.
```

علاوة على ذلك، يمكنك إضافة أو إزالة المُكيّفات (adapters) بعد استدعاء ```create_arrow_model```—على سبيل المثال، لضبط مُكيّف جديد أو التخلّي عن مُكيّف غير ضروري. بمجرد وضع المُكيّفات في مكانها، يمكنك تفعيل ```"arrow_router"``` للاستدلال (inference) لاستخدام Arrow. لاحظ أنه إذا أضفت مُكيّف LoRA جديدًا بعد ```create_arrow_model``` وأردت ضبطه، فيجب عليك تعيين المُكيّف الجديد كفعّال بشكل صريح، لأن ```"arrow_router"``` يكون مفعّلًا افتراضيًا في ```create_arrow_model```.

```py
from trl import SFTTrainer, SFTConfig

# Adding a new adapter and activating it
model.add_adapter(adapter_name='new_adapter')
model.set_adapter('new_adapter')

# Now the model could be trained along the `new_adapter`.
trainer = SFTTrainer(
        model=model,
        args=SFTConfig(...),
        ...
    )

# Once the training is done, you can activate `arrow_router` and use it in inference
model.set_adapter('arrow_router')    # Model is ready to be used at inference time now
```

#### GenKnowSub
يعزز [GenKnowSub](https://aclanthology.org/2025.acl-short.54/) تقنية Arrow من خلال تنقية محولات LoRA الخاصة بالمهام قبل التوجيه. الفكرة الأساسية هي طرح المعرفة العامة المُرمّزة في فضاء LoRA—بناءً على [مبدأ النسيان عبر النفي](https://huggingface.co/papers/2212.04089)—بحيث تصبح محولات المهام أكثر عزلاً وتركيزاً على الإشارات ذات الصلة بالمهمة. عملياً، يقدّر GenKnowSub فضاءً فرعيّاً منخفض الأبعاد “عامّاً” من مجموعة من محولات LoRA العامة (غير الخاصة بمهمة معينة) ثم يزيل هذا المكوّن من تحديث LoRA لكل محوّل مهام قبل التوجيه على مستوى الرموز في Arrow. وهذا يحسّن عادةً قابلية التركيب ويقلل من التداخل عند دمج العديد من محولات المهام.

في PEFT، فعّل GenKnowSub عن طريق تعيين ```use_gks=True``` في ArrowConfig، وتوفير ```general_adapter_paths``` في ```create_arrow_model```:

```py
from peft import create_arrow_model, ArrowConfig
from transformers import AutoModelForCausalLM

# Loading the model
base_model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-3-mini-4k-instruct")

# Creating the Arrow config
arrow_config = ArrowConfig(
    top_k=3,
    router_temperature=1.0,
    use_gks=True,
    rng_seed=42,
)

# Path to task-specific, trained on flan clustered dataset (as we explained before.)
task_specific_adapter_paths = [
        f"TahaBa/phi3-mini-clustered-flan/ts_expert_{i}" for i in range(10)
    ]
# These general adapters are trained on English, German, and French Wikipedia dataset,
# with causal language modelling objective, each pair like: (507 token tsentence, 5 token completion), and the loss computed on the completion
general_adapter_paths = [
        "TahaBa/phi3-mini-general-adapters/cluster0_batch16_prop1.0_langen/checkpoint-17",
        "TahaBa/phi3-mini-general-adapters/cluster0_batch16_prop1.0_langfr/checkpoint-35",
        "TahaBa/phi3-mini-general-adapters/cluster0_batch16_prop1.0_langger/checkpoint-17"
    ]

# Creating the Arrow model
model = create_arrow_model(
        base_model=base_model,
        task_specific_adapter_paths=task_specific_adapter_paths,
        general_adapter_paths=general_adapter_paths,
        arrow_config=arrow_config,
    )

# Now the forward path could be called on this model, like a normal PeftModel.
```
لتشفير المعرفة العامة، يطرح GenKnowSub متوسط المُكيّفات العامة المُقدَّمة من كل مُكيّف خاص بالمهمة مرة واحدة، قبل بدء التوجيه. علاوة على ذلك، لا يزال يُدعم في هذه الحالة القدرة على إضافة أو إزالة المُكيّفات بعد استدعاء ```create_arrow_model``` (كما هو موصوف في قسم Arrow).

> [!TIP]
> **أشياء يجب وضعها في الاعتبار عند استخدام Arrow + GenKnowSub:**
>
> - يجب أن تتشارك جميع محولات LoRA (المخصصة للمهمة والعامة) نفس ```rank``` و```target_modules```.
>
> - أي عدم اتساق في هذه الإعدادات سيؤدي إلى ظهور خطأ في ```create_arrow_model```.
>
> - يُدعَم استخدام عوامل توسيع مختلفة (```lora_alpha```) عبر مُكيّفات المهام — يتعامل Arrow معها تلقائيًا.
>
> - لا يُدعم دمج ```"arrow_router"``` بسبب سلوكه الديناميكي في التوجيه.
>
> - في ```create_arrow_model```، تُحمَّل مُكيّفات المهام باسم ```task_i``` ومُكيّفات الاستخدام العام باسم ```gks_j``` (حيث ```i``` و```j``` هما فهارس). تضمن الدالة اتساق ```target_modules``` و```rank```، وما إذا كانت المُكيّفات مطبّقة على طبقات ```Linear``` أو ```Linear4bit```. ثم تضيف وحدة ```"arrow_router"``` وتفعّلها. أي تخصيص لهذه العملية يتطلب تجاوز ```create_arrow_model```.
>
> - يتوافق هذا التنفيذ مع التكميم بدقة 4 بت (عبر bitsandbytes):
>
>     ```py
>     from transformers import AutoModelForCausalLM, BitsAndBytesConfig
>     import torch
>
>     # Quantisation config
>     bnb_config = BitsAndBytesConfig(
>             load_in_4bit=True,
>             bnb_4bit_quant_type="nf4",
>             bnb_4bit_compute_dtype=torch.bfloat16,
>             bnb_4bit_use_double_quant=False,
>         )
>
>     # Loading the model
>     base_model = AutoModelForCausalLM.from_pretrained(
>         "microsoft/Phi-3-mini-4k-instruct",
>         dtype=torch.bfloat16,
>         device_map="auto",
>         quantization_config=bnb_config,
>     )
>
>     # Now call create_arrow_model() as we explained before.
>     ```

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

## LoraConfig[[peft.LoraConfig]]

#### peft.LoraConfig[[peft.LoraConfig]]

```python
peft.LoraConfig(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: Optional[dict] = <factory>, 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)
```

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

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

r (`int`) : بُعد انتباه Lora (الـ "rank").

target_modules (`Optional[Union[List[str], str]]`) : أسماء الوحدات التي سيتم تطبيق المُكيّف عليها. إذا تم تحديد هذا، فسيتم استبدال الوحدات التي تحمل الأسماء المحددة فقط. عند تمرير نص، سيتم إجراء مطابقة باستخدام تعبير نمطي. عند تمرير قائمة من النصوص، سيتم إجراء مطابقة دقيقة أو يتم التحقق مما إذا كان اسم الوحدة ينتهي بأي من النصوص الممررة. إذا تم تحديد هذا على أنه 'all-linear'، فسيتم اختيار جميع وحدات linear/Conv1D (إذا كان النموذج PreTrainedModel، باستثناء طبقة الإخراج). إذا لم يتم تحديده، فسيتم اختيار الوحدات وفقًا لبنية النموذج. إذا لم تكن البنية معروفة، فسيتم رفع خطأ -- في هذه الحالة، يجب عليك تحديد الوحدات المستهدفة يدويًا. لتجنب استهداف أي وحدات (لأنك تريد تطبيق `target_parameters`)، اضبط `target_modules=[]`.

exclude_modules (`Optional[Union[List[str], str]]`) : أسماء الوحدات التي لا يُطبَّق عليها المُكيّف. عند تمرير نص، يتم إجراء مطابقة باستخدام تعبير نمطي. عند تمرير قائمة من النصوص، يتم إما إجراء مطابقة دقيقة أو التحقق مما إذا كان اسم الوحدة ينتهي بأي من النصوص المُمرَّرة.

lora_alpha (`int`) : معامل ألفا (alpha) لتوسيع لورا (Lora).

lora_dropout (`float`) : احتمال الإسقاط لطبقات Lora.

fan_in_fan_out (`bool`) : اضبط هذا على True إذا كانت الطبقة التي سيتم استبدالها تخزن الأوزان على شكل (fan_in, fan_out). على سبيل المثال، يستخدم gpt-2 `Conv1D` الذي يخزن الأوزان على شكل (fan_in, fan_out)، وبالتالي يجب ضبط هذا على `True`.

bias (`str`) : نوع الانحياز (Bias) الخاص بـ LoRA. يمكن أن يكون 'none' أو 'all' أو 'lora_only'. إذا كان 'all' أو 'lora_only'، فسيتم تحديث الانحيازات المقابلة أثناء التدريب. انتبه إلى أن هذا يعني أنه حتى عند تعطيل المُكيّفات (adapters)، لن ينتج النموذج نفس المخرجات التي كان سينتجها النموذج الأساسي دون أي تكيّف.

use_rslora (`bool`) : عند ضبطه على True، يستخدم [Rank-Stabilized LoRA](https://huggingface.co/papers/2312.03732) الذي يضبط معامل توسيع المُكيّف على `lora_alpha/math.sqrt(r)`، إذ ثبت أنه يعمل بشكل أفضل. وإلا، فسيستخدم القيمة الافتراضية الأصلية `lora_alpha/r`.

modules_to_save (`List[str]`) : قائمة بالوحدات التي يجب ضبطها لتكون قابلة للتدريب وحفظها في نقطة الفحص النهائية، باستثناء طبقات المحوّل.

init_lora_weights (`bool` | `Literal["gaussian", "eva", "olora", "pissa", "pissa_niter_[number of iters]", "corda", "astra", "loftq", "orthogonal", "mica", "nora"]`) : كيفية تهيئة أوزان طبقات المحوّل. تمرير True (الافتراضي) يؤدي إلى التهيئة الافتراضية من التنفيذ المرجعي من Microsoft، حيث يتم تعيين وزن LoRA B إلى 0. وهذا يعني أنه بدون تدريب إضافي، سيكون محوّل LoRA عملية لا تؤثر في شيء. تعيين التهيئة إلى False يؤدي إلى تهيئة عشوائية لـ LoRA A و B، مما يعني أن LoRA ليست عملية لا تؤثر في شيء قبل التدريب؛ هذا الإعداد مخصص لأغراض التصحيح. تمرير 'gaussian' يؤدي إلى تهيئة غاوسية مُقيّمة حسب رتبة LoRA للطبقات الخطية. مرّر `'loftq'` لاستخدام تهيئة LoftQ. تمرير `'eva'` يؤدي إلى تهيئة مبنية على البيانات لتكييف التباين المفسَّر. يقوم EVA بتهيئة LoRA بناءً على التحليل القيمي المفرد (SVD) لتفعيلات مدخلات الطبقة ويحقق أداءً متقدمًا (SOTA) بسبب قدرته على التكيف مع بيانات الضبط الدقيق. مرّر `'olora'` لاستخدام تهيئة OLoRA. تمرير `'pissa'` يؤدي إلى تهيئة تكييف القيم المفردة المتجهية والمتجهات المفردة (PiSSA)، والتي تتقارب بشكل أسرع من LoRA وتحقق في النهاية أداءً متفوقًا. علاوة على ذلك، يقلل PiSSA من خطأ التكميم مقارنة بـ QLoRA، مما يؤدي إلى تحسينات إضافية. تمرير `'pissa_niter_[number of iters]'` يبدأ تهيئة PiSSA القائمة على Fast-SVD، حيث يشير `[number of iters]` إلى عدد تكرارات الفضاء الجزئي لتنفيذ FSVD، ويجب أن يكون عددًا صحيحًا غير سالب. عند تعيين `[number of iters]` إلى 16، يمكن إكمال تهيئة نموذج 7B خلال ثوانٍ، ويكون تأثير التدريب مكافئًا تقريبًا لاستخدام SVD. تمرير `'corda'` يؤدي إلى تهيئة تكييف التفكيك الموجَّه نحو السياق، والذي يتقارب بشكل أسرع حتى من PiSSA في وضع المعاينة التوجيهية، ويحافظ بشكل أفضل على المعرفة العالمية في وضع الحفاظ على المعرفة. تمرير `'astra'` يؤدي إلى تهيئة تكييف الرتبة المنخفضة لمتجهات eigen الذيلية في فضاء التفعيل، والذي يرمز الوزن الأساسي إلى فضاء eigen لتفعيلات المخرجات المُقدَّرة من مجموعة بيانات معايرة صغيرة. تمرير `"orthogonal"` يؤدي إلى تهيئة LoRA A و B بشكل متعامد؛ في ذلك، يشبه `"olora"`، لكن الأوزان الأساسية تُترك دون تغيير (يتطلب أن يكون `r` زوجيًا، مدعوم حاليًا فقط للطبقات الخطية). تمرير `"mica"` يؤدي إلى تهيئة تكييف المكوّن الثانوي (MiCA)، والتي تهيئ B من r متجهات مفردة يسارية للوزن الأساسي المرتبطة بأصغر القيم المفردة، وتعيّن A إلى صفر، وتجمّد B أثناء التدريب؛ يتم تحديث A فقط. مدعوم حاليًا للطبقات الخطية وطبقات التضمين. تمرير `"nora"` يؤدي إلى تهيئة تكييف الرتبة المنخفضة المُطبَّع (NoRA)، والذي يُطبّع كل عمود من وزن LoRA A المُهيَّأ عشوائيًا إلى معيار L2 وحدة، ويعيّن وزن LoRA B إلى صفر. يُطبَّق التطبيع فقط عند التهيئة؛ الأوزان الأساسية غير متغيرة ويبقى كل من A و B قابلًا للتدريب. الإعداد الموصى به هو `lora_alpha` يساوي `r` مع `use_rslora=False`، مما يحافظ على نسبة 1:1 ومعامل مقياس 1. مدعوم حاليًا للطبقات الخطية ولـ `nn.Parameter`s المستهدفة بـ `target_parameters`.

layers_to_transform (`Union[List[int], int]`) : فهارس الطبقات المراد تحويلها. إذا تم تمرير قائمة من الأعداد الصحيحة، فسيتم تطبيق المُكيّف على فهارس الطبقات المحددة في هذه القائمة. أما إذا تم تمرير عدد صحيح واحد، فسيتم تطبيق التحويلات على الطبقة الموجودة عند هذا الفهرس.

layers_pattern (`Optional[Union[List[str], str]]`) : اسم نمط الطبقة، يُستخدم فقط إذا كان `layers_to_transform` مختلفًا عن `None`. يجب أن يستهدف هذا `nn.ModuleList` الخاص بالنموذج، والذي يُسمى غالبًا `'layers'` أو `'h'`.

rank_pattern (`dict`) : الترميز من أسماء الطبقات أو تعبيرات النمط المنتظم إلى الرتب التي تختلف عن الرتبة الافتراضية المحددة بواسطة `r`. على سبيل المثال، `{'^model.decoder.layers.0.encoder_attn.k_proj': 16}`.

alpha_pattern (`dict`) : الترميز من أسماء الطبقات أو تعبيرات النمط المنتظم إلى قيم ألفا التي تختلف عن قيمة ألفا الافتراضية المحددة بواسطة `lora_alpha`. على سبيل المثال، `{'^model.decoder.layers.0.encoder_attn.k_proj': 16}`.

megatron_config (`Optional[dict]`) : حُجج TransformerConfig الخاصة بـ Megatron. تُستخدم لإنشاء طبقة الخطي المتوازي الخاصة بـ LoRA. يمكنك الحصول عليها على النحو التالي، `core_transformer_config_from_args(get_args())`، حيث أن هاتين الدالتين من Megatron. ستُستخدم الحُجج لمبادرة TransformerConfig الخاصة بـ Megatron. تحتاج إلى تحديد هذا المعامل عندما تريد تطبيق LoRA على طبقات ColumnParallelLinear و RowParallelLinear في megatron.

megatron_core (`Optional[str]`) : الوحدة الأساسية من Megatron للاستخدام، القيمة الافتراضية هي `"megatron.core"`.

trainable_token_indices (`Optional[Union[List[int], dict[str, List[int]]]]`) : يتيح لك تحديد فهارس الرموز التي تريد ضبطها بدقة بشكل انتقائي دون الحاجة إلى إعادة تدريب مصفوفة التضمين الكاملة باستخدام طريقة `peft.TrainableTokensModel`. يمكنك تحديد فهارس الرموز بطريقتين. إما أن تحدد قائمة بالفهارس التي ستستهدف طبقة تضمين الإدخال في النموذج (أو، إذا لم تُعثر عليها، `embed_tokens`). أو يمكنك تحديد قاموس يكون مفتاحه اسم وحدة التضمين وقيمته قائمة بفهارس الرموز، على سبيل المثال `{'embed_tokens': [0, 1, ...]}`. لاحظ أن التدريب باستخدام FSDP يتطلب `use_orig_params=True` لتجنب المشكلات المتعلقة بـ `requires_grad` غير المنتظمة.

loftq_config (`Optional[LoftQConfig]`) : إعدادات LoftQ. إذا لم تكن هذه القيمة None، فسيتم استخدام LoftQ لتهيئة أوزان الهيكل الأساسي (backbone) وتبني طبقات Lora. كما يجب تمرير `init_lora_weights='loftq'`. لاحظ أنه يجب عدم تمرير نموذج مُكمَّم في هذه الحالة، لأن LoftQ سيُكمم النموذج بنفسه. يُطبَّق LoftQ على الطبقات الخطية فقط، بما في ذلك تلك المستهدفة عبر `target_parameters`. لا تُدعَم طبقات التضمين (Embedding) والطبقات التلافيفية (convolutional)، بل تُستخدم بدلاً من ذلك تهيئة LoRA الافتراضية. لا تُدعَم طبقات `nn.MultiheadAttention` وتُطلق خطأً.

eva_config (`Optional[EvaConfig]`) : إعدادات EVA. على الأقل يجب تعيين حجة مجموعة البيانات (استخدم نفس مجموعة البيانات المستخدمة في الضبط الدقيق).

corda_config (`Optional[CordaConfig]`) : إعدادات CorDA. إذا لم تكن هذه القيمة None، فسيتم استخدام CorDA لبناء طبقات المحوّل. كما مرّر `init_lora_weights='corda'`.

astra_config (`Optional[AstraConfig]`) : إعدادات Astra. إذا لم تكن هذه القيمة None، فسيتم استخدام Astra لبناء طبقات المحوّل (adapter). كما يجب تمرير `init_lora_weights='astra'`، واستدعاء `preprocess_astra` قبل `get_peft_model` في هذه الحالة.

lora_ga_config (`Optional[LoraGAConfig]`) : إعدادات LoRA-GA. إذا تم تمرير هذا، فسيتم استخدام LoRA-GA لتبطين طبقات المحوّل. كما يجب تعيين `init_lora_weights='lora_ga'` في هذه الحالة.

use_dora (`bool`) : تفعيل تقنية 'Weight-Decomposed Low-Rank Adaptation' (DoRA). تقوم هذه التقنية بتفكيك تحديثات الأوزان إلى جزأين: المقدار والاتجاه. يُعالَج الاتجاه بواسطة LoRA العادي، بينما يُعالَج المقدار بواسطة معامل قابل للتعلم منفصل. يمكن أن يحسّن هذا أداء LoRA، لا سيما عند استخدام رتب منخفضة. حاليًا، تدعم DoRA طبقات linear وConv2D فقط. نظرًا لأن DoRA تُدخل عبئًا أكبر مقارنة بـ LoRA النقي، يُوصى بدمج الأوزان عند الاستدلال. لمزيد من المعلومات، راجع https://huggingface.co/papers/2402.09353.

velora_config (`Optional[VeloraConfig]`) : تفعيل VeLoRA من خلال توفير VeloraConfig. يستبدل VeLoRA مسار التراجع المخصص لإسقاط LoRA A، حيث يخزّن التفعيلات المضغوطة بدلاً من التفعيلات الكاملة للإدخال.

kasa_config (`Optional[KasaConfig]`) : تفعيل KaSA (Knowledge-aware Singular-value Adaptation) من خلال توفير KasaConfig. يقوم KaSA بقصّ أصغر `r` مكوّنات ذاتية من وزن الأساس المجمّد عبر عملية SVD لمرة واحدة، ويُدخل قطريًا قابلًا للتعلم من القيم الذاتية بين عاملَي LoRA A و B. حاليًا، لا يتم دعم سوى الطبقات الخطية.

alora_invocation_tokens (`List[int]`) : إذا لم تكن None، فعّل 'Activated LoRA' (aLoRA)، حيث يكون alora_invocation_tokens هو السلسلة المُحوَّلة إلى رموز (tokenized) لاستدعاء المُكيّف (adapter) (يجب أن تكون موجودة في جميع نصوص مدخلات النموذج). تُفعّل هذه التقنية أوزان المُكيّف بشكل انتقائي فقط على الرموز (tokens) أثناء وبعد alora_invocation_tokens. عند استخدامه في CausalLM، يعني ذلك أن ذاكرة KV (KV cache) السابقة للاستدعاء قابلة للتبديل مع ذاكرة النموذج الأساسي (ومع مُكيّفات aLoRA الأخرى التي تعمل بهذه الطريقة). ونتيجةً لذلك، في خطوط الأنابيب الاستدلالية التي تتضمن التبديل بين استدلال النموذج الأساسي واستدلال المُكيّف (مثل خطوط الأنابيب الوكيلية، راجع الورقة العلمية للحصول على أمثلة)، يتم تحقيق توفير كبير (مقارنةً بـ LoRA) من خلال حفظ عمليات التعبئة المسبقة (prefill operations). يمكن أن تحدث تسارعات إجمالية في سرعة استدلال المُكيّف بمقدار مرتبة واحدة أو أكثر على vLLM، اعتمادًا على طول السياق المشترك. لاحظ أن الدمج (merging) غير ممكن بسبب التطبيق الانتقائي للأوزان.

use_qalora (`bool`) : حاليًا، تم تنفيذه في GPTQ فقط. تفعيل تكييف الرتبة المنخفضة الواعي بالتكميم (QALoRA). تجمع هذه التقنية بين التدريب الواعي بالتكميم وLoRA لتحسين أداء النماذج المكمّمة. يمكن أن يحسّن هذا أداء LoRA، خاصة عند الرتب المنخفضة. في الوقت الحالي، يدعم QALoRA طبقات الخطية فقط.

qalora_group_size (`int`) : معامل حجم المجموعة لتجميع QALoRA، يتحكم في معامل تقليل الأبعاد. يتم تجميع أبعاد الإدخال في مجموعات بهذا الحجم، مما يقلل من التكلفة الحسابية. توفر القيم الأعلى ضغطًا أكبر، لكنها قد تقلل من جودة النموذج. يحدد هذا المعامل عدد الميزات الأصلية التي يتم أخذ متوسطها معًا لإنشاء ميزة مجمعة واحدة. يُستخدم فقط عندما يكون `use_qalora=True`.

monteclora_config (`Optional[MontecloraConfig]`) : إعدادات Monteclora (التكيّف منخفض الرتبة باستخدام مونت كارلو). إذا تم تمريرها، فسيتم استخدام Monteclora لإضافة أخذ عينات مونت كارلو التبايني فوق مُكيّفات LoRA. راجع `MontecloraConfig` للحصول على تفاصيل حول المعلمات الفائقة الفردية.

layer_replication (`List[Tuple[int, int]]`) : بناء مكدس جديد من الطبقات عن طريق تكدس طبقات النموذج الأصلي وفقًا للنطاقات المحددة. يتيح ذلك توسيع (أو تقليص) النموذج دون تكرار أوزان النموذج الأساسي. سيتم إرفاق محولات LoRA منفصلة بجميع الطبقات الجديدة.

runtime_config (`LoraRuntimeConfig`) : إعدادات وقت التشغيل (التي لا يتم حفظها أو استعادتها).

lora_bias (`bool`) : القيمة الافتراضية هي `False`. ما إذا كان سيتم تفعيل حد الانحياز (bias) لمعامل LoRA B. عادةً، يجب تعطيل هذا الخيار. الاستخدام الرئيسي لهذا الخيار هو عندما تكون أوزان LoRA مستخرجة من معاملات تم ضبطها بالكامل (fully fine-tuned)، بحيث يمكن أخذ انحياز تلك المعاملات في الاعتبار.

target_parameters (`List[str]`, *اختياري*) : قائمة بأسماء المعاملات التي سيتم استبدالها بـ LoRA. يتصرف هذا الحجة بشكل مشابه لـ `target_modules`، باستثناء أنه يجب تمرير اسم المعامل. بشكل عام، يجب استخدام `target_modules` لاستهداف الوحدة (مثل `nn.Linear`). ومع ذلك، في بعض الظروف، لا يكون ذلك ممكنًا. على سبيل المثال، في العديد من طبقات خليط الخبراء (MoE) في HF Transformers، يتم استخدام `nn.Parameter` بدلاً من `nn.Linear`. يقوم PEFT عادةً بتجاوز طريقة `forward` لـ LoRA، لكن في حالة `nn.Parameter`، لا توجد طريقة. لذلك، لتطبيق LoRA على ذلك المعامل، يجب استهدافه باستخدام `target_parameters`. كمثال، بالنسبة إلى Llama4، يمكنك تمرير: `target_parameters=['feed_forward.experts.gate_up_proj', 'feed_forward.experts.down_proj]`. لم يتم تنفيذ تمرير نص لتنطابق الأنماط النمطية بعد. لاحظ أنه عند تجميع النموذج واستخدام `target_parameters`، يُتوقع حدوث إعادة تجميع و/أو انكسارات في الرسم البياني. يُنصح بعدم استخدام كليهما في الوقت نفسه.

use_bdlora (`Optional[BdLoraConfig]`) : تفعيل BD-LoRA (LoRA القطري الحزمي) من خلال توفير BdLoraConfig. تستخدم هذه التقنية مصفوفات قطرية حزمية لعوامل LoRA-A أو LoRA-B لتمكين تقديم متعدد LoRA أسرع من خلال إزالة تكاليف الاتصال في الإعدادات الموزعة.

arrow_config (`Optional[ArrowConfig]`) : الإعدادات اللازمة لتطبيق توجيه arrow على النموذج.

ensure_weight_tying (`bool`, *اختياري*) : ما إذا كان سيتم ربط الأوزان أم لا بعد تهيئة peft. سيضمن هذا أن المكيّفات المضافة إلى الطبقات المرتبطة تكون مرتبطة أيضًا. ينطبق هذا فقط على الطبقات المُمررة عبر `modules_to_save` و`target_modules`.

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

#### to_dict[[peft.LoraConfig.to_dict]]

```python
to_dict()
```

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

يعيد إعدادات نموذج المُكيّف الخاص بك على شكل قاموس. يزيل إعدادات وقت التشغيل.

## LoraModel[[peft.LoraModel]]

#### peft.LoraModel[[peft.LoraModel]]

```python
peft.LoraModel(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/lora/model.py#L143)

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

model (`torch.nn.Module`) : النموذج الذي سيتم تكييفه.

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

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

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

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

نموذج Lora.

ينشئ نموذج Low Rank Adapter (LoRA) من نموذج transformers مُدرَّب مسبقًا.

يُوصف هذا الأسلوب بالتفصيل في https://huggingface.co/papers/2106.09685.

مثال:

```py
>>> from transformers import AutoModelForSeq2SeqLM
>>> from peft import LoraConfig, get_peft_model

>>> config = LoraConfig(
...     task_type="SEQ_2_SEQ_LM",
...     r=8,
...     lora_alpha=32,
...     target_modules=["q", "v"],
...     lora_dropout=0.01,
... )

>>> model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
>>> lora_model = get_peft_model(model, config)
```

```py
>>> import torch
>>> import transformers
>>> from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training

>>> rank = ...
>>> target_modules = ["q_proj", "k_proj", "v_proj", "out_proj", "fc_in", "fc_out", "wte"]
>>> config = LoraConfig(
...     r=4, lora_alpha=16, target_modules=target_modules, lora_dropout=0.1, bias="none", task_type="CAUSAL_LM"
... )
>>> quantization_config = transformers.BitsAndBytesConfig(load_in_8bit=True)

>>> tokenizer = transformers.AutoTokenizer.from_pretrained(
...     "kakaobrain/kogpt",
...     revision="KoGPT6B-ryan1.5b-float16",  # or float32 version: revision=KoGPT6B-ryan1.5b
...     bos_token="[BOS]",
...     eos_token="[EOS]",
...     unk_token="[UNK]",
...     pad_token="[PAD]",
...     mask_token="[MASK]",
... )
>>> model = transformers.GPTJForCausalLM.from_pretrained(
...     "kakaobrain/kogpt",
...     revision="KoGPT6B-ryan1.5b-float16",  # or float32 version: revision=KoGPT6B-ryan1.5b
...     pad_token_id=tokenizer.eos_token_id,
...     use_cache=False,
...     device_map={"": rank},
...     torch_dtype=torch.float16,
...     quantization_config=quantization_config,
... )
>>> model = prepare_model_for_kbit_training(model)
>>> lora_model = get_peft_model(model, config)
```

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

#### add_weighted_adapter[[peft.LoraModel.add_weighted_adapter]]

```python
add_weighted_adapter(adapters: list[str], weights: list[float], adapter_name: str, combination_type: Literal['svd', 'linear', 'cat', 'ties', 'ties_svd', 'dare_ties', 'dare_linear', 'dare_ties_svd', 'dare_linear_svd', 'magnitude_prune', 'magnitude_prune_svd'] = 'svd', svd_rank: int | None = None, svd_clamp: int | None = None, svd_full_matrices: bool = True, svd_driver: str | None = None, density: float | None = None, majority_sign_method: Literal['total', 'frequency'] = 'total')
```

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

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

adapters (`list`) : قائمة بأسماء المُكيِّفات (adapters) التي سيتم دمجها.

weights (`list`) : قائمة بالأوزان الخاصة بكل مُكيّف. يمكن أن تكون الأوزان موجبة أو سالبة، مما يتيح الجمع بين تأثيرات المُكيّفات أو طرحها.

adapter_name (`str`) : اسم المُكيّف الجديد.

combination_type (`str`) : يمكن أن يكون نوع الدمج أحد [`svd`، `linear`، `cat`، `ties`، `ties_svd`، `dare_ties`، `dare_linear`، `dare_ties_svd`، `dare_linear_svd`، `magnitude_prune`، `magnitude_prune_svd`]. عند استخدام `cat` كـ combination_type، يكون رتبة المُكيّف الناتج مساويةً لمجموع رتب جميع المُكيّفات (قد يكون المُكيّف المختلط كبيرًا جدًا مما يؤدي إلى أخطاء نفاد الذاكرة OOM). لاحظ أن `cat` و`svd` طريقتان دقيقتان وستمنحانك دقة جيدة، بينما `linear` فعّالة لكنها تقريب خشن جدًا ويجب تجنبها إذا كان بإمكانك تحمّل التكلفة.

svd_rank (`int`, *اختياري*) : رتبة مُكيّف المخرجات لـ svd. إذا لم يُقدَّم أي قيمة، فسيتم استخدام الرتبة القصوى لمُكيّفات الدمج.

svd_clamp (`float`, *اختياري*) : عتبة نسبة مئوية (quantile) لقص (clamping) مخرجات التحليل بالقيم المفردة (SVD). إذا تم تقديم None، فلا يتم تنفيذ القص. القيمة الافتراضية هي None.

svd_full_matrices (`bool`, *اختياري*) : يتحكم في ما إذا كان سيتم حساب SVD الكامل أو المُختزل، وبالتالي شكل المصفوفات U وVh المُعادَة. القيمة الافتراضية هي True.

svd_driver (`str`, *اختياري*) : اسم طريقة cuSOLVER التي سيتم استخدامها. لا يعمل هذا الحُجج المُسمّى إلا عند الدمج على CUDA. يمكن أن يكون أحد القيم التالية [None, `gesvd`, `gesvdj`, `gesvda`]. لمزيد من المعلومات، يُرجى الرجوع إلى توثيق `torch.linalg.svd`. القيمة الافتراضية هي None.

density (`float`، *اختياري*) : قيمة بين 0 و 1. تعني 0 أن جميع القيم تُحذف، وتعني 1 عدم حذف أي قيم. يجب استخدامه مع [`ties`، `ties_svd`، `dare_ties`، `dare_linear`، `dare_ties_svd`، `dare_linear_svd`، `magnintude_prune`، `magnitude_prune_svd`]

majority_sign_method (`str`) : الطريقة، يجب أن تكون واحدة من ["total", "frequency"]، لاستخدامها في الحصول على مقدار قيم الإشارة. يجب استخدامها مع [`ties`, `ties_svd`, `dare_ties`, `dare_ties_svd`]

تضيف هذه الطريقة مُكيِّفًا جديدًا من خلال دمج المُكيِّفات المُعطاة مع الأوزان المُعطاة.

عند استخدام `cat` كقيمة لـ combination_type، يجب أن تكون على دراية بأن رتبة المحوّل الناتج ستكون مساوية لمجموع رتب جميع المحوّلات. لذا، من الممكن أن يصبح المحوّل المختلط كبيرًا جدًا مما يؤدي إلى أخطاء نفاد الذاكرة (OOM).

#### subtract_mutated_init[[peft.LoraModel.subtract_mutated_init]]

```python
subtract_mutated_init(output_state_dict: dict[str, torch.Tensor], adapter_name: str, kwargs = None)
```

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

يمكن لهذا الدالة حساب تحديثات PiSSA/CorDA/OLoRA من خلال مقارنة معاملات مُكيّف PiSSA/CorDA/OLoRA في `output_state_dict` مع القيم الأولية لـ PiSSA/CorDA/OLoRA في `adapter_name`، وبالتالي تحويل PiSSA/CorDA/OLoRA إلى LoRA.

تزيل طرق مثل PiSSA جزءًا من أوزان النموذج الأساسية للتدريب، ولذلك لا يمكن استبدالها بسهولة. ولكن إذا كنت تعرف كلًا من أوزان ما قبل التدريب الأولية وأوزان ما بعد التدريب، يمكنك حساب \Delta W واستخدامه كمُكيّف LoRA.

خطوات الحساب:

- $W = W_{res} + A_0 B_0$ (تهيئة PiSSA)
- $W + \Delta W = W_{res} + A B$ (PiSSA بعد التدريب)
- $\Delta W = W_{res} + AB - W = W_{res} + AB - W_{res} - A_0 B_0$ (اشتقاق dW لـ LoRA)
- $\Delta W = AB - A_0 B_0$

## أدوات مساعدة

### ArrowConfig[[peft.ArrowConfig]]

#### peft.ArrowConfig[[peft.ArrowConfig]]

```python
peft.ArrowConfig(top_k: int = 3, router_temperature: float = 1.0, use_gks: bool = False, rng_seed: Optional[int] = None)
```

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

هذا هو فئة التهيئة الفرعية لتخزين إعدادات خوارزميتي Arrow وGenKnowSub. Arrow هي خوارزمية توجيه لدمج وحدات LoRA المدربة لحل مهام جديدة، وقد طُرحت في 'https://huggingface.co/papers/2405.11157'. أما GenKnowSub فهي تحسين على الوحدات المدربة قبل دمجها عبر Arrow، وقد عُرضت في 'https://aclanthology.org/2025.acl-short.54/'

### LoftQ

#### replace_lora_weights_loftq[[peft.replace_lora_weights_loftq]]

#### peft.replace_lora_weights_loftq[[peft.replace_lora_weights_loftq]]

```python
peft.replace_lora_weights_loftq(peft_model, model_path: Optional[str] = None, adapter_name: str = 'default', callback: Optional[Callable[[torch.nn.Module, str], bool]] = None)
```

[المصدر](https://github.com/huggingface/peft/blob/main/src/peft/utils/loftq_utils.py#L223)

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

peft_model (`PeftModel`) : النموذج الذي سيتم استبدال أوزانه. يجب أن يكون نموذج PEFT مُكمَّمًا مع طبقات LoRA.

model_path (`Optional[str]`) : المسار إلى ملف safetensors الخاص بالنموذج. إذا كان النموذج من نماذج Hugging Face، فسيتم استنتاجه من إعدادات النموذج. وإلا، يجب تقديمه.

adapter_name (`str`) : اسم المُكيّف الذي سيُستبدل أوزانه. اسم المُكيّف الافتراضي هو "default".

callback (`Optional[Callable[[PeftModel, str], bool]]`) : دالة استجابة ستُستدعى بعد استبدال كل وحدة. يجب أن تستقبل دالة الاستجابة النموذج واسم الوحدة الحالية كمدخلات، وتعيد قيمة منطقية تشير إلى ما إذا كان يجب الإبقاء على الاستبدال أم لا. إذا أعادت الدالة False، فسيتم التراجع عن الاستبدال. يمكن أن يكون هذا مفيدًا جدًا للتأكد من أن تهيئة LoftQ تقلل فعليًا من خطأ التكميم في النموذج. كمثال، يمكن لهذه الدالة توليد قيم logits لإدخال معين ومقارنتها بقيم logits من النموذج الأصلي غير المكمم مع نفس الإدخال، ولا تعيد `True` إلا إذا كان هناك تحسن. وبما أن هذا تحسين طمع، فمن الممكن أن يؤدي استدعاء هذه الدالة عدة مرات إلى تحسينات تدريجية.

استبدل أوزان LoRA لنموذج مُكمَّم باستخدام bitsandbytes، باستخدام تقنية LoftQ.

يتم الاستبدال على الفور عن طريق تحميل الأوزان غير المُكمّمة من ملف نموذج safetensors مخزّن محليًا، وتبديل أوزان LoRA بحيث يتم تقليل خطأ التكميم بين الأوزان الأصلية والأوزان المُكمّمة إلى أدنى حد.

تُحمَّل الأوزان بشكل كسول، مما يتطلب تخزين النموذج بتنسيق safetensors.

قد يستغرق استدعاء هذه الدالة بعض الوقت للانتهاء، وذلك اعتمادًا على حجم النموذج.

#### LoftQConfig[[peft.LoftQConfig]]

#### peft.LoftQConfig[[peft.LoftQConfig]]

```python
peft.LoftQConfig(loftq_bits: int = 4, loftq_iter: int = 1)
```

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

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

loftq_bits (`int`) : عدد بتات التكميم لـ LoftQ.

loftq_iter (`int`) : تكرارات متناوبة لخوارزمية LoftQ.

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

### PiSSA

#### replace_lora_weights_pissa[[peft.replace_lora_weights_pissa]]

#### peft.replace_lora_weights_pissa[[peft.replace_lora_weights_pissa]]

```python
peft.replace_lora_weights_pissa(peft_model, model_path: Optional[str] = None, adapter_name: str = 'default', init_lora_weights: str = 'pissa')
```

[المصدر](https://github.com/huggingface/peft/blob/main/src/peft/utils/loftq_utils.py#L305)

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

peft_model (`PeftModel`) : النموذج الذي سيتم استبدال أوزانه. يجب أن يكون نموذج PEFT يحتوي على طبقات LoRA، ومكمَّم باستخدام bitsandbytes بدقة 4 بت.

model_path (`Optional[str]`) : المسار إلى ملف safetensors الخاص بالنموذج. إذا كان النموذج من نماذج Hugging Face، فسيتم استنتاجه من إعدادات النموذج. وإلا، يجب تقديمه.

adapter_name (`str`) : اسم المُكيّف الذي سيُستبدل أوزانه. اسم المُكيّف الافتراضي هو "default".

init_lora_weights (`str`) : إما `"pissa"` أو `"pissa_niter_[number of iters]"`، راجع [LoraConfig](/docs/peft/main/ar/package_reference/lora#peft.LoraConfig). بالنسبة للنماذج الكبيرة، يكون الخيار الثاني أسرع بكثير.

استبدل أوزان LoRA والأوزان الأساسية لنموذج مُكمَّم باستخدام bitsandbytes، وذلك باستخدام PiSSA.

يُؤمَّن دعم تكميم 4 بت من bitsandbytes فقط.

لا يمكن تطبيق PiSSA مباشرة على الأوزان المُكمّمة، لذا يتطلب الأمر عادةً تحميل النموذج بدقة كاملة، وحفظ الباقي، ثم تحميل ذلك الباقي مع التكميم. تعطي هذه الدالة النتيجة نفسها انطلاقًا من النموذج المُكمَّم: حيث تُحمَّل الأوزان غير المُكمَّمة على نحوٍ فوري من ملف safetensors مخزَّن محليًا، طبقةً طبقة، بحيث لا يتعين إبقاء النموذج بدقة كاملة في الذاكرة أبدًا.

يُستبدل كل وزن أساسي بالمتبقي المُعاد تكميمه من PiSSA. وكما هو الحال مع أي تهيئة PiSSA، فإن المُكيّف وحده غير كافٍ لاستعادة النموذج، انظر إلى الحجة `path_initial_model_for_weight_conversion` في [save_pretrained()](/docs/peft/main/ar/package_reference/peft_model#peft.PeftModel.save_pretrained).

تُحمَّل الأوزان بشكل كسول، مما يتطلب تخزين النموذج بتنسيق safetensors.

قد يستغرق استدعاء هذه الدالة بعض الوقت للانتهاء، وذلك اعتمادًا على حجم النموذج.

### Eva

#### EvaConfig[[peft.EvaConfig]]

#### peft.EvaConfig[[peft.EvaConfig]]

```python
peft.EvaConfig(rho: float = 2.0, tau: float = 0.99, use_label_mask: bool = True, label_mask_value: int = -100, whiten: bool = False, adjust_scaling_factors: bool = True)
```

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

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

rho (`float`) : قيمة Rho لإعادة توزيع EVA (>= 1.0). الحد الأقصى للرتبة لطبقة معينة هو lora_r * rho. القيمة الافتراضية هي 2.0، مما يعني أن الحد الأقصى للرتبة المسموح بها لطبقة معينة هو 2r. زيادة rho ستسمح بدرجة أعلى من إعادة توزيع الرتب عبر الطبقات. قد تكون بعض النماذج المُدرَّبة مسبقًا أكثر حساسية لإعادة توزيع الرتب. لذلك، قد يكون من المفيد تجربة rho=1.0 (بدون إعادة توزيع) إذا كانت الأداء أقل من المتوقع.

tau (`float`) : عتبة تشابه جيب التمام للإيقاف المبكر. يقارن تشابه جيب التمام للمتجهات المفردة اليمنى بين خطوتين متتاليتين من التحليل القيمي المفرد. إذا كان تشابه جيب التمام أعلى من هذه العتبة، يتم إيقاف تكرار التحليل القيمي المفرد. القيمة الافتراضية هي 0.99.

use_label_mask (`bool`) : استخدام قناع التسميات (label mask) لتهيئة EVA. وهذا يعني أن المواضع التي تكون فيها التسميات=label_mask_value تُتجاهل في حساب SVD. يُفضَّل ضبط use_label_mask=True في معظم الحالات، وقد يكون مفيدًا بشكل خاص للمحادثات متعددة الأدوار. القيمة الافتراضية هي True. قد يؤدي استبعاد العناصر بناءً على قناع التسميات أحيانًا إلى حجم دفعة صغير، مما يتسبب في عدم استقرار في حساب SVD. في الحالات التي يُستبعد فيها حصة كبيرة من عناصر الدفعة، اضبط use_label_mask=False.

label_mask_value (`int`) : إذا كان use_label_mask=True، فهو القيمة التي يتم البحث عنها لإخفاء الرموز المهملة. القيمة الافتراضية هي -100.

whiten (`bool`) : تطبيق التبييض على المتجهات المفردة. القيمة الافتراضية هي False. وقد تبيّن أن التبييض مفيد لـ EVA في مجال الرؤية.

adjust_scaling_factors (`bool`) : ضبط عوامل تحجيم LoRA بعد إعادة توزيع الرتب. تعيين هذا الخيار إلى True يعني ضبط عوامل التحجيم بحيث تمتلك جميع تدرجات LoRA نفس المقياس بغض النظر عن رتبها. القيمة الافتراضية هي True.

هذا هو فئة التهيئة الفرعية لتخزين إعدادات التهيئة القائمة على البيانات عبر EVA. تم تقديم EVA في Explained Variance Adaptation.

#### initialize_lora_eva_weights[[peft.initialize_lora_eva_weights]]

#### peft.initialize_lora_eva_weights[[peft.initialize_lora_eva_weights]]

```python
peft.initialize_lora_eva_weights(model: Module, dataloader: collections.abc.Iterable | None = None, eva_state_dict: dict | None = None, forward_fn: collections.abc.Callable | None = <function forward_fn_dict at 0x7f13acb5fe20>, prepare_model_inputs_fn: collections.abc.Callable | None = <function prepare_model_inputs_fn_language_modeling at 0x7f13acb5fc10>, prepare_layer_inputs_fn: collections.abc.Callable | dict[str, collections.abc.Callable] | None = <function prepare_layer_inputs_fn_language_modeling at 0x7f13acb5fd70>, adapter_name: str = 'default', gather_distributed_inputs: bool = True, show_progress_bar: bool = True)
```

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

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

model (PeftModel) : نموذج peft الذي يتم حساب SVD له.

dataloader (Optional[Iterable]) : مُحمِّل البيانات (dataloader) الذي سيُستخدم في المرور الأمامي. إذا كانت القيمة None، فيجب تقديم eva_state_dict.

eva_state_dict (Optional[dict]) : قاموس الحالة (state_dict) الذي سيتم تحميله في النموذج. إذا كان القيمة None، فيجب توفير مُحمِّل بيانات (dataloader) وسيتم حساب قاموس الحالة باستخدام `get_eva_state_dict`.

forward_fn (Callable) : دالة الأمامي (forward) المستخدمة في المرور الأمامي. تستقبل حجتين: `model` و`inputs`. السلوك الافتراضي هو `return model(**inputs)`

prepare_model_inputs_fn (Optional[Callable]) : This function receives the model inputs and the peft_config and passes the output to `prepare_layer_inputs_fn`. Can be used to modify the input to the SVD computation based on the original model inputs. For example for language modeling the attention mask is used to determine which indices are padding tokens and should not be used for SVD. Any function defined here expects two arguments: `model_input` and `peft_config`. `peft.tuners.lora.eva.prepare_model_inputs_fn_language_modeling` is used by default.

prepare_layer_inputs_fn (Union[Callable, Dict[str, Callable], None]) : تستقبل هذه الدالة مدخلات الطبقة، ومدخلات النموذج (التي قد تُعدَّل بواسطة `prepare_model_inputs_fn`)، واسم الطبقة، وتعيد المدخلات التي يجب استخدامها لتفكيك القيم المفردة (SVD) لتلك الطبقة المحددة. تتوقع أي دالة مخصصة تُعرَّف هنا ثلاثة حُجج: `layer_input`، و`model_input`، و`layer_name`، ويجب أن تعيد مصفوفة ثنائية الأبعاد. يمكن العثور على المنطق الافتراضي في peft.tuners.lora.eva.prepare_layer_inputs_fn_language_modeling وهو يعمل لنمذجة اللغة. في هذه الحالة، يكون model_inputs هو القناع المستخدم لتحديد الفهارس التي يجب استخدامها لتفكيك القيم المفردة (SVD) (الذي أُنشئ بواسطة `prepare_model_inputs_fn_language_modeling`).

adapter_name (str) : اسم المُكيّف الذي سيتم تهيئة الأوزان له.

gather_distributed_inputs (bool) : ما إذا كان سيتم جمع مدخلات الطبقة من جميع الرتب. القيمة الافتراضية هي True، مما يعني أنه في الإعداد الموزّع سيتم جمع مدخلات الطبقة من جميع الرتب لحساب SVD. في الإعدادات غير الموزّعة يتم تجاهل هذا الحجة. اضبطه على False إذا كنت تستخدم مُحمِّل بيانات غير موزّع في إعداد موزّع.

show_progress_bar (bool) : ما إذا كان يجب عرض شريط تقدم. القيمة الافتراضية هي True.

**يعيد:** `model (torch.nn.Module)`

النموذج الذي تم تهيئته بأوزان LoRA.

تهيئة أوزان طبقات LoRA باستخدام طريقة EVA.

تُهيّئ هذه الدوال أوزان طبقات LoRA باستخدام طريقة EVA. فهي تحسب التحليل القيمي المفرد (SVD) لكل طبقة مُكيّف (adapter) وتحديث الأوزان وفقاً لذلك.

#### get_eva_state_dict[[peft.get_eva_state_dict]]

#### peft.get_eva_state_dict[[peft.get_eva_state_dict]]

```python
peft.get_eva_state_dict(model: Module, dataloader: Iterable, peft_config: peft.tuners.lora.config.LoraConfig | None = None, forward_fn: collections.abc.Callable | None = <function forward_fn_dict at 0x7f13acb5fe20>, prepare_model_inputs_fn: collections.abc.Callable | None = <function prepare_model_inputs_fn_language_modeling at 0x7f13acb5fc10>, prepare_layer_inputs_fn: collections.abc.Callable | dict[str, collections.abc.Callable] | None = <function prepare_layer_inputs_fn_language_modeling at 0x7f13acb5fd70>, adapter_name: str = 'default', gather_distributed_inputs: bool = True, show_progress_bar: bool = True)
```

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

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

model (torch.nn.Module) : النموذج الذي سيتم حساب التحليل القيمي المفرد (SVD) له. لا يلزم أن يكون PeftModel.

dataloader (Iterable) : مُحمِّل البيانات (dataloader) الذي يُستخدم في المرور الأمامي (forward pass).

peft_config (اختياري[LoraConfig]) : إعدادات طبقات LoRA. مطلوب فقط إذا لم يكن `model` من نوع PeftModel.

forward_fn (Callable) : دالة الأمامي (forward) المستخدمة في المرور الأمامي. تستقبل حجتين: `model` و`inputs`. السلوك الافتراضي هو `return model(**inputs)`

prepare_model_inputs_fn (Optional[Callable]) : This function receives the model inputs and the peft_config and passes the output to `prepare_layer_inputs_fn`. Can be used to modify the input to the SVD computation based on the original model inputs. For example for language modeling the attention mask is used to determine which indices are padding tokens and should not be used for SVD. Any function defined here expects two arguments: `model_input` and `peft_config`. `peft.tuners.lora.eva.prepare_model_inputs_fn_language_modeling` is used by default.

prepare_layer_inputs_fn (Union[Callable, Dict[str, Callable], None]) : تستقبل هذه الدالة مدخلات الطبقة، ومدخلات النموذج (التي قد تُعدَّل بواسطة `prepare_model_inputs_fn`)، واسم الطبقة، وتعيد المدخلات التي يجب استخدامها لتفكيك القيم المفردة (SVD) لتلك الطبقة المحددة. تتوقع أي دالة مخصصة تُعرَّف هنا ثلاثة حُجج: `layer_input`، و`model_input`، و`layer_name`، ويجب أن تعيد مصفوفة ثنائية الأبعاد. يمكن العثور على المنطق الافتراضي في peft.tuners.lora.eva.prepare_layer_inputs_fn_language_modeling وهو يعمل لنمذجة اللغة. في هذه الحالة، يكون model_inputs هو القناع المستخدم لتحديد الفهارس التي يجب استخدامها لتفكيك القيم المفردة (SVD) (الذي أُنشئ بواسطة `prepare_model_inputs_fn_language_modeling`).

adapter_name (str) : اسم المُكيّف الذي سيتم حساب التحليل القيمي المفرد (SVD) له.

gather_distributed_inputs (bool) : ما إذا كان سيتم جمع مدخلات الطبقة من جميع الرتب. القيمة الافتراضية هي True، مما يعني أنه في الإعداد الموزّع سيتم جمع مدخلات الطبقة من جميع الرتب لحساب SVD. في الإعدادات غير الموزّعة يتم تجاهل هذا الحجة. اضبطه على False إذا كنت تستخدم مُحمِّل بيانات غير موزّع في إعداد موزّع.

show_progress_bar (bool) : ما إذا كان يجب عرض شريط تقدم. القيمة الافتراضية هي True.

**يعيد:** `eva_state_dict (dict)`

قاموس الحالة الذي يحتوي على مكونات التحليل القيمي المفرد (SVD) لكل طبقة.

احسب التحليل القياسي للقيم المفردة (SVD) لكل طبقة في النموذج.

تُحسب هذه الدالة تحليل القيم المفردة (SVD) لكل طبقة في النموذج. إنها تستخدم طريقة PCA التزايدية لحساب مكونات SVD. كما تتحقق الدالة من تقارب المكونات المحسوبة باستخدام التشابه الجيبية. يُحدد توزيع الرتبة لكل طبقة بناءً على نسبة التباين المفسَّر.

### LoraGAConfig[[peft.LoraGAConfig]]

#### peft.LoraGAConfig[[peft.LoraGAConfig]]

```python
peft.LoraGAConfig(direction: Literal['ArBr', 'A2rBr', 'ArB2r', 'random'] = 'ArB2r', scale: Literal['stable', 'weight_svd', 'gd_scale', 'unit'] = 'stable', stable_gamma: int = 16)
```

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

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

direction (`Literal["ArBr", "A2rBr", "ArB2r", "random"]`) : استراتيجية لتوزيع مكونات SVD المتدرّجة على مصفوفتي lora_A و lora_B. - "ArBr": تبادل الفهارس (تأخذ A الفهارس الفردية، وتأخذ B الفهارس الزوجية) - "A2rBr": تأخذ A الفهارس [r:2r]، وتأخذ B الفهارس [:r] - "ArB2r": تأخذ A الفهارس [:r]، وتأخذ B الفهارس [r:2r] (موصى به) - "random": اختيار عشوائي للفهارس الافتراضي: "ArB2r"

scale (`Literal["stable", "weight_svd", "gd_scale", "unit"]`) : استراتيجية التوسيع (Scaling) لتهيئة المُكيِّف (adapter). - "stable": توسيع مستقر باستخدام معامل gamma - "weight_svd": توسيع بناءً على القيم المفردة لمصفوفة الأوزان - "gd_scale": توسيع يعتمد على هبوط التدرج (Gradient descent) - "unit": بدون توسيع إضافي الافتراضي: "stable"

stable_gamma (`int`) : معامل غاما لطريقة التوسيع المستقر. الافتراضي: 16

هذا هو فئة التهيئة الفرعية لتخزين إعدادات تهيئة LoRA-GA.

يستخدم LoRA-GA (التكيّف منخفض الرتبة مع تقريب التدرّج) معلومات التدرّج أثناء التهيئة لتحقيق تقارب أسرع (تسريع بمقدار 2-4 أضعاف) من خلال محاذاة أوزان المُكيِّف الأولي مع اتجاه تدرّجات الضبط الكامل.

مرجع: https://arxiv.org/abs/2407.05000

#### أدوات[[peft.tuners.lora.loraga.estimate_gradients]]

#### peft.tuners.lora.loraga.estimate_gradients[[peft.tuners.lora.loraga.estimate_gradients]]

```python
peft.tuners.lora.loraga.estimate_gradients(model: Module, lora_config: LoraConfig, train_step: Callable)
```

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

تقدير التدرجات لتهيئة LoRA-GA.

تُمكّن هذه الدالة من حساب التدرّجات على أوزان الوحدة المستهدفة فقط، وتُشغّل مستدعي train_step. وهذا أكثر كفاءة في استخدام الذاكرة من تفعيل التدرّجات على مستوى النظام بالكامل.

#### peft.preprocess_loraga[[peft.preprocess_loraga]]

```python
peft.preprocess_loraga(model: Module, lora_config: LoraConfig, train_step: Callable, cache_file: str | None = None)
```

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

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

model (`nn.Module`) : النموذج الذي سيتم معالجته مسبقًا.

lora_config (`LoraConfig`) : إعدادات Lora للنموذج. يجب تعيين `lora_config.lora_ga_config`.

train_step (`Callable[[], None]`) : استدعاء يُنفَّذ لتقدير التدرجات. عادةً ما ينبغي تنفيذ تمريرَي النموذج الأمامي والخلفي داخل هذا الاستدعاء. سيتم تجميع التدرجات عبر جميع الاستدعاءات داخل هذا الاستدعاء.

cache_file (`Optional[str]`) : مسار اختياري لملف التخزين المؤقت لحفظ/تحميل التدرجات. إذا تم تقديمه وكان الملف موجودًا، سيتم تحميل التدرجات من التخزين المؤقت. وإلا، سيتم تقدير التدرجات وحفظها في هذا المسار.

إنشاء الحقول اللازمة لـ LoRA-GA لنموذج من خلال تقدير التدرجات.

بالنسبة لكل طبقة خطية، سيتم تقدير التدرجات من خلال تشغيل استدعاء train_step المُقدَّم. ثم تُربط هذه التدرجات بالوحدات وتُستخدم أثناء التهيئة.

عند الانتهاء، يتم تعيين الحقول التالية لكل وحدة هدف: _peft_loraga_grad (`torch.Tensor`): التدرج المتراكم لمصفوفة الأوزان.

## تقليل الأبعاد للغريب[[peft.tuners.lora.intruders.reduce_intruder_dimension]]

#### peft.tuners.lora.intruders.reduce_intruder_dimension[[peft.tuners.lora.intruders.reduce_intruder_dimension]]

```python
peft.tuners.lora.intruders.reduce_intruder_dimension(peft_model, old_adapter_name = 'default', new_adapter_name = 'intruder_reduced', top_k = 10, threshold_epsilon = 0.5, mitigation_lambda = 0.75, logging_sink = <built-in function print>)
```

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

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

peft_model : نموذج PEFT مع محوّل LoRA محمّل باسمه المُقدَّم في `old_adapter_name`. حاليًا، لا يتم دعم النماذج المختلطة.

top_k (الافتراضي: 10) خذ بعين الاعتبار الأبعاد الأعلى قيمة (top-k) لكشف المتسللين. كلما زادت القيمة، زاد عدد الأبعاد التي تُؤخذ في الاعتبار لتحليل كشف المتسللين (وبالتالي تزداد احتمالية وجود إيجابيات خاطئة). يعمل هذا المعامل على التشابه الجيبوي (cosine similarity) بين الأوزان الأساسية وأوزان المُكيِّف (adapter)، مرتبةً تقريبًا حسب تأثير كل بُعد (المُحدَّد عبر التحليل بالقيم المفردة)، لذا فإن قيمة top-k تساوي 10 تعني النظر إلى الأبعاد العشرة الأكثر "أهمية".

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

mitigation_lambda (الافتراضي: 0.75) الجزء النسبي من أبعاد المُغِير الذي يُطرح من وزن الدلتا الخاص بالمُكيِّف. كلما ارتفعت القيمة، زاد مقدار بُعد المُغِير الذي يُطرح، لكن زاد أيضًا مقدار المعلومات المفقودة. راجع الشكل 8 في الورقة البحثية لتحليل التوازن بين الأداء والتكلفة.

logging_sink (الافتراضي: print) دالة تطبع معلومات حول عملية التخفيف. اضبطها على None إذا لم ترغب في أي مخرجات.

التخفيف من بُعد المتسلل بناءً على https://huggingface.co/papers/2410.21228 ("LoRA vs Full Fine-tuning: An Illusion of Equivalence").

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

بعد اكتمال التخفيف، سيظهر مُكيّف جديد يحمل الاسم المحدد في `new_adapter_name`، وسيُعدّ هذا المُكيّف هو المُكيّف النشط حاليًا. لذلك، سيعتمد الاستدلال على النموذج المُخفَّف على المُكيّف المُعدَّل. للعودة إلى المُكيّف الأصلي، يمكنك استخدام `peft_model.set_adapter(<old_adapter_name>)`.

حاليًا، لا يُدعم سوى LoRA، إذ لم يتضح بعد ما إذا كان بإمكان هذه الطريقة التعميم على طرق أوزان الدلتا الأخرى.

