本地文本转语音的规格表上,参数量是最不具预测性的一行。真正决定一个模型该不该装进你机器的,是同样输入下的实际耗时,以及语音转文字往返之后的词错误率。2026年10月20日,我在一台Mac mini上按这两项指标把TTS通道换了一遍:一个31.2M参数的模型接替了2.37B的旧模型,小模型在墙钟时间上快了2.6倍,散文样本经Whisper回转后词错误率为0.0%。
![]()
旧通道是跑在:8310端口上的Kyutai Pocket TTS中间层,torch运行时,ReLU-2.37B权重,缓存283 MB。挑战者是gradium/phonon-31m-en,31.2M参数,q8量化后64.5 MB,Rust运行时,整个链路里没有torch。同一台机器、同一段129字符的文本喂给两边:旧模型花0.96秒墙钟产出14.08秒音频,但它的WAV是压缩格式,Python的wave模块直接以unknown format: 3拒收,连一帧都数不了。Phonon花0.37秒产出6.64秒音频,76%有声帧,墙钟快2.6倍,输出长度约紧一倍,权重小了76倍。
这次替换只动了本地通道,没碰通话链路。旧中间层唯一的调用方是那条老式串联循环——语音转文字、进模型、再合成;实时通话走的是全双工云端语音,所以问题从来不是通话有没有变快,而是文本框背后由谁来应答。
模型本身
Phonon S 31M采用Apache-2.0许可,40M版本和多语言版本则挂在CC BY-NC和门控之后,音频一旦涉及商用,这个许可分界立刻生效。ptts 0.4.0的wheel把xn引擎和Mimi解码器打包成一个Python扩展,核心是Rust,输出24 kHz单声道16位。这和Pocket TTS通道原本用的编解码器同属一个家族,所以体积差异落在权重和运行时上,传输层是共用的。
机器上的实测数字
全部在16 GB Mac mini上纯CPU跑q8:RTF稳定在0.027到0.036,4.4秒音频用0.16秒墙钟,流式首块0.20秒,9个块覆盖那4.4秒,新进程加载热启动0.17到0.19秒、冷启动4.5秒,首块延迟8到23毫秒,完整CLI调用1.07到1.46秒。2026年10月22日我又跑了一遍,RTF 0.034,首块13毫秒,同一台机器,两次之间没有调过任何参数。
合成音频的可信度取决于回转出来的文本,所以每个样本都过了一遍whisper-large-v3-turbo打分。散文:Easton、Miles、Preston三个音色都是0.0%词错误率,逐字一致。一行口语数字:15%,错的地方是归一化,口语数字对上了阿拉伯数字。一行shell命令:50%,launchctl被听成launchtel,gui/1000被听成gkg slash 1000。
最后这行就是护栏。小模型只在你测过的领域里可信,代码和路径恰恰是失败的那个领域,所以随通道一起定下的规则是:别喂它代码,非喂不可时加--lang none。WAV本身是诚实的,68%到87%有声帧,最大振幅14k到18k,每一个里都是真实语音。
小模型输在哪
没能带过来的是克隆音色。旧中间层的音色由音频提示经get_state_for_audio_prompt派生,Phonon 0.4.0没有音频提示路径,add_voice要的是Gradium Studio导出的.safetensors,HF上的检查点不带说话人编码器,克隆得靠scripts/clone-voice.py对着样本录音跑。第一天的能力就是目录里的37个英文音色,13女12男12角色,总数102个。速度赢在这里,对等不是白送的,得等一次基于样本录音的重新克隆。
吃掉一周的三个坑
- 厂商服务器流式返回的WAV声称data块长度24932,实际文件更大,严格解析器直接拒收;mp3或pcm能活,pcm是无头16位单声道24 kHz。
- hermes config set拒绝tts.providers.*这种点路径,提示providers.phonon.type,加--force才写对,用yaml.safe_load验证过。
- 钉死的流式提供方指向一个已经死掉的端点,curl对它返回000,而resolve_streaming_provider从不为了拿到流式而切换提供方,这个钉死的配置每次调用都在捶那具尸体,直到我把它删掉,调度器才改走同步路径逐句朗读。
在接这些之前我先跑了厂商的现成服务器,docker run一个ptts-openai-server,/health返回{"status":"ok"},/v1/models报出gradium/phonon-31m-en,/v1/audio/voices列出37个英文音色,向/v1/audio/speech发一个voice为Easton的POST,0.67秒墙钟返回318,764字节,词错误率0.0%。那台服务器讲的正是旧中间层提供的同一套API,所以中间层最终的样子几乎是零代码。
最终落地
三份配置全部改成tts.provider: phonon,worker是一个遵守command-provider约定的CLI,文本写进临时文件,输出扩展名说了算,非零退出加stderr就是失败详情。默认音色Easton,美式男声,冲击感强、起音干脆。未知音色返回干净的OpenAI错误形状,比如unknown voice 'bender';这台服务器有Alfie等等,所以别名表集中放在一处。
两个门槛扛下了这个决定:墙钟2.6倍,散文0.0%词错误率,而且这两项在提交任何通道之前都是免费可测的。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.