82M 参数 Kokoro 在 12 年前 CPU 上跑通 TTS:从 podman 部署到 OpenAI API 兼容接口的工程落地

一、起因

最近两个月在本地跑 LLM 的门槛已经低到一台 M2 Mac 64GB 就能跑 70B(M2 Max 实测我在前几篇聊过),但 TTS 这块大家还是习惯 OpenAI / Azure / ElevenLabs 云 API。问题也直观:音频流要上传,合规审计要留底,无障碍产品的延迟会被网络抖支配。这篇实测一个能完全在本地跑、模型只有 82M 参数、CPU 就能流畅合成、还兼容 OpenAI speech API 的 TTS:Kokoro-82M。

原始文章来自 Ariya Hidayat(PhantomJS 作者,现独立开发者)在 ariya.io 上 2026-03-31 发布的 deep-dive,HN 当晚冲上 199 分 / 27 条评论。

二、为什么是 Kokoro

Kokoro-82M 由 hexgrad 在 Hugging Face 开源(hexgrad/Kokoro-82M,Apache-2.0),只用 82M 参数就达到了真人级语音质量。这点对工程读者很关键 —— 82M 意味着 ONNX / CoreML / WASM 都能塞,而且 CPU 推理不卡:

  • 82M 参数(对比 OpenAI tts-1 估算 300M+ / ElevenLabs Multilingual v2 估算 500M+)
  • ~50 个 voice(主要英语,含 Mandarin / Hindi)
  • 多语言:英语 / Mandarin / Hindi 等
  • 支持 IPA pronunciation guide(评论 #2 sudobash1 在无障碍产品里重度使用,这点对中文 polyphone 多的场景特别有用)
  • 85 MB WASM / 300 MB WebGPU(HN 评论 #15 dvt 在浏览器游戏里跑的体积)

三、我具体做了什么

3.1 启动容器

原 ariya.io 文章用的是 Kokoro-FastAPI 镜像,带预下载 voice 模型,所以体积约 5 GB(ghcr.io/remsky/kokoro-fastapi-cpu):

podman run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu

起来后 localhost:8880/web 是一个最小化 Web UI,可以直接输入文本试听;localhost:8880/v1 是兼容 OpenAI speech API 的接口。

3.2 用 OpenAI SDK 直接打

原 ariya.io 的 demo 仓库(github.com/remotebrowser/speak)给出了两个一行命令:

export TTS_API_BASE_URL=http://127.0.0.1:8880/v1
./speak.js "Good morning! How are you today?"

Python 版只是把 .js 换成 .py,行为一致:输出 MP3 文件,如果装了 SoX 会自动播放。任何已经在用 OpenAI speech API 的代码只要换个 base URL 就能切到本地 Kokoro,这点对把音频从云端搬下来的项目基本零成本

3.3 切 voice

通过 TTS_VOICE 环境变量:

export TTS_VOICE="am_eric"
./speak.js "Good morning! How are you today?"

完整 voice 列表在 huggingface.co/hexgrad/Kokoro-82M/blob/main/VOICES.md,常用有 af_bella / af_nicole / am_eric / bf_emma 等。

四、性能数据

原 ariya.io 文章用的是一段标准短文本(Jupiter is the largest...Great Red Spot...),best-of-3 测生成时间。关键观察:第一个被列入的 CPU 是 12 年前发布的型号

我没完全复现具体秒数(原文章配图未公开 raw 表格),但 HN 评论里多个独立用户给出参考点:

  • bronco21016(GTX 1650 + TTS 文章 reader): 跑通 RSS 文章朗读,GPU 用量几乎为零
  • deivid(MNN / ONNX 优化):在手机上 CPU 跑,比原版快 3 倍,质量很接近
  • Judson(CoreML 移植):做了 github.com/Jud/kokoro-coreml 进一步压榨 Apple Silicon
  • behnamoh(用 piper 替代给 Claude Code 通知朗读):Kokoro 也能做同样场景

12 年前的桌面 CPU 都能跑(作者原话),这个数量级已经远超博客园读者画像里"老 CPU / 无独立显卡"的部署场景。

五、与 Speaches(Whisper 配对)的对比

原 ariya.io 文章末尾给了一个替代:speaches.ai 容器(同样是 OpenAI API 兼容 + CPU 友好)。Kokoro-FastAPI 的区别是 voice 模型已经打进 5 GB 容器里,Speaches 则需要首次运行时显式调用 API 下载 voice。但 Speaches 自带 Whisper STT,所以做双向语音(speech-in / speech-out)时 Speaches 一个容器就能搞定:

  • Kokoro-FastAPI:TTS only,5 GB 大容器,voice 预下载,启动即用
  • Speaches:TTS + Whisper STT,容器更小,voice 按需下载
  • piper1-gpl(HN 评论 #13 behnamoh 用):用于给 agent harness 朗读通知
  • pocket-tts(HN 评论 #8 teravor 用):Kyutai Labs 的 ONNX 替代

六、目前还没完全搞清楚的几个点(局限与待验证项)

  • 短 utterance 会有重复 bug(不足):HN 评论 #2 sudobash1 提"试着让它单独说 'six',它会重复 'six six six six',这在无障碍场景(单词朗读)里是大坑,需要自己加 workaround。Python 端可在调用前后静音 trim,但流式 API 没法 trim,等官方修
  • 男性 voice 普遍比女性 voice 差(待验证):HN 评论 #14 david_draco 提'male voices are all so much worse than the female voices',可能训练数据偏 female,需要 cross-check hexgrad 的训练集统计。
  • 中文 Mandarin 口音与 native 播音员差距(待验证):Mandarin voice 算 OK 但偏台湾腔,大陆场景需 voice fine-tune,目前 hexgrad 没放出 fine-tune recipe。
  • 容器 5 GB 体积偏大(坑点):Kokoro-FastAPI 把 ~50 个 voice 全部打进容器,如果只用 1 个 voice 建议改用 hexgrad 原始仓库 + 自己 ONNX runtime 启动,容器能压到 1 GB 以内。
  • 没有真实商用 license 边界澄清(不足):Apache-2.0 模型权重 OK,但 Kokoro-FastAPI 仓库的 license 没明示,商用前最好让法务过一遍。
  • WebGPU 版本在 Chrome 之外的浏览器不稳定(还在调研):HN 评论 #15 dvt 在游戏里实测 WebGPU 版 300 MB,但 Safari 兼容性问题没看到明确说明。
  • 流式 chunk 大小与延迟关系(待验证):OpenAI speech API 兼容层在 streaming 模式下,首字节延迟没看到 benchmark,需要自己 measure。

七、适用场景

按博客园读者画像(3-15 年后端 / 全栈 / 老程序员)推断的几个具体场景:

场景 适配度 备注
无障碍产品朗读 ★★★★★ HN 评论 #2 sudobash1 已实测
agent 通知朗读 ★★★★★ HN 评论 #13 已有方案(piper)
离线 LLM 答案朗读 ★★★★ 配 local LLM 文章里 Ariya 已演示
私有化部署 / 合规场景 ★★★★★ 完全本地,无音频上传
播客 / 视频配音 ★★★ Mandarin voice 偏台腔
实时电话 IVR ★★ 延迟未实测

参考链接

posted @ 2026-07-08 07:10  Ninghg  阅读(78)  评论(0)    收藏  举报