咱们很快乐地宣布,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 (阿东)