基于 sherpa-onnx 和 SenseVoice 的 C++ WebSocket 实时语音识别服务实践
2025/7/13...大约 5 分钟
基于 sherpa-onnx 和 SenseVoice 的 C++ WebSocket 实时语音识别服务实践
随着语音交互在智能设备、办公自动化等场景的普及,实时、高效、易部署的语音识别服务需求日益增长。本文将介绍如何基于 sherpa-onnx 和 SenseVoice,构建一个高性能的 C++ WebSocket 流式语音识别服务器,支持多语言、VAD、容器化部署,并兼容多种客户端。
GitHub 项目地址:mawwalker/stt-server,欢迎 star 和交流。
一、项目背景与目标
传统的语音识别服务往往部署复杂、性能有限,难以满足多客户端高并发和低延迟需求。本项目以 C++ 实现,结合 sherpa-onnx 推理引擎和 SenseVoice 多语言模型,提供了:
- 实时流式语音识别(Streaming ASR)
- 一句话识别(OneShot ASR,支持情感分析、语言检测)
- WebSocket 标准接口,易于集成
- 多语言支持(中、英、日、韩、粤语)
- 内置 VAD(语音活动检测),自动分段
- 高并发、低延迟,适合生产环境
- 一键本地/容器化部署,配置统一
二、系统架构与核心组件
整体架构如下:
- WebSocketASRServer:负责 WebSocket 连接管理、消息路由
- ASREngine:封装 sherpa-onnx 推理与 VAD,支持多线程
- ASRSession:管理每个客户端的音频流、识别状态
- 统一配置系统:支持本地与 Docker 环境自动适配
- Logger:统一日志输出,便于调试与运维
架构示意:
┌──────────────┐ ┌────────────────────┐ ┌───────────────┐
│ WebSocket │ │ WebSocket ASR │ │ sherpa-onnx │
│ Client │◄──►│ Server │◄──►│ Engine │
└──────────────┘ └────────────────────┘ └───────────────┘
三、主要特性与亮点
- 实时流式识别:边说边出结果,适合语音助手、会议转写等场景
- OneShot 一句话识别:支持完整音频后处理,自动语言检测、情感分析
- 多语言支持:SenseVoice 模型,覆盖中、英、日、韩、粤语
- 内置 VAD:自动检测语音段落,提升识别准确率
- 高并发、低延迟:C++ 实现,资源占用低,支持多客户端
- 统一配置:.env 文件一键切换本地/Docker,环境自适应
- 容器化部署:Dockerfile、docker-compose 支持,生产环境友好
- 丰富接口:标准 WebSocket,兼容 Python/JS 客户端
四、配置与部署
1. 依赖安装
- 系统依赖(以 Ubuntu 为例):
sudo apt-get install -y cmake build-essential libjsoncpp-dev libwebsocketpp-dev libasio-dev pkg-config
- sherpa-onnx 安装(推荐自动脚本):
./install_sherpa_onnx.sh
source ./setup_env.sh
2. 模型准备
确保 assets/
目录下有 SenseVoice 和 Silero VAD 模型:
# 下载 SenseVoice 多语言模型
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2
tar xvf sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2
mv sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17 assets/
# 下载 VAD 模型
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad.onnx
mkdir -p assets/silero_vad
mv silero_vad.onnx assets/silero_vad/
3. 一键启动
- 本地启动(推荐):
chmod +x run.sh
./run.sh local
- Docker 启动:
./run.sh docker
# 或
docker compose up -d
- Makefile 支持:
make run # 本地
make run-docker # Docker
- 查看服务状态:
./run.sh status
# 或
make status
4. 统一配置说明
只需维护一个 .env
文件,支持本地与 Docker 环境自动切换。主要参数如:
参数 | 说明 | 默认值 |
---|---|---|
SERVER_PORT | 服务端口 | 8000 |
ASR_MODEL_NAME | ASR模型名 | sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17 |
VAD_THRESHOLD | VAD检测阈值 | 0.5 |
ASR_POOL_SIZE | ASR线程池大小 | 2 |
支持命令行参数、环境变量、默认值三级优先级。
五、WebSocket 接口与使用示例
1. 端点说明
- 流式识别:
ws://localhost:8000/sttRealtime?samplerate=16000
- OneShot 识别:
ws://localhost:8000/oneshot
2. 协议说明
- 流式识别:发送 PCM 音频流,实时返回 JSON 识别结果
- OneShot:支持
start/stop
控制,返回完整识别、语言、情感等信息
流式识别返回示例:
{
"text": "识别的文本",
"finished": false,
"idx": 0,
"lang": "zh"
}
OneShot 识别返回示例:
{
"type": "result",
"text": "识别的文本",
"finished": true,
"lang": "zh",
"emotion": "neutral",
"timestamps": [...]
}
3. Python 客户端示例
import asyncio
import websockets
import wave
import json
async def test_asr():
uri = "ws://localhost:8000/sttRealtime?samplerate=16000"
async with websockets.connect(uri) as websocket:
with wave.open("test.wav", "rb") as wav_file:
data = wav_file.readframes(1024)
while data:
await websocket.send(data)
data = wav_file.readframes(1024)
async for message in websocket:
result = json.loads(message)
print(f"识别结果: {result['text']}")
if result['finished']:
break
asyncio.run(test_asr())
4. JavaScript 客户端示例
const socket = new WebSocket('ws://localhost:8000/sttRealtime?samplerate=16000');
socket.onopen = function() { /* 发送音频数据 */ };
socket.onmessage = function(event) {
const result = JSON.parse(event.data);
console.log('识别结果:', result.text);
};
六、性能优化与故障排查
- 编译优化:
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native"
- 多线程:
./build/websocket_asr_server --threads 8
- 系统参数:
ulimit -n 65536
,调整内核参数提升并发 - 常见问题:模型缺失、端口占用、防火墙阻断等,详见 README 故障排查章节
七、开发与扩展
- 核心代码结构:
ASREngine
(推理)、ASRSession
(会话)、WebSocketASRServer
(服务端) - C++17 标准,Google 风格,Doxygen 注释
- 支持自定义模型、VAD 参数、认证机制等扩展
- 测试与调试:Valgrind、GDB、日志系统等工具支持
八、总结
本项目以 C++ 为核心,结合 sherpa-onnx 和 SenseVoice,提供了高性能、易用、可扩展的实时语音识别服务。无论是本地开发还是生产部署,都能一键启动,快速集成。欢迎大家试用、反馈和贡献!
如有问题或建议,欢迎在 GitHub 提 issue 或交流。