开源 TTS 最大的坑:一段话讲到一半,声音变成另一个人了。
社区大佬 Kai Wang 在 Mac Studio 上挨个测过一圈,结论是——能跑的不少,能用的没有。直到他撞上 IndexTTS2。
他列出来的痛点很具体:
- 文本一长,前后段听着像两个人
- 情绪基本表达不出来,机器味重
- 同一段输入跑两次结果还不一样
声音和情绪是两件事
传统 TTS 把“这个人长什么声音”和“这个人在用什么情绪说话”混在一起预训练。结果就是换个情绪要重新找参考音频,甚至控制不了。
IndexTTS2 把这两件事拆开了。
举个例子,你就懂了:给它一段 A 的声音做参考,然后让 A 用悲伤的语气说话——直接写一句“我特别难过”作为情绪描述就行。再切开心,A 还是 A 那个声音,只是说话方式变了。
不用为每种情绪都准备一段参考音频。这是它和别的开源 TTS 最大的差异。
情绪控制:写句话就完事
之前做配音最烦的环节:想要一段“害怕”的语气,得真的去找一段害怕的音频做参考。
IndexTTS2 不用:
text = "快躲起来!他来了!他来抓我们了!"
emo_text = "你吓我一跳!你是鬼吗?"
tts.infer(
spk_audio_prompt="voice_12.wav",
text=text,
output_path="gen.wav",
emo_alpha=0.6,
use_emo_text=True,
emo_text=emo_text,
)
emo_text 是情绪描述,emo_alpha 是情绪强度。换情绪只改一行,人声还是那个人,说话方式跟着情绪走。
实战:一个演讲者克隆成两个声音
Kai 拿这个做了个实验。
素材是 5 月 6 日 Anthropic 在旧金山 Code with Claude 活动里的一段对话。原视频里只有一个人在台上讲,他想把这一个人替换成两个克隆声音:男声讲一半,女声讲一半。
流程拆开看其实很简单:
原视频 → 提取音频 → Whisper 转 SRT → IndexTTS2 重新合成 → 替换原音轨
SRT 里每一行加一个说话人标签,脚本循环跑,男声段用男声参考,女声段用女声参考,最后按时间轴拼回去。
核心代码长这样(简化版):
from indextts.infer_v2 import IndexTTS2
tts = IndexTTS2(
cfg_path="checkpoints/config.yaml",
model_dir="checkpoints",
device="mps", # Mac 用 mps,也能换 cpu / cuda
)
ref_map = {
"Male": "refs/male.wav",
"Female": "refs/female.wav",
}
for i, sub in enumerate(subtitles):
tts.infer(
spk_audio_prompt=ref_map[sub.speaker],
text=sub.text,
output_path=f"seg_{i:04d}.wav",
)
参考音频干净就行,10 秒左右够用,不用特别长。
不想写代码?有 WebUI
界面把核心参数都暴露出来了,情绪控制有四种方式:
| 方式 |
适用场景 |
| 跟参考音频一致 |
参考音频本身情绪就对 |
| 上传情绪参考音频 |
有现成的情绪样本 |
| 选内置情绪向量(8 个) |
快速套一个常见情绪 |
| 文字描述情绪 |
最灵活,对应代码里的 emo_text |
Kai 的工作流是:先在 WebUI 里调好参数,再把配置搬到脚本里批量跑。
安装别自己动手
他直接交给 Codex 干了,一句话:
帮我装 IndexTTS2,把 web demo 跑起来。
环境配置、模型权重下载、依赖冲突、各种小报错——全程没自己动手。这个时代装环境基本不用人干了。
谁该试一下
- 做 AI 视频、教程、播客的
- 想做多语言配音但不想付云 TTS 钱的
- 对声音风格控制有要求,云 TTS 给不了的
本地、可控、免费。Kai 的原话是:目前没找到能换掉它的方案。
GitHub: https://github.com/index-tts/index-tts
在云栈社区,还有更多开源实战项目讨论与资源共享。