`--mac-optimal-settings` 做了什么,又被什么覆盖

2026-08-09

在 Apple Silicon 的机器上跑 speech-to-speech,最容易让人放松警惕的就是那一句 --mac-optimal-settings。名字里带着 optimal,看上去像是「打开它,剩下的交给项目」。但翻 README 会发现,官方对它的描述其实相当克制:它做四件事,而且这四件事只是默认值——你在命令行上显式写下的任何一个相关参数,都排在它前面。

这个优先级方向特别容易在脑子里搞反。很多人默认「专用预设应该压过通用参数」,于是一边加预设一边加设备参数,发现行为跟预期对不上,又回头怀疑是模型或环境的问题。这篇就把预设的边界、覆盖关系、命令写法和验收动作按仓库口径摆出来。

一、这个预设到底做了哪四件事

README 写得很具体,就四条:

  1. 对支持的模型组件使用 MPS 默认值
  2. STT 设为 Parakeet TDT
  3. LLM 后端设为 MLX LM
  4. 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 的实际输出为准。

localserve 的区别不只是「带不带客户端」。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--deviceNone--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 的实际输出为准。 安全相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。