Transformers documentation

MMS

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

该模型于 2023-05-22 在 HF papers 上发布,并于 2023-06-20 贡献至 Hugging Face Transformers。

MMS

概述

MMS 模型由 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 在 Scaling Speech Technology to 1,000+ Languages 中提出。

该论文的摘要如下:

扩展语音技术的语言覆盖范围,有望让更多人获取信息。 然而,当前的语音技术仅支持约一百种语言,而全球使用的语言超过 7,000 种,这一比例微乎其微。 Massively Multilingual Speech (MMS) 项目根据任务不同,将支持的语言数量提升了 10 到 40 倍。 其核心要素包括:一个基于公开宗教文本朗读的新数据集,以及对自监督学习的有效利用。我们构建了覆盖 1,406 种语言的预训练 wav2vec 2.0 模型、一个支持 1,107 种语言的多语言自动语音识别模型、支持相同数量语言的语音合成模型,以及一个支持 4,017 种语言的语言识别模型。 实验表明,我们的多语言语音识别模型在 FLEURS 基准测试的 54 种语言上,将 Whisper 的词错误率降低了一半以上,而训练所用的标注数据仅为后者的一小部分。

以下是 MMS 项目中开源的不同模型。这些模型和代码最初发布在此处。我们已将其添加到 transformers 框架中,使其更易于使用。

自动语音识别(ASR)

ASR 模型检查点可以在这里找到:mms-1b-fl102、mms-1b-l1107、mms-1b-all。为了获得最佳准确率,请使用 mms-1b-all 模型。

提示:

  • 所有 ASR 模型都接受一个浮点数数组,该数组对应语音信号的原始波形。原始波形应使用 Wav2Vec2FeatureExtractor 进行预处理。
  • 这些模型使用连接主义时间分类(CTC)进行训练,因此模型输出必须使用 Wav2Vec2CTCTokenizer 进行解码。
  • 您可以通过 load_adapter() 为不同语言加载不同的语言适配器权重。语言适配器仅包含约 200 万个参数,因此可以在需要时高效地即时加载。

加载

默认情况下,MMS 会加载英语的适配器权重。如果您想加载其他语言的适配器权重,请确保同时指定 target_lang=<your-chosen-target-lang> 以及 "ignore_mismatched_sizes=True。 必须传入 ignore_mismatched_sizes=True 关键字,以便根据指定语言的词汇表调整语言模型头的大小。 同样,处理器也应使用相同的 target language 进行加载

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")

您可以安全地忽略如下警告:

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 流水线,可以按如下方式加载您选定的目标语言:

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 加载不同语言的音频数据。

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"]

接下来,我们加载模型和处理器


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 所做的那样。

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() 函数和分词器的 set_target_lang() 函数即可切换语言适配器。我们将目标语言作为输入传入——法语对应 "fra"。

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"

以同样的方式,可以切换为所有其他受支持的语言。请参阅:

processor.tokenizer.vocab.keys()

以查看所有支持的语言。

为了进一步提升 ASR 模型的性能,可以使用语言模型解码。有关更多详细信息,请参阅此处的文档。

语音合成(TTS)

MMS-TTS 使用了与 VITS 相同的模型架构,该架构已在 v4.33 版本中添加至 🤗 Transformers。MMS 为该项目中的 1100 多种语言分别训练了独立的模型检查点。所有可用的检查点均可在 Hugging Face Hub 上找到:facebook/mms-tts,推理文档位于 VITS 下。

推理

要使用 MMS 模型,请先将 Transformers 库更新到最新版本:

pip install --upgrade transformers accelerate

由于 VITS 中的基于流的模型是非确定性的,因此设置随机种子以确保输出的可复现性是一种良好的实践。

  • 对于使用罗马字母的语言(例如英语或法语),可以直接使用分词器对文本输入进行预处理。以下代码示例使用 MMS-TTS 英语检查点执行前向传播:
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 文件:

import scipy


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

或在 Jupyter Notebook / Google Colab 中显示:

from IPython.display import Audio


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

对于某些使用非拉丁字母的语言(例如阿拉伯语、普通话或印地语),需要 uroman perl 包来将文本输入预处理为拉丁字母。

您可以通过检查预训练 tokenizer 的 is_uroman 属性,来确定您的语言是否需要 uroman 包:

from transformers import VitsTokenizer


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

如有需要,应在将文本输入传递给 VitsTokenizer 之前,使用 uroman 包对其进行处理,因为目前该分词器本身不支持执行预处理。

为此,首先将 uroman 仓库克隆到本地机器,并将 bash 变量 UROMAN 设置为本地路径:

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

然后,您可以使用以下代码片段对文本输入进行预处理。您可以选择使用 bash 变量 UROMAN 指向 uroman 仓库,也可以将 uroman 目录作为参数传递给 uromanize 函数:

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 控制:
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、256、512、1024、2048、4017。

推理

首先,我们安装 transformers 和其他一些库

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

接下来,我们通过 datasets 加载几个音频样本。请确保音频数据的采样率为 16000 kHz。

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"]

接下来,我们加载模型和处理器


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")

现在,我们处理音频数据,并将处理后的音频数据传递给模型,将其分类为一种语言,就像我们通常对 ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition 等 Wav2Vec2 音频分类模型所做的那样。

# 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'

要查看某个检查点支持的所有语言,可以按照以下方式打印语言 ID:

processor.id2label.values()

音频预训练模型

提供两种不同规模的预训练模型 - 300M 和 1Bil。

MMS for ASR 架构基于 Wav2Vec2 模型,有关如何使用模型针对各种下游任务进行微调的详细信息,请参阅 Wav2Vec2 的文档页面。

MMS-TTS 使用与 VITS 相同的模型架构,请参阅 VITS 的文档页面 以获取 API 参考。

Update on GitHub