kaldi windows安装_kaldi在Windows下的使用

其实不是特别推荐在Windows下使用kaldi,因为在egs下所有的脚本都无法运行,我也是弄了很久才在Windows下配置好kaldi,都一度差点弃坑。就连官方也说There is no commitment to support Windows. The Windows port of Kaldi is targeted at experienced developers who want to program their own apps using the kaldi libraries and are able to do the troubleshooting on their own.就让我来把坑填平那么一点点吧🧐

kaldi在Windows下的安装

工具准备git

cmake

Visual Studio 2017

vs2017要注意安装win8.1 SDK,如果已经安装了vs2017,也可以在上方的菜单栏中的工具->获取工具和功能中来查看是否有安装。git和cmake的安装没有什么特别的,就不做介绍了。

编译Openfst

首先从github上将openfst clone下来。然后这里用cmake的方式来先编译出vs的工程文件,具体操作方法如下:

1

2

3

4

5git clone https://github.com/kkm000/openfst.git

cd openfst

mkdir build64

cd build64

cmake -G "Visual Studio 15 2017 Win64" ../

如果这一步成功会显示以下提示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24-- The C compiler identification is MSVC 19.11.25547.0

-- The CXX compiler identification is MSVC 19.11.25547.0

-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/cl.exe

-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/cl.exe -- works

-- Detecting C compiler ABI info

-- Detecting C compiler ABI info - done

-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/cl.exe

-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/cl.exe -- works

-- Detecting CXX compiler ABI info

-- Detecting CXX compiler ABI info - done

-- Detecting CXX compile features

-- Detecting CXX compile features - done

-- The following ICU libraries were not found:

-- data (required)

-- i18n (required)

-- io (required)

-- test (required)

-- tu (required)

-- uc (required)

-- Failed to find all ICU components (missing: ICU_INCLUDE_DIR ICU_LIBRARY _ICU_REQUIRED_LIBS_FOUND)

-- Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)

-- Configuring done

-- Generating done

-- Build files have been written to: C:/Users/jtrmal/Documents/openfst/build64

成功后会在build64目录下面生成一个openfst.sln文件,用vs2017打开这个文件,分别用Debug|x64和Release|x64来生成一遍,如下图,如果失败为0则代表编译通过。

配置OpenBLAS

首先也是从github上先将kaldi clone下来

1git clone https://github.com/kaldi-asr/kaldi.git kaldi

然后我们就需要去配置线性代数库,这里有两个选择,一个是Intel MKL,一个是OpenBLAS。这里我选用OpenBLAS。用下面的命令来下载OpenBLAS的二进制包(在kaldi/tools目录下):

1

2curl -L -O http://sourceforge.net/projects/openblas/files/v0.2.14/OpenBLAS-v0.2.14-Win64-int32.zip

unzip OpenBLAS-v0.2.14-Win64-int32.zip

注意这里要下载Win64-int32版本,而不是Win64-int64版本

修改配置文件

进入kaldi/windows路径想,将varialbe.props.dev复制一份重命名为variables.props,打开后将刚刚配置好的库修改为自己的路径:

1

2

3

4

5

6

7

C:\Program Files\(x86)\IntelSWTools\compilers_and_libraries\windows\mkl\

C:\Users\Yenda\Downloads\kaldi-svn\tools\OpenBLAS-v0.2.14-Win64-int32

C:\Users\jtrmal\Documents\openfst

C:\Users\jtrmal\Documents\openfst\build64

我们需要将OpenBLAS和Openfst修改为自己的路径,因为没有用到MKL就不用修改了。下面就是我修改后的路径:

1

2

3

4

5

6

7

C:\Program Files(x86)\IntelSWTools\compilers_and_libraries\windows\mkl\

D:\git_home\kaldi\tools\OpenBLAS-v0.2.14-Win64-int32

D:\git_home\openfst

D:\git_home\openfst\build64

产生工程文件

同样还是在kaldi/windows路径下,因为我们是使用OpenBLAS所以就把kaldiwin_openblas.props复制一份重命名为kaldiwin.prosp。然后在windows路径下用git bash运行以下命令:

1

2./generate_solution.pl --vsver vs2017 --enable-openblas

./get_version.pl

kaldi编译测试

然后我们打开在kaldi/kaldiwin_vs2017_OPENBLAS这个新生成的文件夹,打卡里面的kaldiwin_vs2017.sln工程文件,这里面就包括了所有kaldi/src中*bin中的.cc文件。这时候需要来测试一下kaldi能否运行,首先要把Debug|Win32改为Debug|x64,然后右键选择online2-wav-nnet2-latgen-faster生成,如下图,如果生成成功则代表之前的工作都做对啦,kaldi已经配置好了✌️~exe文件会生成在kaldiwin_vs2017_OPENBLAS/x64/Debug中,不过当用命令行来运行刚刚生成的exe文件时,还是有可能会报错,如缺少dll等,解决方法见常见问题。

kaldi在Windows下的调试

新建自己的kaldi项目

在配置好kaldi之后,就可以开始调试和编写自己的使用kaldi的程序了。不过原来的kaldi项目中有630个项目或者称为解决方案,每次打开都要加载很久。所以我们可以新建一个空项目:

添加引用

然后点击左上角文件->添加->现有项目,切换到kaldi/kaldiwin_vs2017_OPENBLAS/kaldiwin路径下。

最好把所有以kaldi开头的项目都添加进去(点进去具体的文件夹,添加.vcxproj文件),包含test的不用。不过如果你清楚你用的项目要用到哪些具体的引用,那么只添加特定的项目即可。那么要怎么看需要用到那些引用呢,这时就要回到之前那个包含630个项目的vs中去。

比如说我想要提取mfcc特征,就可以去看看compute-mfcc-feats这个项目中以用了那些项目,然后在自己的项目提取mfcc特征项目中,也要以用相同的项目,那么就把对应的项目添加到自己的项目中,如下图:

添加工程属性表

配置好引用还需要我们去添加刚才配置好的vs工程属性表,点开左上菜单栏中的视图->其他窗口->属性管理器。

然后在自己的项目的Debug|64中添加variables.props kaldiwin.props openfst_debug.props(如果要release则添加对应的release版本)

修改附加包含目录

还差一步就大功告成,首先要在自己的项目中添加一个cpp文件,然后右键属性->C/C++->所有选项->附加包含目录,需要把kaldi/src目录添加进去

配置好之后,就可以写自己的调用kaldi的程序了,之后也可以按照这样的方式来。总结一下:

在当前项目中文件->添加->新建项目

添加需要用到的引用

添加已经配置好的工程属性表

最后把kaldi/src添加到附加包含目录就可以了

另外要记住调试模式要切换成Debug|x64

写自己的kaldi程序

如果想写自己的调用kaldi的程序要怎么开始呢,最好的办法就是去看run.sh中用到了哪些命令,然后在看命令中C++代码是怎么做的。以提取mfcc特征为例,在声纹识别中,一般都是下面几条命令用来提取mfcc特征:

1

2

3

4

5

6

7

8

9

10#run.sh

#Now make MFCC features.

#mfccdir should be some place with a largish disk where you

#want to store MFCC features.

mfccdir=mfcc

for x in train test; do

steps/make_mfcc.sh --cmd "$train_cmd" --nj 10 data/$x exp/make_mfcc/$x $mfccdir

sid/compute_vad_decision.sh --nj 10 --cmd "$train_cmd" data/$x exp/make_mfcc/$x $mfccdir

utils/fix_data_dir.sh data/$x

done

具体的提取mfcc的特征程序就在steps/make_mfcc.sh中了

1

2

3

4

5

6

7#make_mfcc.sh

$cmd JOB=1:$nj $logdir/make_mfcc_${name}.JOB.log \

extract-segments scp,p:$scp $logdir/segments.JOB ark:- \| \

compute-mfcc-feats $vtln_opts --verbose=2 --config=$mfcc_config ark:- ark:- \| \

copy-feats --compress=$compress $write_num_frames_opt ark:- \

ark,scp:$mfccdir/raw_mfcc_$name.JOB.ark,$mfccdir/raw_mfcc_$name.JOB.scp \

|| exit 1;

里面具体提取mfcc特征的命令就应该是steps/make_mfcc.sh了,看下make_mfcc.sh,在经过一系列处理后,使用compute-mfcc-feat这个命令来提取mfcc特征的。我们就可以去看在featbin下的compute-mfcc-feat.cc中是如何提取mfcc特征的,下面就贴上我的提取mfcc并写入一个txt文件的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53#include

#include

#include"feat/feature-mfcc.h"

#include"feat/wave-reader.h"

#include"base/kaldi-math.h"

#include"matrix/kaldi-matrix-inl.h"

#include"matrix/kaldi-vector.h"

int main(int argc,char * argv[]){

try {

using namespace kaldi; //要记住使用namespace kaldi

const char * Usage =

"my_kaldi.exe [wav_filename] [mfcc_filename] \n";

ParseOptions po(Usage);

po.Read(argc, argv);

if (po.NumArgs() != 2) {

po.PrintUsage();

exit(1);

}

std::string wav_filename = po.GetArg(1);

std::string mfcc_filename = po.GetArg(2);

/*读取wav文件*/

std::ifstream wav_file;

wav_file.open(wav_filename, std::ios_base::binary);

WaveData wave;

wave.Read(wav_file);

SubVector waveform(wave.Data(), 0);//将wav文件数据放到waveform中

/*mfcc特征配置*/

MfccOptions mfcc_opts;

mfcc_opts.frame_opts.samp_freq = 16000;

mfcc_opts.frame_opts.frame_length_ms = 25;

mfcc_opts.frame_opts.frame_shift_ms = 10;

mfcc_opts.frame_opts.preemph_coeff = 0.95;

/*提取mfcc特征*/

Matrix mfcc_feature;

Mfcc feat(mfcc_opts);

feat.ComputeFeatures(waveform, wave.SampFreq(), 1.0, &mfcc_feature);

/*写入到文件中*/

WriteKaldiObject(mfcc_feature,mfcc,false);

//kaldi中都可以使用WriteKaldiObject来写使用到的kaldi对象

}

catch (const std::exception &e) {

std::cerr << e.what();

return -1;

}

return 0;

}

kaldi模型的读取

在windows上跑kaldi,不可避免地会用到kaldi中的I/O接口,比如读取在Linux下已经训练好的模型等。kaldi中的模型往往都是一个类,比如说声纹识别中用到的UBM类FullGmm,提取ivector的IvectorExtractor等等,对于这些类的提取都可以用ReadKaldiObject来完成

1

2

3

4using namespace kaldi;

FullGmm fgmm; //首先要声明想要读取的模型的类

std::string ubmFile = "final.ubm"; //然后确定文件名

ReadKaldiObject(ubmFile, &fgmm);

对于其他的模型,也可以通过类似的方法来读取到内存中。如果想把模型等写出来也可以通过WriteKaldiObject来完成。

kaldi在Windows下的移植

此处的移植指的是能够使kaldi在一台没有开发环境下的电脑中正常运行。刚开始要做的时候感觉可能会有各种的坑,不过实际中做要比想象中简单得多,如果上面配置基本没什么问题,移植的话也就没什么问题了。

生成exe

生成exe其实很简单,在每次Debug的时候都会自动生成一个可执行文件,不过要想在一个没有开发环境的电脑上使用,要用Release来重新生成一下。我们可以用main(int argc, char * argv[])来读取命令行的参数,然后可以用ParseOptions po(Usage);来控制输入的参数,具体参考上面提取mfcc的代码,这里就不做过多的介绍了。在移植过程中还遇到的一个问题就是缺少一些dll,主要是mingw的一些dll,解决方法见下面遇到的问题。

生成dll

如果想生成dll打包给其他程序用,就需要在头文件中想要导出的函数的前面加上declspec(dllexport),并且右键右侧的项目属性栏,把常规中的项目默认值->配置类型改为动态库(.dll)

遇到的问题记录

cmake生成Openfst工程文件失败

根据错误提示,应该是缺少了fst_test.h weight-tester.h algo_test.h,在openfst/src目录下搜索这几个文件,发现都在openfst\src\include\fst\test中,于是把几个文件都复制过来,然后再执行那条cmake的命令,就可以成功了~。

缺少libopenblas.dll

当在命令行或git bash中运行生成好的exe时,会报错缺少libopenblas.dll:

我们需要将之前下载的OpenBLAS中bin目录下的libopenblas.dll拷到和exe文件同一个文件夹中就可以执行了。

mingw dll下载

包括libgcc_s_seh-1.dll libgfortran-3.dll libquadmath-0.dll,下载后同样需要放到和exe同一目录下。

1

2curl -L -O http://sourceforge.net/projects/openblas/files/v0.2.14/mingw64_dll.zip

unzip mingw64_dll.zip

参考资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/267933.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#委托的异步调用[转]

本文将主要通过“同步调用”、“异步调用”、“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊。 首先&#xff0c;通过代码定义一个委托和下面三个示例将要调用的方法&#xff1a; /*添加的命名空间using System.Threading;using System.Runtime.…

[Python] isinstance() for checking object type

isinstance("foo", str) isinstance(1, int) isinstance(4.0, float) 转载于:https://www.cnblogs.com/Answer1215/p/8018722.html

钉钉微应用怎么进入_蓝凌携手钉钉走进越秀地产,零距离热聊企业数字化转型...

8月18日&#xff0c;蓝凌携手钉钉一同走进越秀地产&#xff0c;举办了《地产行业数字化实战闭门分享会》主题活动&#xff0c;与30余名嘉宾欢聚一堂&#xff0c;体验智慧管理实践与数字工作模式&#xff0c;探索企业数字化转型升级之道。越秀地产CIO陈磊、越秀地产信息总监郑毅…

mysql5.7半自动同步设置【转】

mysql的主从复制主要有3种模式&#xff1a; a..主从同步复制&#xff1a;数据完整性好&#xff0c;但是性能消耗高 b.主从异步复制&#xff1a;性能消耗低&#xff0c;但是容易出现主从数据唯一性问题 c.主从半自动复制&#xff1a;介于上面两种之间。既能很好的保持完整性&…

virsh 关机_kvm虚拟机不能使用virsh shutdownw命令关闭虚拟机的解决方法

今天笔者在对kvm虚拟机进行管理时&#xff0c;使用virsh shutdown命令关闭指定的虚拟机时&#xff0c;发现虽然有如下的提示&#xff0c;但其实虚拟机却一直不会真正的关闭。经过查看virsh命令帮助和上网查询&#xff0c;才得知virsh shutdown命令使用发送acpi指令来控制虚拟机…

Android之旅---广播(BroadCast)

什么是广播在Android中&#xff0c;Broadcast是一种广泛运用的在应用程序之间传输信息的机制。我们拿广播电台来做个比方。我们平常使用收音机收音是这样的&#xff1a;许许多多不同的广播电台通过特定的频率来发送他们的内容&#xff0c;而我们用户只需要将频率调成和广播电台…

python牛客网编程题_【面经】小米软件开发一面(python)面经 2020 2020

作者&#xff1a;JessyTsuihttps://www.nowcoder.com/discuss/580721?type2&order0&pos15&page1&channel-1&source_iddiscuss_tag_nctrack来源&#xff1a;牛客网小米软件开发一面(python)面经一共三轮技术面&#xff0c;第四轮是HR面&#xff0c;已OC&am…

IDS与IPS

IDS是英文“Intrusion Detection Systems”的缩写&#xff0c;中文意思是“***检测系统”。专业上讲就是依照一定的安全策略&#xff0c;对网络、系统的运行状况进行监视&#xff0c;尽可能发现各种***企图、***行为或者***结果&#xff0c;以保证网络系统资源的机密性、完整性…

c# 数组和集合

数组是最为常见的一种结构&#xff0c;是相同类型的、用一个标识符封装到一起的j基本类型数据序列或对象序列&#xff0c;可以用一个统一的数组名和下标来唯一确定数组中的元素。实质上数组是一个简单的线性序列&#xff0c;因此数组访问起来很快。而集合可以看成一种特殊的数组…

和vs版本关系_栈局部变量优化探究,意外发现了 vs 的一个 bug ?

缘起 我在《栈又溢出了》一文中记录了一个奇怪的栈溢出问题。虽然解决了&#xff0c;但是总感觉哪里不太合理。我想&#xff0c;vs 一定有一个合理的设置。一起折腾起来吧&#xff01;查找工程设置 本以为能找到某个编译选项对局部变量占用内存的行为进行控制。看遍了工程设置也…

Visual C++ 时尚编程百例009(响应键盘)

按钮消息WM_KEYDOWN,WM_CHAR,WM_KEYUP在CXXXDoc.h中添加变量CString Text;在构造函数中初始化Cvc1001Doc::Cvc1001Doc(){ // TODO: 在此添加一次性构造代码 Text_T("");}右击CXXXView类->属性->消息->WM_CHARvoid Cvc1001View::OnChar(UINT nChar, UINT nRe…

在ubuntu 16.04上安装tensorflow,并测试成功

用下面代码测试安装&#xff1a; 1 #! /usr/bin/python2 # -*- coding: utf-8 -*-3 4 import tensorflow as tf5 import numpy6 import matplotlib.pyplot as plt7 rng numpy.random8 9 learning_rate 0.01 10 training_epochs 1000 11 display_step 50 12 #数据集x 13 tra…

redis客户端连接数量_实战解析无所不知的Redis拓展应用——Info,进阶学习,无所不能...

前言学习是一个持续的过程。像咱们一直在更新的Redis学习内容&#xff0c;由基础结构&#xff0c;到原理应用&#xff0c;再到集群搭建&#xff0c;了解的够充分了&#xff0c;咱们接着又介绍Redis拓展应用&#xff0c;将知识面拓宽&#xff0c;毕竟技术都是相通的&#xff0c;…

诡异的防火墙故障,能PING通,但访问ORACLE不稳定

上周四我们的IDC核心数据区到DMZ区的防火墙经历了十分诡异的故障。 虽然我从一开始就断定非ORACLE问题&#xff0c;因为连接核心数据区的多个ORACLE数据库的应用都无一例外的出现了相同的问题&#xff0c;如果三个以上ORACLE能同时出想这么严重的问题&#xff0c;那么我想ORACL…

【Excle数据透视】如何用含有单元格的数据来创建数据透视

取消合并单元格&#xff0c;填充相同内容项&#xff0c;然后创建数据透视表. 如下图&#xff1a;需要使用数据创建数据透视表 步骤一 开始→格式刷&#xff0c;然后对单元格区域G2&#xff1a;G15使用格式刷功能&#xff0c;保留合并单元格格式 步骤二 选中A2&#xff1a;A18区…

css 超出文字头尾相接滚动_前端的一些雕虫小技,从100%和滚动条说起

1、100%和滚动条当我们在css中把html和body同时设为100%时&#xff0c;会出现滚动条html,body {width: 100%;height: 100%;}原因是html和body之间有8px的margin&#xff0c;这个margin怎么来的呢&#xff0c;我们在chrome中用F12看一下这个8px的margin来自于user agent stylesh…

[转] C# 路径(目录)

一、获取当前文件的路径1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName获取模块的完整路径&#xff0c;包括文件名。2. System.Environment.CurrentDirectory获取和设置当前目录(该进程从中启动的目录)的完全限定目录。3. System.IO.Directory.GetCur…

《大鱼海棠》

我告诉你什么事最可悲&#xff0c;你遇见一个人&#xff0c;犯了一个错&#xff0c;你想弥补想还清&#xff0c;到最后才发现&#xff0c;你根本无力回天&#xff0c;犯下的罪过永远无法弥补转载于:https://www.cnblogs.com/ting6/p/9726163.html

class参数传入 python_小白学 Python 爬虫(20):Xpath 进阶

人生苦短&#xff0c;我用 Python如果我的文章对您有帮助&#xff0c;请关注支持下作者的公众号&#xff1a;极客挖掘机&#xff0c;您的关注&#xff0c;是对小编坚持原创的最大鼓励&#xff1a;)前文传送门&#xff1a;小白学 Python 爬虫(1)&#xff1a;开篇小白学 Python 爬…

shellcode

Shellcode实际是一段代码&#xff08;也可以是填充数据&#xff09;&#xff0c;是用来发送到服务器利用特定漏洞的代码&#xff0c;一般可以获取权限。 另外&#xff0c;Shellcode一般是作为数据发送给受攻击服务的。 Shellcode是溢出程序和蠕虫病毒的核心&#xff0c;提到它…