文本转语音 TTS:从 Tacotron 到 F5 与 Kokoro 本节摘要:ASR 把语音反转成文字,TTS(Text-to-Speech)把文字反转成语音。2026 年的工具栈分三段:文本 → token,token → 梅尔,梅尔 → 波形,每一段都有一个能塞进笔记本的默认模型。给你一句「请在下午 6 点提醒我浇花」,你需要一段 3 秒、听起来自然、韵律正确(停顿、重音)、「plants」元音念对、CPU 上 300 毫秒内跑完的音频——还要能换声音、处理语码切换输入、不在人名上丢脸。
本节摘要:ASR 把语音反转成文字,TTS(Text-to-Speech)把文字反转成语音。2026 年的工具栈分三段:文本 → token,token → 梅尔,梅尔 → 波形,每一段都有一个能塞进笔记本的默认模型。给你一句「请在下午 6 点提醒我浇花」,你需要一段 3 秒、听起来自然、韵律正确(停顿、重音)、「plants」元音念对、CPU 上 300 毫秒内跑完的音频——还要能换声音、处理语码切换输入、不在人名上丢脸。本节将沿「Tacotron 2(seq2seq 注意力)→ FastSpeech 2(非自回归时长预测)→ VITS(端到端流+变分推断)→ F5-TTS(流匹配扩散)→ Kokoro(CPU 实时)」这条阶梯逐代演进,讲透声码器(vocoder)从 WaveNet 到 HiFi-GAN 再到神经编解码器的演化,以及 MOS、UTMOS、CER-via-ASR、SECS 这四类评估指标。读完本节,你能为「实时助手」「5 秒参考的零样本克隆」「有声书」「低资源语种」等不同场景选对 TTS 方案,并避开文本归一化、OOV 专名、削波、采样率失配等坑。
阅读完本节,你应当能够:
给你一个字符串:「Please remind me to water the plants at 6 pm.」你需要一段 3 秒音频,听起来自然,韵律正确(停顿、重音),「plants」元音念对,在 CPU 上 300 毫秒内跑完,服务于实时语音助手。你还要能换声音、处理语码切换输入(「remind me at 6 pm, daijoubu?」),并不在人名上丢脸。
现代 TTS 流水线长这样:
到 2026 年,声学模型 + 声码器的分割在端到端扩散与流匹配模型里变得模糊,但「三段式」心智模型仍是排障利器。
商业 SOTA 还有 OpenAI TTS-1-HD、ElevenLabs v2.5、Google Chirp-3。ElevenLabs v2.5 的情感标签(「[whispered]」「[laughing]」)与角色声音在 2026 年的有声书生产中占统治地位。
| 年代 | 声码器 | 延迟 | 质量 |
|---|---|---|---|
| 2016 | WaveNet | 仅离线 | 发布时 SOTA |
| 2018 | WaveRNN | 近实时 | 好 |
| 2020 | HiFi-GAN | 100× 实时 | 接近人类 |
| 2022 | BigVGAN | 50× 实时 | 跨说话人/语种泛化 |
| 2024 | SNAC、DAC(神经编解码) | 与 AR 模型集成 | 离散 token,比特高效 |
到 2026 年,多数「TTS」模型已经从文本端到端到波形,梅尔频谱图只是内部表示。
2026 年 LibriTTS test-clean 的数字:
| 模型 | UTMOS | CER(经 Whisper) | 规模 |
|---|---|---|---|
| 真值 | 4.08 | 1.2% | — |
| F5-TTS | 3.95 | 2.1% | 335M |
| XTTS v2 | 3.81 | 3.5% | 470M |
| VITS | 3.62 | 3.1% | 25M |
| Kokoro v0.19 | 3.87 | 1.8% | 82M |
| Parler-TTS Large | 3.76 | 2.8% | 2.3B |
💡 注意 Kokoro(82M)的 CER 1.8% 比 F5-TTS(335M)的 2.1% 还低——可懂度未必随参数量单调上升。F5 的优势在自然度与零样本克隆,而非纯粹的可懂度。这印证了选模型要先想清楚优化的是哪个指标。
from phonemizer import phonemize ph = phonemize("Hello world", language="en-us", backend="espeak") # 'həloʊ wɜːld'
音素是通用桥梁。任何质量低于 VITS 级别的模型,都别直接喂原始文本。
from kokoro import KPipeline tts = KPipeline(lang_code="a") # "a" = 美式英语 audio, sr = tts("Please remind me to water the plants at 6 pm.", voice="af_bella") # audio: float32 张量, sr=24000
离线、单文件、82M 参数。
from f5_tts.api import F5TTS tts = F5TTS() wav = tts.infer( ref_file="my_voice_5s.wav", ref_text="The quick brown fox jumps over the lazy dog.", gen_text="Please remind me to water the plants.", )
传一段 5 秒参考音频 + 其转写,F5 就克隆韵律与音色。
完整实现塞不进教程脚本,但形状是:
class HiFiGAN(nn.Module): def __init__(self, mel_channels=80, upsample_rates=[8, 8, 2, 2]): super().__init__() # 4 个上采样块,共 256× 把梅尔率提升到音频率 ... def forward(self, mel): return self.blocks(mel) # -> 波形
训练:对抗(短窗判别器)+ 梅尔频谱图重建损失 + 特征匹配损失。已商品化——直接用 hifi-gan 仓库或 nvidia-NeMo 的预训练检查点。
设计要点:HiFi-GAN 把 80 维梅尔上采样 256 倍(8×8×2×2)到波形采样率,本质是「学一个从低时间分辨率频谱到高时间分辨率波形的非线性插值器」。判别器分别看不同尺度的波形窗口(多周期判别器 + 多尺度判别器),迫使生成器同时优化宏观包络与微观细节。
text = "Please remind me at 6 pm." phones = phonemize(text) mel = acoustic_model(phones, speaker=alice) # [T, 80] wav = vocoder(mel) # [T * 256] soundfile.write("out.wav", wav, 24000)
2026 年工具栈:
| 场景 | 选 |
|---|---|
| 实时英语语音助手 | Kokoro(CPU)或 XTTS v2(GPU) |
| 5 秒参考的声音克隆 | F5-TTS |
| 商业角色声音 | ElevenLabs v2.5 |
| 有声书朗读 | ElevenLabs v2.5 或 XTTS v2 + 微调 |
| 低资源语种 | 在 5~20 小时目标语种数据上训 VITS |
| 表现力 / 情感标签 | ElevenLabs v2.5 或 StyleTTS 2 微调 |
2026 年开源领头羊:F5-TTS 拼质量,Kokoro 拼效率。除非你是历史学家,否则别碰 Tacotron。
⚠️ 四类陷阱:① 无文本归一化器——「Dr. Smith」读成「Doctor」还是「Drive」?「2026」读成「twenty twenty six」还是「two zero two six」?必须在 phonemizer 之前归一化;② OOV 专名——「Ghumare」读成「ghyu-mair」?给未知 token 配一个回退的字素到音素模型;③ 削波——声码器输出很少削波,但推理时梅尔缩放失配会冲出 ±1.0,始终
np.clip(wav, -1, 1);④ 采样率失配——Kokoro 输出 24 kHz,下游流水线期望 16 kHz,不重采样就会混叠。
本节产出技能文档(原课程 outputs/skill-tts-designer.md),为给定声音、延迟、语种目标设计 TTS 流水线。核心决策表:
基础:运行 code/main.py。它从玩具词表建音素词典,估算每音素时长,打印假的「梅尔」排程。
进阶:装 Kokoro,用 af_bella 与 am_adam 两个声音合成同一句,对比音频时长与主观质量。
挑战:录一段 5 秒自己的参考音频,用 F5-TTS 克隆,汇报参考与克隆输出之间的 SECS。
下一节,我们聚焦「换声音」——语音克隆与转换,讲透零样本克隆、跨语种克隆、实时变声,以及背后的伦理与反欺诈考量。