众所周知,在Moses中除了语言模型的训练是利用srilm的ngram-count模块单独训练外,其它模型的训练都是利用train-factored-phrase-model.perl模型训练脚本进行一站式训练,包括翻译模型,重排序模型和生成模型等,这些模型的训练只要设置好相应的选项,中间过程无需人工干预,在整个训练过程结束后,就可以生成解码器所需的所有文件,极为方便。
  训练脚本包括以下9个步骤,有些步骤是根据用户的设置进行的,没有的就跳过,但是最基本的翻译模型训练是肯定的:
  (1) 准备语料(prepare corpus)
  (2) 运行Giza++(run GIZA)
  (3) 词语对齐(align words)
  (4) 词典概率评分,既利用MLE计算词语的翻译概率(learn lexical translation)
  (5) 短语抽取(extract phrases)
  (6) 短语评分,既生成phrase-table,也就是翻译模型(score phrases)
  (7) 训练重排序模型(learn reordering model)
  (8) 训练生成模型(learn generation model)
  (9)创建解码器所需的相应配置文件(create decoder config file)
  这9个步骤中,最最耗时的就算运行Giza++了,在moses的参考文档中指出:
  GIZA++ is a freely available implementation of the IBM Models. We need it as a initial step to establish word alignments. Our word alignments are taken from the intersection of bidirectional runs of GIZA++ plus some additional alignment points from the union of the two runs.
  Running GIZA++ is the most time consuming step in the training process. It also requires a lot of memory (1-2 GB RAM is common for large parallel corpora).
  Giza++是从双语句对的两个方向进行迭代学习的,模型训练的绝大多数时间都被这两个方向的迭代训练占去了,所以,Moses提供了第一种简单的解决办法:并行训练(Training in parallel):
  在训练时加上 –parallel选项,这样训练脚本将被fork,Giza++的两个方向的训练将作为独立的进程。这是一台多处理器机器上的最好选择。
  Using the --parallel option will fork the script and run the two directions of GIZA as independent processes. This is the best choice on a multi-processor machine.
  如果你想在单处理器上使用并行运行两个Giza,可以使用下面的方法(我觉得单处理器上没必要使用这个方法,即使使用了效果也应该和正常的方法一样,时间节省效果不明显):
  First you start training the usual way with the additional switches --last-step 2 --direction 1, which runs the data perparation and one direction of GIZA++ training.When the GIZA++ step started, start a second training run with the switches --first-step 2 --direction 2. This runs the second GIZA++ run in parallel, and then continues the rest of the model training. (Beware of race conditions! The second GIZA might finish earlier than the first one to training step 3 might start too early!)
  Moses本身提供的方法可以有效利用2核处理器,但是对于更多核的处理器机器,譬如我的机器是4核cpu的,通过观察发现,训练过程中任何时刻,只有两个处理器的使用率是百分百,其他两个cpu基本闲置。对于闲置的cpu,不用似乎是一种浪费,不过这个问题已经有了解决: Mgiza++
  MGiza++是在Giza++基础上扩充的一中多线程Giza++工具,描述如下:
  Multi Thread GIZA++ is an extension to GIZA++ word aligning tool. It can perform much faster training than origin GIZA++ if you have more than one CPUs, in addition it fixed some bugs in GIZA, and the final aligning perplexity is generally lower than original GIZA++.
  在使用MGiza++时,可以根据自己的机器指定使用几个处理器,非常方便,需要说明的是,MGzia++的作者是一位中国人,他同时提供了Giza++并行化的另一个工具:PGIZA++ 。Pgiza++是运行在分布式机器上的Giza++工具,使用了MapReduce技术的框架:
  PGIZA++ is another version that can run on cluters. PGIZA++ based on schedulers of the cluster, here we have script for maui, Condor and simply ssh remote procedure call.
  关于MGiza++,PGiza++两个工具的主页:
    http://www.cs.cmu.edu/~qing/
  参考的三篇文献,这些在Google上很容易搜到:
  1、Parallelizing the Training Procedure of Statistical Phrase-based Machine Translation
  2、Parallel Implementations of Word Alignment Tool
  3、Fast, Easy, and Cheap: Construction of Statistical Machine Translation Models with MapReduce

注:原创文章,转载请注明出处“我爱自然语言处理”:www.52nlp.cn

本文链接地址:
https://www.52nlp.cn/the-issue-of-parallel-in-moses-model-training/

作者 52nlp

《Moses中模型训练的并行化问题》有23条评论
  1. 你好!我想请教一下, 关于训练和解码的过程部分,我的理解是训练和解码是两个完全独立的部分,举例来说:

    1、利用中英语料库训练生成解码的需要的文件(只是生成一次文件即可)
    2、Moses解码器在翻译过程中只需要利用这些文件即可以进行翻译

    [回复]

    admin 回复:

    是这样的,训练和解码是两个独立的部分。

    [回复]

  2. 你好,在用摩西的过程中,giza++用的是IBM的5个模型。我想问一下,如果我只想用模型1,或者我想用到模型3,该怎么做呢?是否可以参数设置一下?

    我的giza++是放在moses里面,由moses调用的。
    我的运行命令如下:
    ${mosesScript}/training/train-factored-phrase-model.perl \
    --scripts-root-dir "${mosesScript}" \
    --root-dir "${trainDir}" \
    --corpus "${dataDir}/${trainPrefix}" \
    --f ${trainF} \
    --e ${trainE} \
    --max-phrase-length 7 \
    --reordering msd-bidirectional-fe \
    --alignment union \
    --lm 0:5:"${lm}":0 \
    --first-step 1 \
    --parallel
    如果可以,您能给我发封邮件解释一下吗?
    我的邮箱地址是08lixianhua@gmail.com
    非常非常的感谢。

    [回复]

    52nlp 回复:

    Moses脚本里提供了一个GIZA++ Options的设置:
    http://www.statmt.org/moses/?n=FactoredTraining.TrainingParameters
    在这个页面关于GIZA++ Options是这样提的:

    GIZA++ takes a lot of parameters to specify the behavior of the training process and limits on sentence length, etc. Please refer to the corresponding documentation for details on this.

    Parameters can be passed on to GIZA++ with the switch --giza-option.

    For instance, if you want to the change the number of iterations for the different IBM Models to 4 iterations of Model 1, 0 iterations of Model 2, 4 iterations of the HMM Model, 0 iterations of Model 3, and 3 iterations of Model 4, you can specify this by

    train-phrase-model.perl [...] --giza-option m1=4,m2=0,mh=4,m3=0,m4=3
    如果你只想使用IBM model1的话,试着只将m1设置为你想迭代的次数,其他的都设置为0看看。

    [回复]

    lixianhua 回复:

    非常感谢你的帮助,我已经大致知道了做法。
    我要做的事情是:giza++用不同IBM模型做对齐,最后将测试结果进行比较,决定在我们的项目中,giza++到底用哪个IBM模型。
    我要做三组实验,一种是giza++参数默认,一种是用模型1,一种是用模型3.
    现在我的问题是:
    1.参数默认的情况下,giza++各个模型会迭代几轮呢?还是迭代到增长不多才自动停止迭代?
    因为要做三组实验的比较,模型1和模型3的迭代次数最好和默认的相同,但是我不知道默认迭代几轮,所以有此疑问。
    2.IBM的5个模型中,第N个模型是否要前N-1个模型都跑了,才能跑?还是只有模型1是必须跑的,后面的模型在模型1的结果上就能继续了?
    我看到您上面的举例,在模型2,4迭代0轮的基础上,隐马和模型4仍然能指定迭代次数,所以有此疑问。

    如果方便,请您仍然给我的gmail邮箱发封邮件,邮箱地址是:08lixianhua@gmail.com
    非常感谢您回答我这种菜鸟的问题,真心谢谢您。

    [回复]

    52nlp 回复:

    不好意思,今晚有点事,现在才顾得上博客,关于第一个问题,Giza++的默认设置好像是这样的:
    hmmiterations = 5 (mh)
    model1iterations = 5 (number of iterations for Model 1)
    model2iterations = 0 (number of iterations for Model 2)
    model3iterations = 5 (number of iterations for Model 3)
    model4iterations = 5 (number of iterations for Model 4)
    model5iterations = 0 (number of iterations for Model 5)
    model6iterations = 0 (number of iterations for Model 6)
    既HMM,Model1,3,4的迭代次数是5,其他为0。
    关于第二个问题,建议你读一下“A Statistical MT Tutorial Workbook“,原则上是前一个模型的训练结果作为下一个模型训练的一部分初始条件的,不过Giza++的Readme也说了:
    Normally, Model1 is trained first, and the result is used to start Model2 training.Then Model2 is transfered to Model3. Model3 viterbi training follows.This sequence can be adjusted by the various options, either on the command line or in a config file.
    Model1应该是必须的。Giza++的代码我没有仔细读过,所以这些问题我也不是很肯定。另外,我觉得这个问题可能具有一定的普遍性,就在这里回答了,也好为后来者留个提示,就不回信了,抱歉!

  3. 您好!
    我最近在https://www.52nlp.com/tag/dictionary/
    看到您关于GIZA中加入词典的方法的探讨,很感谢您的分享,这里想向您具体请教一下。
    1、怎么查看词典和训练语料的编码格式呢?
    2、useDict具体是在哪个文件夹的哪个文件里呢?
    3、不是很清楚词典具体是什么样子的,现在处理出来的词典只能够做到一个目标语言的词对应于一个源语言的词,但是不知道该怎样把词转化为对应的id,是需要根据训练语料训练出来的.vcb文件吗?还是另外有什么决定id的文件?
    我的邮箱是:hyxsunshine@yahoo.com.cn
    希望能够收到您的回信,以后多交流。
    非常感谢您的帮助!

    [回复]

    52nlp 回复:

    首先需要说明的是https://www.52nlp.com/tag/dictionary/下的文章不是我和别人的讨论,而是我摘录Moses邮件列表里的一些相关问题。
    关于文件格式,在windows下,可以利用notepad++等文本编辑器查看文件格式并进行相互转化;在linux下,可以利用enca命令来查看,这个网页下有更具体的说明:http://www.ej38.com/showinfo/linux-132533.html
    关于在Giza++里添加词典,我个人没有专门研究过,所以不太清楚,最好读一下Giza++的说明文档。
    将“一个目标语言的词对应于一个源语言的词”的词典转化为对应的id的事情Giza++就可以做得,你只需要按它的要求做成相应的训练格式,Giza++训练完毕后会产生很多文件,其中就包括词语的id,事实上,它的第一步就是先生成词语的id,而后就只根据id作处理了。

    [回复]

    hyxsunshine 回复:

    您好,很感谢您的回复!
    GIZA++的README文件里只有一个大概的词典格式的介绍,没有找到更为具体的信息。
    在处理的第一步确实生成了.vcb文件,那么对于词典上有而训练语料里没有出现的词我们是不是就必须舍弃了呢?因为这样的话,在.vcb里面是没有id的。
    而且,一般我们词典的颗粒度都会比分词过的训练语料的颗粒度大,这个问题该怎么处理呢?是不是我们的词典也要进行分词,然后进行对应?比如:“最\好\的 best”分开对应还是直接舍去呢?
    另外,还想请教一下,怎么把训练出来的词典运用到测试语料呢?比如:训练出来的文件是:chinese.vcb english.vcb english_chinese.snt 词典是dictionary.txt 而我们的测试语料是ch.txt en.txt那么我们的命令该怎样给出呢?
    再次感谢您的回复!

    [回复]

    52nlp 回复:

    不好意思,有些问题我不太清楚,只能按个人的理解回答。
    我曾经利用过双语词典,不过是采用最简单的一种方法:就是直接将双语词典视为双语对齐的语料加入到已有的训练语料中,没有专门利用Giza++中的词典接口,所以不太清楚,不过你可以靠考虑这种方法对训练语料库进行补充并利用双语词典。
    在我利用词典时,是与训练语料同等对待的,因此采用相同的预处理过程,包括分词。
    关于如何将训练出来的词典运用到测试语料,我也不太清楚,不过如果你采用了前面的方法,就基本上算是利用上词典了。

  4. 您好!
    您提供的这一种方法正是我现在正在使用的,但是我的两个词典中有一个在加入之后使GIZA在进行HMM训练时出现了“段错误”,这两个词典的格式是一样的,但是在出现了错误的词典进行IBM模型训练时出现“Error:No Word Index for "通配符"”,不知道您知不知道是什么导致的错误呢?应该是文本本身的问题吧。

    [回复]

    52nlp 回复:

    这个问题我不太清楚,但是感觉和文本本身的问题比较相关。Giza++对文本格式的要求比较高,最好在预处理时把一些不必要的符号过滤掉。

    [回复]

  5. 您好,请教一下。每次准备数据的第一步骤都是进行token,这个步骤到底有什么用呢?我对比结果没发现进行了操作,除了字体有些改变。还有就是这一步骤用中文描述应该怎么说呢?谢谢

    [回复]

    52nlp 回复:

    token是Tokenization的意思,本意是对英文进行词串识别,目的是将字符串转换成词串进而降低信息的不确定性,例如将it's转换为it is。Moses脚本中的token脚本是针对西文字符的,因此对于中文基本不起作用。对等到中文,可以看做是我们的“中文分词”,这个基本上是我们自己处理中文上的第一步。可以参考一下我早起翻译的一篇MIT自然语言处理的文章,稍微生涩一点:
    https://www.52nlp.cn/mit-nlp-second-lesson-word-counting-fourth-part

    [回复]

    Fanlc 回复:

    谢谢。终于搭建好了一个模型,对中英文进行了翻译,效果还不错,呵呵

    [回复]

    52nlp 回复:

    不客气,我看了你的记录,写得挺好的。

  6. 我想问一下:
    我没有进行tuning,想利用训练模型 之后的moses.ini进行测试翻译,结果翻译结果都是错误的
    想问一下是没有tuning的原因,还是我训练模型过程中出错?
    盼望回复~

    [回复]

    52nlp 回复:

    tuning和不tuning的区别不会非常大,不清楚这个翻译结果是错的程度如何?如果程度很大,也许训练过程中有问题,但是如果不大,可能还好其他因素有关。另外翻译的好坏和你的语料库规模和类型也相关。

    [回复]

  7. 你好,我想请问一下PGIZA++现在有版本吗?为什么高勤的个人主页上没有相应的联接,只有MGIZA++和一个并行的Chaski?谢谢您。

    [回复]

    52nlp 回复:

    刚才google了一下,这个链接下有:http://www.cs.cmu.edu/~qing/giza/

    [回复]

发表回复

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