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

خط أنابيب

يُعدّ Pipeline واجهة برمجة تطبيقات (API) للاستدلال بسيطة لكنها قوية، ومتاحة بسهولة لمجموعة متنوعة من مهام تعلّم الآلة مع أي نموذج من Hub على Hugging Face.

خصّص Pipeline لمهمتك باستخدام معاملات مخصصة للمهمة، مثل إضافة الطوابع الزمنية إلى خط أنابيب التعرف التلقائي على الكلام (ASR) لنسخ ملاحظات الاجتماعات. يدعم Pipeline وحدات معالجة الرسوميات (GPUs) وشريحة Apple Silicon والأوزان بدقة نصفية لتسريع الاستدلال وتوفير الذاكرة.

يحتوي Transformers على فئتي خط أنابيب: فئة عامة هي Pipeline، وفئات خطوط أنابيب فردية مخصصة لمهام محددة مثل TextGenerationPipeline. قم بتحميل هذه الخطوط الفردية عن طريق تعيين معرّف المهمة في معامل task داخل Pipeline. يمكنك العثور على معرّف المهمة لكل خط أنابيب في توثيق واجهة برمجية التطبيقات الخاصة به.

يُهيّأ كل مهمة لاستخدام نموذج مُسبَق التدريب ومعالج مسبق افتراضيين، لكن يمكن تجاوز ذلك باستخدام معامل model إذا كنت ترغب في استخدام نموذج مختلف.

على سبيل المثال، لاستخدام TextGenerationPipeline مع Gemma 2، اضبط task="text-generation" وmodel="google/gemma-2-2b".

from transformers import pipeline

pipeline = pipeline(task="text-generation", model="google/gemma-2-2b")
pipeline("the secret to baking a really good cake is ")
[{'generated_text': 'the secret to baking a really good cake is 1. the right ingredients 2. the'}]

عندما يكون لديك أكثر من مدخل واحد، قم بتمريرها كقائمة.

from transformers import pipeline
from accelerate import Accelerator

device = Accelerator().device

pipeline = pipeline(task="text-generation", model="google/gemma-2-2b", device=device)
pipeline(["the secret to baking a really good cake is ", "a baguette is "])
[[{'generated_text': 'the secret to baking a really good cake is 1. the right ingredients 2. the'}],
 [{'generated_text': 'a baguette is 100% bread.\n\na baguette is 100%'}]]

ستُعرّفك هذه الدليل على Pipeline، وتُظهر مزاياها، وتوضح كيفية ضبط مختلف معامِلاتها.

المهام

يتوافق Pipeline مع العديد من مهام تعلم الآلة عبر أنماط مختلفة. مرّر مدخلًا مناسبًا إلى خط الأنابيب وسيُعالج الباقي.

فيما يلي بعض الأمثلة على كيفية استخدام Pipeline لمهام وأنماط مختلفة.

التعرف التلقائي على الكلام
تصنيف الصور
الإجابة على الأسئلة البصرية
from transformers import pipeline

pipeline = pipeline(task="automatic-speech-recognition", model="openai/whisper-large-v3")
pipeline("https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac")
{'text': ' I have a dream that one day this nation will rise up and live out the true meaning of its creed.'}

المعاملات

في الحد الأدنى، لا يتطلب Pipeline سوى معرّف للمهمة، والنموذج، والمدخلات المناسبة. لكن هناك العديد من المعاملات المتاحة لضبط خط المعالجة، بدءًا من المعاملات الخاصة بالمهمة وصولاً إلى تحسين الأداء.

تعرّفك هذه الأقسام على بعض أهم المعاملات.

الجهاز

يتوافق Pipeline مع العديد من أنواع الأجهزة، بما في ذلك وحدات معالجة الرسوميات (GPU) ووحدات المعالجة المركزية (CPU) وشريحة Apple Silicon وغيرها. قم بتكوين نوع الجهاز باستخدام معامل device. افتراضيًا، عند ترك device غير مُعيَّن، يقوم Pipeline تلقائيًا بوضع النموذج على أول مُسرِّع متاح (وحدة معالجة رسومات CUDA، أو Apple Silicon MPS، أو XPU، ...) ولا يلجأ إلى وحدة المعالجة المركزية (CPU) إلا إذا لم يتوفر أي مُسرِّع. مرِّر device="cpu" لإجباره على العمل على وحدة المعالجة المركزية (CPU).

وحدة معالجة الرسوميات
شريحة Apple

لتشغيل Pipeline على وحدة معالجة رسومية (GPU)، اضبط device على معرّف جهاز CUDA المرتبط. على سبيل المثال، device=0 يشغّل العملية على وحدة معالجة رسومية أولى.

from transformers import pipeline

pipeline = pipeline(task="text-generation", model="google/gemma-2-2b", device=0)
pipeline("the secret to baking a really good cake is ")

يمكنك أيضاً السماح لمكتبة Accelerate المخصصة للتدريب الموزّع باختيار كيفية تحميل أوزان النموذج وتخزينها على الجهاز المناسب تلقائياً. وهذا مفيد بشكل خاص إذا كان لديك أجهزة متعددة. تقوم Accelerate بتحميل أوزان النموذج وتخزينها على أسرع جهاز أولاً، ثم تنقل الأوزان إلى أجهزة أخرى (وحدة المعالجة المركزية، القرص الصلب) حسب الحاجة. اضبط device_map="auto" للسماح لـ Accelerate باختيار الجهاز.

تأكد من تثبيت Accelerate.

!pip install -U accelerate
from transformers import pipeline

pipeline = pipeline(task="text-generation", model="google/gemma-2-2b", device_map="auto")
pipeline("the secret to baking a really good cake is ")

الاستدلال الدُفعي

يمكن لـ Pipeline أيضاً معالجة دفعات من المدخلات باستخدام معامل batch_size. قد يحسّن الاستدلال بالدفعات السرعة، لا سيما على وحدة معالجة رسومية (GPU)، لكن ذلك ليس مضموناً. فمتغيرات أخرى مثل العتاد والبيانات والنموذج نفسه يمكن أن تؤثر على ما إذا كان الاستدلال بالدفعات يحسّن السرعة أم لا. ولهذا السبب، يكون الاستدلال بالدفعات معطلاً افتراضياً.

في المثال أدناه، عندما يكون هناك 4 مدخلات، ويُضبط batch_size على 2، يمرر Pipeline دفعة من مدخلتين إلى النموذج في كل مرة.

from transformers import pipeline
from accelerate import Accelerator

device = Accelerator().device

pipeline = pipeline(task="text-generation", model="google/gemma-2-2b", device=device, batch_size=2)
pipeline(["the secret to baking a really good cake is", "a baguette is", "paris is the", "hotdogs are"])
[[{'generated_text': 'the secret to baking a really good cake is to use a good cake mix.\n\ni’'}],
 [{'generated_text': 'a baguette is'}],
 [{'generated_text': 'paris is the most beautiful city in the world.\n\ni’ve been to paris 3'}],
 [{'generated_text': 'hotdogs are a staple of the american diet. they are a great source of protein and can'}]]

استخدام جيد آخر للاستدلال الدُفعي هو بث البيانات في Pipeline.

from transformers import pipeline
from accelerate import Accelerator
from transformers.pipelines.pt_utils import KeyDataset
import datasets

device = Accelerator().device

# KeyDataset is a utility that returns the item in the dict returned by the dataset
dataset = load_dataset("stanfordnlp/imdb", name="plain_text", split="unsupervised")
pipeline = pipeline(task="text-classification", model="distilbert/distilbert-base-uncased-finetuned-sst-2-english", device=device)
for out in pipeline(KeyDataset(dataset, "text"), batch_size=8, truncation="only_first"):
    print(out)

احرص على مراعاة القواعد العامة التالية عند تحديد ما إذا كان الاستدلال الدُفعي (batch inference) يمكن أن يساعد في تحسين الأداء.

  1. الطريقة الوحيدة لمعرفة ذلك على وجه اليقين هي قياس الأداء على نموذجك وبياناتك وأجهزتك.
  2. لا تقم بتجميع الاستدلال (Inference) إذا كنت مقيدًا بزمن الاستجابة (Latency)، على سبيل المثال في منتج استدلال مباشر.
  3. لا تقم بتجميع الاستدلال (Batch Inference) إذا كنت تستخدم وحدة المعالجة المركزية (CPU).
  4. لا تقم بتجميع الاستدلال إذا كنت لا تعرف sequence_length لبياناتك. قِس الأداء، وأضف إلى sequence_length بشكل تكراري، وشمل فحوصات تجاوز الذاكرة (OOM) للتعافي من الأعطال.
  5. إذا كانت قيمة sequence_length لديك منتظمة، فقم بالاستدلال الدُفعي (batch inference) وواصل زيادتها حتى تصل إلى خطأ نفاد الذاكرة (OOM). كلما كان حجم وحدة معالجة الرسوميات (GPU) أكبر، كان الاستدلال الدُفعي أكثر فائدة.
  6. تأكد من قدرتك على معالجة أخطاء نفاد الذاكرة (OOM) إذا قررت تنفيذ الاستدلال الدُفعي (batch inference).

معلمات محددة للمهمة

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

تُظهر الأمثلة أدناه بعض المعلمات الخاصة بالمهام المتاحة.

التعرف التلقائي على الكلام
توليد النص

مرّر معامل return_timestamps="word" إلى Pipeline لإرجاع وقت نطق كل كلمة.

from transformers import pipeline

pipeline = pipeline(task="automatic-speech-recognition", model="openai/whisper-large-v3")
pipeline(audio="https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac", return_timestamps="word")
{'text': ' I have a dream that one day this nation will rise up and live out the true meaning of its creed.',
 'chunks': [{'text': ' I', 'timestamp': (0.0, 1.1)},
  {'text': ' have', 'timestamp': (1.1, 1.44)},
  {'text': ' a', 'timestamp': (1.44, 1.62)},
  {'text': ' dream', 'timestamp': (1.62, 1.92)},
  {'text': ' that', 'timestamp': (1.92, 3.7)},
  {'text': ' one', 'timestamp': (3.7, 3.88)},
  {'text': ' day', 'timestamp': (3.88, 4.24)},
  {'text': ' this', 'timestamp': (4.24, 5.82)},
  {'text': ' nation', 'timestamp': (5.82, 6.78)},
  {'text': ' will', 'timestamp': (6.78, 7.36)},
  {'text': ' rise', 'timestamp': (7.36, 7.88)},
  {'text': ' up', 'timestamp': (7.88, 8.46)},
  {'text': ' and', 'timestamp': (8.46, 9.2)},
  {'text': ' live', 'timestamp': (9.2, 10.34)},
  {'text': ' out', 'timestamp': (10.34, 10.58)},
  {'text': ' the', 'timestamp': (10.58, 10.8)},
  {'text': ' true', 'timestamp': (10.8, 11.04)},
  {'text': ' meaning', 'timestamp': (11.04, 11.4)},
  {'text': ' of', 'timestamp': (11.4, 11.64)},
  {'text': ' its', 'timestamp': (11.64, 11.8)},
  {'text': ' creed.', 'timestamp': (11.8, 12.3)}]}

دفعات المقاطع

توجد بعض الحالات التي تحتاج فيها إلى معالجة البيانات على شكل مقاطع.

  • بالنسبة لبعض أنواع البيانات، قد يحتاج مدخل واحد (على سبيل المثال، ملف صوتي طويل جداً) إلى تقسيمه إلى عدة أجزاء قبل أن يمكن معالجته
  • في بعض المهام، مثل التصنيف بدون تدريب مسبق أو الإجابة على الأسئلة، قد يتطلب إدخال واحد عدة تمريرات أمامية، مما قد يسبب مشاكل مع معامل batch_size

صُمِّم فئة ChunkPipeline للتعامل مع هذه الحالات. تُستخدم كلا فئتي خط الأنابيب بالطريقة نفسها، لكن بما أن ChunkPipeline يمكنها معالجة الدفعات تلقائيًا، فلا داعي للقلق بشأن عدد عمليات المرور الأمامي التي تُطلقها مدخلاتك. وبدلاً من ذلك، يمكنك تحسين batch_size بشكل مستقل عن المدخلات.

يُظهر المثال أدناه كيف يختلف عن Pipeline.

# ChunkPipeline
all_model_outputs = []
for preprocessed in pipeline.preprocess(inputs):
    model_outputs = pipeline.model_forward(preprocessed)
    all_model_outputs.append(model_outputs)
outputs =pipeline.postprocess(all_model_outputs)

# Pipeline
preprocessed = pipeline.preprocess(inputs)
model_outputs = pipeline.forward(preprocessed)
outputs = pipeline.postprocess(model_outputs)

مجموعات بيانات كبيرة

للاستدلال على مجموعات بيانات كبيرة، يمكنك التكرار مباشرة على مجموعة البيانات نفسها. وهذا يتجنب تخصيص ذاكرة فورية للمجموعة بأكملها، ولا تحتاج إلى القلق بشأن إنشاء الدفعات بنفسك. جرّب الاستدلال بالدفعات باستخدام معامل batch_size لمعرفة ما إذا كان يحسّن الأداء.

from transformers.pipelines.pt_utils import KeyDataset
from transformers import pipeline
from accelerate import Accelerator
from datasets import load_dataset

device = Accelerator().device

dataset = load_dataset("stanfordnlp/imdb", name="plain_text", split="unsupervised")
pipeline = pipeline(task="text-classification", model="distilbert/distilbert-base-uncased-finetuned-sst-2-english", device=device)
for out in pipeline(KeyDataset(dataset, "text"), batch_size=8, truncation="only_first"):
    print(out)

تشمل الطرق الأخرى لتشغيل الاستدلال على مجموعات بيانات كبيرة باستخدام Pipeline استخدام مُكرِّر أو مُولِّد.

def data():
    for i in range(1000):
        yield f"My example {i}"

pipeline = pipeline(model="openai-community/gpt2", device=0)
generated_characters = 0
for out in pipeline(data()):
    generated_characters += len(out[0]["generated_text"])

النماذج الكبيرة

يتيح Accelerate بعض التحسينات لتشغيل النماذج الكبيرة باستخدام Pipeline. تأكد أولاً من تثبيت Accelerate.

!pip install -U accelerate

يُعدّ الإعداد device_map="auto" مفيداً لتوزيع النموذج تلقائياً على أسرع الأجهزة (وحدات معالجة الرسوميات) أولاً، ثم توجيهه إلى أجهزة أخرى أبطأ إن توفرت (وحدة المعالجة المركزية، القرص الصلب).

يدعم Pipeline أوزانًا بدقة نصفية (torch.float16)، مما قد يؤدي إلى سرعة أكبر بكثير وتوفير في الذاكرة. تكون خسارة الأداء ضئيلة في معظم النماذج، لا سيما النماذج الأكبر حجمًا. إذا كان جهازك يدعم ذلك، يمكنك تفعيل torch.bfloat16 بدلاً من ذلك للحصول على نطاق أوسع.

تُحوَّل المدخلات داخليًا إلى torch.float16، ولا يعمل هذا إلا مع النماذج التي تعتمد على محرك PyTorch.

أخيرًا، يقبل Pipeline أيضًا النماذج المُكمّاة لتقليل استهلاك الذاكرة بشكل أكبر. تأكد أولًا من تثبيت مكتبة bitsandbytes، ثم أضف quantization_config إلى model_kwargs في خط الأنابيب.

import torch
from transformers import pipeline, BitsAndBytesConfig

pipeline = pipeline(model="google/gemma-7b", dtype=torch.bfloat16, device_map="auto", model_kwargs={"quantization_config": BitsAndBytesConfig(load_in_8bit=True)})
pipeline("the secret to baking a good cake is ")
[{'generated_text': 'the secret to baking a good cake is 1. the right ingredients 2. the right'}]
Update on GitHub