# MMS

## نظرة عامة

قُدم نموذج MMS في [Scaling Speech Technology to 1,000+ Languages](https://huggingface.co/papers/2305.13516) بواسطة Vineel Pratap, Andros Tjandra, Bowen Shi, Paden Tomasello, Arun Babu, Sayani Kundu, Ali Elkahky, Zhaoheng Ni, Apoorv Vyas, Maryam Fazel-Zarandi, Alexei Baevski, Yossi Adi, Xiaohui Zhang, Wei-Ning Hsu, Alexis Conneau, Michael Auli

المستخلص من الورقة البحثية هو كالتالي:

*توسيع نطاق تغطية اللغات في تقنيات الصوت يحمل إمكانية تحسين الوصول إلى المعلومات لعدد أكبر من الناس. ومع ذلك، فإن تقنيات الصوت الحالية تقتصر على حوالي مئة لغة، وهي نسبة صغيرة من أصل أكثر من 7000 لغة تُتحدث حول العالم. يزيد مشروع الكلام متعدد اللغات على نطاق واسع (MMS) عدد اللغات المدعومة بمقدار 10 إلى 40 مرة، اعتمادًا على المهمة. المكونات الرئيسية هي مجموعة بيانات جديدة مبنية على قراءات نصوص دينية متاحة للعموم، والاستفادة الفعّالة من التعلّم غير المُشرط (self-supervised learning). قمنا ببناء نماذج wav2vec 2.0 مُسبقة التدريب تغطي 1406 لغات، ونموذجًا واحدًا متعدد اللغات للتعرف التلقائي على الكلام لـ 1107 لغات، ونماذج لتوليد الكلام لنفس عدد اللغات، بالإضافة إلى نموذج لتحديد اللغة لـ 4017 لغة. تُظهر التجارب أن نموذج التعرف على الكلام متعدد اللغات لدينا يُقلل من معدل خطأ الكلمة لنموذج Whisper إلى النصف تقريبًا على 54 لغة من مجموعة معايير FLEURS، وذلك مع التدريب على جزء صغير من البيانات المُصنّفة.*

فيما يلي النماذج المختلفة التي تم نشرها كمصادر مفتوحة في مشروع MMS. تم إطلاق النماذج والكود في الأصل [هنا](https://github.com/facebookresearch/fairseq/tree/main/examples/mms). لقد أضفناها إلى إطار عمل `transformers` لتسهيل استخدامها.

### التعرف التلقائي على الكلام (ASR)

يمكن العثور على نقاط التفتيش لنموذج ASR هنا: [mms-1b-fl102](https://huggingface.co/facebook/mms-1b-fl102)، [mms-1b-l1107](https://huggingface.co/facebook/mms-1b-l1107)، [mms-1b-all](https://huggingface.co/facebook/mms-1b-all). للحصول على أعلى دقة، استخدم نموذج `mms-1b-all`.

نصائح:

- تقبل جميع نماذج ASR مصفوفة من نوع float تتوافق مع الموجة الخام لإشارة الصوت. يجب معالجة الموجة الخام مسبقًا باستخدام [Wav2Vec2FeatureExtractor](/docs/transformers/main/ar/model_doc/wav2vec2#transformers.Wav2Vec2FeatureExtractor).
- تم تدريب النماذج باستخدام التصنيف الزمني المتصل (CTC) لذا يجب فك ترميز مخرجات النموذج باستخدام [Wav2Vec2CTCTokenizer](/docs/transformers/main/ar/model_doc/wav2vec2#transformers.Wav2Vec2CTCTokenizer).
- يمكنك تحميل أوزان محوِّلات لغوية مختلفة للغات متعددة عبر [load_adapter()](/docs/transformers/main/ar/model_doc/wav2vec2#transformers.Wav2Vec2ForCTC.load_adapter). تتكوّن محوِّلات اللغة من حوالي مليوني معامل فقط، وبالتالي يمكن تحميلها بكفاءة عند الحاجة إليها.

#### جارٍ التحميل

بشكل افتراضي، يحمّل MMS أوزان المُكيّف للغة الإنجليزية. إذا كنت ترغب في تحميل أوزان المُكيّف للغة أخرى، فتأكد من تحديد `target_lang=<your-chosen-target-lang>` بالإضافة إلى `"ignore_mismatched_sizes=True`. يجب تمرير الكلمة المفتاحية `ignore_mismatched_sizes=True` للسماح بإعادة حجم رأس نموذج اللغة وفقاً لمفردات اللغة المحددة. وبالمثل، يجب تحميل المعالج مع نفس اللغة المستهدفة

```python
from transformers import AutoProcessor, Wav2Vec2ForCTC

model_id = "facebook/mms-1b-all"
target_lang = "fra"

processor = AutoProcessor.from_pretrained(model_id, target_lang=target_lang)
model = Wav2Vec2ForCTC.from_pretrained(model_id, target_lang=target_lang, ignore_mismatched_sizes=True, device_map="auto")
```

يمكنك تجاهل تحذير مثل ما يلي بأمان:

```text
Some weights of Wav2Vec2ForCTC were not initialized from the model checkpoint at facebook/mms-1b-all and are newly initialized because the shapes did not match:
- lm_head.bias: found shape torch.Size([154]) in the checkpoint and torch.Size([314]) in the model instantiated
- lm_head.weight: found shape torch.Size([154, 1280]) in the checkpoint and torch.Size([314, 1280]) in the model instantiated
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
```

إذا كنت ترغب في استخدام خط أنابيب ASR، يمكنك تحميل لغة الهدف المختارة كما يلي:

```python
from transformers import pipeline

model_id = "facebook/mms-1b-all"
target_lang = "fra"

pipe = pipeline(model=model_id, model_kwargs={"target_lang": "fra", "ignore_mismatched_sizes": True})
```

#### الاستدلال

فيما يلي، سننظر في كيفية تشغيل MMS في الاستدلال وتغيير طبقات المحوّل بعد استدعاء `~PretrainedModel.from_pretrained` أولاً، نقوم بتحميل بيانات صوتية بلغات مختلفة باستخدام [Datasets](https://github.com/huggingface/datasets).

```python
from datasets import Audio, load_dataset

# English
stream_data = load_dataset("mozilla-foundation/common_voice_13_0", "en", split="test", streaming=True)
stream_data = stream_data.cast_column("audio", Audio(sampling_rate=16000))
en_sample = next(iter(stream_data))["audio"]["array"]

# French
stream_data = load_dataset("mozilla-foundation/common_voice_13_0", "fr", split="test", streaming=True)
stream_data = stream_data.cast_column("audio", Audio(sampling_rate=16000))
fr_sample = next(iter(stream_data))["audio"]["array"]
```

بعد ذلك، نقوم بتحميل النموذج والمعالج

```python

from transformers import AutoProcessor, Wav2Vec2ForCTC

model_id = "facebook/mms-1b-all"

processor = AutoProcessor.from_pretrained(model_id)
model = Wav2Vec2ForCTC.from_pretrained(model_id, device_map="auto")
```

الآن نقوم بمعالجة بيانات الصوت، ثم تمرير البيانات الصوتية المعالجة إلى النموذج، وننسخ مخرجات النموذج، تمامًا كما نفعل عادةً مع [Wav2Vec2ForCTC](/docs/transformers/main/ar/model_doc/wav2vec2#transformers.Wav2Vec2ForCTC).

```py
inputs = processor(en_sample, sampling_rate=16_000, return_tensors="pt").to(model.device)

with torch.no_grad():
    outputs = model(**inputs).logits

ids = torch.argmax(outputs, dim=-1)[0]
transcription = processor.decode(ids)
# 'joe keton disapproved of films and buster also had reservations about the media'
```

يمكننا الآن إبقاء النموذج نفسه في الذاكرة والتبديل ببساطة بين محولات اللغة عن طريق استدعاء الدالة المريحة [load_adapter()](/docs/transformers/main/ar/model_doc/wav2vec2#transformers.Wav2Vec2ForCTC.load_adapter) للنموذج و [set_target_lang()](/docs/transformers/main/ar/model_doc/wav2vec2#transformers.Wav2Vec2CTCTokenizer.set_target_lang) لمُرمِّز الرموز. نمرر اللغة المستهدفة كمدخل - `"fra"` للفرنسية.

```py
processor.tokenizer.set_target_lang("fra")
model.load_adapter("fra")

inputs = processor(fr_sample, sampling_rate=16_000, return_tensors="pt").to(model.device)

with torch.no_grad():
    outputs = model(**inputs).logits

ids = torch.argmax(outputs, dim=-1)[0]
transcription = processor.decode(ids)
# "ce dernier est volé tout au long de l'histoire romaine"
```

وبالمثل، يمكن تبديل اللغة إلى جميع اللغات الأخرى المدعومة. يرجى الاطلاع على:

```py
processor.tokenizer.vocab.keys()
```

لرؤية جميع اللغات المدعومة.

لتحسين أداء نماذج التعرف على الكلام (ASR) بشكل أكبر، يمكن استخدام فك الترميز بنموذج اللغة. راجع التوثيق [هنا](https://huggingface.co/facebook/mms-1b-all) لمزيد من التفاصيل.

### توليد الكلام (TTS)

يستخدم MMS-TTS نفس بنية النموذج المستخدمة في VITS، والتي أُضيفت إلى 🤗 Transformers في الإصدار v4.33. يقوم MMS بتدريب نقطة تحقق (checkpoint) منفصلة لكل لغة من بين أكثر من 1100 لغة في المشروع. يمكن العثور على جميع نقاط التحقق المتاحة على Hugging Face Hub: [facebook/mms-tts](https://huggingface.co/models?sort=trending&search=facebook%2Fmms-tts)، وتوثيق الاستدلال (inference) تحت [VITS](./vits).

#### الاستدلال

لاستخدام نموذج MMS، حدّث أولاً إلى أحدث إصدار من مكتبة Transformers:

```bash
pip install --upgrade transformers accelerate
```

بما أن النموذج القائم على التدفق في VITS غير حتمي، فإن الممارسة الجيدة هي تعيين بذرة (seed) لضمان قابلية إعادة إنتاج المخرجات.

- بالنسبة للّغات التي تستخدم الأبجدية اللاتينية، مثل الإنجليزية أو الفرنسية، يمكن استخدام مُجزّئ النص مباشرةً ل
معالجة المدخلات النصية مسبقًا. ينفذ مثال الشيفرة التالي تمريرًا أماميًا باستخدام نقطة الفحص الإنجليزية لنموذج MMS-TTS:

```python
import torch

from transformers import VitsModel, VitsTokenizer, set_seed

tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-eng")
model = VitsModel.from_pretrained("facebook/mms-tts-eng", device_map="auto")

inputs = tokenizer(text="Hello - my dog is cute", return_tensors="pt").to(model.device)

set_seed(555)  # make deterministic

with torch.no_grad():
   outputs = model(**inputs)

waveform = outputs.waveform[0]
```

يمكن حفظ الموجة الناتجة كملف `.wav`:

```python
import scipy

scipy.io.wavfile.write("synthesized_speech.wav", rate=model.config.sampling_rate, data=waveform)
```

أو يُعرض في Jupyter Notebook / Google Colab:

```python
from IPython.display import Audio

Audio(waveform, rate=model.config.sampling_rate)
```

بالنسبة لبعض اللغات التي تستخدم أبجديات غير لاتينية، مثل العربية أو المندرينية أو الهندية، يُعد حزمة [`uroman`](https://github.com/isi-nlp/uroman) بلغة بيرل مطلوبة لمعالجة نصوص الإدخال مسبقاً وتحويلها إلى الأبجدية اللاتينية.

يمكنك التحقق مما إذا كنت بحاجة إلى حزمة `uroman` للغة من خلال فحص خاصية `is_uroman` في `tokenizer` المُدرَّب مسبقًا:

```python
from transformers import VitsTokenizer

tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-eng")
print(tokenizer.is_uroman)
```

إذا لزم الأمر، يجب عليك تطبيق حزمة uroman على مدخلات النص **قبل** تمريرها إلى `VitsTokenizer`، لأن المُرمِّز لا يدعم حاليًا تنفيذ المعالجة المسبقة بنفسه.

لتنفيذ ذلك، قم أولاً بنسخ مستودع uroman إلى جهازك المحلي ثم اضبط متغير bash `UROMAN` على المسار المحلي:

```bash
git clone https://github.com/isi-nlp/uroman.git
cd uroman
export UROMAN=$(pwd)
```

يمكنك بعد ذلك معالجة النص المدخل مسبقًا باستخدام مقتطف الشيفرة التالي. يمكنك إما الاعتماد على استخدام متغير bash `UROMAN` للإشارة إلى مستودع uroman، أو يمكنك تمرير مجلد uroman كحجة إلى الدالة `uromanize`:

```python
import os
import subprocess

import torch

from transformers import VitsModel, VitsTokenizer, set_seed

tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-kor")
model = VitsModel.from_pretrained("facebook/mms-tts-kor", device_map="auto")

def uromanize(input_string, uroman_path):
    """Convert non-Roman strings to Roman using the `uroman` perl package."""
    script_path = os.path.join(uroman_path, "bin", "uroman.pl")

    command = ["perl", script_path]

    process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    # Execute the perl command
    stdout, stderr = process.communicate(input=input_string.encode())

    if process.returncode != 0:
        raise ValueError(f"Error {process.returncode}: {stderr.decode()}")

    # Return the output as a string and skip the new-line character at the end
    return stdout.decode()[:-1]

text = "이봐 무슨 일이야"
uromanized_text = uromanize(text, uroman_path=os.environ["UROMAN"])

inputs = tokenizer(text=uromanized_text, return_tensors="pt").to(model.device)

set_seed(555)  # make deterministic
with torch.no_grad():
   outputs = model(inputs["input_ids"])

waveform = outputs.waveform[0]
```

**نصائح:**

* تُدرب نقاط التفتيش الخاصة بـ MMS-TTS على نصوص صغيرة الأحرف وخالية من علامات الترقيم. افتراضيًا، يقوم `VitsTokenizer` بـ *تطبيع* المدخلات عبر إزالة أي تمييز لحالة الأحرف وعلامات الترقيم، لتجنب تمرير أحرف خارج نطاق المفردات إلى النموذج. وبالتالي، فإن النموذج لا يتأثر بحالة الأحرف أو علامات الترقيم، لذا ينبغي تجنب استخدامها في نص الأمر. يمكنك تعطيل التطبيع عن طريق تعيين `normalize=False` في استدعاء المُرمّز، لكن هذا سيؤدي إلى سلوك غير متوقع ولا يُنصح به.
* يمكن تغيير معدل الكلام عن طريق تعيين الخاصية `model.speaking_rate` إلى قيمة محددة. وبالمثل، يتم التحكم في عشوائية الضوضاء من خلال `model.noise_scale`:

```python
import torch

from transformers import VitsModel, VitsTokenizer, set_seed

tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-eng")
model = VitsModel.from_pretrained("facebook/mms-tts-eng", device_map="auto")

inputs = tokenizer(text="Hello - my dog is cute", return_tensors="pt").to(model.device)

# make deterministic
set_seed(555)

# make speech faster and more noisy
model.speaking_rate = 1.5
model.noise_scale = 0.8

with torch.no_grad():
   outputs = model(**inputs)
```

### تحديد اللغة (LID)

تتوفر نماذج LID مختلفة بناءً على عدد اللغات التي يمكنها التعرف عليها - [126](https://huggingface.co/facebook/mms-lid-126)، [256](https://huggingface.co/facebook/mms-lid-256)، [512](https://huggingface.co/facebook/mms-lid-512)، [1024](https://huggingface.co/facebook/mms-lid-1024)، [2048](https://huggingface.co/facebook/mms-lid-2048)، [4017](https://huggingface.co/facebook/mms-lid-4017).

#### الاستدلال

أولاً، نقوم بتثبيت مكتبة transformers وبعض المكتبات الأخرى

```bash
pip install torch accelerate datasets[audio]
pip install --upgrade transformers
````

في الخطوة التالية، نقوم بتحميل بعض عينات الصوت عبر `datasets`. تأكد من أن بيانات الصوت مُعيَّنة التردد عند 16000 هرتز.

```python
from datasets import Audio, load_dataset

# English
stream_data = load_dataset("mozilla-foundation/common_voice_13_0", "en", split="test", streaming=True)
stream_data = stream_data.cast_column("audio", Audio(sampling_rate=16000))
en_sample = next(iter(stream_data))["audio"]["array"]

# Arabic
stream_data = load_dataset("mozilla-foundation/common_voice_13_0", "ar", split="test", streaming=True)
stream_data = stream_data.cast_column("audio", Audio(sampling_rate=16000))
ar_sample = next(iter(stream_data))["audio"]["array"]
```

بعد ذلك، نقوم بتحميل النموذج والمعالج

```python

from transformers import AutoFeatureExtractor, Wav2Vec2ForSequenceClassification

model_id = "facebook/mms-lid-126"

processor = AutoFeatureExtractor.from_pretrained(model_id)
model = Wav2Vec2ForSequenceClassification.from_pretrained(model_id, device_map="auto")
```

الآن نقوم بمعالجة بيانات الصوت، ثم نمرر بيانات الصوت المعالجة إلى النموذج لتصنيفها إلى لغة، تمامًا كما نفعل عادةً مع نماذج تصنيف الصوت Wav2Vec2 مثل [ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition](https://huggingface.co/harshit345/xlsr-wav2vec-speech-emotion-recognition)

```py
# English
inputs = processor(en_sample, sampling_rate=16_000, return_tensors="pt").to(model.device)

with torch.no_grad():
    outputs = model(**inputs).logits

lang_id = torch.argmax(outputs, dim=-1)[0].item()
detected_lang = model.config.id2label[lang_id]
# 'eng'

# Arabic
inputs = processor(ar_sample, sampling_rate=16_000, return_tensors="pt").to(model.device)

with torch.no_grad():
    outputs = model(**inputs).logits

lang_id = torch.argmax(outputs, dim=-1)[0].item()
detected_lang = model.config.id2label[lang_id]
# 'ara'
```

للعرض جميع اللغات المدعومة في نقطة التفتيش، يمكنك طباعة معرّفات اللغات على النحو التالي:

```py
processor.id2label.values()
```

### نماذج الصوت المُسبقة التدريب

تتوفر نماذج مُدرَّبة مسبقًا بحجمين مختلفين - [300M](https://huggingface.co/facebook/mms-300m) ، [1Bil](https://huggingface.co/facebook/mms-1b).

يعتمد بنية MMS الخاصة بمهمة ASR على نموذج Wav2Vec2، ويُرجى الرجوع إلى [صفحة توثيق Wav2Vec2](./wav2vec2) لمزيد من التفاصيل حول كيفية ضبط النماذج الدقيقة لمهام مختلفة.

يستخدم MMS-TTS نفس بنية النموذج المستخدمة في VITS، يرجى الرجوع إلى [صفحة توثيق VITS](./vits) للاطلاع على مرجع واجهة برمجة التطبيقات.

