NeMo Speech 五分钟上手实战:ASR 转录、Magpie TTS 合成、说话人分离与 SpeechLM2 语音大模型一站式指南
【免费下载链接】SpeechA scalable generative AI framework built for researchers and developers working on Large Language Models, Multimodal, and Speech AI (Automatic Speech Recognition and Text-to-Speech)项目地址: https://gitcode.com/GitHub_Trending/nem/Speech
导读
本文基于 NeMo Speech 官方《Ten Minutes》快速上手指南(docs/source/starthere/ten_minutes.rst)整理而成,带你在约 50 行 Python 代码内完成四大核心任务的端到端实操:用 Parakeet 系列模型将音频转写为文本(含逐词时间戳)、用 Magpie TTS 从文本合成多语言语音、用 Sortformer 模型对多人会议音频进行说话人分离,以及用 Canary-Qwen 语音语言模型执行"语音进、文本出"的生成式推理。读完本文,你将掌握 NeMo Speech 全部核心能力的调用方式、关键参数语义及其底层实现原理,可直接迁移到自己的推理脚本中。
前提:开始前请先完成 NeMo Speech 的安装,参见安装指南。文中所有模型均通过
from_pretrained从 Hugging Face 拉取预训练权重,首次运行需联网下载。
1. 语音转录(ASR):三行代码把音频变成文字
Automatic Speech Recognition(ASR)将语音转换为文本。NeMo Speech 的Parakeet系列模型是该方向的主力模型。下面从"最简调用"到"带时间戳"再到"命令行批量处理"逐步展开。
1.1 最简转录:3 行代码
import nemo.collections.asr as nemo_asr asr_model = nemo_asr.models.ASRModel.from_pretrained("nvidia/parakeet-tdt-0.6b-v2") transcript = asr_model.transcribe(["audio.wav"])[0].text print(transcript)要点说明:
ASRModel.from_pretrained(...)是 NeMo 统一的模型加载入口,nvidia/parakeet-tdt-0.6b-v2为 Parakeet TDT(Token-and-Duration Transducer)架构的 0.6B 参数版本;transcribe接受单个文件路径、路径列表、np.ndarray/torch.Tensor音频数组,甚至 manifest 文件路径(见 ctc_models.py 的签名定义);- 返回结果是按输入顺序排列的假设列表,
[0].text取第一条假设的转写文本。
1.2 带时间戳转录:知道每个词"何时说出"
hypotheses = asr_model.transcribe(["audio.wav"], timestamps=True) for stamp in hypotheses[0].timestamp['word']: print(f"{stamp['start']}s - {stamp['end']}s : {stamp['word']}")实现细节(值得了解):
- 当
timestamps=True时,transcribe内部会自动开启解码策略中的compute_timestamps,并强制return_hypotheses=True(见 ctc_models.py); - 时间戳按
word、segment、char三个粒度挂在假设对象的timestamp字段上,每个词包含start/end(秒)与word文本; transcribe还支持batch_size(越大吞吐越高、显存占用越大)、num_workers、channel_selector(多声道选通道或'average'平均混音)等参数,批量推理场景非常实用。
1.3 命令行批量转录
python examples/asr/transcribe_speech.py \ pretrained_name="nvidia/parakeet-tdt-0.6b-v2" \ audio_dir=./my_audio_files/对应脚本 examples/asr/transcribe_speech.py 的配置规则如下:
- 模型二选一:
model_path(本地.nemo检查点)或pretrained_name(NGC 注册表/ Hugging Face 预训练名),两者不可同时为空; - 数据二选一:
audio_dir(音频目录)或dataset_manifest(NeMo manifest 文件),两者不可同时为空; - 脚本内部会校验这四项约束,不满足直接抛
ValueError(见 transcribe_speech.py)。
2. 语音合成(TTS):用 Magpie TTS 从文本生成自然语音
Text-to-Speech(TTS)从文本生成自然音频。NeMo Speech 的Magpie TTS是基于 codec(神经音频编解码)的多语言模型,支持多说话人、多语言,并可通过说话人索引切换音色。
from nemo.collections.tts.models import MagpieTTSModel import soundfile as sf # 加载多语言 357M 模型(来自 Hugging Face) model = MagpieTTSModel.from_pretrained("nvidia/magpie_tts_multilingual_357m") model.eval() # 生成语音 audio, audio_len = model.do_tts( transcript="Hello! Welcome to NeMo Speech AI.", language="en", ) # 保存为文件 sf.write("output.wav", audio[0].cpu().numpy(), 22050) print("Speech saved to output.wav")do_tts是 magpietts.py 中为"单句合成"提供的便捷方法,其核心参数如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
transcript | 必填 | 待合成的原始文本 |
language | "en" | 语言代码,用于文本归一化与 tokenizer 选择,常见取值如en、de、es等,具体以模型 tokenizer 配置为准 |
apply_TN | False | 是否启用nemo_text_processing做文本归一化(如数字、日期展开);开启前需安装对应依赖 |
use_cfg | True | 是否使用 Classifier-Free Guidance(无分类器引导),提升合成质量与稳定性 |
speaker_index | None | 内置说话人索引,取值[0, num_baked_speakers - 1],None时使用说话人 0 |
返回值说明(来自源码 docstring):
audio:生成的波形,形状为(1, T_audio);audio_len:音频采样点数,形状为(1,);- 该方法仅支持内置说话人(baked context embedding)的语音合成,不支持自定义音色条件注入;自定义音色请改用
infer_batch等高级接口; - 若模型没有内置说话人 embedding,
do_tts会直接抛出ValueError。
此外,源码中还包含一个实用细节:当language == "ja"(日语)时,方法会自动移除文本中的空格以规避日语归一化器的已知问题(见 magpietts.py)。
3. 说话人分离(Diarization):回答"谁在什么时候说话"
说话人分离解决多说话人音频中的"who spoke when"问题。NeMo Speech 的Sortformer端到端模型可直接输出带说话人标签的语音片段。
from nemo.collections.asr.models import SortformerEncLabelModel diar_model = SortformerEncLabelModel.from_pretrained("nvidia/diar_streaming_sortformer_4spk-v2") diar_model.eval() segments = diar_model.diarize(audio=["meeting.wav"], batch_size=1) for seg in segments[0]: print(seg) # (begin_seconds, end_seconds, speaker_index)SortformerEncLabelModel定义于 sortformer_diar_models.py,diarize是其"一键推理"入口(sortformer_diar_models.py),关键参数:
audio:单个/多个音频文件路径,或 manifest 文件路径;batch_size:推理批大小,越大吞吐越高、显存占用越大;include_tensor_outputs:是否额外返回原始说话人活跃度概率张量;postprocessing_yaml:自定义后处理参数的 YAML 路径;override_config:DiarizeConfig配置对象,用于覆盖默认后处理行为;verbose:是否显示 tqdm 进度条。
输出格式约定:返回[[begin_seconds, end_seconds, speaker_index], ...]的片段列表;若include_tensor_outputs=True,则返回(片段列表, 概率张量列表)的元组(见 sortformer_diar_models.py)。
提示:模型名中的
streaming与4spk分别代表支持流式推理与面向 4 说话人场景优化,选用时请结合自己的会议规模评估。
4. 语音大模型(SpeechLM2):Canary-Qwen 的"语音进、文本出"生成
SpeechLM2 为 LLM 注入语音理解能力。Canary-Qwen将 ASR 编码器与 Qwen LLM 结合,支持把音频作为对话输入参与生成式推理。
from nemo.collections.speechlm2.models import SALM model = SALM.from_pretrained('nvidia/canary-qwen-2.5b') answer_ids = model.generate( prompts=[[{ "role": "user", "content": f"Transcribe the following: {model.audio_locator_tag}", "audio": ["speech.wav"], }]], max_new_tokens=128, ) print(model.tokenizer.ids_to_text(answer_ids[0].cpu()))这套用法与 salm.py 中generate的高层 API 完全对应,理解几个核心概念:
audio_locator_tag:音频占位符 token(源码中取自self.cfg.audio_locator_tag,见 salm.py)。它在提示词中出现的位置决定音频嵌入被插入文本序列的哪个位置,模型初始化时会将其注册为特殊 token(salm.py);prompts:支持多轮对话结构(role/content/audio),每个 prompt 中<audio_locator_tag>的出现次数必须与audio列表中的音频数一致,一个 prompt 可携带多段音频;max_new_tokens:控制生成最大新 token 数,示例中128适合转写类短任务;- 更精细的控制:可传入 Hugging Face
GenerationConfig对象自定义解码策略,例如GenerationConfig(do_sample=True, num_beams=5); - 低层 API:将音频预加载为
(batch, time)的float32张量并通过audios/audio_lens传入,适合对加载流程有定制需求的场景(见 salm.py 的三种用法示例)。
由于generate返回的是 token id 张量,最后需用model.tokenizer.ids_to_text(...)解码为可读文本——这一步是新手最容易遗漏的收尾操作。
5. 四大任务背后的统一设计:NeMo 模型基座
观察前四节可以发现一条统一规律:所有任务都走from_pretrained加载 + 任务专属推理方法的模式。这与 NeMo 的模型基座设计一脉相承:
ASRModel、MagpieTTSModel、SortformerEncLabelModel继承自ModelPT(NeMo 可训练模型基类),统一提供from_pretrained、保存/恢复、导出等能力;SALM则基于LightningModule+HFHubMixin实现(salm.py),与 Hugging Face 生态深度互通,便于复用 LLM 的 chat template 与GenerationConfig解码体系;- 推理方法高度"一键化":
transcribe(ASR)、do_tts(TTS)、diarize(分离)、generate(SpeechLM2),输入输出约定统一、上手成本低。
这种"统一基座 + 任务专属接口"的设计,使得从单任务原型到多任务流水线(如"先 VAD 切段 → 再 ASR 转写 → 最后 diarization 归属说话人")的拼装变得非常自然。
6. 下一步:从快速上手到深入进阶
到这里你已经跑通了 NeMo Speech 的全部核心能力。继续深入的方向与对应仓库文档如下:
- key_concepts.rst — 理解这些模型背后的语音 AI 核心概念;
- choosing_a_model.rst — 针对自己的场景(语言、实时性、显存预算)选择合适的模型;
- docs/source/asr/ — 完整的 ASR 文档(含说话人分离与识别、流式解码、CTC/Transducer/Hybrid 架构等);
- docs/source/tts/ — 完整的 TTS 文档(FastPitch、HiFi-GAN、Magpie 系列等);
- docs/source/asr/speaker_diarization/ — 说话人分离与识别的深入文档;
- tutorials.rst — 配套的 Jupyter Notebook 教程。
如果你需要运行更完整的参考实现,仓库中的 examples/asr/transcribe_speech.py(含并行转录脚本transcribe_speech_parallel.py)、examples/tts/magpietts.py 以及 examples/speechlm2/ 目录下的salm_eval.py、salm_generate.py都是可直接修改运行的实战入口,可作为本文示例代码的工程化延伸。
【免费下载链接】SpeechA scalable generative AI framework built for researchers and developers working on Large Language Models, Multimodal, and Speech AI (Automatic Speech Recognition and Text-to-Speech)项目地址: https://gitcode.com/GitHub_Trending/nem/Speech
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考