原创 潘小小 深度学习自然语言处理 3月23日
作者:潘小小(字节跳动AI Lab算法工程师)
编辑:zenRRan
深度学习自然语言处理公众号原创出品
今天给大家介绍EMNLP2020的一篇关于多语言翻译新范式的工作multilingual Random Aligned Substitution Pre-training (mRASP)[1],核心思想就是打造“机器翻译界的BERT”,通过预训练技术再在具体语种上微调即可达到领先的翻译效果,其在32个语种上预训练出的统一模型在47个翻译测试集上取得了全面显著的提升。
目录
机器翻译预训练的挑战
mRASP发明的动机和方法
mRASP实际效果和分析
En-De和En-Fr Benchmark
预训练阶段没见过的语言扩展
案例分析
效果分析
手把手教你用mRASP快速得到任意翻译模型
附注:相关技术已经被应用于火山翻译[2]
1. 机器翻译预训练的挑战
目前绝大多数AI任务都是建立在数据的基础之上的统计学习,模型的表现效果很大程度上依赖于数据的质量和数量。利用大量较易获得的数据来预训练模型,在具体应用场景再利用少量标注数据微调来实现实际场景可用的模型,已经成为NLP新的成功范式。例如BERT[3]在大规模纯文本上预训练后,在自然语言理解的11项任务上少量微调就能取得很好的成绩。不过,在多语言的机器翻译中,通过预训练再微调的范式还未取得普遍的成功。以前的NLP预训练方式例如BERT、GPT[4]训练目标与翻译关注的目标之间差距过大,不易直接使用。mRASP提出了全新的思路,利用多个语言已经积累的大量双语平行语料,合并起来联合训练一个统一的模型,之后再基于此微调,让预训练和微调目标尽可能接近,这样才能更大发挥预训练模型作用。
BERT和GPT的示意图
MASS和机器翻译示意图对比
上图对比分析了之前NLP预训练方法在机器翻译场景直接应用的限制。BERT和GPT分别对应了Transformer[5] 编码器部分和解码器部分的预训练,而机器翻译用的是序列生成模型。这种模型结构的不一致会导致翻译模型只有一部分参数被初始化,有效发挥预训练作用会比较困难,因此需要很多特殊的技巧才能得到提升[6]。
针对序列模型,很快也有研究者提出了MASS[7]和BART[8]等框架将预训练扩展到序列生成任务,它们使用 auto-encoder(自编码器)进行自学习,在很多下游生成任务上都取得了显著的效果,但是在机器翻译的应用上依然存在两个重要的问题,第一是在资源丰富的语种(例如英德和英法)上没有观察到提升,第二是没有办法扩展到多语种翻译任务上。这种局限性,很大一部分原因就是自编码相对是简单任务,很难学习到更深层次的表示,而机器翻译需要更复杂的语义转化,这种预训练目标和下游任务之间的差异,导致模型很难最大程度利用好预训练数据。如何克服着两个问题,成了预训练模型在机器翻译领域应用的重要挑战。
2. 多语言翻译预训练方法mRASP的动机和方法
对于语言学习者来说,有一个非常有意思的现象,他们发现在学习了三四种语言之后,再学习一个新的语言速度会加快。一个简单的例子,如果有人分别学习德语和法语,可能各需要一年的时间,然而他先学习了德语,再去学法语,可能只需要一年零三个月就学会了,接下来再去学习西班牙语,速度可能会更快。对于程序语言其实也是类似的道理,学习C++可能需要一年,接下来再学习 Java,Python 可能只需要一个月。一个浅显的解释是,人类在多语言学习的过程会自发去总结语言中比较抽象的共性,重点学习新语言的特性。因此想要提升个人的语言学习能力,往往需要学习更多的语言,能够对语言的共性有更精确的把握,而不是拼命学习一个语言。同样的道理,对于机器翻译而言,能否把翻译能力迁移到不同语言上,使得不同语言之间的信息可以互相利用,就成了一件非常有趣的问题。
mRASP的设计目标正是基于这样的考虑,设计一个通用的预训练模型,学习语言之间转换的共性,接下来就被更容易迁移到新的翻译方向。就好像语言学习者一样,在学习了两种语言之后,第三种语言就变得很轻松了。mRASP 的设计遵循了两个基本原则:第一,预训练的目标和机器翻译基本一致,需要学习到语言的转换能力;第二,尽可能学习语言的通用表示,跨语言的句子或词语,如果语义接近则隐空间中的表示也应该接近。
mRASP方法,使用带语言标识的Transformer作为翻译网络框架
mRASP遵循了通用的预训练-微调框架。预训练阶段,不同于传统预训练模型大量堆叠无监督单语数据的方式, mRASP另辟蹊径,采用了多语言平行数据作为预训练的主要目标,将几十种语言的平行数据放到同一个模型进行联合训练。神经网络结构采用Transformer,加上语言标识符(Language token)标识源语言和目标语言。为了保证不同语言的句子和词语能嵌入到同一个空间,同一个意思的句子无论中文还是英文说得都应该是对应同一个向量表示,又引入了随机替换对齐技术RAS,来制造更丰富的上下文。
一句中文的句子"我 爱 北京 天安门"中的"爱"有一定概率被替换成"aime"(法语),"北京"也有一定概率被替换成"Pékin"(法语),于是原句就可能会变成"我 aime Pékin 天安门"。训练集中的一对平行句对可以变为两对(甚至三对、四对,……):
我 爱 北京 天安门 ==>I love Beijing Tiananmen Square我 aime Pékin 天安门 ==>I love Beijing Tiananmen Square
而在微调阶段,只需要使用预训练阶段的参数作初始化,之后采用和传统单向机器翻译相同的训练方法即可。因此使用mRASP并不需要掌握任何额外的技能。
3. mRASP实际效果和分析
mRASP使用32个语言的平行语料来预训练,在英语到法语方向上仅使用wmt14的平行语料进行微调,就达到了不需要使用费时费力的海量单语Back Translation的最佳效果(44.3 BLEU),同时,应用到新的语言方向荷兰语(Nl)到葡萄牙语(Pt)上,仅使用1.2万平行句对,微调了十分钟就可以获得一个可使用的(BLEU 10+)模型,而同等平行句对量很难从头训练一个可使用的MT模型(BLEU接近0)。
简单概况,mRASP具有如下几点优势:
1. 模型简单易复现
mRASP的预训练仅使用了共1.1亿对平行句对(由于同一对平行句对对两个方向都适用,所以一共是2.2亿个训练样本),词表大小仅64k个bpe subword,相比于其它预训练方法,动辄百亿数据几十层网络,训练难度更小,单机8卡不到一周在32个语言上就可以完成预训练。当然在更多语言上的预训练模型也可以简单扩展获得。
2. 通用性极强
mRASP在大中小规模训练集上,相对于直接训练的单向机器翻译模型,效果都有一定的提升,甚至包括平行语料最多的语向英语到法语(提升了1.1BLEU)。即使对于预训练数据中从来没有见过的语种荷兰语到葡萄牙语,也取得了 10+BLEU 的显著收益。
这里摘录了有代表性的部分实验结果:
3.1. En-De和En-Fr Benchmark
下图中对比了mRASP加微调在英德(En-De)和英法(En-Fr)上的效果和最近同期的其他几个跨语言预训练模型加微调的结果。可以看出,mRASP的效果是有一定优势的,En->De wmt 2016测试集上达到了30.3 (tokenized BLEU), En->Fr wmt 2014测试集上达到了44.3 (tokenized BLEU)。CTNMT 使用了 BERT预训练。MASS使用了大规模单语数据。mBERT是多语言 BERT 模型。mBART 是同期出现的另一种预训练方式,引入了海量多语言单语数据,训练时间也达到256卡20天。
3.2. 预训练阶段没见过的语言扩展
不包含在预训练阶段平行句对中的语向,也称作"Exotic Directions",在Exotic Directions上是否有效果,决定了 mRASP 是否具有很好的扩展性和泛化能力。
论文中对Exotic Directions分为四种情况:
Exotic Pair: 源语言和目标语言都经过了单独的预训练,但模型还没有见过它们组成的双语对
Exotic Source: 模型在预训练阶段只见过目标端语言,源端语言完全没见过
Exotic Target: 模型在预训练阶段只见过源端语言,目标端语言完全没见过
Exotic Full: 模型在预训练阶段完全没见过源端语言和目标端语言
这四种未见语对情况下训练机器翻译都很难。当然其中难度最大的是最后一种,相当于要求只学习了中文和英语的人,读少量拉丁语和印地语的句子就可以从拉丁语到印地语翻译。
Exotic Directions的四种分类
值得关注的是,法中(Fr-Zh)两边都单独出现过,但是没有作为平行语对出现过,只使用了20K平行语料就可以达到20+的BLEU score。
同时,对于两边语言都没在预训练阶段出现过的语对,比如荷兰语到葡萄牙语(Nl-Pt),只使用1.2万句平行语料,经过大概10分钟的训练后,也可以达到10+ BLEU score。
3.3. 案例分析
英语-法语案例。mRASP方法训练出来的模型比Direct方法的模型优秀的地方之一在于: Direct系统忽略了无实际意义单词(比如冠词,指示词等)的倾向,而mRASP保持了冠词和指示词的一致。
法语-中文案例。Exotic Pair,20k平行句对。Direct 0.7 BLEU 远弱于 mRASP 25.8 BLEU,Direct系统完全不能翻译,而mRASP系统翻译得很好
荷兰语-葡萄牙语案例。Exotic Full,1.2万平行句对。Direct 0 BLEU vs mRASP 14.1 BLEU。mRASP得到的荷葡翻译模型的翻译效果虽然不能成功翻译每个细节,但是能抓住原文的一些关键信息。比如例子中的(1) 日期 (2) 会议记录 -会议的消息 (3) 分发-共享。
3.4. 效果分析mRASP
作为通用的预训练模型,它对各个MT下游任务的的提升效果从何而来?
作者认为,其提升主要来源于两个方面:
mRASP拉近了不同语言间同义词的向量表示
mRASP拉近了不同语言间同义句子的向量表示
单词级别和句子级别的表示被拉近意味着: 经过预训练阶段对大量语言的平行句对的处理和学习,mRASP隐式地“掌握”了语言无关的表示,而这个表示是可以被迁移到任意语言上的,因此mRASP可以普遍地提高机器翻译下游任务的效果。
1. mRASP拉近不同语言单词级别的向量表示
RAS的引入通过使得不同语言的同义词之间共享相同的上下文,而在NLP中词义是由上下文(context)决定的,从而进一步拉近不同语言之间同义词的表示。
左图: w/o RAS, 右图: w/ RAS
可以看出,加了RAS方法之后,不同语言之间的embedding分布被拉近了(角度变小)。
2. mRASP拉近不同语言句子级别的向量表示
除了拉近同义词的向量表示之外,mRASP也拉近了语义的向量表示。
使用编码器输出向量作为句子的空间表征(L2 normalized averaged-pooled encoder output),从TED平行测试集(经过过滤得到的15-way 平行测试集,共2284条) 中匹配到相似度(cosine similarity)最近的句子,计算Top-1准确度(sentence retrieval accuracy)。mRASP 检索的平均准确度达到76%。我们将mRASP和mBART[9]进行对比:
mRASP的准确度减去mBART的准确度,注意荷兰语(Nl)在mRASP预训练数据中完全没出现过,其他方向上的准确度都大大超过了mBART。
mRASP的准确度减去不使用RAS的mRASP的方法的准确度。可以看出mRASP的RAS方法在预训练阶段没出现过的语言(Nl)上有明显收益
将句首的语种标识符(Language token)去掉以后,Nl的准确度还可以进一步提升,不过其他语言上的准确度大幅下降
总结
mRASP建立了多语言预训练到微调到多个语种翻译模型的成功路径,这也会成为机器翻译的新范式。我们很期待在这个方向上不断有新的方法涌现出来,朝向最终目标大踏步前进。未来几年,机器翻译的进展可以帮助几十上百个国家的每个人真正无语言障碍的沟通交流。
最后,附上我们的Github[10]、Paper[11]和体验官网[12]。
4. 手把手教你用mRASP快速得到任意翻译模型
简单上手
下面我们就来手把手教大家如何使用作者开源的mRASP模型来快速得到一个单向的机器翻译模型。在后面的例子中,我们选用作者提供的toy en-de数据集[13]来做示范。
环境配置
在开始正式训练的过程之前,我们首先需要配置好环境。
由于作者的实现是基于fairseq(使用pytorch框架)的,因此你需要安装pytorch。
将repo同步到本地,并且使用pip命令安装requirements.txt文件里的包。
gitclonehttps://github.com/linzehui/mRASP.gitcdmRASPpip install -r requirements.txt
下载mRASP模型
进入作者分享的链接里下载,这里我们需要下载有RAS的版本[14]。
训练数据预处理
合并词表(可选)
如果使用原来的词表,跳过这一步。当你需要加入新的语种(不在原词表支持的59个语种中)时,需要先将词表进行合并:
python${PROJECT_ROOT}/train/scripts/concat_merge_vocab.py --checkpoint${CKPT}--now-vocab${CURRENT_VOCAB}--to-append-vocab${NEW_VOCAB}--output-dir${OUTPUT_DIR}
预处理训练集和测试集
对数据进行清洗、tokenize、subword操作,其中subword使用的是原来的词表或者合并后的词表,具体配置在yaml配置文件中展开。
# training setbash${PROJECT_ROOT}/preprocess/multilingual_preprocess_main.sh${PROJECT_ROOT}/experiments/example/configs/preprocess/train_en2de.yml# test setbash${PROJECT_ROOT}/preprocess/multilingual_preprocess_main.sh${PROJECT_ROOT}/experiments/example/configs/preprocess/test_en2de.yml
配置文件如下
https://github.com/linzehui/mRASP/blob/master/experiments/example/configs/preprocess/train_en2de.yml
https://github.com/linzehui/mRASP/blob/master/experiments/example/configs/preprocess/test_en2de.yml
运行预处理脚本会产生如下输出
==== Working directory: ====/data00/home/panxiao.94/experiments/pmnmt/preprocess==================================== 1. Clean & TokenizationBEGIN========******** Generate configforLANGUAGE**************** Generate configforLANGUAGEPAIR en_deandClean & Tokenize en_deParallelData********========1.Clean & TokenizationALLDONE ================2.Subword & VocabBEGIN========********OnlyApplyBEGIN****************OnlyApplyALLDONE ********========2.Subword & VocabALLDONE ================3.MergeBEGIN================3.MergeALLDONE ========
处理好的数据会出现在${merged_output_path}所指定的位置
#比如,在测试集配置文件所指定的${merged_output_path}目录下面dev.de dev.en
在预处理完之后,需要将上述数据进行binarize(fairseq中特定的二进制化操作),具体操作可以参考
bash${PROJECT_ROOT}/experiments/example/bin_finetune.sh
运行时显示如下
微调训练
新建微调阶段配置文件
作者使用的是yaml格式的配置文件,微调阶段的配置参数如下面的例子,各参数的具体说明可以在作者的说明中找到。
src: entgt: demodel_arch: transformer_wmt_en_de_bigencoder_learned_pos: truedecoder_learned_pos: truedata_path: /data00/home/panxiao.94/experiments/mRASP/experiments/example/data/fine-tune/en2demodel_dir: /data00/home/panxiao.94/experiments/mRASP/experiments/example/models/fine-tune/transformer_big/en2depretrain_model_dir: /data00/home/panxiao.94/experiments/mRASP/experiments/example/models/pre-train/transformer_bigupdate_freq:1log_interval:5save_interval_updates:50max_update:500max_tokens:2048max_source_positions:256max_target_positions:256lr:5e-4dropout:0.2activation_fn: gelucriterion: label_smoothed_cross_entropyreset_optimizer: truereset_lr_scheduler: truereset_dataloader: truereset_meters: truelr_scheduler: inverse_sqrtweight_decay:0.0clip_norm:0.0warmup_init_lr:1e-07label_smoothing:0.1fp16: trueseed:9823843
开始训练!
在准备好配置文件后,运行下面的命令
exportCUDA_VISIBLE_DEVICES=0,1,2 &&exportEVAL_GPU_INDEX=${eval_gpu_index}&& bash${PROJECT_ROOT}/train/fine-tune.sh${finetune_yml}${eval_yml}
eval_gpu_index 表示被分配用于在训练时进行评估的GPU的id,如果设置成 -1则表示在训练过程中将使用CPU进行评估。
${finetune_yml}是上一步中配置好的yaml文件
${eval_yml} 参考https://github.com/linzehui/mRASP/blob/master/experiments/example/configs/eval/en2de_eval.yml
用模型翻译吧!
当训练完成后,我们就可以直接使用fairseq-interactive来实时生成翻译了。假设将checkpoint和bpe codes文件都放在${PROJECT_ROOT}/model目录下,那么可以运行下面的命令:
repo_dir=${PROJECT_ROOT}fairseq-interactive \ --path${repo_dir}/model/checkpoint_last.pt \ --beam 5 --source-lang en --target-lang de \ --tokenizer moses \ --bpe subword_nmt --bpe-codes${repo_dir}/model/codes.bpe.32000
注意输入文本时,一定要在句子前加上language token,比如:
LANG_TOK_EN This was also confirmedbyPeter Arnoldfromthe Offenburg District Office.
模型的输出也会以目标端语言的language token为开头:
LANG_TOK_DEDies bestätigt auch Peter Arnold vom Landratsamt Offenburg.