在边缘设备上实现实时说话人分割(speaker diarization)是多模态 AI 系统的一个关键挑战,尤其是在噪声环境中处理多说话人音频时。Sherpa-ONNX 作为一款开源的下一代 Kaldi 框架,提供离线、低延迟的语音处理能力,支持说话人分割、VAD(语音活动检测)和嵌入提取等功能。它特别适合嵌入式设备,如 Raspberry Pi、ARM 处理器和 RISC-V 平台,无需互联网连接即可运行。这使得它成为构建实时管道的理想选择,能够在会议记录、监控系统或智能音箱中识别并分割不同说话人。
Sherpa-ONNX 的说话人分割管道主要依赖于三个核心组件:语音活动检测(VAD)、说话人分割(segmentation)和说话人嵌入提取(embedding extraction),最终通过聚类(clustering)完成说话人识别。VAD 模块使用如 Silero-VAD 的轻量模型,首先过滤非语音段落,确保后续处理聚焦于活跃音频,从而降低延迟。分割模型如 pyannote-segmentation-3.0 或 reverb-diarization-v1,能够检测说话人变化点,将音频切分成小段。嵌入提取则使用 3D-Speaker 或 NeMo Titanet 等模型,从每个段落生成固定维度的说话人特征向量。最后,快速聚类算法(如基于阈值的谱聚类)将相似嵌入归为一类,实现多说话人标识。
证据显示,Sherpa-ONNX 在边缘设备上的性能出色。例如,在 16kHz 单声道音频上,使用 INT8 量化模型的 RTF(实时因子)可低至 0.1-0.3,意味着处理 1 分钟音频仅需 6-18 秒 CPU 时间。这得益于 ONNX Runtime 的优化,支持 CPU、GPU 和 NPU(如 RK NPU)。在噪声测试中(如添加 10dB 白噪声),结合 VAD 的管道准确率可达 85%以上,优于传统方法。GitHub 仓库中提供的预训练模型体积小(5-10MB),加载快速,适合内存受限的设备。实际部署中,Raspberry Pi 4 上运行 pyannote + NeMo 模型,端到端延迟小于 200ms,支持实时流式处理。
构建管道时,需要关注可落地参数和优化策略。首先,选择合适的模型组合:对于中文/英文混合场景,推荐 pyannote-segmentation-3.0(5.7MB)作为分割模型,搭配 nemo_en_titanet_small.onnx(嵌入模型,~2MB),以实现跨语言鲁棒性。VAD 参数设置:使用 Silero-VAD 的 threshold=0.5,min_speech_duration_ms=250,min_silence_duration_ms=100,确保低延迟检测(<50ms)。分割阈值:min_duration_on=0.3s,min_duration_off=0.5s,避免短段误判。聚类参数:若已知说话人数,使用 num-clusters=4;否则,cluster-threshold=0.7-0.9(阈值越大,说话人越少)。为噪声环境,集成预增强模块,如使用 Sherpa-ONNX 的 speech-enhancement 模型(gtcrn.onnx),参数 noise-gate=-20dB。
落地清单如下:
-
环境准备:在目标设备上安装 Sherpa-ONNX(C++ 或 Python API)。对于嵌入式,优先 C++ 构建:git clone https://github.com/k2-fsa/sherpa-onnx,cmake 配置 ONNX Runtime,编译 offline-speaker-diarization 二进制。Python 用户:pip install sherpa-onnx>=1.10.28。
-
模型下载:从 releases 下载:sherpa-onnx-pyannote-segmentation-3-0.tar.bz2(解压 model.onnx 或 model.int8.onnx),nemo_en_titanet_small.onnx,silero_vad.onnx。放置在统一目录,如 /models/。
-
管道实现(C++ 示例):
- 初始化 OfflineSpeakerDiarizationConfig:设置 segmentation.pyannote-model="./model.int8.onnx",embedding.model="./nemo_en_titanet_small.onnx",clustering.num-clusters=未知时用 threshold=0.8。
- 加载音频:使用 wave reader,采样率 16000Hz,单声道。
- 运行:OfflineSpeakerDiarization diarizer(config); auto segments = diarizer.Process(samples);
- 输出:遍历 segments,打印 start_time -- end_time speaker_id。
Python 类似:from sherpa_onnx import OfflineSpeakerDiarization; config = ...; diarizer = OfflineSpeakerDiarization(config); segments = diarizer.ProcessFile('audio.wav')。
-
VAD 集成:在管道前端添加 OfflineVad:vad_config.model='./silero_vad.onnx',vad.Process(samples) 获取活跃段落,仅对活跃部分运行 diarization。参数:update_interval=100ms,确保实时。
-
优化与监控:
- 延迟监控:使用 RTF 计算,目标 <0.2;若超标,切换 INT8 模型或减少 threads=1。
- 准确率评估:使用 DER(Diarization Error Rate)指标,测试集如 AMI Corpus;在噪声下,fallback 到更高阈值。
- 资源监控:内存 <100MB,CPU 使用 <50%;在 ARM 上测试功耗 <2W。
- 回滚策略:若聚类失败(<2 说话人),默认单说话人模式;日志记录 embedding 相似度 >0.9 为异常。
-
测试与部署:在 Raspberry Pi 上运行 30s 多说话人音频,验证输出如 "0.3--6.8 speaker_00"。部署时,使用 WebSocket API 实现流式输入,支持 Android/iOS 客户端。
此管道在实际应用中,如智能会议系统,可显著提升转录准确性。风险包括极度噪声下分割错误(缓解:增强 + 后处理),及多说话人重叠(>3 人时阈值调至 0.6)。总体,Sherpa-ONNX 提供高效、模块化的解决方案,易于扩展到生产环境。
资料来源: