本地离线唤醒词检测组件,支持中英文及混合关键词,支持 Sherpa-ONNX 和 Vosk 引擎
Project description
SoulShell-KWS
本地离线唤醒词检测组件,支持中英文及混合关键词,默认在 CPU 上运行。
功能特性
- 本地离线运行,无需联网
- 支持自定义唤醒词(中文、英文、中英混合)
- 低延迟实时检测
- 支持多个唤醒词同时监听
- 支持关键词二次唤醒
- 多引擎支持:Sherpa-ONNX(端到端 KWS)和 Vosk(ASR + 拼音匹配)
- 统一的引擎接口与工厂模式
- 完整的日志与异常处理
支持的引擎
| 引擎 | 特点 | 适用场景 |
|---|---|---|
| sherpa-onnx(推荐) | 端到端 KWS 模型,低延迟,高精度 | 推荐用于生产环境 |
| vosk | ASR + 拼音/文本匹配,灵活配置 | 需要自定义匹配逻辑时使用 |
技术栈
- Python: 3.10+
- 包管理: uv
- 异步框架: asyncio
- 数据验证: dataclasses
- 日志: logging (标准库)
项目结构
soulshell-kws/
├── src/soulshell_kws/
│ ├── __main__.py # python -m 入口
│ ├── cli.py # CLI 实现
│ ├── base.py # 抽象基类与结果结构
│ ├── factory.py # 引擎工厂
│ └── engines/
│ ├── sherpa_engine.py # Sherpa-ONNX 引擎实现
│ └── vosk_engine.py # Vosk 引擎实现
├── examples/
│ └── sherpa/
│ └── sherpa_usage.py # API 调用示例
├── pyproject.toml
├── Changelog.md
└── README.md
快速开始
1. 安装
# 安装基础包
pip install soulshell-kws
# 推荐:安装 Sherpa-ONNX 引擎
pip install "soulshell-kws[sherpa]"
# 安装 Vosk 引擎
pip install "soulshell-kws[vosk]"
# 如需麦克风支持
pip install "soulshell-kws[mic]"
# 安装所有运行时能力
pip install "soulshell-kws[all]"
2. 下载模型
Sherpa-ONNX 模型(推荐,中英双语):
官方模型列表见 Sherpa-ONNX KWS 预训练模型。
mkdir -p models
curl -L -o sherpa-onnx-kws-zipformer-zh-en-3M-2025-12-20.tar.bz2 \
https://github.com/k2-fsa/sherpa-onnx/releases/download/kws-models/sherpa-onnx-kws-zipformer-zh-en-3M-2025-12-20.tar.bz2
tar -xjf sherpa-onnx-kws-zipformer-zh-en-3M-2025-12-20.tar.bz2 -C models/
Vosk 模型:
# 中文模型
curl -L -O https://alphacephei.com/vosk/models/vosk-model-small-cn-0.22.zip
unzip vosk-model-small-cn-0.22.zip -d models/
# 英文模型
curl -L -O https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip
unzip vosk-model-small-en-us-0.15.zip -d models/
3. API 使用
Sherpa-ONNX 引擎(推荐)
import asyncio
from soulshell_kws.factory import WakeWordEngineFactory
async def main():
engine = await WakeWordEngineFactory.create_engine(
engine_name="sherpa-onnx",
config={
"tokens": "models/sherpa-onnx-kws-zipformer-zh-en-3M-2025-12-20/tokens.txt",
"encoder": "models/sherpa-onnx-kws-zipformer-zh-en-3M-2025-12-20/encoder-epoch-13-avg-2-chunk-8-left-64.onnx",
"decoder": "models/sherpa-onnx-kws-zipformer-zh-en-3M-2025-12-20/decoder-epoch-13-avg-2-chunk-8-left-64.onnx",
"joiner": "models/sherpa-onnx-kws-zipformer-zh-en-3M-2025-12-20/joiner-epoch-13-avg-2-chunk-8-left-64.onnx",
"wake_words": ["你好 世界", "HELLO WORLD"],
"sample_rate": 16000,
"auto_generate_keywords":false,
"two_stage_wake": {
"enabled": true,
"prefix_labels": ["你好", "HELLO"],
"target_labels": ["世界", "WORLD"],
"full_labels": ["你好 世界", "HELLO WORLD"],
"window_seconds": 0.35,
"latency_grace": 0.8,
"latency_max": 5.0,
"cooldown_seconds": 0.3,
"ema_alpha": 0.2,
"latency_margin": 0.4
}
},
)
audio_chunk = b"..." # 16-bit PCM, 16kHz
result = await engine.process_audio(audio_chunk)
# result = await engine.process_audio_two_stage_wake(audio_chunk)#二次唤醒,two_stage_wake.enabled为false走process_audio
if result.detected:
print(f"检测到: {result.keyword}")
await engine.unload()
asyncio.run(main())
Vosk 引擎
import asyncio
from soulshell_kws.factory import WakeWordEngineFactory
async def main():
# 中文(使用拼音匹配)
engine = await WakeWordEngineFactory.create_engine(
engine_name="vosk",
config={
"model_path": "models/vosk-model-small-cn-0.22",
"wake_words": ["你好"],
"use_pinyin_match": True,
"sample_rate": 16000,
},
)
audio_chunk = b"..." # 16-bit PCM, 16kHz
result = await engine.process_audio(audio_chunk)
if result.detected:
print(f"检测到: {result.keyword}")
await engine.unload()
asyncio.run(main())
async def english_example():
# 英文(使用文本匹配)
engine = await WakeWordEngineFactory.create_engine(
engine_name="vosk",
config={
"model_path": "models/vosk-model-small-en-us-0.15",
"wake_words": ["你好 世界", "hello world"],
"use_pinyin_match": False,
"sample_rate": 16000,
},
)
# ...
4. 配置参数
Sherpa-ONNX 配置
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
tokens |
str | ✅ | tokens.txt 文件路径 |
encoder |
str | ✅ | encoder.onnx 文件路径 |
decoder |
str | ✅ | decoder.onnx 文件路径 |
joiner |
str | ✅ | joiner.onnx 文件路径 |
wake_words |
list[str] | ✅ | 唤醒词列表 |
sample_rate |
int | ❌ | 采样率,默认 16000 |
keywords_score |
float | ❌ | 关键词分数,默认 2.5 |
keywords_threshold |
float | ❌ | 检测阈值,默认 0.08 |
num_threads |
int | ❌ | 线程数,默认 4 |
provider |
str | ❌ | 推理后端,默认 "cpu" |
Vosk 配置
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model_path |
str | ✅ | Vosk 模型目录路径 |
wake_words |
list[str] | ✅ | 唤醒词列表 |
use_pinyin_match |
bool | ❌ | 是否使用拼音匹配(中文 True,英文 False),默认 True |
sample_rate |
int | ❌ | 采样率,默认 16000 |
5. 返回结果
WakeWordResult 数据结构:
| 字段 | 类型 | 说明 |
|---|---|---|
detected |
bool | 是否检测到唤醒词 |
keyword |
str | None | 检测到的唤醒词 |
confidence |
float | 置信度 (0.0-1.0) |
timestamp |
float | 检测时间戳 |
audio_duration |
float | 音频时长(秒) |
engine_name |
str | 引擎名称 |
CLI 使用
# 查看帮助
soulshell-kws --help
# 列出可用引擎
soulshell-kws list-engines
# 查看引擎信息
soulshell-kws engine-info --engine sherpa-onnx
soulshell-kws engine-info --engine vosk
# 列出音频设备
soulshell-kws list-devices
# 麦克风检测
soulshell-kws detect-mic --config config.json --device 1
# 二次唤醒
soulshell-kws detect-mic_two_stage --config config.json --engine sherpa-onnx --debug --enabled
# 文本匹配测试
soulshell-kws match-text --text "你好 世界" --config config.json
# 设置唤醒词
soulshell-kws set-wake-words --config config.json --wake-words "你好 世界" "HELLO WORLD"
# 批量测试
soulshell-kws batch-test --config config.json --audio-dir output_wakewords
在其他项目中使用
安装
# 从 PyPI 安装
pip install soulshell-kws[sherpa] # Sherpa-ONNX 引擎
pip install soulshell-kws[vosk] # Vosk 引擎
pip install soulshell-kws[all] # 所有引擎
# 从源码构建
uv build
pip install dist/soulshell_kws-*.whl
作为依赖添加
# pyproject.toml
dependencies = [
"soulshell-kws[sherpa]", # 或 [vosk], [all]
]
开发
# 安装开发依赖
uv sync --extra dev
# 运行测试
uv run pytest
# 代码检查
uv run ruff check src/
uv run basedpyright src/
# 格式化
uv run ruff format src/
依赖
核心依赖
- Python 3.10+
- numpy >= 1.21.0
Sherpa-ONNX 引擎
- sherpa-onnx >= 1.12.23
- onnxruntime >= 1.18.0
- g2p-en >= 2.1.0
Vosk 引擎
- vosk >= 0.3.45
- pypinyin >= 0.50.0
可选
- pyaudio >= 0.2.14(麦克风支持)
参考
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
soulshell_kws-0.2.4.tar.gz
(28.0 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file soulshell_kws-0.2.4.tar.gz.
File metadata
- Download URL: soulshell_kws-0.2.4.tar.gz
- Upload date:
- Size: 28.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9644d37b7728910cfaa8df734aedf060f058f991dac6de99826a02b8c54c8611
|
|
| MD5 |
99be079f1a1ab4d9596b9bcbf812325d
|
|
| BLAKE2b-256 |
85af2d35fb58045b2831aafa42dcf425d9d9e6b89493263748aaa544c748172e
|
File details
Details for the file soulshell_kws-0.2.4-py3-none-any.whl.
File metadata
- Download URL: soulshell_kws-0.2.4-py3-none-any.whl
- Upload date:
- Size: 29.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0429c8c65c4ed53bedf346dfbd151792f51ab4fa96055bf2db945bf5d6c1c35a
|
|
| MD5 |
7a643f0372c5b2da5cc8249a764e9ed0
|
|
| BLAKE2b-256 |
b63dd1fc38123c0b6a9089600cff8acb6e05f6c314067fc8f3fe96f0ab2bd17c
|