Moses是统计机器翻译领域最常见的工具(可能没有“之一”),使用C++编写。由于工作需要,我需要训练一个翻译模型,而平行语料比较小,使用NMT不现实,因此自然需要考虑借助moses的帮助。但是moses官网上的指导稍微有点乱,而且代码库里也存在一些错误,我自己也把C++忘光了(本来也就学了个皮毛),所以编译不是很顺利,好在靠组内两位C++大拿的指导最后搞定了。这里我简要记一下踩过的坑
我的系统是Mac OS High Sierra 10.13.6,编译器信息如下
1 | Apple LLVM version 9.1.0 (clang-902.0.39.2) |
一、手工构建boost库
官网上说如果手工构建boost,需要在编译moses时指定位置。我开始的方案是直接用brew install boost
,然后编译的时候指定好boost装在了哪儿。后来我发现效果好像不太好,总之有错误发生。比较稳妥的方法是直接从官网下载boost源码然后编译
(当然,构建失败可能是后面所叙几个原因造成的,我之前没有仔细检查过。不过手工编译boost至少在我这儿行得通)
二、修改phrase-extract/syntax-common/tree-inl.h
该文件有一些地方写得不太符合C++关于模板类的语法,所以会导致error。具体修改如下(这里只贴改后的版本,下同)
76行
1 | typename Tree<T>::template PreOrderIter<V> &Tree<T>::PreOrderIter<V>::operator++() { |
103行
1 | typename Tree<T>::template PreOrderIter<V> Tree<T>::PreOrderIter<V>::operator++(int) { |
165行
1 | typename Tree<T>::template LeafIter<V> &Tree<T>::LeafIter<V>::operator++() { |
190行
1 | typename Tree<T>::template LeafIter<V> Tree<T>::LeafIter<V>::operator++(int) { |
简单说,把所有返回Tree<T>::PreOderIter<V>
的函数定义的返回类型改为typename Tree<T>::template PreOderIter<V>
。LeafIter
的同理
三、修改symal/{Jamfile,cmd.c}
由于在构建的时候指定了-std=c++0x
,因此不会编译C文件且会报错
1 | error: invalid argument '-std=c++0x' not allowed with 'C' |
这里的解决方法分三步
修改Jamfile文件,改为
1
exe symal : symal.cpp cmd.cpp ;
将cmd.c重命名为cmd.cpp
由于此时变为C++文件,因此
calloc
和malloc
的返回值不能是void*
,需要加六处类型转换 147行1
int *subrange = (int *)calloc(2, sizeof(int));
155行
1
int *value = (int *)calloc(1, sizeof(int));
323行
1
a = (char **)calloc(n+1, sizeof(char *));
328行
1
a[n] = (char *)malloc(l+1);
482行
1
indent = (char *)malloc(l+2);
581行
1
if(!(Line=(char *)malloc(LINSIZ))) {
之后应该就可以编译成功了
A short summary of this blog: How to build Moses on Mac
This article records the issues and solutions I caught when I built moses, the de facto SMT toolkit on Mac. The details of my system can be referred to the Chinese part. Generally there are three issues:
- Boost library. I failed to build the system if I install the boost via
brew install boost
(It kept prompting that a library cannot be linked). When I built the boost library manually errors have gone. phrase-extract/syntax-common/tree-inl.h
doesn't follow the C++ syntax on templates. Follow the detailed above to solve itsymal/cmd.c
is a C file whilst make file indicates that C++ 0x standard should be followed. So just rename cmd.c to a c++ file extension e.g. cmd.cpp, then modify Jamfile. Since the code should follow C++ syntax instead of C syntax now, the return type ofcalloc/malloc
isvoid*
and cannot be directly used, thus a type cast should be applied. Details could also be checked in the Chinese part.