Communitygithub.com

Local TTS

在本地 GPU(或 CPU)上生成逼真的语音,无需 API 费用——适用于解说视频的画外音、旁白、文字朗读、音频片段,还附带根据已知行时间匹配的 .srt 字幕。

Local TTS 是什么?

该技能提供了一个本地化的文本转语音(TTS)引擎,基础模型是 Qwen3-TTS 1.7B 8-bit GGUF 模型,通过 qwentts.cpp 在用户自己的硬件上运行。它无需云 API 调用或付费,就能生成高质量的语音输出,默认“aiden”音色在盲听测试中胜过了 Kokoro、Chatterbox 等模型。核心功能包括批量生成 WAV 文件、通过 `--srt` 选项自动生成 .srt 字幕、多种声音风格指令,以及一个检查机制,确保 GPU 和模型路径配置正确。该技能还整合了一套系统化的模型评估流程,通过语音指标和人工试听来对比候选模型,因此非常适合需要可靠本地 TTS 的开发者,可用于 Remotion 或 HyperFrames 等视频项目,也适合负责评估和更新本地语音模型的人。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Ayushmaniar/claude-explainer-skills/tree/HEAD/plugins/explainer-skills/skills/local-tts

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Local TTS 是做什么的?

默认语音:Qwen3-TTS 1.7B CustomVoice,发音人 aiden,8-bit GGUF (Q8_0),由 qwentts.cpp(C++/ggml,MIT 协议)运行,并带有以下风格指令:

温暖、清晰且充满好奇,就像一位友好的科技解说视频旁白。放松、平稳的语速。

它在与 Kokoro、Chatterbox、PyTorch Qwen3-TTS、VoxCPM2 和 Phonon 的盲听测试中胜出(详情见 references/benchmarks.md)。在 8 GB RTX 4070 笔记本 GPU 上,包含模型加载在内,运行速度约为实时速度的 4 倍:一段 18 分钟的旁白约需 4.5 分钟。

设置(每台机器只需一次)

首先运行 python -I <skill>/scripts/say.py --check。如果显示 OK,请跳过此部分。 否则,请自行设置引擎,或请用户帮忙。大约需要 10-20 分钟和约 2.5 GB 磁盘空间。

  1. 构建 qwentts.cpp。 没有预编译的 Windows 二进制文件,因此需要从源码构建:
    git clone --recurse-submodules https://github.com/ServeurpersoCom/qwentts.cpp ~/tools/qwentts.cpp
    cd ~/tools/qwentts.cpp
    ./buildcuda.sh       # NVIDIA (Linux);AMD/Intel 使用 ./buildvulkan.sh;仅 CPU 使用 ./buildcpu.sh(例如 macOS)
    
    在 Windows 上,安装包含 C++ 工作负载的 VS 2022(或更新版本)构建工具、CMake、Ninja 和 CUDA Toolkit,然后在仓库中运行 buildcuda.cmd。如果 vcvars64.bat 在其他位置,请编辑该脚本顶部的路径。要仅针对一个 GPU,请在 cmake 命令行中添加 -DCMAKE_CUDA_ARCHITECTURES=89 (RTX 40xx;86 = RTX 30xx,120 = RTX 50xx)。
  2. 下载权重(约 2 GB)来自 Hugging Face Serveurperso/Qwen3-TTS-GGUF:
    pip install -U huggingface_hub
    hf download Serveurperso/Qwen3-TTS-GGUF qwen-talker-1.7b-customvoice-Q8_0.gguf qwen-tokenizer-12hz-Q8_0.gguf --local-dir ~/tools/qwen-gguf
    
  3. 让 say.py 指向它们:如果使用了其他文件夹,请设置 QWEN_TTS_HOME(检出目录)、 QWEN_TTS_EXE(二进制文件)或 QWEN_TTS_MODELS(.gguf 文件夹)。在 Windows 上,say.py 会 自动将 %CUDA_PATH%\bin\x64 添加到 PATH 中(使用 CUDA_BIN 覆盖)。
  4. 再次运行 say.py --check,然后输入一行测试文本。

硬件:8 GB VRAM 对于 Q8_0 来说绰绰有余(实际使用约 3 GB)。如果没有 GPU,CPU 构建版本的运行速度大约只有 GPU 的四分之一。GGML_BACKEND=CPU 强制 GPU 构建版本使用 CPU 运行。

生成之前

  1. 有其他程序正在使用 GPU 吗? 如果正在运行游戏或其他 GPU 密集型应用,生成速度会变慢约 4 倍,并且会导致该应用卡顿。在开始长时间任务之前,请先询问用户。如果用户提到了这类应用,请设置 TTS_BUSY_APPS=app1,app2,这样当有应用正在运行时,say.py 会发出警告。
  2. 需要检查是否有更新的模型吗? 请参见下面的“持续寻找更好的模型”。如果距离上次检查已超过约 6 周,并且当前任务是真正的旁白(而非单行测试),请先快速扫描一次。
  3. 文本听起来像人说的吗? 语音朗读 AI 生成的文本时,每次的语气都一样,因此这种模式会比在纸面上更明显。对于超过几行的任何旁白,请阅读 whiteboard-explainer 技能(同一插件,位于 references/ 目录下)中的 natural-narration.md,并运行其 scripts/aispeak_scan.py,该脚本接受 script.py 或纯文本文件。

生成

该脚本仅使用标准库,因此任何 Python 3.10+ 版本均可使用。<skill> 是此技能所在的文件夹。

python -I <skill>/scripts/say.py "第一行。" "第二行。" -o out.wav       # 单个 WAV 文件,0.35 秒间隔
python -I <skill>/scripts/say.py --file lines.txt -o clips/                    # 生成 000.wav, 001.wav, ...

选项:

标志作用
--speakeraiden(默认);ryan 是另一个原生英语语音
--instruct风格文本,例如“兴奋,快节奏”或“冷静,严肃”
--seed N生成可重复的结果
--gap S合并文件时各行之间的静音秒数
--srt F同时写入与合并的 WAV 文件时间同步的字幕(参见字幕部分)
--quantQ8_0(默认,最佳)或 Q4_K_M(更小,音质稍差;请先下载)
--check报告找到的引擎、模型和 CUDA 文件夹

工作原理:

  • 每行文本都在一个进程中处理,因此模型只加载一次(3–8 秒)。请批量传递文本行,而非逐行调用。
  • 输出为 24 kHz 单声道 16 位 WAV。

每次生成的音频都是随机的,因此每次运行都可能不同:

  • 保留您喜欢的音频片段。基于文本和设置,为每行文本缓存结果。
  • 如果某行音频的长度与每字符约 0.07 秒的预期相差甚远,请重新生成。这意味着模型可能遗漏或编造了单词。

对于视频旁白,还需要:

  • 将每个音频片段的静音修剪到约 50 毫秒的填充,然后使用您自己的间隔在时间线上放置各行文本。
  • 对最终音轨进行响度归一化:ffmpeg -af loudnorm=I=-16:TP=-1.5:LRA=11。

字幕 (.srt):在每个旁白视频中提供

您已经知道每行音频的开始和结束时间,因此无需转录。直接根据这些时间信息构建字幕即可。

  • 配合 say.py: 添加 --srt narration.srt(需要指定 .wav 的 -o 输出文件)。字幕将与合并后的音轨完全匹配。
  • 在您自己的流程中: 调用 scripts/srt.py,to_srt([(start_s, end_s, text), ...], display=[...]),传入视频时间线上每行口语的开始/结束时间。或者使用 CLI:python srt.py timings.tsv -o video.srt。
  • 修正语音拼写。 旁白文本通常是为语音朗读而编写的,例如“D I L”、姓名音译、”runner dot HTML”、数字转为文字。使用 display / --display display.tsv(口语书面语)将它们映射回书面形式。从屏幕上显示的内容获取书面形式,并对数字使用数字表示法(”$232“,”83%”)。
  • 检查结果。 搜索其中残留的大写字母加空格模式([A-Z] [A-Z])和“ dot ”。
  • 模块应用的规则:
    • 每个字幕最多 2 行,每行 42 个字符
    • 在句子处换行,然后是子句,最后是单词
    • 合并过短的句子,以避免一闪而过
    • 时间按长度比例分配
  • 将字幕文件命名为与视频文件相同(Video Name.srt 放在 Video Name.mp4 旁边),以便播放器自动加载。在 VLC 中,--sub-file= 可强制指定文件。

whiteboard-explainer 技能的 template/narration/build_vo.py 是一个完整的工作流示例:包含逐行缓存、重新生成、静音修剪、停顿塑造、词对齐、提示表以及嘴型同步包络。

注意事项

  • CUDA DLL 必须在 PATH 环境变量中(Windows)。 CUDA 13 将它们放在 ...\CUDA\v13.x\bin\x64 中。如果 PATH 中没有这个文件夹,qwen-tts.exe 会静默退出,不产生任何输出。say.py 会自动为您添加该路径。
  • --stream-by-line -o - 写入流式 WAV 头(大小为 0x7fffffff),每行一个。在 RIFF....WAVEfmt 处分割,并丢弃每个 44 字节的头信息。不要相信 size 字段。
  • Aiden 会误读单个字母和奇怪的词元。 通过一次无提示的 Whisper 审核发现:
    • “h star” 变成了 “a hap” 或 “our star”,“y t” 变成了 “VT”,“y” 变成了 “we”,“arXiv” 变成了 “ArcSireFolk”。
    • 以下写法可行:大写 “H star” / “under H”,“why tee” / “why tilde”,“archive”,以及 “SMILES check”。
    • “aitch” 的表现不稳定。一个名字单独出现时可能没问题,但放在句子中间就可能被扭曲:请在整个句子中测试。
    • 句首的 K 可能会丢失(”Kwenputer” → “When Pooter”):可以以 “And” 或 “So” 开头这样的句子。
    • 审核方法:将每个音频片段不带脚本文本作为初始提示进行转录,然后与脚本进行对比。使用提示的 Whisper 会“听到”预期的单词并隐藏错误。工具:whiteboard-explainer/template/narration/audit_vo.py 和 tts_try.py。
  • 冒号处会停顿。 Qwen 在冒号处会停顿 0.6-0.8 秒,有时在短语中间也会停顿。在旁白中,通过其前面的标点符号来限制每次静音(模板 build_vo.py 中的 shape()),并避免使用冒号分隔的片段行(”First: ...”)。
  • CPU 后备方案:Kokoro 82M(kokoro-onnx)音质平淡但 CPU 运行速度快,适合在 GPU 繁忙时用于草稿。

持续寻找更好的模型

本地 TTS 发展很快,当前的选择终将被超越。请将其视为当前冠军,而非最终答案。在大型旁白任务之前,或上次检查(如下)超过约 6 周时,寻找更新更好的模型。

  1. 扫描。 搜索网络中自上次检查以来发布或更新的开源权重 TTS。查看:
    • TTS Arena / Artificial Analysis 语音排行榜
    • Hugging Face 趋势文本转语音模型
    • r/LocalLLaMA
    • 以下引擎的 GitHub 发布版本
  2. 筛选。 仅当满足以下条件时,才保留候选模型:
    • 可以本地免费使用(开源权重、宽松或个人使用许可证)
    • 能在用户的 GPU 内存和操作系统上运行
    • 能说所需的语言
    • 在质量上超越冠军,或者质量相当但速度快得多
  3. 试用。 使用候选模型生成 eval/lines.txt。使用 scripts/voice_metrics.py 对其进行评分,并与冠军进行对比(pip install numpy librosa;冠军和基准录音在 eval/ 目录中):
    • 音高标准差 ≥ ~5 个半音且范围 ≥ ~17 个半音,才能听起来自然。
    • 通过每秒生成的音频时长来测量速度。
  4. 试听。 请用户在候选模型的音频和 eval/champion_*.wav 之间进行听感选择(ffplay -nodisp -autoexit file.wav)。指标仅用于筛选候选模型;最终由人耳决定。
  5. 记录。 无论是否有任何变化,都请更新下面的“上次检查”行和 references/benchmarks.md。如果冠军模型发生变化,请替换 eval/champion_*.wav 并更新 say.py,并在删除旧模型前询问用户。

上次检查:2026-11-02(网络调查以及本地 VoxCPM2 Q8 和 Phonon 31m/Miles 试用)。Aiden 在听感上优于两者。尚未本地尝试的模型:Phonon 40m、OmniVoice、Breeze TTS 2、Drama 3、Orpheus、Dia、Sesame CSM、Spark-TTS、IndexTTS-2、VibeVoice、Higgs Audio、Kyutai TTS 和 Fish/OpenAudio。详情见 references/benchmarks.md。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能