GPT-1简介
GPT-1(Generative Pre-trained Transformer)是2018年由Open AI提出的一个结合预训练和微调的用于办理文本明确和文本生成任务的模型。它的底子是Transformer架构,具有如下创新点:
- NLP范畴的迁移学习:通过最少的任务专项数据,利用预训练模型出色地完成具体的下游任务。
- 语言建模作为预训练任务:使用无监视学习和大规模的文本语料库来训练模型
- 为具体任务微调:采用预训练模型来适应监视任务
和BERT雷同,GPT-1同样采取pre-train + fine-tune的思路:先基于大量未标注语料数据进行预训练, 后基于少量标注数据进行微调。但GPT-1在预训练任务思路和模型结构上与BERT有所差别。
GPT-1的目的是在预训练的过程中根据现有的全部词元,预测下一个词元。这个任务被称为“自回归语言建模”。
一个简单的例子:
输入序列为:“The sun rises in the”
训练数据的原句子为:“The sun rises in the east”
所以我们的目的输出为:“east”
将输入序列输入GPT模型,GPT根据输入预测下一个词元(“east”)在语料库中的概率分布
准确词元“east”作为一个“伪标签”来帮助模型训练
模型架构
GPT主要使用Transformer Decoder架构,但由于没有Encoder,所以在Transformer Decoder的底子上移除了盘算Encoder与Decoder间注意力分数的Multi-Head Attention Layer。
Masked Multi-HeadSelf-Attention
Masked Multi-Head Self-Attention 是Multi-Head Attetion的变种。 最大的不同来自于MMSA的掩码机制,掩码机制防止模型通过观测未来的词元以进行“作弊”。
一个掩码词元<mask>被用于注意力分数矩阵,所以当前词元只能注意到序列中自己和自己之前的词元。未来的次元的注意力分数将被设为0以确保其在Softmax步骤后的实际贡献为0。
为什么掩码机制非常告急?
对于自回归任务,模型必须线性地生成词元,不能基于未来的信息预测下一个词元。
损失函数
GPT使用Cross-Entropy Loss作为损失函数:
交叉熵损失是这项任务的抱负选择,由于它通过丈量预测的概率分布与真实分布的距离来惩罚不准确的预测。它自然适于处置惩罚多类分类任务,此中模型从大量词汇表中选择一个标志。
模型输入
GPT-1的输入同样为句子或句子对,并添加Special Tokens。
- [BOS]:表现句子的开始,(论文中给出的token表现为[START]),添加到序列最前;
- [EOS]:表现序列的结束,(论文中的给出的[EXTRACT]),添加到序列末了,在进行分类任务时,会将 该special token对应的输出接入输出层;我们也可以明确为该token可以学习到整个句子的语义信息;
- [SEP]:用于隔断句子对中的两个句子;
GPT Embedding 同样分为三类:token Embedding、Position Embedding、Segment Embedding
GPT-1模型具体参数
模型架构
- 12个Transformer Decoder Block
- hidden_size为768(模型输入和输出的向量纬度)
- 注意力头数为12
- FFN维度为3072
- 词表(Vocab)大小为40000
- 序列长度为512(上下文窗口长度)
训练过程
- Adam优化器,超参数为:0.9, 0.99
- 学习率:最大学习率:2.5x10e-4 使用2000步作为热身,随后线性衰退
- 批大小:64
- 梯度剪裁:1.0
- Dropout率:0.1
训练过程
100000步,约莫花费8张NVIDIA V100 GPU训练30天,共有117M参数。使用Xavier初始化,权重衰退为0.01。
下游任务
GPT按照生成式的逻辑统一了下游任务的应用模板,使用末了一个token([EOS]or[EXTRACT])对应的hidden state,输出到额外的输出层中,进行分类标签预测。 任务包罗:文天职类(情感分类、新闻分类)、文本蕴含(根据条件推出假设)、文本语义相似度、多类选择(在多个next token中进行选择) 基于MindSpore微调GPT-1进行情感分类
- # #安装mindnlp 0.4.0套件
- # !pip install mindnlp
- # !pip uninstall soundfile -y
- # !pip install download
- # !pip install jieba
- # !pip install https://ms-release.obs.cn-north-4.myhuaweicloud.com/2.3.1/MindSpore/unified/aarch64/mindspore-2.3.1-cp39-cp39-linux_aarch64.whl --trusted-host ms-release.obs.cn-north-4.myhuaweicloud.com -i https://pypi.tuna.tsinghua.edu.cn/simple
- import os
- import mindspore
- from mindspore.dataset import text, GeneratorDataset, transforms
- from mindspore import nn
- from mindnlp.dataset import load_dataset
- from mindnlp.engine import Trainer
- # loading dataset
- imdb_ds = load_dataset('imdb', split=['train', 'test'])
- imdb_train = imdb_ds['train']
- imdb_test = imdb_ds['test']
- imdb_train.get_dataset_size()
- import numpy as np
- def process_dataset(dataset, tokenizer, max_seq_len=512, batch_size=4, shuffle=False):
- is_ascend = mindspore.get_context('device_target') == 'Ascend'
- def tokenize(text):
- if is_ascend:
- tokenized = tokenizer(text, padding='max_length', truncation=True, max_length=max_seq_len)
- else:
- tokenized = tokenizer(text, truncation=True, max_length=max_seq_len)
- return tokenized['input_ids'], tokenized['attention_mask']
- if shuffle:
- dataset = dataset.shuffle(batch_size)
- # map dataset
- dataset = dataset.map(operations=[tokenize], input_columns="text", output_columns=['input_ids', 'attention_mask'])
- dataset = dataset.map(operations=transforms.TypeCast(mindspore.int32), input_columns="label", output_columns="labels")
- # batch dataset
- if is_ascend:
- dataset = dataset.batch(batch_size)
- else:
- dataset = dataset.padded_batch(batch_size, pad_info={'input_ids': (None, tokenizer.pad_token_id),
- 'attention_mask': (None, 0)})
- return dataset
- from mindnlp.transformers import OpenAIGPTTokenizer
- # tokenizer
- gpt_tokenizer = OpenAIGPTTokenizer.from_pretrained('openai-gpt')
- # add sepcial token: <PAD>
- special_tokens_dict = {
- "bos_token": "<bos>",
- "eos_token": "<eos>",
- "pad_token": "<pad>",
- }
- num_added_toks = gpt_tokenizer.add_special_tokens(special_tokens_dict)
- #为方便体验流程,把原本数据集的十分之一拿出来体验训练和评估,
- imdb_train, _ = imdb_train.split([0.1, 0.9], randomize=False)
- # split train dataset into train and valid datasets
- imdb_train, imdb_val = imdb_train.split([0.7, 0.3])
- dataset_train = process_dataset(imdb_train, gpt_tokenizer, shuffle=True)
- dataset_val = process_dataset(imdb_val, gpt_tokenizer)
- dataset_test = process_dataset(imdb_test, gpt_tokenizer)
- # load GPT sequence classification model and set class=2
- from mindnlp.transformers import OpenAIGPTForSequenceClassification # Import the GPT model for sequence classification
- from mindnlp import evaluate # Import the evaluation module from MindNLP
- import numpy as np # Import NumPy for numerical operations
- # Set up the GPT model for sequence classification with 2 output labels (binary classification).
- model = OpenAIGPTForSequenceClassification.from_pretrained('openai-gpt', num_labels=2)
- # Set the padding token ID in the model configuration to match the tokenizer's padding token ID.
- model.config.pad_token_id = gpt_tokenizer.pad_token_id
- # Resize the token embedding layer to account for any added tokens (e.g., special tokens).
- model.resize_token_embeddings(model.config.vocab_size + 3)
- from mindnlp.engine import TrainingArguments # Import training arguments for model training configuration.
- # Define training arguments.
- training_args = TrainingArguments(
- output_dir="gpt_imdb_finetune", # Directory to save model checkpoints and outputs.
- evaluation_strategy="epoch", # Evaluate the model at the end of each epoch.
- save_strategy="epoch", # Save model checkpoints at the end of each epoch.
- logging_strategy="epoch", # Log metrics and progress at the end of each epoch.
- load_best_model_at_end=True, # Automatically load the best model (based on evaluation metrics) at the end of training.
- num_train_epochs=1.0, # Number of training epochs (default is 1 for quick experimentation).
- learning_rate=2e-5 # Learning rate for the optimizer.
- )
- # Load the accuracy metric for evaluation.
- metric = evaluate.load("accuracy")
- # Define a function to compute metrics during evaluation.
- def compute_metrics(eval_pred):
- logits, labels = eval_pred # Unpack predictions (logits) and true labels.
- predictions = np.argmax(logits, axis=-1) # Convert logits to class predictions using argmax.
- return metric.compute(predictions=predictions, references=labels) # Compute accuracy metric.
- # Initialize the Trainer class with the model, training arguments, datasets, and metric computation function.
- trainer = Trainer(
- model=model, # The GPT model to be fine-tuned.
- args=training_args, # Training configuration arguments.
- train_dataset=dataset_train, # Training dataset (must be preprocessed and tokenized).
- eval_dataset=dataset_val, # Validation dataset for evaluation.
- compute_metrics=compute_metrics # Metric computation function for evaluation.
- )
- # start training
- trainer.train()
- trainer.evaluate(dataset_test)
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |