前言特别感谢文章作者:HonestQiao / 乔楚,辛苦制作了一整套详尽的教程,非常适合新人及树莓派爱好者学习使用!在文章底部,可以查看乔工树莓派CM0教程系列。
一款能跑在边缘设备上的轻量级语音合成模型,是无数开发者和硬件爱好者梦寐以求的。在 AI 浪潮中,我们见过太多”大模型”,却鲜少见到真正能落地的”小模型”。今天要介绍的 KittenTTS,正是这样一款专为端侧设计的开源语音合成方案——最小仅 15M 参数,25MB 即可存储,在树莓派上就能流畅运行。
项目地址:https://github.com/KittenML/KittenTTS
一、项目背景
KittenTTS 是由 KittenML 开源的超轻量级文本转语音(TTS)项目,定位是”嵌入式端侧 AI”。根据官方描述:
最小模型仅 15M 参数,int8 量化后仅 25MB
基于 ONNX 推理,无需 GPU,CPU 即可运行
支持 8 种音色(4 男 4 女)
然而,实际情况如何?本文带你在树莓派上实际部署测试,揭晓答案。
二、测试环境
2.1 硬件环境
注:测试通过 SSH 远程连接到 mpi5.ssh 主机进行。
2.2 软件环境
2.3 关于 Python 版本的重要说明
KittenTTS 依赖 misaki>=0.9.4,但该版本要求 Python < 3.13。当前系统自带 Python 3.13.5,无法直接满足。
解决方案:使用 Conda 管理多版本 Python(详见下文)。
三、详细部署步骤
3.1 前置准备
3.1.1 克隆项目代码
# 创建项目目录并克隆仓库mkdir -p ~/Projects/ttscd ~/Projects/ttsgit clone https://github.com/KittenML/KittenTTS.gitcd KittenTTS
3.1.2 安装系统依赖
KittenTTS 的语音合成后端依赖 eSpeak NG:
# Debian/Ubuntu 系统安装 espeak-ngsudo apt-get updatesudo apt-get install -y espeak-ng
3.2 Python 环境配置
3.2.1 问题背景
由于系统 Python 版本(3.13)与依赖要求(< 3.13)不匹配,需要通过 Conda 灵活管理 Python 版本。
3.2.2 安装 Miniconda
# 下载最新 Miniconda (aarch64 版本)cd /tmpcurl -LO https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh# 安装到用户目录bash Miniconda3-latest-Linux-aarch64.sh -b -p ~/miniconda3# 激活 condasource ~/miniconda3/etc/profile.d/conda.sh
3.2.3 创建 Python 3.11 环境
# 接受服务条款(首次使用需要)conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/mainconda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r# 创建 Python 3.11 环境(相比 3.12 兼容性更好)conda create -n tts python=3.11 -y# 激活环境conda activate tts# 确认 Python 版本python --version# 输出应显示: Python 3.11.x
3.3 安装 Python 依赖
# 设置代理(如果需要)export HTTP_PROXY=http://127.0.0.1:8080export HTTPS_PROXY=http://127.0.0.1:8080# 安装依赖pip install -r requirements.txt
完整依赖清单(requirements.txt 内容):
num2wordsspacyespeakng_loadermisaki[en]>=0.9.4onnxruntimesoundfilenumpyhuggingface_hub
安装过程大约需要 3-5 分钟,取决于网络状况。安装成功的标志是看到 Successfully installed 提示。
3.4 配置 Hugging Face 加速下载(可选)
Hugging Face Hub 默认源在国外,下载模型较慢:
# 配置使用镜像站(阿里云)export HF_ENDPOINT=https://hf-mirror.com# 或在 Python 代码中指定# from huggingface_hub import hf_hub_download# hf_hub_download(..., local_files_only=False)
四、快速体验
4.1 运行官方示例
# 设置代理export HTTP_PROXY=http://127.0.0.1:8080export HTTPS_PROXY=http://127.0.0.1:8080# 运行示例代码cd ~/Projects/tts/KittenTTSpython example.py
首次运行会从 Hugging Face 下载模型(约 15-80MB),根据网络情况可能需要几分钟。
4.2 示例代码说明
example.py 内容:
from kittentts import KittenTTS# 加载模型(默认 mini 版本,80M 参数)m = KittenTTS("KittenML/kitten-tts-mini-0.8")# 生成语音text = "One day, a little girl named Lily found a needle in her room."audio = m.generate(text=text, voice="Bruno")# 保存为 WAV 文件import soundfile as sfsf.write("output.wav", audio, 24000)
参数说明:
五、基准测试
5.1 测试方案
测试文本(来自 TinyStories 数据集):
One day, a little girl named Lily found a needle in her room.She knew it was difficult to play with it because it was sharp.
| 属性 | 值 |
| 字符数 | 113 |
| 单词数 | 29 |
| 句子数 | 2 |
测试流程:
1. 加载模型(冷启动)
2. Warmup 一次(避免首次 JIT 开销)
3. 连续 3 次生成测试文本,记录每次耗时
5.2 测试代码
from kittentts import KittenTTSimport timemodels = [('kitten-tts-mini-0.8', 'mini (80M)'),('kitten-tts-micro-0.8', 'micro (40M)'),('kitten-tts-nano-0.8', 'nano (15M FP32)'),('KittenML/kitten-tts-nano-0.8-int8', 'nano (15M INT8)'),]text = "One day, a little girl named Lily found a needle in her room. She knew it was difficult to play with it because it was sharp."voice = "Bruno"results = []for model_id, model_name in models:# 加载模型start = time.time()m = KittenTTS(model_id)load_time = time.time() - start# Warmupm.generate(text="warmup", voice=voice)# 3 次生成测试gen_times = []for i in range(3):start = time.time()m.generate(text=text, voice=voice)gen_times.append(time.time() - start)results.append((model_name, load_time, gen_times))print(f"{model_name}: load={load_time:.2f}s, gen={sum(gen_times)/len(gen_times):.2f}s avg")
5.3 测试结果
5.4 结果分析
5.4.1 生成速度排名
nano FP32 (1.81s) > micro (5.91s) > nano INT8 (5.23s) > mini (10.63s)
nano FP32 是最快的,原因是:
1. 参数量最小(15M),计算量最少
2. FP32 在 ARM CPU 上有成熟的 SIMD 优化
5.4.2 INT8 为何更慢?
这是一个反直觉的发现:INT8 量化版本反而比 FP32 慢了约 2.9 倍。
原因分析:
结论:INT8 量化是针对 GPU/NPU/TensorRT 设计的,在纯 CPU 环境下反而不如 FP32 高效。
5.4.3 micro 为何加载最慢?
micro 模型加载时间(14.73s)显著高于其他模型,可能原因:
模型文件较大(40M),首次下载解析耗时
ONNX Runtime 对该模型的优化策略不同
5.5 音频质量对比
已生成各模型测试音频,文件位于项目目录:
建议实际试听对比:nano 模型生成速度快但音质相对较弱,mini 模型生成较慢但音质更好。
六、部署建议
6.1 模型选择建议
6.2 内存需求估算
6.3 关于”Arduino 能不能跑”
答案:不能。
KittenTTS 的”25MB 模型”指的是模型文件大小,运行还需要 ONNX Runtime(约 30MB)和运行时内存(约 100MB)。标准 Arduino/ESP32 的硬件资源完全无法满足。
七、常见问题
Q1: pip install 报错 “externally-managed-environment”
原因:PEP 668 保护,禁止在系统 Python 直接 pip install。
解决:使用虚拟环境(venv/conda)。
Q2: 模型下载失败或超时
解决:
# 设置代理export HTTP_PROXY=http://127.0.0.1:8080export HTTPS_PROXY=http://127.0.0.1:8080# 或使用镜像export HF_ENDPOINT=https://hf-mirror.com
Q3: 生成的音频有杂音
可能原因:
1. 模型首次加载不稳定 → 重试一次
2. 输入文本过长 → 自动分chunk处理
Q4: 如何指定中文?
当前版本不支持中文。KittenTTS 目前仅支持英语(en-us),多语言支持在路线图中。
八、总结
8.1 主要发现
1.✅ KittenTTS 可以在树莓派上正常运行,无需 GPU
2.✅ nano FP32 生成速度最快(1.8s),是最佳性价比选择
3.❌ INT8 在 CPU 上反而更慢,比 FP32 慢约 3 倍
4.❌ Arduino/ESP32 无法运行,内存差距太大
8.2 性能对比一览
8.3 下一步
尝试在不同语音( Bella/Jasper/Luna 等)下的效果差异
测试不同文本长度对生成时间的影响
对比其他嵌入式设备(如 RK3588)的性能
附录:完整复现命令
# ===== 树莓派部署 KittenTTS 完整脚本 =====# 1. 安装 Minicondacd /tmpcurl -LO https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.shbash Miniconda3-latest-Linux-aarch64.sh -b -p ~/miniconda3# 2. 创建 Python 环境source ~/miniconda3/etc/profile.d/conda.shconda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/mainconda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/rconda create -n tts python=3.11 -yconda activate tts# 3. 安装 espeak-ngsudo apt-get update && sudo apt-get install -y espeak-ng# 4. 安装 Python 依赖export HTTP_PROXY=http://127.0.0.1:8080export HTTPS_PROXY=http://127.0.0.1:8080cd ~/Projects/tts/KittenTTSpip install -r requirements.txt# 5. 运行示例python example.py
测试时间:2026-03-21
测试设备:Raspberry Pi 5 (mpi5.ssh)
官方网站:https://edatec.cn/zh/cm0
淘宝店铺:https://edatec.taobao.com/
602