使用sherpa-ncnn进行中文语音识别(ubuntu22)

news2025/2/25 3:05:41

        获取该开源项目的渠道,是我在b站上,看到了由csukuangfj制作的一套语音识别视频。以下地址均为csukuangfj在视频中提供,感谢分享!

新一代Kaldi + RISC-V: VisionFive2 上的实时中英文语音识别_哔哩哔哩_bilibili

开源项目地址:GitHub - k2-fsa/sherpa-ncnn: Real-time speech recognition using next-gen Kaldi with ncnn without Internet connection. Support iOS, Android, Raspberry Pi, VisionFive2, LicheePi4A etc.

文档地址:Python API — sherpa 1.3 documentation

该开源项目可以在linux\windows\ios\安卓使用

我用的机器是ubuntu22虚拟机进行测试

        请注意,需要首先安装安装了所有必要的依赖项,包括 CMake、Git 和一个合适的 C/C++ 编译器。如果遇到任何问题,您可以查看 sherpa-ncnn 的 GitHub 仓库(Issues · k2-fsa/sherpa-ncnn · GitHub)或相关文档获取帮助。

        使用sherpa-ncnn前,安装并编译过kaldi,所以在编译sherpa-ncnn前只安装了cmake

        安装命令如下:

sudo apt install cmake

其他依赖如需安装,可以参考kaldi的相关依赖安装

详细解析Ubuntu22 部署Kaldi大模型-CSDN博客

一、安装sherpa-ncnn

按照要求,执行安装命令:

(一)下载sherpa-ncnn脚本文件

git clone https://github.com/k2-fsa/sherpa-ncnn

(二)编译 

1. 进入sherpa-ncnn文件夹后,新建build文件并进入build目录

cd sherpa-ncnn
mkdir build
cd build

 2. 配置编译

cmake -DCMAKE_BUILD_TYPE=Release ..

3. 开始编译

make -j 6

编译后结果显示如下:

编译后,在bin文件夹获得这两个文件:

 4.(可选)剥离二进制文件: 

        您可以通过 strip 命令减小二进制文件的大小,移除调试符号

        回到sherpa-ncnn文件夹中,执行下列命令:

strip bin/sherpa-ncnn
strip bin/sherpa-ncnn-microphone

二、使用sherpa-ncnn的Python API实现语音识别

         参考Python API — sherpa 1.3 documentation 

        我们将实现如下工作:

                实时语音识别

                识别一个文件

(一) 安装必备软件及依赖

         在Linux或Windows上使用时,python版本必须>=3.6       

        如果您使用方法1,它将安装预编译的库。缺点是它可能没有针对您的平台进行优化,而优点是您不需要安装cmake或C++编译器。

        对于其他方法,需要先执行以下命令:

        安装cmake:

pip install cmake

         C++编译器,例如在Linux和macOS上的GCC,在Windows上的Visual Studio,这里我们使用的ubuntu22所以安装gcc

sudo apt update
sudo apt install build-essential

    build-essential 包含了编译 C 和 C++ 程序所需的工具,其中就包括 GCC。

安装完成后,您可以通过以下命令来检查 GCC 的版本,以确保它已正确安装:

gcc --version

(二)安装 Python 包 sherpa-ncnn

 1. 方法1

        安装sherpa-ncnn包

pip install sherpa-ncnn

        安装完毕显示如下:

2. 方法2

        下载并进入sherpa-ncnn文件夹

git clone https://github.com/k2-fsa/sherpa-ncnn
cd sherpa-ncnn

        执行安装命令(按照官网说法没有使用sudo命令,会报错)

sudo python3 setup.py install

3. 方法3

        直接使用以下命令进行安装

pip install git+https://github.com/k2-fsa/sherpa-ncnn

4. 方法4(适用于开发者和嵌入式开发板)

        针对不同平台,有不同的安装方式。

 

        使用ubuntu22平台,使用x86_64的安装方法

# 下载sherpa-ncnn
git clone https://github.com/k2-fsa/sherpa-ncnn
# 进入sherpa-ncnn目录
cd sherpa-ncnn
# 新建build目录
mkdir build
# 进入build目录
cd build

# 配置编译
cmake \
  -D SHERPA_NCNN_ENABLE_PYTHON=ON \
  -D SHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
  -D BUILD_SHARED_LIBS=ON \
  ..
# 开始编译
make -j6

        配置环境变量

export PYTHONPATH=$PWD/lib:$PWD/../sherpa-ncnn/python:$PYTHONPATH

5. 检查安装是否成功

(1)检查方法1

        使用命令,导入sherpa-ncnn和_sherpa_ncnn两个包,并显示其所在路径

python3 -c "import sherpa_ncnn; print(sherpa_ncnn.__file__)"
python3 -c "import _sherpa_ncnn; print(_sherpa_ncnn.__file__)"

         执行完毕显示如下:

(2)检查方法2

        使用命令,显示sherpa-ncnn的版本号

python3 -c "import sherpa_ncnn; print(sherpa_ncnn.__version__)"

        执行后显示如下:

(三)实时语音识别

        安装python图形化编译器geany,命令如下:

sudo apt install geany
1.实时语音识别(使用麦克风)
(1)环境配置
        A. 设置虚拟机共享主机麦克风

                a.在VirtualBox虚拟机窗口右下角,点击音频,在声音输入上打勾

                 b.在ubuntu22声音设置中,声音输入选择“line in”,并关掉设置窗口。 

        B. 测试麦克风 
rec test.wav

         使用"Ctrl+C"结束录音,可以直接双击test.wav文件进行播放,检查刚才是否已经将声音录制进去。

        C. 安装python声音设备驱动包,命令如下:
pip install sounddevice
         D. 让python命令可以直接调用python3,执行如下命令
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10
        E. 安装portaudio(我在后面的执行中的出现了报错,显示sounddevice不包括protaudio,解决办法就是单独安装一下),命令如下
sudo apt install portaudio19-dev

 

(2)使用下列代码

可以直接从这里下载代码:https://github.com/k2-fsa/sherpa-ncnn/blob/master/python-api-examples/speech-recognition-from-microphone.py

在shell窗口中输入geany,打开编译器。复制代码并另存为speech-recognition-from-microphone.py(该文件只有在sherpa-ncnn下可以使用)

import sys

try:
    import sounddevice as sd
except ImportError as e:
    print("Please install sounddevice first. You can use")
    print()
    print("  pip install sounddevice")
    print()
    print("to install it")
    sys.exit(-1)

import sherpa_ncnn


def create_recognizer():
    # Please replace the model files if needed.
    # See https://k2-fsa.github.io/sherpa/ncnn/pretrained_models/index.html
    # for download links.

    recognizer = sherpa_ncnn.Recognizer(
        tokens="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt",
        encoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.param",
        encoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.bin",
        decoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param",
        decoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin",
        joiner_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.param",
        joiner_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.bin",
        num_threads=4,
    )
    '''
    # 可以使用这里的代码,将浮点16位,改为8位
    recognizer = sherpa_ncnn.Recognizer(
        tokens="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt",
        encoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.int8.param",
        encoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.int8.bin",
        decoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param",
        decoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin",
        joiner_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.int8.param",
        joiner_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.int8.bin",
        num_threads=4,
    '''


    return recognizer


def main():
    print("Started! Please speak")
    recognizer = create_recognizer()
    sample_rate = recognizer.sample_rate
    samples_per_read = int(0.1 * sample_rate)  # 0.1 second = 100 ms
    last_result = ""
    with sd.InputStream(
        channels=1, dtype="float32", samplerate=sample_rate
    ) as s:
        while True:
            samples, _ = s.read(samples_per_read)  # a blocking read
            samples = samples.reshape(-1)
            recognizer.accept_waveform(sample_rate, samples)
            result = recognizer.text
            if last_result != result:
                last_result = result
                print(result)


if __name__ == "__main__":
    devices = sd.query_devices()
    print(devices)
    default_input_device_idx = sd.default.device[0]
    print(f'Use default device: {devices[default_input_device_idx]["name"]}')

    try:
        main()

(3)创建识别器:使用模型: csukuangfj/sherpa-ncnn-conv-emformer-transducer-2022-12-06 (Chinese + English) 可以同时识别英语和中文。
A. 进入sherpa-ncnn目录
cd /path/to/sherpa-ncnn
B.执行下列命令,下载模型
wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-conv-emformer-transducer-2022-12-06.tar.bz2
tar xvf sherpa-ncnn-conv-emformer-transducer-2022-12-06.tar.bz2
(4)执行语音识别功能

进入sherpa-ncnn目录

执行speech-recognition-from-microphone.py脚本,命令如下:

python speech-recognition-from-microphone.py

(四)识别一个Wav文件

wav文件要求:波形文件的采样率必须是 16 kHz。此外,它应该只包含一个通道,并且采样应该以 16 位(即 int16)编码。

1. 获得脚本

        下载脚本地址:https://github.com/k2-fsa/sherpa-ncnn/blob/master/python-api-examples/decode-file.py

         也可以复制下面脚本内容到decode-file.py(该文件只有在sherpa-ncnn下可以使用)

import wave

import numpy as np
import sherpa_ncnn


def main():

    recognizer = sherpa_ncnn.Recognizer(
        tokens="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt",
        encoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.param",
        encoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.bin",
        decoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param",
        decoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin",
        joiner_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.param",
        joiner_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.bin",
        num_threads=4,
    )
    '''
    # 可以使用这里的代码,将浮点16位,改为8位       
    recognizer = sherpa_ncnn.Recognizer(
        tokens="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt",
        encoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.int8.param",
        encoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.int8.bin",
        decoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param",
        decoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin",
        joiner_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.int8.param",
        joiner_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.int8.bin",
        num_threads=4,
)
    '''

    filename = (
        "./sherpa-ncnn-conv-emformer-transducer-2022-12-06/test_wavs/1.wav"
    )
    with wave.open(filename) as f:
        assert f.getframerate() == recognizer.sample_rate, (
            f.getframerate(),
            recognizer.sample_rate,
        )
        assert f.getnchannels() == 1, f.getnchannels()
        assert f.getsampwidth() == 2, f.getsampwidth()  # it is in bytes
        num_samples = f.getnframes()
        samples = f.readframes(num_samples)
        samples_int16 = np.frombuffer(samples, dtype=np.int16)
        samples_float32 = samples_int16.astype(np.float32)

        samples_float32 = samples_float32 / 32768

    recognizer.accept_waveform(recognizer.sample_rate, samples_float32)

    tail_paddings = np.zeros(
        int(recognizer.sample_rate * 0.5), dtype=np.float32
    )
    recognizer.accept_waveform(recognizer.sample_rate, tail_paddings)

    recognizer.input_finished()

    print(recognizer.text)


if __name__ == "__main__":
    main()
2. 执行脚本

        执行decode-file.py脚本,将对sherpa-ncnn//sherpa-ncnn-conv-emformer-transducer-2022-12-06/test_wavs/1.wav文件进行转换

python decode-file.py

        执行结果如下:

3. 替换指定文件路径

如果想要对指定文件进行转换,可以修改脚本红框内容为想要转换的wav文件的路径

要了解预训练模型以获取更多模型,可以参考Pre-trained models — sherpa 1.3 documentation

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1824118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue41-vc实例与vm实例

一、 vc实例与vm实例的区别 vc实例与vm实例,99%结构都是类似的,仅2点不同: el属性data的书写格式 1-1、 el属性 vc有的功能vm都有,但是vm能通过el决定为哪个容器服务,但是vc却不行! 1-2、data的书写格式

利用Cesium和JS实现地点点聚合功能

引言 在实现基于地图的业务场景时,当地图上需要展示过多的标记点时,大量的分散点会使地图上显得杂乱无章,导致标记点对地图上的其他重要信息造成遮挡和混淆,降低地图整体的可读性。 标记点的聚合就很好的解决了这些痛点的同时&a…

理解Es的DSL语法(二):聚合

前一篇已经系统介绍过查询语法,详细可直接看上一篇文章(理解DSL语法(一)),本篇主要介绍DSL中的另一部分:聚合 理解Es中的聚合 虽然Elasticsearch 是一个基于 Lucene 的搜索引擎,但…

单通道触摸感应开关RH6016

1.简介 SOT23-6 RH6016 封装和丝印 RH6016 是一款内置稳压模块的单通道电容式触摸感应控制开关IC,可以替代传统的机械式开关。 RH6016可在有介质(如玻璃、亚克力、塑料、陶瓷等)隔离保护的情况下实现触摸功能,安全性高。 RH6016内置高精度稳压、上电复…

C++17并行算法与HIPSTDPAR

C17 parallel algorithms and HIPSTDPAR — ROCm Blogs (amd.com) C17标准在原有的C标准库中引入了并行算法的概念。像std::transform这样的并行版本算法保持了与常规串行版本相同的签名,只是增加了一个额外的参数来指定使用的执行策略。这种灵活性使得已经使用C标准…

数据采集项目2-业务数据同步

全量同步 每天都将业务数据库中的全部数据同步一份到数据仓库 全量同步采用DataX datax datax使用 执行 python /opt/module/datax/bin/datax.py /opt/module/datax/job/job.json 更多job.json配置文件在: 生成的DataX配置文件 java -jar datax-config-genera…

【RabbitMQ】RabbitMQ 的 6 种工作模式

RabbitMQ 的 6 种工作模式 1.简单模式2.工作队列模式3.交换机模式4.Routing 转发模式5.主题转发模式6.RPC 模式6.1 消息属性6.2 关联标识6.3 工作流程 7.小结 1.简单模式 生产者把消息放入队列,消费者获得消息,如下图所示。这个模式只有 一个消费者、一…

【python】python指南(三):使用正则表达式re提取文本中的http链接

一、引言 对于算法工程师来说,语言从来都不是关键,关键是快速学习以及解决问题的能力。大学的时候参加ACM/ICPC一直使用的是C语言,实习的时候做一个算法策略后台用的是php,毕业后做策略算法开发,因为要用spark&#x…

LeetCode | 520.检测大写字母

这道题直接分3种情况讨论:1、全部都为大写;2、全部都为小写;3、首字母大写其余小写。这里我借用了一个全是大写字母的串和一个全为小写字母的串进行比较 class Solution(object):def detectCapitalUse(self, word):""":type …

Python基础教程(十五):面向对象编程

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝&#x1f49…

【机器学习】Dify:AI智能体开发平台版本升级

一、引言 关于dify,之前力推过,大家可以跳转 AI智能体研发之路-工程篇(二):Dify智能体开发平台一键部署了解,今天主要以dify为例,分享一下如何进行版本升级。 二、版本升级 2.1 原方案 #首次…

超图制作栅格数据集专题图示例

之前写过一两篇专题图的博文,是制作的矢量数据集的专题图; 有一个栅格数据集如下,不知是干嘛的,可能是一个地形,或水系; 看一下对栅格数据集制作专题图;能制作的专题图类型少些, 先…

pytorch学习笔记7

getitem在进行索引取值的时候自动调用,也是一个魔法方法,就像列表索引取值那样,一个意思 import torchvision from torch.utils.data import DataLoaderdata_transformtorchvision.transforms.Compose([torchvision.transforms.ToTensor()] ) test_datatorchvision.datasets.C…

GraphQL(9):Spring Boot集成Graphql简单实例

1 安装插件 我这边使用的是IDEA,需要先按照Graphql插件,步骤如下: (1)打开插件管理 在IDEA中,打开主菜单,选择 "File" -> "Settings" (或者使用快捷键 Ctrl Alt S …

【测试】软件测试方案—实际项目直接套用(Word原件)

1. 引言 1.1. 编写目的 1.2. 项目背景 1.3. 读者对象 1.4. 参考资料 1.5. 术语与缩略语 2. 测试策略 2.1. 测试完成标准 2.2. 测试类型 2.2.1. 功能测试 2.2.2. 性能测试 2.2.3. 安全性与访问控制测试 2.3. 测试工具 3. 测试技术 4. 测试资源 4.1. 人员安排 4.2. 测试环境 4.2.…

宝藏速成秘籍(5)插入排序法

一、前言 1.1、概念 插入排序(Insertion Sort)是一种简单直观的排序算法,其工作原理类似于人们整理一手扑克牌。插入排序通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入…

Javaweb03-Servlet技术1(Servlet,ServletConfig,ServletContext)

Servlet技术(Servlet,ServletConfig,ServletContext) 1.Servlet的概述 Servlet是运行在Web服务器端的Java应用程序,它使用Java语言编写。与Java程序的区别是,Servlet 对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器(Tomcat)的…

MySQL与PostgreSQL关键对比四(关联查询性能)

引言:MySQL单表的数据规模一般建议在百万级别,而PostgreSQL的单表级别一般可以到亿级,如果是MPP版本就会更多。从基础数据建议上,不难看出,MySQL在Join的情况下也就是主要查询的情况下性能和PostgreSQL相差还是很大的。…

Navicat和SQLynx产品功能比较一(整体比较)

Navicat和SQLynx都是数据库管理工具,在过去的二十年中,国内用户主要是使用Navicat偏多,一般是个人简单开发需要,数据量一般不大,开发相对简单。SQLynx是最近几年的数据库管理工具,Web开发,桌面版…

【odoo】odoo中对子数据的独有操作[(0, 0, {‘name‘: ‘demo‘})]

概要 在Odoo中,有种写法用于操作 one2many 或 many2many 字段时,描述如何在数据库中创建、更新或删除相关记录。具体而言,这是一种命令格式,被称为 "commands" 或 "special command tuples",用于 …