news 2026/9/6 18:30:06

ChatTTS 对话式 TTS 模型实战:从安装部署到细粒度韵律控制的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ChatTTS 对话式 TTS 模型实战:从安装部署到细粒度韵律控制的完整指南

ChatTTS 对话式 TTS 模型实战:从安装部署到细粒度韵律控制的完整指南

【免费下载链接】ChatTTSA generative speech model for daily dialogue.项目地址: https://gitcode.com/GitHub_Trending/ch/ChatTTS

本文基于 ChatTTS 仓库的官方韩语文档(docs/kr/README.md)并结合仓库源码,系统讲解这个面向日常对话场景的生成式语音模型的定位、能力边界、完整的安装部署流程,以及最核心的多说话人采样、RefineTextParams/InferCodeParams参数控制、句级与词级韵律标记([laugh][uv_break][lbreak]等)和流式音频生成的实战用法。读完本文,你可以独立完成从克隆仓库到产出可控韵律音频的全链路操作,并理解每个控制参数在源码中的实际作用。

项目定位:为对话任务设计的 TTS 模型

ChatTTS 是一个为对话类任务(例如 LLM 助手语音交互)而设计的文本转语音(TTS)模型,其设计目标是输出自然、富表现力的对话语音。根据官方文档,该项目当前:

  • 支持语言:英语、中文(持续扩展中,英文仍处于实验阶段);
  • 核心特点
    1. 对话式 TTS:针对对话场景优化,支持多说话人,可用于交互式对话;
    2. 细粒度控制:可预测并控制笑声、停顿、插入语等韵律细节;
    3. 增强韵律:在韵律表现上优于多数开源 TTS 模型,并提供预训练权重支持二次研究。

数据与模型规模方面,官方说明如下(适用前提:当前仓库所公开的权重):

  • 主模型使用100,000+ 小时的中英文音频数据训练;
  • 公开下载的是40,000 小时预训练模型,且未应用 SFT(监督微调),因此稳定性与最终效果存在差距;
  • 公开模型仅限学术用途

路线图(截至文档版本):40,000 小时模型与 spk_stats 文件已开源、流式音频生成已实现、DVAE 编码器与零样本推理代码已开源;多情感控制与 ChatTTS.cpp(C++ 推理后端)仍待完成。

许可证与反滥用机制

使用前必须了解两个层面的限制,这在源码与文档中均被强调:

对象许可证说明
代码AGPLv3+见 LICENSE
模型权重CC BY-NC 4.0仅教育与研究用途,禁止商业或非法使用

面免责/反滥用设计:为防止技术被恶意滥用,官方在 40,000 小时模型训练末期加入了少量高频率噪声,并将音频质量尽量压缩后以MP3 格式提供;团队同时训练了内部检测模型,计划后续开源。理解这一点有助于解释为何输出音质带有一定的"压缩感"。

环境准备与依赖安装

1. 克隆仓库

git clone https://gitcode.com/GitHub_Trending/ch/ChatTTS cd ChatTTS

2. 安装依赖

方式一:直接安装

pip install --upgrade -r requirements.txt

方式二:Conda 环境(推荐隔离)

conda create -n chattts conda activate chattts pip install -r requirements.txt

对照 requirements.txt 可以看到核心依赖包括:numpy<3.0.0numba(规范化器中 JIT 加速)、torch>=2.1.0torchaudiotransformers>=4.41.1(BertTokenizerFast)、vocos(声码器)、gradio(WebUI)、pybase16384(说话人编码)、pydub/av(音频处理)等。其中pynini==2.1.5WeTextProcessingnemo_text_processing仅在Linux 平台sys_platform == 'linux')引入,它们对应命令行示例中的中英文文本规范化器(见后文 examples/cmd/run.py 的load_normalizer)。

可选:vLLM(仅 Linux)

pip install safetensors vllm==0.2.7 torchaudio

vLLM 路径对应源码中Chat._load(..., use_vllm=True)分支:当gpt.is_vllm为真时,推理会走 ChatTTS/model/velocity 目录下的引擎(llm_engine.pymodel_runner.pysampler.py等,结构上仿照 vLLM 的调度器/块管理器实现),而 ChatTTS/core.py 中_infer_code对 vLLM 与非 vLLM 有两条独立的生成路径。

不推荐的两个选项(官方文档明确给出警告,原样保留结论):

  • TransformerEngine(NVIDIA GPU,仅 Linux):不要安装!适配工作尚处于开发中,目前无法正常工作,仅限开发目的。相关 issue 为 #672 与 #676。
  • FlashAttention-2(主要面向 NVIDIA GPU):不要安装!据上游 transformers 仓库 issue #26990,FlashAttention-2 在当前场景下会降低生成速度

这两个警告与源码相互印证:ChatTTS/core.py 的load()暴露了use_flash_attn参数,而 ChatTTS/model/cuda/patch.py 与te_llama.py正是 TransformerEngine/FlashAttention 的适配层——从源码结构看,这部分仍是实验性代码路径。

三种安装方式

# 1. 从 PyPI 安装稳定版 pip install ChatTTS # 2. 从 GitHub 源安装最新版 pip install git+https://gitcode.com/GitHub_Trending/ch/ChatTTS # 3. 本地目录开发模式安装 pip install -e .

开发模式安装的打包逻辑见 setup.py。

快速开始:WebUI 与命令行

以下命令必须在项目根目录执行。

运行 WebUI(基于 Gradio)

python examples/web/webui.py

命令行推理

python examples/cmd/run.py "Your text 1." "Your text 2."

生成的音频会保存为当前目录下的./output_audio_n.mp3(n 为序号)。

结合 examples/cmd/run.py 的argparse定义,该脚本支持完整参数如下:

参数类型/默认值作用
texts位置参数,argparse.REMAINDER待合成的文本列表
--spkOptional[str],默认None指定说话人编码字符串;缺省时调用chat.sample_random_speaker()随机采样
--stream布尔开关启用流式模式(逐块输出并分别保存,再拼接总文件)
--sourcelocal/huggingface/custom,默认local模型来源
--custom_path默认空自定义模型资产目录(配合--source custom

从 examples/cmd/run.py 可以看到,命令行推理本质上是chat.infer(texts, stream, params_infer_code=ChatTTS.Chat.InferCodeParams(spk_emb=spk))的一层封装:先加载模型,采样/取用说话人,再按InferCodeParams(spk_emb=spk)固定音色进行合成,音频经pcm_arr_to_mp3_view转 MP3 落盘。

Python API 基础用法与加载参数

最小可用示例

import ChatTTS import torch import torchaudio chat = ChatTTS.Chat() chat.load(compile=False) # 性能导向可设为 True texts = ["PUT YOUR 1st TEXT HERE", "PUT YOUR 2nd TEXT HERE"] wavs = chat.infer(texts) for i in range(len(wavs)): """ 视 torchaudio 版本差异,第一行或第二行可能生效。 """ try: torchaudio.save(f"basic_output{i}.wav", torch.from_numpy(wavs[i]).unsqueeze(0), 24000) except: torchaudio.save(f"basic_output{i}.wav", torch.from_numpy(wavs[i]), 24000)

采样率24000 Hz不是随意写死的:在 ChatTTS/config/config.py 的FeatureExtractorInitArgs中,Vocos 特征提取器即配置为sample_rate=24000, n_fft=1024, hop_length=256, n_mels=100,声码器输出即该采样率的波形。

load()的完整参数(源码级)

文档示例只展示了chat.load(compile=False),而 ChatTTS/core.py 中load()的完整签名还包括多个实战有用选项:

chat.load( source="local", # "huggingface" / "local" / "custom" force_redownload=False, # 强制重新下载模型资产 compile=False, # torch.compile 加速,仅对 cuda 设备生效 custom_path=None, # source="custom" 时的本地资产目录 device=None, # 指定设备,默认自动选择 coef=None, # DVAE 的 codec 系数字符串(一般不填) use_flash_attn=False, # 官方警告:目前不建议开启 use_vllm=False, # 需要安装 vllm,走 velocity 推理引擎 experimental=False, enable_cache=True, )

几个值得注意的实现细节(均以 ChatTTS/core.py 为准):

  • 模型资产与校验download_modelssource分为三条路径——local(当前工作目录,按 ChatTTS/res/sha256_map.json 逐个校验 sha256,缺失才下载)、huggingfacesnapshot_download拉取2Noise/ChatTTS,允许*.yaml/*.json/*.safetensors)、custom(仅校验不下载)。资产路径模板定义在 ChatTTS/config/config.py 的Pathasset/Vocos.safetensorsasset/DVAE.safetensorsasset/gptasset/Decoder.safetensorsasset/tokenizerasset/Embed.safetensors
  • compile的实际生效条件gpt.prepare(compile=compile and "cuda" in str(device)),即只有 CUDA 设备下compile=True才真正编译;
  • 设备回退device_gpt在 MPS 设备下强制回退 CPU,Vocos 在 mps/npu 下也回退 CPU 执行,这是 Apple Silicon 用户能跑通的原因之一;
  • unload():提供显式卸载接口,删除vocos/gpt/decoder/dvae/tokenizer/embed六个模块后重置内部状态。

infer()的完整参数(源码级)

ChatTTS/core.py 中infer()的签名比文档示例丰富得多,各参数默认值如下:

chat.infer( text, stream=False, # 流式生成,返回 generator lang=None, # "zh" / "en",None 时自动检测 skip_refine_text=False, # 跳过"文本润色"阶段(词级控制必须开启) refine_text_only=False, # 只输出润色后的文本 use_decoder=True, # True 用独立 Decoder,False 用 DVAE 解码 do_text_normalization=True,# 文本规范化(数字、标点等) do_homophone_replacement=True, # 同音字纠错替换 split_text=True, # 按 。 或 .(后跟空白)切分长句 max_split_batch=4, # 每批最多句数 params_refine_text=RefineTextParams(), params_infer_code=InferCodeParams(), )

其中split_text的切分逻辑在源码中是re.split(r"(?<=。)|(?<=\.\s)", text)(见 ChatTTS/core.py),即按中文句号或英文"句点+空格"做 lookbehind 切分;多句输入时,系统会先合成第一句,再用sample_audio_speaker从第一句波形中编码出spk_smp(说话人提示)供后续句子复用,从而保证长文本内音色一致——这正是 ChatTTS/core.py 中spk_smp is None分支的作用。

文本规范化:为什么"错字"会被自动纠正

do_homophone_replacement背后的实现是 ChatTTS/norm.py 的Normalizer类,其处理流水线为:

  1. 语言检测:统计中文字符与英文单词数量,取多者(_detect_language);
  2. 按语言规范化[标签]会被_split_tags单独抽出保护起来,避免被规范化器破坏,再拼回(_combine_tags);
  3. 无效字符清理reject_pattern仅保留中日韩汉字、英文字母与,。、,. 空格,其余字符被替换/剔除;
  4. 半角转全角(中文场景)与标点统一(:→,!→。等映射表);
  5. 同音字纠错:基于 ChatTTS/res/homophones_map.json 的映射表,用 numba JIT 的_fast_replace以 utf-16 编码快速逐字替换。该映射表据源码注释由 1200 万词条语料清洗后约 180 万条、结合约 18 万误读词统计构建。

这意味着送入模型前的文本会先经过一轮"发音安全"处理,特殊韵律标签([laugh]等)在此过程中被显式保护,这是后文词级控制能生效的前提。

高级用法:说话人采样与两级推理参数

1. 采样说话人

################################### # 从高斯分布采样一个说话人。 rand_spk = chat.sample_random_speaker() print(rand_spk) # 保存该字符串,用于日后恢复同一音色

rand_spk是一个自包含的字符串编码,可以随时打印、保存、复用以恢复音色。其实现链路在 ChatTTS/model/speaker.py:

  • 配置类GPTspk_emb_dim = 192(见 ChatTTS/config/config.py),即说话人向量是 192 维;
  • _sample_random执行randn(dim) * std + mean,均值/标准差来自Config.spk_stat中用 base16384 编码的预训练统计量,因此采样结果落在训练分布内;
  • _encode将 float16 向量经LZMA 极限压缩 + base16384 编码变成字符串,所以打印出来是一大串"乱码"字符——这不是哈希,而是可逆的压缩表示;
  • 合成时,Speaker.apply(ChatTTS/model/speaker.py)会反解字符串、做 L2 归一化,然后把所有[spk_emb]位置的嵌入直接替换为该说话人向量(torch.where条件替换),从而在解码前就锁定音色。

此外还有一个反向操作:chat.sample_audio_speaker(wav)可从一段波形(经 DVAE 编码)反推说话人编码,用于零样本复刻参考音频的音色。

2. 句级控制:RefineTextParamsInferCodeParams

ChatTTS 的推理是两阶段的:第一阶段_refine_text让 GPT 把输入文本"润色"成带韵律标记的文本(对应RefineTextParams),第二阶段_infer_code再生成音频 token(对应InferCodeParams)。文档示例如下:

################################### # 句级手动控制。 # 使用 oral_(0-9), laugh_(0-2), break_(0-7) # 在文本中生成特殊韵律 token。 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会被 ChatTTS/model/speaker.py 的decorate_text_prompts包装成[Sbreak]{文本}[Pbreak]{prompt}送入润色阶段,引导模型在输出中插入对应强度(0~9 / 0~2 / 0~7)的口语化程度、笑声、停顿标记。润色后的 token 会先被过滤到break_0_ids以下再解码为文本(ChatTTS/core.py),这些标记随文本进入第二阶段。

两个参数类的完整默认值(摘自 ChatTTS/core.py 的数据类定义,ChatTTS/core.py):

RefineTextParams(文本润色阶段)

字段默认值说明
prompt""韵律引导,如'[oral_2][laugh_0][break_6]'
top_P0.7top-p 采样
top_K20top-k 采样
temperature0.7温度
repetition_penalty1.0重复惩罚
max_new_token384最大新 token 数
min_new_token0最小新 token 数
show_tqdmTrue进度条
ensure_non_emptyTrue保证输出非空(空输出重采样)
manual_seedNone手动随机种子

InferCodeParams(音频 token 生成阶段,继承自上表)

字段默认值说明
prompt"[speed_5]"默认引导语速等级
spk_embNone说话人编码字符串(如sample_random_speaker()返回值)
spk_smpNone由参考音频编码的说话人 prompt(多句自动填充)
txt_smpNone参考文本 prompt
temperature0.3注意比润色阶段低,音频解码更保守
repetition_penalty1.05略高于 1,抑制 token 循环
max_new_token2048每句音频 token 上限
stream_batch24流式模式下每批 token 数
stream_speed12000流式切片步长(采样点数)
pass_first_n_batches2流式模式丢弃前 N 个 batch(预热)

temperature在代码层面还支持传列表(按 4 个 VQ 层级分别设置,见 ChatTTS/core.py),num_vq=4来自配置中 4 层向量量化(levels=(5,5,5,5),音频词表 626 个 token、文本词表 21178 个,见 ChatTTS/config/config.py 的GPT/Embed定义)。

3. 词级控制:skip_refine_text与文本内嵌标签

句级控制是"引导模型去加标记",而词级控制是把韵律标签直接写进文本,并跳过润色阶段让模型严格照读:

################################### # 词级手动控制。 text = 'What is [uv_break]your favorite english food?[laugh][lbreak]' wavs = chat.infer(text, skip_refine_text=True, params_refine_text=params_refine_text, params_infer_code=params_infer_code) try: torchaudio.save("word_level_output.wav", torch.from_numpy(wavs[0]).unsqueeze(0), 24000) except: torchaudio.save("word_level_output.wav", torch.from_numpy(wavs[0]), 24000)

文档 FAQ 中明确:当前公开模型可控制的 token 为[laugh][uv_break][lbreak](词级),以及润色阶段的oral_(0-9)laugh_(0-2)break_(0-7)(句级);更多情感控制留待后续版本开源。

skip_refine_text=True的必要性可以从 ChatTTS/core.py 印证:若不跳过,_refine_text会重写文本,你手工放置的标签位置就无法保证;跳过之后,文本经规范化(标签被_split_tags保护)直接进入_infer_code。另外,ChatTTS/model/speaker.py 的decorate_code_prompts会在送入编码前把文本中的[Stts][spk_emb][empty_spk]占位符剥离,避免与内部特殊 token 冲突(对应上游 issue #459 的修复)。

4. 官方示例:带韵律标记的自我介绍

文档附带了一个英文示例(英文输出仍为实验性),完整保留:

inputs_en = """ chat T T S is a text to speech model designed for dialogue applications. [uv_break]it supports mixed language input [uv_break]and offers multi speaker capabilities with precise control over prosodic elements like [uv_break]laughter[uv_break][laugh], [uv_break]pauses, [uv_break]and intonation. [uv_break]it delivers natural and expressive speech,[uv_break]so please [uv_break] use the project responsibly at your own risk.[uv_break] """.replace('\n', '') params_refine_text = ChatTTS.Chat.RefineTextParams( prompt='[oral_2][laugh_0][break_4]', ) audio_array_en = chat.infer(inputs_en, params_refine_text=params_refine_text) torchaudio.save("self_introduction_output.wav", torch.from_numpy(audio_array_en[0]), 24000)

流式音频生成

文档将"流式音频生成"列为已完成路线项,对应infer(stream=True)。从源码看其机制(ChatTTS/core.py):

  • 生成按stream_batch=24个 token 一批推进,每个 batch 完成即解码出一段波形;
  • pass_first_n_batches=2个 batch 被直接丢弃(continue),用于跳过不稳定预热段;
  • 之后按stream_speed=12000个采样点的步长切片yield,最后一段按能量阈值(1e-5)裁掉静音列。

仓库提供了完整的流式消费者示例 examples/cmd/stream.py:其ChatStreamer类负责把生成器输出缓冲、按 8000 点基础块累积,转为PCM16 字节流float_to_int16+<i2小端),并以 24000 Hz 单声道 16 位通过 PyAudio 播放(play(streamchat, wait=5),先预缓冲 5 秒再开播,适配 CPU 等慢速设备)。命令行版本则可用:

python examples/cmd/run.py --stream "第一段文本" "第二段文本"

流式输出会分别保存每个块文件,再拼接出完整output_audio_n.mp3

常见问题(FAQ)

Q1:需要多少显存?推理速度如何?

官方文档给出的数字:生成约 30 秒音频片段最少需要4GB 显存;在 4090 GPU 上约每秒生成 7 个语义 token 对应的音频,RTF 约 0.3。这些是文档口径的参考值,实际受use_vllmcompile、批次与序列长度影响。

Q2:模型偶发不稳定,多说话人场景下音色/音质波动?

官方解释:这是自回归模型(bark、valle 等)的固有难题,当前最佳实践是多次采样、择优保留。这也解释了infer默认ensure_non_empty=True(空输出自动重试)与manual_seed参数的存在。

Q3:除了笑声还能控制其他情感吗?

当前公开模型可控制的 token 仅[laugh][uv_break][lbreak](以及句级的oral_/laugh_/break_强度档位);更多情感控制计划在后续版本中开源(见路线图中的"多情感控制功能"未勾选项)。

延伸阅读与仓库内相关路径

  • 韩语原文档:docs/kr/README.md(并排提供 英文、简体中文、日文、俄文、西班牙文、法文 版本;官方提示韩语文档可能滞后于英文主文档,以英文版为最新基准)
  • 核心 API 与两阶段推理:ChatTTS/core.py
  • 模型结构与词表配置:ChatTTS/config/config.py
  • 说话人采样/编码:ChatTTS/model/speaker.py
  • 文本规范化与同音字纠错:ChatTTS/norm.py、ChatTTS/res/homophones_map.json
  • 分词器(BertTokenizerFast[spk_emb]/[break_0]/[Ebreak]特殊 token):ChatTTS/model/tokenizer.py
  • vLLM 推理引擎(velocity 目录):ChatTTS/model/velocity
  • 示例:WebUI examples/web/webui.py、命令行 examples/cmd/run.py、流式 examples/cmd/stream.py、ONNX 导出 examples/onnx/exporter.py
  • 依赖清单:requirements.txt、打包:setup.py、协议:LICENSE

使用提醒:公开权重仅限学术与研究方向,音频输出自带训练期注入的高频噪声与 MP3 压缩特性,属于官方反滥用设计的一部分;集成到自己的 LLM 助手前请先在本地充分验证稳定性,并遵守 CC BY-NC 4.0 对模型权重的使用限制。

【免费下载链接】ChatTTSA generative speech model for daily dialogue.项目地址: https://gitcode.com/GitHub_Trending/ch/ChatTTS

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

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

概率论与数理统计学习指南:川大数学学院PDF讲义深度解析与实战应用

简介&#xff1a;由四川大学数学学院编写的《概率论与数理统计》PDF&#xff0c;面向理工科非数学专业本科生及考研学生&#xff0c;系统覆盖随机事件与概率、离散型与连续型随机变量、数字特征、大数定律、数理统计基础、参数估计和假设检验等核心模块&#xff0c;既能作为课程…

作者头像 李华
网站建设 2026/9/6 18:21:44

FreeTube 护眼设置完整指南:5 个真实可用的步骤打造舒适夜览界面

FreeTube 护眼设置完整指南&#xff1a;5 个真实可用的步骤打造舒适夜览界面 【免费下载链接】FreeTube An Open Source YouTube app for privacy 项目地址: https://gitcode.com/GitHub_Trending/fr/FreeTube 深夜追番、关灯刷视频&#xff0c;刺眼的纯白背景十分钟就能…

作者头像 李华
网站建设 2026/9/6 18:21:32

铝型材加工工厂课程设计完整指南:工艺流程与设备选型决策

简介&#xff1a;《铝型材加工工厂课程设计说明书》是一份面向材料成型、机械及建筑工程相关专业学生的完整设计文档&#xff0c;聚焦年产量五千吨以上铝型材挤压车间的规划难题&#xff0c;涵盖材料选型、模具设计、挤压机选择、能耗与设备投资等核心环节。文档以6063/LD31铝合…

作者头像 李华