FastASR

基于PaddleSpeech所使用的conformer模型,使用C++的高效实现模型推理,在树莓派4B等ARM平台运行也可流畅运行。

项目简介

本项目仅实现了PaddleSpeech r1.01版本中conformer_wenetspeech-zh-16k预训练模型。

这个预训练模型采用了当下最先进的conformer模型,使用10000+小时的wenetspeech数据集训练得到。

经过测试它识别效果很好,可以媲美许多商用的ASR软件。

PaddleSpeech是基于python实现的,本身的性能已经很不错了,即使在没有GPU的个人电脑上运行,

也能满足实时性的要求(如:时长为10s的语音,推理时间小于10s,即可满足实时性)。

但是要把PaddleSpeech部署在ARM平台,会遇到两个方面的困难。

  • 不容易安装,需要自己编译一些组件。
  • 执行效率很慢,无法满足实时性的要求。

因此就有这个项目,它由纯C++编写,仅实现了模型的推理过程。

  • 语言优势: 由于C++和Python不同,是编译型语言,编译器会根据编译选项针对不同平台的CPU进行优化,更适合在不同CPU平台上面部署,充分利用CPU的计算资源。
  • 独立: 实现不依赖于现有的深度学习框架如pytorch、paddle、tensorflow等。
  • 依赖少: 项目仅使用了两个第三方库libfftw3和libopenblas,并无其他依赖,所以在各个平台的可移植行很好,通用性很强。
  • 效率高:算法中大量使用指针,减少原有算法中reshape和permute的操作,减少不必要的数据拷贝,从而提升算法性能。

快速上手

安装依赖

安装依赖库libfftw3

sudo apt-get install libfftw3-dev libfftw3-single3

安装依赖库libopenblas

sudo apt-get install libopenblas-dev

编译源码

下载最新版的源码

git clone https://github.com/chenkui164/FastASR.git

编译最新版的源码

cd FastASR/
make

下载预训练模型

从PaddleSpeech官网下载预训练模型,如果之前已经在运行过PaddleSpeech,

则可以不用下载,它已经在目录~/.paddlespeech/models/conformer_wenetspeech-zh-16k中。

wget -c https://paddlespeech.bj.bcebos.com/s2t/wenetspeech/asr1_conformer_wenetspeech_ckpt_0.1.1.model.tar.gz

将压缩包解压wenetspeech目录下

mkdir wenetspeech
tar -xzvf asr1_conformer_wenetspeech_ckpt_0.1.1.model.tar.gz -C wenetspeech

将用于Python的模型转换为C++的,这样更方便通过内存映射的方式直接读取参数,加快模型读取速度。

./convert.py wenetspeech/exp/conformer/checkpoints/wenetspeech.pdparams

查看转换后的参数文件wenet_params.bin的md5码,md5码为9cfcf11ee70cb9423528b1f66a87eafd,表示转换正确。

md5sum -b wenet_params.bin

同时我也把转换好的wenet_params.bin上传至github,可以直接下载,可能会有些慢。

wget -c  https://github.com/chenkui164/FastASR/releases/download/V0.01/wenet_params.bin

如何使用

下载用于测试的wav文件

wget -c https://paddlespeech.bj.bcebos.com/PaddleAudio/zh.wav

执行程序

./fastasr zh.wav

程序输出

Audio time is 4.996812 s.
Model initialization takes 0.163184s
result: "我认为跑步最重要的就是给我带来了身体健康"
Model inference takes 0.462369s.

树莓派4B上优化部署

由于深度学习推理过程,属于计算密集型算法,所以CPU的指令集对代码的执行效率会有重要影响。

从纯数值计算角度来看,64bit的指令及要比32bit的指令集执行效率要提升1倍。

经过测试同样的算法在64bit系统上,确实是要比32bit系统上,执行效率高很多。

为树莓派升级64位系统raspios

树莓派官网下载最新的raspios 64位系统,

我下载的是没有桌面的精简版raspios_lite_arm64

当然也可以下载有桌面的版本raspios_arm64

两者没有太大差别,全凭个人喜好。

下载完成镜像,然后烧写SD卡,保证系统新做的系统能正常启动即可。

重新编译依赖库

尽管两个依赖库fftw3和openblas都是可以通过sudo apt install直接安装的,

但是软件源上的版本是通用版本,是兼容树莓派3B等老版本的型号,

并没有针对树莓派4B的ARM CORTEX A72进行优化,所以执行效率并不高。

因此我们需要针对树莓派4B重新编译,让其发挥最大效率。



注意:以下编译安装步骤都是在树莓派上完成,不使用交叉编译!!!

安装fftw3

下载源码

wget -c http://www.fftw.org/fftw-3.3.10.tar.gz

解压

tar -xzvf fftw-3.3.10.tar.gz
cd fftw-3.3.10/

配置工程,根据CPU选择适当的编译选项

./configure --enable-shared --enable-float --prefix=/usr

编译和安装

make -j4
sudo make install

安装OpenBLAS

下载源码

wget -c https://github.com/xianyi/OpenBLAS/releases/download/v0.3.20/OpenBLAS-0.3.20.tar.gz

解压

tar -xzvf OpenBLAS-0.3.20.tar.gz
cd OpenBLAS-0.3.20

编译和安装

make -j4
sudo make PREFIX=/usr install

编译和测试

编译和下载预训练模型的过程,请参考上文的快速上手章节。

运行程序

./fastasr zh.wav

结果

Audio time is 4.996812 s.
Model initialization takes 10.288784s
result: "我认为跑步最重要的就是给我带来了身体健康"
Model inference takes 4.900788s.

当第一次运行时,发现模型初始化时间就用了10.2s,

显然不太合理,这是因为预训练模型是在SD卡中,一个450M大小的文件从SD卡读到内存中,主要受限于SD卡的读取速度,所以比较慢。

得利于linux的缓存机制,第二次运行时,模型已经在内存中,不用在从SD卡读取了,所以只有重启后第一次会比较慢。

第二次运行结果

Audio time is 4.996812 s.
Model initialization takes 0.797091s
result: "我认为跑步最重要的就是给我带来了身体健康"
Model inference takes 4.916471s.

从结果中可以看出,当音频文件为4.99s时,推理时间为4.91秒,推理时间小于音频时间,刚刚好能满足实时性的需求。

FastASR——PaddleSpeech的C++实现的更多相关文章

  1. paddlespeech asr 使用教程

    目录 安装 paddle框架安装 软件源安装 源码安装 快速使用 下载测试使用的音频 非流式命令行接口(CLI) 非流式Server服务 流式Server服务 指令详解 打印paddlespeech_ ...

  2. 年底了是时候学新技术了「GitHub 热点速览 v.21.52」

    作者:HelloGitHub-小鱼干 年底了,又有新技术冒出来需要你来 Pick 了,第一个先要被 Pick 的是即将到来的元旦英文版:Happy New Year,再来的话就是这周非常火的新一代爬虫 ...

随机推荐

  1. LINUX系统下安装PyCharm和annaconda3并配置

    以下是在ubantu18.04版本下的配置教程: Step 1 去PyCharm官网下载Linux版的PyChram安装压缩包 网址:https://www.jetbrains.com/zh-cn/p ...

  2. Water 2.6.3 发布,一站式服务治理平台

    Water(水孕育万物...) Water 为项目开发.服务治理,提供一站式解决方案(可以理解为微服务架构支持套件).基于 Solon 框架开发,并支持完整的 Solon Cloud 规范:已在生产环 ...

  3. 沁恒CH32V103C8T6开发环境笔记

    CH32V103C8T6 CH32V103C8T6是沁恒的RISC-V内核MCU, 基于RISC-V3A处理器, 内核采用2级流水线处理,设置了静态分支预测.指令预取机制,支持DMA. 主要参数如下 ...

  4. 如何形象简单地理解java中只有值传递,而没有引用传递?

    首先,java中只有值传递,没有引用传递.可以说是"传递的引用(地址)",而不能说是"按引用传递". 按值传递意味着当将一个参数传递给一个函数时,函数接收的是原 ...

  5. JavaScript数组常用方法解析和深层次js数组扁平化

    前言 数组作为在开发中常用的集合,除了for循环遍历以外,还有很多内置对象的方法,包括map,以及数组筛选元素filter等. 注:文章结尾处附深层次数组扁平化方法操作. 作为引用数据类型的一种,在处 ...

  6. 【多线程】线程同步 synchronized

    由于同一进程的多个线程共享同一块存储空间 , 在带来方便的同时,也带来了访问 冲突问题 , 为了保证数据在方法中被访问时的正确性 , 在访问时加入 锁机制synchronized , 当一个线程获得对 ...

  7. 152. Maximum Product Subarray - LeetCode

    Question 152. Maximum Product Subarray Solution 题目大意:求数列中连续子序列的最大连乘积 思路:动态规划实现,现在动态规划理解的还不透,照着公式往上套的 ...

  8. vue生命周期加载顺序

    1.beforeCreate(创建前)表示实例完全被创建出来之前,vue 实例的挂载元素$el和数据对象 data 都为 undefined,还未初始化.此钩子函数不能获取到数据,dom元素也没有渲染 ...

  9. 课堂测试——HDFS操作

    要求: 编程实现以下功能,并利用Hadoop提供的Shell命令完成相同任务: 向HDFS中上传任意文本文件,如果指定的文件在HDFS中已经存在,则由用户来指定是追加到原有文件末尾还是覆盖原有的文件: ...

  10. Vue 基础篇---computed 和 watch

    最近在看前端 Vue方面的基础知识,虽然前段时间也做了一些vue方面的小项目,但总觉得对vue掌握的不够 所以对vue基础知识需要注意的地方重新撸一遍,可能比较零碎,看到那块就写哪块吧 1.vue中的 ...