# مساهمة نموذج قديم

> [!TIP]
> جرّب إضافة نماذج جديدة أولاً باستخدام نهج أكثر [تكاملاً](./modular_transformers). هذا يجعل المساهمة بنموذج في Transformers أسهل بكثير!

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

عند إضافة نموذج إلى Transformers، ستتعلم:

- المزيد حول أفضل ممارسات المصادر المفتوحة
- حول بنية النموذج
- حول مبادئ تصميم Transformers
- كيفية اختبار النماذج الكبيرة بكفاءة
- كيفية استخدام أدوات بايثون مثل [Black](https://black.readthedocs.io/en/stable/) و [Ruff](https://docs.astral.sh/ruff/) لإنشاء أكواد نظيفة وسهلة القراءة

إنه عملية صعبة لكنها مثمرة.

ستأخذك هذه الدليل خطوة بخطوة في إضافة نموذج PyTorch جديد باسم BrandNewLlama إلى مكتبة Transformers. قبل أن تبدأ، من الجيد أن تتعرّف على المكتبة بشكل جيد.

## نظرة عامة على Transformers

تُعد مكتبة Transformers مكتبة ذات توجهات واضحة، تتمتع بفلسفة وخيارات تصميم فريدة من نوعها. تساعدنا هذه الخيارات على توسيع نطاق Transformers والحفاظ عليها بشكل مستدام.

> [!TIP]
> تعرف على المزيد حول مبادئ التصميم لدينا في وثيقة [الفلسفة](./philosophy).

بعض هذه الخيارات التصميمية هي:

- التركيب > الإفراط في التجريد
- ليس تكرار الكود سيئًا دائمًا إذا كان يحسّن بشكل كبير من قابلية القراءة وسهولة الوصول
- ملفات النموذج مكتفية ذاتياً، وكل أكواد النموذج اللازمة موجودة في ملف `modeling_mymodel.py`

تُعدّ هذه الاختيارات التصميمية مهمة *لكل من* يتفاعل مع النموذج. فهي أسهل في القراءة والفهم والتعديل.

تصف هذه الأقسام كيفية تفاعل فئات النموذج والإعدادات معًا، وأسلوب كتابة الكود في مكتبة Transformers.

### النموذج والتكوين

تورث جميع نماذج Transformers من الفئة الأساسية [PreTrainedModel](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel) وفئة [PreTrainedConfig](/docs/transformers/main/ar/main_classes/configuration#transformers.PreTrainedConfig). وتُعدّ التهيئة هي المخطط الأساسي للنماذج.

لا يتجاوز مستوى التجريد في أي نموذج مستويين اثنين للحفاظ على قابلية قراءة الكود. النموذج الموضح هنا، BrandNewLlama، يرث من `BrandNewLlamaPreTrainedModel` و [PreTrainedModel](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel). من المهم أن يعتمد النموذج الجديد على [PreTrainedModel](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel) فقط حتى يتمكن من استخدام طريقتي [from_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained) و [save_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.save_pretrained).

Other important functions like the forward method are defined in the `modeling.py` file.

يجب أن تستدعي رؤوس النماذج المحددة (مثل تصنيف التسلسل أو نمذجة اللغة) النموذج الأساسي في مسار الأمامي بدلاً من الوراثة منه، للحفاظ على مستوى التجريد منخفضاً.

تتطلب النماذج الجديدة إعداداً، على سبيل المثال `BrandNewLlamaConfig`، يُخزَّن كخاصية من خصائص [PreTrainedModel](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel).

```py
model = BrandNewLlamaModel.from_pretrained("username/brand_new_llama")
model.config
```

يوفر [PreTrainedConfig](/docs/transformers/main/ar/main_classes/configuration#transformers.PreTrainedConfig) طريقتي [from_pretrained()](/docs/transformers/main/ar/main_classes/configuration#transformers.PreTrainedConfig.from_pretrained) و[save_pretrained()](/docs/transformers/main/ar/main_classes/configuration#transformers.PreTrainedConfig.save_pretrained).

عند استخدامك [PreTrainedModel.save_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.save_pretrained)، يتم استدعاء [PreTrainedConfig.save_pretrained()](/docs/transformers/main/ar/main_classes/configuration#transformers.PreTrainedConfig.save_pretrained) تلقائيًا بحيث يتم حفظ النموذج والإعداد معًا.

يتم حفظ النموذج في ملف `model.safetensors` وحفظ الإعدادات في ملف `config.json`.

### أسلوب الكتابة

يفضّل Transformers كودًا نظيفًا وسهل القراءة على أسلوب برمجي أكثر تجريدًا. وتشمل بعض اختيارات أسلوب الكود ما يلي:

- يجب أن يكون الكود قابلاً للوصول للمستخدمين غير الناطقين بالإنجليزية. اختر أسماء متغيرات وصفية وتجنّب الاختصارات. على سبيل المثال، يُفضَّل استخدام "activation" بدلاً من "act". يُنصح بشدة بعدم استخدام أسماء متغيرات من حرف واحد، ما لم تكن فهارس داخل حلقة for.

- يُفضَّل الكود الصريح - حتى لو كان أطول - على الكود الأقصر.

- تجنّب إنشاء فئة فرعية من [nn.Sequential](https://pytorch.org/docs/stable/generated/torch.nn.Sequential.html). بدلاً من ذلك، أنشئ فئة فرعية من [nn.Module](https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module) حتى يمكن تصحيح الأخطاء في الكود بسرعة باستخدام عبارات الطباعة أو نقاط التوقف.

- يجب أن تكون توقيعات الدوال مُعلَّمةً بأنواع. وإلا، فاستخدم أسماء متغيرات جيدة حتى تكون أكثر قابلية للفهم.

## مشكلة في إضافة نموذج جديد

افتح مشكلة [إضافة نموذج جديد](https://github.com/huggingface/transformers/issues/new?assignees=&labels=New+model&template=new-model-addition.yml) لإضافة نموذج محدد.

> [!TIP]
> استخدم علامة [New model](https://github.com/huggingface/transformers/labels/New%20model) على GitHub للترشيح لعرض طلبات النماذج الموجودة وإضافتها.

الآن هو وقت مناسب للتعرف على BrandNewLlama. من المفيد قراءة ورقة بحثية حول النموذج لفهم تصميمه التقني وتنفيذه. لا داعي للقلق المفرط حول التفاصيل النظرية بالضرورة. بدلاً من ذلك، ركّز على التفاصيل العملية. استخدم الأسئلة أدناه لتوجيه قراءتك.

- ما نوع النموذج BrandNewLlama؟ هل هو نموذج مُشفِّر (encoder) أو مُفكِّك (decoder) أو نموذج مُشفِّر-مُفكِّك (encoder-decoder)؟
- ما هي المهام التي يمكن استخدام BrandNewLlama لأدائها؟
- ما الذي يميّز BrandNewLlama عن النماذج الأخرى؟
- ما هي النماذج الأكثر تشابهاً مع BrandNewLlama في مكتبة Transformers؟
- ما هو مُجزِّئ الرموز (tokenizer) الذي يستخدمه BrandNewLlama؟

بالإضافة إلى الاطلاع على مزيد من المعلومات حول نموذجك، استخدم النصائح أدناه لمساعدتك على إضافة نموذج بشكل أسرع.

> [!TIP]
> لكل مساهب أسلوبه الخاص ومسار عمله لإضافة النماذج إلى Transformers. كمثال، اطّلع على كيفية إضافة [Gemma](https://github.com/huggingface/transformers/pull/29167).

- لا تعِد اختراع العجلة! خذ وقتك لاستكشاف النماذج والمقسّمين (tokenizers) الموجودة مسبقًا لترى ما يمكنك نسخه وإعادة استخدامه. [Grep](https://www.gnu.org/software/grep/) و[ripgrep](https://github.com/BurntSushi/ripgrep) أدوات رائعة لهذا الغرض.
- هذا تحدٍّ هندسي أكثر منه تحدٍّ علمي. ركّز على الجوانب العملية (مثل إعداد بيئة تصحيح أخطاء فعّالة) بدلاً من الجوانب النظرية للنموذج.
- لا تتردد في طلب المساعدة! نحن هنا لدعمك. 🤗

## بيئة التطوير

انقر على زر **Fork** في مستودع [Transformers](https://github.com/huggingface/transformers) لإنشاء نسختك الخاصة للعمل عليها. انسخ المستودع إلى القرص المحلي لديك وأضف المستودع الأساسي كمصدر بعيد.

```bash
git clone https://github.com/[your Github handle]/transformers.git
cd transformers
git remote add upstream https://github.com/huggingface/transformers.git
```

أنشئ بيئة افتراضية وأجرِ [تثبيتاً قابلاً للتعديل](./installation#editable-install) للمكتبة مع تبعيات "dev" أو تبعيات التطوير.

```bash
python -m venv .env
source .env/bin/activate
pip install -e ".[dev]"
```

نظراً إلى تزايد عدد التبعيات الاختيارية مع نمو مكتبة Transformers، قد يفشل هذا الأمر. في هذه الحالة، قم بتثبيت التبعيات الخاصة بـ "quality". كما تأكد من أنك قمت بتثبيت إطار عمل للتعلم العميق.

```bash
pip install -e ".[quality]"
```

عد إلى المجلد الأب ثم استنسخ وثبّت مستودع BrandNewLlama الأصلي.

```bash
git clone https://github.com/org_that_created_brand_new_llama_org/brand_new_llama.git
cd brand_new_bert
pip install -e .
```

عد إلى نسخة Transformers الخاصة بك لبدء نقل BrandNewLlama.

```bash
cd transformers
```

تتوفر بيئتان محتملتان للتشخيص لتشغيل النموذج الأصلي، وهي دفتر ملاحظات ([Google Colab](https://colab.research.google.com/notebooks/intro.ipynb) أو [Jupyter](https://jupyter.org/)) أو سكربت بايثون محلي.

> [!WARNING]
> لا ننصح بإعداد بيئة GPU لتشغيل النموذج الأصلي لأن ذلك قد يكون مكلفًا. وبدلاً من ذلك، ابدأ بالعمل في بيئة CPU للتحقق من أن النموذج يعمل في Transformers. وبعد ذلك، يمكنك التحقق منه على GPU.

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

العيوب هي أنه إذا لم تكون معتادًا عليها، فقد يستغرق الأمر بعض الوقت حتى تعتاد عليها.

> [!TIP]
> إذا كانت بنية النموذج مطابقة لبنية نموذج موجود مسبقًا، فتخطَّ إلى [تحويل نقطة التفتيش](#convert-checkpoints-to-transformers)، إذ يمكنك إعادة استخدام بنية النموذج الموجود.

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

```bash
transformers add-new-model-like
```

## إنشاء طلب سحب

قبل أن تبدأ في تكييف الكود، أنشئ طلب سحب (pull request) لتتبع تقدمك والحصول على ملاحظات من فريق Transformers. اجعل عنوان طلب السحب **[WIP] Add BrandNewLlama** ليكون من الواضح أن هذا عمل قيد التنفيذ.

أنشئ فرعًا باسمًا وصفيًا من الفرع الرئيسي لديك.

```bash
git checkout -b add_brand_new_bert
```

التزم بالكود، ثم استخرج وأعد الأساس على الفرع الرئيسي.

```bash
git add .
git commit
git fetch upstream
git rebase upstream/main
```

ادفع أي تغييرات إلى فرعك وانقر على **Compare & pull request** لفتح طلب سحب على GitHub. افتح طلب السحب كـ *draft* للإشارة إلى أنه قيد العمل.

```bash
git push -u origin a-descriptive-name-for-my-changes
```

قم بتضمين أعضاء فريق Hugging Face المعنيين عن طريق إضافة مقابض GitHub الخاصة بهم في طلب الدمج لطرح الأسئلة، وتقديم الملاحظات والتعليقات، وإجراء المراجعات. وجّه أعضاء الفريق إلى الأجزاء المحددة من الكود التي تريد الإشارة إليها بالنقر على تبويب **Files changed**، ثم انقر على **+** الموجود على يسار رقم السطر لإضافة تعليق. عند حل سؤال أو مشكلة، انقر على **Resolve** للإشارة إلى أن المشكلة قد حُلّت. يحافظ هذا على تنظيم المحادثة ووضوحها.

تذكّر بالالتزام بدفع عملك بشكل دوري، وتحديث عملك مع الفرع الرئيسي الحالي.

```bash
git fetch upstream
git merge upstream/main
```

## نقطة التفتيش الأصلية

خذ بعض الوقت للعمل على تنفيذ النموذج الأصلي أولاً لفهم كيفية عمله.

قد يكون ذلك صعبًا إذا كان مستودع النموذج الأصلي يفتقر إلى التوثيق أو إذا كان كود المشروع معقدًا. لكن يجب أن تستخدم هذا كدافع لتنفيذ النموذج في Transformers. فمساهمتك تجعله أكثر سهولة في الوصول إليه وأسهل استخدامًا للجميع!

تعرّف على المستودع الأصلي من خلال القيام بما يلي.

- حدد أوزان النموذج المُدرَّب مسبقًا.
- حدد كيفية تحميل الأوزان المُسبقة التدريب في النموذج.
- حدد كيفية تشغيل مُجزِّئ الرموز بشكل مستقل عن النموذج.
- تتبّع تمريرةً واحدةً للأمام لفهم الفئات والدوال المطلوبة. على الأرجح، هذه هي الفئات والدوال الوحيدة التي ستحتاج إلى تنفيذها.
- حدد جميع المكونات المهمة (فئة النموذج، فئات النموذج الفرعية، طبقة الانتباه الذاتي، إلخ) للنموذج.
- حدد كيفية تصحيح أخطاء النموذج في المستودع الأصلي. أضف عبارات طباعة، واستخدم مُصحِّحات تفاعلية مثل [ipdb](https://github.com/gotcha/ipdb)، أو بيئة تطوير متكاملة (IDE) فعّالة مثل [PyCharm](https://www.jetbrains.com/pycharm/).

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

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

```py
model = BrandNewLlamaModel.load_pretrained_checkpoint("/path/to/checkpoint/")
input_ids = [0, 4, 5, 2, 3, 7, 9]  # vector of input ids
original_output = model.generate(input_ids)
```

### استكشاف الأخطاء وإصلاحها

إذا واجهت مشكلات، فستحتاج إلى اختيار إحدى استراتيجيات التصحيح التالية اعتمادًا على قاعدة أكواد النماذج الأصلية.

تعتمد هذه الاستراتيجية على تقسيم النموذج الأصلي إلى مكونات فرعية أصغر، كما هو الحال عندما يمكن تشغيل الكود بسهولة في الوضع العاجل (eager mode). وعلى الرغم من أن هذا النهج أكثر صعوبة، إلا أن له بعض المزايا.

1. يكون من الأسهل لاحقًا مقارنة النموذج الأصلي بتنفيذك. يمكنك التحقق تلقائيًا من أن كل مكوّن فردي يطابق المكوّن المقابل له في تنفيذ Transformers. وهذا أفضل من الاعتماد على مقارنة بصرية مبنية على عبارات الطباعة.
2. من الأسهل نقل المكونات الفردية بدلاً من نقل النموذج بأكمله.
3. يكون فهم كيفية عمل النموذج أسهل عند تقسيمه إلى أجزاء أصغر.
4. يكون من الأسهل منع الانحسارات في مرحلة لاحقة عند تغيير الكود بفضل الاختبارات المخصصة لكل مكوّن على حدة.

> [!TIP]
> راجع [فحوصات التكامل](https://gist.github.com/LysandreJik/db4c948f6b4483960de5cbac598ad4ed) الخاصة بـ ELECTRA كمثال جيد على كيفية تفكيك النموذج إلى مكونات أصغر.

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

على سبيل المثال، تنفيذ [T5](https://github.com/tensorflow/mesh/tree/master/mesh_tensorflow) في MeshTensorFlow معقد للغاية ولا يوفر طريقة بسيطة لتفكيك النموذج إلى مكوّناته الفرعية. في هذه الحالة، ستضطر إلى الاعتماد على التحقق من عبارات الطباعة.

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

1. معرفات الإدخال المُمررة إلى النموذج
2. تضمينات الكلمات
3. مدخل طبقة Transformer الأولى
4. مخرجات طبقة Transformer الأولى
5. مخرجات طبقات Transformer التالية n-1
6. مخرجات النموذج بأكمله

يجب أن تكون المعرّفات المدخلة مجرد مصفوفة من الأعداد الصحيحة مثل `input_ids = [0, 4, 4, 3, 2, 4, 1, 7, 19]`.

غالبًا ما تتكون مخرجات الطبقات من مصفوفات فاصلة عشرية متعددة الأبعاد.

```py
[[
 [-0.1465, -0.6501,  0.1993,  ...,  0.1451,  0.3430,  0.6024],
 [-0.4417, -0.5920,  0.3450,  ..., -0.3062,  0.6182,  0.7132],
 [-0.5009, -0.7122,  0.4548,  ..., -0.3662,  0.6091,  0.7648],
 ...,
 [-0.5613, -0.6332,  0.4324,  ..., -0.3792,  0.7372,  0.9288],
 [-0.5416, -0.6345,  0.4180,  ..., -0.3564,  0.6992,  0.9191],
 [-0.5334, -0.6403,  0.4271,  ..., -0.3339,  0.6533,  0.8694]]],
```

يجب أن يكون لكل مخرجات نماذج Transformers دقة أو حد خطأ يقدر بـ *1e-3*. وهذا يأخذ في الاعتبار أي اختلافات في المخرجات تنشأ عن استخدام إطار عمل مكتبة مختلف. قارن المخرجات الوسيطة للنموذج الأصلي بتنفيذ Transformers للتأكد من أنها متطابقة تقريباً. إن وجود بيئة تصحيح أخطاء *فعالة* أمر بالغ الأهمية لهذه الخطوة.

إليك بعض النصائح لبناء بيئة تصحيح أخطاء فعّالة.

- لتصحيح الأخطاء في النتائج الوسيطة، يعتمد الأمر على إطار عمل تعلّم الآلة الذي يستخدمه مستودع النموذج الأصلي. بالنسبة إلى PyTorch، يجب عليك كتابة سكربت لتفكيك النموذج الأصلي إلى مكوّنات فرعية أصغر لاسترجاع القيم الوسيطة.

- يكون تصحيح الأخطاء أسرع عند استخدام نقطة تحقق مسبقة التدريب أصغر حجمًا مقارنةً بنقطة تحقق أكبر يستغرق فيها المرور الأمامي أكثر من 10 ثوانٍ. إذا لم تتوفر سوى نقاط تحقق كبيرة، أنشئ نموذجًا وهميًا بأوزان مهيأة عشوائيًا واحفظ تلك الأوزان للمقارنة مع تنفيذ مكتبة Transformers.

- ابحث عن أسهل طريقة لاستدعاء تمرير النموذج الأمامي. في المثالي، يجب أن يستدعي هذا الدالة (قد يُسمّى `predict` أو `evaluate` أو `forward` أو `__call__`) تمرير الأمام *مرة واحدة فقط*. فمن الأصعب تصحيح الأخطاء في دالة تستدعي تمرير الأمام عدة مرات.

- افصل الترميز (Tokenization) عن مسار التقدّم (Forward pass). حدّد المكان الذي تُحوَّل فيه مدخلات نصية إلى معرّفات المدخلات (Input ids) داخل مسار التقدّم، وابدأ من هناك. قد تحتاج إلى إنشاء سكربت صغير أو تعديل الكود الأصلي لإدخال معرّفات المدخلات مباشرةً بدلاً من النص المدخل.

- تأكد من أن النموذج *ليس* في وضع التدريب. فقد يؤدي ذلك إلى إنتاج مخرجات عشوائية بسبب وجود طبقات dropout متعددة في النموذج. يجب أن يكون التمرير الأمامي في بيئة التصحيح التي تستخدمها *حتمياً* حتى لا تُستخدم طبقات dropout.

بمجرد أن تتمكن من تشغيل نقطة التفتيش الأصلية، تكون مستعدًا لبدء تكييف كود النموذج لمكتبة Transformers.

## تكييف كود النموذج

يجب أن يكون الأمر `transformers add-new-model-like` قد أنشأ ملف نموذج وملف إعدادات.

- `src/transformers/models/brand_new_llama/modeling_brand_new_llama.py`
- `src/transformers/models/brand_new_llama/configuration_brand_new_llama.py`

يتميز الكود المولَّد تلقائيًا في ملف `modeling.py` بنفس البنية المعمارية الخاصة بـ Llama إذا أجبت بأنه نموذج مُفكِّك فقط، أو ستكون بنيته المعمارية مطابقة لتلك الخاصة بـ BART إذا أجبت بأنه نموذج مُرمِّز-مُفكِّك. الكود المولَّد ليس سوى نقطة انطلاق. بناءً على بحثك حول النموذج الجديد، ستحتاج إلى تنفيذ تلك التغييرات المحددة من خلال تكييف الكود المولَّد. وقد يشمل ذلك تغييرات في طبقة الانتباه الذاتي، وترتيب طبقة التطبيع، وما إلى ذلك.

### تهيئة النموذج

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

```py
from transformers import BrandNewLlama, BrandNewLlamaConfig
model = BrandNewLlama(BrandNewLlamaConfig())
```

تحدث التهيئة العشوائية في طريقة `_init_weights` الخاصة بـ `BrandNewLlamaPreTrainedModel`. يتم تهيئة جميع الوحدات الفرعية (leaf modules) بناءً على متغيرات الإعداد. استخدم الأدوات المساعدة من وحدة `transformers.initialization` لضبط القيم، بدلاً من استدعاء العمليات المباشرة على الوزن أو على `.data` الخاص به.

```py
from transformers import initialization as init

def _init_weights(self, module):
    """Initialize the weights"""
    if isinstance(module, nn.Linear):
        init.normal_(module.weight, mean=0.0, std=self.config.initializer_range)
        if module.bias is not None:
            init.zeros_(module.bias)
    elif isinstance(module, nn.Embedding):
        init.normal_(module.weight, mean=0.0, std=self.config.initializer_range)
        if module.padding_idx is not None:
            init.zeros_(module.weight[module.padding_idx])
    elif isinstance(module, nn.LayerNorm):
        init.zeros_(module.bias)
        init.ones_(module.weight)
```

يجب دائمًا تهيئة الأوزان من خلال أدوات المساعدة في `transformers.initialization`. العمليات التي تُنفَّذ في الموقع (In-place) مثل `module.bias.zero_()` أو أي شيء يمس `module.weight.data` يتجاوز `_is_hf_initialized` الذي يحدد المعاملات التي تم تحميلها بالفعل. يُنفّذ [from_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained) الدالة `_init_weights` بعد تحميل نقطة التفتيش (checkpoint)، لذا فإن العمليات التي تُنفَّذ في الموقع تُعيد كتابة الأوزان المحمّلة بقيم عشوائية بصمت. يُفرض هذا على نماذج Transformers من خلال قاعدة [TRF012](./modeling_rules#trf012).

> [!WARNING]
> أثناء [from_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained)، يتم عادةً تهيئة النماذج على جهاز `meta`. يعيد المُحمِّل إنشاء المخازن المؤقتة غير الدائمة كمُتجهات فارغة، لذا فإن القيم المُسندة في `__init__` لا تُحفظ. قم بتهيئة هذه المخازن المؤقتة في `_init_weights` حتى تمتلك القيم الصحيحة بعد التحميل. لمثال على ذلك، راجع كيفية تهيئة BERT لمعرّفات المواقع ومعرّفات أنواع الرموز.

قد يبدو مخطط التهيئة مختلفًا إذا كنت بحاجة إلى تكييفه مع نموذجك. يمكن لوحدة فرعية تحتوي على طريقة `reset_parameters` خاصة بها استدعاؤها مباشرة. على سبيل المثال، يهيّئ [Wav2Vec2ForPreTraining](/docs/transformers/main/ar/model_doc/wav2vec2#transformers.Wav2Vec2ForPreTraining) طبقتَي [nn.Linear](https://pytorch.org/docs/stable/generated/torch.nn.Linear.html) الأخيرتين في طبقاته الخطية. الاستدعاء آمن لأن [from_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained) يعدّل دوال `torch.nn.init` الأساسية لتتوافق مع علم `_is_hf_initialized` أثناء تشغيل `_init_weights`، مما يمنع تجاوز الأوزان المحمّلة.

```py
def _init_weights(self, module):
    """Initialize the weights"""
    if isinstance(module, Wav2Vec2ForPreTraining):
        module.project_hid.reset_parameters()
        module.project_q.reset_parameters()
```

### تحويل نقاط التفتيش إلى Transformers

يجب تحويل نقطة التفتيش الأصلية إلى نقطة تفتيش متوافقة مع Transformers.

> [!TIP]
> حاول البحث عن سكربت تحويل موجود لتُنسخه وتُكيّفه وتعيد استخدامه لنموذجك!
>
> - إذا كنت تنقل نموذجًا من TensorFlow إلى PyTorch، فقد يكون نقطة بداية جيدة هي [سكربت التحويل](https://github.com/huggingface/transformers/blob/7acfa95afb8194f8f9c1f4d2c6028224dbed35a2/src/transformers/models/bert/modeling_bert.py#L91) الخاص بـ BERT. - إذا كنت تنقل نموذجًا من PyTorch إلى PyTorch، فقد تكون نقطة بداية جيدة هي [سكربت التحويل](https://github.com/huggingface/transformers/blob/main/src/transformers/models/bart/convert_bart_original_pytorch_checkpoint_to_pytorch.py) الخاص بـ BART.

تأكد من أن **جميع** الأوزان المطلوبة تم تهيئتها، واطبع جميع أوزان نقطة التفتيش التي لم تُستخدم في التهيئة للتأكد من أن النموذج تم تحويله بشكل صحيح.

قد تواجه عبارات خاطئة تتعلق بالأشكال أو إسناد الأسماء أثناء التحويل. يرجح أن يكون السبب هو وجود معاملات غير صحيحة في `BrandNewLlamaConfig`، أو معمارية غير مناسبة، أو خطأ برمجي في طريقة `init` في تطبيقك، أو أنك بحاجة إلى تبديل أبعاد أحد أوزان نقطة الحفظ.

استمر في تكرار العمل على قسم [تكييف كود النموذج](#adapt-the-model-code) حتى يتم تحميل جميع أوزان نقطة الحفظ بشكل صحيح. بمجرد إمكانية تحميل نقطة حفظ في نموذجك، احفظها في مجلد. يجب أن يحتوي هذا المجلد على ملف `model.safetensors` وملف `config.json`.

```py
model.save_pretrained("/path/to/converted/checkpoint/folder")
```

لمساعدتك في عملية التحويل، يصف القسم التالي بإيجاز كيفية تخزين نماذج PyTorch وأوزان الطبقات وتسميتها.

#### أوزان طبقات PyTorch وأسمائها

من المفيد إنشاء نموذج PyTorch أساسي لفهم كيفية تعريف أسماء الطبقات وتبديل الأوزان.

```py
from torch import nn

class SimpleModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.dense = nn.Linear(10, 10)
        self.intermediate = nn.Linear(10, 10)
        self.layer_norm = nn.LayerNorm(10)
```

تُعرَّف أسماء طبقات PyTorch بواسطة اسم خاصية الفئة الخاصة بالطبقة (`dense`، `intermediate`، `layer_norm`). أنشئ كائنًا من `SimpleModel` لملء جميع الطبقات بأوزان عشوائية.

```py
model = SimpleModel()
print(model)
SimpleModel(
  (dense): Linear(in_features=10, out_features=10, bias=True)
  (intermediate): Linear(in_features=10, out_features=10, bias=True)
  (layer_norm): LayerNorm((10,), eps=1e-05, elementwise_affine=True)
)
```

تُهيّأ قيم الأوزان لطبقة محددة بشكل عشوائي.

```py
print(model.dense.weight.data)
tensor([[-0.0818,  0.2207, -0.0749, -0.0030,  0.0045, -0.1569, -0.1598,  0.0212,
         -0.2077,  0.2157],
        [ 0.1044,  0.0201,  0.0990,  0.2482,  0.3116,  0.2509,  0.2866, -0.2190,
          0.2166, -0.0212],
        [-0.2000,  0.1107, -0.1999, -0.3119,  0.1559,  0.0993,  0.1776, -0.1950,
         -0.1023, -0.0447],
        [-0.0888, -0.1092,  0.2281,  0.0336,  0.1817, -0.0115,  0.2096,  0.1415,
         -0.1876, -0.2467],
        [ 0.2208, -0.2352, -0.1426, -0.2636, -0.2889, -0.2061, -0.2849, -0.0465,
          0.2577,  0.0402],
        [ 0.1502,  0.2465,  0.2566,  0.0693,  0.2352, -0.0530,  0.1859, -0.0604,
          0.2132,  0.1680],
        [ 0.1733, -0.2407, -0.1721,  0.1484,  0.0358, -0.0633, -0.0721, -0.0090,
          0.2707, -0.2509],
        [-0.1173,  0.1561,  0.2945,  0.0595, -0.1996,  0.2988, -0.0802,  0.0407,
          0.1829, -0.1568],
        [-0.1164, -0.2228, -0.0403,  0.0428,  0.1339,  0.0047,  0.1967,  0.2923,
          0.0333, -0.0536],
        [-0.1492, -0.1616,  0.1057,  0.1950, -0.2807, -0.2710, -0.1586,  0.0739,
          0.2220,  0.2358]]).
```

في سكربت التحويل، يجب استبدال الأوزان العشوائية بالأوزان الدقيقة من الطبقة المقابلة في نقطة الفحص الأصلية.

```py
# retrieve matching layer weights with recursive algorithm
layer_name = "dense"
pretrained_weight = array_of_dense_layer

model_pointer = getattr(model, "dense")
model_pointer.weight.data = torch.from_numpy(pretrained_weight)
```

تحقق من أن الأوزان المُهيأة عشوائياً وأوزان نقطة الحفظ المُسبقة التدريب المقابلة لها لها **الشكل** و**الاسم** المتطابقان. أضف عبارات assert للشكل وطبع أسماء أوزان نقطة الحفظ.

```py
assert (
    model_pointer.weight.shape == pretrained_weight.shape
), f"Pointer shape of random weight {model_pointer.shape} and array shape of checkpoint weight {pretrained_weight.shape} mismatched"

logger.info(f"Initialize PyTorch weight {layer_name} from {pretrained_weight.name}")
```

عندما لا يتطابق الشكل أو الاسم، فقد تكون قد قمت بتعيين وزن نقطة التفتيش (checkpoint) غير الصحيح لطبقة تم تهيئتها عشوائياً. قد يكون السبب في الشكل غير الصحيح هو أن معاملات `BrandNewLlama` لا تتطابق تماماً مع معاملات النموذج الأصلي. لكن من الممكن أيضاً أن يتطلب تنفيذ طبقة PyTorch عكس الأوزان أولاً.

### تنفيذ المرور الأمامي

يجب تنفيذ المرور الأمامي (forward pass) تالياً إذا تم تحميل النموذج بشكل صحيح. فهو يستقبل بعض المدخلات ويعيد مخرجات النموذج.

```py
model = BrandNewLlamaModel.from_pretrained("/path/to/converted/checkpoint/folder")
input_ids = [0, 4, 4, 3, 2, 4, 1, 7, 19]
output = model.generate(input_ids).last_hidden_states
```

لا تدعك الإحباط إذا لم يكن مسار التقدّم لديك مطابقًا تمامًا للمخرجات من النموذج الأصلي، أو إذا أعاد خطأً. تأكد من أن مسار التقدّم لا يرمي أي أخطاء. وغالبًا ما يكون السبب في ذلك هو أن الأبعاد غير صحيحة، أو لأن نوع البيانات المستخدم غير صحيح ([torch.long](https://pytorch.org/docs/stable/generated/torch.Tensor.long.html) بدلاً من [torch.float32](https://pytorch.org/docs/stable/tensors.html)).

يجب أن تكون دقة مخرجاتك *1e-3*. تأكد من أن أشكال المخرجات وقيم المخرجات متطابقة تماماً. تشمل الأسباب الشائعة لعدم تطابق المخرجات ما يلي:

- لم تتم إضافة بعض الطبقات (طبقة التنشيط أو اتصال متبقٍ).
- لا يتم ربط مصفوفة تضمين الكلمات.
- تُستخدم تضمينات موضعية خاطئة لأن التنفيذ الأصلي يتضمن إزاحة.
- يُطبَّق Dropout أثناء المرور الأمامي. صحّح هذا الخطأ عن طريق التأكد من أن `model.training` هو `False` ومرر `self.training` إلى [torch.nn.functional.dropout](https://pytorch.org/docs/stable/nn.functional.html?highlight=dropout#torch.nn.functional.dropout).

قارن بين المرور الأمامي (forward pass) للنموذج الأصلي وتنفيذك للتحقق من وجود أي اختلافات. بشكل مثالي، قم بتشخيص الأخطاء وطباعة المخرجات الوسيطة لكلتا التنفيذات الخاصة بالمرور الأمامي لتحديد المكان الذي يختلف فيه التنفيذ الأصلي عن تنفيذك.

1. تأكد من أن `input_ids` المُثبّتة يدويًا في كلا التنفيذين متطابقتان.
2. تحقق من أن مخرجات التحويل الأول لـ`input_ids` (وهي عادةً تضمينات الكلمات) متطابقة، ثم تابع الفحص حتى الطبقة الأخيرة.

يجب أن يشير أي فرق بين التنفيذين إلى وجود خطأ في تنفيذك.

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

عندما تنتج كلتا التنفيذات نفس المخرجات، تحقق من أن المخرجات ضمن دقة *1e-3*.

```py
torch.allclose(original_output, output, atol=1e-3)
```

عادةً ما تكون هذه هي الأصعب في العملية. تهانينا إذا وصلتَ إلى هذه المرحلة!

وإذا واجهتَ صعوبةً أو تعثّرتَ في هذه الخطوة، فلا تتردد في طلب المساعدة على طلب الإرسال الخاص بك.

### إضافة اختبارات النموذج

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

يجب أن يكون [Cookiecutter](https://cookiecutter.readthedocs.io/en/stable/) قد أضاف ملف اختبار لنموذجك. شغّل ملف الاختبار أدناه للتأكد من نجاح جميع الاختبارات الشائعة.

```bash
pytest tests/models/brand_new_llama/test_modeling_brand_new_llama.py
```

يجب إضافة اختبارات التكامل أولاً لأنها تخدم الغرض نفسه الذي خدمته سكربتات التصحيح التي استخدمتها سابقاً لتنفيذ النموذج الجديد في Transformers. وقد أضاف Cookiecutter قالباً لتلك اختبارات النموذج، `BrandNewLlamaModelIntegrationTests`، ويجب ملؤه. ولضمان نجاحه، نفّذ الأمر التالي.

```bash
RUN_SLOW=1 pytest -sv tests/models/brand_new_llama/test_modeling_brand_new_llama.py::BrandNewLlamaModelIntegrationTests
```

```bash
SET RUN_SLOW=1 pytest -sv tests/models/brand_new_llama/test_modeling_brand_new_llama.py::BrandNewLlamaModelIntegrationTests
```

يجب اختبار جميع الميزات الفريدة لـ BrandNewLlama في اختبار منفصل تحت `BrandNewLlamaModelTester/BrandNewLlamaModelTest`. غالبًا ما يُغفل هذا الاختبار، لكنه بالغ الأهمية لأن:

- يساعد في نقل المعرفة التي اكتسبتها خلال العملية إلى المجتمع من خلال توضيح كيفية عمل الميزات الجديدة للنموذج
- يمكن للمساهمين المستقبليين اختبار التغييرات على النموذج بسرعة من خلال تشغيل هذه الاختبارات الخاصة

## تنفيذ مُجزِّئ

> [!TIP]
> نوصي بإضافة مُقسِّم سريع ([PreTrainedTokenizerFast](/docs/transformers/main/ar/main_classes/tokenizer#transformers.TokenizersBackend)) لمنح المستخدمين أفضل أداء. لا تتردد في الإشارة إلى [@ArthurZucker](https://github.com/ArthurZucker) أو [@itazap](https://github.com/itazap) في طلب الإرسال الخاص بك للحصول على مساعدة حول كيفية إضافة [PreTrainedTokenizerFast](/docs/transformers/main/ar/main_classes/tokenizer#transformers.TokenizersBackend).

بعد الانتهاء من النموذج، حان الوقت للتركيز على مُجزّئ النص. يجب أن يكون مُجزّئ النص مطابقًا أو مشابهًا جدًا لمُجزّئ نص موجود مسبقًا في Transformers.

ابحث عن ملف المُجزِّئ (tokenizer) الأصلي وحمله إلى تطبيقك. أنشئ سكربتًا في المستودع الأصلي يستقبل نصًا ويعيد `input_ids`. يجب أن يشبه الشيفرة الزائفة (pseudocode) الشيفرة أدناه.

```py
input_str = "This is a long example input string containing special characters .$?-, numbers 2872 234 12 and words."
model = BrandNewLlamaModel.load_pretrained_checkpoint("/path/to/checkpoint/")
input_ids = model.tokenize(input_str)
```

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

```py
from transformers import BrandNewLlamaTokenizer

input_str = "This is a long example input string containing special characters .$?-, numbers 2872 234 12 and words."
tokenizer = BrandNewLlamaTokenizer.from_pretrained("/path/to/tokenizer/folder/")
input_ids = tokenizer(input_str).input_ids
```

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

## تنفيذ معالج الصور

> [!TIP]
> تستخدم معالجات الصور الآن معمارية مبنية على الخلفية (backend). الخلفية الافتراضية هي [TorchvisionBackend](/docs/transformers/main/ar/main_classes/image_processor#transformers.TorchvisionBackend)، والتي تستخدم مكتبة [torchvision](https://pytorch.org/vision/stable/index.html) ويمكنها تنفيذ معالجة الصور على وحدة معالجة الرسوميات (GPU). كما يتم توفير خلفية بديلة تعتمد على PIL/NumPy ([PilBackend](/docs/transformers/main/ar/main_classes/image_processor#transformers.PilBackend)). يتم استيراد الخلفيتين من `image_processing_backends`. لا تتردد في الإشارة إلى [@yonigozlan](https://github.com/yonigozlan) للحصول على المساعدة.

على الرغم من أن هذا المثال لا يتضمن معالج صور، فقد تحتاج إلى تنفيذ معالج صور إذا كان نموذجك يتطلب مدخلات على شكل صور. يتولى معالج الصور مسؤولية تحويل الصور إلى صيغة مناسبة لنموذجك. قبل تنفيذ معالج صور جديد، تحقق مما إذا كان يمكن إعادة استخدام معالج صور موجود في مكتبة Transformers، حيث تشترك العديد من النماذج في تقنيات معالجة صور متشابهة. لاحظ أنه يمكنك أيضًا استخدام [modular](./modular_transformers) لمعالجات الصور لإعادة استخدام المكونات الموجودة.

إذا كنت بحاجة إلى تنفيذ معالج صور جديد، فإن لكل نموذج ملفَي معالج:

- `image_processing_<model>.py`: المعالج **الافتراضي** المدعوم من torchvision (`<Model>ImageProcessor`)، والذي يرث من [TorchvisionBackend](/docs/transformers/main/ar/main_classes/image_processor#transformers.TorchvisionBackend). يحل هذا المعالج محل المعالج "السريع" القديم.
- `image_processing_pil_<model>.py`: المعالج البديل المعتمد على PIL/NumPy (`<Model>ImageProcessorPil`)، والذي يرث من [PilBackend](/docs/transformers/main/ar/main_classes/image_processor#transformers.PilBackend). يستبدل هذا المعالج القديم "البطيء".

يحدد ملف torchvision backend أيضًا أي فئة kwargs مخصصة يستوردها ملف PIL. يستخدم كلا الملفين زخرفة `@auto_docstring` — لا تضف سطور توثيق يدوية للفئات. راجع [IMAGE_PROCESSOR_REFACTORING_GUIDE.md](https://github.com/huggingface/transformers/blob/main/IMAGE_PROCESSOR_REFACTORING_GUIDE.md) للحصول على شرح خطوة بخطوة وأمثلة كاملة.

أضِف اختبارات لمعالج الصور في `tests/models/your_model_name/test_image_processing_your_model_name.py`. يجب أن تكون هذه الاختبارات مشابهة لتلك الخاصة بمعالجات الصور الأخرى، وأن تتحقق من أن معالج الصور يتعامل مع مدخلات الصور بشكل صحيح. إذا تضمن معالج الصور ميزات أو طرق معالجة فريدة، فتأكد من إضافة اختبارات محددة لها أيضاً.

## تنفيذ المعالج

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

يجب أن يستدعي المعالج المعالجات الخاصة بكل نمط من الأنماط داخل دالة `__call__` الخاصة به للتعامل مع كل نوع من المدخلات بشكل صحيح. تأكد من فحص المعالجات الموجودة في المكتبة لفهم بنيتها المتوقعة. يستخدم Transformers الاتفاق التالي في توقيع دالة `__call__`.

```python
def __call__(
    self,
    images: ImageInput = None,
    text: Union[TextInput, PreTokenizedInput, list[TextInput], list[PreTokenizedInput]] = None,
    audio=None,
    videos=None,
    **kwargs: Unpack[YourModelProcessorKwargs],
) -> BatchFeature:
    ...
```

`YourModelProcessorKwargs` هو `TypedDict` يتضمن جميع معاملات المعالجة النموذجية وأي معاملات إضافية قد يتطلبها معالج محدد.

أضِف اختبارات للمعالج في `tests/models/your_model_name/test_processor_your_model_name.py`. يجب أن تكون هذه الاختبارات مشابهة لتلك الخاصة بالمعالجات الأخرى، وأن تتحقق من أن المعالج يتعامل بشكل صحيح مع الأنماط المختلفة.

## اختبارات التكامل

الآن وبعد أن حصلت على النموذج ومُقسِّم النص، أضف اختبارات تكامل من الطرف إلى الطرف للنموذج ومُقسِّم النص في `tests/models/brand_new_llama/test_modeling_brand_new_llama.py`.

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

إذا لم يتم ضبط نقطة التفتيش (checkpoint) على مهمة فرعية، فإن اختبارات النموذج كافية.

أخيرًا، حاول التأكد من أن اختباراتك يمكن تشغيلها على وحدة معالجة رسومية (GPU) عن طريق إضافة عبارات `.to(self.device)` إلى المصفوفات الداخلية للنماذج. إذا لم يكن لديك وصول إلى وحدة معالجة رسومية، يمكننا التعامل مع ذلك نيابةً عنك.

## إضافة التوثيق

لا يكون نموذجك مفيداً إلا إذا عرف المستخدمون كيفية استخدامه. ولهذا السبب من المهم إضافة التوثيق وسلاسل التوثيق (docstrings). أضاف Cookiecutter ملف قالب، `docs/source/model_doc/brand_new_llama.md`، يمكنك ملؤه بالمعلومات المتعلقة بنموذجك.

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

تأكد من إضافة توثيق الدوال (docstrings) إلى `src/transformers/models/brand_new_llama/modeling_brand_new_llama.py` وأن يتضمن جميع المدخلات والمخرجات اللازمة. راجع [دليلنا](https://github.com/huggingface/transformers/tree/main/docs#writing-documentation---specification) لكتابة التوثيق وتوثيق الدوال.

## إعادة هيكلة

حان الوقت لتنظيم الأمور والتأكد من أن نمط الكود متسق مع بقية المكتبة. نفّذ الأمر التالي لإصلاح الأنماط غير الصحيحة تلقائيًا.

```bash
make style
```

للتحقق من أن نمط الكود يجتاز فحوصات الجودة، نفّذ الأمر أدناه.

```bash
make check-repo
```

قد توجد اختبارات أو فحوصات أخرى فاشلة (مثل غياب سلسلة التوثيق أو تسمية غير صحيحة) في طلب السحب الخاص بك بسبب اختبارات التصميم الصارمة في Transformers. يمكننا مساعدتك في هذه المشكلات إذا واجهت صعوبة في حلها.

بعد التأكد من أن الكود يعمل بشكل صحيح، قد ترغب في إعادة هيكلة الكود لجعله أكثر قابلية للقراءة أو أنظف.

## الرفع إلى المستودع

قم بتحويل جميع نقاط التفتيش (checkpoints) ورفعها إلى [Hub](https://hf.co/models). أضف بطاقة نموذج (model card) لتوفير مزيد من الشفافية والسياق حول النموذج. يجب أن تُبرز بطاقة النموذج خصائص محددة لنقطة التفتيش، وكيفية تدريب النموذج، وأمثلة على الأكواد توضح كيفية استخدامه.

> [!TIP]
> في كثير من الحالات، يُعدّ إضافة دفتر ملاحظات تفاعلي يمكن للمستخدمين تشغيله طريقة رائعة لعرض كيفية استخدام النموذج للاستدلال أو ضبطه الدقيق على مهمة لاحقة. وعلى الرغم من أن تضمين دفتر ملاحظات ليس إلزاميًا، إلا أنه يمكن أن يساهم في زيادة اعتماد مجتمع المستخدمين على نموذجك.

يجب عليك أيضاً الاستشارة مع فريق Transformers لتحديد اسم مناسب للنموذج، والحصول على صلاحيات الوصول المطلوبة لرفع النموذج.

استخدم طريقة [push_to_hub()](/docs/transformers/main/ar/main_classes/model#transformers.utils.PushToHubMixin.push_to_hub) لرفع النموذج.

```py
brand_new_bert.push_to_hub("brand_new_llama")
```

راجع دليل [المشاركة](./model_sharing) لمزيد من المعلومات حول رفع النماذج إلى Hub.

## دمج نموذجك

أنت مستعد أخيرًا لدمج طلب السحب الخاص بك وإضافة النموذج إلى Transformers بشكل رسمي! تأكد من أن جميع الاختبارات ناجحة وأن جميع التعليقات والملاحظات قد تمت معالجتها.

تهانينا على إضافة نموذج جديد إلى Transformers! 🥳

هذا مساهمة ذات أهمية كبيرة. عملك يجعل Transformers أكثر سهولة في الوصول للمطورين والباحثين حول العالم. يجب أن تفخر بمساهمتك وتشارك إنجازك مع المجتمع!

## انظر أيضاً

- [قواعد بنية النموذج](./modeling_rules) — قواعد ثابتة تُفرض على جميع ملفات `modeling_*.py` و`configuration_*.py`. نفّذ `make typing` للتحقق منها قبل فتح طلب دمج.
- [فحوصات طلبات الدمج](./pr_checks) — مرجع كامل للفحوصات التي يجريها نظام التكامل المستمر على طلب الدمج الخاص بك وكيفية اجتيازها.

