XLNET是一种基于新颖的广义置换语言建模目标的新的无监督语言表示学习方法。此外,XLNET还采用Transformer-XL作为骨干模型,在涉及长篇小说的语言任务方面表现出色。总体而言,XLNET在各种下游语言任务上取得了最新的(SOTA),包括问答,自然语言推断,情感分析和文档排名。
有关技术细节和实验结果的详细说明,请参阅我们的论文:
XLNET:通用自动回报预处理以了解语言理解
Zhilin Yang*,Zihang dai*,Yiming Yang,Jaime Carbonell,Ruslan Salakhutdinov,Quoc V. Le
(*:同等贡献)
预印2019年
截至2019年6月19日,XLNet在20个任务上的表现优于Bert,并在18个任务上取得了最新的成果。以下是XLNET-LARGE和BERT-LARGE之间的一些比较,它们具有相似的模型大小:
| 模型 | 种族准确性 | squad1.1 em | squad2.0 em |
|---|---|---|---|
| Bert-large | 72.0 | 84.1 | 78.98 |
| XLNET基础 | 80.18 | ||
| Xlnet-large | 81.75 | 88.95 | 86.12 |
我们在表中使用小队开发结果来排除其他因素,例如使用其他培训数据或其他数据增强技术。有关测试号,请参见小队排行榜。
| 模型 | IMDB | Yelp-2 | Yelp-5 | dbpedia | 亚马逊2 | 亚马逊5 |
|---|---|---|---|---|---|---|
| Bert-large | 4.51 | 1.89 | 29.32 | 0.64 | 2.63 | 34.17 |
| Xlnet-large | 3.79 | 1.55 | 27.80 | 0.62 | 2.40 | 32.26 |
以上数字是错误率。
| 模型 | mnli | Qnli | QQP | rte | SST-2 | MRPC | 可乐 | STS-B |
|---|---|---|---|---|---|---|---|---|
| Bert-large | 86.6 | 92.3 | 91.3 | 70.4 | 93.2 | 88.0 | 60.6 | 90.0 |
| XLNET基础 | 86.8 | 91.7 | 91.4 | 74.0 | 94.7 | 88.2 | 60.2 | 89.5 |
| Xlnet-large | 89.8 | 93.9 | 91.8 | 83.8 | 95.6 | 89.2 | 63.6 | 91.8 |
我们使用表中的单任务开发结果来排除其他因素,例如多任务学习或使用合奏。
截至2019年7月16日,已提供以下模型:
XLNet-Large, Cased :24层,1024个隐藏,16头XLNet-Base, Cased :12层,768隐藏,12头。该模型对完整数据进行了培训(与论文中的数据不同)。我们目前仅发布Cased模型,因为在我们考虑的任务上,我们发现:(1)对于基本设置,壳体和未基于的模型具有相似的性能; (2)对于大型设置,在某些任务中,外壳模型要好一些。
每个.zip文件包含三个项目:
xlnet_model.ckpt ),其中包含预训练的权重(实际上是3个文件)。spiece.model )。xlnet_config.json )指定模型的超参数。我们还计划在不同的设置下不断释放更多预定的模型,包括:
为了接收有关更新,公告和新版本的通知,我们建议在Google组上订阅XLNET。
截至2019年6月19日,该代码基础已在Python2下用Tensorflow 1.13.1进行了测试。
XLNet-Large SOTA SOTA在本文中使用GPU和12GB-16GB的RAM产生,因为16GB GPU只能持有XLNet-Large的长度为512的单个序列。因此,需要大量(从32到128,等于batch_size )的GPU来重现论文中的许多结果。给定上面提到的内存问题,使用默认的登录脚本( run_classifier.py和run_squad.py ),我们使用TensorFlow 1.13.1 :单个16GB GPU上的最大批处理大小进行了基准测试。
| 系统 | SEQ长度 | 最大批处理大小 |
|---|---|---|
XLNet-Base | 64 | 120 |
| ... | 128 | 56 |
| ... | 256 | 24 |
| ... | 512 | 8 |
XLNet-Large | 64 | 16 |
| ... | 128 | 8 |
| ... | 256 | 2 |
| ... | 512 | 1 |
在大多数情况下,可以减少批处理大小train_batch_size或最大序列长度max_seq_length以适合给定的硬件。性能的下降取决于任务和可用资源。
用于执行分类/回归框的代码在run_classifier.py中。它还包含用于标准一文物分类,一道文档回归和文档对分类的示例。在这里,我们提供了两个具体示例,介绍了如何使用run_classifier.py 。
从这里开始,我们假设XLNET-LARGE和XLNET-BASE分别已下载到$LARGE_DIR和$BASE_DIR 。
通过运行此脚本下载胶水数据,然后将其解放到某些目录$GLUE_DIR 。
通过运行,用XLNET-LARGE执行多GPU (4 V100 GPU)
CUDA_VISIBLE_DEVICES=0,1,2,3 python run_classifier.py
--do_train=True
--do_eval=False
--task_name=sts-b
--data_dir= ${GLUE_DIR} /STS-B
--output_dir=proc_data/sts-b
--model_dir=exp/sts-b
--uncased=False
--spiece_model_file= ${LARGE_DIR} /spiece.model
--model_config_path= ${LARGE_DIR} /xlnet_config.json
--init_checkpoint= ${LARGE_DIR} /xlnet_model.ckpt
--max_seq_length=128
--train_batch_size=8
--num_hosts=1
--num_core_per_host=4
--learning_rate=5e-5
--train_steps=1200
--warmup_steps=120
--save_steps=600
--is_regression=True通过单个GPU评估鉴定结果
CUDA_VISIBLE_DEVICES=0 python run_classifier.py
--do_train=False
--do_eval=True
--task_name=sts-b
--data_dir= ${GLUE_DIR} /STS-B
--output_dir=proc_data/sts-b
--model_dir=exp/sts-b
--uncased=False
--spiece_model_file= ${LARGE_DIR} /spiece.model
--model_config_path= ${LARGE_DIR} /xlnet_config.json
--max_seq_length=128
--eval_batch_size=8
--num_hosts=1
--num_core_per_host=1
--eval_all_ckpt=True
--is_regression=True
# Expected performance: "eval_pearsonr 0.916+ "注意:
num_core_per_host表示要使用的GPU数量。train_batch_size是指每gpu批量尺寸。eval_all_ckpt允许人们评估所有保存的检查点(保存频率由save_steps控制),并根据开发性能选择最佳模型。data_dir和output_dir分别是指“原始数据”和“预处理tfrecords”的目录,而model_dir是保存检查点和张量事件的工作目录。 model_dir应设置为init_checkpoint的单独文件夹。--train_batch_size=32和--num_core_per_host=1 ,以及init_checkpoint和model_config_path中的更改。train_batch_size并增加num_core_per_host以使用相同的训练设置。通过运行下载并解开IMDB数据集
wget http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
tar zxvf aclImdb_v1.tar.gz启动Google Cloud TPU V3-8实例(有关如何设置Cloud TPU,请参见Google Cloud TPU教程)。
设置您的Google存储存储桶路径$GS_ROOT ,然后将IMDB数据集移动并验证的检查点进入您的Google存储。
通过运行使用XLNet-Large执行TPU登录
python run_classifier.py
--use_tpu=True
--tpu= ${TPU_NAME}
--do_train=True
--do_eval=True
--eval_all_ckpt=True
--task_name=imdb
--data_dir= ${IMDB_DIR}
--output_dir= ${GS_ROOT} /proc_data/imdb
--model_dir= ${GS_ROOT} /exp/imdb
--uncased=False
--spiece_model_file= ${LARGE_DIR} /spiece.model
--model_config_path= ${GS_ROOT} / ${LARGE_DIR} /model_config.json
--init_checkpoint= ${GS_ROOT} / ${LARGE_DIR} /xlnet_model.ckpt
--max_seq_length=512
--train_batch_size=32
--eval_batch_size=8
--num_hosts=1
--num_core_per_host=8
--learning_rate=2e-5
--train_steps=4000
--warmup_steps=500
--save_steps=500
--iterations=500
# Expected performance: "eval_accuracy 0.962+ "注意:
data_dir和spiece_model_file都使用本地路径而不是Google存储路径。原因是数据预处理实际上是在本地执行的。因此,使用本地路径会导致更快的预处理速度。 run_squad.py中包含了小队数据集的代码。
运行代码:
(1)将squad2.0数据集下载到$SQUAD_DIR中:
mkdir -p ${SQUAD_DIR} && cd ${SQUAD_DIR}
wget https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json
wget https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json (2)使用脚本scripts/prepro_squad.sh执行数据预处理。
为了准确地将字符位置(原始数据)映射到句子件位置(用于训练),这将需要一段时间。
有关更快的并行预处理,请参阅run_squad.py中的标志--num_proc和--proc_id 。
(3)执行培训和评估。
为了获得最佳性能,XLNET-LARGE使用序列长度512和批次48进行训练。
结果,重现GPU的最佳结果非常困难。
对于使用一个TPU V3-8的培训,在设置了TPU和Google Storage之后,就可以简单地运行脚本scripts/tpu_squad_large.sh 。
run_squad.py将自动执行阈值搜索,并输出分数。使用scripts/tpu_squad_large.sh ,预期的F1分数应为88.6(我们多次运行的中位数)。
另外,可以将XLNET基本与GPU一起使用(例如三V100)。一组合理的超参数可以在脚本scripts/gpu_squad_base.sh中找到。
读取理解任务竞赛的代码包含在run_race.py中。
运行代码:
(1)从官方网站下载Race数据集,并将原始数据打开到$RACE_DIR 。
(2)进行培训和评估:
script/tpu_race_large_bsz32.sh 。script/tpu_race_large_bsz8.sh )。提供了与GPU一起使用Google Colab的一个示例。请注意,由于该硬件在示例中受到限制,因此结果比我们获得的最佳功能要差。它主要用作示例,应进行相应的修改以最大程度地提高性能。
对于Finetuning,您很可能可以修改现有文件,例如run_classifier.py , run_squad.py和run_race.py ,以适合您的任务。但是,我们还提供了XLNET的抽象,以实现更灵活的用法。以下是一个示例:
import xlnet
# some code omitted here...
# initialize FLAGS
# initialize instances of tf.Tensor, including input_ids, seg_ids, and input_mask
# XLNetConfig contains hyperparameters that are specific to a model checkpoint.
xlnet_config = xlnet . XLNetConfig ( json_path = FLAGS . model_config_path )
# RunConfig contains hyperparameters that could be different between pretraining and finetuning.
run_config = xlnet . create_run_config ( is_training = True , is_finetune = True , FLAGS = FLAGS )
# Construct an XLNet model
xlnet_model = xlnet . XLNetModel (
xlnet_config = xlnet_config ,
run_config = run_config ,
input_ids = input_ids ,
seg_ids = seg_ids ,
input_mask = input_mask )
# Get a summary of the sequence using the last hidden state
summary = xlnet_model . get_pooled_out ( summary_type = "last" )
# Get a sequence output
seq_out = xlnet_model . get_sequence_output ()
# build your applications based on `summary` or `seq_out`以下是在XLNET中进行令牌化的一个示例:
import sentencepiece as spm
from prepro_utils import preprocess_text , encode_ids
# some code omitted here...
# initialize FLAGS
text = "An input text string."
sp_model = spm . SentencePieceProcessor ()
sp_model . Load ( FLAGS . spiece_model_file )
text = preprocess_text ( text , lower = FLAGS . uncased )
ids = encode_ids ( sp_model , text )其中FLAGS.spiece_model_file是与预处理模型相同的zip中的句子模型文件, FLAGS.uncased是指示是否要进行的布尔。
请参阅train.py ,以便在TPU上进行预处理和train_gpu.py进行GPU预处理。首先,我们需要将文本数据预处理到Tfrecords中。
python data_utils.py
--bsz_per_host=32
--num_core_per_host=16
--seq_len=512
--reuse_len=256
--input_glob= * .txt
--save_dir= ${SAVE_DIR}
--num_passes=20
--bi_data=True
--sp_path=spiece.model
--mask_alpha=6
--mask_beta=1
--num_predict=85如果input_glob定义了所有输入文本文件, save_dir是tfrecords的输出目录,而sp_path是句子件模型。这是我们训练句子模型的脚本
spm_train
--input= $INPUT
--model_prefix=sp10m.cased.v3
--vocab_size=32000
--character_coverage=0.99995
--model_type=unigram
--control_symbols= < cls > , < sep > , < pad > , < mask > , < eod >
--user_defined_symbols= < eop > ,.,(,), " ,-,–,£,€
--shuffle_input_sentence
--input_sentence_size=10000000使用特殊符号,包括control_symbols和user_defined_symbols 。我们使用<eop>和<eod>分别表示段落的结尾和文档的结尾。
输入文本文件到data_utils.py必须使用以下格式:
<eop> ,以指示相应的句子结束段落。例如,文本输入文件可能是:
This is the first sentence.
This is the second sentence and also the end of the paragraph.<eop>
Another paragraph.
Another document starts here.
预处理后,我们准备为XLNET预处理。以下是用于预处理Xlnet-large的超参数:
python train.py
--record_info_dir= $DATA /tfrecords
--train_batch_size=2048
--seq_len=512
--reuse_len=256
--mem_len=384
--perm_size=256
--n_layer=24
--d_model=1024
--d_embed=1024
--n_head=16
--d_head=64
--d_inner=4096
--untie_r=True
--mask_alpha=6
--mask_beta=1
--num_predict=85如果我们仅列出最重要的标志和其他标志,则可以根据特定用例进行调整。