《语音识别原理与应用》洪青阳 第15章 工程应用实践————嵌入式移植

嵌入式移植

《语音识别原理与技术》洪青阳 工业应用实践 书、PPT 15.4

随着物联网的发展和用户对录音隐私的担忧,现在越来越多的需求,如对智声能家居的语音控制,需要采用嵌入式平台,在本地端运行语音识别。下面我们针对ARMLinux 环境介绍嵌人式移植过程。

大部分的ARM平台都带有Linux系统,但用的是裁剪过的版本,里面的很多库跟CentOS或Ubuntu不兼容或缺少,因此移植起来较为繁琐。

以Kaldi的移植为例,其依赖的Atlas加速库包含libatlas.so和liblapack.so两个动态库,需要在ARM Linux环境重新编译。但单独编译这两个库有很多繁琐的配置,一种简便办法是通过Kaldi集成编译后得到,因为其工具包tools自带的安装脚本extras/install_atlas.sh会生成这两个so动态库。基于这两个so,重新编译引擎动态库。(下面基于这两个so动态库,按《动态库封装》这一节介绍的过程,重新编译引擎动态库)。

由于内存空间受限,很多裁剪过的ARM Linux系统,不带编译环境,即只能运行不能编译程序。为编译引擎动态库,我们需要通过交叉编译方式,在服务器另外搭一套编译的环境,所采用的gcc/g++编译器要跟ARM Linux一致,编译成功后再移植到ARM Linux环境。

有的 Linux 环境的 Atlas 加速库无法编译,只能采用 OpenBLAS 加速库,其编译出来的libopenblas.so 库还依赖其他静态库,要另外编译。这些库都准备到位后,再把它们集成到引擎动态库 Makefile 编译文件中,如以下例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CC = arm-buildroot-linux-gnueabihf-gcc
CXX = arm-buildroot-linux-gnueabihf-g++
AR = arm-buildroot-linux-gnueabihf-ar
LD = arm-buildroot-linux-gnueabihf-g++

WINDRES = windres

INC = -Isrc -Iopenfst/include -IOpenBLAS/include
CFLAGS = -std=c++11 -DHAVE_OPENBLAS -DHAVE_POSIX_MEMALIGN
RESINC =
LIBDIR =
LIB = lib/libopenblas.so
LDFLAGS = -ldl lib/libclapack.a lib/libblas.a lib/libf2c.a

其中,CC 和 CXX 指明编译器的名称,对应 gcc 和 g++的嵌入式版本,AR 和 LD配套更新。LDFLAGS用来链接以.a为扩展名的静态库。

嵌入式语音识别一般只支持命令词识别或小范围的“随便说”,如机器人的动作命令和简单的对话。对话内容可能只有几百句,语言模型就可以做得很小,而声学模型本身不会太大,因此编译出来的HCLG也就很小,文件只有几百KByte甚至更小。这样更容易部署到嵌入式平台,识别速度也更快。

针对更低端的DSP平台,嵌入式移植可能还涉及定点化问题,需要把解码器特别是特征提取和DNN的前向传播重新改写,即把浮点运算改为定点运算,而且不再包含加速库,这部分工作量比较大。