Transformers documentation
نظرة عامة
نظرة عامة
توفّر مكتبة Transformers تقنيات متعددة لتحسين الاستدلال لجعل النماذج سريعة وميسورة التكلفة وسهلة الوصول. تشمل الخيارات آليات انتباه بديلة لتقليل حركة الذاكرة، وتجميع الأكواد لتنفيذ أسرع، ونوى مُحسّنة لزيادة الإنتاجية. يمكنك تجميع هذه التقنيات معًا لتحقيق أقصى أداء.
لمزيد من المعلومات حول إعداد الأجهزة والتكوين الخاص بكل جهاز، راجع أدلة الأجهزة. تأكد من التقنيات المدعومة على جهازك قبل تطبيق التحسينات أدناه.
الذاكرة والسرعة مترابطتان ارتباطاً وثيقاً لكنهما ليستا الشيء نفسه. إن تقليص بصمتك في الذاكرة يجعل النموذج "أسرع" لأن هناك بيانات أقل يجب نقلها. التحسينات البحتة للسرعة لا تقلل بالضرورة من استهلاك الذاكرة، بل قد تزيد من استخدامها في بعض الأحيان. اختر التحسين المناسب بناءً على حالة الاستخدام لديك والعتاد المتاح.
استخدم الجدول أدناه لاختيار تقنية تحسين.
| تقنية | السرعة | الذاكرة |
|---|---|---|
| التجميع | ✅ | |
| واجهات الانتباه الخلفية | ✅ | ✅ |
| النوى | ✅ | ✅ |
| التكميم | ✅ | ✅ |
| Caching | ✅ | ✅ |
| التوازي | ✅ | |
| Continuous batching | ✅ |
يقدّم لك هذا الدليل بدايةً سريعةً في تحسينات Transformers.
التجميع
يقلّل torch.compile من الأعباء الإضافية المرتبطة بلغة بايثون، ويجمع العمليات معًا، وينشئ نوى (kernels) مُهيّأة خصيصًا لأشكال بياناتك ومكوناتك العتادية. تُعدّ أول عملية تشغيل مرحلة إحماء، بينما تستخدم عمليات التشغيل اللاحقة المسار المُجمَّع الأسرع.
مرّر ذاكرة مؤقتة بحجم ثابت إلى generate() لتفعيل torch.compile تلقائيًا.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", dtype=torch.float16, device_map="auto")
input = tokenizer("The French Bread Law states", return_tensors="pt").to(model.device)
output = model.generate(**input, do_sample=False, max_new_tokens=20, cache_implementation="static")
tokenizer.batch_decode(output, skip_special_tokens=True)[0]تجنّب استدعاء
torch.compile(model)خارج generate() لمنع إعادة تجميع النموذج في كل خطوة.
واجهات الخلفية للانتباه
تقلّل واجهات الانتباه البديلة حركة الذاكرة. فعلى سبيل المثال، يقوم FlashAttention بتقسيم عمليات الانتباه إلى شرائح وتجنّب المصفوفات الوسيطة الكبيرة لتقليل بصمة الذاكرة.
اضبط attn_implementation في from_pretrained() لتحميل واجهة خلفية مُحسّنة للانتباه.
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", attn_implementation="flash_attention_2")النوى
تدمج النوى (Kernels) العمليات لزيادة الإنتاجية وتقليل استهلاك الذاكرة. يحمّل مكتبة Kernels نوى الحساب المُحسَّنة من Hub بطريقة مرنة وآمنة من حيث الإصدارات.
يُحمّل المثال أدناه نواة FlashAttention-2 المُحسّنة دون تثبيت الحزمة.
import torch
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B", attn_implementation="kernels-community/flash-attn2"
)التكميم
يُقلّص التكميم حجم كل معامل، مما يُخفض استهلاك الذاكرة ويزيد السرعة نظراً لإمكانية تنفيذ المزيد من العمليات.
مرّر إعدادات التكميم إلى معامل quantization_config في from_pretrained(). لكل واجهة خلفية للتكميم إعدادات مختلفة بمعاملات مختلفة. يكمّم المثال أدناه النموذج إلى 4 بتات ويضبط نوع البيانات الحسابي باستخدام واجهة bitsandbytes الخلفية.
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)
model = AutoModelForCausalLM.from_pretrained(
"allenai/Olmo-3-7B-Think", quantization_config=bnb_config
)التخزين المؤقت
يسرّع التخزين المؤقت عملية التوليد من خلال إعادة استخدام المفاتيح والقيم السابقة بدلاً من إعادة حسابها لكل رمز. ولتعويض تكلفة الذاكرة وتخفيضها الناتجة عن تخزين المفاتيح والقيم السابقة، يدعم Transformers نقل التخزين المؤقت إلى وحدة المعالجة المركزية (CPU). ولا يبقى على وحدة معالجة الرسوميات (GPU) سوى الطبقة الحالية.
استخدم معامل cache_implementation في generate() لضبط استراتيجية التخزين المؤقت.
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B", attn_implementation="kernels-community/flash-attn2"
)
inputs = tokenizer("The Le Décret Pain states that a baguette must,", return_tensors="pt")
outputs = model.generate(**inputs, do_sample=False, max_new_tokens=50, cache_implementation="offloaded")التوازي
يقوم التوازي بتوزيع النموذج على عدة أجهزة، مما يتيح تشغيل النماذج التي تتجاوز سعة جهاز واحد بسرعة. يستهلك هذا النهج ذاكرة أكبر بسبب تكاليف تقسيم النموذج والتواصل المتبادل لمزامنة النتائج.
يقوم توازي الموترات بتقسيم طبقة النموذج عبر الأجهزة. اضبط عدد الأجهزة باستخدام DistributedConfig(tp_size=N) وقم بتمريره إلى from_pretrained() لتفعيله.
from transformers import AutoModelForCausalLM, DistributedConfig
distributed_config = DistributedConfig(tp_size=4)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Meta-Llama-3-8B-Instruct",
distributed_config=distributed_config,
)
print(model._tp_plan)الدفعية المستمرة
يعمل Continuous batching على تعظيم الإنتاجية من خلال إبقاء وحدة معالجة الرسوميات (GPU) مشغولة عبر جدولة ديناميكية وتقسيم عملية التمهيد (chunked prefill). تستخدم تطبيقات Serving هذه التقنية لمعالجة طلبات متعددة واردة في وقت واحد.
استخدم generate_batch() لتفعيل الدفع المستمر.
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import ContinuousBatchingConfig, GenerationConfig
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen3-0.6B",
attn_implementation="sdpa",
device_map="auto",
torch_dtype=torch.bfloat16,
)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
prompts = [
"The Le Décret Pain states that a baguette must",
"Explain gravity in one sentence.",
"Name the capital of France.",
]
inputs = [tokenizer.encode(p) for p in prompts]
generation_config = GenerationConfig(
max_new_tokens=32,
eos_token_id=tokenizer.eos_token_id,
pad_token_id=tokenizer.pad_token_id,
do_sample=False,
)
continuous_batching_config = ContinuousBatchingConfig(max_batch_tokens=512)
outputs = model.generate_batch(
inputs=inputs,
generation_config=generation_config,
continuous_batching_config=continuous_batching_config,
)
for request_id, output in outputs.items():
text = tokenizer.decode(output.generated_tokens, skip_special_tokens=True)
print(f"[{request_id}] {text}")