共计 6624 个字符,预计需要花费 17 分钟才能阅读完成。
咱们很快乐地发表,SpeechT5 当初可用于 🤗 Transformers (一个开源库,提供最前沿的机器学习模型实现的开源库)。
SpeechT5 最后见于微软亚洲研究院的这篇论文 SpeechT5: Unified-Modal Encoder-Decoder Pre-Training for Spoken Language Processing。论文作者公布的 官网仓库 可在 Hugging Face Hub 上找到。
如果您想间接尝试,这里有一些在 Spaces 上的演示:
- 语音合成 (TTS)
- 语音转换
- 主动语音辨认
介绍
SpeechT5 不是一种,也不是两种,而是一种架构中的三种语音模型。
它能够做:
- 语音到文本 ,用于主动语音辨认或谈话人辨认;
- 文本转语音 ,用于合成音频;
- 语音到语音 ,用于在不同语音之间进行转换或执行语音加强。
SpeechT5 背地的次要思维是在文本到语音、语音到文本、文本到文本和语音到语音数据的混合体上预训练单个模型。这样,模型能够同时从文本和语音中学习。这种预训练方法的后果是一个模型,该模型具备由文本和语音共享的暗藏示意的 对立空间 。
SpeechT5 的外围是一个惯例的 Transformer 编码器 – 解码器 模型。就像任何其余 Transformer 一样,编码器 – 解码器网络应用暗藏示意对序列到序列的转换进行建模。这个 Transformer 骨干对于所有 SpeechT5 工作都是一样的。
为了使同一个 Transformer 能够同时解决文本和语音数据,增加了所谓的 pre-nets 和 post-nets。per-nets 的工作是将输出文本或语音转换为 Transformer 应用的暗藏示意。post-nets 从 Transformer 获取输入并将它们再次转换为文本或语音。
下图展现了 SpeechT5 的架构 (摘自 原始论文)。
在预训练期间,同时应用所有的 per-nets 和 post-nets。预训练后,整个编码器 – 解码器骨干在单个工作上进行微调。这种通过微调的模型仅应用特定于给定工作的 per-nets 和 post-nets。例如,要将 SpeechT5 用于文本到语音转换,您须要将文本编码器 per-nets 替换为文本输出,将语音解码器 per-nets 和 post-nets 替换为语音输入。
留神: 即便微调模型一开始应用共享预训练模型的同一组权重,但最终版本最终还是齐全不同。例如,您不能采纳通过微调的 ASR 模型并换掉 per-nets 和 post-nets 来取得无效的 TTS 模型。SpeechT5 很灵便,但不是 那么 灵便。
文字转语音
SpeechT5 是咱们增加到 🤗 Transformers 的 第一个文本转语音模型 ,咱们打算在不久的未来增加更多的 TTS 模型。
对于 TTS 工作,该模型应用以下 per-net 和 post-net:
- 文本编码器 per-net。一个文本嵌入层,将文本标记映射到编码器冀望的暗藏示意。相似于 BERT 等 NLP 模型中产生的状况。
- 语音解码器 per-net。这将对数梅尔频谱图作为输出,并应用一系列线性层将频谱图压缩为暗藏示意。此设计取自 Tacotron 2 TTS 模型。
- 语音解码器 post-net。这预测了一个残差以增加到输入频谱图中并用于改良后果,同样来自 Tacotron 2。
微调模型的架构如下所示。
以下是如何应用 SpeechT5 文本转语音模型合成语音的残缺示例。您还能够在 交互式 Colab 笔记本 中进行操作。
SpeechT5 在最新版本的 Transformers 中尚不可用,因而您必须从 GitHub 装置它。还要装置附加的依赖语句,而后重新启动运行。
pip install git+https://github.com/huggingface/transformers.git
pip install sentencepiece
首先,咱们从 Hub 加载 微调模型,以及用于标记化和特征提取的处理器对象。咱们将应用的类是 SpeechT5ForTextToSpeech
。
from transformers import SpeechT5Processor, SpeechT5ForTextToSpeech
processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
接下来,标记输出文本。
inputs = processor(text="Don't count the days, make the days count.", return_tensors="pt")
SpeechT5 TTS 模型不限于为单个谈话者创立语音。相同,它应用所谓的 Speaker Embeddings 来捕获特定谈话者的语音特色。咱们将从 Hub 上的数据集中加载这样一个 Speaker Embeddings。
from datasets import load_dataset
embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")
import torch
speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)
Speaker Embeddings 是形态为 (1, 512) 的张量。这个特定的 Speaker Embeddings 形容了女性的声音。应用 此脚本 从 CMU ARCTIC 数据集取得嵌入 /utils/prep_cmu_arctic_spkemb.py
,任何 X-Vector 嵌入都应该无效。
当初咱们能够通知模型在给定输出标记和 Speaker Embeddings 的状况下生成语音。
spectrogram = model.generate_speech(inputs["input_ids"], speaker_embeddings)
这会输入一个形态为 (140, 80) 的张量,其中蕴含对数梅尔谱图。第一个维度是序列长度,它可能在运行之间有所不同,因为语音解码器 per-net 总是对输出序列利用 dropout。这为生成的语音减少了一些随机变动。
要将预测的对数梅尔声谱图转换为理论的语音波形,咱们须要一个 声码器 。实践上,您能够应用任何实用于 80-bin 梅尔声谱图的声码器,但为了不便起见,咱们在基于 HiFi-GAN 的 Transformers 中提供了一个。此声码器的权重,以及微调 TTS 模型的权重,由 SpeechT5 的原作者情谊提供。
加载声码器与任何其余 🤗 Transformers 模型一样简略。
from transformers import SpeechT5HifiGan
vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
要从频谱图中制作音频,请执行以下操作:
with torch.no_grad():
speech = vocoder(spectrogram)
咱们还提供了一个快捷方式,因而您不须要制作频谱图的两头步骤。当您将声码器对象传递给 generate_speech 时,它会间接输入语音波形。
speech = model.generate_speech(inputs["input_ids"], speaker_embeddings, vocoder=vocoder)
最初,将语音波形保留到文件中。SpeechT5 应用的采样率始终为 16 kHz。
import soundfile as sf
sf.write("tts_example.wav", speech.numpy(), samplerate=16000)
输入听起来像这样 (下载音频)
这就是 TTS 模型!使这个声音好听的要害是应用正确的 Speaker Embeddings。
您能够在 Spaces 上进行 交互式演示。
语音转语音的语音转换
从概念上讲,应用 SpeechT5 进行语音转语音建模与文本转语音雷同。只需将文本编码器 per-net 换成语音编码器 per-net 即可。模型的其余部分放弃不变。
语音编码器 per-net 与 wav2vec 2.0 中的特色编码模块雷同。它由卷积层组成,这些卷积层将输出波形下采样为一系列音频帧示意。
作为语音到语音工作的示例,SpeechT5 的作者提供了一个 微调检查点 用于进行语音转换。要应用它,首先从 Hub 加载模型。请留神,模型类当初是 SpeechT5ForSpeechToSpeech
。
from transformers import SpeechT5Processor, SpeechT5ForSpeechToSpeech
processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_vc")
model = SpeechT5ForSpeechToSpeech.from_pretrained("microsoft/speecht5_vc")
咱们须要一些语音音频作为输出。出于本示例的目标,咱们将从 Hub 上的小型语音数据集加载音频。您也能够加载本人的语音波形,只有它们是单声道的并且应用 16 kHz 的采样率即可。咱们在这里应用的数据集中的样本曾经采纳这种格局。
from datasets import load_dataset
dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation")
dataset = dataset.sort("id")
example = dataset[40]
接下来,对音频进行预处理,使其采纳模型冀望的格局。
sampling_rate = dataset.features["audio"].sampling_rate
inputs = processor(audio=example["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt")
与 TTS 模型一样,咱们须要 Speaker Embeddings。这些形容了指标语音听起来像什么。
import torch
embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")
speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)
咱们还须要加载声码器以将生成的频谱图转换为音频波形。让咱们应用与 TTS 模型雷同的声码器。
from transformers import SpeechT5HifiGan
vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
当初咱们能够通过调用模型的 generate_speech
办法来执行语音转换。
speech = model.generate_speech(inputs["input_values"], speaker_embeddings, vocoder=vocoder)
import soundfile as sf
sf.write("speech_converted.wav", speech.numpy(), samplerate=16000)
更改为不同的声音就像加载新的 Speaker Embeddings 一样简略。您甚至能够嵌入本人的声音!
原始输出下载 (下载)
转换后的语音 (下载)
请留神,此示例中转换后的音频在句子完结前被切断。这可能是因为两个句子之间的进展导致 SpeechT5 (谬误地) 预测曾经达到序列的开端。换个例子试试,你会发现转换通常是正确的,但有时会过早进行。
🔥 您能够进行 交互式演示。
用于主动语音辨认的语音转文本
ASR 模型应用以下 pre-nets 和 post-net:
- 语音编码器 per-net。这是语音到语音模型应用的雷同预网,由来自 wav2vec 2.0 的 CNN 特色编码器层组成。
- 文本解码器 per-net。与 TTS 模型应用的编码器预网相似,它应用嵌入层将文本标记映射到暗藏示意中。(在预训练期间,这些嵌入在文本编码器和解码器预网之间共享。)
- 文本解码器 post-net。这是其中最简略的一个,由一个线性层组成,该层将暗藏示意投射到词汇表上的概率。
微调模型的架构如下所示。
如果您之前尝试过任何其余 🤗 Transformers 语音辨认模型,您会发现 SpeechT5 同样易于应用。最快的入门办法是应用流水线。
from transformers import pipeline
generator = pipeline(task="automatic-speech-recognition", model="microsoft/speecht5_asr")
作为语音音频,咱们将应用与上一节雷同的输出,任何音频文件都能够应用,因为流水线会主动将音频转换为正确的格局。
from datasets import load_dataset
dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation")
dataset = dataset.sort("id")
example = dataset[40]
当初咱们能够要求流水线解决语音并生成文本转录。
transcription = generator(example["audio"]["array"])
打印转录给出:
a man said to the universe sir i exist
听起来完全正确!SpeechT5 应用的分词器十分根底,是字符级别工作。因而,ASR 模型不会输入任何标点符号或大写字母。
当然也能够间接应用模型类。首先,加载 微调模型 和处理器对象。该类当初是 SpeechT5ForSpeechToText
。
from transformers import SpeechT5Processor, SpeechT5ForSpeechToText
processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_asr")
model = SpeechT5ForSpeechToText.from_pretrained("microsoft/speecht5_asr")
预处理语音输入:
sampling_rate = dataset.features["audio"].sampling_rate
inputs = processor(audio=example["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt")
最初,通知模型从语音输入中生成文本标记,而后应用处理器的解码性能将这些标记转换为理论文本。
predicted_ids = model.generate(**inputs, max_length=100)
transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)
播放 语音到文本工作 的交互式演示。
论断
SpeechT5 是一个乏味的模型,因为与大多数其余模型不同,它容许您应用雷同的架构执行多项工作。只有 per-net 和 post-net 发生变化。通过在这些组合工作上对模型进行预训练,它在微调时变得更有能力实现每个独自的工作。
目前咱们只介绍了语音辨认 (ASR)、语音合成 (TTS) 和语音转换工作,但论文还提到该模型已胜利用于语音翻译、语音加强和谈话者辨认。如此宽泛的用处,前途不可估量!
原文: Speech Synthesis, Recognition, and More With SpeechT5
作者: Mathijs Hollemans
译者: innovation64 (李洋)
审校、排版: zhongdongy (阿东)