ChatTTS 对话式语音合成实践指南:基础推理、说话人控制与细粒度韵律调节
本文基于 ChatTTS 仓库的俄语版说明文档(docs/ru/README.md)展开,完整覆盖模型定位、安装依赖、基础/进阶推理、句级与词级韵律控制等实战内容,并结合 ChatTTS/core.py、ChatTTS/config/config.py 等源码补充参数默认值与底层机制解析。读完后你将能够独立搭建 ChatTTS 推理环境,采样并复现说话人,掌握 oral_/laugh_/break_ 与 [uv_break] 等控制标记的实际用法。
俄语文档自身声明:其内容可能不是最新的,请以英文版 README 为准。本文在继承该文档全部核心内容的基础上,对与当前源码不一致之处做了标注和修正。
一、模型定位:面向对话场景的 TTS
ChatTTS 是专为对话场景(如 LLM 助手)设计的文本转语音模型,支持英语与中文。根据俄语文档与主 README.md 的说明:
- 主模型使用 100,000+ 小时的英语与中文音频数据训练;
- 在 HuggingFace 上发布的开源版本为 40,000 小时预训练模型,未做 SFT;
- 本仓库包含算法基础设施与若干简单示例;面向终端用户的扩展产品可参考社区维护的 Awesome-ChatTTS 索引仓库。
文档同时给出官方联系渠道:正式事务联系 open-source@2noise.com,QQ 群 808364215 可用于讨论,GitHub issues 同样欢迎。
二、核心特性
俄语文档总结了三大特性,与主 README 一致:
- 对话式 TTS(Conversational TTS):ChatTTS 针对对话类任务优化,能生成自然、有表现力的语音,并支持多说话人,便于构建交互式对话;
- 细粒度控制(Fine-grained Control):模型可以预测并控制细粒度韵律特征,包括笑声(laughter)、停顿(pauses)、插入语(interjections);
- 更好的韵律(Better Prosody):文档称其在韵律上超过多数开源 TTS 模型,并提供预训练模型供进一步研究与开发。
这一特性与源码结构相互印证:推理链路中专门存在“文本精炼(refine text)”阶段,由 GPT 根据提示词在文本中插入韵律控制 token;说话人则以 192 维高斯参数化嵌入的形式注入模型。
三、安装与依赖
1. 克隆与安装
git clone https://github.com/2noise/ChatTTS
cd ChatTTS
直接安装依赖:
pip install --upgrade -r requirements.txt
或使用 conda:
conda create -n chattts python=3.11
conda activate chattts
pip install -r requirements.txt
也可通过 PyPI 安装稳定版 pip install ChatTTS,或本地开发模式 pip install -e .。
当前 requirements.txt 的关键依赖为:numpy<3.0.0、torch>=2.1.0、torchaudio、transformers>=4.41.1、vocos、vector_quantize_pytorch、numba、gradio、pybase16384 等;Linux 平台还包含 pynini==2.1.5、WeTextProcessing、nemo_text_processing 三个用于文本正则化的可选包。
可选依赖(据主 README,均为不推荐/仅开发用途,此处如实转述):
- vLLM(仅 Linux):
pip install safetensors vllm==0.2.7 torchaudio,源码中load(use_vllm=True)与GPT.is_vllm分支(见 ChatTTS/core.py 中_infer_code)会切换到仓库内置的model/velocity推理引擎; - TransformerEngine / FlashAttention-2:README 明确标注 “DO NOT INSTALL”(分别处于开发中或实测会降速),仅开发目的安装。
2. 模型资产如何下载与校验
chat.load() 内部由 ChatTTS/core.py 的 download_models() 负责,支持三种来源:
| 来源 | 行为 |
|---|---|
local(默认) |
检查当前目录 asset/ 下各文件 SHA256 是否与 ChatTTS/res/sha256_map.json 一致,缺失则自动下载 |
huggingface |
通过 snapshot_download 拉取 2Noise/ChatTTS 仓库(*.yaml、*.json、*.safetensors),支持 HF_HOME 缓存 |
custom |
从 custom_path 指定的本地目录加载,仍做 SHA256 校验 |
校验逻辑位于 ChatTTS/utils/dl.py:check_all_assets 会逐项核对 Decoder.safetensors、DVAE.safetensors、Embed.safetensors、Vocos.safetensors、gpt/(config.json + model.safetensors)与 tokenizer/(三个 json)的哈希,与 ChatTTS/config/config.py 中 Path 数据类定义的文件布局一一对应。
四、基础使用:三行代码完成推理
俄语文档给出的基础用法:
import ChatTTS
from IPython.display import Audio
import torch
chat = ChatTTS.Chat()
chat.load(compile=False) # Set to True for better performance
texts = ["PUT YOUR TEXT HERE",]
wavs = chat.infer(texts)
torchaudio.save("output1.wav", torch.from_numpy(wavs[0]), 24000)
要点说明(结合 ChatTTS/core.py 源码):
Chat()构造时即初始化Config、Normalizer(加载 ChatTTS/res/homophones_map.json 同音字替换表)与 GPT 中断上下文GPT.Context();load()的完整签名为load(source, force_redownload, compile, custom_path, device, coef, use_flash_attn, use_vllm, experimental, enable_cache)。注意源码中compile仅在设备为 CUDA 时生效(gpt.prepare(compile=compile and "cuda" in str(device))),因此在 Apple Silicon(MPS)上设置compile=True不会带来收益;chat.load()依次装配 6 个模块:Vocos 声码器 → DVAE(编解码+VQ)→ Embed 嵌入层 → GPT 主干 → Speaker 说话人模块 → 独立 Decoder,可用has_loaded()检查加载完整性;- 推理输出为 24000 Hz 的 numpy 波形数组列表,保存时采样率需写为 24000。
五、进阶使用:说话人采样与两级采样参数
1. 采样说话人
rand_spk = chat.sample_random_speaker()
print(rand_spk) # save it for later timbre recovery
从源码看,sample_random_speaker() 委托给 ChatTTS/model/speaker.py 的 Speaker.sample_random():先按 randn(dim) * std + mean 从高斯分布采出 192 维向量(dim 即 ChatTTS/config/config.py 中 GPT 配置的 spk_emb_dim: int = 192),其中 mean/std 由配置文件中内嵌的 base16384 编码字符串(spk_stat)解码而来。采样结果被 LZMA 压缩后再以 base16384 编码为字符串返回——保存该字符串即可在不同会话中复现同一音色。
除随机采样外,源码还支持零样本音色:chat.sample_audio_speaker(wav) 用 DVAE 编码器对参考音频提取说话人提示(对应主 README 路线图中的“DVAE encoder and zero shot inferring code”开源项)。
2. 参数控制(当前源码以数据类为准)
俄语文档示例中 params_infer_code 写作普通 dict,这是旧版风格;当前源码的 infer() 参数默认值是数据类 ChatTTS.Chat.RefineTextParams / ChatTTS.Chat.InferCodeParams(定义于 ChatTTS/core.py),按英文 README 的当前写法应如下:
params_infer_code = ChatTTS.Chat.InferCodeParams(
spk_emb = rand_spk, # add sampled speaker
temperature = .3, # using custom temperature
top_P = 0.7, # top P decode
top_K = 20, # top K decode
)
# For sentence level manual control.
# use oral_(0-9), laugh_(0-2), break_(0-7)
# to generate special token in text to synthesize.
params_refine_text = ChatTTS.Chat.RefineTextParams(
prompt='[oral_2][laugh_0][break_6]',
)
wavs = chat.infer(
texts,
params_refine_text=params_refine_text,
params_infer_code=params_infer_code,
)
源码中的完整默认值(可据此按需覆盖):
| 参数 | 所属类 | 默认值 | 说明 |
|---|---|---|---|
prompt |
RefineTextParams | "" |
文本精炼提示,如 [oral_2][laugh_0][break_6] |
top_P / top_K |
两者 | 0.7 / 20 | 采样截断参数 |
temperature |
Refine / Infer | 0.7 / 0.3 | 两阶段温度默认不同 |
repetition_penalty |
Refine / Infer | 1.0 / 1.05 | 抑制重复 |
max_new_token |
Refine / Infer | 384 / 2048 | 各自最大生成长度 |
manual_seed |
两者 | None | 手动随机种子 |
spk_emb |
InferCodeParams | None | 说话人字符串(来自 sample_random_speaker) |
spk_smp / txt_smp |
InferCodeParams | None | 拆分推理时由首句自动提取的音色提示 |
stream_batch / stream_speed / pass_first_n_batches |
InferCodeParams | 24 / 12000 / 2 | 流式分片、每片采样点数、跳过的首片数 |
其中 InferCodeParams.prompt 默认值为 "[speed_5]"。
3. 控制标记的含义
- 句级:
oral_(0-9)、laugh_(0-2)、break_(0-7)三个系列控制口语感、笑声、停顿强度,写入params_refine_text.prompt后,由 refine 阶段自动在文本中生成相应特殊 token; - 词级:直接在输入文本中嵌入
[uv_break](微停顿)、[laugh](笑)、[lbreak](长停顿)等标记,并配合skip_refine_text=True跳过自动精炼,实现逐词精确控制。
俄语文档的词级示例:
text = 'What is your favorite english food?[uv_break]your favorite english food?[laugh][lbreak]'
wav = chat.infer(text, skip_refine_text=True, params_refine_text=params_refine_text, params_infer_code=params_infer_code)
torchaudio.save("output2.wav", torch.from_numpy(wavs[0]), 24000)
(原文此处保存变量沿用 wavs[0],实际应保存上一步 infer 的返回值,英文 README 已修正。)
词级控制能生效的原因是分词器将其识别为独立特殊 token:ChatTTS/model/tokenizer.py 中基于 BertTokenizerFast 加载 asset/tokenizer,并预取 [spk_emb]、[break_0]、[Ebreak] 等关键 token 的 id;配置中音频词表大小 num_audio_tokens=626、文本词表 num_text_tokens=21178、量化层数 num_vq=4,即每帧语音由 4 层 VQ 码本联合表示。
六、示例:自我介绍(俄语文本演示)
俄语文档附带的完整示例,展示混合标记文本 + 句级 prompt 的用法:
inputs_ru = """
ChatTTS - это модель преобразования текста в речь, разработанная для диалоговых приложений.
[uv_break]Она поддерживает смешанный языковой ввод [uv_break]и предлагает возможности множественных говорящих
с точным контролем над просодическими элементами [laugh]как [uv_break]смех[laugh], [uv_break]паузы, [uv_break]и интонацию.
[uv_break]Она обеспечивает натуральную и выразительную речь,[uv_break]поэтому, пожалуйста,
[uv_break] используйте проект ответственно и на свой страх и риск.[uv_break]
""".replace('\n', '') # Русский язык все еще находится в экспериментальной стадии.
params_refine_text = {
'prompt': '[oral_2][laugh_0][break_4]'
}
audio_array_ru = chat.infer(inputs_ru, params_refine_text=params_refine_text)
torchaudio.save("output3.wav", torch.from_numpy(audio_array_ru[0]), 24000)
文档注明俄语仍处实验阶段(官方明确支持英语与中文),示例附男女两个说话人的演示音频。
七、源码视角:一次 infer() 的完整链路
结合 ChatTTS/core.py 的 infer() / _infer() 实现,文档中各控制项对应的内部流程如下:
- 文本规范化:
Normalizer(ChatTTS/norm.py)自动检测中/英文(zh走全角化 + 文本正则化,en走注册的英文正则器),将无效字符替换为标点,并按homophones_map.json做同音字替换(该映射表由 18 万级误读样本构建),保证特殊标记[...]在正则化前后保持原样; - 按句拆分:输入含
\n时按行拆,否则按(?<=。)|(?<=\.\s)正则拆句,split_text=True时每max_split_batch(默认 4)句为一批推理; - refine text 阶段:
_refine_text以[Sbreak]{文本}[Pbreak]{prompt}为模板编码,GPT 以infer_text=True生成精炼文本,再过滤掉[break_0]之后的音频 token,得到带控制标记的文本; - infer code 阶段:
_infer_code中说话人模块将文本包装为[Stts][spk_emb]{txt_smp}{text}[Ptts](无spk_emb时为[empty_spk]),Speaker.apply()用归一化后的说话人向量替换[spk_emb]位置的嵌入;GPT(768 维、20 层、12 头,见 ChatTTS/config/config.py)逐层生成 4 路 VQ 音频 token; - 波形重建:
_decode_to_wavs先用 DVAE Decoder(或use_decoder=False时直接用 DVAE)得到 100 维 mel 谱,再经 Vocos(24 kHz、n_fft=1024、hop=256 的 ISTFTHead)合成波形;非流式模式下还会按1e-5阈值裁掉首尾静音; - 流式模式:
stream=True时infer返回生成器,按stream_speed(12000 采样点/片,约 0.5 秒)切块 yield,并跳过前pass_first_n_batches片以降低首包延迟;chat.interrupt()可通过GPT.Context中断生成。
命令行示例 examples/cmd/run.py 展示了上述接口的典型组装:--spk 传入说话人字符串、--stream 打开流式、--source local/huggingface/custom 切换模型来源,并会尝试注册 nemo_text_processing / WeTextProcessing 正则化器,最终把结果存为 output_audio_n.mp3:
python examples/cmd/run.py "Your text 1." "Your text 2."
八、常见问题(FAQ)
俄语文档保留了三条 FAQ,与源码行为相符:
- 需要多少显存?推理速度如何? 生成 30 秒音频至少需要 4 GB 显存;在 RTX 4090 上约 7 个语义 token/秒,实时率 RTF ≈ 0.3;
- 模型稳定性不够,出现多说话人串音或音质差? 这是自回归模型(bark、valle 同类)的通病,难以完全避免,建议多采样几次挑选结果——这正对应
manual_seed与spk_emb的调参空间; - 除笑声外还能控制什么?能否控制其他情绪? 当前发布模型中,token 级控制单元只有
[laugh]、[uv_break]、[lbreak];更多情绪控制模型“未来可能开源”。
九、免责声明与使用边界
俄语文档的免责条款与主 README 一致,使用与分发时需注意:
- 仓库仅限学术用途,用于教育与研究,不得用于商业或违法目的;数据来自公开渠道,作者不主张数据的所有权或版权;
- 为限制滥用,官方在 40,000 小时模型训练时加入了少量高频噪声,并尽量以 MP3 形式压缩音质,防止被恶意用于犯罪;同时内部训练了检测模型,计划未来开源。
因此代码侧为 AGPLv3+ 许可、模型权重为 CC BY-NC 4.0 许可,商用需另行评估。
十、发展路线(Roadmap)
俄语文档中的路线图(“40 千小时基础模型与 spk_stats 开源”已完成,其余未完成),对照主 README 可补充当前进展:
- [x] 开源 40,000 小时基础模型与 spk_stats 文件;
- [x](主 README 补充)流式音频生成、DVAE 编码器与零样本推理代码;
- [ ] 不经过文本精炼的纯音频流式生成;
- [ ] 开源带多情绪控制能力的 40k 小时版本;
- [ ] ChatTTS.cpp(欢迎 PR 或新仓库)。
十一、致谢
俄语文档致谢部分(名称与主 README 一致):bark、XTTSv2 与 valle 展示了自回归风格 TTS 系统的出色效果;fish-speech 揭示了 GVQ 作为音频 tokenizer 建模 LLM 的能力;vocos 被用作预训练声码器(源码中 from vocos import Vocos 可直接印证);特别感谢 wlu-audio lab 在早期算法实验中的工作。
小结:ChatTTS 的使用门槛很低(Chat() → load() → infer() 三步),但其价值集中在可控性上——spk_emb 音色字符串、RefineTextParams 句级韵律 prompt、InferCodeParams 解码参数以及 [uv_break]/[laugh]/[lbreak] 词级标记构成了完整的控制面。理解 ChatTTS/core.py 中 normalize → refine text → infer code → decode 的四段流水线后,上述每个控制项的作用位置都一目了然,便于在实际项目中做针对性调优。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00