# إعادة تعريف طرق Trainer

أنشئ فئة فرعية من طرق [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) لتغيير سلوك التدريب دون إعادة كتابة الحلقة بأكملها. يعدّل إنشاء فئة فرعية *حلقة التدريب*، على سبيل المثال المرور الأمامي أو حساب الخسارة.

قبل إنشاء فئة فرعية، فكّر فيما إذا كنت بحاجة إلى تغيير *ما* يحسبه [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) أو *متى* و*ما إذا كان* يتخذ إجراءً. أما للتحكم في التوقيت والمنطق الشرطي، فاستخدم [Callback](./trainer_callbacks) بدلاً من ذلك. تتحكم الـ Callbacks في توقيت حدوث الأمور (مثل التسجيل والتقييم والتوقف المبكر)، بينما يغيّر إنشاء فئة فرعية طبيعة ما يحدث (مثل حساب الخسارة وتحميل البيانات والتحسين).

> [!NOTE]
> راجع توثيق واجهة [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) للحصول على قائمة كاملة بالطرق التي يمكنك إنشاء فئة فرعية منها. يمكن أيضًا تجاوز الطرق الخاصة (المسبوقة بـ `_`) مثل `_save_checkpoint` أو `_evaluate`، لكن قد تتغير هذه الطرق دون إشعار مسبق.

## get_train_dataloader

تحمّل الطريقة القياسية [get_train_dataloader()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.get_train_dataloader) دفعة واحدة، وتدرّب عليها، ثم تتخلّى عنها وتحمّل الدفعة التالية.

```py
def get_train_dataloader(self):
    return self._get_dataloader(
        batch_size=self._train_batch_size,
        ...
)
```

[GRPO](https://huggingface.co/docs/trl/en/grpo_trainer) هو خوارزمية تعلّم تعزيزي تفاعلي تولّد إكمالات قبل التدريب عليها. توليد الإكمالات في كل خطوة مكلف لأنه ذاتي التراجع. فإكمال من 512 رمزًا يتطلب نحو 512 تمريرة أمامية متسلسلة، مقارنةً بتمريرة أمامية واحدة لخطوة التدريب. [GRPOTrainer](https://huggingface.co/docs/trl/main/en/grpo_trainer#trl.GRPOTrainer) هو فئة فرعية من [get_train_dataloader()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.get_train_dataloader) تُجمّع التوليد عبر عدة خطوات.

يحمّل `trl.GRPOTrainer.get_train_dataloader` *دفعات* من موجهات التوليد لعدة خطوات تدريب دفعة واحدة، وذلك بضرب حجم الدفعة في معامل `steps_per_generation`. فإذا كان `train_batch_size=4` و`steps_per_generation=8`، فإن مُحمِّل البيانات ينتج دفعات من 32، مما يقلّل تكلفة التوليد إلى ثُمنها.

```py
def get_train_dataloader(self):
    dataloader_params = {
        "batch_size": self._train_batch_size * self.args.steps_per_generation, # this is the only change
        ...
    }
```

## حساب الخسارة

يعيد [compute_loss()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.compute_loss) خسارة الانتروبيا المتقاطعة التي يحسبها النموذج.

```py
def compute_loss(self, model, inputs, return_outputs=False, num_items_in_batch=None):
    ...
    outputs = model(**inputs)
    ...
    loss = outputs["loss"] # get loss from model

    return (loss, outputs) if return_outputs else loss
```

تقيس [DPO](https://huggingface.co/docs/trl/en/dpo_trainer) مدى تفضيل نموذج السياسة للاستجابة المختارة على المستبعدة، مقارنةً بنموذج مرجعي. وتُعرّف فئة [DPOTrainer](https://huggingface.co/docs/trl/main/en/dpo_trainer#trl.DPOTrainer) الدالة [compute_loss()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.compute_loss) لأن حساب الدالة الخاسرة يختلف عن الانتروبيا المتقاطعة القياسية بعدة طرق:

- لا ترى النموذج التسميات أبدًا؛ بل يعيد فقط قيم logits ليحسب DPO منها الاحتمالات اللوغاريتمية.
- تُدمج الاستجابات المختارة والمستبعدة
- يحسب نموذج المرجع احتمالات السجلات الخاصة به
- الدالة الخاسرة هي دالة في `π_chosen`، `π_rejected`، `π_ref_chosen`، `π_ref_rejected`

لا يناسب أيٌّ مما ذُكر أعلاه الطريقة القياسية [Trainer.compute_loss()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.compute_loss).

```py
def compute_loss(
    self,
    model: PreTrainedModel | nn.Module,
    inputs: dict[str, torch.Tensor | Any],
    return_outputs=False,
    num_items_in_batch=None,
) -> torch.Tensor | tuple[torch.Tensor, dict[str, float]]:
    ...
    outputs = model(**inputs)
    logits = outputs.logits
    logps = get_logps(logits, inputs)
    chosen_logps, rejected_logps = logps.chunk(2, dim=0)  # batch is [chosen, rejected]
    ref_logits = self.ref_model(**inputs).logits
    ref_logps = get_logps(ref_logits, inputs)
    ref_chosen_logps, ref_rejected_logps = ref_logps.chunk(2, dim=0)  # batch is [chosen, rejected]
    chosen_scores = chosen_logps - ref_chosen_logps
    rejected_scores = rejected_logps - ref_rejected_logps
    per_sequence_loss = -F.logsigmoid(self.beta * chosen_scores - rejected_scores)
    loss = per_sequence_loss.mean()
    return (loss, outputs) if return_outputs else loss
```

## الخطوات التالية

- لمزيد من الأمثلة الواقعية، راجع كيف يوسّع [GRPOTrainer](https://huggingface.co/docs/trl/main/en/grpo_trainer#trl.GRPOTrainer) و[DPOTrainer](https://huggingface.co/docs/trl/main/en/dpo_trainer#trl.DPOTrainer) كلاسي [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) في TRL، أو كيف يبني [Axolotl](https://github.com/axolotl-ai-cloud/axolotl/tree/main/src/axolotl/core/trainers) مدرّبين مخصّصين فوقه.
- راجع دليل [Callbacks](./trainer_callbacks) إذا كنت بحاجة فقط إلى تخصيص ما يحدث أثناء حدث تدريب، مثل تسجيل المقاييس في نهاية خطوة تدريب.

