`--mac-optimal-settings` 做了什么,又被什么覆盖
在 Apple Silicon 的机器上跑 speech-to-speech,最容易让人放松警惕的就是那一句 --mac-optimal-settings。名字里带着 optimal,看上去像是「打开它,剩下的交给项目」。但翻 README 会发现,官方对它的描述其实相当克制:它做四件事,而且这四件事只是默认值——你在命令行上显式写下的任何一个相关参数,都排在它前面。
这个优先级方向特别容易在脑子里搞反。很多人默认「专用预设应该压过通用参数」,于是一边加预设一边加设备参数,发现行为跟预期对不上,又回头怀疑是模型或环境的问题。这篇就把预设的边界、覆盖关系、命令写法和验收动作按仓库口径摆出来。
一、这个预设到底做了哪四件事
README 写得很具体,就四条:
- 对支持的模型组件使用 MPS 默认值
- STT 设为 Parakeet TDT
- LLM 后端设为 MLX LM
- TTS 设为 Qwen3-TTS,使用
mlx-audio,并默认取6bit的 MLX 变体
注意这四条里没有的东西同样重要:它不改端口,不改绑定地址,不动 VAD 的那些毫秒级参数,也不改并发数。换句话说,它是一个「换硬件路线」的开关,不是一个「调优」的开关。
参数本身在机器导出的参数清单里长这样:--mac_optimal_settings,类型 bool,默认 False。而 README 的命令示例里写的是连字符形式 --mac-optimal-settings。两种写法是不是都被接受,我们没有验证过——照抄 README 里的那条命令是最稳的做法,其余以 -h 的实际输出为准。
二、可以直接复制的三种写法
最短的一条,一个进程里既起服务又起自带的麦克风客户端:
speech-to-speech local --mac-optimal-settings
想同时指定本地 LLM 的模型:
speech-to-speech local \
--mac-optimal-settings \
--model_name mlx-community/Qwen3-4B-Instruct-2507-bf16
这两条都是 README 原文给出的。第二条里 --model_name 是显式参数,它会盖过预设那一档的默认选择——这正是下一节要讲的优先级规则在起作用。
第三种情况 README 也点名了:如果你只想把服务暴露出来、不想启动本机的麦克风客户端,那就把这个开关用在 serve 上,而不是 local 上。
speech-to-speech serve --mac-optimal-settings
以上为按官方参数语义组合的示例,未逐项实测,以官方文档与 --help 的实际输出为准。
local 与 serve 的区别不只是「带不带客户端」。README 明确写了绑定行为:serve 默认绑定 127.0.0.1,要暴露到网络必须显式传 --host 0.0.0.0;而 local 永远绑定环回,并把自带客户端连到 ws://127.0.0.1:<port>/v1/realtime,默认端口是 8765。
三、谁覆盖谁:一张优先级表
README 的原话是:预设只提供默认值。以下这些一旦你显式写出来,全部优先于预设——
--device(不设时默认None,设了则覆盖所有 handler 的设备)- 组件级设备参数,例如
--qwen3_tts_device --stt、--llm_backend、--model_name、--tts
把它和不开预设时的参数默认值放在一起看,覆盖关系就清楚了:
| 预设负责的那一项 | 显式覆盖它的参数 | 不开预设时的参数默认值 |
|---|---|---|
| STT 走 Parakeet TDT | --stt | "parakeet-tdt" |
| LLM 后端走 MLX LM | --llm_backend | "responses-api" |
TTS 走 Qwen3-TTS + mlx-audio | --tts | "qwen3" |
| MLX 量化取 6bit | --qwen3_tts_mlx_quantization | "6bit" |
| 组件使用 MPS 默认值 | --device / --qwen3_tts_device 等 | --device 为 None,--qwen3_tts_device 为 "cuda" |
这张表最值得停下来看一眼的是最后一行。参数导出里 --qwen3_tts_device 的默认值确实写着 "cuda",而它的 help 文本同时说明可选值是 cuda / cpu / mps / auto,并且「在 Apple Silicon 上会自动选择 mlx-audio 后端」。这两句话在实际运行时怎么共同起作用,我们没有跑过,不猜——但它至少解释了预设第一条「对支持的模型组件使用 MPS 默认值」为什么值得单独存在:在 Mac 上,一堆组件级参数的字面默认值并不是为你这台机器写的。
另外顺带一句 README 提到的:macOS 上 --tts pocket 与 --tts kokoro 同样可用。也就是说预设选的 Qwen3-TTS 不是唯一选项,你显式换掉它就换掉了。
四、「我明明设了却没生效」的两个来源
第一个来源就是上面这条优先级——方向搞反。你以为加了预设就锁定了 MLX 路线,结果命令行里还留着一个早年调试时写下的 --llm_backend,那么生效的是你写的那个,预设那一档被压掉了。排查动作很直接:把整条命令逐个参数读一遍,凡是出现在上面那张表第二列里的,全都是压过预设的。
第二个来源更隐蔽,来自 README 的另一条行为说明:CLI 只为选中的后端构造配置;未激活后端的已知选项仍然被接受,但会带警告地忽略。 JSON 配置同理,多余的非激活后端键会被忽略。
这意味着你写错了后端专属参数,程序不会报错停下,只会警告一声照跑。放到 Mac 预设这个场景里就更具体了:Qwen3-TTS 的量化不是一个开关而是两套——GGML 后端看 --qwen3_tts_ggml_quantization(默认 "BF16"),MLX 后端看 --qwen3_tts_mlx_quantization(默认 "6bit")。--qwen3_tts_backend 的 help 文本里也写明了,它是非 macOS 平台上 faster-qwen3-tts 的后端选择项,在 Apple Silicon 上 mlx-audio 会被自动选中、该选项被忽略。所以在开了预设的 Mac 上去调 GGML 那一侧的量化参数,属于典型的「调了个没被激活的旋钮」。
五、怎么验收
我们没有部署过这个服务,所以这里只给有依据的检查动作,不描述任何界面、日志文案或运行手感。
第一步,看这套组合下的参数默认值。 README 给的办法是 speech-to-speech serve -h;如果要看另一种组合的参数,把选择器放在 -h 前面,例如:
speech-to-speech serve --stt mlx-audio-whisper -h
这条是 README 原文给出的用法,也是判断「我这套配置最终生效的是什么」最省事的入口。
第二步,确认绑定与端口符合预期。 用 local 时它永远在环回上;用 serve 时默认也是 127.0.0.1。如果你没有显式写 --host,那么这个服务就不在局域网上——这一条在排查「同事连不上」时能省很多时间。
第三步,如果怀疑某个参数被忽略了,README 说这种情况会带警告。日志级别参数是 --log_level,默认 info,help 里给的示例是 --log_level debug。这条警告具体在哪个级别、以什么措辞打印,我们没有运行过,不替你描述——你自己起一次,把整段启动输出留着比对最可靠。
最容易出错的一步:把 --mac-optimal-settings 和一堆从别人 Linux 教程里抄来的参数混在一条命令里。那些教程默认的是 CUDA 路线,参数名往往落在预设不管的那一侧,混着写既不会报错,也不会按你想的方式生效。
六、什么情况下不该指望这个开关
你不在 Apple Silicon 上。 预设整条路线是 MPS / MLX,四件事里三件都指向 Mac 专属实现,非 macOS 平台上这个开关没有意义。
你要做中文。 这是对中文读者最要命的一条:预设把 STT 设成 Parakeet TDT,而按 README 的多语言矩阵,Parakeet TDT 覆盖的是 25 种欧洲语言。要做中文语音代理,必须显式换 STT——Whisper 系或 Paraformer。README 给的中文示例是:
speech-to-speech serve \
--stt whisper-mlx \
--stt_model_name large-v3 \
--language zh \
--llm_backend mlx-lm \
--model_name mlx-community/Qwen3-4B-Instruct-2507-bf16
README 说这类命令都能配合 --mac-optimal-settings,显式的 --stt 会覆盖预设。换句话说,中文场景下预设仍然可以留着——它负责设备那一档,你负责把 STT 抢回来。顺带一提,--language 的默认值是 en。
你要给多个人同时用。 --num_pipelines 默认是 1,预设不碰它。这是做多用户部署时第一个要动的参数,跟 Mac 与否无关。
你要把服务暴露到网络。 预设与安全无关,别把它当成任何形式的加固。如果确实要传 --host 0.0.0.0,请如实记住 README 自己的声明:服务端自己不做任何认证,也不做任何限流,只应在受信网络上启用,或者把服务部署在一个自己掌管访问控制的网关后面。这句话我们原样转述,不做延伸,也不认为配好某几项就安全了。
你想知道哪种量化更划算。 仓库自带一个对比 MLX 量化变体的脚本:
python scripts/benchmark_tts.py \
--handlers qwen3 \
--iterations 3 \
--qwen3_mlx_quantizations bf16 4bit 6bit 8bit
我们没有跑过它,因此这篇不会给出任何跑分、延迟或音质结论。预设默认取 6bit 是仓库的选择,不是我们验证过的结论;要不要改成别的,用这个脚本在你自己的机器上得数据,比看任何文章都靠谱。
延伸阅读
本文依据 speech-to-speech 官方仓库(github.com/huggingface/speech-to-speech)的 README、
src/speech_to_speech/arguments_classes/ 下的参数定义与 Realtime Engine 架构文档整理,核对日 2026-08-09。
本文内容为仓库源码与文档口径,我们没有安装、部署或调用过该服务,文中毫秒值均为参数默认值而非实测延迟。
参数与默认值随版本变动,请以 speech-to-speech serve -h 的实际输出为准。
安全相关做法请结合自身环境评估,本文不构成安全方案建议。