最近想搞一个完全离线、能念东西给我听的工具——不是什么花里胡哨的需求,就是想让我那些 markdown 笔记能"念"出来,地铁上能听。
之前一直用浏览器自带的 Web Speech API,体验一言难尽:声音机械、断句奇怪、还必须联网。pass。
然后我就开始折腾本地 TTS。先试了 Coqui TTS,模型大得离谱,2GB+ 下下来,配环境又配了半天。装完跑了一下,声音是有了,但是卡顿明显——我这台老机器(i5-8250U)CPU 占用直接拉满。
后来又折腾了 Piper,说是小模型,1.6 亿参数,结果合成中文的时候口音怪怪的,像是英语母语者在硬憋普通话,听着难受。
本来已经想放弃,准备老老实实调 OpenAI API 付费用了,结果 HN 首页飘上来一个 661 分的帖子:Local, CPU-Friendly, High-Quality TTS with Kokoro。点进去一看,82M 参数、Apache 2.0、CPU 就能跑——我心里想:又是营销噱头吧。
试了一下。真香。
Kokoro 是个什么东西
Kokoro-82M 是一个开源的 TTS 模型,Apache 2.0 协议,模型权重在 HuggingFace 上免费下载。整个模型只有 8200 万参数,听起来是不是很弱?但实际跑出来效果,让我前面折腾的那些"大模型"全部下不来台。
几个关键事实先摆出来:
- 参数规模:82M(不是 82B,是 8200 万),磁盘上就 330MB 左右
- 协议:Apache 2.0——意味着你可以商用、改源码、随便搞
- 支持语言:英、美式英语、英式英语、西班牙语、法语、印地语、意大利语、日语、葡萄牙语、中文(惊喜)
- 声音数量:约 50 种,主要优化在英语,但中文也有几个能用的
- 依赖:底层是 StyleTTS 2 架构,用 espeak-ng 做音素转换(这是个坑,待会儿说)
最让我服气的是 CPU 跑的速度。作者 ariya 给的 benchmark(用 am_eric 这个英文声音):
- Intel Core i7-4770K(2012 年发布的,12 年前的 CPU):4.7 秒
- Apple M2 Pro:4.5 秒
- AMD Ryzen 7 8745HS:1.5 秒
一段话就 1-5 秒。我那台 2018 年的笔记本跑起来比这还快点,因为不是冷启动。12 年前的 i7 都能干这个活,你品品。
第一次跑就翻车了
我先按 GitHub README 上最简单的方式装:
| 1 | |
| 2 | |
写了个小脚本测一下:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
跑起来,ModuleNotFoundError: No module named 'kokoro'。
行,我重装:pip install kokoro,装完提示我 Successfully installed kokoro-0.9.4。再跑,又报:
| 1 | |
espeak-ng 没装到 Python 能找到的路径。折腾了一圈才意识到,Linux 上 espeak-ng 不仅要装系统包,还得装对应的 Python 绑定(pip install phonemizer-fork),不然它找不到二进制。
装完再跑,终于出来了 wav 文件。我戴上耳机一听——
效果比 Web Speech API 好太多了。声音自然、有停顿、还能听出情绪。
我当场在群里发了一句:"我去,这个 82M 的比某些 1.6B 的还像人。"
想用 OpenAI 兼容的 API?上 Kokoro-FastAPI
直接 pip install kokoro 适合单次合成,但要部署成服务给别人用(比如接我的笔记系统),得搞个 HTTP API。
我用的方案是 Kokoro-FastAPI,这是个社区做的容器镜像,把 Kokoro 包装成了 OpenAI 兼容的语音 API。
一行命令起服务:
| 1 | |
注:我用 podman 不是 docker,没啥特别的,就是服务器上 docker 已经被别的项目占了。
镜像有点大,5GB 左右。因为它把所有声音模型、espeak-ng、Python 环境都打进去了。下完之后 8880 端口就起来了,浏览器访问 http://localhost:8880/web 能看到一个简易的 web UI,输入文字点播放就能出声音。
但这个不是关键,关键是这个 API 兼容 OpenAI 的 /v1/audio/speech 端点。意味着我之前写的所有调 OpenAI TTS 的代码,只改 base URL 就能直接用:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
我之前的脚本只改了两行(base_url 和一个 api_key 占位),其他都没动。这种 API 兼容性是真省事。
中文效果怎么样?
这是我看很多人关心的问题。我自己测了一下,用 lang_code='z' 加载中文 pipeline:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
听感上:能听清楚,词语发音基本正确,但跟 ElevenLabs、ChatGPT 那种中文 TTS 比,还是有点"机器感"。具体表现是:
- ✅ 字词发音准确,没有明显错误
- ✅ 节奏合理,该停顿的地方停了
- ❌ 语气稍微平一点,缺少那种"抑扬顿挫"
- ❌ 偶尔有"老外说中文"的味道(因为底层是 StyleTTS 2 架构,迁移到中文的痕迹)
不过考虑到 82M 的参数量,做成这样已经离谱了。完全够用场景:笔记朗读、播报、辅助听读。不够用的场景:有声书、播客、专业配音。
如果你要专业中文 TSS,目前还是得上商业方案(或者等 Kokoro 后续版本)。但如果你的需求是"念个东西给我听"——这就是最优解。
几个我踩过的坑
写出来大家别再踩:
1. espeak-ng 必须装
pip install kokoro 只是装了 Python 部分,espeak-ng 是系统依赖。Linux 用户:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
Windows 用户:去 espeak-ng releases 找最新的 .msi 装一下。
2. Mac M1/M2 用户记得开 MPS 加速
默认 Kokoro 在 Mac 上用 CPU 跑,速度虽然不慢但能更快:
| 1 | |
3. 容器镜像 5GB,磁盘紧张的人注意
Kokoro-FastAPI 镜像把所有声音、依赖都打包了。如果你磁盘紧张,或者想用别的镜像替代,可以看看 Speaches。Speaches 的特点是镜像小,但要手动下载声音权重,而且它额外集成了 Whisper(语音转文字),适合要 TTS + STT 一站式搞定的场景。
4. lang_code 必须跟声音匹配
README 里那张表要仔细看:
'a'= American English → 配af_*/am_*声音'b'= British English → 配bf_*/bm_*声音'z'= Mandarin Chinese → 配zf_*/zm_*声音
搞错了会报奇怪的错,比如"找不到声音"或者出来的声音完全是乱码。
5. 中文声音目前就 4 个
去 HuggingFace 的 VOICES.md 一看,中文部分只列了 zf_001 zf_002 zm_001 zm_002 四个声音。男声女声各两个。够用但不多。如果你想念"严肃新闻"风格和"温柔女主播"风格,目前只能用声音本身的特性去调,没法换风格。后续版本会加更多。
跟本地 LLM 联动:让 AI 念给我听
这才是我真正想要的玩法:本地跑 LLM 回答问题 → 用 Kokoro 把答案念出来。
我的设置:
- 本地跑一个 7B 左右的 LLM(我用的是 Qwen2.5-7B,Ollama 起的)
- 用 Kokoro-FastAPI 暴露 8880 端口
- 写个 Python 脚本,把 LLM 输出喂给 OpenAI 兼容的 TTS 端点
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
跑起来是真的爽——AI 回答完问题,音箱里立刻有声音念出来。全离线、断网也能用,数据不离开本机。
地铁上看论文摘要、外语学习跟读、给小孩讲故事(虽然中文还不够好)……场景一下子打开了。
一个我意外的发现
把 LLM 输出扔给 TTS 之前,我建议加一道预处理——把 markdown、emoji、代码块、链接这些东西过滤掉。LLM 默认回答里会有大量格式化的内容,比如:
| 1 | |
| 2 | |
如果直接喂给 TTS,它会一本正经地念出"井号井号井号 简介",或者"中括号 Wikipedia 括号"。笑死。
我的做法是写个简单清洗:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
这么清洗完之后,TTS 念出来就正常多了。这个坑我第一次没注意,听 AI 念"井号井号"差点把咖啡喷出来。
性能上我还测了点东西
ariya 那篇文章只给了英文的声音速度,我自己补了中文的测试(用 zf_001 声音,同样的 Jupiter 段落翻译成中文):
- i5-8250U(我这台笔记本):5.8 秒
- M2 MacBook Air:4.3 秒
- AMD Ryzen 7 5800X(朋友家台式):1.4 秒
纯 CPU 跑的,没用 GPU。5-6 秒念一段话,我觉得完全能接受——比 Coqui TTS 在同样机器上快 3 倍不止。
顺便看了一下内存占用,常驻 600MB 左右。比我那个还在跑的 Slack 还省内存。
长文本怎么搞?
我试过把一整篇 markdown 笔记(大概 5000 字)扔进去,结果:
- 第一次合成完用了 4 分多钟(因为要等全部生成完才出声)
- 中间如果想暂停,没法
- 内存占用峰值到 1.2GB,机器风扇转起来了
我的临时方案是分块:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
然后逐块合成,合并 wav 文件。这样虽然还是一次性出文件,但内存占用稳了,而且可以异步合成下一块的时候同时播放上一块,体验好很多。
更狠的方案是真正的流式——Kokoro 本身就是 generator,可以 chunk-by-chunk 推到音频流里。但这个要写音频后端代码(pyaudio 或者 sounddevice),我打算下次再折腾。
一些还没搞明白的事
写完这个文章的时候,我还有几个事没搞定,先挖个坑:
- 声音克隆:Kokoro 目前不支持声音克隆(用你自己的声音),只能从预设的 50 个声音里选。据说 v2 路线图里有,等吧。
- 流式输出:长文本生成的时候,得等整段念完才能听到第一个字。理论上可以做 chunk-by-chunk 流式,但我还没写代码。
- 多语种混读:比如一段话里中英文混着,我现在是分段处理(中文段用
lang_code='z',英文段用lang_code='a'),很笨拙。希望未来能一个 pipeline 搞定。 - GPU 加速:M1/M2 的 MPS 我开了,但 N 卡上的 CUDA 加速我还没试。按理说 82M 这种小模型在 GPU 上应该是几十毫秒级别,但我的 3060 笔记本被 Stable Diffusion 占着,没法测。
这些坑以后再填。如果你有答案,欢迎评论区告诉我。
跟 ElevenLabs / OpenAI 比,差在哪?
写到这里肯定有人要问:那跟收费的比呢?我自己对比过几个场景:
优势:
- 完全离线:数据不出本机,写私人笔记、医疗记录、合同都能念
- 零边际成本:每念 100 万字还是 0 元
- API 兼容:已经用了 OpenAI TTS 的迁移成本几乎为 0
- 小:82M 参数,普通笔记本就能跑
劣势:
- 声音数量:ElevenLabs 上千种声音、各国口音、各种情绪,Kokoro 50 种
- 声音克隆:ElevenLabs 主打功能,Kokoro 还没有
- 中文质量:跟国产专业 TTS(火山引擎、讯飞)还有差距
- 超长文章:商业方案有专门的优化,Kokoro 长文本体验一般
- 官方支持:社区项目,遇到问题得自己翻 GitHub Issues
什么时候选 Kokoro:
- 数据敏感,必须本地
- 成本敏感,不想续费
- 设备一般,GPU 跑不动大模型
- 用 OpenAI API 风格的代码
什么时候还是上商业方案:
- 要做专业有声书 / 播客
- 要声音克隆(用自己的声音)
- 要 50+ 种语言,覆盖小语种
- 不在乎数据上传
我自己的选择是两个一起用:商业方案做对外产品(声音质量要顶),Kokoro 做个人离线工具(隐私第一)。这个组合到现在用得很顺。
部署上的一些小经验
最后讲几个部署相关的注意点,都是我栽过的:
1. 服务跑在 NAS 上比笔记本好
我笔记本是 2018 年的 i5-8250U,常年开合盖睡眠,但跑 TTS 的时候风扇还是响。后来我把 Kokoro-FastAPI 部署到家里的 NAS(一个小主机,J4125 CPU),24 小时开机、电费忽略不计,需要的时候远程调一下接口就行。
如果你的 NAS 有 4GB+ 内存,完全可以常驻这个服务。82M 模型对硬件几乎没要求。
2. 注意 espeak-ng 的 locale
有用户在 issue 里报告 espeak-ng 在某些 Linux 发行版上因为 locale 问题报错(espeak: error: can't set locale)。如果碰到,最简单的解决:
| 1 | |
| 2 | |
| 3 | |
或者直接在 Docker 启动命令里加 -e LC_ALL=C.UTF-8。
3. Web UI 跟 API 别混用
Kokoro-FastAPI 同时提供了 web UI(8880/web)和 API(8880/v1)。web UI 适合临时测试、给非技术同学体验用,但别在生产环境直接开放 web UI——它没有任何鉴权,任何人能访问就能用你的 TTS 资源。
生产环境最好只暴露 API 端点,前面挂个 nginx 加 basic auth 或者 API key。
4. WAV vs MP3
默认 Kokoro 输出 WAV 文件(24kHz 采样率)。WAV 没压缩,10 秒音频就 1.5MB 左右。如果你要做长篇笔记朗读,存 WAV 磁盘会爆炸。
解决方案:用 ffmpeg 转 MP3:
| 1 | |
| 2 | |
64kbps 对人声来说足够清晰,10 秒音频压缩到 80KB,省 95% 空间。
或者在 API 层面,Kokoro-FastAPI 的 /v1/audio/speech 端点直接支持 MP3 输出,不用后处理。
该说点啥结尾的话了
如果你有这些需求:
- 想完全本地、离线 TTS
- 不愿意给 ElevenLabs / OpenAI 续费
- 想要一个直接兼容 OpenAI API 的开源替代
- 设备一般,没有 4090 / H100
Kokoro-82M 就是 2026 年最该知道的本地 TTS 模型。82M 参数做出来这种质量,开源社区是真猛。
要去折腾的,路线很简单:
pip install kokoro(先确保装了 espeak-ng)- 跑官方 notebook 听效果
- 想要 API 服务的,
podman run起 Kokoro-FastAPI - 之前用 OpenAI TTS 的代码改一行 base_url 就行
后面我打算再折腾一下把流式输出搞通,然后再试试 N 卡 CUDA 加速——到时候再写一篇。有啥问题评论区聊。
参考链接: