@cosformula/openclaw-mlx-audio
v0.1.14
Published
OpenClaw local TTS plugin powered by mlx-audio — zero API key, zero cloud dependency
Maintainers
Readme
openclaw-mlx-audio
OpenClaw 本地语音合成插件,基于 mlx-audio 在 Apple Silicon 上运行。
MLX 与平台兼容性
MLX 是 Apple 为 M 系列芯片设计的机器学习框架,针对其统一内存架构优化。本插件依赖 MLX,因此仅支持 Apple Silicon Mac(M1 及以后)。
不适用于 Intel Mac、Windows 或 Linux。这些平台可考虑:
- openedai-speech(自托管,需 NVIDIA GPU)
- Chatterbox-TTS-Server(同上)
- OpenClaw 内置 Edge TTS(云端,无需 GPU)
系统要求
- macOS,Apple Silicon(M1 及以后)
- 默认
pythonEnvMode: managed无需预装 Python 或 Homebrew,插件会自举uv与基于 lockfile 的本地 Python 运行时 - 可选
pythonEnvMode: external,通过pythonExecutable复用已有 Python 环境 - OpenClaw
快速开始
告诉你的 OpenClaw:
安装 @cosformula/openclaw-mlx-audio 插件,把 TTS 切到本地,重启生效。
OpenClaw 会自动完成插件安装、配置修改和重启。
如需中文 TTS(Qwen3-TTS):
安装 @cosformula/openclaw-mlx-audio 插件,把 TTS 切到本地,用 Qwen3-TTS-0.6B,重启生效。
手动安装
1. 安装插件
openclaw plugin install @cosformula/openclaw-mlx-audio或在 openclaw.json 中从本地路径加载:
{
"plugins": {
"load": { "paths": ["/path/to/openclaw-mlx-audio"] }
}
}2. 配置插件
在 openclaw.json 的 plugins.entries.openclaw-mlx-audio.config 中设置:
{
"plugins": {
"entries": {
"openclaw-mlx-audio": {
"enabled": true,
"config": {}
}
}
}
}默认配置使用 Kokoro-82M,langCode 默认为 auto(Kokoro 自动语言检测)。如需中文并使用 Qwen3-TTS,设置 model:
{
"config": {
"model": "mlx-community/Qwen3-TTS-12Hz-0.6B-Base-bf16",
"workers": 1
}
}3. 将 OpenClaw TTS 指向本地端点
{
"env": {
"vars": {
"OPENAI_TTS_BASE_URL": "http://127.0.0.1:19280/v1"
}
},
"messages": {
"tts": {
"provider": "openai",
"openai": { "apiKey": "local" }
}
}
}4. 重启 OpenClaw
插件启动时会自动完成以下步骤:
- 在配置的
port启动代理服务(默认19280) - 在内部派生端口启动
mlx_audio.server(默认19281) - 若
autoStart: true,后台预热 mlx-audio 服务 - 若
autoStart: false,在首次/v1/audio/speech、GET /v1/models、toolgenerate或/mlx-tts test时拉起服务 - 启动链路要求上游
/v1/models在约 10 秒内通过健康检查,否则该请求返回不可用,下次请求再重试启动 - 若
pythonEnvMode: managed,首次运行时将uv安装到~/.openclaw/mlx-audio/bin/uv,随后根据内置pyproject.toml与uv.lock同步~/.openclaw/mlx-audio/runtime/,并通过uv run --project ...启动服务 - 若
pythonEnvMode: external,启动前校验pythonExecutable(Python 3.11-3.13 且可导入关键依赖)并直接使用该环境
服务运行期间会后台轮询配置并自动应用(约每 2 秒一次)。也可执行 /mlx-tts reload(或 tool action reload)立即热更新,无需重启 OpenClaw 网关。
首次启动需下载模型(Kokoro-82M 约 345 MB,Qwen3-TTS-0.6B-Base 约 2.3 GB)。启动阶段可通过 /mlx-tts status 与 tool status 查看启动阶段和模型缓存近似下载进度(文本进度条 + 百分比)。若启动超时,返回给 OpenClaw 的 503 detail 也会包含相同状态信息。模型下载完成后不再需要网络连接。
模型
默认模型为 Kokoro-82M。以下是按使用场景筛选的模型:
| 模型 | 说明 | 语言 | 链接 | |---|---|---|---| | Kokoro | 轻量多语言 TTS,54 种预设音色 | EN, JA, ZH, FR, ES, IT, PT, HI | Kokoro-82M-bf16 | | Qwen3-TTS Base | 阿里巴巴多语言 TTS,支持 3 秒参考音频声音克隆 | ZH, EN, JA, KO 等 | 0.6B-Base-bf16 | | Qwen3-TTS VoiceDesign | 通过自然语言描述生成音色 | ZH, EN, JA, KO 等 | 1.7B-VoiceDesign-bf16 | | Chatterbox | 表现力丰富的多语言 TTS | EN, ES, FR, DE, IT, PT 等 16 种语言 | chatterbox-fp16 |
mlx-audio 还支持 Soprano、Spark-TTS、OuteTTS、CSM、Dia 等模型,完整列表见 mlx-audio README。
Qwen3-TTS 模型变体
| 变体 | 说明 | |---|---| | Base | 基础模型,支持通过 3 秒参考音频进行声音克隆,可用于微调 | | VoiceDesign | 根据自然语言描述生成音色(如"低沉的男声,带英式口音"),不接受参考音频 | | CustomVoice | 提供 9 种预设音色,支持通过指令控制语气和风格 |
目前 mlx-community 提供了 0.6B-Base 和 1.7B-VoiceDesign 的 MLX 转换版本。
选型参考
内存占用参考:
| 模型 | 磁盘 | 内存(1 worker) | |---|---|---| | Kokoro-82M | 345 MB | ~400 MB | | Qwen3-TTS-0.6B-Base | 2.3 GB | ~1.4 GB | | Qwen3-TTS-1.7B-VoiceDesign | 4.2 GB | ~3.8 GB | | Chatterbox | ~3 GB | ~3.5 GB |
对于 Chatterbox,运行时建议按约 3.5 GB 内存(1 worker)规划。
- 8 GB Mac:Kokoro-82M 或 Qwen3-TTS-0.6B-Base,
workers设为 1。1.7B 及以上的模型会因内存不足被系统终止。 - 16 GB 及以上:所有模型均可运行。
- 中文:Qwen3-TTS 系列。Kokoro 支持中文但合成质量不如 Qwen3-TTS。
- 英语:Kokoro-82M 体积最小,延迟最低。
- 多语言:Chatterbox 覆盖 16 种语言。
语言代码(仅 Kokoro)
langCode 仅对 Kokoro 生效。Qwen3-TTS 会根据文本自动识别语言,其他模型会忽略该字段。
当 langCode: auto 时,当前只会识别为 a、z、j。
| 代码 | 语言 |
|---|---|
| a | 美式英语 |
| b | 英式英语 |
| z | 中文 |
| j | 日语 |
| e | 西班牙语 |
| f | 法语 |
音色
Kokoro 内置 50+ 预设音色:
| 类别 | 示例 |
|---|---|
| 美式女声 | af_heart, af_bella, af_nova, af_sky |
| 美式男声 | am_adam, am_echo |
| 中文女声 | zf_xiaobei |
| 中文男声 | zm_yunxi |
| 日语 | jf_alpha, jm_kumo |
Qwen3-TTS Base 通过参考音频(refAudio)克隆音色。VoiceDesign 通过自然语言描述(instruct)生成音色。
未指定时使用模型默认音色。
配置项参考
所有字段均为可选:
| 字段 | 默认值 | 说明 |
|---|---|---|
| model | mlx-community/Kokoro-82M-bf16 | HuggingFace 模型 ID |
| port | 19280 | 对外 OpenAI 兼容 TTS 端点端口(OPENAI_TTS_BASE_URL) |
| proxyPort | | 兼容旧配置字段。设置后按旧语义运行,即 port 作为 server 端口,proxyPort 作为对外端口 |
| workers | 1 | Uvicorn worker 数 |
| speed | 1.0 | 语速倍率 |
| langCode | auto | Kokoro 专用语言代码。Qwen3-TTS 根据文本自动识别,其他模型忽略该字段 |
| refAudio | | 参考音频路径(声音克隆,仅 Base 模型) |
| refText | | 参考音频对应文字 |
| instruct | | 音色描述文本(仅 VoiceDesign 模型) |
| temperature | 0.7 | 生成温度 |
| topP | 0.95 | Nucleus sampling 参数(top_p) |
| topK | 40 | Top-k sampling 参数(top_k) |
| repetitionPenalty | 1.0 | 重复惩罚参数(repetition_penalty) |
| autoStart | true | 随 OpenClaw 自动启动 |
| healthCheckIntervalMs | 30000 | 健康检查间隔(毫秒) |
| restartOnCrash | true | 崩溃后自动重启 |
| maxRestarts | 3 | 最大连续重启次数 |
架构
OpenClaw tts() -> 代理 (:port,默认 19280) -> mlx_audio.server (:内部端口,默认 19281) -> Apple Silicon GPU
^ 注入 model、lang_code、speed、temperature、top_p、top_k、repetition_penalty、response_format=mp3OpenClaw 的 TTS 客户端使用 OpenAI /v1/audio/speech API。mlx-audio 需要的额外参数(完整模型 ID、语言代码等)不在 OpenAI API 规范中。
代理拦截请求,注入配置参数(model、lang_code、speed、temperature、top_p、top_k、repetition_penalty),并强制 response_format: "mp3" 后转发至 mlx-audio 服务。OpenClaw 侧无需改动,代理对其表现为标准 OpenAI TTS 端点。
对于 POST /v1/audio/speech,请求体超过 1 MB 时返回 HTTP 413。
如果下游客户端在响应完成前断开,代理会立即取消上游请求。
插件同时管理服务生命周期:
managed模式下,自举本地uv工具链,按内置pyproject.toml与uv.lock同步依赖,并使用~/.openclaw/mlx-audio/runtime/.venv/external模式下,仅校验并使用pythonExecutable指向的环境,不修改用户环境- 以子进程方式启动 mlx-audio 服务
- 崩溃自动重启(健康运行 30 秒后重置计数)
- 启动前清理端口上的残留进程
- 启动前检查可用内存,识别 OOM kill
- 跟踪启动阶段和模型缓存近似下载进度,并在
/mlx-tts status、toolstatus和启动超时错误中暴露 - 限制 tool 输出路径仅允许
/tmp或~/.openclaw/mlx-audio/outputs,使用异步文件系统检查校验 realpath,并拒绝符号链接路径段 - 生成音频采用流式写盘,并拒绝超过 64 MB 的响应,避免内存峰值增长
故障排查
服务连续崩溃 3 次后停止重启
查看 OpenClaw 日志中的 [mlx-audio] Last errors:。常见原因:Python 依赖缺失、模型名称错误、端口冲突。修复后修改任意配置项可重置崩溃计数。
SIGKILL
日志中出现 ⚠️ Server was killed by SIGKILL (likely out-of-memory),表明系统因内存不足终止了进程。应更换为更小的模型或将 workers 设为 1。
端口占用
插件启动时只会清理残留的 mlx_audio.server 进程。如果目标端口被其他程序占用,请手动停止该程序,或修改 port:
# 1) 先确认对外端口被谁占用(单端口模式下内部 server 端口为 +1)
/usr/sbin/lsof -nP -iTCP:19280 -sTCP:LISTEN
# 2) 仅在确认是 mlx_audio.server 后,优先优雅终止
kill -TERM <mlx_audio_server_pid>启动健康检查超时
若日志出现 Server did not pass health check within 10000ms,表示启动阶段未在预期时间内通过健康检查。错误详情会附带启动阶段和模型缓存近似进度。常见原因包括首次依赖/模型预热较慢、模型名错误、或 external 模式依赖不完整。修复后再次触发请求即可重试启动。
首次启动耗时较长
模型正在下载。Kokoro-82M 约 345 MB,Qwen3-TTS-0.6B-Base 约 2.3 GB。
致谢
License
MIT
