关于深度学习:Huggingface微调BART的代码示例WMT16数据集训练新的标记进行翻译

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理