# فحوصات طلبات الدمج

عند فتح طلب سحب، يقوم نظام Hugging Face CI بتشغيل عدة فحوصات يجب أن تنجح قبل إمكانية دمج طلب السحب الخاص بك.

- يُدرج [إصلاح CI](#fixing-the-ci) الأوامر التي يجب تشغيلها محلياً لاجتياز الفحوصات.
- تصف الأقسام التالية ما يتحقق منه كل فحص، مثل [جودة الكود](#code-quality) و[اتساق المستودع](#repository-consistency).
- تصف [الاختبارات](#tests) الاختبارات التي يتم تشغيلها، وفئات الاختبارات، والاختبارات البطيئة.

## إصلاح CI

في معظم الحالات، يكفي استخدام `make style` لتجاوز فحص جودة الكود، وهو السبب الأكثر شيوعاً للفشل.

```bash
make style
```

في حال وجود أخطاء في اتساق المستودع أو النسخ أو الملفات المولّدة تلقائيًا، شغّل `make fix-repo`. يقوم هذا الأمر بإصلاح الأسلوب والنسخ وسلاسل التوثيق والملفات المولّدة تلقائيًا في عملية واحدة.

```bash
make fix-repo
```

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

```bash
make fix-repo   # auto-fix everything that can be auto-fixed
make typing     # check types and model structure, fix any errors manually
make check-repo # verify all checks pass, fix anything that remains
```

يكتشف `make typing` أخطاء الأنواع ومخالفات بنية النموذج التي تُصحَّح يدويًا. أما `make check-repo` فيقوم بمرحلة نهائية للقراءة فقط لتأكيد جاهزية كل شيء.

> [!NOTE]
> تكون اختبارات التكامل المستمر (CI) غير مستقرة في بعض الأحيان. إذا فشل فحص بسبب شيء لا يتعلق بتغييراتك، فاطلب من أحد المشرفين إعادة تشغيله.

## جودة الكود

يتناول فحص جودة التنسيق، والاستيرادات، وفحص الأنواع، وقواعد بنية النموذج. وهو يقابل `make fix-repo` و`make typing`.

`make style` (المشتمل في `make fix-repo`) يُصلح تلقائيًا تنسيق [Ruff](https://docs.astral.sh/ruff/) وتنسيقه، وترتيب استيرادات `__init__.py`، واتساق الخرائط التلقائية.

يُجري `make typing` فحص الأنواع باستخدام [ty](https://docs.astral.sh/ty/) ويتحقق من قواعد TRansFormers (TRF)، التي تشمل تسميات فئات الإعدادات وتواقيع `forward()`. تُبلّغ أخطاء الأنواع ومخالفات TRF عن رقم قاعدة محددة، ويجب تصحيحها يدوياً. توجد القواعد في مستودع [mlinter](https://github.com/huggingface/transformers-mlinter). شغّل `python -m utils.mlinter --list-rules` لعرض جميع قواعد TRF، أو `python -m utils.mlinter --rule TRFXXX` لعرض التوثيق الكامل لقاعدة محددة.

إذا احتاجت قاعدة TRF إلى استثناء، فاختر أحد هذه الخيارات (راجع [كبت الانتهاكات](./modeling_rules#suppressing-violations) لمزيد من التفاصيل).

- أضف اسم النموذج الخاص بك إلى قائمة `allowlist_models` للقاعدة ذات الصلة في `utils/mlinter/rules.toml`. استخدم هذا عندما يحتاج ملف النموذج بأكمله إلى استثناء.
- أضف `# trf-ignore: TRFXXX` في نفس السطر الذي يحتوي على البنية المُعلَّمة، أو في السطر الذي يسبقها مباشرةً. استخدم هذا عندما تحتاج إلى استثناء لبنية مُعلَّمة واحدة فقط.

## اتساق المستودع

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

| الفئة | ما يتم التحقق منه | تم إصلاحه تلقائيًا؟ |
|---|---|---|
| ملفات Init | ملفات `__init__.py` الموجودة في `src/transformers/models/` محدّثة  | `make fix-repo` |
| النسخ والوحدات | تطابق كتل `# Copied from` مع مصدرها، وملفات التوليد المعيارية محدّثة | `make fix-repo` |
| سلاسل التوثيق والتوثيق | تطابق وثائق الوصف (docstrings) للباراميترات مع توقيعات الدوال وفهرس المحتويات | `make fix-repo` |
| الملفات المولّدة تلقائيًا | المتغيرات الوهمية، أنواع خطوط الأنابيب، قائمة doctest، البيانات الوصفية، جدول التبعيات | `make fix-repo` |
| التحقق من صحة الإعداد | تحتوي فئات الإعداد على نقاط تحقق صالحة في توثيق الدوال، وتتطابق سمات الإعداد مع ملف النمذجة | دليل |
| تعيين المراجع | كل دليل نموذج، وكل قاعدة في ملف المراجع، تصل إلى مراجع | دليل |

## تعيين المراجع

عندما يُعلَّم طلب الدمج بأنه جاهز للمراجعة، يطلب سير عمل `Assign PR Reviewers` ما يصل إلى مراجعين اثنين، مرتبين حسب عدد الأسطر التي يغيّرها طلب الدمج في الملفات التي يملكونها. لا يُسند أي مراجعين لطلب الدمج المسودة حتى يخرج من حالة المسودة. يقع سير العمل نفسه في [huggingface/transformers-ci](https://github.com/huggingface/transformers-ci) ويستدعيه هذا المستودع؛ وما يبقى هنا هو بيانات الملكية التي يقرؤها.

يتم تحديد الملكية لكل ملف على حدة، مع إعطاء الأولوية للأكثر تحديداً.

| حيث | يبدو أن | استخدمه ل |
|---|---|---|
| ملف النموذج | `# Reviewers: @login` في كتلة التعليق التمهيدية لـ `modular_<model>.py` أو `modeling_<model>.py` | نموذج يحتاج إلى شخص غير مالك نمطه. ينسخ المحوّل المعيّن الترويسة إلى ملف النمذجة المولّد، لذا يبقى الوسم قائماً بعد إعادة التوليد |
| قاعدة مسار | `/src/transformers/<area>/ @login` في `.github/scripts/codeowners_for_review_action` | أي شيء ليس نموذجًا |
| جدول النمط | `@@modality/vision @login`، في الملف نفسه | كل نموذج توجد صفحة مستنداته في ذلك القسم من `docs/source/en/_toctree.yml` |
| الحالة العامة | `* @Rocketknight1 @ArthurZucker` | ما لم يدّعيه أي شيء آخر |

لا يحتاج النموذج الجديد إلى إدراج في أي مكان: فإضافة صفحة توثيقه إلى `_toctree.yml`، وهو ما يفرضه فحص فهرس توثيق المحتوى مسبقاً، يضعه ضمن نمط، ويتولى جدول الأنماط تغطيته من هناك.

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

لا يمكن لطلب الاستحواذ إعادة توجيه مراجعته الخاصة. يُقرأ `.github/scripts/codeowners_for_review_action` من الفرع الأساسي، وليس من رأس طلب الاستحواذ أبدًا، ويمنع بواب الأمان الخاصة بالاختبار المستمر لطلبات الاستحواذ أي طلب استحواذ غير صادر عن متعاون من لمس أي شيء خارج `src/` و`tests/` و`docs/` و`utils/` — وهذا هو السبب في وجود ذلك الملف في مكانه. يُقرأ وسم `# Reviewers:` من الرأس، نظرًا لأن نموذجًا جديدًا يصل معه، لذا فإن كل تسجيل دخول يُذكر فيه يخضع لفحص المتعاون قبل أن يُطلب من أي شخص.

`make check-repository-consistency` يشغّل `utils/check_reviewers.py`، والذي يفشل عندما لا يصل نموذج إلى أي شخص سوى المُستقبِل العام، أو عندما لم تعد قاعدة تطابق أي ملف، أو عندما لا تتطابق جدول الوسائط مع فهرس المحتويات. يتشارك هذا الفاحص محلّله مع سير عمل إسناد المراجعات، لذا لا يمكن أن يختلف الاثنان. هذا المحلّل ليس من تبعيات `transformers`؛ بل هو مدرج في `utils/checkers-requirements.txt`، والذي يثبّته مشغّل الفاحص عند أول تشغيل له في بيئة. إذا تعذّر التثبيت — مثلًا عند عدم توفر اتصال بالإنترنت — فإن الفاحص يُبلّغ عن ذلك ويمرّ بدلاً من أن يعيق عملك. المسارات خارج `src/transformers/models` التي لا يوجد لها مالك تُبلَّغ عنها كملاحظة؛ اذكرها باستخدام:

```bash
python utils/check_reviewers.py --strict
```

## الاختبارات

تنفّذ CI مجموعة فرعية مستهدفة من الاختبارات بناءً على ما يغيّره طلب الدمج الخاص بك. وتنفّذ CI الاختبارات بترتيب عشوائي إلى حدٍّ ما باستخدام [pytest-random-order](https://github.com/jbasko/pytest-random-order) لكشف الاختبارات المترابطة. وتطبع عملية التشغيل البذرة العشوائية في البداية حتى تتمكن من إعادة تشغيل نفس الترتيب باستخدام `--random-order-seed=<seed>`.

إذا نجح اختبار محليًا على وحدة معالجة رسومية (GPU) لكنه فشل في بيئة التكامل المستمر (CI)، فاضبط `TRANSFORMERS_TEST_DEVICE="cpu"` للتحقق مما إذا كان بإمكانك إعادة إنتاج الفشل على وحدة المعالجة المركزية (CPU).

```bash
TRANSFORMERS_TEST_DEVICE="cpu" pytest tests/models/my_model/ -v
```

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

### اختيار الاختبار

لا ينفّذ CI مجموعة الاختبارات الكاملة مع كل طلب دمج. يتخطى CI الاختبارات المزينة بـ`@slow` مع كل طلب دمج، ويطلقها صانع المحتوى على وحدة معالجة الرسوميات (GPU) عندما يدخل الطلب مرحلة المراجعة.

يتتبع `utils/tests_fetcher.py` اعتماديات الاستيراد من الملفات التي قمت بتعديلها لتحديد الاختبارات المتأثرة، ثم يشغّل تلك الاختبارات فقط. كما يلتقط أي انكسارات في نماذج أخرى عند تعديلك للأدوات المشتركة. يطبع المُجلب الملفات التي تغيّرت والاختبارات المتأثرة، ثم يكتب القائمة في `tests_torch_test_list.txt`.

استخدم أداة الاستخراج fetcher لتكرار ما ينفذه CI بالضبط.

```bash
python utils/tests_fetcher.py
python -m pytest -n 8 --dist=loadfile -rA -s $(cat test_preparation/tests_torch_test_list.txt)
```

> [!TIP]
> يؤدي تغيير الملفات الأساسية مثل `modeling_utils.py` أو `generation/utils.py` إلى تشغيل جميع اختبارات النماذج، وليس فقط المجموعة المتأثرة.

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

```bash
pytest tests/models/my_model/ -v
```

### فئات مهام الاختبار

تُقسَّم الاختبارات على مهام CI متوازية، حيث يختار كل مهمة الملفات بناءً على نمط المسار. والمهام ذات الصلة بطلب نموذج هي:

- `tests_torch`: اختبارات النمذجة (`tests/models/*/test_modeling_*.py`)
- `tests_tokenization`: اختبارات المرمّز (`tests/models/*/test_tokenization_*.py`)
- `tests_processors`: اختبارات المعالج ومستخرج الميزات (`tests/models/*/test_(processing|image_processing|feature_extractor)_*.py`)
- `tests_generate`: اختبارات التوليد
- `pipelines_torch`: اختبارات خط المعالجة
- `tests_training_ci`: اختبارات حلقة التدريب
- `tests_tensor_parallel_ci`: اختبارات التوازي على مستوى الموتر
- `tests_fsdp_ci`: اختبارات FSDP

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

تتخطى عمليات CI العادية الاختبارات المُزيَّنة بـ `@slow`. فهي تُحمِّل نقاط تفتيش حقيقية أو تتطلب قدرًا كبيرًا من الحوسبة، لذا تُنفَّذ على أجهزة GPU، ويطلقها المسؤولون عندما يكون طلب المساهمة الخاص بك قيد المراجعة.

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

شغّل الاختبارات البطيئة محليًا باستخدام الأمر أدناه.

```bash
RUN_SLOW=1 python -m pytest tests/models/my_model/ -v
```

### بناء التوثيق

يُشغّل مهمة `build_pr_documentation` عملية بناء وتوليد معاينة للتوثيق. يقوم روبوت بنشر رابط المعاينة في طلب الإرسال الخاص بك، ويجب أن يجتاز الفحص قبل الدمج. معظم حالات الفشل سببها إدخال مفقود في `toctree`. لبناء التوثيق محليًا، راجع [README.md](https://github.com/huggingface/transformers/tree/main/docs) في مجلد التوثيق.

## `# Copied from` syntax

> [!WARNING]
> بالنسبة إلى النماذج الجديدة، يُفضَّل دائمًا استخدام [سير العمل المعياري](modular_transformers) (`modular_*.py`) بدلاً من `# Copied from`. تجنّب استخدام `# Copied from` قدر الإمكان.

يحافظ آلية `# Copied from` على مزامنة الكود المنسوخ مع مصدره. عند تشغيل `make fix-repo`، يتحقق من كل كتلة `# Copied from` ويحدّثها لتطابق الأصل، لذا تُستبدل أي تعديلات داخل كتلة `# Copied from`. عدّل المصدر بدلاً من ذلك ودع `make fix-repo` ينشر التغيير.

تشمل الأشكال الأساسية لـ `# Copied from` ما يلي.

```py
# Copied from transformers.models.bert.modeling_bert.BertSelfOutput

# Copied from transformers.models.bert.modeling_bert.BertAttention with Bert->Roberta

# Copied from transformers.models.bert.modeling_bert.BertForSequenceClassification with Bert->MobileBert all-casing
```

تُطبّق صياغة `with model->newModel` استبدالات النصوص بعد النسخ. افصل بين الاستبدالات المتعددة بفواصل، حيث تُطبَّق من اليسار إلى اليمين. يستبدل الخيار `all-casing` جميع أشكال التباين بين الأحرف الكبيرة والصغيرة دفعة واحدة (تصبح `Bert` و`bert` و`BERT` على التوالي `MobileBert` و`mobilebert` و`MOBILEBERT`).

