如何使用Transformers和Tokenizers从头开始训练新的语言模型

huggingface教程翻译,原文博客地址cloab地址

前言

在过去的几个月,我们对transformers库和 tokenizers库进行了一些改进,目标是使得从头开始训练新的语言模型变得容易。

在这个demo里,展示了怎么在Esperanto训练一个"small"模型((84 M parameters = 6 layers, 768 hidden size, 12 attention heads)) ,这是和DistilBERT有相同的层和头的数量。然后在下游的词性标注任务进行微调。

1. 下载数据集

首先,在Esperanto上找到数据集文本。这里,我们使用来自INRIA.OSCAR的OSCAR语料库的Esperanto部分,它是一个庞大的多语言语料库,它是通过对网络上Common Crawl转储进行语言分类和过滤得到的。
在这里插入图片描述

在数据集的Esperanto部分仅有299M,因此我们将会拼接Leipzig Corpora Collection的Esperanto子语料库,它来自不同的文本,包括(新闻, 文学,维基百科)组成。

最后训练的语料库有3GB,对于你的模型,它仍然是小的,获得的语料越多,预训练效果越好

# in this notebook we'll only get one of the files (the Oscar one) for the sake of simplicity and performance
!wget -c https://cdn-datasets.huggingface.co/EsperBERTo/data/oscar.eo.txt

2.训练一个分词器(tokenizer)

我们选择来训练一个byte-level的字节对编码分词器(像GPT-2),和RoBERTa一样的特殊tokens。我们任意取它的大小为52000。

我们推荐训练byte-level水平的BPE(而不是像BERT的WordPiece tokenizer),因为它将从单个字节的字母表开始构建词汇表,因此,所有的单词都会被分解(不再有标记!)

# We won't need TensorFlow here
!pip uninstall -y tensorflow
# Install `transformers` from master
!pip install git+https://github.com/huggingface/transformers
!pip list | grep -E 'transformers|tokenizers'
# transformers version at notebook update --- 2.11.0
# tokenizers version at notebook update --- 0.8.0rc1
%%time 
from pathlib import Path

from tokenizers import ByteLevelBPETokenizer

paths = [str(x) for x in Path(".").glob("**/*.txt")]

# Initialize a tokenizer
tokenizer = ByteLevelBPETokenizer()

# Customize training
tokenizer.train(files=paths, vocab_size=52_000, min_frequency=2, special_tokens=[
    "<s>",
    "<pad>",
    "</s>",
    "<unk>",
    "<mask>",
])

保存文件到磁盘

!mkdir EsperBERTo
tokenizer.save_model("EsperBERTo")

现在有一个vocab.json文件,它是一个按照字符频率排序的列表,还有一个merges.txt的合并文件

{
    "<s>": 0,
    "<pad>": 1,
    "</s>": 2,
    "<unk>": 3,
    "<mask>": 4,
    "!": 5,
    "\"": 6,
    "#": 7,
    "$": 8,
    "%": 9,
    "&": 10,
    "'": 11,
    "(": 12,
    ")": 13,
    # ...
}
 
# merges.txt
l a
Ġ k
o n
Ġ la
t a
Ġ e
Ġ d
Ġ p
# ...

我们的tokenizer是根据Esperanto优化的。相比与普通的基于英语的tokenizer,拥有更多的本地单词由一个单独的、未拆分的token表示。例如:在Esperanto中的单词——ĉ、ĝ、ĥ、ĵ、ŝ和ŭ——都是本地编码的。我们还用一种跟有效的方式表示序列。在这个语料库中,编码序列的平均长度比使用预训练的GPT-2标记器时小约30%。

下面是如何在tokenizers中使用它,包括处理RoBERTa中的特殊tokens–当然,你也可以在transformer中使用它。

from tokenizers.implementations import ByteLevelBPETokenizer
from tokenizers.processors import BertProcessing


tokenizer = ByteLevelBPETokenizer(
    "./EsperBERTo/vocab.json",
    "./EsperBERTo/merges.txt",
)
tokenizer._tokenizer.post_processor = BertProcessing(
    ("</s>", tokenizer.token_to_id("</s>")),
    ("<s>", tokenizer.token_to_id("<s>")),
)
tokenizer.enable_truncation(max_length=512)
tokenizer.encode("Mi estas Julien.")
tokenizer.encode("Mi estas Julien.").tokens

3. 从零开始训练语言模型

更新:本节遵循run_language_modeling.py脚本,使用新的Trainer。你可以任意挑选你最喜欢的方法。

我们将会训练一个类似RoBERTa的模型,它是一个类似bert的模型但是又有一些改进(详细信息可以看文档)

因为是类似bert的模型,我们训练这个任务在Masked language modeling,例如,预测如何填充我们在数据集中随机屏蔽的任意标记。这是由示例脚本处理的。

# Check that we have a GPU
!nvidia-smi
# Check that PyTorch sees it
import torch
torch.cuda.is_available()

定义这个模型的配置文件

from transformers import RobertaConfig

config = RobertaConfig(
    vocab_size=52_000,
    max_position_embeddings=514,
    num_attention_heads=12,
    num_hidden_layers=6,
    type_vocab_size=1,
)

现在在teansformers中重新创建tokenizer

from transformers import RobertaTokenizerFast

tokenizer = RobertaTokenizerFast.from_pretrained("./EsperBERTo", max_len=512)

最后,我们来初始化模型

重要的是:

当我们从头开始训练时,我们只从配置进行初始化,而不是从现有的预先训练过的模型或检查点。

from transformers import RobertaForMaskedLM

model = RobertaForMaskedLM(config=config)
model.num_parameters()
# => 84 million parameters

建立训练数据集

我们通过应用我们的tokenizer到文本文件来建立我们的数据集。

在这里,因为我们只有一个文本文件,我们甚至不需要自定义我们的Dataset。 我们将使用LineByLineDataset

%%time
from transformers import LineByLineTextDataset

dataset = LineByLineTextDataset(
    tokenizer=tokenizer,
    file_path="./oscar.eo.txt",
    block_size=128,
)

run_language_modeling.py脚本中描述的一样,我们需要定义一个 data_collator

这是一个小助手,这将帮助我们将数据集的不同样本批处理到一个Pytorch知道如何执行的backprop中.

from transformers import DataCollatorForLanguageModeling

data_collator = DataCollatorForLanguageModeling(
    tokenizer=tokenizer, mlm=True, mlm_probability=0.15
)

最后,我们将设置Trainer的初始值

from transformers import Trainer, TrainingArguments

training_args = TrainingArguments(
    output_dir="./EsperBERTo",
    overwrite_output_dir=True,
    num_train_epochs=1,
    per_gpu_train_batch_size=64,
    save_steps=10_000,
    save_total_limit=2,
)

trainer = Trainer(
    model=model,
    args=training_args,
    data_collator=data_collator,
    train_dataset=dataset,
    prediction_loss_only=True,
)

开始训练

%%time
trainer.train()

保存最终的模型(+ tokenizer + config)到磁盘

trainer.save_model("./EsperBERTo")

检查LM是否受过训练

除了查看训练和评估的loss外,检查我们的语言模型是否学习了任何有趣的东西最简单的方法就是通过FillMaskPipeline.

管道是标记器和模型的简单包装器,而“fill-mask”可以让您输入一个包含屏蔽标记的序列(这里是),并返回最可能被填充的序列及其概率的列表。

from transformers import pipeline

fill_mask = pipeline(
    "fill-mask",
    model="./EsperBERTo",
    tokenizer="./EsperBERTo"
)
# The sun <mask>.
# =>

fill_mask("La suno <mask>.")

好的,简单的语法可以工作。 让我们尝试一个更有趣的提示:

fill_mask("Jen la komenco de bela <mask>.")

# This is the beginning of a beautiful <mask>.
# =>

总结

最后的上传模型可以直接参考原文

  • 5
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
使用Transformers库自己训练一个模型,您需要进行以下步骤: 1. 准备数据:准备您的训练数据集,并将其整理为适合模型输入的格式。这可能涉及到数据清洗、分词、标记化等预处理操作。 2. 加载预训练模型:选择适合您任务的预训练模型,并使用`from_pretrained()`方法加载模型。您可以选择不同的模型架构(如BERT、GPT、RoBERTa等)和模型大小(如base、large等)。 3. 创建模型:根据您的任务类型,使用训练模型构建一个适当的分类器、生成器或序列标注器等。您可以根据需要微调预训练模型的不同层。 4. 准备训练器:选择合适的优化器和损失函数,并设置训练时的超参数,如学习率、批量大小、训练迭代次数等。 5. 训练模型使用准备好的数据集和训练器进行模型训练。在每个训练迭代中,将数据输入模型,计算损失并进行反向传播更模型参数。 6. 评估模型:在训练过程中或训练结束后,使用验证集或测试集评估模型的性能。这可以包括计算准确率、精确度、召回率、F1分数等指标。 7. 保存模型:在训练结束后,保存训练好的模型以便后续使用使用`save_pretrained()`方法将模型保存到磁盘上。 这是一个基本的训练流程示例。具体的实现可能因任务类型、数据集和需求而有所不同。Transformers库提供了丰富的功能和示例代码,可以帮助您更轻松地进行模型训练。 如果您需要更详细的代码示例或有特定的问题,请告诉我,我将尽力提供帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值