机器学习 / 语音识别 · 2023年8月1日

Kaldi解码器移植(Nano-pi M1) 一

1.准备KALDI解码器依赖软件包:

KALDI解码器主要依赖下面几个软件包
openfst-1.6.7.tar.gz // openFST 主要用于HCLG的解码
OpenBLAS-master.zip // OpenBLAS 主要用线性代码库
clapack-3.1.1.1.tgz // Clapack 同上
alsa-lib-1.1.5.tar.bz2 // Alsa 语音采集应用层软件 (可用可不用)
pa_stable_v190600_20161030.tgz // portaudio 语音采集应用层软件(可用可不用)

我们从易到难去交叉编译,先从简单的开始

alsa-lib交叉编译

首先下载源码,这个可以自行下载,在其源码路径下创建交叉编译安装的路径output


 ./configure --host=arm-linux-gnueabi --prefix=/data/zsf/Zsf_WorkSpace/Kaldi_W
orkSpace/alsa-lib-1.1.5/output  CC=arm-linux-gnueabi-gcc

make && make install

最后checkout一下:

(base) zsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/alsa-lib-1.1.5/output$ ls
bin  include  lib  share
zsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/alsa-lib-1.1.5/output/bin$ file aserver 
aserver: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, BuildID[sha1]=beae6218c6b8f775e45496a495b002c9e9a35fc0,
 for GNU/Linux 3.2.0, with debug_info, not stripped

接下我们编译portaudio

portaudio交叉编译

下载源码,进行configure

 CC=arm-linux-gnueabi-gcc  ./configure --enable-static --host=arm-linux-gnueabi

接下来需要修改一个Makefile,因为默认OSS,我们需要上层需要用ALSA去采集语音数据,当然OSS也可以,只是OSS确实已经很老了,快要被淘汰的边缘了,在Makefile的CFLAGS中添加,主要是使能alsa

-DPA_USE_ALSA=1 

然后添加 ALSA相关的内容

CC = arm-none-linux-gnueabihf-gcc
CXX = arm-none-linux-gnueabihf-g++
CFLAGS = -g -O2 -DPA_LITTLE_ENDIAN -I$(top_srcdir)/include -I$(top_srcdir)/src/common -I$(top_srcdir)/src/os/unix -pthread -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACK
AGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_SYS_SOUNDCARD_H=1 -DHAVE_LINUX_SOUNDCARD_H=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DHAVE_CLOCK_GETTIME=1 -DHAVE_NANOSLEEP=1 -DPA_USE_ALSA=1 -DPA_USE_OSS=1 -I/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/alsa-lib-1.1.5/output/include#LIBS =  -lasound -lm -lpthread
LIBS =  -lm -lpthread -L/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/alsa-lib-1.1.5/output/lib/ -lasound
AR = arm-none-linux-gnueabihf-ar
RANLIB = arm-none-linux-gnueabihf-ranlib



OTHER_OBJS = src/hostapi/alsa/pa_linux_alsa.o src/hostapi/oss/pa_unix_oss.o src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o src/common/pa_ringbuffer.o
INCLUDES = portaudio.h pa_linux_alsa.h


LIBS =  -lm -lpthread -lasound
LDFLAGS = -L/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/alsa-lib-1.1.5/output/lib

for include in $(INCLUDES); do \
    $(INSTALL_DATA) -m 644 $(top_srcdir)/include/$$include $(DESTDIR)$(includedir)/$$include; \
done


$(INSTALL_DATA) -m 644 $(top_srcdir)/src/common/pa_ringbuffer.h $(DESTDIR)$(includedir)/$$include;
$(INSTALL_DATA) -m 644 $(top_srcdir)/src/common/pa_memorybarrier.h $(DESTDIR)$(includedir)/$$include;
$(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig




如果出现类似错误

/usr/lib/gcc-cross/arm-linux-gnueabi/9/../../../../arm-linux-gnueabi/bin/ld: lib/.libs/libportaudio.so: undefined reference to `snd_pcm_hw_params_any'
/usr/lib/gcc-cross/arm-linux-gnueabi/9/../../../../arm-linux-gnueabi/bin/ld: lib/.libs/libportaudio.so: undefined reference to `snd_pcm_areas_silence'
/usr/lib/gcc-cross/arm-linux-gnueabi/9/../../../../arm-linux-gnueabi/bin/ld: lib/.libs/libportaudio.so: undefined reference to `snd_pcm_hw_params_sizeof'
/usr/lib/gcc-cross/arm-linux-gnueabi/9/../../../../arm-linux-gnueabi/bin/ld: lib/.libs/libportaudio.so: undefined reference to `snd_config_iterator_next'
/usr/lib/gcc-cross/arm-linux-gnueabi/9/../../../../arm-linux-gnueabi/bin/ld: lib/.libs/libportaudio.so: undefined reference to `snd_pcm_hw_params_test_access'
/usr/lib/gcc-cross/arm-linux-gnueabi/9/../../../../arm-linux-gnueabi/bin/ld: lib/.libs/libportaudio.so: undefined reference to `snd_config_iterator_entry'

则修改Makefile中的lib库链接,说明没找到alsa库

LIBS =  -lm -lpthread -L/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/alsa-lib-1.1.5/output/lib/ -lasound

编译完成后 ,完成后,查下库文件,看编译是否正确

make install PREFIX=`pwd`/install

zsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/portaudio$ file install/lib/libportaudio.so.2.0.0 
install/lib/libportaudio.so.2.0.0: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=230ace3f93ce4e447eed03d2775aa46a46ed1852, wi
th debug_info, not strippedzsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/portaudio$
交叉编译openfst

下载源码,进入目录

CXX=arm-linux-gnueabi-g++ ./configure --prefix=`pwd`/install  --enable-static --enable-shared --enable-ngram-fsts --host=arm-linux-gnueabi

make 

make install

最后checkout

(base) zsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/openfst-1.6.7/install/bin$ ls
fstarcsort  fstconcat       fstdifference    fstepsnormalize  fstintersect   fstminimize  fstpush     fstreverse           fstshortestpath  fstunion
fstclosure  fstconnect      fstdisambiguate  fstequal         fstinvert      fstprint     fstrandgen  fstreweight          fstsymbols
fstcompile  fstconvert      fstdraw          fstequivalent    fstisomorphic  fstproject   fstrelabel  fstrmepsilon         fstsynchronize
fstcompose  fstdeterminize  fstencode        fstinfo          fstmap         fstprune     fstreplace  fstshortestdistance  fsttopsort
(base) zsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/openfst-1.6.7/install/bin$ file fsttopsort 
fsttopsort: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, BuildID[sha1]=09f2a910ce2f067eca3c36c97a7d0d168893c1
7c, for GNU/Linux 3.2.0, not stripped

接下就是编译较为重要的2个数学库,主要用于运算

交叉编译OpenBlas

因为用的H3,所以其架构是ARMV7的,故修改ARMV7的相关内容就可以了,接下来就可以编译了,具体的编译参数可以参照OPENBLAS的GITHUB参考内容:

make clean
make TARGET=ARMV7    ONLY_CBLAS=1 CC=arm-linux-gnueabi-gcc  AR=arm-linux-gnueabi-ar HOSTCC=gcc ARM_SOFTFP_ABI=1 -j 8

或者 如果交叉编译器包含了gfortran才用此命令
make TARGET=ARMV7 HOSTCC=gcc BINARY=32 CC=arm-linux-gnueabi-gcc FC=arm-linux-gnueabi-gfortran

  
sudo make PREFIX=`pwd`/install  install

接下来核查一个生成的文件

zsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/OpenBLAS-0.2.20/install/lib$ ls
cmake  libopenblas.a  libopenblas_armv7p-r0.2.20.a  libopenblas_armv7p-r0.2.20.so  libopenblas.so  libopenblas.so.0  pkgconfig
zsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/OpenBLAS-0.2.20/install/lib$ file libopenblas_armv7p-r0.2.20.so 
libopenblas_armv7p-r0.2.20.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=48d094f8ca9971684e0d8252904afa1100a919fc, not st
rippedzsf@kaldi-Super-Server:/data/zsf/Zsf_WorkSpace/Kaldi_WorkSpace/OpenBLAS-0.2.20/install/lib$

交叉编译clapack

下载源码,然后进入目录,将make.inc.example复制一份,重命名成make.inc :

CC        = arm-linux-gnueabi-gcc
LOADER    = arm-linux-gnueabi-gcc
ARCH     = arm-linux-gnueabi-ar
RANLIB   = arm-linux-gnueabi-ranlib
                                       

主要就是改交叉编译器,接下来就是编译,一般不会有什么问题
先进入
cd ./BLAS/SRC/
然后make
arm-linux-gnueabi-ranlib …/…/blas_LINUX.a

然后进入 cd ./F2CLIBS/libf2c/,修改Makefile

注释该两行:
#       ld -r -x -o $*.xxx $*.o
#       mv $*.xxx $*.o

注释或修改如下几行:
libf2c.a: $(OFILES)
#       ar r libf2c.a $?
#       -ranlib libf2c.a
        arm-linux-gnueabihf-ar r libf2c.a $?
        arm-linux-gnueabihf-ranlib libf2c.a

注释如下部分中的两行:
arith.h: arithchk.c
    $(CC) $(CFLAGS) -DNO_FPINIT arithchk.c -lm ||\
     $(CC) -DNO_LONG_LONG $(CFLAGS) -DNO_FPINIT arithchk.c -lm
    #./a.out >arith.h
    #rm -f a.out arithchk.o

另外:删除所有关于uninit的部分,比如uninit.o uninit.c等等。

make
如果有如下错误出现,则需要先编译INSTALL目录,因为对其有依赖

L/lsame.o arm-linux-gnueabi-ar: ../INSTALL/slamch.o: No such file or directory
make: *** [Makefile:370: ../liblapack.a] Error 1

注意不在其下面 make clean, 不然它会清除掉signal1.h的头文件 ,然后你再次编译就会编译不过

最后再进入 cd ./SRC
make
总共需要生成三个静态库,分为是lapack_LINUX.a ,blas_LINUX.a, libf2c.a

打赏作者