使用fairseq从头开始训练一个中英神经机器翻译模型

本文详细介绍了在news-commentary-v15语料上训练中英神经机器翻译模型的全过程,包括工具安装、数据预处理(切分、标准化、分词、BPE、过滤)、训练、解码以及后处理和评估。在训练过程中,使用了transformer模型,经过多轮迭代,最终得到最佳模型。

前言

本文在news-commentary-v15语料上训练了中英NMT模型,并将整个流程,包括工具和数据的准备、数据的预处理、训练及解码,以及中途遇到的问题和解决方案记录在此,希望能够给予别人一些帮助。

1 相关工具及目录结构

1.1 相关工具

jieba是使用pip install安装外,其他几个工具都是建议直接克隆库到自己的用户目录中,方便使用其脚本(moses/subword-nmt),或未来可能要自己拓展其中的模型(fairseq)

  1. Moses (一个SMT工具,在这里只会用到一些预处理脚本,如:tokenisation, truecasing, cleaning), 这是文档,安装指令如下:
git clone https://github.com/moses-smt/mosesdecoder.git
  1. subword-nmt (使用BPE算法生成子词的预处理脚本),安装指令如下:
git clone https://github.com/rsennrich/subword-nmt.git
  1. jieba (中文分词组件),安装指令如下:
pip install jieba
  1. fairseq (一个基于PyTorch的序列建模工具), 这是文档,安装指令如下:
git clone https://github.com/pytorch/fairseq
cd fairseq
pip install --editable ./

1.2 目录结构与初始化

1.2.1 目录结构

提前组织一个目录结构的好处是可以让后面的一系列操作更加统一、规范化。下表中~代表linux系统中我的用户目录, v15news目录名代表此次我使用的数据集名称

~
├── mosesdecoder
├── subword-nmt
├── fairseq
└── nmt
    ├── data
        └── v15news
            ├── result          # 用于存放翻译结果
            └── data-bin        # 用于存放二进制文件
    ├── models                  # 用于保存过程中的model文件和checkpoint
        └── v15news
            └── checkpoints     # 保存checkpoints
    ├── utils                   # 一些其他工具
        ├── split.py            # 用于划分train,valid,test
        └── cut2.py             # 用于划分src,tgt
    └── scripts                 # 一些脚本

1.2.2 用于初始化的bash文件

这个文件是在上述目录结构的基础下,定义了一些后面需要用到的变量(主要是各种脚本的路径),包括tokenizer.perl, truecase.perl等,可以在linux中使用bash xx.sh运行,也可以把这些内容直接全部复制到linux命令行中按回车

#!/bin/sh

src=zh
tgt=en

SCRIPTS=~/mosesdecoder/scripts
TOKENIZER=${SCRIPTS}/tokenizer/tokenizer.perl
DETOKENIZER=${SCRIPTS}/tokenizer/detokenizer.perl
LC=${SCRIPTS}/tokenizer/lowercase.perl
TRAIN_TC=${SCRIPTS}/recaser/train-truecaser.perl
TC=${SCRIPTS}/recaser/truecase.perl
DETC=${SCRIPTS}/recaser/detruecase.perl
NORM_PUNC=${SCRIPTS}/tokenizer/normalize-punctuation.perl
CLEAN=${SCRIPTS}/training/clean-corpus-n.perl
BPEROOT=~/subword-nmt/subword_nmt
MULTI_BLEU=${SCRIPTS}/generic/multi-bleu.perl
MTEVAL_V14=${SCRIPTS}/generic/mteval-v14.pl

data_dir=~/nmt/data/v15news
model_dir=~/nmt/models/v15news
utils=~/nmt/utils

2 数据的准备

2.1 平行语料

对于有监督神经机器翻译,能够找到的中英平行语料如下:

  1. NEU nlp lab 开源语料 (10w,国内政治新闻领域)
  2. WMT新闻翻译任务News Commentary语料 (32w左右,国际新闻领域。其实News Commentary每年都有新闻数据集,但是基本没啥变化,每次在前一年的基础上加几百句,所以这里的链接直接指向最新的WMT20)
  3. NIST数据集 (200w左右,需要购买)
  4. United Nations Parallel Corpus (1500w左右,联合国文件领域)

我本人使用过语料1、3,其中3是跟已购买的师兄要的,不向外提供。其实初次训练建议使用语料1,规模小训练快,能够快速体验整个流程。当然,中英还有很多其他语料,见参考资料1, 2

2.2 数据预处理

2.2.1 数据格式

在本篇博客中,我准备使用WMT20新闻翻译任务的news-commentary-v15语料,放于以下位置:

...
└── nmt
    ├── data
        └── v15news     
            └── news-commentary-v15.en-zh.tsv
...

格式如下:

1929 or 1989?	1929年还是1989年?
PARIS – As the economic crisis deepens and widens, the world has been searching for historical analogies to help us understand what has been happening.	巴黎-随着经济危机不断加深和蔓延,整个世界一直在寻找历史上的类似事件希望有助于我们了解目前正在发生的情况。
At the start of the crisis, many people likened it to 1982 or 1973, which was reassuring, because both dates refer to classical cyclical downturns.	一开始,很多人把这次危机比作1982年或1973年所发生的情况,这样得类比是令人宽心的,因为这两段时期意味着典型的周期性衰退。
...

2.2.2 切分

首先,需要将一个单独的数据文件切分成标准格式,即源语言(raw.zh)、目标语言(raw.en)文件各一个,一行一句,附自己写的脚本(~/nmt/utils/cut2.py):

import sys

'''
Usage: 
python cut2.py fpath new_data_dir
'''

def cut2(fpath, new_data_dir, nsrc='zh', ntgt='en'):
    fp = open(fpath, encoding='utf-8')
    src_fp = open(new_data_dir + 'raw.' + nsrc, 'w', encoding='utf-8')
    tgt_fp = open(new_data_dir + 'raw.' + ntgt, 'w', encoding='utf-8')
    for line in fp.readlines():
        tgt_line, src_line = line.replace('\n', '').split('\t')
        src_fp.write(src_line + '\n')
        tgt_fp.write(tgt_line + '\n')
    src_fp.close()
    tgt_fp.close()

if __name__ == '__main__':      
    cut2(fpath
评论 78
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值