news 2026/9/14 19:04:42

unilm 仓库 GSLM 之 unit2speech 模型:基于离散语音单元的 Tacotron2 语音合成与推理实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
unilm 仓库 GSLM 之 unit2speech 模型:基于离散语音单元的 Tacotron2 语音合成与推理实战指南

unilm 仓库 GSLM 之 unit2speech 模型:基于离散语音单元的 Tacotron2 语音合成与推理实战指南

【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm

本文是 kosmos-2/fairseq/examples/textless_nlp/gslm 子项目(Generative Spoken Language Modeling)中unit2speech模块的技术指南。它讲解如何利用一个改造自 Tacotron2 的声学模型,把由 Log Mel Filterbank、Modified CPC、HuBERT Base 或 wav2vec 2.0 Large 配合 K-means 量化得到的离散语音单元,重新合成为可听的自然语音(配合 Waveglow 声码器)。读完本文,你将掌握 unit2speech 的模型下载清单、运行环境准备、量化单元输入文件格式,以及端到端推理脚本synthesize_audio_from_units.py的完整参数与底层调用链,并理解其源码级实现原理。

1. 什么是 unit2speech:从离散单元回到语音

在 GSLM(Generative Spoken Language Modeling)流水线中,语音被拆解为三个环节(见 gslm/README.md):

  • speech2unit:把原始语音量化为离散单元(speech2unit 子目录);
  • ulm:在离散单元上训练生成式语言模型(ulm 子目录);
  • unit2speech:把离散单元重新合成为语音,即本文主体(unit2speech 子目录)。

unit2speech 模型是Tacotron2 的改造版本:它不再以字符/音素文本为输入,而是以离散语音单元序列为输入,学习从单元序列到梅尔频谱再到波形音频的映射。官方模型均基于量化后的 LJSpeech 数据集训练,上游单元来源可以是以下四种声学特征之一:

  • Log Mel Filterbank(logmel)
  • Modified CPC
  • HuBERT Base
  • wav2vec 2.0 Large

每种特征再配合 K-means 聚类得到的码本规模(KM50 / KM100 / KM200,即 50 / 100 / 200 个簇)即可构成不同分辨率的离散单元。关键约束是:推理时输入给 unit2speech 的量化音频,必须使用与训练该模型时完全相同的单元体系(同一上游特征 + 同一 K 值)。

2. 预训练模型下载清单

| 上游单元 | 模型与码表下载 | 模型 md5 | |-|-|-| | Log Mel Filterbank + KM50 | model · code_dict |932b3b8527c0125f5f964b57762eba49| | Log Mel Filterbank + KM100 | model · code_dict |cde0b0d278a39011d0acbd5df27abdf4| | Log Mel Filterbank + KM200 | model · code_dict |dba0f1d4de64bc7976718834010b23e7| | Modified CPC + KM50 | model · code_dict |a585e8dd8890ea56164f17635dd8e613| | Modified CPC + KM100 | model · code_dict |5c0ee2869b4f483d17f37f1a41a548e0| | Modified CPC + KM200 | model · code_dict |2f0c9951cf37020d9464514bff48bc5d| | HuBERT Base + KM50 | model · code_dict |85ffce8baec5aa90035ab696fe676fce| | HuBERT Base + KM100 | model · code_dict |df4a9c6ffd1bb00c91405432c234aba3| | HuBERT Base + KM200 | model · code_dict |ac72f2c0c563589819bec116c7f8d274| | wav2vec 2.0 Large + KM50 | model · code_dict |e3503d0ad822b2c24b89f68b857fedff| | wav2vec 2.0 Large + KM100 | model · code_dict |eb3666e456ae4c96bf2a1eec825c13ed| | wav2vec 2.0 Large + KM200 | model · code_dict |777d343e963c4d64f04d78eef032f4e8|

每个条目由两部分组成:

  • modeltts_checkpoint_best.pt,即训练好的 unit2speech(改造版 Tacotron2)检查点;
  • code_dict:训练时使用的码表文件,每行一个单元标识,推理时把量化单元字符串映射为词表 ID(详见第 5 节)。

下载后建议用表中 md5 校验文件完整性。另外还需要一个声码器:

  • Waveglow checkpointwaveglow_256channels_new.pt(256 通道版本),它是从梅尔频谱合成最终波形音频的声码器。

3. 运行环境准备

官方 README 给出的依赖安装命令:

pip install librosa, unidecode, inflect

配套的推理代码 synthesize_audio_from_units.py 还依赖soundfile(写入 wav 输出)与torch(模型推理),因此实际环境还需要:

pip install soundfile torch

此外,如果要使用交互式复述工具 resynthesize_speech.py 还需要joblib(加载 K-means 模型)。请确保运行机器具备可用的 CUDA GPU,因为源码中模型与输入张量均被显式搬移到.cuda()(见 utils.py 的load_tacotronload_waveglowsynthesize_audio)。

4. 输入文件:量化单元清单格式

推理脚本通过--quantized_unit_path读取一个文本清单文件,每行表示一条待合成的音频,格式为:

<基础文件名>|<整数单元ID 用空格分隔>

例如:

utt_0001|12 8 45 90 3 67 ... utt_0002|1 2 3 4 5 6 7 ...

解析逻辑位于 utils.py 的load_quantized_audio_from_file:按行切分|,左侧为输出 wav 的基础文件名,右侧将空格分隔的字符串转换为整数列表。输出时脚本会生成<基础文件名>.wav写入--out_audio_dir(见 synthesize_audio_from_units.py)。

如何获得这些量化单元?需要先对原始音频做特征提取与 K-means 量化,即 speech2unit 环节(speech2unit/README.md)。值得注意的是,若要跨 16k 采样率处理,仓库还提供了 convert_to_16k.py 脚本,它基于sox把目录下音频统一转成单声道 16bit 16kHz wav(sox -c 1 -b 16 ... rate 16k)。

5. 端到端推理命令与参数详解

官方 README 给出的标准推理命令:

FAIRSEQ_ROOT=<path_to_your_fairseq_repo_root> TTS_MODEL_PATH=<unit2speech_model_file_path> QUANTIZED_UNIT_PATH=<quantized_audio_file_path> OUT_DIR=<dir_to_dump_synthesized_audio_files> WAVEGLOW_PATH=<path_where_you_have_downloaded_waveglow_checkpoint> CODE_DICT_PATH=<unit2speech_code_dict_path> PYTHONPATH=${FAIRSEQ_ROOT}:${FAIRSEQ_ROOT}/examples/textless_nlp/gslm/unit2speech python ${FAIRSEQ_ROOT}/examples/textless_nlp/gslm/unit2speech/synthesize_audio_from_units.py \ --tts_model_path $TTS_MODEL_PATH \ --quantized_unit_path $QUANTIZED_UNIT_PATH \ --out_audio_dir $OUT_DIR \ --waveglow_path $WAVEGLOW_PATH \ --code_dict_path $CODE_DICT_PATH \ --max_decoder_steps 2000

其中FAIRSEQ_ROOT指向本仓库kosmos-2/fairseq目录。由于脚本内部使用from examples.textless_nlp.gslm.unit2speech...形式的包导入,必须把 fairseq 根目录及 unit2speech 目录加入PYTHONPATH

5.1 参数总表

以下参数由 get_parser() 定义:

| 参数 | 类型 | 默认值 | 含义 | |-|-|-|-| |--quantized_unit_path| str | 必填 | 量化单元清单文件路径(格式见第 4 节) | |--tts_model_path| str | 必填 | unit2speech(Tacotron2)检查点路径 | |--waveglow_path| str | 必填 | Waveglow 声码器检查点路径 | |--code_dict_path| str | 必填 | 与训练单元体系一致的码表文件路径 | |--max_decoder_steps| int |2000| 解码器最大自回归步数上限,防止生成失控无限循环 | |--denoiser_strength| float |0.1| Waveglow denoiser 的降噪强度 | |--out_audio_dir| str | 必填 | 合成 wav 输出目录 |

5.2 推理主流程(源码级)

synthesize_audio_from_units.py 的main按以下步骤执行:

  1. 加载量化单元load_quantized_audio_from_file解析清单,得到文件名列表与单元整数序列;
  2. 加载 Tacotron2load_tacotron读取检查点中的hparams、把max_decoder_steps覆盖为用户传入值,恢复Tacotron2权重并转为cuda().eval().half()(半精度推理);
  3. 加载 Waveglowload_waveglow读取声码器与Denoiser,同样半精度搬移到 GPU;
  4. 码表兜底:若检查点内记录的hparams.code_dict路径不存在,则改用--code_dict_path
  5. 逐条合成:对每个文件,把整数单元序列拼成字符串" ".join(...),交给TacotronInputDataset.get_tensor转为 token ID 张量,再调用synthesize_audio得到梅尔谱、原始波形与降噪后波形,最后以检查点记录的采样率写出<name>.wav

其中synthesize_audio(utils.py)内部完成:model.inference自回归生成梅尔谱 →waveglow.infer(mel, sigma=0.666)从梅尔谱合成波形 →denoiser(aud, strength=...)去除声码器高频噪声。

6. 量化单元如何变成 token:码表与预处理细节

TacotronInputDataset(tts_data.py)负责把量化单元字符串转成模型输入张量,其行为由检查点内hparams的若干字段控制:

  • text_or_code:决定走文本路径还是单元路径。unit2speech 为"code",此时使用码表;若为"text"则退化为传统文本 TTS(english_cleaners);
  • code_dict:码表文件路径。加载时在首行前置_作为 padding 占位(见 tacotron2/utils.py 的load_code_dict),随后按行建立{单元字符串: 数字ID}映射;
  • add_sos/add_eos:是否在单元序列首尾插入<s>/</s>特殊 token(对应 tacotron2/text.py 定义的SOS_TOK/EOS_TOK),token 追加在码表末尾;
  • collapse_code:是否合并相邻重复单元(连续相同单元只保留一个)。启用时还会抑制“单元未登录(OOV)”告警;禁用时若 OOV 比例超过 5%,会打印WARNING : over 5% codes are OOV(见 tacotron2/text.py 的code_to_sequence)。

实战要点--code_dict_path必须与模型训练时完全一致(对应表中同行的 code_dict),且量化单元必须来自同一上游特征与同一 K 值;否则会出现大量 OOV 或语义错配,合成质量严重下降。

7. 改造版 Tacotron2 的架构原理

unit2speech 在传统 Tacotron2 基础上做了适配,核心实现位于 tacotron2/model.py,可从源码结构看出以下几大组件:

  • Encoder(model.py#L150-L202):三组一维卷积(ConvNorm+ BatchNorm)+ 双向 LSTM,对输入的 token 序列编码。unit2speech 中该 token 序列来自码表 ID(离散单元),而非音素;
  • Prenet(model.py#L90-L101):两层线性投影 + ReLU + 训练时 dropout 0.5,为解码器提供上一步梅尔帧;
  • Attention(model.py#L30-L87):location-sensitive 注意力,把当前解码状态与编码器记忆对齐,提供对齐分数与上下文向量,用于自回归逐帧生成;
  • Decoder(model.py#L269-L450):两层 RNN(attention RNN + decoder RNN),每步预测n_frames_per_step帧梅尔谱与一个门控(gate)输出,门控值超过gate_threshold或达到max_decoder_steps即停止生成;
  • Postnet(model.py#L104-L147):五层一维卷积,对梅尔谱进行残差细化,提升高频还原度;
  • AudioEncoder / 潜在属性模块(model.py#L205-L266):额外的卷积 + 双向 LSTM + 全局平均池化分支,输出均值/方差并重参数化采样一个潜在向量z,在解码时作为属性条件拼接(obs_and_lat),用于刻画说话人/风格等信息。

推理时由model.inference走自回归路径:以全零帧启动(get_go_frame),每步把上一帧梅尔谱经 Prenet 送入注意力与解码器,直到门控判定结束。随后梅尔谱交给 Waveglow 声码器生成波形,这正是第 5.2 节synthesize_audio的完整闭环。

8. 相关工具与扩展用法

除了批量推理脚本,仓库还提供交互式复述工具 resynthesize_speech.py:它读取一条真实语音文件路径,先用--feature_typelogmel/hubert/w2v2/cpc)对应的预训练特征提取器取特征,再经 K-means 模型(--kmeans_model_path)量化得到单元序列,最后走与第 5 节完全相同的 unit2speech + Waveglow 链路合成语音并写出 wav,实现在线逐条“语音 → 单元 → 语音”的复述。

该工具同样支持--tts_model_path--code_dict_path--waveglow_path--max_decoder_steps(默认 2000)与--denoiser_strength(默认 0.1)等参数,可视为 unit2speech 推理能力的复用示例。

9. 常见问题与注意事项

  • PYTHONPATH 配置错误:脚本采用examples.textless_nlp.gslm.unit2speech包内导入,务必按第 5 节设置PYTHONPATH,否则ModuleNotFoundError
  • 单元体系不匹配:合成音频使用的量化单元必须与目标模型的上游特征、K 值一致,且code_dict必须与模型训练时相同,否则 OOV 激增、合成失败或音质严重劣化;
  • GPU 依赖load_tacotronload_waveglowsynthesize_audio均直接调用.cuda(),无 GPU 环境无法运行;
  • 合成长度失控:若单元序列很长或门控未及时触发停止,解码器可能长时间自回归,可用--max_decoder_steps(默认 2000)作为硬上限;
  • 采样率:输出 wav 的采样率来自检查点内hparams.sampling_rate(LJSpeech 体系下通常为 22050),必要时可先经 convert_to_16k.py 统一为 16k 再进入上游量化流程。

10. 小结

unit2speech 是 GSLM 闭环中“单元 → 语音”的关键一环:它把 Tacotron2 的文本输入替换为离散语音单元,配合 K-means 码表与 Waveglow 声码器,即可从任意(与训练同源的)量化语音单元序列重建可听语音。结合本文给出的模型下载清单、环境准备、清单文件格式、完整推理命令与源码级原理拆解,你可以在 kosmos-2/fairseq/examples/textless_nlp/gslm/unit2speech 目录下直接复现该流程,并与 speech2unit、ulm 两个环节串联成完整的生成式口语语言建模系统。

【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 19:04:11

西安成人专升本机构怎么选?附 2026 核验清单

直接答案&#xff1a;先定路径&#xff0c;再选机构。专升本至少有成考专升本、自考专升本、国开专升本三条路&#xff0c;入学方式、考试安排、时间成本完全不同。路径没定就去选机构&#xff0c;等于让别人替你决定后半程怎么走。一、第一步是把路径定下来很多人问"哪家…

作者头像 李华
网站建设 2026/9/14 19:03:39

Tolaria 的 Vault 文件布局:扁平结构、递归扫描与特殊目录约定

Tolaria 的 Vault 文件布局&#xff1a;扁平结构、递归扫描与特殊目录约定 【免费下载链接】tolaria Desktop app to manage markdown knowledge bases 项目地址: https://gitcode.com/GitHub_Trending/to/tolaria Tolaria 是一款以 Markdown 为源、以 Git 为同步介质的…

作者头像 李华
网站建设 2026/9/14 19:03:21

网盘直链下载助手:八大网盘直链地址一键获取

网盘直链下载助手&#xff1a;八大网盘直链地址一键获取 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅…

作者头像 李华
网站建设 2026/9/14 18:55:36

微信小程序音乐播放器源码解析:从页面架构到后台播放

简介&#xff1a;基于微信小程序的音乐播放器源码是一份完整的小程序实战项目&#xff0c;面向零基础及有经验的开发者&#xff0c;既可用于学习&#xff0c;也可作为快速搭建音乐播放功能的框架。项目覆盖小程序架构的核心环节&#xff0c;包括WXML/WXSS页面结构设计、JavaScr…

作者头像 李华