让kaldi在Linux开发板上运行起来~ (测试运行篇)
【kaldi各文件解释】
/egs:不同语料例子的执行脚本文件
/tools:存放asr过程中用到的库
/src:存放实际执行的c++算法
解码工具(src/onlinebin中):
online-gmm-decode-faster:识别从麦克风输入的语音
online-wav-gmm-decode-faster:识别指定的wav文件
【分析chain模型的目录结构】
run.sh根据wavpath生成的数据关系保存在/data里,文件解释如下:
- spk2utt 包含说话人编号和说话人的语音编号的信息
- utt2spk 语音编号和说话人编号之间的关系
- wav.scp 包含了原始语音的路径信息(格式:文件名 路径)
{local, steps, utils}里面包含了run.sh所要用到各种的脚本文件
【运行数据堂chain模型】
将数据堂训练好的模型移动到kaldi/egs的后续准备工作:
①Go to kaldi/egs/aidatatang_asr, create symlinks to /steps/ and /utils/ like this:
ln -s ../wsj/s5/steps/ steps
ln -s ../wsj/s5/utils/ utils
②设置你自己的WAVPATH
③运行模型:./run.sh WAVpath
但事情往往没那么简单。。。
【run.sh运行过程】
报错1:
需要移植python,perl。
用buildroot配置,target packages->Interpreter languages and scripting->选中python和perl
sudo make时报错
将文件复制到设备:__populate_fs: 无法为ext2文件系统分配块 写入文件“modules.symbols.bin”时
mkfs.ext4: 无法为ext2文件系统分配块 于填充文件系统时
*** Maybe you need to increase the filesystem size (BR2_TARGET_ROOTFS_EXT2_SIZE)
解决:sudo vim .config,调整BR2_TARGET_ROOTFS_EXT2_SIZE为100M
报错2:
解决:去掉.decode('utf8')
报错3:
local/decode.sh exp/chain/tdnn_1a_sp exp/chain/tdnn_1a_sp/decode_offline_test_19700101 8
utils/copy_data_dir.sh: copied data from data/offline_test to data/offline_test_hires
mktemp: Invalid argument
sort: invalid option -- 'C'
BusyBox v1.29.3 (2020-12-01 11:02:45 CST) multi-call binary.Usage: sort [-nrugMcszbdfiokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR] [FILE]...Sort lines of text-o FILE Output to FILE-c Check whether input is sorted-b Ignore leading blanks-f Ignore case-i Ignore unprintable characters-d Dictionary order (blank or alphanumeric only)-n Sort numbers-g General numerical sort-M Sort month-t CHAR Field separator-k N[,M] Sort by Nth field-r Reverse sort order-s Stable (don't sort ties alphabetically)-u Suppress duplicate lines-z Lines are terminated by NUL, not newline
utils/validate_data_dir.sh: file data/offline_test_hires/utt2spk is not sorted or has duplicates
查找包含mktemp的文件:grep -rn "mktemp" *
根据上面的结果追踪:decode.sh → utils/copy_data_dir.sh → utils/validate_data_dir.sh
tmpdir=$(mktemp -d /tmp/kaldi.XXXX);
根源:脚本是gnu版本的mktemp,而它与busybox版本的mktemp用法不同。
gnu linux核心命令和工具的源码路径
mktemp源码:ftp://ftp.mktemp.org/pub/mktemp
结果:交叉编译后在板子上正常运行!
还需要解决sort错误:
【更换coreutils】
大部分人的工作环境基本都是GNU/Linux,而我们的开发板中的工作组件(busybox-coreutils),与gnu的核心工具组件有一部分是不太兼容的,如mktemp
#mktemp --help in busybox
Create a temporary file with name based on TEMPLATE and print its name.
TEMPLATE must end with XXXXXX (e.g. [/dir/]nameXXXXXX).
Without TEMPLATE, -t tmp.XXXXXX is assumed.#mktemp --help in gnu
Create a temporary file or directory, safely, and print its name.
TEMPLATE must contain at least 3 consecutive `X's in last component.
If TEMPLATE is not specified, use tmp.XXXXXXXXXX, and --tmpdir is implied.
诸如mv,sort等命令在gnu和busybox的实现多少是有些差别的。
而因为我们要想在开发板上(移植)运行一些开源软件,就需要重新交叉编译一下移植gnu的coreutils。
手动编译:gnu-coreutils源码下载地址:https://ftp.gnu.org/gnu/coreutils/
buildroot配置coreutils:target packages → systemtool → coreutils
报错4:
执行decode.sh时莫名其妙就aborted了。。。
卡在解码!!!
手动运行解码命令:
export TRAINDIR=exp/chain/tdnn_1a_sp
export GRAPHDIR=exp/chain/tdnn_1a_sp/graph./steps/online/nnet3/prepare_online_decoding.sh $GRAPHDIR $TRAINDIR ./chain_conf #生成一些配置文件
/root/kaldi/src/online2bin/online2-wav-nnet3-latgen-faster --do-endpointing=false --frames-per-chunk=20 --extra-left-context-initial=0 --online=true --config=chain_conf/conf/online.conf --min-active=200 --max-active=7000 --beam=15.0 --lattice-beam=6.0 --acoustic-scale=1.0 --word-symbol-table=$GRAPHDIR/words.txt $TRAINDIR/final.mdl $GRAPHDIR/HCLG.fst --utt2spk=ark:data/offline_test_hires/split4/1/utt2spk 'ark,s,cs:wav-copy scp,p:data/offline_test_hires/split4/1/wav.scp ark:- |' 'ark:|lattice-scale --acoustic-scale=10.0 ark:- ark:- | gzip -c >exp/chain/tdnn_1a_sp/decode_offline_test_19700101/lat.1.gz'
报错:
what(): std::bad_alloc
经查找资源,好像是内存不够了,(别好像,就是内存不够)。
还尝试过修改源码(意义不大):
结合提示信息与nnet-compile-looped.cc上下文中的提示输出,可以定位到
for (num_requests = num_requests1; num_requests <= max_requests;num_requests *= factor) {if (CompileLoopedInternal(nnet, optimize_opts,request1, request2, request3,num_requests, computation)) {KALDI_LOG << "Spent " << timer.Elapsed()<< " seconds in looped compilation.";return;} }}
应该是for循环中内存耗尽。再看CompileLoopedInternal函数
std::vector extra_requests
修改:在CompileLoopedInternal函数结尾添加vector().swap(extra_requests); 手动清除vector空间。
意义不大。。。
#### 编译valgrind,查看内存使用情况,是否有泄漏:
buildroot → target packages → debugging… 中有valgrind选项,但下载很慢。不过手动下载也不快,然后编译也有不少问题,建议用buildroot直接配置。
下载地址:http://valgrind.org
手动编译:
#!/bin/bashCXX=arm-linux-gnueabihf-g++
CC=arm-linux-gnueabihf-gcc
./configure --prefix= --host=arm-linux-gnueabihf
make -j4
make install DESTDIR=`pwd`/build
开发板中测试,valgrind --tool=memcheck --leak-check=full ./onlinewav.sh
==554== HEAP SUMMARY:
==554== in use at exit: 26,382 bytes in 540 blocks
==554== total heap usage: 999 allocs, 459 frees, 51,831 bytes allocated
==554==
==554== 594 bytes in 33 blocks are still reachable in loss record 1 of 4
==554== at 0x483D858: malloc (vg_replace_malloc.c:307)
==554== by 0x6DC4B: initialize_signames (in /bin/bash)
==554==
==554== 1,614 bytes in 4 blocks are still reachable in loss record 2 of 4
==554== at 0x483D858: malloc (vg_replace_malloc.c:307)
==554== by 0x6DAD7: xrealloc (in /bin/bash)
==554==
==554== 1,657 bytes in 4 blocks are still reachable in loss record 3 of 4
==554== at 0x4840550: realloc (vg_replace_malloc.c:834)
==554== by 0x6DACB: xrealloc (in /bin/bash)
==554==
==554== 22,517 bytes in 499 blocks are still reachable in loss record 4 of 4
==554== at 0x483D858: malloc (vg_replace_malloc.c:307)
==554== by 0x6DA8F: xmalloc (in /bin/bash)
==554==
==554== LEAK SUMMARY:
==554== definitely lost: 0 bytes in 0 blocks
==554== indirectly lost: 0 bytes in 0 blocks
==554== possibly lost: 0 bytes in 0 blocks
==554== still reachable: 26,382 bytes in 540 blocks
==554== suppressed: 0 bytes in 0 blocks
==554==
==554== For lists of detected and suppressed errors, rerun with: -s
==554== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
没有什么发现。。。(kaldi有那么多大神在维护,源码上应该没问题的,更何况是内存泄露这种严重的问题。)
将整个文件系统烧到128G SD卡中:
本以为这会儿应该能解决了,但,,,,磁盘==内存?
我的天,plan-lastest(基本是最后的测试方案了),行不通。。。。。。。
上网查std::bad_alloc是怎么回事,在github中看到一个dan神的回复:https://github.com/kaldi-asr/kaldi/issues/3977,建议用gdb调试。
尝试用gdb调试,定位错误:
https://jason–liu.github.io/2018/01/23/gdbdebug/
【gdb调试时函数都是“?”】
猜测:交叉编译环境下和开发板运行环境中调用的lib.so.6不一样。实际用diff命令检查时,发现还真不一样。
修改kaldi.mk
删除src/nnet3和src/nnet3bin下的目标文件(*.o)
重新编译链接:make
现实是残酷的:还是存在问号。
【实际原因】:注意info sharedlibrary时报的错误(*): Shared library is missing debugging information.
动态库缺少debug 信息,但这影响的仅仅是gdb调试过程,而对kaldi实际运行过程没有影响。先跳过。
【尝试添加虚拟内存】:
尝试了很多种方法,但好像都有点问题,如
①直接NFS时创建swap文件,报swapfile has holes;
②在进入sd卡文件系统后,fdisk /dev/mmcblk0p2,对分区2(根文件系统的挂载分区)再分区,但doesn’t contain a valid partition table,fdisk命令后无法w,不起作用。也试过在虚拟机下对/dev/sdd2分区,行不通。
③sd卡下创建swap文件,运行时报mmcblk0: retrying using single block read,error:-84…
最后,在某一天晚上,在解决gdb问句和swap分区不起作用问题,都没有建树后,打算睡觉来着。但想了想再看一下,整理一下虚拟机环境(解决问号问题时尝试移植glibc库,版本不对,根文件系统直接崩溃了,还把lib目录搞的有点乱)
正文!!!:
然后又试了下运行kaldi解码,就那一刻突然开窍了,注意到了一个细节,③中:在解码时,报错会晚一点点,猜测是在尝试使用虚拟内存时报的错。说明什么?说明使用虚拟内存使得程序的崩溃点推迟了,根本原因就是运行内存不足!
重新分析添加虚拟内存时出现的问题,在尝试③中有了突破,mmcblk0: retrying using single block read,error:-84…的问题在于SD卡的读写速度太快,应该要修改一下sd卡的时钟频率。SD卡中swap文件虽然可以作为虚拟内存,但与实际内存的读写速度是不一样的。
于是我想到好像可以去dts中修改usdhc的时钟配置。而在这时突然灵光一闪,sd卡速度太快?emmc作为开发板上的默认储存器,与CPU的读写应该适配吧。然后就尝试用emmc作为虚拟内存。
mkswap /dev/mmcblk1p2
swapon /dev/mmcblk1p2
cat /proc/swap //查看交换区是否被成功启用。
重新运行kaldi,终于没报aborted或bad_alloc()了。
import zlib问题:
ModuleNotFoundError,没有找到zlib库,import zlib失败
先到steps/nnet3/decode.sh中,将stage修改为2。因为steps/nnet3/decode.sh: feature type is raw这一步花费时间实在太长了,而且在第一次测试时通过了,所以直接可以跳过。方便后面的调试。(所有步骤测试都完成后记得改回去。)
Buildroot配置python:
Target packages --》 Interpreter languages and scripting --》python
(之前配置为python3.7时,使能zlib module无效;现在换成python2.7,能成功通过import zlib)
创建一个test.py:
import zlib
print "import zlib ok."
python test.py,能正常打印说明配置成功。
结果还是要python3.7的zlib的模块,不能直接将python2中的zlib.so拷贝。
File "usr/lib/python3.7/gzip.py", line 9, in <module>
ImportError: dynamic module does not define module export function (PyInit_zlib)
怎么将python3.7编译出zlib.so链接库???
在output/build/python3.7中的Makefile和configure修改了半天,但每次重新编译buildroot时却没有反应?
buildroot重新编译问题:
解决:修改Makefile或configure后,还要将.stamp_configured或.stamp_built等删除,再重新编译buildroot。
成功解决import zlib问题。
再次运行run.sh
测试成功,不过运行要3分钟左右,也为难开发板了,只有512MB DDR3,792MHz 主频。其中的数字和字母的组合好像没识别出来,可以尝试使用其它模型(推荐CVTE的模型,正确率高达92%)或自己训练模型。
因为IMX6ULL的性能远不如树莓派4,且在其它嵌入式平台上配置不如在raspbian上方便,故而在运行时会出很多其它问题。
总结:Imx6ull的性能导致其解码识别的速度很慢,所以要实际应用到项目用,需要换更高配一些的芯片。
让kaldi在Linux开发板上运行起来~ (测试运行篇)相关推荐
- 在VIM3开发板上运行无修改的iOS内核镜像
在VIM3开发板上运行无修改的iOS内核镜像 之前在网上有看到过人使用QEMU成功的把IOS内核运行起来且成功挂载根文件系统的相关文章.理论上能在QEMU上跑成功,在真实的ARMv8开发板上运行起来也 ...
- 使用QT程序控制Linux开发板上的继电器(一)
`使用QT程序控制Linux开发板上的继电器(一)` 测试平台介绍 测试系统接线 编写PlatformIO驱动程序 修改设备树 烧录设备树 Platform字符设备驱动设备框架 完善驱动框架 编写测试 ...
- 在Developerkit开发板上运行blink例程
2019独角兽企业重金招聘Python工程师标准>>> 摘要: 本文将介绍怎么样在VScode环境下,将AliOS Tings提供的blink例程在Developerkit开发板上运 ...
- 嵌入式Linux开发板上NFS文件系统的使用【ZT】
本文转载于http://www.dz863.com/RTOS/Embedded-linux/Linux-NFS.htm 本文描述了在开发嵌入式linux系统时调试程序的一个方法,本文以深圳远峰的YF2 ...
- 海思hi3518用eclipse采用交叉编译器编译程序在海思开发板上运行
题记:在linux下开发C/C++程序时,eclipse是一款不错的IDE软件,在eclipse开发运行在linux系统下的程序时,用到 的编译工具莲是linux gcc,而如果要将eclipse开发 ...
- linux开发板上程序如何调试,linux开发板调试典型方法
tftpd sudo apt-get install tftpd openbsd-inetd 将/etc/inetd.conf中的最后一个路径设置成你希望让客户端存取文件的目录例如下面的"/ ...
- 我在这块牛X的A40i Linux开发板上点了个流水灯
为啥要搞这个linux评估板? 小飞哥自毕业以来,工作5年了,一直从事的都是嵌入式MCU层面的开发工作,还从未涉足过linux开发相关的领域,最近的一次应该是翻过<鸟哥的linux私房菜> ...
- 在riscv sifive u740开发板上运行FreeRTOS及裸板程序
riscv是当前比较火热的玩意,sifive的u740开发板是当前性能还不错的板子. sifive官方提供了一个SDK,https://github.com/sifive/freedom-e-sdk ...
- 海思AI芯片(Hi3519A/3559A)方案学习(十七)开发板上运行yolo3模型的代码分析
前言 前面的博客系列 已经介绍了如何将caffemodel转换成wk文件,如何将jpg文件转成bgr格式数据以及如何在PC上仿真模型推理等,基于这些基础,本文来结合代码分析如何在板子上推理yolov3 ...
最新文章
- 青海省计算机应用能力考试,青海省2015年职称计算机应用能力考试西宁考区四月份考试安排通知...
- Linux0.11进程分配时间片的策略
- java stream 多次读取_多次从具有大量数据的Java InputStream中读取
- idea 一直在build_CEO季度表彰团队| 我们一直在做最酷的事
- 一文读懂机器学习的常用模型评价指标
- 前端学习(2617):删除品牌
- (转)配置Website的IIS时遇到的问题与解决方法
- 日常工作中,个人总结的 - Git - 常用操作方法 (三)
- JavaScript中的[]和{}
- UCOSII系统移植详解
- 半导体芯片行业的运作模式(IDM/Fabless/Foundry模式)
- 游戏策划笔记:记忆点的构造
- 动物生存竞争对投资的启示!
- C语言 进阶版三子棋小游戏
- 【Three.js入门】标准网格材质、置换贴图、粗糙度贴图、金属贴图、法线贴图
- 自学Python 45 数字处理函数(三)
- 童年依恋风格影响成年后的两性关系
- 【opencv-c++】获得视频宽高以及帧率
- dayjs怎么处理UTC时间格式
- 知道hash值如何搜索文件
热门文章
- fastJson、JackJson以及Gson序列化对象与get、set以及对象属性之间的关系
- Unity 中子弹弓箭射击脚本
- 计算机学院职业规划大赛策划书,大学生职业生涯规划大赛策划书(策划书范文).doc...
- 如何正确拟订网络推广投资?
- 右键添加显示隐藏文件夹功能
- 租车App第一次迭代报告
- python实现键盘记录木马
- 北京喜意来误请“熊猫烧香”骗子团伙“毒王”解决password01.txt.shs病毒(图)
- 如何解决ASP.NET网站更改后上传到IIS,看到的依然是旧版内容的问题
- html css 奥运五环,用css3实现一个奥运五环