一个「错误」的直觉,做成了产品
语音转写这件事,过去十年的标准打法非常固定:拿一个声学编码器,接一个 CTC 或者注意力解码器,用几千小时甚至几万小时的标注语音训练,最后得到一个「语音进、文本出」的专用模型。Whisper、Parakeet、Granite Speech 全是这条路。
而 Embedding Gemma Transcribe(eg2.haku.sh 上发布的免费 Mac 应用)走的完全是另一条路:它的底层模型从头到尾没有被训练去做语音转写。Google 的 EmbeddingGemma 2 是一个多模态嵌入模型——它的本职工作是把文本、图片、音频、视频统统映射进同一个向量空间,让「语义相近的东西在空间里相邻」。作者团队的洞察是:既然你对着麦克风说一个词时,这段音频的向量天然落在那个词的文本向量附近,那为什么不直接「在这个空间里查词」?
这个想法听起来像民科,但实测数据相当硬:在 8GB 内存的 base M3 MacBook Air 上,一小时的音频约 12.6 秒转完,也就是 288 倍实时,全跑在 Neural Engine 上,模型加起来 715MB,音频不离开机器。这篇实战文章拆解它的完整原理、和主流方案的对比,以及如果你想在它基础上动手(比如做中文版),路径长什么样。
技术拆解:四层流水线,只有一层是训练出来的
整个系统的架构可以拆成四步,关键在于每一步只做一件小事:
- 音频编码器原封不动。EmbeddingGemma 2 自带的 audio encoder 负责把音频切成短片段并编码成向量,这一层的权重完全冻结,一字未改。
- 一个很小的 reader 做空间映射。reader 的唯一职责是把每个音频切片的向量「搬」进模型的文本空间——注意不是生成文本,而是搬到一个位置,让这个位置正好靠近该切片对应的单词。整个系统里只有这个 reader 被训练。
- 最近邻查词。映射后的向量在一个约 22.9 万英文单词的词表里做最近邻检索,每个切片选出一个词,切片序列连起来就是转写稿。
- 一个微型后处理模型补标点。查词得到的是全小写、无标点的词流,最后接一个小模型补上标点和大小写。
训练成本是这个方案最反直觉的部分:reader 只用了 8 张 H100、不到两小时,训练数据是全部开放授权的英文语音。没有任何一步需要动基础模型。这意味着同样的流程可以被任何人复刻到其他语言上——这一点我们最后细说。
为什么这个做法在工程上成立?因为 EmbeddingGemma 2 的多模态对齐训练已经替你完成了最难的部分:「这个声音」和「这个词」在空间里的对应关系,模型早就知道了。传统 STT 模型要用海量数据从零学这个映射,而这里只需要学一个轻量的「空间校正」。
实测对比:速度第一梯队,精度暂时落后
从官方基准页的表格看,同规格硬件下它是目前 Mac 上最快的转写方案之一:
| 模型 | 推理路径 | 设备 | 速度(× 实时) |
|---|---|---|---|
| Embedding Gemma Transcribe | Neural Engine | base M3 MacBook Air, 8GB | 288×(1 小时 12.6 秒) |
| IBM Granite Speech 5.0 Turbo CTC | GPU (MLX) | base M3 MacBook Air, 8GB | 约 150×(1 小时 25.7 秒) |
| NVIDIA Parakeet TDT 0.6B v3 | Neural Engine | M4 Pro | 156× |
| NVIDIA Parakeet TDT 0.6B v3 | Neural Engine | M5 Pro | 335× |
| Phonon-2(Parakeet v3 微调) | Neural Engine | M5 Pro | 480× |
需要强调,后三行数据来自 FluidAudio 在更新、更大的机器上的公开基准,音频样本也不同,官方自己也标注这是「粗略参考而非严格对位排名」。但结论清晰:在入门级 MacBook Air 上,它的速度比同机 GPU 方案快约一倍,这主要归功于查词式解码的计算量极低——没有自回归生成,没有束搜索,每切片就是一次矩阵乘加一次最近邻。
精度方面目前是短板:WER 约 5%,而主流语音模型在 2% 到 3%。作者的归因也很坦率:不是方案不行,是 reader 训练得还不够好,下一迭代目标就是收窄这个差距。从工程角度看这个精度水平已经跨过了「能用」的门槛——会议笔记、语音输入这类场景里,用户本来就会实时扫视输出。
上手:五分钟跑起来
应用从 eg2.haku.sh 免费下载(v1.6,要求 macOS 14+ 与 Apple Silicon),首次启动会下载 715MB 的模型。两种用法:
- 文件转写:拖入音频文件,进度条基本是装饰品——一小时录音在 M3 Air 上十几秒完成。
- 全局听写:按住 Right Option 键说话,松开后文本直接键入当前应用。这个模式跑在 Neural Engine 上,延迟低到没有「等待感」,而且音频全程不出机器——对着它念密码短语和财务数字,与对云端 API 念是两种隐私模型。
如果你想在它的思路上做二次开发,核心流程可以抽象成一段伪代码:
# reader 伪代码:把音频切片映射进文本空间并查词
words = load_vocabulary() # 约 229k 英文单词的文本嵌入矩阵
for chunk in slice_audio(audio, chunk_len=0.25):
emb = frozen_audio_encoder(chunk) # 原封不动的 EmbeddingGemma 2 编码器
emb_text = reader(emb) # 唯一被训练的映射层
idx = nearest_neighbor(emb_text, words)
tokens.append(words[idx])
transcript = punctuator(" ".join(tokens)) # 微型模型补标点
真正值得动手的扩展是中文版。词表换成中文词元表,训练数据换中文语音语料,reader 的训练成本依然是「8 张 H100 不到两小时」的量级——如果用租用算力折算,成本大约是一次重度超参搜索的价格。难点不在训练,而在中文没有像英文那样现成的、大规模开放授权的「音频-词元」对齐数据集,需要自己花时间整理。
它真正的意义:嵌入空间是未充分开采的资产
把视线从产品拉远一点,这个项目演示了一个更通用的模式:多模态嵌入模型里藏着大量「免费的下游能力」,大多数团队只用它做检索相似度。音频编码器与文本空间的桥梁已经在预训练时架好了,谁都可以在上面接一个便宜的映射层,得到一个原本要几万小时数据才能训出来的系统。
同样的思路可以套在别处:视频切片→文本空间可以做「画面内容的时间轴索引」;图文空间里可以做零样本地检测画面里的物体类别。这些都未必比专用模型精度高,但当「够用的精度 × 十倍的速度 × 本地隐私」组合在一起时,打开的是一批过去因为云端成本或隐私限制而根本不存在的场景。
顺带一提它的局限清单,动手前先看清边界:仅支持英文;WER 5% 对字幕级精度的场景不够;长音频的说话人分离(diarization)没有做,多人对话会混在一起。它是把「快、小、本地」做到极致的专用工具,不是 Whisper 的全能替代品。
对开发者来说,最有价值的一课或许是:当你面对一个大模型时,先问一句「它的哪个空间已经在预训练里学好了」,而不是「我要用什么数据把它再训一遍」。前者只需要两小时和 8 张卡,后者是一个季度。