Moonshine 性能基准测试指南:用 benchmark 与 test-mobile-latency 量化实时语音延迟与计算负载
【免费下载链接】moonshineVery low latency speech to text, intent recognition, and text to speech, for building voice agents and interfaces项目地址: https://gitcode.com/GitHub_Trending/moonshine3/moonshine
本篇技术指南围绕 Moonshine 仓库的基准测试体系展开,涵盖核心库自带的benchmark二进制工具、移动端真机延迟测量脚本test-mobile-latency.sh,以及面向 Python 平台的 Moonshine 与 Whisper 对比脚本run-benchmarks.py。读完本文,你将掌握三个关键指标(处理耗时、计算负载百分比、响应延迟)的准确含义与测量方法,能够在自己硬件上复现官方对比表的数据,并理解流式模型为何在实时语音场景中具备延迟优势。
指标解读:三个数字分别意味着什么
官方基准的核心工具会模拟实时处理:加载一个.wav文件,按小分块把音频喂给模型,最终输出三个数字:
- 绝对处理时间:处理整段音频文件实际花费的墙钟时间(秒)。
- 计算负载百分比:处理时间占音频文件本身时长的百分比。它近似反映模型在你硬件上运行时占用的算力比例。例如显示
20%,意味着在你的应用中语音处理会占用五分之一的计算时间,其余 80% 留给你的业务代码。计算方式见 core/benchmark.cpp:transcription_percentage = (duration_seconds / wav_duration_seconds) * 100.0f。 - 平均延迟(Average Latency):单位毫秒,统计方式是累加每条 transcript line 的
lastTranscriptionLatencyMs再除以行数(见 core/benchmark.cpp)。
延迟指标需要特别说明:大多数语音应用真正关心的是“用户说完话之后,多久能收到这条短语的结果”,这决定了产品回应的速度。与任何 UI 一样,从语音结束到应用做出反应之间的时间决定了语音界面的响应感,业界经验目标是把这一数值控制在200ms 以下。这里记录的延迟,正是从库检测到用户停止说话,到该短语最终转录文本交付给客户端之间的平均时间。流式模型(Streaming)在这项指标上优势最大,因为它们在说话过程中就完成了大部分计算,通常能非常快地收尾。
构建并运行核心 benchmark 工具
在仓库根目录执行以下命令,从源码构建并运行基准工具:
cd core mkdir -p build cd build cmake .. cmake --build . --config Release ./benchmark默认情况下,benchmark二进制使用 Tiny English 模型和仓库test-assets目录下的two_cities.wav录音(这就是需要从构建目录运行的原因——它按相对路径回找../../test-assets/two_cities.wav)。运行结束后,输出类似(格式来自 core/benchmark.cpp):
Average Latency: 280ms Transcription took 5.26 seconds (11.34% of audio duration)可调参数
你可以用命令行参数指定自己的模型与音频:
| 参数 | 别名 | 说明 |
|---|---|---|
--model-path | -m | 已下载模型的目录路径,默认../../test-assets/tiny-en |
--model-arch | -a | 模型架构,取moonshine::ModelArch枚举的整数值,默认 Tiny(0) |
--wav-path | -w | 要处理的 WAV 文件,默认../../test-assets/two_cities.wav |
--transcription-interval | -t | 转录更新间隔(秒),默认 0.5 |
--keyterms | -k | 启用上下文关键词偏置的逗号分隔词表 |
--keyterms-file | — | 从文件读取关键词(逗号或换行分隔),适合较长的词表 |
--keyterm-boost | -b | 关键词偏置的 boost 值 |
参数解析与默认值见 core/benchmark.cpp。其中--transcription-interval控制转录更新的频率:间隔越长,计算量略有下降,但更新变慢;具体取值取决于你的应用需要多快的更新。模型文件的获取方式参见 下载模型。
关键词偏置相关参数值得一提:基准工具内置了对上下文偏置的测量支持。当关键词列表过长无法放在命令行时,可写入文件用--keyterms-file传入,工具内部会把换行/回车替换为逗号再交给库(见 core/benchmark.cpp),并在输出中统计实际保留的关键词数量。
移动端真机延迟:test-mobile-latency.sh
README 对比表中 MacBook Pro、Pixel 10a、iPad (A16) 三列的 Tiny / Small / Medium Streaming 延迟数据,使用与benchmark完全相同的指标,由 scripts/test-mobile-latency.sh 测量。该脚本的行为在文件头部注释中有完整说明(scripts/test-mobile-latency.sh):
- 从 CDN 下载模型,将
two_cities.wav以设备能处理的最快速度切成小分块喂入; - 对完成的每条 line 求
lastTranscriptionLatencyMs的平均值(解析逻辑见 scripts/test-mobile-latency.sh); - 通过 adb(Android)与
xcrun devicectl(iOS)自动发现连接的设备,也可用--android-serial与--ios-udid显式指定。
常用运行方式:
# 全部平台(macOS + Android + iOS) ./scripts/test-mobile-latency.sh # 只测当前 MacBook Pro 主机 ./scripts/test-mobile-latency.sh --macos-only # 附加上下文关键词偏置,对比偏置开销(结果落在 .mobile-latency/*-biased.log) ./scripts/test-mobile-latency.sh --keyterms "target_word,another_word" --keyterm-boost 5用 --update-readme 刷新对比表
重新测量并刷新 README 对比表:
./scripts/test-mobile-latency.sh --update-readme脚本只有当新平均值与已发布数值相差超过5%时才重写对应单元格(阈值常量见 scripts/test-mobile-latency.sh)。需要说明的是:
- 该命令写的是单次运行的结果。这对 iPad 没问题——连续三次运行误差在一毫秒以内;但 Mac 和 Pixel 波动较大,单次运行的结果不值得发布。
- 文档记录的原始数据是很好的复现参照:Medium Streaming 在 Mac 上三次运行介于 56–83ms,在 Pixel 上介于 383–432ms,主要取决于机器近期是否繁忙。已发布单元格是三次运行(期间让设备冷却)的中位数,因此单次运行与之略有出入属正常现象。
- Linux x86 和 Raspberry Pi 5 两列是单独测量的,且最后一次测量发生在 changelog 中记录的构建优化修复之前,因此目前读起来偏悲观,直到有相应硬件的人刷新它们。
在发布流程中,该脚本也会作为 scripts/build-all-platforms.sh 的一个 stage 运行(test-mobile-latency阶段,见 scripts/build-all-platforms.sh),并且可以在无硬件环境用MOBILE_LATENCY_OPTIONAL=1跳过。该脚本还要求scripts/fetch-voice-assets.sh预先拉取模型与音频资产。
与 Whisper 的对比:run-benchmarks.py
在支持 Python 的平台上,可以运行 scripts/run-benchmarks.py。它评估与上面相同类型的指标,优势在于会自动下载模型,无需操心路径处理;同时也评估同等规模的 Whisper 模型。
这是一个观点鲜明的基准,它审视两个模型家族在“许多常见实时语音应用需求”下的延迟与总计算成本:
- 用户说完一个短语后,需要尽快响应;
- 短语时长范围在 1 到 10 秒之间。
这与批量离线处理场景的需求截然不同——离线场景更看重系统整体吞吐量,单段语音的延迟反而不重要,因而可以采用批处理等优化手段。文档明确声明:并非否定 Whisper 在离线处理上的优秀表现,而是要突出 Moonshine 在具备实时延迟需求的实时语音应用中的优势。
实验设置
- 使用
two_cities.wav作为测试音频,因为它混合了短句与长句;可通过--wav_path参数换成自己的音频文件。 - Moonshine 侧使用 Tiny、Base、Tiny Streaming、Small Streaming、Medium Streaming 五个模型。
- Whisper 侧使用 Tiny、Base、Small、Large v3 四个模型。由于 Moonshine Medium Streaming 的 WER 低于 Whisper Large v3,因此将这两者配对比较;其余模型按同名规格一一对应。
- 使用 Moonshine VAD 分割器把音频切成短语,逐条喂给 Whisper 转写。
- 两方的响应延迟都定义为:VAD 判定短语结束,到转写文本返回之间的时间。对 Whisper 来说这就是完整的转写耗时;而 Moonshine 模型是流式的,说话过程中已完成大量工作,所以延迟低得多。
- 总计算成本的计算方式:把每个模型的音频处理耗时累加,再表示为总音频时长的百分比。这是常用实时因子(RTF)指标的倒数形式,反映的是实时应用所需的计算负载。
- Whisper 使用 faster-whisper 实现(
WhisperModel(model_size, "cpu", compute_type="int8")),因为它在跨平台性能上表现最好;测试固定在 CPU 上运行,因为大多数应用无法保证目标平台都具备 GPU/NPU 加速。仓库不否认存在大量优秀的 GPU/NPU 加速 Whisper 实现,只是认为它们对目标应用场景而言不够便携。
运行与输出
python scripts/run-benchmarks.py python scripts/run-benchmarks.py --wav_path path/to/your.wav python scripts/run-benchmarks.py --chunk_duration 0.48 --verbose脚本支持的参数(见 scripts/run-benchmarks.py):--wav_path(默认test-assets/two_cities.wav)、--chunk_duration(分块时长,默认 0.48 秒)、--verbose/-v、--options(以key=value逗号分隔传给库的附加选项)。
输出形如:
Moonshine tiny-en: latency=280ms, compute load=11.34% Whisper tiny: latency=1420ms, compute load=45.21%从实现上看,Whisper 的测量有一个值得注意的设计:Moonshine 侧直接累加 transcript line 的last_transcription_latency_ms;Whisper 侧则以skip_transcription选项让 Moonshine 只做 VAD 切分,再在on_line_completed回调里对每条短语调用 faster-whisper 转写并计时(见 scripts/run-benchmarks.py),从而保证两者共享同一套 VAD 短语切分,延迟口径一致。
实战建议:如何选择指标与测量方法
- 评估计算负载:使用核心
benchmark工具输出中的“百分比”。它直接告诉你模型会在你的 CPU 上占多大比例的算力,是估算“剩余算力能否支撑业务逻辑”的最快途径。 - 评估交互响应感:优先关注平均延迟,并与 200ms 的经验目标对照。流式模型因为边说话边计算,通常在这项指标上远优于非流式模型。
- 移动端与发布流程:使用
test-mobile-latency.sh,注意采用“三次测量取中位数、期间设备冷却”的方法学,单次运行结果仅作参考;用--update-readme刷新表格时会自动遵守 5% 差异阈值。 - 与 Whisper 横向对比:在 Python 环境直接运行
run-benchmarks.py,注意其延迟口径与计算负载定义与benchmark一致,便于横向比较。
以上三个测量入口共享同一套延迟语义(lastTranscriptionLatencyMs的平均值)与计算负载语义(处理耗时/音频时长的百分比),因此无论你通过 C++ 核心、移动端真机还是 Python 脚本测量,得到的数据都可以直接对照仓库 README 中的对比表。
【免费下载链接】moonshineVery low latency speech to text, intent recognition, and text to speech, for building voice agents and interfaces项目地址: https://gitcode.com/GitHub_Trending/moonshine3/moonshine
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考