目录
1. 目的及数据集
主要目的是用fairseq在windows上跑一遍transformer模型,记录一下流程以帮助其他人(健忘),次要目的是实验zero-shot效果。
以de<->en,it<->en四个方向进行训练,测试de<->it结果。
初步实验在开发集上运行,开发集负采样newstest2010,最终每个方向各650句。测试集则是在训练集上采样it<->de各20句,bpe_size 12000。
预处理过程不赘述,tokenize, clean, lowercase, learn_bpe, aply_bpe 依次进行,参考fairseq-master/examples/translation中的sh例子
2. 命令行运行工具
Git for windows是必不可少的工具,直接参照git官网安装。
* 坑1:git bash必须以管理员权限启动,不然一些操作无法完成。通过Pycharm也可以使用Git,同样需要管理员权限。
3. 环境
可以使用conda,也可以直接本地装上python。
参照fairseq github的指示,直接pip install -requirement.txt即可。
* 坑2:Git bash中启动conda环境的命令是:
source activate your-env
但是关闭还是:conda deactivate
4.安装fairseq
(带有个人偏好)github上下载源码,解压到自己喜欢的地方,启动git bash,cd进目录,然后pip install(参照github说明)
实际上git可以一键完成。(所有操作均是在启动conda环境的前提下)
5. 开始训练
5.1 二值化原数据
TEXT=your-path-data
fairseq-preprocess --source-lang input \
--target-lang output \
--trainpref $TEXT/train \
--validpref $TEXT/valid \
--testpref $TEXT/test \
--destdir your-path-binarization
* 坑3:bpe的时候不再需要抽取词典(dict)
说明:二值化后,fairseq才可以读取数据,文件名必须为train,valid和test,而source-lang 以及 target-lang 只是对应文件的后缀,并不约束数据的语言。
5.2 训练
fairseq-train your-path-binarization \
--task translation \
--source-lang input --target-lang output \
--arch transformer \
--optimizer adam --adam-betas '(0.9,0.98)' \
--clip-norm 0.1 \
--lr 5e-4 --lr-scheduler inverse_sqrt \
--warmup-updates 2000 --dropout 0.3 \
--weight-decay 0.0001 \
--max-tokens 4096 \
--save-dir checkpoints \
--save-interval 5 \
--eval-bleu --eval-bleu-args '{"beam": 5}' --eval-bleu-detok moses --eval-bleu-remove-bpe
说明:path, source-lang, target-lang参照上节,参照Johnson et al. 以及近年many-to-many work的通常做法,仅修改数据,任务以及模型选basic transformer就行。最后一部分的eval-bleu可以不用。
*坑4:checkpoints一定要间隔保存,不然一会儿就把我可怜的100G E盘跑满了。
注意:在这里我没有使用tensorboard记录log,实际实验中推荐使用
6. 解码以及翻译
6.1 解码
fairseq-generate your-path-binarization \
--path checkpoints/checkpoint_best.pt \
--remove-bpe
说明:解码是自动翻译二值化后的test.input(按照我的格式)文件,所以path依旧不需要制定到具体文件,最终会得到bleu以及在控制台显示翻译。
6.2 翻译
fairseq-interactive your-path-binarization\
--path checkpoints/checkpoint_best.pt \
--beam 5 --remove-bpe \
> predict_test.txt
说明:依旧是那个目录,这次是为了加载fairseq-preprocess产生的dict文件,最后将输出保存到该txt文件夹中
grep ^H predict_test.txt | cut -f3- > predict_test1.txt
sed -r 's/(@@ )| (@@ ?$)//g' < predict_test1.txt > predict_test2.txt
说明:第一个命令是为了消除 “除翻译外的” 所有文字,第二个命令是为了消除bpe的符号,predict-test2.txt即为最终输出
*小坑5:该输出是tokenized,请注意!
6.3 计算bleu
perl mosesdecoder/scripts/generic/multi-bleu.perl \
your-target-file < predict_test2.txt
说明:使用moses自带的perl计算bleu,前者为target file,后者为我们得到的输出
7. 结果
100个epoch
(数据集太小,只是开发使用,结果不好哈哈哈哈)
it->de BLEU = 6.53, 19.6/6.0/5.1/4.1 (BP=0.930, ratio=0.932, hyp_len=179, ref_len=192)
de->it BLEU = 6.54, 16.9/6.0/5.2/4.9 (BP=0.919, ratio=0.922, hyp_len=177, ref_len=192)
但对于zero-shot来说,最大的问题肯定还是target-off即脱靶问题。虽然给定<2it>或者<2de>命令,但依然会出现code-switching的结果。
8. 训练参数解释
2021-09-24 00:11:15 | INFO | fairseq_cli.train | begin validation on "valid" subset
2021-09-24 00:12:02 | INFO | valid | epoch 015 | valid on 'valid' subset | loss 3.156 | nll_loss 3.156 | ppl 8.91 | bleu 8.16 | wps 69.7 | wpb 1056 | bsz 66.7 | num_updates 765 | best_loss 3.156
2021-09-24 00:12:02 | INFO | fairseq_cli.train | end of epoch 15 (average epoch stats below)
2021-09-24 00:12:02 | INFO | train | epoch 015 | loss 4.439 | nll_loss 4.439 | ppl 21.7 | wps 601.7 | ups 0.43 | wpb 1394.2 | bsz 58.8 | num_updates 765 | lr 0.00019125 | gnorm 4.874 | clip 100 | train_wall 69 | gb_free 2.7 | wall 1546
- bsz = batch size
- gnorm = L2 norm of the gradients
- clip = gradient clipping threshold
- train_wall = time taken for one training step
- wall = total time spent training
- wps = Words Per Second
- ups = Updates Per Second
- wpb = Words Per Batch