在线解码器

警告:这是一个旧版本的在线解码器的文档。最新的在线解码文章在这里

在kaldi 的工具集里有好几个程序可以用于在线识别。这些程序都位在src/onlinebin文件夹里,他们是由src/online文件夹里的文件编译而成(你现在可以用make ext 命令进行编译).这些程序大多还需要tools文件夹中的portaudio 库文件支持, portaudio 库文件可以使用tools文件夹中的相应脚本文件下载安装。这些程序罗列如下:

  • online-gmm-decode-faster: 从麦克风中读取语音,并将识别结果输出到控制台
  • online-wav-gmm-decode-faster:读取wav文件列表中的语音,并将识别结果以指定格式输出。
  • online-server-gmm-decode-faster:从UDP连接数据中获取语音MFCC向量,并将识别结果打印到控制台。
  • online-net-client :从麦克风录音,并将它转换成特征向量,并通过UDP连接发送给online-server-gmm-decode-faster
  • online-audio-server-decode-faster :从tcp连接中读取原始语音数据,并且将识别结果返回给客户端
  • online-audio-client :读出wav文件列表,并将他们通过tcp 发送到online-audio-server-decode-fater,得到返回的识别结果后,将他存成指定的文件格式

代码中还有一个java版的online-audio-client ,他包含更多的功能,并且有一个界面。另外,还有一个与GStreamer 1.0兼容的插件,他可以对输入的语音进行识别,并输出的文字结果。这个插件基于onlinefasterDecoder,也可以做为在线识别程序

在线语音服务器

online-server-gmm-decode-faster 和online-audio-server-decode-faster的主要区别是各自的输入不同,前者接受特征向量做为输入,而后者则接收原始音频。后者的好处是他可以处理任意客户端直接传过来的数据:不管他是互联网上的计算机还是一部移动设备。最主要的是客户端不需要知道训练模型使用了何种特征集,只要设定好预先定义的采样率和位深度,他就可以跟服务器进行通信。使用特征向量做为输入的服务器的一个好处是,在客户端和服务器之间传输的数据比音频服务器小得多,而这只需使用简单的音频代码就可以实现。

在online-audio-client和online-audio-server-decode-faster之间的通信包括两个步骤:第一步客户端将原始音频数据包发送给服务器,第二步服务器将识别结果发回给客户端。这两步可以同步进行,这意味着解码器不用等音频数据发送完毕,就可以在线输出结果,这给未来新的应用提供了很多可以扩展的功能。

音频数据

音频数据格式必须是采样率16KHz,16-bit 位深,单声道,线性PCM编码的硬编码数据。 通信协议数据分为块和前缀,每一个块包含4字节指示此块的长度。这个长度值也是一个long型little-endian值,可以是正也可以是负(因为是16-bit采样)。最后一个长度为0的包被当作音频流的结束,这将迫使解码器导出所有剩余的结果,并且结束识别过程

识别结果

服务器返回两种类型的结果。时间对齐结果和部分结果。

解码器识别出每一个词都会立即发送一个部分结果,而当解码器识别到一次发音结束时则会发送一个时间对齐结果(这可能是也可能不是一次停顿或者句子结束)。

每一个部分结果包会有以字符串:“PARTIAL:"开头,后面跟一个词,每一个词发送一次不同的部分结果包。时间对齐结果包会以字符串:"RESULT:"开头。后面是以逗号为分格的key=value参数列表,这些参数列表包含一些有用信息。

  • NUM:后面词的个数
  • FORMAT :返回结果的格式,目前只支持WSEC格式(词-开始-结束-置信度),未来会允许修改
  • RECO-DUR: 识别语音所使用的时间。(以秒计的浮点型值)
  • INPUT-DUR:输入语音的时间长度(以秒计的浮点型值) 你可以用识别时间除以输入时间得到解码器的实时识别速度。当服务器将识别结果全部返回后会发送一个"RESULT:DONE", 这种情况下服务器会等待输入或是断开。

在数据头部后面包含有NUM行以FORMAT格式组成的词行,现在的WSEC格式,只是简单以逗号分隔的四个部分:词,起始时间,终止时间(以秒计的浮点数),置信度(0-1之间浮点数)要记住这些词只是在词典中的编码,因此客户端必须执行转换操作。online-audio-client 在生成webvtt文件时不进行任何字符转换,因此你需要用iconv将结果文件转换成UTF8

服务器返回的结果的例子如下:

RESULT:NUM=3,FORMAT=WSEC,RECO_DUR=1.7,INPUT_DUR=3.22
 one,0.4,1.2,1
 two,1.4,1.9,1
 three,2.2,3.4,0.4
 RESULT:DONE

使用举例

命令行启动服务器:

online-audio-server-decode-faster --verbose=1 --rt-min=0.5 --rt-max=3.0 --max-active=6000 --beam=72.0 --acoustic-scale=0.0769 final.mdl graph/HCLG.fst graph/words.txt '1:2:3:4:5' 5010 graph/word_boundary_phones.int final.mat

各参数含义如下:

  • final.mdl :声音模型文件
  • HCLG.fst :完全的fst
  • words.txt:发音词典(将词的id号映射到对应的字符上)
  • '1:2:3:4:5' :sil 的id号
  • 5010 :服务器的端口号
  • word_boundary_phones.int :词对齐时使用的音素边界信息
  • final.mat :特征的LDA矩阵

命令行启动客户端

 online-audio-client --htk --vtt localhost 5010 scp:test.scp

各参数含义如下

  • –htk 结果存成htk 标注文件
  • –vtt 结果存成webvtt文件
  • localhost 服务器地址
  • 5010 服务器端口号
  • scp:test.scp Wav文件的列表文件

命令行方式启动java客户端

java -jar online-audio-client.jar

或者直接在图形界面上双点jar文件

GStreamer 插件

Kaldi 工具集为GStream 多媒体流框架提供了一个插件(1.0或兼容版)。此插件可以做为过滤器,接收原始音频做为输入并将识别结果做为输出。这个插件的主要好处是他使得kaldi 在线语音识别功能对所有支持GStreamer1.0的编程语言都可用(包括python,ruby,java,vala等等)。这也使得可以把kaldi 在线解码器集成到支持GStreamer 通信标准的应用程序中

安装

GStreamer 插件的源码位于src/gst-plugin 目录。要完成编译,kaldi工具集的其它部分必须使用共享库进行编译。因此在配置的时候必须使用--shared 参数,同进需要编译在线扩展(make ext).确保支撑GStreamer 1.0开发头文件的包已经安装在你的系统中。在Debian Jessie系统版本中,需要包libgstreamer1.0-dev。在Debian Wheezy版本中,GStreamer 1.0 可以从backports源中下载到。需要安装gstreamer1.0-plugins-good和gstreamer1.0-tools这两个包。演示程序还需要PulseAudio Gstreamer插件 ,包名:gstreamer1.0-pulseaudio

最后,在src/gst-plugin目录中运行make depend和make。这样就会生成一个文件src/gst-plugin/libgstkaldi.so,他包含了GStreamer 插件。为确保GStreamer 可以找到kaldi 插件,必须把src/gst-plugin目录加到他的插件搜索目录。因此需要把这个目录加入环境变量中 export GST_PLUGIN_PATH=$KALDI_ROOT/src/gst-plugin 当然,你需要把$KALDI_ROOT修改成你自己文件系统中kaldi所在 的根目录。

未完待续。