1. 本章目标
本章的目标是:
通过一组可复现的对照实验,解释现代神经网络 TTS 中"多次生成同一句话,但不完全一致"的现象,并在工程应用中进行控制。
完成本章后,读者应能够:
- 理解 TTS 为什么会有随机性
- 通过实验验证"存在随机性,而且可控制"
- 如何在工程应用中进行控制:何时固定随机种子seed,何时保留变化
2. 结论先行
在进入细节之前,需要先明确本章的核心结论:
现代神经网络 TTS 的随机性通常不是缺陷,而是自然度的重要来源;同时,这种随机性在工程上是可控制、可复现的。
具体而言:
- 不固定随机种子(seed)时:同一句话可能出现轻微差异(语速、停顿、韵律细节)
- 固定随机种子(seed)时:同一句话的生成结果在同一环境中可高度复现
3. 背景:为什么"完全一致"反而可能不自然?
现实中的人类朗读并不是确定性过程。即使同一个人重复朗读同一句话,也会出现:
- 呼吸位置差异
- 音节时长变化
- 语调与停顿的细微波动
因此,在听感层面,"每次都完全一致"的语音输出往往会更接近机械朗读。
现代 TTS 的发展趋势之一,就是在保持可理解性的前提下,引入受约束的变化,使朗读更接近真实语音。
4. 机制概念:随机性与噪声的区别
在工程语境中应明确区分:
- 噪声(Noise):不可预测、破坏音质/可理解性的干扰(爆音、断裂、失真)
- 随机性(Stochasticity):在合理范围内的变化,不改变语义,主要影响韵律细节(节奏、停顿、语调微差)
本章讨论的是后者。
5. 实验设计:用对照方法验证"随机性存在且可控"
本章采用最简单且最有效的对照实验:
- 不固定 seed:连续生成 3 次,比较差异
- 固定 seed:连续生成 3 次,比较一致性
实验的目标不是"每个人都必须听出明显差别",而是验证:
- 变化是否存在
- 是否能通过 seed 控制复现性
6. 环境准备
6.1 安装依赖
bash
pip install torch transformers soundfile
说明:
torch:推理框架transformers:加载 MMS-TTS 模型与 tokenizersoundfile:写出 wav 文件
7. 完整可运行代码
将以下代码保存为 exp_tts_randomness.py,然后运行。
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Experiment: randomness vs deterministic output in neural TTS
Model: facebook/mms-tts-adx (Amdo Tibetan)
Outputs:
- out_random_1.wav / out_random_2.wav / out_random_3.wav
- out_fixed_1.wav / out_fixed_2.wav / out_fixed_3.wav
"""
from transformers import VitsModel, AutoTokenizer
import torch
import soundfile as sf
def synthesize_to_wav(model, tokenizer, text: str, out_path: str):
"""Synthesize one utterance and save to wav."""
inputs = tokenizer(text, return_tensors="pt")
with torch.no_grad():
waveform = model(**inputs).waveform # shape: (1, n_samples)
sf.write(
out_path,
waveform.squeeze().cpu().numpy(),
samplerate=model.config.sampling_rate
)
def main():
# 1) Load model & tokenizer (must be done before calling synthesize)
model_name = "facebook/mms-tts-adx"
model = VitsModel.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
# 2) A short Tibetan sentence for testing
text = "བོད་སྐད་ནི་སྐད་ཡིག་གལ་ཆེན་པོ་ཞིག་ཡིན།"
# -----------------------------
# Part A: stochastic outputs
# -----------------------------
# No seed is set here.
for i in range(1, 4):
synthesize_to_wav(model, tokenizer, text, f"out_random_{i}.wav")
# -----------------------------
# Part B: deterministic outputs
# -----------------------------
# Fix seed before each generation to force repeatability.
for i in range(1, 4):
torch.manual_seed(42)
synthesize_to_wav(model, tokenizer, text, f"out_fixed_{i}.wav")
print("Done. Generated wav files:")
print(" out_random_1.wav, out_random_2.wav, out_random_3.wav")
print(" out_fixed_1.wav, out_fixed_2.wav, out_fixed_3.wav")
print(f"Sampling rate: {model.config.sampling_rate}")
if __name__ == "__main__":
main()
8. 运行方式与验收结果
8.1 运行脚本
bash
python exp_tts_randomness.py
运行完成后,你应该在当前目录看到 6 个文件:
out_random_1.wavout_random_2.wavout_random_3.wavout_fixed_1.wavout_fixed_2.wavout_fixed_3.wav
8.2 如何验证实验结论
建议按以下顺序试听:
-
先听
out_fixed_1.wav、out_fixed_2.wav、out_fixed_3.wav- 预期:几乎完全一致(同环境下)
-
再听
out_random_1.wav、out_random_2.wav、out_random_3.wav- 预期:可能存在轻微差异(不一定每次都明显)
如果你听不出差异,也不意味着实验失败。你仍可以通过"固定组一致"来确认:
seed 能控制复现性。
9. 工程解读:在真实应用中如何使用 seed?
本章实验对应真实工程中的两类典型场景:
9.1 建议固定 seed 的场景(追求一致性)
- 教材示例音
- 教学对照音
- 自动化测试(回归测试)
目标:可复现性与一致性。
9.2 建议不固定 seed 的场景(追求自然度)
- 自然朗读
- 学习陪练(避免"机械重复感")
- 对话系统朗读
目标:自然感与多样性。
10. 常见问题与排错
10.1 NameError: name 'model' is not defined
原因:只运行了片段代码,没有加载模型。
解决:使用本章提供的完整脚本(已包含模型加载)。
10.2 下载模型很慢或失败
- 多数情况下是网络问题。
- 可尝试在网络条件更好的环境执行一次,模型会被缓存到本地,后续运行会快很多。
10.3 生成的 wav 找不到
确认运行目录是否正确。建议在脚本所在目录运行:
bash
cd path/to/your/script
python exp_tts_randomness.py
11. 本章总结
本章通过对照实验验证并明确:
- 神经网络 TTS 的输出存在"受约束的随机性"
- 固定随机种子可以获得高度可复现的输出
- 随机性是自然度的重要来源,工程上应按场景取舍
这一结论将在后续理解 VITS 与多语言 TTS 策略时反复出现。