Transformers documentation
توليد النص
توليد النص
يُعد توليد النص التطبيق الأكثر شيوعًا لنماذج اللغة الكبيرة (LLMs). يتم تدريب نموذج LLM على توليد الكلمة التالية (رمز) بناءً على نص أولي (موجّه) إلى جانب مخرجاته المولّدة ذاتيًا حتى طول محدد مسبقًا أو حتى يصل إلى رمز نهاية التسلسل (EOS).
في Transformers، يتولى واجهة generate() معالجة توليد النصوص، وهي متاحة لجميع النماذج التي تتمتع بقدرات توليدية. ستُظهر لك هذه الدليل أساسيات توليد النصوص باستخدام generate()، بالإضافة إلى بعض الأخطاء الشائعة التي يجب تجنبها.
بالنسبة للأوامر التالية، يرجى التأكد من أن
transformers serveقيد التشغيل.transformers chat Qwen/Qwen2.5-0.5B-Instruct
الافتراضي generate
قبل أن تبدأ، من المفيد تثبيت bitsandbytes لتكميم النماذج الكبيرة جداً لتقليل استهلاكها للذاكرة.
!pip install -U transformers bitsandbytes
يدعم Bitsandbytes عدة واجهات خلفية (backends) بالإضافة إلى وحدات معالجة الرسوميات (GPUs) المعتمدة على CUDA. راجع دليل التثبيت متعدد الواجهات الخلفية لمزيد من التفاصيل.
حمّل نموذج LLM باستخدام from_pretrained() وأضف المعاملين التاليين لتقليل متطلبات الذاكرة.
device_map="auto"يفعّل ميزة Big Model Inference في Accelerate، والتي تُنشئ هيكل النموذج تلقائيًا وتحمّل أوزان النموذج وتوزّعها على جميع الأجهزة المتاحة، بدءًا من أسرع جهاز (GPU).quantization_configهو كائن إعدادات يحدد إعدادات التكميم. يستخدم هذا المثال bitsandbytes كواجهة خلفية للتكميم (راجع قسم Quantization لمعرفة الواجهات الخلفية المتاحة الأخرى) ويحمّل النموذج بدقة 4-bits.
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" لأن نموذج اللغة الكبير لا يُدرَّب على مواصلة التوليد من رموز الحشو. يعيد مُجزِّئ النص معرّفات المدخلات وقناع الانتباه.
يمكنك معالجة أكثر من موجه في وقت واحد عن طريق تمرير قائمة من النصوص إلى مُرمّز الرموز. قم بتجميع المدخلات لتحسين معدل الإنتاجية مقابل تكلفة طفيفة في زمن الاستجابة والذاكرة.
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() لتوليد الرموز، ثم استخدم batch_decode() لتحويل الرموز المولّدة إلى نص.
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. في المثال أعلاه، تُشتق إعدادات التوليد من ملف generation_config.json الخاص بـ mistralai/Mistral-7B-v0.1. يتم استخدام استراتيجية فك ترميز افتراضية عندما لا يكون هناك تكوين محفوظ مع النموذج.
افحص الإعدادات من خلال خاصية generation_config. تُظهر هذه الخاصية فقط القيم التي تختلف عن الإعدادات الافتراضية، وفي هذه الحالة، هي bos_token_id وeos_token_id.
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() عن طريق تجاوز المعاملات والقيم في GenerationConfig. راجع هذا القسم أدناه للاطلاع على المعاملات التي يتم ضبطها بشكل شائع.
# enable beam search sampling strategy
model.generate(**inputs, num_beams=4, do_sample=True)يمكن أيضًا توسيع generate() باستخدام مكتبات خارجية أو أكواد مخصصة:
- يقبل معامل
logits_processorأمثلة مخصصة من LogitsProcessor لتعديل توزيع احتمالات الرمز التالي؛ - يدعم معامل
stopping_criteriaمعايير إيقاف مخصصة StoppingCriteria لوقف توليد النص؛ - يمكن تحميل طرق توليد مخصصة أخرى من خلال علم
custom_generate(التوثيق).
راجع دليل استراتيجيات التوليد لمعرفة المزيد حول استراتيجيات البحث والعينة والتفكيك.
الحفظ
أنشئ مثيلًا من GenerationConfig وحدد معاملات فك الترميز التي تريدها.
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() لحفظ تكوين توليد محدد، و اضبط معامل push_to_hub على True لرفعه إلى Hub.
generation_config.save_pretrained("my_account/my_model", push_to_hub=True)اترك معامل config_file_name فارغًا. يُستخدم هذا المعامل عند تخزين إعدادات توليد متعددة في مجلد واحد، إذ يتيح لك تحديد إعداد التوليد الذي تريد تحميله. يمكنك إنشاء إعدادات مختلفة لمهام توليدية مختلفة (توليد نصوص إبداعية باستخدام العينة، والتلخيص باستخدام بحث الحزمة) لاستخدامها مع نموذج واحد.
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() أداة قوية يمكن تخصيصها بشكل كبير. وقد يبدو ذلك مُرهِقًا للمستخدمين الجدد. تتضمن هذه القائمة خيارات التوليد الشائعة التي يمكنك تعريفها في معظم أدوات توليد النصوص في Transformers: generate()، GenerationConfig، pipelines، سطر الأوامر chat، …
| اسم الخيار | النوع | وصف مبسّط |
|---|---|---|
max_new_tokens | int | يتحكم في الحد الأقصى لطول التوليد. تأكد من تعريفه، إذ إنه عادةً ما يكون افتراضياً بقيمة صغيرة. |
do_sample | bool | يحدد ما إذا كانت عملية التوليد ستعتمد على أخذ عينة للرمز التالي (True)، أم أنها ستكون طمعية بدلاً من ذلك (False). ينبغي ضبط هذا العلم على True في معظم حالات الاستخدام. راجع هذا الدليل لمزيد من المعلومات. |
temperature | float | مدى عدم قابلية التنبؤ بالرمز الذي سيُختار في الخطوة التالية. القيم العالية (>0.8) مناسبة للمهام الإبداعية، بينما القيم المنخفضة (مثل <0.4) مناسبة للمهام التي تتطلب "تفكيرًا". يتطلب do_sample=True. |
num_beams | int | عند ضبطه على >1، يتم تفعيل خوارزمية البحث الحزمي. يُعد البحث الحزمي مناسبًا للمهام المعتمدة على المدخلات. راجع هذا الدليل لمزيد من المعلومات. |
repetition_penalty | float | اضبطه على >1.0 إذا كنت تلاحظ أن النموذج يكرر نفسه بشكل متكرر. القيم الأكبر تفرض عقوبة أكبر. |
eos_token_id | list[int] | الرمز (أو الرموز) الذي سيؤدي إلى إيقاف التوليد. القيمة الافتراضية عادةً ما تكون جيدة، لكن يمكنك تحديد رمز مختلف. |
المشكلات
يتناول القسم أدناه بعض المشكلات الشائعة التي قد تواجهها أثناء توليد النص وكيفية حلها.
طول المخرجات
يعيد generate() ما يصل إلى 20 رمزًا افتراضيًا ما لم يُحدد خلاف ذلك في GenerationConfig للنموذج. يُوصى بشدة بإعداد عدد الرموز المولّدة يدويًا باستخدام معامل max_new_tokens للتحكم في طول المخرجات. تعيد نماذج Decoder-only الموجه الأولي إلى جانب الرموز المولّدة.
model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to(model.device)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'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() هي البحث الجشع، والتي تختار الرمز التالي الأكثر احتمالاً، ما لم يُحدَّد خلاف ذلك في GenerationConfig للنموذج. وعلى الرغم من أن استراتيجية فك الترميز هذه تعمل بشكل جيد للمهام المرتبطة بالمدخلات (النسخ، الترجمة)، إلا أنها ليست مثالية لحالات الاستخدام الإبداعية أكثر (كتابة القصص، تطبيقات الدردشة).
على سبيل المثال، فعّل استراتيجية multinomial sampling لتوليد مخرجات أكثر تنوعاً. راجع دليل Generation strategy لمزيد من استراتيجيات فك الترميز.
model_inputs = tokenizer(["I am a cat."], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]generated_ids = model.generate(**model_inputs, do_sample=True)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]جانب الحشو
يجب ملء المدخلات إذا لم تكن بنفس الطول. لكن نماذج اللغة الكبيرة لا تُدرَّب على مواصلة التوليد من رموز الملء، مما يعني أن المعامل padding_side() يجب أن يُضبط على يسار المدخلات. يكون الملء على اليمين أسوأ بالنسبة للنماذج ذات الحالة المكانية والنماذج الهجينة، لأن حالتها التكرارية تستمر في التحديث فوق رموز الملء المتأخرة، وبالتالي لم يعد المخزن المؤقت متطابقًا مع نهاية الموجز.
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'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,'صيغة الموجه
تتوقع بعض النماذج والمهام صيغة محددة لمدخلات المحفّز، وإذا كانت الصيغة غير صحيحة، فإن النموذج يُرجع مخرجات غير مثلى. يمكنك معرفة المزيد حول المحفّزات في دليل هندسة المحفّزات.
على سبيل المثال، يتوقع نموذج المحادثة إدخال البيانات على شكل قالب محادثة. يجب أن يتضمن موجهك role وcontent لتحديد من يشارك في المحادثة. إذا حاولت تمرير موجهك كنص واحد، فقد لا يعيد النموذج المخرجات المتوقعة دائمًا.
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)
)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"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: امتداد لـ Transformers يركّز على تحسين التدريب والاستدلال على أجهزة العتاد المحددة
- Outlines: مكتبة لتوليد النص المقيد (مثل توليد ملفات JSON).
- SynCode: مكتبة لتوليد موجّه بقواعد اللغة الحرة من السياق (JSON، SQL، Python).
- Text Generation Inference: خادم جاهز للإنتاج لنماذج اللغة الكبيرة.
- واجهة ويب لتوليد النص: واجهة ويب مبنية على Gradio لتوليد النص.
- logits-processor-zoo: معالجات logits إضافية للتحكم في توليد النص.