ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

小智改造实战解读-用kokoro-onnx替换云端 TTS 的完整记录

小智改造实战解读-用kokoro-onnx替换云端 TTS 的完整记录 本篇速览语音链路里 LLM 已本地化若 TTS 仍走云端断网即哑、数据出设备——这是替换 TTS 环的直接动机。kokoro-onnx 是基于 Kokoro-TTS 与 ONNX Runtime 的轻量本地语音合成封装README 标称约 300MB量化后约 80MB多语言多音色官方建议用 uv 建隔离环境。一个 TTS 系统内部有清晰的三段文本前端 → 时长预测 → 声码器延迟主要被这三者瓜分用打点而不是体感来定位。精度不是只有全精度导出脚本支持 fp16 与 int8但仓库提交明确记录量化副本预测的时长略有差异只有全精度被验证输出一致——这是真实的精度坑。边界必须写清本地 TTS 的音色丰富度与自然度通常不如云端服务这是取舍不是缺陷。一、一句话结论把语音助手搬到点位上最容易被人忽略的一环是说话。很多人把 LLM 和 ASR 都本地化了TTS 却还留着云端接口——结果断网时整条链路立刻哑火前面所有本地化努力都白做。本篇用一个轻量组件 kokoro-onnx 把 TTS 也搬下来并把它从外到内拆一遍让你知道一段文字变成声音这件事时间到底花在哪儿。二、背景为什么先拆 TTS 环2.1 链路里 TTS 是最后一跳回顾整条链路麦克风 → VAD → ASR → LLM → TTS → 扬声器。前四环都本地化之后TTS 是最后一跳。这一跳如果还在云端有两个后果断网即哑虽然 LLM 已经能本地回答了但答案合成不出声音。数据出设备要合成的文本可能是对话内容经过外部 TTS 服务。所以 TTS 本地化不是锦上添花而是闭环的必要一步。2.2 为什么选 kokoro-onnx选型时考虑过更知名的 Piper但它的主仓库最后 Release 停在 2023-11-14、最后提交 2025-08-26近三年无 ReleaseGitHub 元数据且 sherpa-onnx 的示例集已包含 Piper TTS素材会与 A 类主线重叠。kokoro-onnx 近期仍在更新代码最近 push 2026-09-01且已支持导出 fp16 / int8 精度副本能做出三种精度对照的完整实验。许可证也清晰README 的 License 小节写明代码为 MIT、模型为 Apache 2.0没有双许可陷阱。2.3 它是什么kokoro-onnx 是基于 Kokoro-TTS 与 ONNX Runtime 的轻量级本地语音合成封装。README 的 Features 明确写出约 300MB量化后约 80MB、在 macOS M1 上达到接近实时的合成速度、支持多种语言、提供多个音色。具体音色与语言清单由上游 Kokoro-82M 仓库的VOICES.md维护。使用方式为安装kokoro-onnx包下载kokoro-v1.0.onnx与voices-v1.0.bin两个文件后直接调用官方建议用 uv 建立隔离环境v1.0 起搭配 misaki 做音素前端。“near real-time on macOS M1” 是在特定硬件上的表述搬到 ARM 开发板上必须重测不能套用。这也是为什么本篇所有性能数字都标注来源与条件——同一个组件在不同板子上的表现可能差出数倍拿一处的数据当通用结论会误导选型。2.4 kokoro 的模型与音色是怎么组织的kokoro-onnx 把模型权重和音色表拆成了两个文件kokoro-v1.0.onnx是声学模型本身voices-v1.0.bin是预训练的音色向量集合。这种拆分带来一个工程上的便利换音色不需要换模型只换voices里的向量即可。具体有哪些音色、每种音色的语言与风格由上游的VOICES.md定义命名通常带语言/性别/风格前缀如af_*表示美式英语女声一类。选型时要先翻VOICES.md确认你需要的语言确实有对应音色再决定用不用——没有对应音色的语言硬上要么报错要么效果差。2.5 许可证与版本代码 MIT、模型 Apache 2.0这对要落地到产品的团队是友好的MIT 宽松到几乎无附加条件Apache 2.0 还带专利授权。版本方面模型 Release 为model-files-v1.1代码最近有 push2026-09-01。版本迭代快发布前建议再核一次模型文件名与接口是否变化——尤其是voices文件的版本要和onnx模型版本匹配错配会导致加载报错或音色错乱。版本校验还有一个动作下载后比对文件的字节数或官方提供的校验和排除传输损坏。模型文件损坏的表现前文 2.6 已提过这里再强调一次——版本与完整性是模型落地的两道基础关往往被急于跑通的人跳过最后却花更多时间排灵异问题。2.6 模型文件要不要校验完整性从官方仓库下载kokoro-v1.0.onnx与voices-v1.0.bin后建议对文件做完整性确认记录下载后的字节大小若仓库提供了校验和就比对没有就用字节数 后续能否正常加载来间接确认。模型文件在网络传输中损坏后会表现为加载时报文件截断magic number 错误或推理输出全零/乱码排查时先怀疑下载完整性而不是代码。把实际文件名、字节数、来源 URL 写进 env.txt是改造类项目的基本纪律。2.7 本篇与 A 类 TTS 的关系A 类把 TTS 作为 sherpa-onnx 的一部分提过其示例集含 Piper、Matcha 等本篇为何另写 kokoro-onnx因为两者是同一环的不同实现sherpa 的 TTS 和 VAD/ASR 同库适合一个库收三环kokoro 是专门的轻量 TTS 封装体积与精度对照更干净适合只替换 TTS 一环、且要 fp16/int8 三种精度实验的场景。两篇不是重复而是给 TTS 这一环两种可替换的实现选项——你按要不要和 ASR 同库要不要做精度对照来选。三、安装与运行3.1 官方推荐做法README 的 Setup 小节给出以项目文档当前版本为准pipinstall-Ukokoro-onnx# 包名以官方文档为准# 或官方推荐的 uv 隔离环境uvaddkokoro-onnx soundfile然后下载两个文件kokoro-v1.0.onnx模型与voices-v1.0.bin音色放进同一目录即可运行。v1.0 起建议搭配 misaki g2p 做音素前端。3.2 一个接口面很窄的好处它依赖少主要是 onnxruntime 与音频读写核心用法只有几行。这让一篇功能拆解文能把整个组件从上到下讲清楚写到字节与毫秒的粒度而不是停在调用示例这一层。窄接口也意味着出错面小——能出错的地方就那么几个模型/音色路径、输入文本格式、输出采样率、运行时版本。3.3 一个最小可运行示例# 接口形态示例实际 API 以官方文档当前版本为准fromkokoro_onnximportKokoroimportsoundfileassf# 模型与音色两个文件需提前下载到本地kokoroKokoro(kokoro-v1.0.onnx,voices-v1.0.bin)# 核心调用文本 → 音频audio,sample_ratekokoro.create(text今天天气不错我们出去走走吧。,voiceaf_heart,# 音色名需存在于 voices 表speed1.0,# 语速# langzh # 语言提示按文档可选)# 写出可播放文件sf.write(out.wav,audio,sample_rate)要点voice必须是voices表里真实存在的键传一个不存在的音色名会在加载或推理阶段报错。这一段就是 TTS 环在链路里被调用的最小形态——LLM 产出文本后调一次create拿到音频再交给播放线程。工程上建议在create外包一层异常处理捕获模型加载失败路径/版本错、推理异常输入格式错、以及音频写出失败路径权限。把异常类型和触发条件记到日志比合成没声音这种笼统反馈好定位得多。尤其模型/音色路径错在板子上很常见见 10.x 的路径与版本问题。四、分段耗时在哪4.1 TTS 内部的三段一段文字变成声音内部大致是三段流水线文本前端文字 → 音素/拼音 ↓ 时长预测每个音素持续多久 ↓ 声码器声学特征 → 波形每一段都有自己的耗时定位瓶颈要先分清楚是哪一段慢而不是笼统说合成慢。4.2 文本前端中文尤其不能省英文可以靠字母拼读中文必须把汉字转成拼音或音素才能合成。这一步通常叫 g2pgrapheme-to-phoneme。kokoro-onnx 在 v1.0 起明确建议搭配 misaki 做音素前端。漏掉这一步是中文 TTS 最常见的翻车点——直接把汉字丢进模型要么报错要么读音全错。更细一点misaki 对英文有成熟的音素前端但中文需要对应的中文 g2p 支持如果目标语言是中文要确认 misaki 的中文路径可用或换成其他中文 g2p 工具再喂给模型。这一处语言—前端的匹配是 kokoro-onnx 在多语言落地时最容易踩的坑。4.3 时长预测与声码器时长预测决定每个字拖多长声码器决定最后的波形长什么样。前者影响节奏自然度后者影响音色。对延迟而言声码器往往是耗时大头尤其是高采样率输出时。定位方法很朴素在三段之间各打一个时间戳看哪一段占的时间最长。如果声码器占了一半以上优化重点就应该是声码器或换更快的声码器 / 降采样率而不是去折腾文本前端。补充一点通用背景不特指 kokoro 内部实现声码器的任务是把声学特征如 mel 谱还原成时域波形主流路线有基于 GAN 的、基于流flow的、以及基于扩散diffusion的各有速度与质量的取舍。端侧更看重速度与体积所以落地时常常选轻量声码器代价是高频细节略损。了解这个大背景有助于理解为什么声码器是耗时大头、又为什么量化后音质先在这里掉。4.4 用打点而不是体感不要靠感觉合成挺快。在固定测试文本集上跑记录三段各自的耗时中位数再乘以一轮对话的句数句级流式下每轮会合成多句得到整轮的合成耗时。这样才有数字可对照也才能在优化时知道该动哪一段。4.5 一个打点示例importtime t0time.perf_counter()phonemesg2p(text)# 文本前端t1time.perf_counter()durationskokoro.predict_duration(phonemes)# 时长预测示意t2time.perf_counter()audiokokoro.vocode(phonemes,durations)# 声码器示意t3time.perf_counter()print(f前端{(t1-t0)*1000:.1f}ms | 时长{(t2-t1)*1000:.1f}ms | 声码{(t3-t2)*1000:.1f}ms)上面的predict_duration/vocode是示意拆分实际 API 可能把这几步包在create里一次完成打点时要按真实 API 的可拆分点来插桩不要凭示意代码硬套。实务上 kokoro-onnx 的create往往一步完成三段要打点就要在库内部或前后包裹计时若库不暴露中间产物可用输入前时间戳与输出后时间戳先算出总耗时再用固定开销 单句耗时 × 句数的结构反推各段占比。反推虽不如直接插桩准但足以定位瓶颈大概在哪一段。4.6 多音字与数字中文前端的两道坎中文音素前端最棘手的是多音字如银行的行和行走的行和数字的读法中英文混排。g2p 模型若训练语料覆盖不足会把多音字读错、把2026读成两千零二十六或逐位读。这一项要在测试集里专门准备含多音字 含数字 中英混读的句子逐句核对读音。它不是 kokoro 独有的问题而是所有中文 TTS 的共性难点写稿时要作为前端质量的硬检查项列出。4.7 不同语言的文本前端差异kokoro 走多语言路线但每种语言的 g2p 难度不同英文靠字母拼读相对规则中文必须做汉字→拼音日文要处理假名与汉字混排韩文有自身的字母组合规则。落地多语言时要为每种目标语言确认其前端的可用性misaki 对中文的支持程度就是一例不能假设一个前端通吃所有语言。缺某语言前端时要么补该语言的 g2p要么该语言退回到云端 TTS不要硬上。五、体积与精度三种档位5.1 为什么是三种仓库近期的提交记录说明导出脚本scripts/export.py支持--fp16与--int8会生成全精度之外的降精度副本。三种档位对应不同的体积与质量档位体积量级速度质量风险fp32全精度最大最慢基准输出被验证一致fp16介于中间居中通常可接受int8最小约 80MB 量级最快可能引入可闻差异5.2 一个真实的精度坑仓库提交里明确写道量化副本预测的时长略有差异因此只有全精度导出被验证为输出一致。这句话值得放大——它说明量化不只是体积变小还会让每个音素拖多长的预测偏掉最终表现为节奏不对、停顿位置异常。所以精度选择不能只看体积要实测用固定文本合成后主观听节奏与音色并对比全精度版本。把量化后时长预测差异作为一个专门的检查项比只看音色像不像更全面。5.3 怎么实测精度差异一个可复用的实验取同一段固定文本分别用 fp32 / fp16 / int8 三个模型合成做三件事节奏检查把三段音频对齐播放听停顿位置与语速是否一致音色检查听音色的明亮度、共振峰是否偏移客观检查算三段音频的时长差、以及和参考fp32的波形相似度如 MSE。只有三项都过才能放心用低精度副本上板任何一项明显异常就退回更高精度。5.4 量化对体积/速度/质量的综合影响把 5.1 的三方表在真机上填实记录每个档位的模型体积磁盘、首次推理耗时、单句合成耗时、以及 5.3 的主观/客观评分。板子内存紧时int8 的体积优势可能直接决定装不装得下但一旦质量掉到不可接受体积优势就毫无意义。所以这张表是“能不能上”和“上哪个档”的联合判据。一个具体的填法示例数字为推算真机替换fp32 体积 300MB、首帧 260ms、单句 450ms、节奏评分 5/5int8 体积 80MB、首帧 180ms、单句 300ms、节奏评分 4/5 且有可察停顿偏移。当板子内存只够装 int8 时4/5 的节奏若产品可接受int8 就是答案若不可接受就要么换更小模型、要么接受保留部分云端。这张表的真正价值是把“上不上、上哪个档”从拍脑袋变成查表。六、流式策略边合成边播放6.1 为什么不能整段等完在语音对话里TTS 如果是整段合成完再播用户要等很久才听到第一个字。句级流式的做法是一句一句合成、合成完一句就播一句把首帧延迟压到可接受。6.2 句长与延迟的关系整轮合成耗时大致随句数线性增长。如果每轮对话合成 5–8 句每一句的固定开销初始化、文本前端、首帧都会被乘上句数。优化时有两个方向一是缩短不必要的固定开销二是把可并行的部分如提前对下一句做文本前端前移。这两个方向的共同前提是 6.4 的队列设计——如果队列不做背压优化单句耗时的收益会被上游突发灌入抵消所以 TTS 优化要和编排层的队列参数一起调。6.3 长度过长要切块超长文本一次性合成会占用大量内存并拉长首帧。常见做法是按标点切句逐句合成切句的同时要注意句尾停顿自然避免切成碎句后听起来像电报。切句逻辑要和 LLM 的输出节奏配合——LLM 边生成边吐句TTS 边收边合成两者用有界队列衔接见第一章骨架。一个切块的工作例以中文标点为切分依据句号/问号/感叹号作为强切分逗号作为弱切分弱切分累积到一定长度再切同时限制单句最大字数如 30 字防止超长。这样既能控制首帧又保留自然停顿避免切成碎句后听起来像电报。6.4 句级流式的队列设计沿用第一章的本地多线程 有界队列骨架TTS 环节的输入是 LLM 产出的文本句队列输出是音频队列喂给播放线程。关键参数有两个队列长度上限防止 LLM 突发吐很多句把内存堆满和背压策略队列满时 LLM 侧应暂停生成或丢弃最旧句。这两点和 VAD/ASR 的队列是同一套方法论整套链路的稳定性取决于每个环节都正确做了背压。6.5 实时性预算一句话要多少毫秒把 6.2 的句数 × 固定开销落成可算的数字。假设单次create的首帧约 200ms、单句合成约 400ms示意真机实测替换一轮对话合成 6 句则合成总耗时约 6 × 400 2400ms加上首帧 200ms 约 2600ms。这个数字要和 LLM 生成耗时叠加看——如果 LLM 生成 6 句花了 3000ms而 TTS 合成它们要 2600ms且两者是串行的整轮就要 ~5600ms。优化思路要么是并行LLM 出一句 TTS 合成一句要么是压 TTS 单句耗时见 4.3 声码器优化。所有数字为示意真机填入实测。七、音色取舍7.1 音色丰富度不如云端本地方案的音色数量通常少于云端 TTS 服务如 CosyVoice、EdgeTTS 之类。如果产品对角色音色要求高本地化可能要接受音色选择变少这一代价。若还想要品牌专属音色就要考虑能否用少量数据微调——而微调又带来训练与分发成本这要在选型时一并算进去而不是只看本地 TTS 免费这一面。7.2 自然度通常不如云端端侧小模型的韵律与自然度通常不敌云端的大模型 TTS。这不是缺陷是端侧方案的固有取舍必须写明。7.3 怎么写才诚实在对照表里同时给出本地 TTS和云端 TTS的音色数量与自然度主观评分并说明测量条件。优势离线可用、数据不出设备、零调用成本和边界音色少、自然度弱一起列比单写优势可信得多。写对照表时还建议加一列测量条件注明测试集、播放设备、板子温度——否则不同条件下的分数放一起比没有意义。诚实的对照不是比谁分数高而是让读者知道在你的场景下本地 TTS 能不能用、代价是什么。7.4 音色选择的方法不要凭名字挑音色。实务上把VOICES.md里的目标语言音色逐个合成同一段测试文本主观打分自然度、有无电音/破音、停顿是否自然选出 2–3 个稳定可用的作为产品默认音色池。这一步在真机上做因为同一音色在不同 ORT 版本/不同板子上的表现可能略有差异。7.5 韵律与标点TTS 的自然度很大程度来自韵律而韵律的输入常常是标点与句法。句号、逗号、问号对应的停顿长短不同缺失或错误的标点会让合成听起来像一口气念完。在 LLM 产出文本后、送进 TTS 前最好做一次标点规整补全缺失标点、把异常的长句按语义切分。这一步看似小事却常常是本地 TTS 听着比云端生硬的关键差异点之一——云端大模型的韵律建模更强本地小模型更依赖正确标点。八、集成路径8.1 挂回主链路把 kokoro-onnx 的合成函数封装成一个本地调用由编排层在 LLM 产出文本后调用。关键改动是原来调用云端 TTS 的base_url换成本地函数其余编排句级流式、边合成边播沿用第一章的骨架。8.2 改造前后差异改造前LLM → 云端 TTS网络 API → 播放 改造后LLM → 本地 TTSonnxruntime → 播放差异只有TTS 这一跳是否出设备。这一跳的消除正是离线可用与数据不出设备两条优势的直接来源。8.3 与第一章 LLM 编排的衔接第一章把 LLM 换成了本地 OpenAI 兼容服务链路此时是VAD→ASR→LLM(本地)→TTS(云端)→播放。本篇把 TTS 这环也换成本地后整条链路在编排上只剩本地调用 本地队列没有任何一环需要网络。衔接点就是 LLM 文本输出队列的下游消费者从云端 TTS 客户端换成本地 kokoro-onnx 调用——接口形态尽量保持一致输入文本、输出音频流让编排层无感切换。接 8.3一个串起整链路的计时草图数字为引用/推算真机替换LLM 首 token 300–600ms、后续每句生成约 500ms、TTS 每句首帧 200ms 加合成 400ms。若 LLM 与 TTS 串行一轮 6 句约 (600 6×500) (200 6×400) ≈ 3600 2600 6200ms若改为 LLM 出一句 TTS 合成一句的流水线瓶颈变为两者较慢者总耗时接近 max 侧而非求和。这说明串行 vs 流水线对整轮体感影响巨大是本地化后最该优化的架构点。第一章把 LLM 换成了本地 OpenAI 兼容服务链路此时是VAD→ASR→LLM(本地)→TTS(云端)→播放。本篇把 TTS 这环也换成本地后整条链路在编排上只剩本地调用 本地队列没有任何一环需要网络。衔接点就是 LLM 文本输出队列的下游消费者从云端 TTS 客户端换成本地 kokoro-onnx 调用——接口形态尽量保持一致输入文本、输出音频流让编排层无感切换。九、质量评估与对照实验9.1 主观评测怎么做得不走过场本地 TTS 的质量不能只靠我听着还行。一个可重复的主观评测找若干条覆盖不同句长、不同语气、含数字/专有名词的测试文本由 3 人以上独立打分维度包括自然度1–5、 intelligibility能否听清、韵律停顿是否自然。取平均分与方差方差大说明不稳定不能只看均值。多人评测之所以必要是因为单人的好听受个人口音偏好影响很大3 人以上独立打分取均值能抵消个体偏差。测试文本要覆盖不同情绪与句长因为 TTS 在长句、感叹句、疑问句上的韵律表现往往和陈述句不同。评测结果要记平均分 方差 最差样本最差样本往往比均值更能暴露问题。9.2 与云端 TTS 的对照表模板指标本地 kokoro-onnx云端 TTS如 CosyVoice测量条件音色数量待填看 VOICES.md待填—自然度主观 1–5待填待填同一测试集首帧延迟待填待填固定文本单句合成耗时待填待填固定文本是否出设备否是—调用成本0按量计费—上表实测列待真机填入发布前不许留空自然度为主观分要注明评测人数与测试集。9.3 控制变量对照时控制同一批测试文本、同一录音回放设备、相近板子温度。不要让本地在冷板子上测、云端在网络好的时候测这种变量污染结论。尤其延迟项本地要等板子温度稳定再测云端要标明网络往返。另外对照结论要写成在什么条件下本地 TTS 可替代云端而不是本地明显占优云端——本地 TTS 在离线/隐私/成本上占优在音色丰富度与自然度上通常让步这是条件化的取舍不是优劣。结论里把占优项和让步项并列读者才能照着自己的产品需求判断。9.4 评测要避免的偏差做主观评测时几个常见偏差要避开一是用自己的声音偏好打分应多人独立二是只测陈述句忽略了疑问/感叹/长句的韵律三是不记录测试集导致结论无法复现。客观评测也要避免只测首帧不测长句——长句才暴露内存峰值与韵律衰减。对照实验的价值在于可复现而可复现的前提是测试集、设备、条件都固定并写清楚。十、常见故障10.1 misaki 装不上或中文路径缺失misaki 是音素前端依赖版本不匹配或缺少中文支持时会报错。排查确认 misaki 版本与 kokoro-onnx 文档要求一致中文场景确认 misaki 的中文 g2p 可用否则换其他中文前端。漏装或版本错是最常见的合成报错源。10.2 音色文件版本错配voices-v1.0.bin要和kokoro-v1.0.onnx的版本匹配。模型升级后旧 voices 文件不兼容表现为加载报错或音色错乱。做法是模型与音色成对下载、成对升级并在 env.txt 记录两者的版本号。10.3 输出采样率与播放不一致模型输出采样率如 22050 或 24000要和播放设备支持的采样率对齐否则变调或播放失败。合成后若直接写 wav 播放没问题但若要经过其他音频管线要显式重采样到设备支持的速率。10.4 ORT 版本与算子和 A 类一样kokoro-onnx 依赖 ONNX Runtime。ORT 版本过旧可能缺模型用到的算子。板子上用不低于模型导出时依赖的 ORT 版本或按板子 ORT 重新导出。跨平台搬运时同一版本号也可能因构建选项不同而缺算子。10.5 内存峰值声码器在高采样率、长文本下内存占用会跳高。板子内存紧时用 5.4 的体积/速度表选更低精度并把长文本切块见 6.3来控制峰值。监控峰值用/proc/pid/status的 VmHWM而不是只看平均占用。10.6 多音字读错如前 4.6 所述多音字、数字、中英混读是中文前端高发问题。若合成出现明显读错先定位是前端g2p给的音素就错了还是模型阶段读错——把 g2p 的输出音素打印出来核对能快速区分。前者补前端词典/规则后者只能换模型或接受。10.7 中英文混读断点异常中英混读时前端若把英文词拆成字母逐个读、或把中文按英文规则处理会出怪音。排查要确认中英文的 g2p 分别正确且在语言切换处有合理的韵律边界。这一项要专门准备中英混读测试句。十一、选型决策什么时候本地 TTS 值得本地 TTS 不是对所有产品都划算决策看三件事离线/隐私是否是硬需求如果是如本地机器人、涉密场景本地 TTS 是必选项自然度和音色少都要接受。音色/自然度的下限是否可接受用 9.1 的评测确认本地 TTS 的自然度达到产品最低标准达不到就宁可保留云端或换更强的本地模型。板子资源是否装得下用 5.4 的体积表确认模型尤其全精度能装、内存峰值可控。三者都满足本地 TTS 就是理所当然的闭环一步任一不满足就退回到本地为主、云端兜底的混合这一架构在 B 类第 4 篇讲网关路由时会展开。11.4 选型检查清单把 11.1–11.3 收敛成一张清单换产品或换板子时照着打勾离线 / 隐私是硬需求吗是 → 本地必选本地 TTS 自然度达到产品下限了吗9.1 评测模型含全精度装得下、内存峰值可控吗5.4目标语言前端可用吗2.4 / 4.7音色池稳定可用吗7.4任一不满足考虑混合架构或换更强本地模型。这里说的换更强本地模型不是任意换——要回到 5.4 的体积/质量表看有没有体积可接受、质量达标的候选没有就接受混合架构本地为主、罕见/高难请求回退云端而不是硬撑一个不达标的纯本地方案。十二、常见问题FAQ问kokoro-onnx 许可证清晰吗清晰。README 的 License 小节写明代码为 MIT、模型为 Apache 2.0没有双许可陷阱采用前不必额外纠结。问中文 TTS 为什么要做音素前端因为模型接收的是音素/拼音而非汉字。中文必须先把汉字转成拼音或音素v1.0 起建议用 misaki g2p漏掉这一步要么报错要么读音全错。问量化后体积能小多少README 给出全精度约 300MB、量化后约 80MB 的标称量级但near real-time on macOS M1是特定硬件下的表述搬到开发板必须重测。问量化会影响合成质量吗会且不止体积。仓库提交明确记录量化副本的时长预测有差异只有全精度被验证输出一致。选型时要实测节奏与音色。问TTS 本地化后断网能用吗如果 LLM、VAD、ASR、TTS 全部本地化整条链路断网可用。TTS 是最后一跳它本地化之后闭环才真正成立。问本地 TTS 和云端 TTS 怎么公平对照用 9.2 的对照表控制同一测试集、同一播放设备、相近温度分别记自然度主观分、首帧、单句耗时、是否出设备、调用成本。不要只比延迟要把边界音色少、自然度弱一起列。问音色文件能和模型分开升级吗不建议。voices 与 onnx 版本要匹配模型升级后旧 voices 可能不兼容。两者成对下载、成对升级并在 env.txt 记录版本。问声码器慢能单独优化吗可以。声码器通常是耗时大头见 4.3优化重点应放在它换更快的声码器、降输出采样率、或对声码器做量化。前提是 5.3 的质量检查仍通过。问多音字和英文混读本地 TTS 容易错吗容易这是中文 TTS 的共性难点。测试集要专门准备多音字、数字、中英混读句逐句核对读音出错时先打印 g2p 音素区分是前端错还是模型错见 10.6。问标点会影响本地 TTS 的自然度吗会而且影响很大。缺失或错误的标点让合成失去韵律边界。LLM 文本送 TTS 前做一次标点规整常是听感变自然的关键一步见 7.5。问本地 TTS 能和云端混合用吗能。当本地自然度不达标或遇罕见语种时可让这部分请求回退云端架构见 B 类第 4 篇的网关路由。但要记住回退意味着该次数据出设备需按场景显式决策。问本地 TTS 在开发机如 Mac M1上跑得快板子上也一定快吗不一定。README 的near real-time on macOS M1是特定硬件表述M1 的 CPU 与神经引擎和 ARM 开发板不同。板子上的实际速度必须真机实测不能套用开发机数字。问多音字读错是模型问题还是前端问题两类都有可能。定位方法是打印 g2p 输出的音素如果音素本身就读错是前端g2p问题音素对但合成读错是模型问题。前者补前端词典后者换模型见 10.6。问kokoro 和 A 类里的 sherpa TTS 什么关系会不会重复不重复。两者是 TTS 这一环的不同实现sherpa 的 TTS 与 VAD/ASR 同库适合一个库收三环kokoro 是专门的轻量 TTS 封装适合单独替换 TTS 且做精度对照。按要不要和 ASR 同库要不要做 fp16/int8 实验来选见 2.7。问本地 TTS 合成时卡顿或首帧很长怎么查先按 4.4 的三段打点定位是前端、时长还是声码器慢再确认是否长文本未切块见 6.3、是否模型每次都重新初始化、以及板子是否降频。多数卡顿是长文本未切块与串行等待叠加按 6.5 的预算逐项核对。问本地 TTS 输出有杂音或电音可能是什么原因常见三类一是声码器量化int8引入的高频伪影回到 fp16/fp32 验证是否消失二是输出采样率与播放设备不匹配导致的重采样失真三是 ORT 版本/算子差异导致数值不稳定。按换精度→对齐采样率→换 ORT 版本的顺序排查比盲目调参数快。问本地 TTS 能不能做流式边合成边播能且这是推荐做法见 6.1。做法是句级流式LLM 边生成边吐句TTS 边收边合成边播放而不是等整段文本到齐再合成。前提是 LLM 的流式输出和 TTS 的句级切分配合好二者用有界队列衔接见 6.4。十三、总结与可带走物本篇把本地 TTS 这一环从动机讲到内部拆解替换动机是闭环保环内部拆解给出文本前端 / 时长预测 / 声码器三段精度拆解给出 fp32 / fp16 / int8 三档并点出量化改的不只是体积、还有时长预测这个真实坑。可带走的产出TTS 三段打点方法、三种精度对照表体积/速度/质量、与云端 TTS 的对照实验模板自然度/首帧/成本、句级流式的队列设计要点、什么时候本地 TTS 值得的决策框架、以及中文前端的多音字/数字/中英混读检查清单。最后落到一条本地 TTS 的优势离线、数据不出设备、零调用成本和边界音色少、自然度弱要一起写只写一边结论就立不住。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进