在本文中,将深入探讨OpenAI研究人员提出的一个框架,该框架通过生成式预训练和判别式微调,使得单一任务不可知模型能够实现强大的自然语言理解(NLU)。这项开创性的工作彻底改变了当今语言模型的开发方式。此外,还将使用这个模型(GPT-1)来生成文本。
提出了一种在多样化未标记文本语料库上进行语言模型的生成式预训练,然后对每个特定任务进行判别式微调的方法(通过提供特定下游任务的例子,如分类、情感分析、文本蕴含等),从而获得了巨大的提升。在微调期间使用任务感知的输入转换,以实现高效的迁移,同时对模型架构的改动最小。这种通用的任务不可知模型比使用为每个任务特别定制的架构的判别式训练模型表现得更好,在考察的12个任务中有9个任务显著提高了最新技术水平。在测试中,常识推理(Stories Cloze Test)上绝对提升了8.9%,文本蕴含(MultiNLI)上提升了1.5%,问答(RACE)上提升了5.7%。
在GPT开发之前,大多数最新技术水平的自然语言处理(NLP)模型都是针对特定任务(如问答、文本蕴含、语义相似度评估、文档分类等)使用监督学习进行训练的。然而,监督模型有两个主要限制:一是标记数据的稀缺性,二是泛化能力差。
鉴于此,提出了在多样化未标记文本语料库上进行语言模型的生成式预训练,然后对每个特定下游任务进行判别式微调的方法,从而获得了巨大的提升。
GPT-1使用了一个12层的仅解码器变换框架,并通过掩码自注意力进行训练。GPT模型的架构在很大程度上保持了原始变换工作时的状态。通过掩码,实现了语言模型目标,即模型无法访问当前词右侧的后续词。GPT-1语言模型使用BooksCorpus数据集进行训练,该数据集包含了大约7000本未出版的书籍,这有助于在未见数据上训练语言模型。
这个语料库还包含了长段连续文本,这有助于模型处理长距离依赖关系。现在让看看GPT-1模型使用的训练方法。
训练GPT模型包括以下三个阶段:i) 在大量文本语料库上学习高容量语言模型(预训练),ii) 微调,即用标记数据适应模型到判别任务,iii) 对于某些任务(如问答或文本蕴含)需要特定任务的输入转换,这些任务有结构化输入,如文档的三元组、有序句子对、问题和答案。
// 使用无监督语料库的标记U = {u1, ..., un},使用标准语言建模目标来最大化以下可能性:
// 其中i) k是上下文窗口的大小,ii) 条件概率P是使用神经网络(NN)和参数Θ来建模的。
II) 监督微调:在模型用上述目标训练后,即最大化可能性后,参数被适应到监督目标任务。使用标记数据集C,其中每个实例由输入标记序列x1, ..., xm和标签y组成。然后输入通过预训练模型传递,得到最终变换块的激活hl m,然后注入到额外的线性输出层参数Wy来估计y:
// 然后目标是最大化以下可能性:
// 为了提高泛化能力并实现更快的收敛,不仅仅是最大化L2,
// 而是优化以下目标:
本质上,通过在变换模型上添加线性和softmax层,实现了监督微调,以获得下游任务的任务标签。
如上所述,可以直接对文本分类等任务进行微调。然而,像文本蕴含、问答等任务需要特定任务的定制。为了在微调期间对模型架构进行最小的调整,特定下游任务的输入被转换为有序序列。标记被重新排列如下:在输入序列中添加开始和结束标记。在示例的不同部分之间添加分隔符标记,将输入作为有序序列传递。对于问答(QA)、多项选择题(MCQ)等任务,每个示例发送多个序列。
这种通用的任务不可知模型比使用为每个任务特别定制的架构的判别式训练模型表现得更好,在考察的12个任务中有9个任务显著提高了最新技术水平。在测试中,常识推理(Stories Cloze Test)上绝对提升了8.9%,文本蕴含(MultiNLI)上提升了1.5%,问答(RACE)上提升了5.7%。
GPT-1在各种NLP任务上具有不错的零样本性能,如问答、模式解析、情感分析等。
通常,该模型的预测可能包含针对受保护类别、身份特征和敏感的社会、职业及人口统计群体的攻击性和有害的刻板印象。GPT-1模型通过书籍和互联网上容易获得的文本获取关于世界的知识,这些知识并不包含关于世界的完整或甚至准确的信息。
尽管GPT-1在各种任务上表现良好,但在对抗性、系统性或分布外的评估中,它表现出令人惊讶和违反直觉的行为。此外,它还表现出脆弱的泛化能力。GPT-1需要昂贵的预训练步骤,即在8个GPU上需要1个月的时间!
为此,将直接使用Hugging Face hub中的“openai-gpt”模型,并使用“text-generation”管道。首先,将安装transformers库并导入pipeline和set_seed。由于GPT的文本生成依赖于一些随机性,因此为了可重复性,设置了种子。
// 安装transformers库并导入pipeline和set_seed
!pip install -q transformers
from transformers import pipeline, set_seed
model_name = "openai-gpt"
generator = pipeline(
'text-generation'
, model=model_name)
set_seed(42)
generator(“Hi, I’m a transformer-based language model,”, max_length=30, num_return_sequences=5)