Transformers documentation
التعرف التلقائي على الكلام
التعرف التلقائي على الكلام
تقوم تقنية التعرف التلقائي على الكلام (ASR) بتحويل إشارة صوتية إلى نص، حيث تُقرن تسلسل مدخلات صوتية بمخرجات نصية. تستخدم المساعدات الافتراضية مثل Siri وAlexa نماذج ASR لمساعدة المستخدمين يومياً، كما توجد تطبيقات مفيدة أخرى موجهة للمستخدمين مثل الترجمة الفورية أثناء الاجتماعات وتدوين الملاحظات.
ستُظهر لك هذه الدليل كيفية:
- قم بضبط Wav2Vec2 على مجموعة بيانات MInDS-14 لتحويل الصوت إلى نص.
- استخدم النموذج المُحسَّن لديك للاستدلال.
للاطلاع على جميع البنى المعمارية ونقاط التفتيش المتوافقة مع هذه المهمة، ننصح بالتحقق من صفحة المهمة
قبل أن تبدأ، تأكد من تثبيت جميع المكتبات اللازمة:
pip install transformers datasets evaluate jiwer soundfile librosa torchcodec
ننصحك بتسجيل الدخول إلى حسابك على Hugging Face حتى تتمكن من رفع نموذجك ومشاركته مع المجتمع. عند الطلب، أدخل رمزك (token) لتسجيل الدخول:
>>> from huggingface_hub import notebook_login
>>> notebook_login()تحميل مجموعة بيانات MInDS-14
ابدأ بتحميل مجموعة فرعية أصغر من مجموعة بيانات MInDS-14 من مكتبة 🤗 Datasets. سيمنحك هذا فرصة للتجربة والتأكد من عمل كل شيء بشكل صحيح قبل قضاء مزيد من الوقت في التدريب على المجموعة الكاملة.
>>> from datasets import load_dataset, Audio
>>> minds = load_dataset("PolyAI/minds14", name="en-US", split="train[:100]")قسّم مجموعة train من مجموعة البيانات إلى مجموعة تدريب ومجموعة اختبار باستخدام طريقة ~Dataset.train_test_split:
>>> minds = minds.train_test_split(test_size=0.2)ثم اطّلع على مجموعة البيانات:
>>> minds
DatasetDict({
train: Dataset({
features: ['path', 'audio', 'transcription', 'english_transcription', 'intent_class', 'lang_id'],
num_rows: 16
})
test: Dataset({
features: ['path', 'audio', 'transcription', 'english_transcription', 'intent_class', 'lang_id'],
num_rows: 4
})
})على الرغم من أن مجموعة البيانات تحتوي على الكثير من المعلومات المفيدة، مثل lang_id وenglish_transcription، فإن هذا الدليل يركّز على audio وtranscription. احذف الأعمدة الأخرى باستخدام طريقة remove_columns:
>>> minds = minds.remove_columns(["english_transcription", "intent_class", "lang_id"])راجع المثال مرة أخرى:
>>> minds["train"][0]
{'audio': {'array': array([-0.00024414, 0. , 0. , ..., 0.00024414,
0.00024414, 0.00024414], dtype=float32),
'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602ba9e2963e11ccd901cd4f.wav',
'sampling_rate': 8000},
'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602ba9e2963e11ccd901cd4f.wav',
'transcription': "hi I'm trying to use the banking app on my phone and currently my checking and savings account balance is not refreshing"}هناك حقلان:
audio: مصفوفة أحادية البُعدarrayلإشارة الصوت، ويجب استدعاؤها لتحميل ملف الصوت وإعادة أخذ عيناته.transcription: النص المستهدف.
المعالجة المسبقة
الخطوة التالية هي تحميل معالج Wav2Vec2 لمعالجة إشارة الصوت:
>>> from transformers import AutoProcessor
>>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base")يتميز مجموعة بيانات MInDS-14 بمعدل أخذ عينات يبلغ 8000 هرتز (يمكنك العثور على هذه المعلومات في بطاقة المجموعة)، مما يعني أنك ستحتاج إلى إعادة أخذ عينات المجموعة بمعدل 16000 هرتز لاستخدام نموذج Wav2Vec2 المُدرَّب مسبقاً:
>>> minds = minds.cast_column("audio", Audio(sampling_rate=16_000))
>>> minds["train"][0]
{'audio': {'array': array([-2.38064706e-04, -1.58618059e-04, -5.43987835e-06, ...,
2.78103951e-04, 2.38446111e-04, 1.18740834e-04], dtype=float32),
'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602ba9e2963e11ccd901cd4f.wav',
'sampling_rate': 16000},
'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602ba9e2963e11ccd901cd4f.wav',
'transcription': "hi I'm trying to use the banking app on my phone and currently my checking and savings account balance is not refreshing"}كما ترون في transcription أعلاه، يحتوي النص على مزيج من الأحرف الكبيرة والصغيرة. وقد تم تدريب مُجزِّئ Wav2Vec2 على الأحرف الكبيرة فقط، لذا يجب التأكد من تطابق النص مع مفردات المُجزِّئ:
>>> def uppercase(example):
... return {"transcription": example["transcription"].upper()}
>>> minds = minds.map(uppercase)الآن أنشئ دالة معالجة مسبقة:
- يستدعم عمود
audioلتحميل ملف الصوت وإعادة عيّنته. - يستخرج
input_valuesمن ملف الصوت ويقوم بتجزئة عمودtranscriptionباستخدام المعالج.
>>> def prepare_dataset(batch):
... audio = batch["audio"]
... batch = processor(audio["array"], sampling_rate=audio["sampling_rate"], text=batch["transcription"])
... batch["input_length"] = len(batch["input_values"][0])
... return batchلتطبيق دالة المعالجة المسبقة على مجموعة البيانات بأكملها، استخدم دالة map في 🤗 Datasets. يمكنك تسريع map عن طريق زيادة عدد العمليات باستخدام معامل num_proc. احذف الأعمدة التي لا تحتاجها باستخدام طريقة remove_columns:
>>> encoded_minds = minds.map(prepare_dataset, remove_columns=minds.column_names["train"], num_proc=4)لا يتوفر في 🤗 Transformers مُجمِّع بيانات (data collator) خاص بالتعرف على الكلام من النص (ASR)، لذا ستحتاج إلى تكييف DataCollatorWithPadding لإنشاء دفعة من الأمثلة. كما سيقوم بتوسيط (padding) النص والوسوم ديناميكيًا حتى طول أطول عنصر في الدفعة (بدلاً من طول مجموعة البيانات بأكملها) لضمان تساوي الأطوال. ورغم أنه يمكن توسيط النص داخل دالة tokenizer بإعداد padding=True، فإن التوسيط الديناميكي أكثر كفاءة.
على عكس مُجمِّعات البيانات الأخرى، يحتاج مُجمِّع البيانات هذا تحديداً إلى تطبيق طريقة ملء مختلفة على input_values وlabels:
>>> import torch
>>> from dataclasses import dataclass, field
>>> from typing import Any, Dict, List, Optional, Union
>>> @dataclass
... class DataCollatorCTCWithPadding:
... processor: AutoProcessor
... padding: Union[bool, str] = "longest"
... def __call__(self, features: list[dict[str, Union[list[int], torch.Tensor]]]) -> dict[str, torch.Tensor]:
... # split inputs and labels since they have to be of different lengths and need
... # different padding methods
... input_features = [{"input_values": feature["input_values"][0]} for feature in features]
... label_features = [{"input_ids": feature["labels"]} for feature in features]
... batch = self.processor.pad(input_features, padding=self.padding, return_tensors="pt")
... labels_batch = self.processor.pad(labels=label_features, padding=self.padding, return_tensors="pt")
... # replace padding with -100 to ignore loss correctly
... labels = labels_batch["input_ids"].masked_fill(labels_batch.attention_mask.ne(1), -100)
... batch["labels"] = labels
... return batchالآن قم بإنشاء كائن من DataCollatorCTCWithPadding:
>>> data_collator = DataCollatorCTCWithPadding(processor=processor, padding="longest")تقييم
غالباً ما يكون تضمين مقياس أثناء التدريب مفيداً لتقييم أداء نموذجك. يمكنك تحميل طريقة تقييم بسرعة باستخدام مكتبة 🤗 Evaluate. لهذه المهمة، حمّل مقياس word error rate (WER) (راجع quick tour الخاص بـ 🤗 Evaluate لمعرفة المزيد حول تحميل وحساب المقاييس):
>>> import evaluate
>>> wer = evaluate.load("wer")ثم أنشئ دالة تمرّر تنبؤاتك والتسميات إلى compute لحساب WER:
>>> import numpy as np
>>> def compute_metrics(pred):
... pred_logits = pred.predictions
... pred_ids = np.argmax(pred_logits, axis=-1)
... pred.label_ids[pred.label_ids == -100] = processor.tokenizer.pad_token_id
... pred_str = processor.batch_decode(pred_ids)
... label_str = processor.batch_decode(pred.label_ids, group_tokens=False)
... wer_score = wer.compute(predictions=pred_str, references=label_str)
... return {"wer": wer_score}دالة compute_metrics الخاصة بك جاهزة الآن، وستعود إليها عند إعداد التدريب.
تدريب
إذا لم تكن على دراية بتدريب نموذج باستخدام Trainer، فاطّلع على الدرس الأساسي هنا!
أنت الآن مستعد لبدء تدريب نموذجك! حمّل Wav2Vec2 باستخدام AutoModelForCTC. حدّد نوع الاختزال المطلوب تطبيقه عبر المعامل ctc_loss_reduction. وغالباً ما يكون استخدام المتوسط أفضل من عملية الجمع الافتراضية:
>>> from transformers import AutoModelForCTC, TrainingArguments, Trainer
>>> model = AutoModelForCTC.from_pretrained(
... "facebook/wav2vec2-base",
... ctc_loss_reduction="mean",
... pad_token_id=processor.tokenizer.pad_token_id,
... )في هذه المرحلة، تبقى ثلاث خطوات فقط:
- حدد معاملات التدريب الفائقة في TrainingArguments. المعامل الوحيد الإلزامي هو
output_dirالذي يحدد مكان حفظ النموذج. ستقوم بدفع هذا النموذج إلى Hub من خلال تعيينpush_to_hub=True(يتعين عليك تسجيل الدخول إلى Hugging Face لرفع النموذج). في نهاية كل حقبة، سيقوم Trainer بتقييم WER وحفظ نقطة الفحص للتدريب. - مرّر حُجج التدريب إلى Trainer مع النموذج، ومجموعة البيانات، ومُجزّئ الرموز، ومُجمِّع البيانات، ودالة
compute_metrics. - استدعِ train() لضبط نموذجك.
>>> training_args = TrainingArguments(
... output_dir="my_awesome_asr_mind_model",
... per_device_train_batch_size=8,
... gradient_accumulation_steps=2,
... learning_rate=1e-5,
... warmup_steps=500,
... max_steps=2000,
... gradient_checkpointing=True,
... fp16=True,
... train_sampling_strategy="group_by_length",
... eval_strategy="steps",
... per_device_eval_batch_size=8,
... save_steps=1000,
... eval_steps=1000,
... logging_steps=25,
... load_best_model_at_end=True,
... metric_for_best_model="wer",
... greater_is_better=False,
... push_to_hub=True,
... report_to="trackio",
... )
>>> trainer = Trainer(
... model=model,
... args=training_args,
... train_dataset=encoded_minds["train"],
... eval_dataset=encoded_minds["test"],
... processing_class=processor,
... data_collator=data_collator,
... compute_metrics=compute_metrics,
... )
>>> trainer.train()بمجرد اكتمال التدريب، شارك نموذجك على Hub باستخدام طريقة push_to_hub() ليصبح متاحاً للجميع:
>>> trainer.push_to_hub()لمثال أكثر تفصيلاً حول كيفية ضبط نموذج للتعرف التلقائي على الكلام، راجع هذا المقال للتعرف على الكلام باللغة الإنجليزية وهذا المقال للتعرف على الكلام متعدد اللغات.
الاستدلال
ممتاز، والآن بعد أن قمت بضبط نموذج، يمكنك استخدامه للاستدلال!
حمّل ملف الصوت الذي تريد تشغيل الاستدلال عليه. تذكّر بإعادة أخذ عينات معدل أخذ العينات لملف الصوت ليتطابق مع معدل أخذ العينات للنموذج إذا لزم الأمر!
>>> from datasets import load_dataset, Audio
>>> dataset = load_dataset("PolyAI/minds14", "en-US", split="train")
>>> dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))
>>> sampling_rate = dataset.features["audio"].sampling_rate
>>> audio_file = dataset[0]["audio"]["path"]أبسط طريقة لتجربة نموذجك المُحسَّن للاستدلال هي استخدامه في pipeline(). أنشئ كائن pipeline للتعرف التلقائي على الكلام باستخدام نموذجك، ثم مرّر ملف الصوت الخاص بك إليه:
>>> from transformers import pipeline
>>> transcriber = pipeline("automatic-speech-recognition", model="stevhliu/my_awesome_asr_minds_model")
>>> transcriber(audio_file)
{'text': 'I WOUD LIKE O SET UP JOINT ACOUNT WTH Y PARTNER'}النسخ مقبول، لكنه يمكن أن يكون أفضل! جرّب ضبط نموذجك على مزيد من الأمثلة للحصول على نتائج أفضل!
يمكنك أيضًا إعادة إنتاج نتائج pipeline يدويًا إذا رغبت في ذلك:
حمّل معالجًا لمعالجة ملف الصوت والنسخ مسبقًا وإرجاع input كمُتَنسَرات PyTorch:
>>> from transformers import AutoProcessor
>>> processor = AutoProcessor.from_pretrained("stevhliu/my_awesome_asr_mind_model")
>>> inputs = processor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt")مرّر مدخلاتك إلى النموذج وأعد قيم logits:
>>> from transformers import AutoModelForCTC
>>> model = AutoModelForCTC.from_pretrained("stevhliu/my_awesome_asr_mind_model")
>>> with torch.no_grad():
... logits = model(**inputs).logitsاحصل على input_ids المتوقعة ذات أعلى احتمال، واستخدم المعالج لفك ترميز input_ids المتوقعة مرة أخرى إلى نص:
>>> import torch
>>> predicted_ids = torch.argmax(logits, dim=-1)
>>> transcription = processor.batch_decode(predicted_ids)
>>> transcription
['I WOUL LIKE O SET UP JOINT ACOUNT WTH Y PARTNER']