# النمذجة اللغوية السببية

توجد نوعان من نمذجة اللغة: السببي والمقنّع. يوضح هذا الدليل نمذجة اللغة السببية. تُستخدم نماذج اللغة السببية بشكل شائع لتوليد النصوص. يمكنك استخدام هذه النماذج لتطبيقات إبداعية مثل اختيار مغامرات نصية تفاعلية، أو كمساعد برمجة ذكي مثل Copilot أو CodeParrot.

يتنبأ نمذجة اللغة السببية بالرمز التالي في تسلسل الرموز، ولا يمكن للنموذج الانتباه إلا إلى الرموز الواقعة على اليسار. وهذا يعني أن النموذج لا يمكنه رؤية الرموز المستقبلية. يُعدّ GPT-2 مثالاً على نموذج اللغة السببية.

ستُظهر لك هذه الدليل كيفية:

1. قم بضبط [DistilGPT2](https://huggingface.co/distilbert/distilgpt2) على مجموعة [r/askscience](https://www.reddit.com/r/askscience/) الفرعية من مجموعة بيانات [ELI5](https://huggingface.co/datasets/dany0407/eli5_category).
2. استخدم النموذج المُحسَّن لديك للاستدلال.

للاطلاع على جميع البنى المعمارية ونقاط التفتيش المتوافقة مع هذه المهمة، ننصح بالتحقق من [صفحة المهمة](https://huggingface.co/tasks/text-generation)

قبل أن تبدأ، تأكد من تثبيت جميع المكتبات اللازمة:

```bash
pip install transformers datasets evaluate
```

ننصحك بتسجيل الدخول إلى حسابك على Hugging Face حتى تتمكن من رفع نموذجك ومشاركته مع المجتمع. عند الطلب، أدخل رمزك (token) لتسجيل الدخول:

```py
>>> from huggingface_hub import notebook_login

>>> notebook_login()
```

## تحميل مجموعة بيانات ELI5

ابدأ بتحميل أول 5000 مثال من مجموعة بيانات [ELI5-Category](https://huggingface.co/datasets/dany0407/eli5_category) باستخدام مكتبة 🤗 Datasets. سيمنحك هذا فرصة للتجربة والتأكد من عمل كل شيء بشكل صحيح قبل قضاء مزيد من الوقت في التدريب على المجموعة الكاملة.

```py
>>> from datasets import load_dataset

>>> eli5 = load_dataset("dany0407/eli5_category", split="train[:5000]")
```

قسّم مجموعة `train` من مجموعة البيانات إلى مجموعة تدريب ومجموعة اختبار باستخدام طريقة [train_test_split](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.train_test_split):

```py
>>> eli5 = eli5.train_test_split(test_size=0.2)
```

ثم اطّلع على مثال:

```py
>>> eli5["train"][0]
{'q_id': '7h191n',
 'title': 'What does the tax bill that was passed today mean? How will it affect Americans in each tax bracket?',
 'selftext': '',
 'category': 'Economics',
 'subreddit': 'explainlikeimfive',
 'answers': {'a_id': ['dqnds8l', 'dqnd1jl', 'dqng3i1', 'dqnku5x'],
  'text': ["The tax bill is 500 pages long and there were a lot of changes still going on right to the end. It's not just an adjustment to the income tax brackets, it's a whole bunch of changes. As such there is no good answer to your question. The big take aways are: - Big reduction in corporate income tax rate will make large companies very happy. - Pass through rate change will make certain styles of business (law firms, hedge funds) extremely happy - Income tax changes are moderate, and are set to expire (though it's the kind of thing that might just always get re-applied without being made permanent) - People in high tax states (California, New York) lose out, and many of them will end up with their taxes raised.",
   'None yet. It has to be reconciled with a vastly different house bill and then passed again.',
   'Also: does this apply to 2017 taxes? Or does it start with 2018 taxes?',
   'This article explains both the House and senate bills, including the proposed changes to your income taxes based on your income level. URL_0'],
  'score': [21, 19, 5, 3],
  'text_urls': [[],
   [],
   [],
   ['https://www.investopedia.com/news/trumps-tax-reform-what-can-be-done/']]},
 'title_urls': ['url'],
 'selftext_urls': ['url']}
```

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

## المعالجة المسبقة

الخطوة التالية هي تحميل مُجزِّئ DistilGPT2 لمعالجة الحقل الفرعي `text`:

```py
>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilgpt2")
```

ستلاحظ من المثال أعلاه أن حقل `text` مضمّن فعلياً داخل `answers`. وهذا يعني أنك ستحتاج إلى استخراج الحقل الفرعي `text` من بنيته المضمّنة باستخدام طريقة [`flatten`](https://huggingface.co/docs/datasets/process#flatten):

```py
>>> eli5 = eli5.flatten()
>>> eli5["train"][0]
{'q_id': '7h191n',
 'title': 'What does the tax bill that was passed today mean? How will it affect Americans in each tax bracket?',
 'selftext': '',
 'category': 'Economics',
 'subreddit': 'explainlikeimfive',
 'answers.a_id': ['dqnds8l', 'dqnd1jl', 'dqng3i1', 'dqnku5x'],
 'answers.text': ["The tax bill is 500 pages long and there were a lot of changes still going on right to the end. It's not just an adjustment to the income tax brackets, it's a whole bunch of changes. As such there is no good answer to your question. The big take aways are: - Big reduction in corporate income tax rate will make large companies very happy. - Pass through rate change will make certain styles of business (law firms, hedge funds) extremely happy - Income tax changes are moderate, and are set to expire (though it's the kind of thing that might just always get re-applied without being made permanent) - People in high tax states (California, New York) lose out, and many of them will end up with their taxes raised.",
  'None yet. It has to be reconciled with a vastly different house bill and then passed again.',
  'Also: does this apply to 2017 taxes? Or does it start with 2018 taxes?',
  'This article explains both the House and senate bills, including the proposed changes to your income taxes based on your income level. URL_0'],
 'answers.score': [21, 19, 5, 3],
 'answers.text_urls': [[],
  [],
  [],
  ['https://www.investopedia.com/news/trumps-tax-reform-what-can-be-done/']],
 'title_urls': ['url'],
 'selftext_urls': ['url']}
```

أصبح كل حقل فرعي عمودًا مستقلًا كما يشير بادئة `answers`، وأصبح الحقل `text` قائمة. بدلًا من تحويل كل جملة إلى رموز بشكل منفصل، حوّل القائمة إلى نص حتى تتمكن من تحويلها إلى رموز معًا.

إليك أول دالة للمعالجة المسبقة لدمج قائمة النصوص لكل مثال وتحويل النتيجة إلى رموز:

```py
>>> def preprocess_function(examples):
...     return tokenizer([" ".join(x) for x in examples["answers.text"]])
```

لتطبيق دالة المعالجة المسبقة هذه على مجموعة البيانات بأكملها، استخدم طريقة [map](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.map) في 🤗 Datasets. يمكنك تسريع دالة `map` عن طريق تعيين `batched=True` لمعالجة عدة عناصر من مجموعة البيانات في وقت واحد، وزيادة عدد العمليات باستخدام `num_proc`. احذف أي أعمدة لا تحتاج إليها:

```py
>>> tokenized_eli5 = eli5.map(
...     preprocess_function,
...     batched=True,
...     num_proc=4,
...     remove_columns=eli5["train"].column_names,
... )
```

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

يمكنك الآن استخدام دالة معالجة مسبقة ثانية ل

- دمج جميع التسلسلات
- قسّم التسلسلات المدمجة إلى مقاطع أقصر تُعرَّف بواسطة `block_size`، والتي يجب أن تكون أقصر من الحد الأقصى لطول الإدخال وفي الوقت نفسه قصيرة بما يكفي لتناسب ذاكرة وحدة معالجة الرسوميات (GPU) لديك.

```py
>>> block_size = 128

>>> def group_texts(examples):
...     # Concatenate all texts.
...     concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()}
...     total_length = len(concatenated_examples[list(examples.keys())[0]])
...     # We drop the small remainder, we could add padding if the model supported it instead of this drop, you can
...     # customize this part to your needs.
...     if total_length >= block_size:
...         total_length = (total_length // block_size) * block_size
...     # Split by chunks of block_size.
...     result = {
...         k: [t[i : i + block_size] for i in range(0, total_length, block_size)]
...         for k, t in concatenated_examples.items()
...     }
...     result["labels"] = result["input_ids"].copy()
...     return result
```

طبّق دالة `group_texts` على كامل مجموعة البيانات:

```py
>>> lm_dataset = tokenized_eli5.map(group_texts, batched=True, num_proc=4)
```

الآن أنشئ دفعة من الأمثلة باستخدام [DataCollatorForLanguageModeling](/docs/transformers/main/ar/main_classes/data_collator#transformers.DataCollatorForLanguageModeling). من الكفاءة أن *نملأ الجمل ديناميكياً* حتى أطول طول في الدفعة أثناء التجميع، بدلاً من ملء مجموعة البيانات بأكملها حتى الطول الأقصى.

استخدم رمز نهاية التسلسل كرمز الحشو، و اضبط `mlm=False`. سيؤدي هذا إلى استخدام المدخلات كملصقات مُزاحة إلى اليمين بعنصر واحد:

```py
>>> from transformers import DataCollatorForLanguageModeling

>>> tokenizer.pad_token = tokenizer.eos_token
>>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)
```

## تدريب

إذا لم تكن على دراية بضبط نموذج باستخدام [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer)، فاطّلع على [الدليل التعليمي الأساسي](../training)!

أنت مستعد الآن لبدء تدريب نموذجك! حمّل DistilGPT2 باستخدام [AutoModelForCausalLM](/docs/transformers/main/ar/model_doc/auto#transformers.AutoModelForCausalLM):

```py
>>> from transformers import AutoModelForCausalLM, TrainingArguments, Trainer

>>> model = AutoModelForCausalLM.from_pretrained("distilbert/distilgpt2")
```

في هذه المرحلة، تبقى ثلاث خطوات فقط:

1. حدّد معاملات التدريب الفائقة في [TrainingArguments](/docs/transformers/main/ar/main_classes/trainer#transformers.TrainingArguments). المعامل الوحيد الإلزامي هو `output_dir` الذي يحدد مكان حفظ النموذج. ستقوم بدفع هذا النموذج إلى Hub عن طريق تعيين `push_to_hub=True` (يتعين عليك تسجيل الدخول إلى Hugging Face لرفع النموذج).
2. مرّر حُجج التدريب إلى [Trainer](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer) مع النموذج ومجموعات البيانات ومُجمِّع البيانات.
3. استدعِ [train()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.train) لضبط نموذجك.

```py
>>> training_args = TrainingArguments(
...     output_dir="my_awesome_eli5_clm-model",
...     eval_strategy="epoch",
...     learning_rate=2e-5,
...     weight_decay=0.01,
...     push_to_hub=True,
... )

>>> trainer = Trainer(
...     model=model,
...     args=training_args,
...     train_dataset=lm_dataset["train"],
...     eval_dataset=lm_dataset["test"],
...     data_collator=data_collator,
...     processing_class=tokenizer,
... )

>>> trainer.train()
```

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

```py
>>> import math

>>> eval_results = trainer.evaluate()
>>> print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}")
Perplexity: 49.61
```

ثم شارك نموذجك على Hub باستخدام طريقة [push_to_hub()](/docs/transformers/main/ar/main_classes/trainer#transformers.Trainer.push_to_hub) ليتمكن الجميع من استخدام نموذجك:

```py
>>> trainer.push_to_hub()
```

لمثال أكثر تفصيلاً حول كيفية ضبط نموذج لنمذجة اللغة السببية، راجع [دفتر PyTorch](https://colab.research.google.com/github/huggingface/notebooks/blob/main/examples/language_modeling.ipynb) المقابل.

## الاستدلال

ممتاز، والآن بعد أن قمت بضبط نموذج، يمكنك استخدامه للاستدلال!

فكّر في موجه (Prompt) ترغب في توليد نص بناءً عليه:

```py
>>> prompt = "Somatic hypermutation allows the immune system to"
```

أبسط طريقة لتجربة نموذجك المُحسَّن للاستدلال هي استخدامه في [pipeline()](/docs/transformers/main/ar/main_classes/pipelines#transformers.pipeline). قم بإنشاء كائن `pipeline` لتوليد النص باستخدام نموذجك، ثم مرر النص إليه:

```py
>>> from transformers import pipeline

>>> generator = pipeline("text-generation", model="username/my_awesome_eli5_clm-model")
>>> generator(prompt)
[{'generated_text': "Somatic hypermutation allows the immune system to be able to effectively reverse the damage caused by an infection.\n\n\nThe damage caused by an infection is caused by the immune system's ability to perform its own self-correcting tasks."}]
```

قم بتجزئة النص وإرجاع `input_ids` كمُتجهات PyTorch:

```py
>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_eli5_clm-model")
>>> inputs = tokenizer(prompt, return_tensors="pt").input_ids
```

استخدم طريقة [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate) لتوليد النص. لمزيد من التفاصيل حول استراتيجيات توليد النص المختلفة ومعلمات التحكم في التوليد، راجع صفحة [استراتيجيات توليد النص](../generation_strategies).

```py
>>> from transformers import AutoModelForCausalLM

>>> model = AutoModelForCausalLM.from_pretrained("username/my_awesome_eli5_clm-model")
>>> outputs = model.generate(inputs, max_new_tokens=100, do_sample=True, top_k=50, top_p=0.95)
```

فكّ ترميز معرّفات الرموز المولّدة إلى نص:

```py
>>> tokenizer.batch_decode(outputs, skip_special_tokens=True)
["Somatic hypermutation allows the immune system to react to drugs with the ability to adapt to a different environmental situation. In other words, a system of 'hypermutation' can help the immune system to adapt to a different environmental situation or in some cases even a single life. In contrast, researchers at the University of Massachusetts-Boston have found that 'hypermutation' is much stronger in mice than in humans but can be found in humans, and that it's not completely unknown to the immune system. A study on how the immune system"]
```

