sherpa-onnx语音命令定制:用户自定义词汇表实现

sherpa-onnx语音命令定制:用户自定义词汇表实现

【免费下载链接】sherpa-onnx k2-fsa/sherpa-onnx: Sherpa-ONNX 项目与 ONNX 格式模型的处理有关,可能涉及将语音识别或者其他领域的模型转换为 ONNX 格式,并进行优化和部署。 【免费下载链接】sherpa-onnx 项目地址: https://gitcode.com/GitHub_Trending/sh/sherpa-onnx

引言

在语音交互应用中,固定词汇表往往无法满足特定场景需求。Sherpa-ONNX作为一款高效的ONNX格式语音模型部署工具,提供了灵活的关键词定制功能,允许用户根据实际业务需求扩展词汇表。本文将系统介绍如何通过自定义词汇表实现专属语音命令识别,从环境准备到高级优化,全程基于本地部署,无需依赖云端服务。

技术背景

核心概念解析

术语解释作用
关键词 spotting(KWS)实时检测音频流中特定关键词的技术唤醒设备、触发指令
ONNX(Open Neural Network Exchange)开放格式的机器学习模型表示跨平台模型部署
词汇表(Vocabulary)模型可识别的词语集合限定识别范围,提升准确率
拼音分词(Pinyin Tokenization)将汉字转换为拼音音节序列的过程解决语音到文本的映射

Sherpa-ONNX架构优势

Sherpa-ONNX的关键词识别模块采用流式处理架构,支持两种词汇扩展方式:

  • 静态扩展:通过关键词文件批量导入
  • 动态扩展:运行时实时添加词汇

其技术优势体现在:

  • 低延迟:最小检测延迟可达200ms
  • 轻量级:模型体积最小仅3.3M
  • 跨平台:支持x86/ARM架构,Linux/macOS/Windows系统
  • 多语言:原生支持中英文混合识别

环境准备

开发环境配置

# 克隆仓库
git clone https://gitcode.com/GitHub_Trending/sh/sherpa-onnx
cd sherpa-onnx

# 创建虚拟环境
python -m venv venv
source venv/bin/activate  # Linux/macOS
# venv\Scripts\activate  # Windows

# 安装依赖
pip install -r requirements.txt

预训练模型下载

模型名称大小适用场景下载命令
流式Zipformer模型3.3M轻量级设备./scripts/download_kws_model.sh
通用关键词模型12M高精度场景./scripts/download_kws_large_model.sh

提示:模型默认下载至sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01目录

自定义词汇表实现

1. 基础实现:通过文件定义关键词

关键词文件格式

创建custom_keywords.txt,遵循以下格式:

# 格式:拼音分词 @关键词 [阈值]
h e l l o @hello 0.5
n i h a o @你好 0.6
y ǎn y uán @演员 0.45
  • 拼音分词:每个音节用空格分隔
  • @符号:分隔拼音与关键词
  • 阈值(可选):0-1之间,越高识别越严格
加载自定义关键词文件
import sherpa_onnx

def create_kws_with_custom_file():
    return sherpa_onnx.KeywordSpotter(
        tokens="./sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/tokens.txt",
        encoder="./sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/encoder-epoch-12-avg-2-chunk-16-left-64.onnx",
        decoder="./sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/decoder-epoch-12-avg-2-chunk-16-left-64.onnx",
        joiner="./sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/joiner-epoch-12-avg-2-chunk-16-left-64.onnx",
        num_threads=2,
        keywords_file="./custom_keywords.txt",  # 自定义关键词文件
        provider="cpu",
    )

2. 高级实现:动态添加关键词

在不修改文件的情况下,可通过API在运行时动态添加关键词:

def dynamic_keyword_demo():
    kws = create_kws_with_custom_file()
    
    # 场景1:添加单个关键词
    stream1 = kws.create_stream("z ì d òng huà @自动化")
    process_audio(stream1, "audio1.wav")
    
    # 场景2:添加多个关键词(用/分隔)
    stream2 = kws.create_stream("j i qì rén @机器人/k ōng tiáo @空调")
    process_audio(stream2, "audio2.wav")
    
    # 场景3:临时覆盖所有关键词
    stream3 = kws.create_stream("*|y ùn xíng @运行")  # *|表示清除现有关键词
    process_audio(stream3, "audio3.wav")

3. 词汇表扩展:自定义Token处理

当需要添加模型未包含的新词时,需扩展tokens.txt:

# tokens.txt 示例片段
<eps> 0
<s> 1
</s> 2
a 3
ai 4
an 5
# ... 现有内容 ...
# 添加自定义拼音
xuan 1001
zhi 1002
hua 1003

注意:扩展token后需重新导出模型,具体方法参见项目scripts/export_bpe_vocab.py脚本

完整代码示例

实时麦克风关键词识别

import argparse
import time
import numpy as np
import sherpa_onnx
import sounddevice as sd

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--keywords-file", type=str, default="custom_keywords.txt")
    parser.add_argument("--sample-rate", type=int, default=16000)
    parser.add_argument("--num-threads", type=int, default=2)
    args = parser.parse_args()

    # 创建关键词识别器
    kws = sherpa_onnx.KeywordSpotter(
        tokens="./sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/tokens.txt",
        encoder="./sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/encoder-epoch-12-avg-2-chunk-16-left-64.onnx",
        decoder="./sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/decoder-epoch-12-avg-2-chunk-16-left-64.onnx",
        joiner="./sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/joiner-epoch-12-avg-2-chunk-16-left-64.onnx",
        num_threads=args.num_threads,
        keywords_file=args.keywords_file,
        provider="cpu",
    )

    # 麦克风音频回调函数
    def audio_callback(indata, frames, time, status):
        if status:
            print(f"音频状态: {status}", file=sys.stderr)
        
        # 转换为float32格式
        audio_data = indata.flatten().astype(np.float32) / 32768.0
        
        # 喂入音频流
        stream.accept_waveform(args.sample_rate, audio_data)
        
        # 处理识别
        while kws.is_ready(stream):
            kws.decode_stream(stream)
            result = kws.get_result(stream)
            if result:
                print(f"检测到关键词: {result}")
                kws.reset_stream(stream)  # 重置流以继续检测

    # 创建音频流
    stream = kws.create_stream()
    
    # 启动麦克风监听
    with sd.InputStream(
        samplerate=args.sample_rate,
        channels=1,
        dtype="int16",
        callback=audio_callback
    ):
        print("开始监听关键词... (按Ctrl+C停止)")
        while True:
            time.sleep(0.1)

if __name__ == "__main__":
    main()

批量文件处理工具

def batch_process_audio_files(kws, audio_dir):
    """批量处理目录中的音频文件"""
    results = {}
    
    for audio_path in Path(audio_dir).glob("*.wav"):
        samples, sample_rate = read_wave(str(audio_path))
        stream = kws.create_stream()
        
        # 添加尾部填充(确保关键词在结尾也能被检测)
        tail_padding = np.zeros(int(0.66 * sample_rate), dtype=np.float32)
        stream.accept_waveform(sample_rate, samples)
        stream.accept_waveform(sample_rate, tail_padding)
        stream.input_finished()
        
        # 处理识别
        detected = []
        while kws.is_ready(stream):
            kws.decode_stream(stream)
            result = kws.get_result(stream)
            if result:
                detected.append(result)
                kws.reset_stream(stream)
        
        results[str(audio_path)] = detected
    
    return results

性能优化策略

识别准确率调优

参数作用推荐值
关键词阈值控制检测灵敏度0.4-0.7
音频增益提升弱音信号1.5-3.0
窗口大小平衡响应速度与准确率200-500ms
平滑系数减少误检0.3-0.5

代码优化示例

# 优化1:设置动态阈值(根据环境噪音调整)
def adaptive_threshold(noise_level):
    if noise_level < -40:  # 安静环境
        return 0.45
    elif noise_level < -20:  # 中等噪音
        return 0.55
    else:  # 嘈杂环境
        return 0.65

# 优化2:多流并行处理
def parallel_process(kws, audio_files):
    with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
        futures = {executor.submit(process_single_file, kws, f): f for f in audio_files}
        for future in concurrent.futures.as_completed(futures):
            # 处理结果

常见问题解决

关键词冲突问题

当多个关键词拼音相似时,可通过权重设置解决:

# 关键词文件中设置权重(越高优先级越高)
n i h a o @你好 0.6;2  # 权重2
n i h a o a @你好啊 0.5;1  # 权重1

低置信度问题

若关键词频繁漏检,可尝试:

  1. 降低阈值(0.5→0.4)
  2. 优化拼音分词(如"j i q i @机器"改为"j i qì @机器")
  3. 录制多版本样本进行模型微调:./scripts/finetune_kws.sh --data_dir ./custom_samples

资源占用优化

在嵌入式设备上可采用以下优化:

# 减少线程数
kws = sherpa_onnx.KeywordSpotter(num_threads=1)

# 降低采样率(可能影响准确率)
stream = kws.create_stream(sample_rate=8000)

# 关闭动态更新
kws.set_update_threshold(False)

应用场景案例

智能家居控制

# 智能家居关键词配置
keywords = """
k ā i dēng @开灯
gu ā n dēng @关灯
k ā i k ōng tiáo @开空调
gu ā n k ōng tiáo @关空调
t i á o g ā o wēn dù @调高温度
t i á o dī wēn dù @调低温度
"""

with open("smart_home_keywords.txt", "w") as f:
    f.write(keywords)

工业语音指令

# 工业控制动态关键词管理
class IndustrialCommandManager:
    def __init__(self, kws):
        self.kws = kws
        self.command_sets = {
            "maintenance": "tíng jī @停机/xiū lǐ @修理",
            "production": "kāi gōng @开工/jìn dù @进度",
            "quality": "jiǎn chá @检查/pǐn zhì @品质"
        }
    
    def switch_mode(self, mode):
        """切换工作模式,加载对应指令集"""
        if mode in self.command_sets:
            return self.kws.create_stream(self.command_sets[mode])
        raise ValueError(f"未知模式: {mode}")

总结与展望

核心功能回顾

Sherpa-ONNX的自定义词汇表实现主要通过三种方式:

  1. 文件配置:适合静态关键词集
  2. 动态注入:适合临时场景需求
  3. Token扩展:适合新增词汇场景

其技术优势在于:

  • 无需重新训练模型即可扩展词汇
  • 支持实时更新与多场景切换
  • 轻量级设计适合边缘设备部署

进阶方向

  1. 上下文感知识别:结合对话语境动态调整关键词权重
  2. 多语言混合识别:扩展支持中英文以外的其他语言
  3. 个性化适应:通过少量样本学习用户发音特点
  4. 低功耗优化:针对电池供电设备的功耗优化

学习资源

  • 官方文档:项目根目录下docs/文件夹
  • 示例代码:python-api-examples/目录下的关键词识别示例
  • 模型库:./scripts/download_*脚本可获取更多预训练模型

通过本文介绍的方法,开发者可以快速实现专属语音命令系统,满足特定业务场景需求。无论是智能家居、工业控制还是移动应用,Sherpa-ONNX提供的灵活词汇扩展机制都能帮助开发者构建高效、准确的语音交互体验。

【免费下载链接】sherpa-onnx k2-fsa/sherpa-onnx: Sherpa-ONNX 项目与 ONNX 格式模型的处理有关,可能涉及将语音识别或者其他领域的模型转换为 ONNX 格式,并进行优化和部署。 【免费下载链接】sherpa-onnx 项目地址: https://gitcode.com/GitHub_Trending/sh/sherpa-onnx

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值