Moses目前支持三个语言模型工具包:SRILM(The SRI language modeling toolkit),IRSTLM(IRST language modeling toolkit)和RandLM(the RandLM language modeling toolkit). SRILM我已经多次介绍过了,这里再介绍一下IRSTLM。
IRSTLM是意大利Trento FBK-IRST实验室开发的语言模型训练工具包,其开发的目的是处理较大规模的训练数据,譬如Google提供给LDC的训练好的语言模型是在海量单语语料库(8 trillion-word texts)的基础上训练的。在大规模语言模型的训练和使用上,IRSTLM较SRILM有较大的优势,其内存消耗仅是SRILM的一半。
IRSTLM在训练语言模型时采用了划分词典分块训练快速合并的方式,从而在训练大规模语料时取得了优异的性能。IRSTLM 训练语言模型时分以下 5 步:
1)在训练语料上统计带词频词汇表;
2)按照词频均衡的原则将词汇表划分为若干个子词汇表;
3)对各个子词汇表统计 n-gram,这些 n-gram 必须以词汇表中的词汇开头;
4)根据第四步的统计结果,建立多个子语言模型;
5)把所有的子语言模型融合成最终语言模型;
事实上,我也是首次使用这个工具包,安装和使用过程中遇到一些问题,这些问题总结起来可能与我的Linux环境有关(ubuntu8.10, gcc,g++默认都是4.3版本, /bin/sh指向/bin/dash),这里做个详细说明,希望能对将来遇到这些问题的用户有所帮助:
1、建立irstlm目录并利用svn下载安装包(目前的最新版本是 irstlm-5.20.01):
52nlp@52nlp-desktop:~/mtworkdir$ mkdir irstlm
52nlp@52nlp-desktop:~/mtworkdir$ svn co https://irstlm.svn.sourceforge.net/svnroot/irstlm irstlm
2.安装,irstlm的安装说明很简单,没有srilm那么繁琐,进入其主目录运行install脚本即可:
52nlp@52nlp-desktop:~/mtworkdir$ cd irstlm/
52nlp@52nlp-desktop:~/mtworkdir/irstlm$ ./install
但是,这一步却发生了如下错误:
mfstream.h:98: 错误: ‘memmove’不是‘std’的成员
注:如果你没有遇到此问题,请直接跳到第3步;如果你遇到了此问题,请先阅读一下倒数3段,再考虑是否按如下的方法修改。
进入src目录,打开mfstream.h文件:
52nlp@52nlp-desktop:~/mtworkdir/irstlm$ cd src/
52nlp@52nlp-desktop:~/mtworkdir/irstlm/src$ vi mfstream.h
发现第98行是:
std::memmove (buffer+(4-numPutback), gptr()-numPutback, numPutback);
将std::去掉,即换成:
memmove (buffer+(4-numPutback), gptr()-numPutback, numPutback);
再运行install,OK!
52nlp@52nlp-desktop:~/mtworkdir/irstlm/src$ cd ..
52nlp@52nlp-desktop:~/mtworkdir/irstlm$ ./install
但是,这种修改方法却为后来使用时的错误(buffer overflow detected)埋下了隐患。
3.试用:
在irstlm/doc目录下有irstlm 的使用手册(irstlm-manual.pdf),按照它的说明,我尝试着使用了一下irstlm工具包,另一方面也就是验证一下安装是否正确。
下载的irstlm包里有样本可以用来训练和测试,在irstlm/example目录下有两个文件,分别是测试用的test和训练用的train.gz。
以下我们使用irstlm训练一个ARPA格式的语言模型,和SRILM生成的语言模型文件格式相同:
进入example:
52nlp@52nlp-desktop:~/mtworkdir/irstlm$ cd example
首先建立一个stat目录,这个目录是训练脚本运行过程中存放临时的切分词汇表等文件的:
52nlp@52nlp-desktop:~/mtworkdir/irstlm/example$ mkdir stat
然后按使用手册的说明运行build-lm.sh脚本,此脚本在irstlm/scripts目录下:
52nlp@52nlp-desktop:~/mtworkdir/irstlm/example$ ../scripts/build-lm.sh -i "gunzip -c train.gz" -n 3 -o train.ilm.gz -k 5
但是这一步运行时报错如下:
Set IRSTLM environment variable with path to irstlm
这里要声明IRSTLM的安装路径:
export IRSTLM=/home/52nlp/mtworkdir/irstlm
export PATH=$PATH:$IRSTLM/bin:/$IRSTLM/bin/$MACHTYPE
之后再运行上面那个脚本,这一次又出现如下错误:
Cleaning temporary directory stat
../scripts/build-lm.sh: 145: Syntax error: Bad fd number
查了一下,这个错误的原因是ubuntu将/bin/sh/指向/bin/dash而不是/bin/bash,这里将scripts目录下的bulit-lm.sh的第一行#! /bin/sh 修改为#! /bin/bash。然后再运行:
52nlp@52nlp-desktop:~/mtworkdir/irstlm/example$ ../scripts/build-lm.sh -i "gunzip -c train.gz" -n 3 -o train.ilm.gz -k 5
这一次又出现了如下错误:
...
Collecting 1-gram counts
sh: /usr/bin/gzip: not found
...
irstlm的问题真多!
这一次发现gzip,gunzip都在/bin目录下,于是在scripts里将build-sublm.pl, merge-sublm.pl, lm-stat.pl 等几个perl脚本里的:
my $gzip="/usr/bin/gzip" 修改为 my $gzip="/bin/gzip";
my $gunzip="/usr/bin/gunzip"修改为my $gunzip="/bin/gunzip";
但是再次运行还是出现同样的错误。
于是将/bin下的gizp, gunzip拷贝到/usr/bin下,终于运行通过了。
注意这一步生成的train.ilm.gz的文件格式并不是最终的ARPA格式,是一种中间格式,称之为iARPA,这个格式Moses解码时可以识别。
下一步将这个文件转换为标准的ARPA格式,使用如下命令:
52nlp@52nlp-desktop:~/mtworkdir/irstlm/example$:
../bin/i686/compile-lm train.ilm.gz --text yes train.lm
因为环境路径已经声明了,也可以直接使用:
52nlp@52nlp-desktop:~/mtworkdir/irstlm/example$: compile-lm train.ilm.gz --text yes train.lm
这一次,问题又来了:
...
1-grams: reading 15059 entries
2-grams: reading 142684 entries
*** buffer overflow detected ***: ../bin/i686/compile-lm terminated
这个错误差点让我崩溃,Google国内外怎么也找不到一点线索,弄到最后开始怀疑起我的4核机器了,我想莫非irstlm对多核机器不支持?于是拿我以前的单核机器做实验,却发现第一个问题”mfstream.h:98: 错误: ‘memmove’不是‘std’的成员“并没有出现,这一下子让我想起了“Giza++不能被gcc,g++4.3或更高版本编译的问题”了,原因再于这台旧机器的gcc,g++是4.1版本,于是打开install脚本,发现它调用irstlm/src下的makefile文件,又打开src目录下的makefile,发现第9行是CPPEXE=g++ ,将其修改为CPPEXE=g++-4.1,重新运行./install,这个问题最终解决了。
注意,如果你还没有安装g++4.1版本,请先安装: sudo apt-get install g++-4.1 。如果你已经在第2步安装时按我的方法将mfstream.h的第98行的std::去掉了,请将其再修改回来或者重新编译一个新的下载版本。
最终生成的train.lm就是标准的ARPA格式的语言模型文件了。
注:原创文章,转载请注明出处“我爱自然语言处理”:www.52nlp.cn
本文链接地址:https://www.52nlp.cn/language-modeling-toolkit-irstlm-installation-and-trial-noting/
看到你介绍的HMM最佳实践,挺有用的。感谢!
[回复]
admin 回复:
16 6 月, 2009 at 22:36
不用客气,欢迎常来看看!
[回复]
这个工具包训练出来的语言模型文件格式和SRILM一样么?
[回复]
52nlp 回复:
26 10 月, 2010 at 08:44
一样的,都是ARPA格式的语言模型。
[回复]
"*** buffer overflow detected ***: ../bin/i686/compile-lm terminated" 问题搞了好久,终于发现了这篇。。感谢
[回复]
52nlp 回复:
17 2 月, 2011 at 19:25
不客气!
[回复]
IRSTLM能直接对计数文件训练语言模型么?比如Google的ngram。SRILM是可以的~
[回复]
请教下:IRSTLM能直接对ngram计数文件(如google的ngram)训练语言模型么?具体命令是什么呢?SRILM是可以的~
[回复]
52nlp 回复:
4 7 月, 2011 at 22:16
抱歉,我此前也是主要用SRILM的,IRSTLM也仅仅是碰了一下;另外好久没用,也忘了。可以看看它的这个脚本(../scripts/build-lm.sh)是否调用了分步训练的脚本。
[回复]
jiangfeng 回复:
4 7 月, 2011 at 22:23
好的,多谢哈,我去研究一下。
另外再请教一个关于SRILM的问题:SRILM训练得到的model中,比如“-0.494355 are priced to yield from” 是指联合概率P(are priced to yield from)还是条件概率P(from | are priced to yield)?
[回复]
52nlp 回复:
5 7 月, 2011 at 22:59
应该是联合概率取对数吧?我也不是很确定。
老师您好~ 您后来安装过irstLM后来的5.80吗?
[回复]
52nlp 回复:
28 11 月, 2012 at 21:40
我前段时间安装过5.80,印象很顺利,没有这篇文章中的问题了,安装包是irstlm-5.80.01.tgz
[回复]
求教,我用IRSTLM和mosesdecoder搭配训练出来的模型,每次用moses进行翻译的时候,就会发生segmentation fault,头都大了,会是什么原因呢?
我是做中英翻译
[回复]