BART模型是用来预训练seq-to-seq模型的降噪主动编码器(autoencoder)。它是一个序列到序列的模型,具备对损坏文本的双向编码器和一个从左到右的自回归解码器,所以它能够完满的执行翻译工作。

如果你想在翻译工作上测试一个新的体系结构,比方在自定义数据集上训练一个新的标记,那么解决起来会很麻烦,所以在本文中,我将介绍增加新标记的预处理步骤,并介绍如何进行模型微调。

因为Huggingface Hub有很多预训练过的模型,能够很容易地找到预训练标记器。然而咱们要增加一个标记可能就会有些辣手,上面咱们来残缺的介绍如何实现它,首先加载和预处理数据集。

加载数据集

咱们应用WMT16数据集及其罗马尼亚语-英语子集。load_dataset()函数将从Huggingface下载并加载任何可用的数据集。

 importdatasets  dataset=datasets.load_dataset("stas/wmt16-en-ro-pre-processed", cache_dir="./wmt16-en_ro")

在上图1中能够看到数据集内容。咱们须要将其“压平”,这样能够更好的拜访数据,让后将其保留到硬盘中。

 defflatten(batch):     batch['en'] =batch['translation']['en']     batch['ro'] =batch['translation']['ro']          returnbatch  # Map the 'flatten' function train=dataset['train'].map( flatten ) test=dataset['test'].map( flatten ) validation=dataset['validation'].map( flatten )  # Save to disk train.save_to_disk("./dataset/train") test.save_to_disk("./dataset/test") validation.save_to_disk("./dataset/validation")

下图2能够看到,曾经从数据集中删除了“translation”维度。

标记器

标记器提供了训练标记器所需的所有工作。它由四个根本组成部分:(但这四个局部不是所有的都是必要的)

Models:标记器将如何合成每个单词。例如,给定单词“playing”:i) BPE模型将其合成为“play”+“ing”两个标记,ii) WordLevel将其视为一个标记。

Normalizers:须要在文本上产生的一些转换。有一些过滤器能够更改Unicode、小写字母或删除内容。

Pre-Tokenizers:为操作文本提供更大灵活性解决的函数。例如,如何解决数字。数字100应该被认为是“100”还是“1”、“0”、“0”?

Post-Processors:后处理具体情况取决于预训练模型的抉择。例如,将 [BOS](句首)或 [EOS](句尾)标记增加到 BERT 输出。

上面的代码应用BPE模型、小写Normalizers和空白Pre-Tokenizers。而后用默认值初始化训练器对象,次要包含

1、词汇量大小应用50265以与BART的英语标记器统一

2、非凡标记,如<s>和<pad>,

3、初始词汇量,这是每个模型启动过程的预约义列表。

 fromtokenizersimportnormalizers, pre_tokenizers, Tokenizer, models, trainers  # Build a tokenizer bpe_tokenizer=Tokenizer(models.BPE()) bpe_tokenizer.normalizer=normalizers.Lowercase() bpe_tokenizer.pre_tokenizer=pre_tokenizers.Whitespace()  trainer=trainers.BpeTrainer(     vocab_size=50265,     special_tokens=["<s>", "<pad>", "</s>", "<unk>", "<mask>"],     initial_alphabet=pre_tokenizers.ByteLevel.alphabet(), )

应用Huggingface的最初一步是连贯Trainer和BPE模型,并传递数据集。依据数据的起源,能够应用不同的训练函数。咱们将应用train_from_iterator()。

 defbatch_iterator():     batch_length=1000     foriinrange(0, len(train), batch_length):         yieldtrain[i : i+batch_length]["ro"]          bpe_tokenizer.train_from_iterator( batch_iterator(), length=len(train), trainer=trainer )  bpe_tokenizer.save("./ro_tokenizer.json") 

BART微调

当初能够应用应用新的标记器了。

 fromtransformersimportAutoTokenizer, PreTrainedTokenizerFast  en_tokenizer=AutoTokenizer.from_pretrained( "facebook/bart-base" ); ro_tokenizer=PreTrainedTokenizerFast.from_pretrained( "./ro_tokenizer.json" ); ro_tokenizer.pad_token=en_tokenizer.pad_token  deftokenize_dataset(sample):     input=en_tokenizer(sample['en'], padding='max_length', max_length=120, truncation=True)     label=ro_tokenizer(sample['ro'], padding='max_length', max_length=120, truncation=True)      input["decoder_input_ids"] =label["input_ids"]     input["decoder_attention_mask"] =label["attention_mask"]     input["labels"] =label["input_ids"]      returninput  train_tokenized=train.map(tokenize_dataset, batched=True) test_tokenized=test.map(tokenize_dataset, batched=True) validation_tokenized=validation.map(tokenize_dataset, batched=True)

下面代码的第5行,为罗马尼亚语的标记器设置填充标记是十分必要的。因为它将在第9行应用,标记器应用填充能够使所有输出都具备雷同的大小。

上面就是训练的过程:

 fromtransformersimportBartForConditionalGeneration fromtransformersimportSeq2SeqTrainingArguments, Seq2SeqTrainer  model=BartForConditionalGeneration.from_pretrained(  "facebook/bart-base" )  training_args=Seq2SeqTrainingArguments(     output_dir="./",     evaluation_strategy="steps",     per_device_train_batch_size=2,     per_device_eval_batch_size=2,     predict_with_generate=True,     logging_steps=2,  # set to 1000 for full training     save_steps=64,  # set to 500 for full training     eval_steps=64,  # set to 8000 for full training     warmup_steps=1,  # set to 2000 for full training     max_steps=128, # delete for full training     overwrite_output_dir=True,     save_total_limit=3,     fp16=False, # True if GPU )  trainer=Seq2SeqTrainer(     model=model,     args=training_args,     train_dataset=train_tokenized,     eval_dataset=validation_tokenized, )  trainer.train()

过程也非常简单,加载bart根底模型(第4行),设置训练参数(第6行),应用Trainer对象绑定所有内容(第22行),并启动流程(第29行)。上述超参数都是测试目标,所以如果要失去最好的后果还须要进行超参数的设置,咱们应用这些参数是能够运行的。

推理

推理过程也很简略,加载通过微调的模型并应用generate()办法进行转换就能够了,然而须要留神的是对源 (En) 和指标 (RO) 序列应用适当的分词器。

总结

尽管在应用自然语言解决(NLP)时,标记化仿佛是一个基本操作,但它是一个不应漠视的关键步骤。HuggingFace的呈现能够不便的让咱们应用,这使得咱们很容易遗记标记化的基本原理,而仅仅依赖事后训练好的模型。然而当咱们心愿本人训练新模型时,理解标记化过程及其对上游工作的影响是必不可少的,所以相熟和把握这个根本的操作是十分有必要的。

本文代码:https://avoid.overfit.cn/post/6a533780b5d842a28245c81bf46fac63

作者:Ala Alam Falaki