首页 > 其他分享 >【预训练语言模型】使用Transformers库进行GPT2预训练

【预训练语言模型】使用Transformers库进行GPT2预训练

时间:2024-03-13 22:35:16浏览次数:22  
标签:... datasets Transformers 训练 tokenizer GPT2 text ids token

基于 HuggingFace的Transformer库,在Colab或Kaggle进行预训练。

本教程提供:英文数据集wikitext-2和代码数据集的预训练。
注:可以自行上传数据集进行训练

目的:跑通自回归语言模型的预训练流程

image

一、准备

1.1 安装依赖

!pip install -U datasets
!pip install accelerate -U

注意:在Colab上训练时,最好将datasets更新到最新版(再重启kernel),避免版本低报错

colab和kaggle已经预安装transformers库

1.2 数据准备

加载数据

from datasets import load_dataset

datasets = load_dataset('wikitext', 'wikitext-2-raw-v1')

当然你也可使用huggingface上任何公开的文本数据集,或使用自己构造的数据,并将路径替换为指定路径:

# datasets = load_dataset("text", data_files={"train": path_to_train.txt, "validation": path_to_validation.txt}

要访问一个数据中实际的元素,您需要先选择一个key,然后给出一个索引:
看一下数据的格式

datasets["train"][10].keys()

可以看到该数据集的每个元素就是一个仅包含文本的字典

dict_keys(['text'])

查看例子

datasets["train"][1]
{‘text': ' =Valkyria Chronicles III = \n'}

训练集和测试集数量

print(len(datasets["train"]), len(datasets["test"]))

36718 4358

通过如下的函数来随机展示数据集中的一些样本:

from datasets import ClassLabel
import random
import pandas as pd
from IPython.display import display, HTML

def show_random_elements(dataset, num_examples=10):
    assert num_examples <= len(dataset), "Can't pick more elements than there are in the dataset."
    picks = []
    for _ in range(num_examples):
        pick = random.randint(0, len(dataset)-1)
        while pick in picks:
            pick = random.randint(0, len(dataset)-1)
        picks.append(pick)
    
    df = pd.DataFrame(dataset[picks])
    for column, typ in dataset.features.items():
        if isinstance(typ, ClassLabel):
            df[column] = df[column].transform(lambda i: typ.names[i])
    display(HTML(df.to_html()))

show_random_elements(datasets["train"])

image

数据集中,一些是空文本或标题,一些文本完整段落,

二、因果语言建模(Causal Language Modeling,CLM)

对于因果语言建模,我们首先拿到数据集中的所有文本,并将它们分词的结果拼接起来。

然后,我们将它们拆分到特定序列长度的训练样本中,这样模型将接收如下所示的连续文本块:

part of text 1

end of text 1 [BOS_TOKEN] beginning of text 2

这取决于训练样本是否跨越数据集中的几个原始文本:

  • 原始文本长于特定序列长度则被切分
  • 原始文本短于特定序列长度则和其他文本拼接。

模型的标签就是将输入右移一个位置(预测下一个token)。

本例中,将使用gpt2模型。

model_checkpoint = "gpt2"
tokenizer_checkpoint = "sgugger/gpt2-like-tokenizer"

当然,你也可以选择这里列出的任何一个https://huggingface.co/models?filter=causal-lm 因果语言模型的checkpoint。

为了用训练模型时使用的词汇对所有文本进行分词,先下载一个预训练过的分词器(Tokenizer)。

直接使用AutoTokenizer类来自加载:

from transformers import AutoTokenizer
    
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint, use_fast=True)

现在可以对所有的文本进行分词。

首先定义一个对文本进行分词的函数

def tokenize_function(examples):
    return tokenizer(examples["text"])

然后,将它用到datasets对象中进行分词,使用batch=True和4个进程来加速预处理,并移除之后用不到的text列。

tokenized_datasets = datasets.map(tokenize_function, batched=True, num_proc=4, remove_columns=["text"])

查看已分词的数据集的样本,文本已转换为input_ids (文本的Token Id序列)和attention_mask:

tokenized_datasets["train"][1]
{'input_ids': [238, 8576, 9441, 2987, 238, 252],
 'attention_mask': [1, 1, 1, 1, 1, 1]}

然后,需要将所有文本分词的结果拼接在一起,并将其分割成特定block_size的小块(第二节开头提到的操作,block_size其实就是Batch后的max_length)。

为此,将再次使用map方法,并使用选项batch=True。设置不同的block_size,可以获得不同数量的样本,从而能改变样本数量。

通过这种方式,可以从一批样本中得到新的一批样本。

首先,需要设置预训练CLM模型时所使用的最大序列长度。在这里设置为256,以防您的显存爆炸

标签:...,datasets,Transformers,训练,tokenizer,GPT2,text,ids,token
From: https://www.cnblogs.com/justLittleStar/p/18071696

相关文章