重要提示

您正在查看 NeMo 2.0 文档。此版本引入了 API 的重大更改和一个新的库,NeMo Run。我们目前正在将 NeMo 1.0 的所有功能移植到 2.0。有关先前版本或 2.0 中尚不可用的功能的文档,请参阅 NeMo 24.07 文档

机器翻译模型#

机器翻译是将文本从一种语言翻译成另一种语言的任务。例如,从英语翻译成西班牙语。模型基于 Transformer 序列到序列架构 [nlp-machine_translation5]

有关如何训练模型的示例脚本,请在此处找到:NeMo/examples/nlp/machine_translation/enc_dec_nmt.py。模型的默认配置文件可以在以下位置找到:NeMo/examples/nlp/machine_translation/conf/aayn_base.yaml

快速入门指南#

from nemo.collections.nlp.models import MTEncDecModel

# To get the list of pre-trained models
MTEncDecModel.list_available_models()

# Download and load the a pre-trained to translate from English to Spanish
model = MTEncDecModel.from_pretrained("nmt_en_es_transformer24x6")

# Translate a sentence or list of sentences
translations = model.translate(["Hello!"], source_lang="en", target_lang="es")

可用模型#

预训练模型#

模型

预训练检查点

新检查点

英语 -> 德语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_de_transformer24x6

德语 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_de_en_transformer24x6

英语 -> 西班牙语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_es_transformer24x6

西班牙语 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_es_en_transformer24x6

英语 -> 法语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_fr_transformer24x6

法语 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_fr_en_transformer24x6

英语 -> 俄语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_ru_transformer24x6

俄语 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_ru_en_transformer24x6

英语 -> 中文

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_zh_transformer24x6

中文 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_zh_en_transformer24x6

旧检查点

英语 -> 德语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_de_transformer12x2

德语 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_de_en_transformer12x2

英语 -> 西班牙语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_es_transformer12x2

西班牙语 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_es_en_transformer12x2

英语 -> 法语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_fr_transformer12x2

法语 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_fr_en_transformer12x2

英语 -> 俄语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_ru_transformer6x6

俄语 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_ru_en_transformer6x6

英语 -> 中文

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_en_zh_transformer6x6

中文 -> 英语

https://ngc.nvidia.com/catalog/models/nvidia:nemo:nmt_zh_en_transformer6x6

数据格式#

监督机器翻译模型需要平行语料库,其中包含源语言的句子及其在目标语言中的对应翻译的许多示例。我们使用格式化为源语言和目标语言的单独文本文件的平行数据,其中相应文件中的句子像下表一样对齐。

平行语料库#

train.english.txt

train.spanish.txt

Hello .

Hola .

Thank you .

Gracias .

You can now translate from English to Spanish in NeMo .

Ahora puedes traducir del inglés al español en NeMo .

通常的做法是在训练翻译模型之前对数据应用数据清理、规范化和分词,NeMo 期望数据已经过清理、规范化和分词。NeMo 唯一的数据预处理是使用 BPE 进行子词分词 [nlp-machine_translation4]

数据清理、规范化和分词#

我们建议应用以下步骤来清理、规范化和分词您的数据。所有发布的预训练模型都应用了这些数据预处理步骤。

  1. 请查看关于预处理和清理数据集的最佳实践的详细笔记本 - NeMo/tutorials/nlp/Data_Preprocessing_and_Cleaning_for_NMT.ipynb

  2. 语言 ID 过滤 - 此步骤从您的训练数据集中过滤掉非正确语言的示例。例如,许多数据集包含源句和目标句使用相同语言的示例。您可以使用来自 fastText 的预训练语言 ID 分类器。安装 fastText,然后您可以使用从 fastText 网站下载的 lid.176.bin 模型运行我们的脚本。

    python NeMo/scripts/neural_machine_translation/filter_langs_nmt.py \
      --input-src train.en \
      --input-tgt train.es \
      --output-src train_lang_filtered.en \
      --output-tgt train_lang_filtered.es \
      --source-lang en \
      --target-lang es \
      --removed-src train_noise.en \
      --removed-tgt train_noise.es \
      --fasttext-model lid.176.bin
    
  3. 长度过滤 - 我们从数据中过滤掉长度低于最小值 (1) 或超过最大长度 (250) 的句子。我们还过滤掉源长度和目标长度之间的比率超过 1.3 的句子,英语 <-> 中文模型除外。Moses 是一个统计机器翻译工具包,包含许多有用的预处理脚本。

    perl mosesdecoder/scripts/training/clean-corpus-n.perl -ratio 1.3 train en es train.filter 1 250
    
  4. 数据清理 - 虽然语言 ID 过滤有时可以帮助过滤掉包含过多标点符号的噪声句子,但它对翻译可能不正确、不流畅或不完整的情况没有帮助。我们使用 bicleaner 工具来识别此类句子。它基于许多特征训练分类器,包括预训练语言模型流畅度、来自诸如 Giza++ 等词对齐模型的词对齐分数。我们在可能的情况下使用他们可用的预训练模型,并使用他们的框架为剩余语言训练模型。以下脚本将预训练的 bicleaner 模型应用于数据,并选择概率 > 0.5 的干净句子。

    awk '{print "-\t-"}' train.en \
    | paste -d "\t" - train.filter.en train.filter.es \
    | bicleaner-classify - - </path/to/bicleaner.yaml> > train.en-es.bicleaner.score
    
  5. 数据去重 - 我们使用 bifixer(它使用 xxHash)来哈希源句和目标句,并基于此从文件中删除重复条目。您可能需要执行类似操作以删除测试数据集中存在的训练示例。

    cat train.en-es.bicleaner.score \
      | parallel -j 25 --pipe -k -l 30000 python bifixer.py --ignore-segmentation -q - - en es \
      > train.en-es.bifixer.score
    
    awk -F awk -F "\t" '!seen[$6]++' train.en-es.bifixer.score > train.en-es.bifixer.dedup.score
    
  6. 过滤掉 bifixer 分配概率 < 0.5 的数据。

    awk -F "\t" '{ if ($5>0.5) {print $3}}' train.en-es.bifixer.dedup.score > train.cleaned.en
    awk -F "\t" '{ if ($5>0.5) {print $4}}' train.en-es.bifixer.dedup.score > train.cleaned.es
    
  7. 标点符号规范化 - 标点符号,尤其是引号之类的东西,可以用不同的方式书写。规范化它们在文本中出现的方式通常很有用。我们对除中文外的所有语言使用 moses 标点符号规范化器。

    perl mosesdecoder/scripts/tokenizer/normalize-punctuation.perl -l es < train.cleaned.es > train.normalized.es
    perl mosesdecoder/scripts/tokenizer/normalize-punctuation.perl -l en < train.cleaned.en > train.normalized.en
    

    例如

    Before - Aquí se encuentran joyerías como Tiffany`s entre negocios tradicionales suizos como la confitería Sprüngli.
    After  - Aquí se encuentran joyerías como Tiffany's entre negocios tradicionales suizos como la confitería Sprüngli.
    
  8. 中文的分词和分词 - 自然书写的文本通常包含标点符号标记,如逗号、句点和撇号,它们附加到单词上。仅通过在空格上拆分字符串进行分词将导致非常相似的项目(如 NeMoNeMo.)的单独标记 ID。分词将标点符号从单词中拆分出来以创建两个单独的标记。在前面的示例中,NeMo. 变为 NeMo .,当按空格拆分时,会产生两个标记并解决早期的问题。

    例如

    Before - Especialmente porque se enfrentará "a Mathieu (Debuchy), Yohan (Cabaye) y Adil (Rami) ", recuerda.
    After  - Especialmente porque se enfrentará " a Mathieu ( Debuchy ) , Yohan ( Cabaye ) y Adil ( Rami ) " , recuerda .
    

    我们对除中文外的所有语言使用 Moses 分词器。

    perl mosesdecoder/scripts/tokenizer/tokenizer.perl -l es -no-escape < train.normalized.es > train.tokenized.es
    perl mosesdecoder/scripts/tokenizer/tokenizer.perl -l en -no-escape < train.normalized.en > train.tokenized.en
    

    对于像中文这样没有空格等显式标记分隔单词的语言,我们使用 Jieba 将字符串分段为以空格分隔的单词。

    例如

    Before - 同时卫生局认为有必要接种的其他人员包括公共部门卫生局将主动联络有关机构取得名单后由卫生中心安排接种
    After  - 同时  卫生局 认为  必要 接种  其他 人员  包括 公共部门  卫生局  主动 联络 有关 机构 取得 名单   卫生 中心 安排 接种 
    

训练 BPE 分词器#

字节对编码 (BPE) [nlp-machine_translation4] 是一种子词分词算法,通常用于通过将单词拆分为频繁出现的子词来减小数据集的大词汇量。目前,机器翻译仅支持 YouTokenToMe BPE 分词器。可以按如下方式设置分词配置

参数

数据类型

默认值

描述

model.{encoder_tokenizer,decoder_tokenizer}.tokenizer_name

str

yttm

BPE 库名称。目前仅支持 yttm

model.{encoder_tokenizer,decoder_tokenizer}.tokenizer_model

str

null

现有 YTTM BPE 模型的路径。如果为 null,将根据提供的数据从头开始训练一个。

model.{encoder_tokenizer,decoder_tokenizer}.vocab_size

int

null

BPE 分词后所需的词汇表大小。

model.{encoder_tokenizer,decoder_tokenizer}.bpe_dropout

float

null

BPE dropout 概率。[nlp-machine_translation3]

model.{encoder_tokenizer,decoder_tokenizer}.vocab_file

str

null

如果存在,则为预计算词汇表文件的路径。

model.shared_tokenizer

bool

True

是否在编码器和解码器之间共享分词器。

应用 BPE 分词、批处理、分桶和填充#

给定 BPE 分词器和清理后的平行语料库,应用以下步骤来创建 TranslationDataset 对象。

  1. 文本转 ID - 这使用 BPE 模型对输入字符串执行子词分词,并将其映射到源文本和目标文本的标记序列。

  2. 分桶 - 句子的长度各不相同,在创建小批量时,我们希望其中的句子长度大致相同,以最大限度地减少 <pad> 标记的数量并最大限度地提高计算效率。此步骤将长度大致相同的句子分组到桶中。

  3. 批处理和填充 - 使用 model.{train_ds,validation_ds,test_ds}.tokens_in_batch 指定的最大标记数从桶中创建小批量并进行填充,以便可以将它们打包到张量中。

数据集可以按如下方式配置

参数

数据类型

默认值

描述

model.{train_ds,validation_ds,test_ds}.src_file_name

str

null

源语言文件的路径。

model.{train_ds,validation_ds,test_ds}.tgt_file_name

str

null

目标语言文件的路径。

model.{train_ds,validation_ds,test_ds}.tokens_in_batch

int

512

每个小批量的最大标记数。

model.{train_ds,validation_ds,test_ds}.clean

bool

true

是否通过丢弃大于 max_seq_length 的示例来清理数据集。

model.{train_ds,validation_ds,test_ds}.max_seq_length

int

512

要与上面的 clean 参数一起使用的最大序列。

model.{train_ds,validation_ds,test_ds}.shuffle

bool

true

是否在 PyTorch DataLoader 中随机排序小批量。

model.{train_ds,validation_ds,test_ds}.num_samples

int

-1

要使用的样本数。-1 表示整个数据集。

model.{train_ds,validation_ds,test_ds}.drop_last

bool

false

如果最后一个小批量的大小与其他小批量的大小不相等,则丢弃最后一个小批量。

model.{train_ds,validation_ds,test_ds}.pin_memory

bool

false

是否在 PyTorch DataLoader 中固定内存。

model.{train_ds,validation_ds,test_ds}.num_workers

int

8

PyTorch DataLoader 的工作进程数。

大型语料库的 Tarred 数据集#

当使用 DistributedDataParallel 进行训练时,每个进程都有其自己的数据集副本。对于大型数据集,这可能并不总能放入 CPU 内存中。Webdatasets 通过有效地迭代存储在磁盘上的 tar 文件来规避此问题。每个 tar 文件可以包含数百到数千个 pickle 文件,每个文件包含单个小批量。

当处理包含超过 100 万个句子对的数据集时,我们建议使用此方法。

Tarred 数据集可以按如下方式配置

参数

数据类型

默认值

描述

model.{train_ds,validation_ds,test_ds}.use_tarred_dataset

bool

false

是否使用 tarred 数据集。

model.{train_ds,validation_ds,test_ds}.tar_files

str

null

指定所有 tar 文件路径的字符串。包含 100 个 tar 文件的示例 /path/to/tarfiles._OP_1..100_CL_.tar

model.{train_ds,validation_ds,test_ds}.metadata_file

str

null

JSON 元数据文件的路径,该文件仅包含数据集中批次总数的单个条目。

model.{train_ds,validation_ds,test_ds}.lines_per_dataset_fragment

int

1000000

用于分桶和填充的行数。

model.{train_ds,validation_ds,test_ds}.num_batches_per_tarfile

int

100

每个 tar 文件中的批次数(pickle 文件)。

model.{train_ds,validation_ds,test_ds}.tar_shuffle_n

int

100

要向前查看和加载以进行随机排序的样本数。

model.{train_ds,validation_ds,test_ds}.shard_strategy

str

scatter

分片如何在多个工作进程之间分布。

model.preproc_out_dir

str

null

包含处理后的 tar 文件的文件夹的路径或写入新 tar 文件的目录。

可以通过两种方式创建 Tarred 数据集

  1. 使用 Hydra 配置和 训练脚本

    例如

    python examples/nlp/machine_translation/enc_dec_nmt.py \
      -cn aayn_base \
      do_training=false \
      model.preproc_out_dir=/path/to/preproc_dir \
      model.train_ds.use_tarred_dataset=true \
      model.train_ds.lines_per_dataset_fragment=1000000 \
      model.train_ds.num_batches_per_tarfile=200 \
      model.train_ds.src_file_name=train.tokenized.en \
      model.train_ds.tgt_file_name=train.tokenized.es \
      model.validation_ds.src_file_name=validation.tokenized.en \
      model.validation_ds.tgt_file_name=validation.tokenized.es \
      model.encoder_tokenizer.vocab_size=32000 \
      model.decoder_tokenizer.vocab_size=32000 \
      ~model.test_ds \
      trainer.devices=[0,1,2,3] \
      trainer.accelerator='gpu' \
      +trainer.fast_dev_run=true \
      exp_manager=null \
    

    上面的脚本将平行的分词文本文件处理成 tarred 数据集,这些数据集被写入 /path/to/preproc_dir。由于 do_training 设置为 False,因此上面的脚本仅创建 tarred 数据集,然后退出。如果 do_training 设置为 True,则会发生以下两种情况之一

    1. 如果 model.preproc_out_dir 中不存在 tar 文件,则脚本首先创建这些文件,然后开始训练。

    2. 如果 model.preproc_out_dir 中已存在 tar 文件,则脚本从提供的 tar 文件开始训练。

  2. 使用没有 Hydra 的单独脚本。

    平行语料库的 Tarred 数据集也可以使用不需要通过 Hydra 指定配置的脚本创建,而只需使用 Python argparse。

    例如

    python examples/nlp/machine_translation/create_tarred_parallel_dataset.py \
      --shared_tokenizer \
      --clean \
      --bpe_dropout 0.1 \
      --src_fname train.tokenized.en \
      --tgt_fname train.tokenized.es \
      --out_dir /path/to/preproc_dir \
      --vocab_size 32000 \
      --max_seq_length 512 \
      --min_seq_length 1 \
      --tokens_in_batch 8192 \
      --lines_per_dataset_fragment 1000000 \
     --num_batches_per_tarfile 200
    

然后,您可以设置 model.preproc_out_dir=/path/to/preproc_dirmodel.train_ds.use_tarred_dataset=true 以使用此数据进行训练。

模型配置和训练#

总体模型由编码器、解码器和分类头组成。编码器和解码器具有以下配置选项

参数

数据类型

默认值

描述

model.{encoder,decoder}.max_sequence_length

int

512

位置编码的最大序列长度。

model.{encoder,decoder}.embedding_dropout

float

0.1

JSON 元数据文件的路径,该文件仅包含数据集中批次总数的单个条目。

model.{encoder,decoder}.learn_positional_encodings

bool

false

如果为 True,则这是一个常规的可学习嵌入层。如果为 False,则将位置编码固定为正弦波。

model.{encoder,decoder}.hidden_size

int

512

Transformer 隐藏状态的大小。

model.{encoder,decoder}.num_layers

int

6

Transformer 层数。

model.{encoder,decoder}.inner_size

int

2048

前馈层中隐藏状态的大小。

model.{encoder,decoder}.num_attention_heads

int

8

注意力头的数量。

model.{encoder,decoder}.ffn_dropout

float

0.1

前馈层中的 dropout 概率。

model.{encoder,decoder}.attn_score_dropout

float

0.1

softmax 归一化之前注意力分数的 dropout 概率。

model.{encoder,decoder}.attn_layer_dropout

float

0.1

注意力查询、键和值投影激活的 dropout 概率。

model.{encoder,decoder}.hidden_act

str

relu

整个网络中的激活函数。

model.{encoder,decoder}.mask_future

bool

false, true

是否屏蔽未来时间步以进行注意力。解码器默认为 True,编码器默认为 False

model.{encoder,decoder}.pre_ln

bool

false

是在子层之前 (true) 还是之后 (false) 应用层归一化。

我们的预训练模型使用 Adam 优化,最大学习率为 0.0004,beta 为 (0.9, 0.98),以及来自 [nlp-machine_translation5] 的反平方根学习率计划。model.optim 部分设置优化参数。

以下脚本基于提供的平行语料库创建 tarred 数据集,并基于来自 [nlp-machine_translation5]base 配置训练模型。

python examples/nlp/machine_translation/enc_dec_nmt.py \
  -cn aayn_base \
  do_training=true \
  trainer.devices=8 \
  trainer.accelerator='gpu' \
  ~trainer.max_epochs \
  +trainer.max_steps=100000 \
  +trainer.val_check_interval=1000 \
  +exp_manager.exp_dir=/path/to/store/results \
  +exp_manager.create_checkpoint_callback=True \
  +exp_manager.checkpoint_callback_params.monitor=val_sacreBLEU \
  +exp_manager.checkpoint_callback_params.mode=max \
  +exp_manager.checkpoint_callback_params.save_top_k=5 \
  model.preproc_out_dir=/path/to/preproc_dir \
  model.train_ds.use_tarred_dataset=true \
  model.train_ds.lines_per_dataset_fragment=1000000 \
  model.train_ds.num_batches_per_tarfile=200 \
  model.train_ds.src_file_name=train.tokenized.en \
  model.train_ds.tgt_file_name=train.tokenized.es \
  model.validation_ds.src_file_name=validation.tokenized.en \
  model.validation_ds.tgt_file_name=validation.tokenized.es \
  model.encoder_tokenizer.vocab_size=32000 \
  model.decoder_tokenizer.vocab_size=32000 \
  ~model.test_ds \

训练器跟踪提供的验证集上的 sacreBLEU 分数 [nlp-machine_translation2],并保存 sacreBLEU 分数最高的 5 个(默认情况下)检查点。

在训练结束时,.nemo 文件被写入结果目录,这允许在测试集上运行推理。

多重验证#

要在多个数据集上运行验证,请使用文件路径列表指定 validation_ds.src_file_namevalidation_ds.tgt_file_name

model.validation_ds.src_file_name=[/data/wmt13-en-de.src,/data/wmt14-en-de.src] \
model.validation_ds.tgt_file_name=[/data/wmt13-en-de.ref,/data/wmt14-en-de.ref] \

当使用 val_lossval_sacreBLEU 作为 exp_manager.checkpoint_callback_params.monitor 时,则第 0 个索引的数据集将用作监视器。

要使用其他索引,请附加索引

exp_manager.checkpoint_callback_params.monitor=val_sacreBLEU_dl_index_1

多个测试数据集的工作方式与验证数据集完全相同,只需在上面的示例中将 validation_ds 替换为 test_ds 即可。

瓶颈模型和隐变量模型 (VAE, MIM)#

还支持带有瓶颈编码器架构的 NMT(即,固定大小的瓶颈),以及隐变量模型(当前为 VAE 和 MIM)的训练。

  1. 支持的学习框架 (model.model_type)
    • NLL - 条件交叉熵(通常的 NMT 损失)

    • VAE - 变分自动编码器 (论文)

    • MIM - 互信息机 (论文)

  2. 支持的编码器架构 (model.encoder.arch)
    • seq2seq - 没有瓶颈的常用 Transformer 编码器

    • bridge - 注意力桥瓶颈 (论文)

    • perceiver - Perceiver 瓶颈 (论文)

参数

数据类型

默认值

描述

model.model_type

str

nll

学习(即,损失)类型:nll(即,交叉熵/自动编码器)、mim、vae(请参阅上面的描述)

model.min_logv

float

-6

mim 的最小允许对数方差

model.latent_size

int

-1

从隐藏层投影的潜在维度 -1 将采用隐藏层大小的值

model. non_recon_warmup_batches

bool

200000

mim 和 vae 损失的预热步骤(退火非重建部分)

model. recon_per_token

bool

true

当为 false 时,重建是按样本计算的,而不是按标记计算的

model.encoder.arch

str

seq2seq

支持的架构:seq2seqbridgeperceiver(请参阅上面的描述)。

model.encoder.hidden_steps

int

32

固定数量的隐藏步骤

model.encoder.hidden_blocks

int

1

重复块的数量(有关描述,请参阅类)

model.encoder. hidden_init_method

str

default

有关可用值,请参阅类

配置参数的详细描述

  • model.encoder.arch=seq2seq
    • model.encoder.hidden_steps 被忽略

    • model.encoder.hidden_blocks 被忽略

    • model.encoder.hidden_init_method 被忽略

  • model.encoder.arch=bridge
    • model.encoder.hidden_steps: 输入被投影到指定的固定步骤

    • model.encoder.hidden_blocks: 注意力桥投影后要重复的编码器块数

    • model.encoder.hidden_init_method
      • enc_shared (default) - 将编码器应用于输入,然后应用注意力桥,然后是 hidden_blocks 数量的相同编码器(前置编码器和后置编码器共享参数)

      • identity - 将注意力桥应用于输入,然后是 hidden_blocks 数量的相同编码器

      • enc - 类似于 enc_shared,但初始编码器具有独立的参数

  • model.encoder.arch=perceiver
    • model.encoder.hidden_steps: 输入被投影到指定的固定步骤

    • model.encoder.hidden_blocks: 初始化块后要重复的交叉注意力 + 自注意力块的数量(所有自注意力和交叉注意力共享参数)

    • model.encoder.hidden_init_method
      • params (default) - 隐藏状态使用学习的参数初始化,然后是具有独立参数的交叉注意力

      • bridge - 隐藏状态使用注意力桥初始化

训练需要使用以下脚本(而不是 enc_dec_nmt.py

python -- examples/nlp/machine_translation/enc_dec_nmt-bottleneck.py \
      --config-path=conf \
      --config-name=aayn_bottleneck \
      ...
      model.model_type=nll \
      model.non_recon_warmup_batches=7500 \
      model.encoder.arch=perceiver \
      model.encoder.hidden_steps=32 \
      model.encoder.hidden_blocks=2 \
      model.encoder.hidden_init_method=params \
      ...

模型推理#

要在测试集上生成翻译并计算 sacreBLEU 分数,请运行推理脚本

python examples/nlp/machine_translation/nmt_transformer_infer.py \
  --model /path/to/model.nemo \
  --srctext test.en \
  --tgtout test.en-es.translations \
  --batch_size 128 \
  --source_lang en \
  --target_lang es

必须在分词和规范化之前提供 --srctext 文件。生成的 --tgtout 文件经过反分词,可用于计算 sacreBLEU 分数。

cat test.en-es.translations | sacrebleu test.es

推理改进#

实际上,在推理中有一些常用的技术可以提高翻译质量。NeMo 实现了

  1. 模型集成

  2. 使用 Transformer 语言模型的浅层融合解码 [nlp-machine_translation1]

  3. 噪声信道重排序 [nlp-machine_translation6]

  1. 模型集成 - 给定许多使用相同编码器和解码器分词器训练的模型,可以集成它们的预测(通过平均每个步骤的概率)以生成更好的翻译。

\[P(y_t|y_{<t},x;\theta_{1} \ldots \theta_{k}) = \frac{1}{k} \sum_{i=1}^k P(y_t|y_{<t},x;\theta_{i})\]

注意:重要的是要确保所有集成的模型都使用相同的分词器进行训练。

推理脚本将集成通过 --model 参数提供的所有模型,作为指向多个模型路径的逗号分隔字符串。

例如,要集成三个模型 /path/to/model1.nemo、/path/to/model2.nemo、/path/to/model3.nemo,请运行

python examples/nlp/machine_translation/nmt_transformer_infer.py \
  --model /path/to/model1.nemo,/path/to/model2.nemo,/path/to/model3.nemo \
  --srctext test.en \
  --tgtout test.en-es.translations \
  --batch_size 128 \
  --source_lang en \
  --target_lang es
  1. 浅层融合解码与 Transformer 语言模型 - 给定一个翻译模型或翻译模型集成,可以将翻译模型(们)提供的分数与目标端语言模型结合起来。

在每个解码步骤中,beam 上特定假设的分数由翻译模型对数概率和语言模型对数概率的加权和给出。

\[\mathcal{S}(y_{1\ldots n}|x;\theta_{s \rightarrow t},\theta_{t}) = \mathcal{S}(y_{1\ldots n - 1}|x;\theta_{s \rightarrow t},\theta_{t}) + \log P(y_{n}|y_{<n},x;\theta_{s \rightarrow t}) + \lambda_{sf} \log P(y_{n}|y_{<n};\theta_{t})\]

Lambda 控制分配给语言模型的权重。目前,仅支持在 NeMo 中训练的 transformer 语言模型系列。

注意:transformer 语言模型需要使用与 NMT 系统中解码器 tokenizer 相同的 tokenizer 进行训练。

例如,要使用 LM /path/to/lm.nemo 通过浅层融合集成三个模型 /path/to/model1.nemo、/path/to/model2.nemo、/path/to/model3.nemo

python examples/nlp/machine_translation/nmt_transformer_infer.py \
  --model /path/to/model1.nemo,/path/to/model2.nemo,/path/to/model3.nemo \
  --lm_model /path/to/lm.nemo \
  --fusion_coef 0.05 \
  --srctext test.en \
  --tgtout test.en-es.translations \
  --batch_size 128 \
  --source_lang en \
  --target_lang es
  1. 噪声信道重排序 - 与集成和浅层融合不同,噪声信道重排序仅对 beam 搜索产生的最终候选进行重排序。它基于三个分数进行重排序

  1. 前向(源到目标)翻译模型(们)对数概率

  2. 反向(目标到源)翻译模型(们)对数概率

  3. 语言模型(目标)对数概率

\[\argmax_{i} \mathcal{S}(y_i|x) = \log P(y_i|x;\theta_{s \rightarrow t}^{ens}) + \lambda_{ncr} \big( \log P(x|y_i;\theta_{t \rightarrow s}) + \log P(y_i;\theta_{t}) \big)\]

要执行噪声信道重排序,首先生成一个 .scores 文件,其中包含来自前向翻译模型的 beam 上每个假设的对数概率。

python examples/nlp/machine_translation/nmt_transformer_infer.py \
  --model /path/to/model1.nemo,/path/to/model2.nemo,/path/to/model3.nemo \
  --lm_model /path/to/lm.nemo \
  --write_scores \
  --fusion_coef 0.05 \
  --srctext test.en \
  --tgtout test.en-es.translations \
  --batch_size 128 \
  --source_lang en \
  --target_lang es

这将生成一个分数文件 test.en-es.translations.scores,该文件作为输入提供给 NeMo/examples/nlp/machine_translation/noisy_channel_reranking.py

此脚本还需要反向(目标到源)翻译模型和目标语言模型。

python noisy_channel_reranking.py \
    --reverse_model=/path/to/reverse_model1.nemo,/path/to/reverse_model2.nemo \
    --language_model=/path/to/lm.nemo \
    --srctext=test.en-es.translations.scores \
    --tgtout=test-en-es.ncr.translations \
    --forward_model_coef=1.0 \
    --reverse_model_coef=0.7 \
    --target_lm_coef=0.05 \

预训练编码器#

来自 HuggingFace TransformersMegatron-LM 的预训练 BERT 编码器可用于训练 NeMo NMT 模型。

library 标志接受以下值:huggingfacemegatronnemo

model_name 标志用于指示命名模型架构。例如,我们可以使用 HuggingFace 的 bert_base_cased 或 Megatron-LM 的 megatron-bert-345m-cased

pretrained 标志指示是否下载预训练权重(pretrained=True)或实例化具有随机权重的相同模型架构(pretrained=False)。

要使用来自特定库的自定义模型架构,请使用 model_name=null,然后在 encoder 配置下添加自定义配置。

HuggingFace#

我们提供了一个 HuggingFace 配置文件,用于 HuggingFace 编码器。

要从 CLI 使用配置文件

--config-path=conf \
--config-name=huggingface \

例如,我们可以通过使用 huggingface 配置文件并进行设置,将 NeMo NMT 编码器配置为使用 HuggingFace 的 bert-base-cased

model.encoder.pretrained=true \
model.encoder.model_name=bert-base-cased \

要使用 HuggingFace 的自定义架构,我们可以使用

+model.encoder._target_=transformers.BertConfig \
+model.encoder.hidden_size=1536 \

请注意,如果我们不将参数添加到 YAML 配置文件,则需要 + 符号。

Megatron#

我们提供了一个 Megatron 配置文件,用于 Megatron 编码器。

要从 CLI 使用配置文件

--config-path=conf \
--config-name=megatron \

checkpoint_file 应该是 Megatron-LM 检查点的路径

/path/to/your/megatron/checkpoint/model_optim_rng.pt

如果您的 megatron 模型需要模型并行性,则 checkpoint_file 应指向包含标准 Megatron-LM 检查点格式的目录

3.9b_bert_no_rng
├── mp_rank_00
   └── model_optim_rng.pt
├── mp_rank_01
   └── model_optim_rng.pt
├── mp_rank_02
   └── model_optim_rng.pt
└── mp_rank_03
    └── model_optim_rng.pt

例如,要使用 3.9B Megatron BERT 编码器训练 NeMo NMT 模型,我们将使用以下编码器配置

model.encoder.checkpoint_file=/path/to/megatron/checkpoint/3.9b_bert_no_rng \
model.encoder.hidden_size=2560 \
model.encoder.num_attention_heads=40 \
model.encoder.num_layers=48 \
model.encoder.max_position_embeddings=512 \

要训练 Megatron 345M BERT,我们将使用

model.encoder.model_name=megatron-bert-cased \
model.encoder.checkpoint_file=/path/to/your/megatron/checkpoint/model_optim_rng.pt \
model.encoder.hidden_size=1024 \
model.encoder.num_attention_heads=16 \
model.encoder.num_layers=24 \
model.encoder.max_position_embeddings=512 \

如果预训练的 megatron 模型使用了自定义词汇表文件,则设置

model.encoder_tokenizer.vocab_file=/path/to/your/megatron/vocab_file.txt
model.encoder.vocab_file=/path/to/your/megatron/vocab_file.txt

对于带有自定义词汇表的非大小写模型,使用 encoder.model_name=megatron_bert_uncased,对于带有自定义词汇表的大小写模型,使用 encoder.model_name=megatron_bert_cased

参考文献#

[nlp-machine_translation1]

Caglar Gulcehre, Orhan Firat, Kelvin Xu, Kyunghyun Cho, Loic Barrault, Huei-Chi Lin, Fethi Bougares, Holger Schwenk, 和 Yoshua Bengio. On using monolingual corpora in neural machine translation. arXiv preprint arXiv:1503.03535, 2015.

[nlp-machine_translation2]

Matt Post. A call for clarity in reporting bleu scores. arXiv preprint arXiv:1804.08771, 2018.

[nlp-machine_translation3]

Ivan Provilkov, Dmitrii Emelianenko, 和 Elena Voita. Bpe-dropout: simple and effective subword regularization. arXiv preprint arXiv:1910.13267, 2019.

[nlp-machine_translation4] (1,2)

Rico Sennrich, Barry Haddow, 和 Alexandra Birch. Neural machine translation of rare words with subword units. arXiv preprint arXiv:1508.07909, 2015.

[nlp-machine_translation5] (1,2,3)

Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez, Łukasz Kaiser, 和 Illia Polosukhin. Attention is all you need. In Advances in Neural Information Processing Systems, 6000–6010. 2017.

[nlp-machine_translation6]

Kyra Yee, Nathan Ng, Yann N Dauphin, 和 Michael Auli. Simple and effective noisy channel modeling for neural machine translation. arXiv preprint arXiv:1908.05731, 2019.