语言模型工具IRSTLM安装及试用手记

  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

本文链接地址:http://www.52nlp.cn/language-modeling-toolkit-irstlm-installation-and-trial-noting/

此条目发表在机器翻译, 语言模型分类目录,贴了, , , , , 标签。将固定链接加入收藏夹。

语言模型工具IRSTLM安装及试用手记》有 14 条评论

  1. yanyuzuo说:

    看到你介绍的HMM最佳实践,挺有用的。感谢!

    [回复]

    admin 回复:

    不用客气,欢迎常来看看!

    [回复]

  2. duckyaya说:

    这个工具包训练出来的语言模型文件格式和SRILM一样么?

    [回复]

    52nlp 回复:

    一样的,都是ARPA格式的语言模型。

    [回复]

  3. hawston说:

    “*** buffer overflow detected ***: ../bin/i686/compile-lm terminated” 问题搞了好久,终于发现了这篇。。感谢

    [回复]

    52nlp 回复:

    不客气!

    [回复]

  4. jiangfeng说:

    IRSTLM能直接对计数文件训练语言模型么?比如Google的ngram。SRILM是可以的~

    [回复]

  5. jiangfeng说:

    请教下:IRSTLM能直接对ngram计数文件(如google的ngram)训练语言模型么?具体命令是什么呢?SRILM是可以的~

    [回复]

    52nlp 回复:

    抱歉,我此前也是主要用SRILM的,IRSTLM也仅仅是碰了一下;另外好久没用,也忘了。可以看看它的这个脚本(../scripts/build-lm.sh)是否调用了分步训练的脚本。

    [回复]

    jiangfeng 回复:

    好的,多谢哈,我去研究一下。
    另外再请教一个关于SRILM的问题:SRILM训练得到的model中,比如“-0.494355 are priced to yield from” 是指联合概率P(are priced to yield from)还是条件概率P(from | are priced to yield)?

    [回复]

    52nlp 回复:

    应该是联合概率取对数吧?我也不是很确定。

  6. 饶高琦说:

    老师您好~ 您后来安装过irstLM后来的5.80吗?

    [回复]

    52nlp 回复:

    我前段时间安装过5.80,印象很顺利,没有这篇文章中的问题了,安装包是irstlm-5.80.01.tgz

    [回复]

  7. AmoeLiu说:

    求教,我用IRSTLM和mosesdecoder搭配训练出来的模型,每次用moses进行翻译的时候,就会发生segmentation fault,头都大了,会是什么原因呢?
    我是做中英翻译

    [回复]

发表评论

电子邮件地址不会被公开。 必填项已用*标注