lamtramツールキットを使って、ニューラル機械翻訳を試す


言語モデルの作成から翻訳まで、ニューラルネットワークを用いた言語処理が盛んである。
前から気になっていたニューラル機械翻訳（以下NMT）をツールキット(lamtram)を用いて試す。

いくつかハマリどころがあったので作業内容を記す。
- cnnのインストール設定
- CUDAのパス
なおインストール作業は、CUDA(GPU)を利用する設定で行った。

# lamtramのインストール
## lamtramとは
[lamtram](https://github.com/neubig/lamtram)は[Graham Neubig](http://www.phontron.com/)先生がオープンソースで開発されている「ニューラルネットワークを用いた言語モデルおよび翻訳モデル作成ツールキット」である。
同じくNeubig先生がNMTに関する[チップス集](https://github.com/neubig/nmt-tips)をまとめている。

## 依存パッケージのインストール
lamtramの動作には、
- autotools
- libtool
- boost > 1.49
- CUDA(GPUを利用する場合)
- Eigen
- cnn
が求められる。

上記のうちautotools, libtool, boost, CUDAはaptやyumなどの管理ツールでインストール可能なので、今回は説明を省略する。

### Eigenのインストール
Eigenは線形代数やベクトル演算、数値解析などを提供するC++のテンプレートライブラリである。

[レポジトリ](https://bitbucket.org/eigen/eigen)から **最新版(development version)** をcloneする。
ここでハマった。
私の環境の問題かもしれないが、cloneができなかった。
そこで、[ダウンロードページ](https://bitbucket.org/eigen/eigen/downloads?tab=branches)から直接ダウンロードを行った。(defaultをダウンロード)

```sh
$ wget https://bitbucket.org/eigen/eigen/get/default.tar.bz2
$ tar -xvf default.tar.bz2
# ディレクトリ名がeigen-eigen-7fa8c5d1a42dのようにコミット番号が付いたものになるが、ここではeigenと省略する。
$ cd eigen # ~/eigenとする。
```

### cnnのインストール
cnnはC++のニューラルネットワークのライブラリである。
cnnをコンパイルするために、Eigenが必用となる。

ここで、1点注意がある。
**lamtramはcnn v2のみをサポートしている。**
githubレポジトリからcloneしたあとに、ブランチを切り替える。

```sh
$ git clone https://github.com/clab/cnn.git
$ git fetch origin v2
$ git checkout v2
```

[レポジトリのREADME](https://github.com/clab/cnn)に従って、ビルドを進める。

依存ライブラリのフェッチ

```
$ cd cnn
$ git submodule init
$ git submodule update
```

cmakeによるCPU利用版のMakefileの作成

```
# cnnディレクトリにて
$ mkdir build
$ cd build
# -DEIGEN3_INCLUDE_DIR=/path/to/eigen
$ cmake .. -DEIGEN3_INCLUDE_DIR=~/eigen
```

コンパイル

```sh
# -j 引数の数値は、スレッド数
$ make -j 4
```

cmakeによるGPU利用版のMakefileの作成

```
$ cmake .. -DBACKEND=cuda -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-7,5/
$ make -j 4
```

ここでハマった。
makeが通らない。
共有ライブラリがどうのこうのという問題に遭う。
この[ページ](https://github.com/trevorcohn/mantis)を参考にmakeファイルを書き換える。

エディタで`~/cnn/build/cnn/CMakeFiles/cnncuda_shared.dir/build.make`を開く。
`--compiler-options "-fPIC"`を以下の記述の場所に追記する。

> cd \$PATH_TO_CNN/build-cuda/cnn && /usr/local/cuda-7.5/bin/nvcc -m64 -ccbin "/usr/bin/cc" --compiler-options "-fPIC" -dlink \$PATH_TO_CNN/build-cuda/cnn/CMakeFiles/cnncuda_shared.dir//./cnncuda_shared_generated_gpu-ops.cu.o -o \$PATH_TO_CNN/build-cuda/cnn/CMakeFiles/cnncuda_shared.dir/./cnncuda_shared_intermediate_link.o

cuda-7.5やcnncuda_shared_generated_gpu-ops.cu.oなどで検索すると見つかる。
私のbuild.makeファイルでは12,704行目であった。

もう一度makeする。

```
$ make clean
$ make -j4
```

### lamtramのインストール
公式[README](https://github.com/neubig/lamtram)に従う。

```sh
$ autoreconf -i
$ ./configure --with-cnn=~/cnn --with-eigen=~/cnn --with-cuda=/usr/local/cuda-7.5
$ make -j 4
```

ここで、若干ハマった。
64ビット環境でcudaをインストールしていると、一部のライブラリが足りないと言われる。
`/usr/local/cuda-7.5/lib`を参照してしまっているのが原因である。

環境変数LDFLAGSを確認する。

```sh
echo $LDFLAGS
```

-L/usr/local/cuda/lib64のように参照されているかどうか確認する。
もしlib64が参照されていない場合は、環境変数に追加する。

```sh
export LDFLAGS=-L/usr/local/cuda/lib64:$LDFLAGS
```

仕切り直して、同じようにconfigureしたのちに、makeを行うとコンパイルできる。

# lamtramを試す

[nmt-tips](https://github.com/neubig/nmt-tips)に記載されている通り、学習と翻訳を実行する。
encoder-decoder NMTで日英翻訳を試したところ、サンプルの1文目は以下のようになった。

- 入力文：君 は １ 日 で それ が でき ま す か 。
- 出力文：are you interested ?

出力を見ていると、veryが30回繰り返されているものがあった。
終端記号がなかなか出ないからであろうか。

素晴らしいツールのおかげで、手軽にニューラル機械翻訳を試すことができた。