Transformers documentation

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

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

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

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

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

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

  1. قم بضبط DistilGPT2 على مجموعة r/askscience الفرعية من مجموعة بيانات ELI5.
  2. استخدم النموذج المُحسَّن لديك للاستدلال.

للاطلاع على جميع البنى المعمارية ونقاط التفتيش المتوافقة مع هذه المهمة، ننصح بالتحقق من صفحة المهمة

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

pip install transformers datasets evaluate

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

>>> from huggingface_hub import notebook_login

>>> notebook_login()

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

ابدأ بتحميل أول 5000 مثال من مجموعة بيانات ELI5-Category باستخدام مكتبة 🤗 Datasets. سيمنحك هذا فرصة للتجربة والتأكد من عمل كل شيء بشكل صحيح قبل قضاء مزيد من الوقت في التدريب على المجموعة الكاملة.

>>> from datasets import load_dataset

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

قسّم مجموعة train من مجموعة البيانات إلى مجموعة تدريب ومجموعة اختبار باستخدام طريقة train_test_split:

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

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

>>> 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:

>>> from transformers import AutoTokenizer

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

ستلاحظ من المثال أعلاه أن حقل text هو في الواقع متداخل داخل answers. وهذا يعني أنك ستحتاج إلى استخراج الحقل الفرعي text من بنيته المتداخلة باستخدام طريقة flatten:

>>> 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 قائمة. بدلاً من تحويل كل جملة إلى رموز بشكل منفصل، قم بتحويل القائمة إلى نص حتى تتمكن من تحويلها إلى رموز معًا.

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

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

لتطبيق دالة المعالجة المسبقة هذه على مجموعة البيانات بأكملها، استخدم طريقة map في 🤗 Datasets. يمكنك تسريع دالة map عن طريق تعيين batched=True لمعالجة عدة عناصر من مجموعة البيانات في وقت واحد، وزيادة عدد العمليات باستخدام num_proc. احذف أي أعمدة لا تحتاج إليها:

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

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

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

  • دمج جميع التسلسلات
  • قسّم التسلسلات المدمجة إلى مقاطع أقصر تُعرَّف بواسطة block_size، والتي يجب أن تكون أقصر من الحد الأقصى لطول الإدخال وفي الوقت نفسه قصيرة بما يكفي لتناسب ذاكرة وحدة معالجة الرسوميات (GPU) لديك.
>>> 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 على كامل مجموعة البيانات:

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

الآن أنشئ دفعة من الأمثلة باستخدام DataCollatorForLanguageModeling. من الكفاءة أن نملأ الجمل ديناميكيًا حتى الطول الأطول في الدفعة أثناء التجميع، بدلاً من ملء مجموعة البيانات بأكملها حتى الطول الأقصى.

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

>>> from transformers import DataCollatorForLanguageModeling

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

تدريب

إذا لم تكن على دراية بضبط نموذج باستخدام Trainer، فاطّلع على الدليل التعليمي الأساسي!

أنت مستعد الآن لبدء تدريب نموذجك! حمّل DistilGPT2 باستخدام AutoModelForCausalLM:

>>> from transformers import AutoModelForCausalLM, TrainingArguments, Trainer

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

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

  1. حدّد معاملات التدريب الفائقة في TrainingArguments. المعامل الوحيد الإلزامي هو output_dir الذي يحدد مكان حفظ النموذج. ستقوم بدفع هذا النموذج إلى Hub عن طريق تعيين push_to_hub=True (يتعين عليك تسجيل الدخول إلى Hugging Face لرفع النموذج).
  2. مرّر حُجج التدريب إلى Trainer مع النموذج ومجموعات البيانات ومُجمِّع البيانات.
  3. استدعِ train() لضبط نموذجك.
>>> 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() لتقييم نموذجك والحصول على قيمة الحيرة (perplexity) الخاصة به:

>>> import math

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

ثم شارك نموذجك على Hub باستخدام طريقة push_to_hub() ليتمكن الجميع من استخدام نموذجك:

>>> trainer.push_to_hub()

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

الاستدلال

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

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

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

أبسط طريقة لتجربة نموذجك المُحسَّن للاستدلال هي استخدامه في pipeline(). قم بإنشاء كائن pipeline لتوليد النص باستخدام نموذجك، ثم مرر النص إليه:

>>> 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:

>>> from transformers import AutoTokenizer

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

استخدم طريقة generate() لتوليد النص. لمزيد من التفاصيل حول استراتيجيات توليد النص المختلفة ومعلمات التحكم في التوليد، راجع صفحة Text generation strategies.

>>> 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)

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

>>> 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"]
Update on GitHub