最近还卡在复现工作的结果这一环节上。具体来说,我使用那篇工作提供的脚本,使用的是fairseq-generate来完成的结果的评估。然后我发现我得到的结果和论文中的结果完全不一致。
首先,在预处理阶段,如记一次多语言机器翻译模型的训练所示,我是用moses的tokenizer完成的tokenize,然后又使用moses的lowercase完成的小写化,最后用subword-nmt bpelearn和apply的子词。当然,一方面,小写化不利于模型性能的比较(来自师兄);另一方面,可以使用sentencepiece这一工具来直接学bpe,而不需要做额外的tokenize,但本文暂不考虑。
这部分内容主要参考:Computing and reporting BLEU scores
考虑以下情况:机器翻译的训练和测试数据,都经过tokenize和truecased的预处理,以及bpe的分词。而在后处理阶段,在保证正确答案(ref)和模型输出(hyp)经过相同的后处理操作的情况下,不同的操作带来的BLEU值是很不同的。如下图所示:
主要有以下发现:
总结:
经过上一部分,可以看到,我的预处理步骤的问题并不大(虽然小写会导致结果偏高),我的问题主要出在,在运行fairseq-generate时,我没有提供bpe\bpe-codes\tokenizer\scoring\post-process参数,也就是说,我没有做任何的post-process。其中,各参数的功能如下:
(x + " ").replace(self.bpe_symbol, "").rstrip(),其中self.bpe_symbol=@@
MosesDetokenizer.detokenize(inp.split())
scorer.add(target_tokens, hypo_tokens)
,其中,target\hypo_tokens是经过一些预处理(可能经过了undo bpe和detokenize,也有可能什么也没做:只是用" "这个分隔符把sentence中所有的tokenized bpe子词连成了一串字符串),得到target\hypo_str之后,再做fairseq提供的简单的tokenize(fairseq/fairseq/tokenizer.py),然后计算BLEU值。而如果scoring=‘sacrebleu’,则具体计算的语句为scorer.add_string(target_str, detok_hypo_str)
,在这种情况下,如果我们做好了应该做的post-process,target_str就是纯纯的原文本,detok_hypo_str也如此。而在计算BLEU值时,我们又是用的sacrebleu的standard tokenization,可比性会高很多。CUDA_VISIBLE_DEVICES=5 fairseq-generate ../../data/iwslt14/data-bin --path checkpoints/iwslt14/baseline/evaluate_bleu/checkpoint_best.pt --task translation_multi_simple_epoch --source-lang ar --target-lang en --encoder-langtok "src" --decoder-langtok --bpe subword_nmt --tokenizer moses --scoring sacrebleu --bpe-codes /home/syxu/data/iwslt14/code --lang-pairs "ar-en,de-en,en-ar,en-de,en-es,en-fa,en-he,en-it,en-nl,en-pl,es-en,fa-en,he-en,it-en,nl-en,pl-en" --quiet
主要就是提供了bpe\bpe-codes\tokenizer\scoring,这四个参数。结果如下。
TBC
另外,也可以不看fairseq-generate提供的BLEU结果,而是利用它生成的hyp.txt和ref.txt文件,然后用sacrebleu工具来计算分数。
TBC
TBC