语音转文字这件事,云端方案一直有两个绕不开的问题:一段会议录音要等上传、识别结果要等返回;公司内部资料、客户名字、私密对话又不太适合发到别人的服务器上。BetterWispr 走的是另一条路——把语音识别模型直接跑在 Mac 本地,按下快捷键说话,松手就把文字塞进当前光标位置,全程不联网(模型下载除外)。
下面是一套从零开始的完整流程。
适用场景
这套方案适合三类人:一是每天要写大量文字、颈椎不太行的职场人,用口述代替敲键盘;二是经常写代码注释、提交信息、PR 描述的开发者,中文夹英文的识别也扛得住;三是对隐私有要求、不想把语音上传到第三方服务的用户。它能替代 macOS 自带的听写功能,换来的是可自选模型、可自定义热词、可离线运行。
环境与前置条件
写在前面的重要提醒:BetterWispr 属于社区开源项目,安装方式、配置文件名、字段命名都可能随版本变化。下文给出的是一套通用流程和可以直接照抄的基础命令;凡是涉及仓库地址、模型下载脚本、配置文件字段名的地方,请以官方仓库当前说明为准,不要照搬旧教程。
硬件和系统要求:
- 系统:较新的 macOS(建议 Ventura 及以上,具体以官方 README 为准)。旧系统可能缺少新版语音框架或权限面板入口。
- 芯片:Apple Silicon(M 系列)体验明显更好,本地推理速度快、发热低。Intel Mac 也能跑,但建议只用 small 级别以下的小模型,否则边说话边等转写会很难受。
- 内存:8GB 可以跑 base / small 级别模型;16GB 起可以比较从容地用 medium 级别;想上 large 级别建议 24GB 以上。
- 磁盘:模型文件从几百 MB 到 3GB 左右不等,取决于模型大小和量化精度。预留 10GB 比较稳妥。
需要提前装好的东西:
- Xcode Command Line Tools(编译依赖、Python 头文件都要用)
- Homebrew(装 ffmpeg、git 等)
- Python 3.10 及以上(如果官方发布的是源码版而非 .app)
- 一枚顺手的快捷键。建议避开
Ctrl+Space(输入法切换)和Cmd+Space(Spotlight)
权限方面,装完之后需要开三个开关:麦克风、辅助功能(Accessibility)、输入监控(Input Monitoring)。少一个都会导致"快捷键按了没反应"。
分步骤部署
第 1 步:装好基础工具链
先确认 Xcode 命令行工具:
```bash
xcode-select -p
```
如果输出类似 /Library/Developer/CommandLineTools 就说明已装好。如果提示未安装,执行:
```bash
xcode-select --install
```
然后确认 Homebrew:
```bash
brew --version
```
没有输出的话,用官方脚本安装,装完按终端提示把 brew 加进 PATH:
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
接着装依赖:
```bash
brew install git ffmpeg cmake python
```
ffmpeg 会在后面用来录音测试和重采样,cmake 是编译本地推理后端用的。
第 2 步:获取 BetterWispr
先看一眼官方页面,确认当前推荐的安装方式是「下载预编译应用」还是「从源码构建」。如果官方提供 .dmg 或 .app,直接拖进「应用程序」文件夹就行,可以跳过本节剩下的内容。
源码方式:
```bash
mkdir -p ~/Developer && cd ~/Developer
git clone <官方仓库地址> betterwispr
cd betterwispr
cat README.md
```
把 <官方仓库地址> 换成官方页面上给出的 clone 地址。先读完 README 再动手,这一步能省掉后面大半的报错。重点关注三件事:安装命令、模型下载方式、配置文件放在哪。
如果是 Python 项目,通常是这样:
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e .
```
最后一行输出 Successfully installed ... 就算成功。如果项目是 Swift 写的,对应的通常是 swift build -c release,产物在 .build/release/ 下面。
第 3 步:下载本地模型
模型是识别质量的决定因素,也是内存占用的主要来源。常见的模型格式有 whisper.cpp 的 ggml-*.bin 和 faster-whisper 的 CTranslate2 目录,具体用哪种看官方支持。
下载方式以仓库说明为准,一般有三种:仓库自带的 scripts/download_model.sh 之类的脚本、make model 之类的构建目标,或者手动从 Hugging Face 拉:
```bash
pip install -U "huggingface_hub[cli]"
huggingface-cli download <模型仓库名> --local-dir ~/.cache/betterwispr/models
```
模型统一放在一个固定目录里(上面的路径只是示例,以官方约定为准),后面配置时直接指向这个目录。
模型怎么选,给一个实用的判断表:
| 模型级别 | 内存占用 | 适合场景 |
|---|---|---|
| tiny / base | 几百 MB | 快速口述短句、8GB 内存机器、纯英文 |
| small | 1GB 上下 | 日常邮件、聊天、英文为主的工作流 |
| medium | 1.5–2GB | 中文听写的主力选择,准确率和速度平衡 |
| large 系列 | 2–3GB+ | 长文口述、专业术语多、对准确率要求高 |
几条实践经验:
- 中文听写建议从 medium 起步。小模型在中文上的错误率会明显上升,尤其是同音字和专业名词。
- 量化版本是省内存的好办法。同一个模型有
q5_0、q8_0等不同量化精度,精度越低文件越小、速度越快,代价是准确率略降。8GB 机器上 medium 的量化版往往比 small 的完整版更划算。 - 英文场景可以直接用
.en结尾的英文专用模型,同样体积下英文准确率更高。 - 准备一份热词表。把公司名、同事名字、项目代号、常用变量名写进去,作为
initial_prompt传给模型,识别率会有肉眼可见的提升。
第 4 步:写配置文件
在项目目录或 ~/.config/betterwispr/ 下创建配置文件。字段名和层级以官方示例为准,下面只是常见形态:
```yaml
model: ~/.cache/betterwispr/models/ggml-medium.bin
language: zh
initial_prompt: "常见的专有名词写在这里,比如 Kubernetes、BetterWispr、产品代号"
hotkey:
push_to_talk: "ctrl+opt+space"
injection:
method: clipboard # 或 keystrokes
restore_clipboard: true # 注入后恢复原剪贴板
```
关键的两处说明:
快捷键。push_to_talk 是按住说话、松开转写,比按一下开始再按一下结束更符合直觉。选键时避开系统占用的组合。如果还想保留一个长录音用的模式,可以额外配一个 toggle 键。
文本注入方式。keystrokes 是模拟键盘逐个字符敲进去,兼容性最好,但在某些 Electron 应用里会丢字符;clipboard 是写进剪贴板再模拟 Cmd+V,速度快、长文本稳,代价是会临时占用剪贴板,所以要开 restore_clipboard 把原内容放回去。
第 5 步:授予系统权限
这一步最容易卡住,单独拎出来说。
打开「系统设置」→「隐私与安全性」,依次开启:
1. 麦克风 —— 不给就没法录音
2. 辅助功能 —— 不给就没法往其他应用里注入文字
3. 输入监控 —— 不给就监听不到全局快捷键
终端和 BetterWispr 应用本身可能都需要加进去,取决于你是从终端启动还是从访达启动。
顺便把系统的听写关掉,避免快捷键打架:「系统设置」→「键盘」→「听写」,关闭或改一个不冲突的组合键。
第 6 步:启动并设为开机自启
首次启动直接跑:
```bash
betterwispr
```
或者走源码入口 python -m betterwispr(具体入口名以官方为准)。确认能用之后,做成登录项:
```bash
cat > ~/Library/LaunchAgents/com.local.betterwispr.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.local.betterwispr</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/betterwispr</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict>
</plist>
EOF
launchctl load ~/Library/LaunchAgents/com.local.betterwispr.plist
```
把 ProgramArguments 里的路径换成 which betterwispr 的实际输出。用 LaunchAgent 而不是直接扔进登录项的好处是崩溃后会自动拉起。
验证部署是否成功
分三层验证,一层层排查。
第一层:麦克风能不能录到声音。 录 5 秒并播放:
```bash
ffmpeg -f avfoundation -i ":0" -t 5 -ar 16000 -ac 1 /tmp/test.wav
afplay /tmp/test.wav
```
如果 ffmpeg 报了设备列表错误,先执行下面这条看设备编号,把 :0 换成实际编号:
```bash
ffmpeg -f avfoundation -list_devices true -i ""
```
第二层:模型能不能转写。 用仓库提供的 CLI 入口转写刚才那段录音,具体命令以官方文档为准,常见形式是:
```bash
betterwispr transcribe /tmp/test.wav
```
预期结果是终端打印出一段文字,内容和你刚才说的话对得上。这一步能过,说明模型加载、音频解码、推理链路都是通的。
第三层:快捷键和文本注入能不能用。 打开「备忘录」或任意文本编辑器,把光标放进正文,按住 Ctrl+Opt+Space 说一句「今天下午三点开周会」,松开。预期在 1–3 秒内(取决于模型大小和句子长度)文字出现在光标处。
如果第一、二层都过、第三层不过,问题一定在权限或注入方式上,往下看报错部分。
常见报错与解决
报错 1:按下快捷键毫无反应,日志里也没有任何记录
原因:辅助功能或输入监控权限没给,进程收不到全局按键事件。
解决:打开「系统设置」→「隐私与安全性」→「辅助功能」和「输入监控」,把 BetterWispr 和终端都打开;改完权限后必须重启进程才生效。如果列表里已经有但就是不生效,重置后重新授权:
```bash
tccutil reset Accessibility
tccutil reset ListenEvent
```
报错 2:Operation not permitted 或录音直接返回全 0 数据
原因:麦克风权限未授予,或者授权给了终端但这个进程是从访达启动的,属于两个不同的主体。
解决:
```bash
tccutil reset Microphone
```
然后重新启动应用,在弹出的系统对话框里点「允许」。注意从访达启动和从终端启动,在系统眼里是两个不同的授权对象,别只给其中一个。
报错 3:文字被注入但缺字符、错位,或者只出来一半
原因:keystrokes 模式下注入速度太快,目标应用(尤其是 Electron 系的编辑器)处理不过来按键事件。
解决:改用剪贴板注入,或调大字符间隔:
```yaml
injection:
method: clipboard
restore_clipboard: true
```
如果必须用 keystrokes,把间隔调到 10–20 毫秒试试。另外,注入前先点一下目标输入框,确保焦点真的在文本框里。
报错 4:failed to load model / 模型加载失败
原因:配置里的模型路径写错了,或者文件下载不完整(网络中断导致下了一半)。
解决:先确认文件存在且体积合理:
```bash
ls -lh ~/.cache/betterwispr/models/
```
正常应该是几百 MB 到 3GB。如果只有几 KB 或者 0 字节,删掉重新下载。同时确认配置里的 ~ 有没有被正确展开,保险起见写绝对路径。
报错 5:中文识别成繁体,或者中英混杂时输出很奇怪
原因:没有显式指定语言,模型在自动检测时判断错了。
解决:在配置里写死:
```yaml
language: zh
initial_prompt: "以下是普通话的句子,可能夹杂英文技术名词。"
```
initial_prompt 不只是热词表,它同时也在告诉模型"接下来是什么风格的内容",对中英混说的场景帮助很大。
报错 6:首次打开提示「无法验证开发者」
原因:macOS 对未签名应用的 Gatekeeper 拦截。
解决:
```bash
xattr -dr com.apple.quarantine /Applications/BetterWispr.app
```
路径换成实际位置。
报错 7:command not found: brew,但确实装过 Homebrew
原因:Apple Silicon 上 Homebrew 装在 /opt/homebrew,默认不在 PATH 里。
解决:
```bash
eval "$(/opt/homebrew/bin/brew shellenv)"
```
把这一行写进 ~/.zshrc,以后新开终端就自动生效。
后续维护
备份。真正值得备份的只有两样:配置文件(热词表、快捷键、模型选择都在里面)和模型目录。模型文件体积大、可以随时重下,配置文件丢了要重新调一遍,所以重点备份配置文件:
```bash
cp ~/.config/betterwispr/config.yaml ~/Documents/betterwispr-config-$(date +%Y%m%d).yaml
```
升级。源码安装的话:
```bash
cd ~/Developer/betterwispr
git pull
source .venv/bin/activate
pip install -e .
```
升级前先备份配置,然后读一遍 release notes——字段改名、默认值变化这类改动经常发生在小版本里。升级后重启进程:
```bash
launchctl unload ~/Library/LaunchAgents/com.local.betterwispr.plist
launchctl load ~/Library/LaunchAgents/com.local.betterwispr.plist
```
日志。用「控制台」App 搜索进程名,或者直接看仓库约定
