语音合成(TTS)技术分册 · 选型 / 部署 / 服务化¶
用途:为「跟读评测」服务提供朗读音源(TTS 朗读 → 用户跟读 → ASR+SOE 打分);同时作为中文 TTS 的选型依据与 CPU 部署操作手册,供 AI 助手直接照做。 环境:Windows Server 宿主机,2×Xeon Gold 6138(40 核 / 80 线程)、256GB 内存、F 盘 895G(剩余 862G);无独立 GPU,纯 CPU 推理。所有服务以 Docker 容器部署,产物只落
F:\EricLiu\,模型权重放labs\models\。 版本基线:Piper v1.8.0(2026-09-04)|GPT-SoVITS20250606v2pro(2025-06-06,主线另推 v2ProPlus / v4)|CosyVoice Fun-CosyVoice3-0.5B-2512|F5-TTS v1.1.22(2026-07-23)|Fish Speech / OpenAudio Drama 3(前代 S2-Pro 4B)|IndexTTS-2.5(2026-08-10)|ChatTTS v0.2.5(2026-04-10)|Speech-AI-Forge(聚合层,AGPL-3.0;最新 Windows 整合包 2026-02-02,更新日志持续至 2026-04)|edge-tts 7.3.1(2026-10-13,LGPL-3.0)|Kokoro-82M v1.0(2025-01-27)/ v1.1-zh(2025-02-26,独立中文权重)|MeloTTS v0.1.2(2024-03,MyShell/MIT)|OpenVoice v2(2024-04,MyShell/MIT;2025-04 后维护停滞)|bark(suno-ai,无 release,代码事实停更)|Spark-TTS-0.5B(2025-03,权重 CC-BY-NC-SA)|FireRedTTS-1S(小红书,2025-05 流匹配更新,代码 MPL-2.0 / 权重 Apache-2.0)(核对日期 2026-11-11,来源:官网/GitHub/HF/ModelScope)
0. 一页速查(AI 先读这段)¶
本机唯一能"实时"出声的只有 Piper。 其余模型在本机只能当离线批处理(一句几秒到几十秒),Fish Speech 直接不可行。
| 你要做的事 | 用哪个 | 一句话理由 |
|---|---|---|
| 跟读评测的朗读音源(EB1-1) | Piper + zh_CN-huayan-medium |
CPU 实时、200ms 级延迟、模型 60MB、GPL 引擎但可自用 |
| 音色克隆(3-10 秒参考音频) | GPT-SoVITS v2ProPlus | 中文克隆效果最好,CPU RTF≈0.3-0.8(慢但能出) |
| 多语言 / 方言 / 情绪指令 | CosyVoice2/Fun-CosyVoice3-0.5B | 覆盖 9 语种 + 18 方言,Apache-2.0,CPU 需 10 秒/句量级 |
| 英文自然度对比实验 | F5-TTS | 质量好,但 CPU 上是"泡咖啡"级速度 |
| 商用 / 生产 | ❌ 除 Piper 外都不建议直接用 | Piper 自用/内部服务可(GPL-3.0,对外分发闭源产品需评估);Fish Speech 权重非商用、ChatTTS AGPL+非商用、IndexTTS 自定义协议 |
三个硬约束(写进任何方案前先自查)
1. 无 GPU → 单句合成耗时按"Piper 0.1-0.5s / 其它 3-30s"预估,不要向用户承诺流式对话级体验。
2. 内存红线:同时开的容器合计 ≤150GB / 48 vCPU(宿主机 60%)。
3. 模型权重一律 F:\EricLiu\AppDocs\TTS\labs\models\,禁止落 C 盘用户目录。
1. 选型对比表¶
1.1 总表¶
| 项目 | 定位 | 中文支持 | 许可证 | CPU 推理可行性(RTF 量级) | 内存 / 模型体积 | 活跃度 | 推荐场景 |
|---|---|---|---|---|---|---|---|
| Piper (OHF-Voice/piper1-gpl) | 轻量 VITS + ONNX,边缘/嵌入 | ✅ zh_CN-huayan-medium/x_low(espeak 音素);xia_ya 需 pinyin 音素,易踩坑 |
引擎 GPL-3.0-or-later;各音色单独授权(多为 MIT/CC) | ✅✅ 实时。官方称树莓派 4 即实时;本机估算 RTF 0.01-0.05 | <1GB / 单音色 20-80MB | 活跃,v1.8.0(2026-09-04),但官方公开"寻找维护者" | 跟读朗读源首选、批量配音、离线播报 |
| GPT-SoVITS (RVC-Boss) | 少样本克隆(5s 零样本 / 1min 微调) | ✅✅ 最强中文克隆之一,含粤语 | MIT | ⚠️ 可跑但慢。官方 M4 CPU RTF 0.526;本机估算 0.3-0.8 | 6-10GB / 预训练权重约 3-4GB + G2PW | 很活跃,tag 20250606v2pro,主线 v2ProPlus/v4 |
定制音色、有声书、离线批量克隆 |
| CosyVoice (FunAudioLLM → QwenAudio) | LLM 式 TTS,指令/方言/流式 | ✅✅ 9 语种 + 18 方言,拼音纠音 | Apache-2.0 | ⚠️ 可跑(自动关掉 fp16/jit/trt/vllm);第三方 32 核实测 约 12.4s/句,估算 RTF 0.5-1.5 | 4-8GB / 0.5B ≈ 2-4GB | 活跃但无 tag,最后提交 2026-05-25 | 多语言/方言、情绪与语速指令、GPU 场景 |
| F5-TTS (SWivid) | Flow-matching 扩散 Transformer,克隆 | ✅ 中英(Emilia 训练) | 代码 MIT / 权重 CC-BY-NC(非商用) | ⚠️ 能跑,官方无 CPU 数据;估算 RTF 5-15 | 4-6GB / 1.35GB + Vocos | 活跃,v1.1.22(2026-07-23) | 英文自然度实验、GPU 场景克隆 |
| Fish Speech / OpenAudio | 商用级 Dual-AR / MoE | ✅ 80+ 语种 | 代码 Apache-2.0 → 新版 Fish Audio Community/Research License;权重 CC-BY-NC-SA / 研究许可 | ❌ 不可行。Drama 3 需 48GB 显存(FP8);S2-Pro 4B 亦需 GPU | Drama 3 约 70GB 权重 | 很活跃(预发布节奏) | 本机不用;仅作技术观察/云端 API |
| IndexTTS (B站 index-tts) | 可导演情绪、语速、发音纠错 | ✅✅ 中英日西阿,拼音/CMU/假名标注 | B站自定义模型协议(商用需授权) | ❌ 官方未声明 CPU 支持,全流程围绕 CUDA;估算 RTF 3-10 | 6-8GB / 0.8B ≈ 3-4GB + 辅助模型 | 活跃,IndexTTS-2.5(2026-08-10) | 情绪化中文配音、短视频,GPU 场景 |
| ChatTTS (2noise) | 对话式口语化 TTS | ✅ 中英 | 代码 AGPL-3.0 / 权重 CC-BY-NC | ⚠️ 能跑;4090 上 RTF 0.3,CPU 估算 2-5 | 3-5GB / 约 1GB | 缓慢维护,v0.2.5(2026-04-10),开源权重故意降质(MP3 压缩+高频噪声) | 口语化/笑声停顿研究,禁商用 |
| Kokoro (hexgrad/Kokoro-82M) | 82M 轻量 StyleTTS 2 + ISTFTNet,单次前向(无扩散/自回归) | ⚠️ v1.0 中文仅"部分支持"(misaki 前端弱);v1.1-zh 为独立权重(100 个中文音色,注音音素 + misaki[zh],官方标注"早期发布收集反馈") | 权重 Apache-2.0 / 推理代码 MIT(espeak-ng 依赖 GPLv3) | ✅✅ 第三方评测 CPU 约 5× 实时,显著快于 GPT-SoVITS/CosyVoice | ~1GB / 82M ≈ 330MB(fp32),ONNX int8 约 80MB | v1.0(2025-01-27)、v1.1-zh(2025-02-26,独立分支未并入主线);2026 生态仍活跃(NVIDIA ONNX 导出等) | Piper 之外的自然度升级候选(CPU 可行的固定音色合成;上线前须按 EB1-1 实测中文质量) |
| MeloTTS (myshell-ai) | VITS 系多语种 TTS,固定音色 | ✅ 中文 + 中英混读(另有英式四口音/日/韩/法/西) | MIT(代码+权重均 MIT) | ✅✅ 官方称 CPU 快于实时(第三方 i7-12700 实测 RTF≈0.41) | ~1GB / 约 180-300MB(按语种分装) | 成熟稳定:v0.1.2(2024-03)后低频发版,代码库已定型 | 多语种/中英混读朗读;无克隆、无情绪控制,表达力低于大模型 |
| OpenVoice v2 (myshell-ai) | 两段式音色克隆(MeloTTS 基础合成 + 音色转换器),零样本跨语种 | ✅ 中/英/日/韩/法/西原生 | MIT(2024-04 起代码+权重均 MIT) | ⚠️ 能跑但慢:音色提取模块默认 CUDA、CPU 无优化路径,估算 RTF >1 | 2-4GB / 基础 TTS + 转换器约 1GB | 维护趋于停滞:最后实质提交 2025-04 | MIT 全套干净的克隆备选;本机克隆仍首选 GPT-SoVITS(中文效果更好且更快) |
| bark (suno-ai) | GPT 式音频语言模型(笑声/叹词/简单音乐) | ✅ 含简中(13 语种) | MIT | ❌ CPU 不实用:3×300M 自回归逐 token 生成,小模型 + CPU offload 后仍以"几十秒-分钟/句"计 | 原生库 ~12GB 常驻;transformers fp16 权重 ~2GB | 事实停更:代码最后实质提交 2023-09(README 最后修改 2024-08),从未发过 release,269 个 open issues;Suno 转向商业音乐产品 | ❌ 回避本机部署;仅研究性试玩(权重 MIT 不会失效) |
| Spark-TTS (SparkAudio) | LLM 式 TTS(Qwen2.5 骨干 + BiCodec 单流语音 token),零样本克隆 | ✅ 中英双语 + 跨语种/混说 | 权重 CC-BY-NC-SA 4.0(2025-05 从 Apache-2.0 改约,禁商用);代码 Apache-2.0 | ⚠️ 0.5B LLM 自回归,官方推理路径按 GPU 设计;CPU 估算 RTF 5-15,仅离线批处理 | 2-4GB / 0.5B ≈ 1.6GB(fp16) | 推理代码发布后基本无大更新(2025 上半年后),仅推理无训练代码 | ❌ 商用链路回避(权重改约禁商用);技术观察 |
| FireRedTTS (小红书 FireRedTeam) | 工业级流式 TTS 基座(1S 版,2025-05 加流匹配解码器) | ✅✅ 中文自然度高(小红书自用同款) | 代码 MPL-2.0 / 权重 Apache-2.0 | ❌ 全流程按 CUDA 设计(安装文档只给 CUDA 版 torch),官方未声明 CPU 支持 | 4-8GB / 权重仓 11.75GB(ModelScope) | FireRedTTS-1S(2025-05 技术报告+流匹配更新);已被 Speech-AI-Forge 聚合 | ❌ 回避本机部署;仅作技术观察/云端方案 |
RTF = 合成耗时 / 音频时长。RTF<1 才是"快于实时"。表中"估算"为本机 40 核 Xeon 的量级推断,首次实测后请回来改成实测值(EB1-1 判据)。
1.2 许可证红线(比性能更容易翻车)¶
| 项目 | 代码 | 权重 | 商用结论 |
|---|---|---|---|
| Piper | GPL-3.0-or-later(wheel 内静态嵌入 espeak-ng) | 音色各自授权,见仓库 docs/LICENSING.md |
自用/内部服务无碍;对外分发闭源产品需评估 GPL,且逐个核对音色许可 |
| GPT-SoVITS | MIT | MIT(自训权重更干净) | ✅ 可商用(注意参考音频本身的权利) |
| CosyVoice | Apache-2.0 | Apache-2.0 | ✅ 最宽松,首选做产品化验证 |
| F5-TTS | MIT | CC-BY-NC(因 Emilia 数据集) | ❌ 权重不可商用 |
| Fish Speech | Apache-2.0(旧)/ 自定义(新) | CC-BY-NC-SA / 研究许可 | ❌ 商用需单独书面协议 |
| IndexTTS | B站协议 | 同 | ⚠️ 商用需联系 indexspeech@bilibili.com |
| ChatTTS | AGPL-3.0 | CC-BY-NC | ❌ 双重不友好 |
| Kokoro | MIT(推理代码) | Apache-2.0 | ✅ 可商用(espeak-ng 依赖为 GPLv3,容器分发时注意合规;v1.1-zh 中文数据来自 LongMaoData 授权,同样 Apache-2.0) |
| MeloTTS | MIT | MIT | ✅ 可商用 |
| OpenVoice v2 | MIT | MIT | ✅ 可商用(注意参考音频本身的权利) |
| bark | MIT | MIT | ✅ 许可最宽松,但已停更 + CPU 不实用,许可好不等于能用 |
| Spark-TTS | Apache-2.0(代码) | CC-BY-NC-SA 4.0(2025-05 改约) | ❌ 权重禁商用,衍生作品须同协议 |
| FireRedTTS | MPL-2.0 | Apache-2.0 | ⚠️ 权重可商用,但 CUDA 导向、CPU 无官方路径(本机回避) |
1.3 选型决策树¶
需要"实时/低延迟"出声? ── 是 ──> Piper(唯一答案)
│
否
↓
需要克隆某个特定人声? ── 是 ──> 中文优先 GPT-SoVITS;多语种/方言优先 CosyVoice
│
否
↓
只要"好听、像播音"? ──> 先用 Piper huayan 试听,不满意再上 CosyVoice(Apache 最安全)
1.4 整合/聚合型项目(推荐与回避)¶
推荐逻辑:TTS 起步一律 Piper 直连(§3.3 内置 HTTP 或 §4 自封装,无中间层、延迟最低)。聚合层只在两种情况下引入:① 需要 ChatTTS/CosyVoice/GPT-SoVITS 等多引擎统一 HTTP 面板;② 需要 SSML/长文本切分/多角色播客这类"重前端工作流",用现成聚合省去自研封装。被聚合引擎的许可证会逐层叠加,商用前必须逐个核对。
| 项目 | 定位 | 维护状态 | 许可证 | CPU 可行性 | 结论:推荐用/选配/回避 |
|---|---|---|---|---|---|
| Speech-AI-Forge (lenML) | 多引擎 TTS/ASR 聚合服务:API Server(:7870,OpenAPI 文档 /docs)+ Gradio WebUI;SSML/长文本分割/播客/音色管理 |
活跃:2026-04 仍在新增后端(260402 接入 MiniMax 云 TTS);最新 Windows 整合包 2026-02-02 | AGPL-3.0(网络服务需开源修改;本库自用无碍) | ⚠️ 是封装层,CPU 可行性=被聚合引擎的可行性:本机可跑 ChatTTS/CosyVoice/GPT-SoVITS(离线级速度),FishSpeech/IndexTTS 系不可行 | 选配:需要多引擎统一入口或 SSML/播客工作流时用,省去自研多引擎封装;注意其聚合列表是 ChatTTS/CosyVoice2-3/F5-TTS/GPT-SoVITS/FireRedTTS/Index-TTS/Qwen3-TTS/Spark-TTS/FishSpeech + MiniMax 云 TTS,不含 EdgeTTS 与 Piper——日常朗读仍走 Piper 直连 |
| edge-tts (rany2) | 调用微软 Edge"大声朗读"在线神经语音的 Python 库 | 活跃,v7.3.1(2026-10-13) | LGPL-3.0(代码);语音本身无商用授权 | ✅ 本地零推理开销,但依赖外网 | 回避(进生产链路):走微软非官方接口——Microsoft 服务协议未对 Read Aloud 语音授予商用权(官方 Q&A 2026-06-22 答复确认无公开商用授权文档),无 SLA、接口随时可能变更/封禁;仅可作临时试听、与本地音色做对比参考。生产音源一律用本地 Piper/其它自托管引擎 |
1.5 推荐结论(一句话版)¶
- 首选 = Piper(
zh_CN-huayan-medium):本机唯一能实时出声的引擎(RTF 0.01-0.05、单音色 20-80MB、200ms 级响应),跟读朗读源的标准答案;GPL-3.0 引擎自用/内部服务无碍,对外分发闭源产品再评估。 - 选配 = Speech-AI-Forge(AGPL-3.0):仅在需要多引擎统一 HTTP 面板或 SSML/长文本/播客工作流时引入(其聚合列表不含 Piper 与 EdgeTTS,日常朗读仍走 Piper 直连);克隆加 GPT-SoVITS(MIT,CPU 慢速可用)、多语种/方言加 CosyVoice(Apache-2.0)。
- 回避 = edge-tts 进生产(微软非官方 Read Aloud 接口,无商用授权、无 SLA、随时变更/封禁);F5-TTS 权重(CC-BY-NC)、ChatTTS(AGPL+CC-BY-NC)、Fish Speech(研究许可/需 48GB 显存)、IndexTTS(B站协议)在商用链路一律回避,只作技术观察。
- 2026-11 扩充(CPU 小模型候选与新增回避):
- 选配候选 = Kokoro(82M,Apache-2.0)/ MeloTTS(MIT):两者均为 CPU 友好的固定音色 TTS(Kokoro 第三方评测 CPU 约 5× 实时;MeloTTS 官方称快于实时),是"Piper 音色不够自然、又不想上 GPT-SoVITS/CosyVoice 级耗时"时的中间档;中文分别依赖 v1.1-zh 独立权重与内置中文模型,上线前必须按 EB1-1 先单句实测。
- 新增回避:bark(代码事实停更于 2023-09 + 3×300M 自回归 CPU 不实用)、Spark-TTS(权重 2025-05 由 Apache-2.0 改为 CC-BY-NC-SA 禁商用)、FireRedTTS(安装与推理全流程 CUDA 导向,CPU 无官方路径)、OpenVoice v2(CPU 慢 + 2025-04 后维护停滞;其 MIT 全套干净的优势在 GPU 环境才体现,本机克隆仍首选 GPT-SoVITS)。
2. 安装部署¶
2.1 Piper 安装(三选一)¶
方式 A:pip(最快验证,Windows 宿主机直接跑)
python -m venv F:/EricLiu/Envs/piper
F:/EricLiu/Envs/piper/Scripts/activate
pip install piper-tts # 引擎(自带 espeak-ng 数据,无需系统装 espeak-ng)
pip install "piper-tts[http]" # 需要内置 HTTP 服务时
# 列音色 / 下音色(默认下到当前目录,用 --data-dir 指定)
python -m piper.download_voices
python -m piper.download_voices zh_CN-huayan-medium --data-dir F:/EricLiu/AppDocs/TTS/labs/models/piper
国内下载卡住时:
export HF_ENDPOINT=https://hf-mirror.com
python -m piper.download_voices zh_CN-huayan-medium --data-dir F:/EricLiu/AppDocs/TTS/labs/models/piper
音色选择坑:中文只有
zh_CN-huayan-medium/zh_CN-huayan-x_low是标准 espeak 音素,开箱即用。zh_CN-xia_ya-*用的是拼音音素集,缺 g2pW 时会大量报Parsing phonemes failed。先用 huayan。
方式 B:Docker(推荐,服务化基线)
见 §4.2 的 docker-compose.yml。
方式 C:二进制
官方仅提供 Linux amd64/arm64/armv7 预编译包(piper_amd64.tar.gz)。Windows 宿主机不适用,请用方式 A 或 B。
2.2 Piper 目录约定¶
F:\EricLiu\AppDocs\TTS\
├── README.md ← 本文件
├── docker\tts-piper\ ← Dockerfile + compose + app
└── labs\
├── models\piper\ ← zh_CN-huayan-medium.onnx + .onnx.json
└── EB1-1-first-wav\ ← 实验产物(wav + 报告)
2.3 GPT-SoVITS(CPU 跑通路径,诚实提示:慢)¶
CPU 能跑,但只适合离线批量:一句 10 秒音频约 3-8 秒出(v2ProPlus,40 核),比 Piper 慢两个数量级。
# 1) 只要 CPU 环境,安装时显式指定 CPU(不要装 CUDA 版 torch)
conda create -n GPTSoVits python=3.10 -y && conda activate GPTSoVits
git clone https://github.com/RVC-Boss/GPT-SoVITS.git F:/EricLiu/AppDocs/TTS/labs/src/GPT-SoVITS
cd F:/EricLiu/AppDocs/TTS/labs/src/GPT-SoVITS
bash install.sh --device CPU --source HF-Mirror # Windows 用: pwsh -F install.ps1 --Device CPU --Source HF-Mirror
# 2) 权重放到 GPT_SoVITS/pretrained_models(约 3-4GB)
# v2Pro / v2ProPlus 权重 + 中文必备 G2PWModel → GPT_SoVITS/text/G2PWModel
# 3) 启动 API(比 WebUI 更适合服务化)
python api_v2.py -a 127.0.0.1 -p 9880 -c GPT_SoVITS/configs/tts_infer.yaml
CPU 下的必要动作:
- 推理前确认 is_half: false(半精度在 CPU 上无意义,还可能报错)。
- 设 OMP_NUM_THREADS=16(别开 80,OpenMP 超线程反而抖动)。
- 参考音频 3-10 秒、干净单人、无 BGM;先用 UVR5 去伴奏再切片。
- 长文本按句切分后串行合成,避免一次性显存/内存峰值。
2.4 CosyVoice(CPU 跑通路径)¶
CosyVoice 的推理封装会在检测不到 CUDA 时自动把 load_jit/load_trt/load_vllm/fp16 全置 False 并打印 no cuda device... 警告——这是正常现象,说明已回退到 CPU。
git clone --recursive https://github.com/FunAudioLLM/CosyVoice.git F:/EricLiu/AppDocs/TTS/labs/src/CosyVoice
cd F:/EricLiu/AppDocs/TTS/labs/src/CosyVoice
conda create -n cosyvoice python=3.10 -y && conda activate cosyvoice
# 关键:先装 CPU 版 torch,再装依赖,否则会拖进来 2GB+ 的 CUDA 轮子
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu
pip install -r requirements.txt
# 权重(二选一,国内优先 ModelScope)
python -c "from modelscope import snapshot_download; snapshot_download('iic/CosyVoice2-0.5B', local_dir='pretrained_models/CosyVoice2-0.5B')"
CPU 下的调用参数(务必显式关加速):
from cosyvoice.cli.cosyvoice import CosyVoice2
cosy = CosyVoice2('pretrained_models/CosyVoice2-0.5B',
load_jit=False, load_trt=False, load_vllm=False, fp16=False)
依赖地狱预警:
sox/ttsfrd/WeTextProcessing任一缺失都可能让文本前端报错;pip install -r requirements.txt失败时优先查 Python 版本(必须 3.10)与 torch 是否被 CUDA 版覆盖。
2.5 不建议在本机安装的几个¶
- Fish Speech:Drama 3 需 ≥48GB 显存(FP8),S2-Pro 为 4B+400M 双 AR,CPU 上单句以"分钟"计。结论:本机不装,需要时走官方 API。
- IndexTTS-2.5:仓库全部流程按 CUDA 设计(
tools/gpu_check.py、CUDA 12.8、deepspeed),未声明 CPU 支持。装了大概率卡在编译 kernel。 - bark(2026-11 补充核实):代码事实停更(最后实质提交 2023-09),3×300M 自回归 + EnCodec,CPU 上"几十秒-分钟/句";原生库要 ~12GB 常驻。不值得装。
- Spark-TTS / FireRedTTS(2026-11 补充核实):前者权重 CC-BY-NC-SA 禁商用且官方路径按 GPU 设计;后者 CUDA 导向、权重仓 11.75GB、未声明 CPU 支持。均回避。
3. 高频用法¶
3.1 Piper 命令行¶
# 基础:stdin 文本 → wav(-m 音色名,-f 输出文件,-- 分隔)
python -m piper -m zh_CN-huayan-medium \
--data-dir F:/EricLiu/AppDocs/TTS/labs/models/piper \
-f F:/EricLiu/AppDocs/TTS/labs/EB1-1-first-wav/hello.wav \
-- '你好,这是一段中文语音合成测试。'
# 从文件读入(批量)
python -m piper -m zh_CN-huayan-medium --input-file sentences.txt --output-dir out/
# 常用开关
# --cuda 启用 GPU(本机无效,需 onnxruntime-gpu)
# --sentence-silence 句间静音秒数(默认偏短,朗读评测建议 0.2)
# --volume 音量倍数;--no-normalize 关闭自动归一化
# --output-raw 输出裸 PCM(流式场景)
CLI 每次都要重新加载模型(约 0.1-0.5s),批量合成请用 HTTP 服务或 Python 常驻进程。
注音注入(多音字兜底):Piper 支持 espeak 音素直写
他在银 [[ j ǐ n ]] 行里行走。 # 用 espeak-ng -v cmn --ipa=3 -q 银行 先查出音素
3.2 Piper Python API¶
import wave
from piper import PiperVoice
# 1.7+ 的用法:load 一次,反复 synthesize(务必复用对象)
voice = PiperVoice.load(
"F:/EricLiu/AppDocs/TTS/labs/models/piper/zh_CN-huayan-medium.onnx"
)
with wave.open("out.wav", "wb") as wav:
voice.synthesize_wav("你好,世界。", wav)
控制语速/随机度(1.7+ 用 SynthesisConfig):
from piper import PiperVoice, SynthesisConfig
cfg = SynthesisConfig(length_scale=1.15, noise_scale=0.667, noise_w_scale=0.8)
with wave.open("slow.wav", "wb") as wav:
voice.synthesize_wav("慢一点读。", wav, syn_config=cfg)
length_scale > 1变慢,< 1变快;跟读场景建议 1.0-1.15(太慢会破坏韵律,SOE 打分反而失真)。
3.3 内置 HTTP 服务(零代码起步)¶
pip install "piper-tts[http]"
python -m piper.http_server -m zh_CN-huayan-medium --host 0.0.0.0 --port 5000 \
--data-dir F:/EricLiu/AppDocs/TTS/labs/models/piper
curl localhost:5000/info
curl localhost:5000/voices
curl -X POST -H 'Content-Type: application/json' \
-d '{"text":"你好","length_scale":1.1}' \
-o out.wav localhost:5000/synthesize
字段:text(必填)、voice、speaker/speaker_id、length_scale、noise_scale、noise_w_scale。缺省回落到启动参数 → 音色配置。
3.4 GPT-SoVITS API¶
curl -X POST http://127.0.0.1:9880/tts -H "Content-Type: application/json" -d '{
"text": "要合成的中文文本",
"text_lang": "zh",
"ref_audio_path": "F:/EricLiu/AppDocs/TTS/labs/ref/voice.wav",
"prompt_text": "参考音频里说的那句话",
"prompt_lang": "zh",
"speed_factor": 1.0,
"streaming_mode": false
}' --output out.wav
prompt_text必须与参考音频逐字一致,否则音色漂移。api_v2.py文件头部 docstring 是完整字段说明。
3.5 CosyVoice Python(零样本克隆)¶
import torchaudio
from cosyvoice.cli.cosyvoice import CosyVoice2
cosy = CosyVoice2('pretrained_models/CosyVoice2-0.5B',
load_jit=False, load_trt=False, load_vllm=False, fp16=False)
for i, out in enumerate(cosy.inference_zero_shot(
'要合成的文本。', '参考音频对应的文本。', 'ref.wav', stream=False)):
torchaudio.save(f'out_{i}.wav', out['tts_speech'], cosy.sample_rate)
首次调用会触发模型加载(CPU 上 20-60s),服务化时必须做"启动预热 + 常驻单例"。
4. 服务化:FastAPI 封装 Piper(EB1-2)¶
为什么还要自己包一层:内置 http_server 没有 /health(HAProxy/Keepalived 探活要用)、没有统一错误码、不方便加缓存与鉴权、也不便与 ASR/SOE 共用一套响应格式。
4.1 目录结构¶
F:\EricLiu\AppDocs\TTS\docker\tts-piper\
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── app\
└── main.py
4.2 docker-compose.yml¶
services:
tts-piper:
build: .
image: local/tts-piper:1.8.0
container_name: tts-piper
restart: unless-stopped
ports:
- "8101:8000"
environment:
PIPER_DATA_DIR: /models
PIPER_VOICE: zh_CN-huayan-medium
OMP_NUM_THREADS: "8" # 单容器别超 8,靠多副本横向扩
volumes:
- "F:/EricLiu/AppDocs/TTS/labs/models/piper:/models:ro"
deploy:
resources:
limits:
cpus: "8"
memory: 4G
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request;urllib.request.urlopen('http://127.0.0.1:8000/health')"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40s
4.3 Dockerfile¶
FROM python:3.12-slim
# onnxruntime 依赖 libgomp1;piper wheel 已自带 espeak-ng 数据,无需装 espeak-ng
RUN apt-get update && apt-get install -y --no-install-recommends libgomp1 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ ./app/
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]
requirements.txt:
piper-tts==1.8.0
fastapi==0.115.*
uvicorn[standard]==0.32.*
固定版本号:Piper 1.x 的 Python API 在小版本间改过(
synthesize→synthesize_wav+SynthesisConfig),不锁版本迟早踩坑。--workers 1:模型是进程内对象,多 worker 会复制内存;要并发就多开容器。
4.4 app/main.py(完整可跑,含 /health)¶
import io
import os
import threading
import time
import wave
from fastapi import FastAPI, HTTPException
from fastapi.responses import Response
from pydantic import BaseModel, Field
from piper import PiperVoice
try: # piper-tts >= 1.7
from piper import SynthesisConfig
except ImportError: # 1.2.x 分支
SynthesisConfig = None
DATA_DIR = os.getenv("PIPER_DATA_DIR", "/models")
DEFAULT_VOICE = os.getenv("PIPER_VOICE", "zh_CN-huayan-medium")
STARTED_AT = time.time()
app = FastAPI(title="Piper TTS API", version="1.0.0")
_voices: dict[str, PiperVoice] = {}
_lock = threading.Lock()
def get_voice(name: str) -> PiperVoice:
"""懒加载 + 复用。加载耗时 0.1-0.5s,不可每次请求新建。"""
with _lock:
if name not in _voices:
path = os.path.join(DATA_DIR, f"{name}.onnx")
if not os.path.exists(path):
raise FileNotFoundError(f"voice not found: {path}")
_voices[name] = PiperVoice.load(path)
return _voices[name]
class TTSRequest(BaseModel):
text: str = Field(..., min_length=1, max_length=2000)
voice: str | None = None
length_scale: float = Field(1.0, ge=0.5, le=2.0)
speaker_id: int | None = None
@app.get("/health")
def health():
return {
"status": "ok",
"engine": "piper",
"default_voice": DEFAULT_VOICE,
"loaded_voices": sorted(_voices),
"uptime_sec": round(time.time() - STARTED_AT, 1),
}
@app.get("/voices")
def voices():
"""列出 /models 下已下载的音色(.onnx 与 .onnx.json 成对才算)。"""
items = []
if os.path.isdir(DATA_DIR):
for f in sorted(os.listdir(DATA_DIR)):
if f.endswith(".onnx"):
name = f[:-5]
items.append({"name": name,
"ready": os.path.exists(os.path.join(DATA_DIR, f + ".json"))})
return {"data_dir": DATA_DIR, "voices": items}
@app.post("/synthesize")
def synthesize(req: TTSRequest):
name = req.voice or DEFAULT_VOICE
try:
voice = get_voice(name)
except FileNotFoundError as e:
raise HTTPException(status_code=404, detail=str(e))
buf = io.BytesIO()
t0 = time.perf_counter()
try:
with wave.open(buf, "wb") as wf:
cfg = None
if SynthesisConfig is not None:
cfg = SynthesisConfig(
length_scale=req.length_scale,
speaker_id=req.speaker_id,
)
if hasattr(voice, "synthesize_wav"):
if cfg is not None:
voice.synthesize_wav(req.text, wf, syn_config=cfg)
else:
voice.synthesize_wav(req.text, wf)
else:
voice.synthesize(req.text, wf)
except Exception as e:
raise HTTPException(status_code=500, detail=f"synthesis failed: {e}")
cost = time.perf_counter() - t0
data = buf.getvalue()
return Response(
content=data,
media_type="audio/wav",
headers={
"X-Voice": name,
"X-Synth-Seconds": f"{cost:.3f}",
"X-Audio-Bytes": str(len(data)),
},
)
启动后自检:
docker compose up -d --build
curl -s localhost:8101/health
curl -s -X POST localhost:8101/synthesize -H "Content-Type: application/json" \
-d '{"text":"你好,欢迎使用跟读评测服务。"}' -o hello.wav
ffprobe hello.wav # 看时长是否与文本匹配
验收判据(EB1-2):/health 返回 200;合成 wav 可播放;响应头 X-Synth-Seconds / 音频时长 得到 RTF;容器 healthy。
5. 排障速查¶
| 现象 | 根因 | 处理 |
|---|---|---|
Parsing phonemes failed for ... |
音色与音素集不匹配(xia_ya 需 pinyin/g2pW) |
换 zh_CN-huayan-medium;或装 piper-tts[zh] |
| 合成出来是静音/极短 | .onnx 与 .onnx.json 不配套或 json 缺失 |
两文件必须同名同目录 |
| 首次请求 5xx,之后正常 | 懒加载超时 / 并发首次加载 | 启动后预热一句;_lock 已串行化,或加 start_period |
ImportError: libgomp.so.1 |
slim 镜像缺 OpenMP | apt install libgomp1 |
| 下载音色超时 | HF 不可达 | HF_ENDPOINT=https://hf-mirror.com,或手动下载两文件放入 --data-dir |
| 中文读音怪 / 多音字错 | espeak 前端局限 | 用 [[ 音素 ]] 强制注音;或改用 GPT-SoVITS/CosyVoice |
| 合成速度慢 | CLI 每次加载模型 / OMP 线程过多 | 用常驻服务;OMP_NUM_THREADS=8 左右 |
| 音色像"念稿机" | Piper 本身就是轻量 VITS | 属预期;跟读场景可接受,追求自然度换模型 |
| GPT-SoVITS 报 G2PW 相关错 | 中文前端模型没放对 | 解压为 GPT_SoVITS/text/G2PWModel |
CosyVoice no cuda device, set load_... to False |
正常回退 | 忽略;不要试图在 CPU 上开 fp16 |
| 容器 OOM | 多副本 + 大模型 | 单容器限 4G,副本数按 free -g 规划 |
6. AI 操作守则(本分册强制)¶
- 先确认体积再下载。任何
snapshot_download/hf download之前,告诉用户:仓库名、总体积(Piper 音色 20-80MB;GPT-SoVITS 3-4GB;CosyVoice 2-4GB;F5-TTS 1.4GB)、落盘路径、预估耗时,等确认再执行。 - 长任务一律后台跑。合成超过 30 秒、模型下载、权重转换,都用后台任务并定期汇报进度;不要阻塞对话。
- CPU 耗时诚实预告。启动任何非 Piper 的合成前,先给"预计 X 秒/句",禁止说"很快"。
- 单句先验证再批量。批量合成前先跑 1 句,检查时长(
ffprobe)与听感,再放大到 N 句。 - 不改系统环境。不
pip install到全局、不动 C 盘、不改 PATH;一律 venv 或容器。 - 许可证先查后用。推荐任何模型前先看 §1.2;商用场景默认推 CosyVoice(Apache-2.0)/ GPT-SoVITS(MIT),禁推 F5-TTS 权重与 ChatTTS。
- 不代注册、不代充值。Fish Speech / 讯飞 / 腾讯云等只做能力说明。
- 产物落盘有规矩:音频进
labs\E*XX-*\,权重进labs\models\,临时文件进F:\EricLiu\tmp\,并在实验报告里引用具体文件名。 - 端口登记:TTS 用 8101(保留 8100 给网关),Piper 内置服务 5000,GPT-SoVITS 9880,CosyVoice WebUI 50000。新占端口先查冲突。
- 失败即记录。踩坑与解决方式同步到
AppDocs\Reusable\,避免同一坑踩两次。
7. 参考链接与更新记录¶
- Piper:https://github.com/OHF-Voice/piper1-gpl | CLI/HTTP/Python 文档见
docs/| 音色试听 https://rhasspy.github.io/piper-samples - 旧仓库(已归档,MIT):https://github.com/rhasspy/piper
- 音色库:https://huggingface.co/rhasspy/piper-voices
- GPT-SoVITS:https://github.com/RVC-Boss/GPT-SoVITS
- CosyVoice:https://github.com/FunAudioLLM/CosyVoice (现重定向至 QwenAudio/CosyVoice)
- F5-TTS:https://github.com/SWivid/F5-TTS
- Fish Speech / OpenAudio:https://github.com/fishaudio/fish-speech
- IndexTTS:https://github.com/index-tts/index-tts
- ChatTTS:https://github.com/2noise/ChatTTS
- Speech-AI-Forge:https://github.com/lenML/Speech-AI-Forge
- edge-tts:https://github.com/rany2/edge-tts | PyPI https://pypi.org/project/edge-tts/
- Kokoro:https://huggingface.co/hexgrad/Kokoro-82M | 中文权重 https://huggingface.co/hexgrad/Kokoro-82M-v1.1-zh | 推理库 https://github.com/hexgrad/kokoro
- MeloTTS:https://github.com/myshell-ai/MeloTTS
- OpenVoice:https://github.com/myshell-ai/OpenVoice
- bark:https://github.com/suno-ai/bark
- Spark-TTS:https://github.com/SparkAudio/Spark-TTS | 权重 https://huggingface.co/SparkAudio/Spark-TTS-0.5B
- FireRedTTS:https://github.com/FireRedTeam/FireRedTTS | 权重 https://modelscope.cn/models/FireRedTeam/FireRedTTS-1S
| 日期 | 变更 |
|---|---|
| 2026-11-11 | 建档:7 个项目版本基线核对、选型表、Piper 部署与服务化模板、CPU 可行性评估 |
| 2026-11-11 | 新增 §1.4 整合/聚合型项目:Speech-AI-Forge(选配,AGPL-3.0)、edge-tts(回避生产,LGPL-3.0+微软非官方接口风险);版本基线补充 |
| 2026-11-11 | 选型表扩充 6 行(联网核实):Kokoro(82M,Apache-2.0,CPU 约 5× 实时,中文走 v1.1-zh 独立权重,选配候选)、MeloTTS(MIT,CPU 快于实时,选配候选)、OpenVoice v2(MIT 但 CPU 慢+维护停滞)、bark(事实停更 2023-09,CPU 不实用,回避)、Spark-TTS(权重 2025-05 改约 CC-BY-NC-SA 禁商用,回避)、FireRedTTS-1S(MPL-2.0/Apache-2.0,CUDA 导向,回避);§1.2 许可证表、§2.5、§1.5 同步;版本基线补充 |