会话式人工智能正在改变我们与计算机的交互方式。它包括三个令人兴奋的人工智能研究领域:自动语言识别(Automatic Speech Recognition,ASR)、自然语言处理(Natural Language Processing,NLP)和语言合成(或文本到语音,Text-to-Speech,TTS)。NVIDIA 的目标是通过让研究人员和从业人员更容易地访问、重用和建立这些领域的最新构建模块和预训练模型,使这些领域的进展能够实现民主化并得到加速。
NVIDIA NeMo 是一个基于 PyTorch 的开源工具包,它允许开发者快速构建、训练和微调会话式人工智能模型。NeMo 由 NeMo Core 和 NeMo Collection 组成,NeMo Core 为所有模型和模块提供了一个通用的“外观”,NeMo Collection 是特定领域模块和模型的组合。在 NeMo 的 Speech Collection(nemo_asr)中,你可以找到用于语音识别、命令识别、说话人识别、说话人验证和语音活动检测的模型和各种构建模块。NeMo 的 NLP Collection(nemo_nlp)包含了诸如问题回答、标点符号、命名实体识别等任务的模型。最后,在 NeMo 的 Speech Synthesis(nemo_tts)中,你会发现一些谱图生成器和声码器,它们将让你能够生成合成语音。
图 1:NeMo 的应用栈
语音交换示例
让我们从一个简单的原型开始介绍 NeMo。在 这个示例 中,我们将获取一个音频文件,并用 NeMo 模型生成的合成语音来替换其中的语音。点击 此处 可以获取此语音文件。
从概念上讲,这个应用程序演示了会话式人工智能系统的所有三个阶段:(1)语音识别;(2)推导意义或理解所说的内容;(3)生成合成语音作为响应。如果你有支持 GPU 的 PyTorch 1.6 版或更高版本,NeMo 可以简单地通过 PIP 安装,如下所示:
pip install nemo_toolkit[all]==1.0.0b1
基于 NeMo 的应用程序的第一步是导入必要的 Collection。在这个应用程序中,我们将使用这三种 Collection。
import nemo
# Import Speech Recognition collection
import nemo.collections.asr as nemo_asr
# Import Natural Language Processing collection
import nemo.collections.nlp as nemo_nlp
# Import Speech Synthesis collection
import nemo.collections.tts as nemo_tts
Collection 使我们可以访问 NeMo 模型,我们可以使用它们来执行某些会话式人工智能任务。模型是 NeMo 的关键概念之一,我们将在下面更详细地讨论它们,但我们只使用现在需要的那些:
# Speech Recognition model - QuartzNet
quartznet =
nemo_asr.models.EncDecCTCModel.from_pretrained(model_name="QuartzNet15x5Base-En")
# Punctuation and capitalization model
punctuation =
nemo_nlp.models.PunctuationCapitalizationModel.from_pretrained(model_name='Punctuation
_Capitalization_with_DistilBERT')
# Spectrogram generator which takes text as an input and produces spectrograms
spectrogram_generator =
nemo_tts.models.Tacotron2Model.from_pretrained(model_name="Tacotron2-22050Hz")
# Vocoder model which takes spectrograms and produces actual audio
vocoder = nemo_tts.models.WaveGlowModel.from_pretrained(model_name="WaveGlow-22050Hz")
大多数 NeMo 模型可以使用from_pretrained()函数直接从 NVIDIA NGC 目录 中直接实例化。通过调用list_available_models()函数,你可以查看每个模型的可用预训练权重列表。
从上面的代码片段中可以看到,我们将使用 QuartzNet 模型 进行语音识别,一个基于 DistillBert 的标点模型,以及 Tacotron2+WaveGlow 模型进行语音合成、语音识别。注意,NeMo 的 NLP Collection 与出色的 Hugging Face 转换器兼容,其语言模型通常被 NeMo 的 NLP 模型用作编码器。一旦所有模型被实例化之后,它们就可以使用了。下面是一个使用 ASR 模型转录音频文件和 NLP 模型在转录文本中添加标点符号的例子:
transcription = quartznet.transcribe(paths2audio_files=files)
result = punctuation.add_punctuation_capitalization(queries=transcription)
有关完整的运行示例,请参考这个 交互式 Google Colab Notebook。请注意,标点符号模型是如何在所生成的语音质量 产生巨大影响 的。基于标点符号模型的输出生成的语音比直接从 ASR 模型的原始输出生成的语音更容易理解,因为它会 在适当的位置包含停顿和语调。
NeMo 模型、神经模块和神经类型
在 NeMo 中,主要有三个概念:模型、神经模块和神经类型。模型 包含了训练和优化所需的所有信息。因此,它们封装了如下内容:
1、神经网络实现:所有神经模块都连接在一起进行训练和评估。
2、所有必要的预处理和后处理:标记化、数据增强等。
3、可用于此模型的 Dataset 类。
4、优化算法和学习率调度。
5、基础设施细节:例如,有多少 GPU、节点以及应使用哪种训练精度。
正如我们在上面的演示中所看到的,大多数模型可以直接从 NVIDIA NGC 目录 上的仓库使用特定的预训练权重进行实例化。
深度神经网络通常可以被认为是由负责不同任务的概念构建块组成的。编码器 - 解码器架构就是一个著名的例子。编码器负责学习输入表示,而解码器则负责根据输入表示生成输出序列。在 NeMo 中,我们称这些模块为“神经模块”(顺便说一句,这就是 NeMo 名字的由来)。神经模块(nemo.core.NeuralModule)表示神经网络的逻辑部分,如语言模型、编码器、解码器、数据增强算法、损失函数等。它们构成了描述模型和训练该模型过程的基础。NeuralModule 类是直接从torch.nn派生的。因此,你可以在 PyTorch 应用程序中使用 NeMo Collection 中的模块。Collection 中有数百个神经模块可供你在模型中重用。
神经模块的输入和输出按神经类型输入。神经类型是一对包含有关张量轴布局(类似于 PyTorch 中的命名张量)及其元素语义的信息对。每个神经模块都有input_type和output_type属性,这些属性描述(并帮助强制执行)这个模块接受什么类型的输入以及它返回什么类型的输出。
让我们考虑模型、神经模块和类型是如何相互作用的。如果我们仔细查看 QuartzNet 模型的forward()方法,就会看到:
@typecheck()
def forward(self, input_signal, input_signal_length):
processed_signal, processed_signal_len = self.preprocessor(
input_signal=input_signal, length=input_signal_length,
)
# Spec augment is not applied during evaluation/testing
if self.spec_augmentation is not None and self.training:
processed_signal = self.spec_augmentation(input_spec=processed_signal)
encoded, encoded_len = self.encoder(audio_signal=processed_signal,
length=processed_signal_len)
log_probs = self.decoder(encoder_output=encoded)
greedy_predictions = log_probs.argmax(dim=-1, keepdim=False)
return log_probs, encoded_len, greedy_predictions
QuartzNet 模型包含预处理器、(可选)谱图增强、编码器和解码器神经模块。请注意,它们的使用方式与使用torch.nn.Module模块完全相同,但增加了类型安全性。以下是这个模型的神经模块的一些输入 / 输出类型:
print(quartznet.preprocessor.input_types['input_signal'])
print(quartznet.preprocessor.output_types['processed_signal'])
print(quartznet.spec_augmentation.input_types['input_spec'])
axes: (batch, time); elements_type: AudioSignal
axes: (batch, dimension, time); elements_type: MelSpectrogramType
axes: (batch, dimension, time); elements_type: SpectrogramType
正如你所见到的,类型决定了其元素的张量布局和语义。预处理器不仅将检查传递给它的张量是否为 2 维[batch,time]张量,而且还将强制张量内的元素表示 AudioSignal。神经类型支持继承,这就是为什么MelSpectrogramType 输出在任何地方都可以接受的原因。类型在@typecheck修饰器的帮助下被强制执行,并且可以打开或关闭强制。这是一个实验性的特性,但我们发现,它有助于帮助模块的用户正确使用它们。
使用 NeMo 进行训练和微调
NeMo 是为训练和微调会话式人工智能模型而构建的。虽然可以使用“纯”PyTorch 来处理 NeMo 的模型和模块,但它们可有效地用于 PyTorch 生态系统中的其他两个项目:PyTorch Lightning 和 Hydra。
NeMo 模型派生自 PyTorch Lightning 模块,可用于 Lightning 的 Trainer 实例。这种与 Lightning 的集成使得使用 Tensor Core 可以非常轻松地以混合精度来训练模型,并且可以将训练扩展到多个 GPU 和计算节点。例如,我们将一些 NeMo 模型的训练扩展为使用 512 个 GPU。Lightning 还为用户提供了许多其他方便的功能,如日志记录、检查点、过拟合检查等等。
NeMo 的用户可以使用 Facebook 的 Hydra 来参数化脚本。一个典型的深度学习实验可以包含数百个甚至数千个参数。这就是为什么将它们保存在组织良好的配置文件中很方便。NeMo 模型和模块使用 Hydra 进行参数化,为用户提供了 Hydra 的灵活性和错误检查功能。
与 PyTorch Lighting 和 Hydra 的集成使得为用户简化任务成为可能。请考虑下面的示例。它是一个完整的 Python 脚本,能够获取 .yaml 配置文件并训练语音识别模型。NeMo + Lightning + Hydra 标准化了很多东西,只需修改两行代码,就可以将其转换为一个脚本,用于训练基于 BERT 的问答模型。
import pytorch_lightning as pl
from nemo.core.config import hydra_runner
from nemo.collections.asr.models import EncDecCTCModel
#from nemo.collections.nlp.models.question_answering.qa_model import QAModel
@hydra_runner(config_path="conf", config_name="config")
def main(cfg):
trainer = pl.Trainer(**cfg.trainer)
#model = QAModel(cfg.model, trainer=trainer)
model = EncDecCTCModel(cfg=cfg.model, trainer=trainer)
trainer.fit(asr_model)
结论
NeMo 是为对会话式人工智能——语音识别、自然语言处理和语音合成感到好奇的开发者而打造的。NVIDIA 还投入了大量精力和算力来创建对用户有用的预训练模型的 Collection。
NVIDIA 鼓励开发者尝试 NeMo。请访问 NVIDIA 的 GitHub,以使用 NeMo 的交互式教程。本文开头讨论的语音交换示例就是一个很好的起点。
最后,NeMo 是 GitHub 上的一个开源项目,NVIDIA 欢迎外部的贡献,人们可以通过许多方式做出贡献,从编写代码或文档到使用新语言训练模型。
作者介绍:
Oleksii Kuchaiev,NVIDIA 高级应用科学家;Poonam Chitale,NVIDIA 高级产品经理。
本文转自 公众号:AI前线 ,作者Oleksii Kuchaiev,点击阅读原文