目录

端侧语音识别实战:用 sherpa-onnx 让应用离线听懂中文

为什么要在端侧跑语音识别

智能音箱、会议纪要工具、车载语音助手、儿童故事机——这些场景的语音输入都有一个共同痛点:把音频上传云端识别,既慢又贵,还涉及隐私。端侧语音识别(On-Device ASR)把模型直接跑在设备 CPU 上,离线可用、零延迟感、音频不出设备。

过去端侧 ASR 门槛很高,但 2026 年的今天,一个 14M 参数、24MB 的 int8 模型就能在普通 CPU 上做到快于实时 20 倍的中文识别。这篇文章用 sherpa-onnx 完整跑通一遍,附真实性能实测。

开源方案怎么选

项目 适用场景 特点
sherpa-onnx (k2-fsa) 生产级端侧 ASR/TTS/唤醒词全栈 支持 Zipformer/Paraformer/Whisper 等 20+ 模型,提供 C++/Python/iOS/Android 全套 API,本文主角
whisper.cpp 追求最强离线识别精度 OpenAI Whisper 的 GGML 移植,多语言通用,但模型偏大、流式支持弱
Vosk (alphacep) 快速原型、小语种 Kaldi 系轻量模型,API 极简,中文模型约 40MB
openWakeWord 自定义唤醒词 纯 PyTorch 训练自己的唤醒词,轻量
Porcupine(Picovoice) 商用唤醒词/语音控制 精度高但模型不透明,免费额度有限

怎么选:要全流程生产化选 sherpa-onnx;只看重离线转写精度选 whisper.cpp;只是想快速验证想法选 Vosk。端侧项目优先考虑模型体积与推理框架的绑定成本,sherpa-onnx 的 ONNX 生态迁移成本最低。

10 行代码跑通中文识别

安装只需一个 pip 包(1.13.x 已内置全部模型格式支持):

1
2
3
pip install sherpa-onnx soundfile
# 下载官方预转好的 int8 离线中文模型(287MB 压缩包,内含 int8 量化模型与测试音频)
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-zipformer-ctc-zh-int8-2025-07-03.tar.bz2

识别代码(离线模式,整段音频一次转写):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import sherpa_onnx
import soundfile as sf

# 加载 int8 量化模型(Zipformer CTC 架构)
recognizer = sherpa_onnx.OfflineRecognizer.from_zipformer_ctc(
    model="./sherpa-onnx-zipformer-ctc-zh-int8-2025-07-03/model.int8.onnx",
    tokens="./sherpa-onnx-zipformer-ctc-zh-int8-2025-07-03/tokens.txt",
)

audio, sample_rate = sf.read("test.wav", dtype="float32", always_2d=True)
stream = recognizer.create_stream()
stream.accept_waveform(sample_rate, audio[:, 0])  # 单声道
recognizer.decode_stream(stream)
print(stream.result.text)  # 输出转写文本

不需要对齐采样率:sherpa-onnx 内部会自动把 8kHz 电话音频重采样到 16kHz。这个模型是 2025-07-03 发布的 Zipformer CTC 架构,官方 WER 数据(字错误率):AISHELL 测试集 1.74%,WenetSpeech test_net 测试集 5.92%,日常口语场景完全够用。

流式模型实测:小模型 + 单线程才是最优解

流式(边录音边出字)才是语音助手的日常形态。实测选用官方最小的中文流式模型 sherpa-onnx-streaming-zipformer-zh-14M,14M 参数,int8 量化后三件套(encoder/decoder/joiner)总大小:

  • encoder int8:20.6MB(fp32 为 39.1MB)
  • decoder + joiner int8:3.5MB
  • 合计约 24MB,比 fp32 省 55%

测试环境:Intel N100 处理器(4 个 E-core)、容器内 Linux、sherpa-onnx 1.13.4、CPU 推理。用官方 test_wavs(15.3 秒中文音频)实测:

线程数 计算耗时 RTF(实时率) 结论
1 0.71s 0.046 快于实时 20 倍
4 3.44s 0.225 反而慢 5 倍

反直觉但真实的结论:对这种 14M 小模型,多线程是负优化——线程同步开销远超并行收益,N100 的 E-core 还共享 L2 缓存。端侧小模型请从 num_threads=1 起步,别学服务器大模型的调参套路。

集成到设备

  • iOS:官方提供 xcframework 与 Swift Package Manager 支持,配合 AudioKit 采集麦克风即可离线转写
  • Android:提供 AAR 包,Java/Kotlin API 与 Python 完全对齐
  • 嵌入式:C API 无依赖,树莓派 Zero 级别硬件可跑 zh-14M 模型(官方标注适合 Cortex A7 CPU)

配合 silero-vad 做静音检测、sherpa-onnx 自带的 KWS 唤醒词功能,一套代码就能做出完整的离线语音交互链路。模型下载全部走 GitHub Releases,无闭源依赖,商用无忧。

小结

端侧语音识别已经不是「能不能做」的问题,而是「怎么选模型」的问题。14M 参数的 int8 模型 + 单线程,普通 CPU 上 RTF 0.05 的实测说明:大多数设备端语音场景,一个 24MB 的模型就够了。从 sherpa-onnx 的官方模型库挑一个合适大小的模型开始,比从零训练划算得多。