MOSES翻譯系統的訓練,調優和使用

寒小陽發表於2013-08-20

       這裡我假設你已經成功安裝了摩西moses,並希望在平行語料資料的基礎上建立一個真正的短語翻譯系統。這個過程需要一定的Unix的基礎,理想情況下,最好還有一臺Linux伺服器。當然,如果你只是想試試的話,你也可以在一臺膝上型電腦上安裝並執行它,但最少要2G的記憶體(貌似現在的電腦都至少有這麼大吧),和10G的空閒磁碟空間(宣告一下,這是本人估計的,有可能配置達不到這個也能跑,但訓練的速度會非常慢的)。

       在進行下述操作之前,我建議你將編譯後生成的moses可執行檔案和之前編譯安裝過後的Irstlm以Giza++工具整理到一個資料夾下,便於呼叫,本人大致的目錄結構如下:


1 語料庫準備和預處理

       這個地方,本人使用的是射手網和各種字幕網站採集和清洗過的英文電影電視劇字幕的中英平行語料。你要是隻是想試一試moses而又沒有語料的話,可以wget http://www.statmt.org/wmt12/training-parallel.tgz進行下載,這裡面是歐洲各國語言(德語,英語,法語等)的平行語料庫,你可以用作測試。

       在進行語料訓練之前,要先對我們的平行語料做一些預處理,主要包括以下以下步驟:

       tokenisation:這一步主要是在單詞和單詞之間或者單詞和標點之間插入空白,以便於後續識別和其他操作。

       truecasing:初始每句話的字和片語都被轉換為沒有格式的形式(例如統一為小寫)。這有助於減少資料稀疏性問題。

       cleaning:長句和空語句可引起訓練過程中的問題,因此將其刪除,同時刪除顯不對齊句子刪除。

       對了,對於平行語料的中文部分的話,在訓練之前一定要注意要先分好詞,這樣後面使用giza-pp進行對齊訓練的時候才能精準對齊詞、片語和短語。我使用的是中科院ictclas分詞系統,但是又licence過期的可能,你也可以使用Ansj,基本是將ictlas用java重寫了一遍,詞庫基本不變,分詞的程式我可以在之後的文章裡給出。

       我的語料存在/data/traing_500m_data/中,則執行以下指令即可:

tokenisation:

/home/yaoqiang/moses/moses_binary/scripts/tokenizer/tokenizer.perl -\l en ‐threads 8 < all_movie_data_20130422_en   > all_movie_data_20130422.tok.en

/home/yaoqiang/moses/moses_binary/scripts/tokenizer/tokenizer.perl -\l zh ‐threads 8 < all_movie_data_20130422_zh   > all_movie_data_20130422.tok.zh

Truecaser和truecasing:

/home/yaoqiang/moses/moses_binary/scripts/recaser/train-truecaser.perl --model truecase-model.en --corpus  \

     all_movie_data_20130422.tok.en

/home/yaoqiang/moses/moses_binary/scripts/recaser/train-truecaser.perl --model truecase-model.zh --corpus  \

     all_movie_data_20130422.tok.zh

/home/yaoqiang/moses/moses_binary/scripts/recaser/truecase.perl --model truecase-\model.en < all_movie_data_20130422.tok.en  \

    > all_movie_data_20130422.true.en


/home/yaoqiang/moses/moses_binary/scripts/recaser/truecase.perl --model truecase-\

model.zh < all_movie_data_20130422.tok.zh  \

    > all_movie_data_20130422.true.zh

cleaning:

/home/yaoqiang/moses/moses_binary/scripts/training/clean-corpus-n.perl all_movie_data_20130422.true zh en  \

    all_movie_data_20130422.clean 1 80

2 語言模型訓練

       首先,我前面預處理過的語料已經儲存在/data/train_500m_data/資料夾下了。

       再說一下,這裡要訓練生成的語言模型(LM)是用來確保最後翻譯後流暢的輸出的,所以它是關於目標語言(這裡是中翻英,即英語)的。Irstlm的文獻給出很多命令列選項的詳細說明,但以下的指令足以建立一個合適的3-gram語言模型,消除singletons,並使用改進的Kneser-Ney方法進行平滑了,且新增句子邊界符號:

       /home/yaoqiang/moses/moses_binary/training-tools/irstlm/bin/add-start-\              end.sh  < all_movie_data_20130422.true.en > all_movie_data_20130422.sb.en

       export IRSTLM=$HOME/irstlm; /home/yaoqiang/moses/moses_binary/training-tools/irstlm/bin/build-lm.sh -\       i  all_movie_data_20130422.sb.en -t ./tmp  -p  -s improved-kneser-ney -o all_movie_data_20130422.lm.en 

       /home/yaoqiang/moses/moses_binary/training-tools/irstlm/bin/compile-lm  --\       text yes  all_movie_data_20130422.lm.en.gz  all_movie_data_20130422.arpa.en

       經過這一步之後我們會得到一個*.arpa.en格式的語言模型檔案,接下來我們將會使用KenLM對其進行二值化(這樣的話載入的時間會更快)。

       這一步的指令如下:

       /home/yaoqiang/moses/moses_binary/bin/build_binary all_movie_data_20130422.arpa.en  all_movie_data_20130422\.blm.en

       我們可以在這一步之後測試一下訓練的模型是否正確,運用如下的linux命令:

       echo "is this an English sentence ?" | /home/yaoqiang/moses/moses_binary/bin/query all_movie_data_20130422.blm.en

       我的測試結果如下,表明生產模型成功:

root@yaoqiang-KVM:/data/train_500m_data# echo "is this an English sentence ?" | /home/yaoqiang/moses/moses_binary/bin/query all_movie_data_20130422.blm.en

Loading statistics:

user 0

sys 0.040002

VmPeak:   217224 kB

VmRSS:    215600 kB

is=28 2 -2.221 this=140 3 -1.03372 an=451 3 -2.22049 English=7517 2 -3.12162 sentence=8256 2 -3.97998      ?=60 2 -1.19407 </s>=16 3 -0.0103952 Total: -13.7813 OOV: 0

After queries:

user 0

sys 0.040002

VmPeak:   217232 kB

VmRSS:    215600 kB

Total time including destruction:

user 0

sys 0.052003

VmPeak:   217232 kB

VmRSS:       656 kB

3 翻譯模型訓練

       經過上述這一系列過程之後,我們可以開始訓練我們的翻譯模型了。接下來這一條linux命令,將完成包括詞對齊(使用GIZA++),短語提取和評分,建立詞彙化的重新排序表以及建立你的moses的配置檔案(moses.ini)等一系列任務。我建議你建立適當的目錄結構,然後執行訓練命令,我的目錄結構如下指令中所述。記得最後將訓練過程記錄在日誌中:

       mkdir /data/translating_working

       cd /data/translating_working

       nohup nice /home/yaoqiang/moses/moses_binary/scripts/training/train-model.perl -cores 8 -root-dir train -\              corpus /data/train_500m_data/all_movie_data_20130422.clean -f zh -e en -alignment grow-diag-final-and -\reordering msd-       bidirectional-fe -lm 0:3:/data/train_500m_data/all_movie_data_20130422.blm.en:8 -external-bin-\       dir /home/yaoqiang/moses/moses_binary/training-tools/giza >& training_log.out &

       其中引數-cores 8將伺服器中8個cpu全都用上了。

       這一步的時間稍長,主要是前期giza-pp對詞和短語對齊訓練耗時,比如說我這裡訓練的語料大概是中英文各300m左右,訓練完成的時間大概是36個小時,我這裡使用的是12G記憶體8核cpu的伺服器,所以如果你急著看到訓練結果的話,載入的語料庫要稍小一些,上次載入的語料庫大概是100萬句子(30m左右),訓練了將近4個小時。

       上述過程完成後,你可以在translating_working/train/model 資料夾下找到一個moses.ini配置檔案,這是需要在moses解碼時使用到的。但這裡有幾個問題,首先是它的載入速度很慢,這個問題我們可以通過二值化(binarising)短語表和排序表來解決,即編譯成一個可以很快地載入的格式。第二個問題是,該配置檔案中moses解碼系統用來權衡不同的模型之間重要程度的權重資訊都是剛初始化的,即非最優的,如果你開啟moses.ini檔案看看的話,你會看到各種權重都被設定為預設值,如0.2,0.3等。要尋找更好的權重,我們需要調整(tuning)翻譯系統,即下一步。

4 調整(tuning)翻譯模型

       這是所有步驟中過程進行的最慢的一部分,所以你大可在這一步進行的時候,放張椅子,躺下來吃點東西讀點莫言的小說啥的。調整(tuning)過程需要一份不同於訓練資料的小平行語料,這個的話又要靠你自己收集了(如果你訓練的時候用的是上面提供的歐洲平行語料的話,在相同的網址你還可以下到一些用於tuning的資料),另外一個簡單的處理方法就是在訓練的時候只用全部平行語料的一大部分,例如95%,而剩下的5%用於調優這一步。以下是用於調整的語料準備的過程(同樣需要先將資料進行tokenlizer、truecase和長度限定等處理):

/home/yaoqiang/moses/moses_binary/scripts/tokenizer/tokenizer.perl -l en < dev/rwx.web.en > test.tok.en

/home/yaoqiang/moses/moses_binary/scripts/tokenizer/tokenizer.perl -l zh < dev/rwx.web.zh > test.tok.zh

/home/yaoqiang/moses/moses_binary/scripts/recaser/truecase.perl --model truecase-\model.en < test.tok.en > test.true.en

/home/yaoqiang/moses/moses_binary/scripts/recaser/truecase.perl --model truecase-\model.zh < test.tok.zh > test.true.zh

/home/yaoqiang/moses/moses_binary/scripts/tokenizer/tokenizer.perl -\l en < tuning_data_20130422_en > tuning_data_20130422.tok.en

/home/yaoqiang/moses/moses_binary/tokenizer/tokenizer.perl -\l zh < tuning_data_20130422_zh > tuning_data_20130422.tok.zh

/home/yaoqiang/moses/moses_binary/scripts/recaser/truecase.perl --model truecase-\model.en < tuning_data_20130422.tok.en > tuning_data_20130422.true.en

/home/yaoqiang/moses/moses_binary/scripts/recaser/truecase.perl --model truecase-\model.zh < tuning_data_20130422.tok.zh > tuning_data_20130422.true.zh

       接下來我們可以開始tuning我們moses解碼器配置檔案中的權重了:

nohup nice /home/yaoqiang/moses/moses_binary/scripts/training/mert-\moses.pl ../corpus/test.true.zh ../corpus/test.true.en \  /home/yaoqiang/moses/moses_binary/bin/moses  train/model/moses.ini --mertdir ../moses_binary/bin/ &> mert.out &

可在最後加上--decoder-flags="-threads 8"以使用多個執行緒,因為這個過程非常非常緩慢,你當然要使用能使用上的所有資源。

5 測試系統

       你現在就可以通過/home/yaoqiang/moses/moses_binary/bin/moses -f /data/train_500m_data/translating_working/mert-work/moses.ini來執行moses了,你可以輸入你最喜歡的中文句子(分好詞的),moses將會將其翻譯成為對應的英文句子。

       哦,對了,如果你想讓執行的速度加快的話,你可能還需要稍微修改下/data/train_500m_data/translating_working/mert-work/資料夾下的moses.ini檔案。將其中的語言模型和reordering表載入地址換做二值化後的語言模型和reordering表,如下:

 0 0 0 5 /data/train_500m_data/translating_working/train/model/phrase-table.gz

變成

 1 0 0 5 /data/train_500m_data/translating_working/binarised-model/phrase-table

 0-0 wbe-msd-bidirectional-fe-allff 6 /data/train_500m_data/translating_working/train/model/reordering-table.wbe-msd-bidirectional-fe.gz

變成

 0-0 wbe-msd-bidirectional-fe-allff 6 /data/train_500m_data/translating_working/binarised-model/reordering-table

       至此為止,moses從編譯到訓練語言模型到訓練翻譯模型,再到配置檔案中權重的調整和最後的測試都已講完了,有興趣的話你可以自己下載相關程式碼和平行語料測試一下!

       下面是執行moses後的一個小結果,大家可以看看:


相關文章