fairseq入门:Getting Started


前言

Fairseq is a sequence modeling toolkit written in PyTorch that allows researchers and developers to train custom models for translation, summarization, language modeling and other text generation tasks.

Fairseq 是一个基于PyTorch编写的序列建模工具包 (由Facebook AI Research(FAIR)开发),它允许研究人员和开发人员训练用于翻译、摘要、语言建模和其他文本生成任务的自定义模型,以解决各种自然语言处理(NLP)任务。

安装:

  1. 通常情况下,Fairseq是一个较大的项目,因此它的安装可能会占用一些时间和磁盘空间,尤其是如果您的网络连接速度较慢时。
git clone https://github.com/pytorch/fairseq
cd fairseq
pip install --editable ./
  1. 如果只是想使用Fairseq而不需要进行开发或编辑Fairseq源代码,可以考虑直接安装Fairseq的发布版本
pip install fairseq

实际上本节内容知识主要目的是让使用者知道fairseq能干什么


一、Evaluating Pre-trained Models(评估预训练模型)

首先,需要下载示例的预训练模型(一个英语法语对的翻译任务)及它的词汇表(大概1.9g):

curl https://dl.fbaipublicfiles.com/fairseq/models/wmt14.v2.en-fr.fconv-py.tar.bz2 | tar xvjf -

但实际上我在使用过程中服务器下载速度极慢,改用了wget:

wget -c https://dl.fbaipublicfiles.com/fairseq/models/wmt14.v2.en-fr.fconv-py.tar.bz2
tar -xvjf wmt14.v2.en-fr.fconv-py.tar.bz2

会解压出下面五个文件:
在这里插入图片描述

此模型使用了字节对编码(Byte Pair Encoding,BPE)词汇表,因此在进行翻译之前,我们需要将源文本(source text)进行编码——使用 apply_bpe.py 脚本,并使用 wmt14.en-fr.fconv-cuda/bpecodes 文件进行编码。@@ (用来标记词汇切分的边界)被用作连续标记符,原始文本可以通过诸如
sed s/@@ //g

一个用于文本处理的命令。使用了 sed(流编辑器)工具,执行以下操作:其中 s 表示替换操作,@@ 是要查找的文本,// 之间是要用来替换的文本,g 表示全局替换(即一行中的所有匹配都将被替换)。即在文本中查找所有的 @@ 符号,并将其替换为空格)

或传递 --remove-bpe 标志给 fairseq-generate(命令行工具) 来还原。
在进行BPE之前,输入文本需要使用来自 mosesdecodertokenizer.perl 进行标记化。

使用 fairseq-interactive 以交互方式生成翻译。在这里,我们使用了 5束搜索(beam size)并使用了Moses标记器和给定的字节对编码词汇表对输入进行预处理。它将自动删除BPE连续标记符并对输出进行去标记化处理。

演示:
首先需要下载 subword-nmt 库:

pip install subword-nmt

使用清华源更快:

pip install subword-nmt -i https://pypi.tuna.tsinghua.edu.cn/simple

在命令行键入以下示例代码:

> MODEL_DIR=wmt14.en-fr.fconv-py
> fairseq-interactive \
    --path $MODEL_DIR/model.pt $MODEL_DIR \
    --beam 5 --source-lang en --target-lang fr \
    --tokenizer moses \
    --bpe subword_nmt --bpe-codes $MODEL_DIR/bpecodes

选用英文->法语的示例结果如下:

| loading model(s) from wmt14.en-fr.fconv-py/model.pt
| [en] dictionary: 44206 types
| [fr] dictionary: 44463 types
| Type the input sentence and press return:
Why is it rare to discover new marine mammal species?
S-0     Why is it rare to discover new marine mam@@ mal species ?
H-0     -0.0643349438905716     Pourquoi est-il rare de découvrir de nouvelles espèces de mammifères marins?
P-0     -0.0763 -0.1849 -0.0956 -0.0946 -0.0735 -0.1150 -0.1301 -0.0042 -0.0321 -0.0171 -0.0052 -0.0062 -0.0015

这个生成脚本产生三种类型的输出:

O:原始源句子的副本;
H:假设以及平均对数似然;
P:每个标记位置的位置分数,包括在文本中省略的句子末尾标记。
其他类型的输出行包括
D:解标记化的假设;T:参考目标;A:对齐信息;E:生成步骤的历史记录。

我的结果:
在这里插入图片描述

二、Training a New Model(训练一个新模型)

一个机器翻译任务的教程,其他任务可以参见[https://fairseq.readthedocs.io/en/latest/tasks.html#language-modeling]

2.1.Data Pre-processing(数据预处理)

Fairseq包含用于多个翻译数据集(如:IWSLT 2014(德语-英语)、WMT 2014(英语-法语)和WMT 2014(英语-德语))的示例预处理脚本。

需要注意的是如果使用的是第2种安装方法,还需要将fairseq仓库中的example下载

以IWSLT为例:

> cd examples/translation/
> bash prepare-iwslt14.sh
> cd ../..
> TEXT=examples/translation/iwslt14.tokenized.de-en
> fairseq-preprocess --source-lang de --target-lang en \
    --trainpref $TEXT/train --validpref $TEXT/valid --testpref $TEXT/test \
    --destdir data-bin/iwslt14.tokenized.de-en

2.2.Training(训练)

使用fairseq-train训练新模型:

> mkdir -p checkpoints/fconv
> CUDA_VISIBLE_DEVICES=0 fairseq-train data-bin/iwslt14.tokenized.de-en \
    --optimizer nag --lr 0.25 --clip-norm 0.1 --dropout 0.2 --max-tokens 4000 \
    --arch fconv_iwslt_de_en --save-dir checkpoints/fconv

默认情况下,fairseq-train将使用机器上所有可用的 GPU。使用 CUDA_VISIBLE_DEVICES环境变量选择特定 GPU 和/或 更改将使用的 GPU 设备的数量。

另请注意,批次大小是根据每批次的最大令牌数 ( --max-tokens)指定的,具体取决于系统上的可用 GPU 内存。

2.3.Generation(生成)

模型训练完毕后,可以使用 fairseq-generate (针对二值化数据)或 fairseq-interactive (针对原始文本)生成翻译。
命令如下(示例)(但是个人更建议使用脚本文件,更利用调参,记录等):

fairseq-generate data-bin/iwslt14.tokenized.de-en \
    --path checkpoints/fconv/checkpoint_best.pt \
    --batch-size 128 --beam 5

示例结果:

| [de] dictionary: 35475 types
| [en] dictionary: 24739 types
| data-bin/iwslt14.tokenized.de-en test 6750 examples
| model fconv
| loaded checkpoint trainings/fconv/checkpoint_best.pt
S-721   danke .
T-721   thank you .
...

我的结果:
在这里插入图片描述
使用--remove-bpe可以去除延续标记
在这里插入图片描述


三、 Advanced Training Options(训练进阶)

3.1.Large mini-batch training with delayed updates(延迟更新的大批量训练)

可以通过 --update-freq 选项来累积来自多个小批量的梯度并延迟更新,从而创建更大的有效批量大小(batch size)。延迟更新还可以通过减少GPU之间的通信成本和节省由于GPU之间工作负载差异而导致的空闲时间来提高训练速度。更多详细信息,请参阅 文献

累积梯度的方法是将多个小批量的梯度累积在一起,然后在更新模型参数之前对它们进行平均或求和。这样做的好处是可以有效地增加每次参数更新的批量大小,从而提高了训练的效率。通过增加批量大小,可以在一定程度上提高模型的稳定性和泛化性能。

延迟更新是指在累积了一定数量的小批量后才进行一次参数更新。这个过程可以减少模型参数的更新频率,从而减少了GPU之间的通信成本,因为更新参数通常需要在GPU之间传输数据。此外,延迟更新还可以充分利用GPU的计算能力,因为它可以减少由于不同GPU之间工作负载不均匀而导致的空闲时间。

以下命令使得在单个GPU上进行训练,但有效批量大小相当于在8个GPU上进行训练:

CUDA_VISIBLE_DEVICES=0 fairseq-train --update-freq 8 (...)

3.2.Training with half precision floating point (FP16)(使用半精度浮点数(FP16)进行训练)

FP16训练需要使用Volta GPU以及CUDA 9.1或更高版本

  • 单精度浮点数(32位): 符号位:1位 ; 指数位:8位; 尾数位:23位 精度:大约7位有效数字
    范围:通常在约1.4 x 10-45 到3.4 x 1038之间
  • 双精度浮点数(64位): 符号位:1位; 指数位:11位; 尾数位:52位 精度:大约15-16位有效数字
    范围:通常在约5.0 x 10-324到1.8 x 10308之间
  • 半精度浮点数(16位): 符号位:1位; 指数位:5位; 尾数位:10位 精度:约3位有效数字
    范围:较小,但可表示的范围较有限

最近的GPU支持高效的半精度浮点数计算,例如使用Nvidia Tensor Cores。Fairseq支持使用 --fp16 标志进行FP16训练:

fairseq-train --fp16 (...)

3.3.Distributed training(分布式训练)

Fairseq中的分布式训练是建立在torch.distributed之上的。启动作业的最简单方法是使用torch.distributed.launch工具。

例如,要在两个包含8个GPU的节点上训练一个的大型英德Transformer模型(总共16个GPU),可以在每个节点上运行以下命令,并在第二个节点上将 node_rank=0 替换为 node_rank=1,并确保更新 --master_addr 为第一个节点的IP地址:

python -m torch.distributed.launch --nproc_per_node=8 \
    --nnodes=2 --node_rank=0 --master_addr="192.168.1.1" \
    --master_port=12345 \
    $(which fairseq-train) data-bin/wmt16_en_de_bpe32k \
    --arch transformer_vaswani_wmt_en_de_big --share-all-embeddings \
    --optimizer adam --adam-betas '(0.9, 0.98)' --clip-norm 0.0 \
    --lr-scheduler inverse_sqrt --warmup-init-lr 1e-07 --warmup-updates 4000 \
    --lr 0.0005 \
    --dropout 0.3 --weight-decay 0.0 --criterion label_smoothed_cross_entropy --label-smoothing 0.1 \
    --max-tokens 3584 \
    --max-epoch 70 \
    --fp16

SLURM集群上,fairseq将自动检测节点和GPU的数量,但必须提供一个端口号:

salloc --gpus=16 --nodes 2 (...)
srun fairseq-train --distributed-port 12345 (...).

3.4.Sharding very large datasets(对非常大的数据集进行分片操作)

在非常大的数据集上进行训练可能具有挑战性,特别是如果机器中没有太多系统内存 (RAM)。fairseq 中的大多数任务都支持对“分片”数据集进行训练,其中原始数据集已被预处理为不重叠的块(或“分片”)。
例如,您可以拆分数据并创建“data-bin1”、“data-bin2”等,而不是将所有数据预处理到单个“data-bin”目录中。然后您可以像这样调整训练命令:

fairseq-train data-bin1:data-bin2:data-bin3 (...)

现在,训练将逐个迭代每个分片,每个分片对应一个epoch,从而减少系统内存使用量。


四、 Command-line Tools(命令行工具)

Fairseq 提供了多种用于训练和评估模型的命令行工具:

  • fairseq-preprocess:数据预处理:构建词汇表并对训练数据进行二值化
  • fairseq-train:在一个或多个 GPU 上训练新模型
  • fairseq-generate:使用经过训练的模型翻译预处理数据
  • fairseq-interactive:使用经过训练的模型翻译原始文本
  • fairseq-score:根据参考翻译对生成的翻译进行BLEU 评分
  • fairseq-eval-lm:语言模型评估

此前已经接触了前四种;其余详情见官方文档

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值