ASR/CV/ML      编译kaldi-android   
文章目录  [隐藏]

本文记录于2020年。各种库、软件、系统都在更新,参考时难免有差池。欢迎讨论。


需求:将kaldi编译为 Android8.0-api26、ARMv8 使用的so动态库文件。

环境1:XUbuntu20.04.3,python3.8.10、android_ndk_r20b、git、apt。(建议的编译环境)
环境2:Mac10.14.3,python3、android-ndk、git、brew。

本文参考:
https://www.jianshu.com/p/a896bc4c3c14
https://www.jianshu.com/p/905214cedf97
http://jcsilva.github.io/2017/03/18/compile-kaldi-android/
https://medium.com/swlh/compile-kaldi-for-64-bit-android-on-ubuntu-18-70967eb3a308

安装一些必须的程序:
● linux指令:

● macos指令:

gfortran可以从 https://github.com/fxcoudert/gfortran-for-macOS/releases 下载

也可以根据下文步骤说明安装。

1.准备toolchain

下载地址:https://developer.android.google.cn/ndk/downloads?hl=zh_cn ,
新版(r23b)的dmg解压出来是个app,右键显示包内容,将“NDK”目录提取出来即可。
本例为r20b,解压到用户目录下 ~/apps/android-ndk-r20b。

不要使用ndk内置的 ~/apps/android-ndk-r20b/toolchains,通过 make_standalone_toolchain.py 手动创建:


终端输入以下3句,或配置到环境变量:

linux可以配置到 ~/.bashrc,macos可以配置到 ~/.bash_profile。

2.编译openblas

下载地址:https://github.com/xianyi/OpenBLAS/releases
本例为 OpenBLAS-0.3.18.tar.gz,解压到用户目录下 ~/apps/openblas_0.3.18。
编译参考 https://github.com/xianyi/OpenBLAS/wiki/How-to-build-OpenBLAS-for-Android


如下指令,将编译完成的OpenBLAS安装在当前路径的install目录


3.编译clapack

LAPACK的全称是Linear Algebra PACKage,线性代数库,用Fortran语言开发。下载地址:https://www.netlib.org/lapack/ 。CLAPACK是LAPACK的C语言接口。
下载地址:https://github.com/simonlynen/android_libs/tree/master/lapack/jni 直接使用,
也可以从 https://www.netlib.org/clapack 下载“clapack.tgz”,参照上面的添加mk文件进行修改,本例为github版本3.2.1。
备选链接:https://pan.baidu.com/s/1RU-Md0Z5iK_2WW5-ITJkXA (提取码: jn4i)
或 https://download.csdn.net/download/Vigiles/12245335
解压到用户目录下 ~/apps/clapack_3.2.1。

修改 Application.mk 文件:


使用ndk-build编译

结束后,复制生成的 ~/apps/clapack_3.2.1/obj/local/armeabi-v8a/ 里的全部文件
libblas.a libclapack.a libf2c.a liblapack.so objs(文件夹)
到 ~/apps/openblas_0.3.18/install/lib 目录。如果没有liblapack.a,就复制 libclapack.a 为 liblapack.a 。

编译时tmglib模块缺失参考(来自 九月是我的猫 Mr-zhu0912):


4.编译kaldi

下载

本例kaldi的commit id:66f5434d29e2a528b9363e0fa25f2793069602a3
使用如下指令检查依赖库和工具是否齐全。

根据提示,linux使用ap-get、macos使用brew进行安装。

4.1.编译openfst

本步骤可参考 ~/apps/kaldi_android/tools/Makefile 文件内容,约55行开始。

不要直接在tools目录下执行make编译,否则编译kaldi时可能有下面的openfst错误:

~/apps/kaldi_android/tools/openfst-1.7.2/lib/libfst.a: error adding symbols: File in wrong format
clang80++: error: linker command failed with exit code 1 (use -v to see invocation)

下载地址:https://www.openfst.org/twiki/bin/view/FST/FstDownload
本例为openfst-1.7.2.tar.gz,解压到kaldi目录下 ~/apps/kaldi_android/tools/openfst-1.7.2。


如果报错:

configure: error: cannot run test program while cross compiling

编辑 configure 文件,约16776行,注释掉if块内语句:


编译:


4.2.编译kaldi

进入 ~/apps/kaldi_android/src/matrix,打开Makefile 文件,
TESTFILES 一行注释。

进入 ~/apps/kaldi_android/src,
打开Makefile,SUBDIRS配置了哪些模块会被编译。可以根据需要删除手机上用不到的模块,也可以添加自己开发的模块。
可以看到本例的kaldi默认只有online2,而没有online。


打开configure文件,
(1)找到约750行,
--android-incdir=*) 一项配置,设置 dynamic_kaldi=true 。
(2)约952行,
if [[ "$use_cuda" = true && ! -f $CUBROOT/cub/cub.cuh ]]; then 代码块,整个注释,关闭英伟达的GPU库cuda。

创建kaldi.mk:


如果提示:

***configure failed: aarch64-linux-android-clang++ is not installed.
You need GNU g++ >= 5.0, Apple clang >= 6.0 or LLVM clang >= 3.5. ***

可能是 --android-incdir 设置的路径未访问到,检查《1.准备toolchain》的toolchain的路径。

在 ~/apps/kaldi_android/src 目录生成kaldi.mk文件。打开修改:
约57行一项,末尾行注释并添加一条 -O3 -DNDEBUG。释义:https://www.cnblogs.com/x0rjchen/p/9310671.html 。
c++版本改为11,默认14.


编译:


生成的so文件可在 ~/apps/kaldi_android/src/lib 下找到。


这些都是软连接,可以使用cp命令拷贝22个对应的实际so文件到已存在的目录 ~/Desktop/kaldi-lib :


可以使用aarch64-linux-android-readelf查看so文件的信息。
~/apps/android-ndk-r20b/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-readelf ,
或 ~/apps/android-ndk-r20b/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-readelf。

5.cmake集成kaldi

本章节内容谨供参考,实际开发通常只在手机上做识别,用不到这么多头文件和库文件。
本例手机MiNote3,处理器是骁龙660,MIUI 12.0.1(Android 9)。


5.1.准备h文件

从 ~/apps/kaldi_android/src ,提取不包含“bin”结尾的文件夹,并且只提取h文件。
使用下面的指令和python代码,将目标文件拷贝到 ~/Desktop/kaldi_src_h 。
● 第1步shell,获取src下的文件夹名,即模块名。也可直接在python中提取:

● 第2步python:


去除cuda开头的,
添加fst的 ~/apps/kaldi/tools/openfst-1.7.2/src/include/fst 。

5.2.准备so文件

《4.2.编译kaldi》步骤已经提取到 ~/Desktop/kaldi-lib 。

5.3.Android项目配置

创建一个普通的安卓项目。
● 在java下像通常一样编写本地类方法KaldiUtil.java。
● 在main下创建cpp文件夹,
    ▶ 在cpp下创建CMakeLists.txt文件,
    ▶ 在cpp下放入自己编写的本地方法cpp及自定义的h 。
    ▶ 在cpp下创建一个kaldi文件夹,
        ★ 在kaldi下创建head和lib文件夹,
            ◆ head中放入h文件,
            ◆ lib中放入so文件。

5.3.1.本地方法java类

KaldiUtil.java :


右键 这个文件,Open in Terminal,使用javac指令生成对应的h文件,
把这个h文件改名为KaldiUtil.cpp,放到src/main/cpp下。


5.3.2.本地方法cpp实现

KaldiUtil.cpp :


kaldi.h不是必须的,这里仅供演示:


5.3.3.CMakeLists.txt

这个文件的写法很多,官方教程 https://cmake.org/cmake/help/latest/guide/tutorial/index.html 。


5.3.4.build.gradle

添加cmake相关项。


5.3.5.运行测试

进行前几步骤时,cpp代码通常会报红,可以时不时的点击菜单栏Build下的“Make Project”。
在Activity中调用一下:


日志:



整个Android项目可以从git下载测试:
https://github.com/731942771/kaldi-android
https://gitee.com/vigiles/kaldi-android


- end

承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设