# توليد النص

يُعد توليد النص التطبيق الأكثر شيوعًا لنماذج اللغة الكبيرة (LLMs). يتم تدريب نموذج LLM على توليد الكلمة التالية (رمز) بناءً على نص أولي (موجّه) إلى جانب مخرجاته المولّدة ذاتيًا حتى طول محدد مسبقًا أو حتى يصل إلى رمز نهاية التسلسل (`EOS`).

في Transformers، يتولى واجهة [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate) معالجة توليد النصوص، وهي متاحة لجميع النماذج التي تتمتع بقدرات توليدية. ستُظهر لك هذه الدليل أساسيات توليد النصوص باستخدام [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate)، بالإضافة إلى بعض الأخطاء الشائعة التي يجب تجنبها.

> [!TIP]
> بالنسبة للأوامر التالية، يرجى التأكد من أن [`transformers serve` قيد التشغيل](./serve-cli/serving).
>
> ```shell
> transformers chat Qwen/Qwen2.5-0.5B-Instruct
> ```

## الافتراضي generate

قبل أن تبدأ، من المفيد تثبيت [bitsandbytes](https://hf.co/docs/bitsandbytes/index) لتكميم النماذج الكبيرة جداً لتقليل استهلاكها للذاكرة.

```bash
!pip install -U transformers bitsandbytes
```

يدعم Bitsandbytes عدة واجهات خلفية (backends) بالإضافة إلى وحدات معالجة الرسوميات (GPUs) المعتمدة على CUDA. راجع [دليل](https://huggingface.co/docs/bitsandbytes/main/en/installation#multi-backend) التثبيت متعدد الواجهات الخلفية لمزيد من التفاصيل.

حمّل نموذج LLM باستخدام [from_pretrained()](/docs/transformers/main/ar/main_classes/model#transformers.PreTrainedModel.from_pretrained) وأضف المعاملين التاليين لتقليل متطلبات الذاكرة.

- `device_map="auto"` يُفعّل ميزة [Big Model Inference](./models#big-model-inference) في Accelerate، والتي تُنشئ هيكل النموذج تلقائيًا وتحمّل أوزان النموذج وتوزّعها على جميع الأجهزة المتاحة، بدءًا من أسرع جهاز (GPU).
- `quantization_config` هو كائن إعدادات يحدد إعدادات التكميم. يستخدم هذا المثال bitsandbytes كواجهة خلفية للتكميم (راجع قسم [Quantization](./quantization/overview) لمعرفة الواجهات الخلفية المتاحة الأخرى) ويحمّل النموذج بدقة [4-bits](./quantization/bitsandbytes).

```py
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto", quantization_config=quantization_config)
```

قم بتجزئة مدخلاتك، واضبط معامل `padding_side()` على `"left"` لأن نموذج اللغة الكبير لا يُدرَّب على مواصلة التوليد من رموز الحشو. يعيد مُجزِّئ النص معرّفات المدخلات وقناع الانتباه.

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

```py
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", padding_side="left")
model_inputs = tokenizer(["A list of colors: red, blue"], return_tensors="pt").to(model.device)
```

مرّر المدخلات إلى [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate) لتوليد الرموز، ثم استخدم [batch_decode()](/docs/transformers/main/ar/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.batch_decode) لتحويل الرموز المولّدة إلى نص.

```py
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
"A list of colors: red, blue, green, yellow, orange, purple, pink,"
```

## إعدادات التوليد

تتضمن جميع إعدادات التوليد في [GenerationConfig](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationConfig). في المثال أعلاه، تُشتق إعدادات التوليد من ملف `generation_config.json` الخاص بـ [mistralai/Mistral-7B-v0.1](https://huggingface.co/mistralai/Mistral-7B-v0.1). يتم استخدام استراتيجية فك ترميز افتراضية عندما لا يكون هناك تكوين محفوظ مع النموذج.

افحص الإعدادات من خلال خاصية `generation_config`. تُظهر هذه الخاصية فقط القيم التي تختلف عن الإعدادات الافتراضية، وفي هذه الحالة، هي `bos_token_id` و`eos_token_id`.

```py
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto")
model.generation_config
GenerationConfig {
  "bos_token_id": 1,
  "eos_token_id": 2
}
```

يمكنك تخصيص [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate) عن طريق تجاوز المعاملات والقيم في [GenerationConfig](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationConfig). راجع [هذا القسم أدناه](#common-options) للاطلاع على المعاملات التي يتم ضبطها بشكل شائع.

```py
# enable beam search sampling strategy
model.generate(**inputs, num_beams=4, do_sample=True)
```

يمكن أيضًا توسيع [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate) باستخدام مكتبات خارجية أو أكواد مخصصة:

1. يقبل معامل `logits_processor` أمثلة مخصصة من [LogitsProcessor](/docs/transformers/main/ar/internal/generation_utils#transformers.LogitsProcessor) لتعديل توزيع احتمالات الرمز التالي؛
2. يدعم معامل `stopping_criteria` معايير إيقاف مخصصة [StoppingCriteria](/docs/transformers/main/ar/internal/generation_utils#transformers.StoppingCriteria) لوقف توليد النص؛
3. يمكن تحميل طرق توليد مخصصة أخرى من خلال علم `custom_generate` ([التوثيق](./generation_strategies#custom-generation-methods)).

راجع دليل [استراتيجيات التوليد](./generation_strategies) لمعرفة المزيد حول استراتيجيات البحث والعينة والتفكيك.

### الحفظ

أنشئ مثيلًا من [GenerationConfig](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationConfig) وحدد معاملات فك الترميز التي تريدها.

```py
from transformers import AutoModelForCausalLM, GenerationConfig

model = AutoModelForCausalLM.from_pretrained("my_account/my_model")
generation_config = GenerationConfig(
    max_new_tokens=50, do_sample=True, top_k=50, eos_token_id=model.config.eos_token_id
)
```

استخدم [save_pretrained()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationConfig.save_pretrained) لحفظ تكوين توليد محدد، و اضبط معامل `push_to_hub` على `True` لرفعه إلى Hub.

```py
generation_config.save_pretrained("my_account/my_model", push_to_hub=True)
```

اترك معامل `config_file_name` فارغًا. يُستخدم هذا المعامل عند تخزين إعدادات توليد متعددة في مجلد واحد، إذ يتيح لك تحديد إعداد التوليد الذي تريد تحميله. يمكنك إنشاء إعدادات مختلفة لمهام توليدية مختلفة (توليد نصوص إبداعية باستخدام العينة، والتلخيص باستخدام بحث الحزمة) لاستخدامها مع نموذج واحد.

```py
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, GenerationConfig

tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small")
model = AutoModelForSeq2SeqLM.from_pretrained("google-t5/t5-small")

translation_generation_config = GenerationConfig(
    num_beams=4,
    early_stopping=True,
    decoder_start_token_id=0,
    eos_token_id=model.config.eos_token_id,
    pad_token=model.config.pad_token_id,
)

translation_generation_config.save_pretrained("/tmp", config_file_name="translation_generation_config.json", push_to_hub=True)

generation_config = GenerationConfig.from_pretrained("/tmp", config_file_name="translation_generation_config.json")
inputs = tokenizer("translate English to French: Configuration files are easy to use!", return_tensors="pt")
outputs = model.generate(**inputs, generation_config=generation_config)
print(tokenizer.batch_decode(outputs, skip_special_tokens=True))
```

## خيارات شائعة

يُعدّ [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate) أداةً قوية قابلة للتخصيص بشكل كبير، وقد يبدو ذلك مُرهِبًا للمستخدمين الجدد. تتضمن هذه القائمة خيارات التوليد الشائعة التي يمكنك تعريفها في معظم أدوات توليد النص في Transformers: [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate)، و[GenerationConfig](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationConfig)، و`pipelines`، وواجهة `chat` السطرية، ...

| اسم الخيار | النوع | وصف مبسّط |
|---|---|---|
| `max_new_tokens` | `int` | يتحكم في الحد الأقصى لطول التوليد. تأكد من تعريفه، إذ إنه عادةً ما يكون افتراضياً بقيمة صغيرة. |
| `do_sample` | `bool` | يحدد ما إذا كانت عملية التوليد ستعتمد على أخذ عينة للرمز التالي (`True`)، أم أنها ستكون طمعية بدلاً من ذلك (`False`). ينبغي ضبط هذا العلم على `True` في معظم حالات الاستخدام. راجع [هذا الدليل](./generation_strategies) لمزيد من المعلومات. |
| `temperature` | `float` | مدى عدم قابلية التنبؤ بالرمز التالي الذي سيُختار. القيم العالية (`>0.8`) مناسبة للمهام الإبداعية، بينما القيم المنخفضة (مثل `<0.4`) مناسبة للمهام التي تتطلب "تفكيرًا". يتطلب `do_sample=True`. |
| `num_beams` | `int` | عند ضبطه على `>1`، يتم تفعيل خوارزمية البحث الحزمي. يُعد البحث الحزمي مناسبًا للمهام المعتمدة على المدخلات. راجع [هذا الدليل](./generation_strategies) لمزيد من المعلومات. |
| `repetition_penalty` | `float` | اضبطه على `>1.0` إذا كنت تلاحظ أن النموذج يكرر نفسه بشكل متكرر. فالقيم الأكبر تفرض عقوبة أكبر. |
| `eos_token_id` | `list[int]` | الرمز (أو الرموز) الذي سيؤدي إلى إيقاف التوليد. القيمة الافتراضية عادةً ما تكون جيدة، لكن يمكنك تحديد رمز مختلف. |

## المشكلات

يتناول القسم أدناه بعض المشكلات الشائعة التي قد تواجهها أثناء توليد النص وكيفية حلها.

### طول المخرجات

يعيد [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate) ما يصل إلى 20 رمزًا افتراضيًا ما لم يُحدد خلاف ذلك في [GenerationConfig](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationConfig) للنموذج. يُوصى بشدة بإعداد عدد الرموز المولّدة يدويًا باستخدام معامل `max_new_tokens` للتحكم في طول المخرجات. تعيد نماذج [Decoder-only](https://hf.co/learn/nlp-course/chapter1/6?fw=pt) الموجه الأولي إلى جانب الرموز المولّدة.

```py
model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to(model.device)
```

```py
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'A sequence of numbers: 1, 2, 3, 4, 5'
```

```py
generated_ids = model.generate(**model_inputs, max_new_tokens=50)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'A sequence of numbers: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,'
```

### استراتيجية فك الترميز

استراتيجية فك الترميز الافتراضية في [generate()](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationMixin.generate) هي *البحث الجشع*، والتي تختار الرمز التالي الأكثر احتمالاً، ما لم يُحدَّد خلاف ذلك في [GenerationConfig](/docs/transformers/main/ar/main_classes/text_generation#transformers.GenerationConfig) للنموذج. وعلى الرغم من أن استراتيجية فك الترميز هذه تعمل بشكل جيد للمهام المرتبطة بالمدخلات (النسخ، الترجمة)، إلا أنها ليست مثالية لحالات الاستخدام الإبداعية أكثر (كتابة القصص، تطبيقات الدردشة).

على سبيل المثال، فعّل استراتيجية [multinomial sampling](./generation_strategies#sampling) لتوليد مخرجات أكثر تنوعاً. راجع دليل [Generation strategy](./generation_strategies) لمزيد من استراتيجيات فك الترميز.

```py
model_inputs = tokenizer(["I am a cat."], return_tensors="pt").to(model.device)
```

```py
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
```

```py
generated_ids = model.generate(**model_inputs, do_sample=True)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
```

### جانب الحشو

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

```py
model_inputs = tokenizer(
    ["1, 2, 3", "A, B, C, D, E"], padding=True, return_tensors="pt"
).to(model.device)
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'1, 2, 33333333333'
```

```py
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", padding_side="left")
tokenizer.pad_token = tokenizer.eos_token
model_inputs = tokenizer(
    ["1, 2, 3", "A, B, C, D, E"], padding=True, return_tensors="pt"
).to(model.device)
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'1, 2, 3, 4, 5, 6,'
```

### صيغة الموجه

تتوقع بعض النماذج والمهام صيغة محددة لمدخلات المحفّز، وإذا كانت الصيغة غير صحيحة، فإن النموذج يُرجع مخرجات غير مثلى. يمكنك معرفة المزيد حول المحفّزات في دليل [هندسة المحفّزات](./tasks/prompting).

على سبيل المثال، يتوقع نموذج المحادثة أن تكون المدخلات بصيغة [قالب محادثة](./chat_templating). يجب أن يتضمن موجهك `role` و`content` لتحديد من يشارك في المحادثة. إذا حاولت تمرير موجهك كنص واحد، فقد لا يعيد النموذج المخرجات المتوقعة دائمًا.

```py
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig

tokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-alpha")
model = AutoModelForCausalLM.from_pretrained(
    "HuggingFaceH4/zephyr-7b-alpha", device_map="auto", quantization_config=BitsAndBytesConfig(load_in_4bit=True)
)
```

```py
prompt = """How many cats does it take to change a light bulb? Reply as a pirate."""
model_inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
input_length = model_inputs.input_ids.shape[1]
generated_ids = model.generate(**model_inputs, max_new_tokens=50)
print(tokenizer.batch_decode(generated_ids[:, input_length:], skip_special_tokens=True)[0])
"Aye, matey! 'Tis a simple task for a cat with a keen eye and nimble paws. First, the cat will climb up the ladder, carefully avoiding the rickety rungs. Then, with"
```

```py
messages = [
    {
        "role": "system",
        "content": "You are a friendly chatbot who always responds in the style of a pirate",
    },
    {"role": "user", "content": "How many cats does it take to change a light bulb?"},
]
model_inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to(model.device)
input_length = model_inputs["input_ids"].shape[1]
generated_ids = model.generate(**model_inputs, do_sample=True, max_new_tokens=50)
print(tokenizer.batch_decode(generated_ids[:, input_length:], skip_special_tokens=True)[0])
"Arr, matey! According to me beliefs, 'twas always one cat to hold the ladder and another to climb up it an’ change the light bulb, but if yer looking to save some catnip, maybe yer can
```

## الموارد

تجد أدناه بعض مكتبات توليد النص الأكثر تحديدًا وتخصصًا.

- [Optimum](https://github.com/huggingface/optimum): امتداد لـ Transformers يركّز على تحسين التدريب والاستدلال على أجهزة العتاد المحددة
- [Outlines](https://github.com/dottxt-ai/outlines): مكتبة لتوليد النص المقيد (مثل توليد ملفات JSON).
- [SynCode](https://github.com/uiuc-focal-lab/syncode): مكتبة لتوليد موجّه بقواعد اللغة الحرة من السياق (JSON، SQL، Python).
- [Text Generation Inference](https://github.com/huggingface/text-generation-inference): خادم جاهز للإنتاج لنماذج اللغة الكبيرة.
- [واجهة ويب لتوليد النص](https://github.com/oobabooga/text-generation-webui): واجهة ويب مبنية على Gradio لتوليد النص.
- [logits-processor-zoo](https://github.com/NVIDIA/logits-processor-zoo): معالجات logits إضافية للتحكم في توليد النص.

