本文参考资料是Hugging Face主页Resources下的课程,节选部分内容并注释(加粗斜体),也加了Trainer和args的主要参数介绍。感兴趣的同学可以去查看原文。
本章节主要内容包含两部分内容:
- pipeline工具演示NLP任务处理
- 构建Trainer微调模型
目录
1. 简介
本章节将使用 Hugging Face 生态系统中的库——🤗 Transformers来进行自然语言处理工作(NLP)。
Transformers的历史
以下是 Transformer 模型(简短)历史中的一些参考点:
Transformer 架构于 2017 年 6 月推出。原始研究的重点是翻译任务。随后推出了几个有影响力的模型,包括:
- 2018 年 6 月:GPT,第一个预训练的 Transformer 模型,用于各种 NLP 任务的微调并获得最先进的结果
- 2018 年 10 月:BERT,另一个大型预训练模型,该模型旨在生成更好的句子摘要(下一章将详细介绍!)
- 2019 年 2 月:GPT-2,GPT 的改进(和更大)版本,由于道德问题未立即公开发布
- 2019 年 10 月:DistilBERT,BERT 的蒸馏版本,速度提高 60%,内存减轻 40%,但仍保留 BERT 97% 的性能
- 2019 年 10 月:BART 和 T5,两个使用与原始 Transformer 模型相同架构的大型预训练模型(第一个这样做)
- 2020 年 5 月,GPT-3,GPT-2 的更大版本,无需微调即可在各种任务上表现良好(称为零样本学习zero-shot learning)
这个列表并不全,只是为了突出一些不同类型的 Transformer 模型。大体上,它们可以分为三类:
- GPT类(只使用transformer-decoder部分,自回归 Transformer 模型)
- BERT类(只使用transformer-encoder部分,自编码 Transformer 模型)
- BART/T5 类(Transformer-encoder-decoder模型)
Architectures和checkpoints
对Transformer模型的研究中,会出现一些术语:架构Architecture和检查点checkpoint以及Model。 这些术语的含义略有不同:
Architecture:定义了模型的基本结构和基本运算
checkpoint:模型的某个训练状态,加载此checkpoint会加载此时的权重。(训练时可以选择自动保存checkpoint)
Model:这是一个总称,不像“架构”或“检查点”那样精确,它可以同时表示两者。 当需要减少歧义时,本课程将指定架构或检查点。
例如,BERT 是一种 Architectures,而 bert-base-cased(谷歌团队为 BERT 的第一个版本训练的一组权重)是一个checkpoints。 但是,可以说“the BERT model”和“the bert-base-cased model”。
checkpoint概念在大数据里面说的比较多。模型在训练时可以设置自动保存于某个时间点(比如模型训练了一轮epoch,更新了参数,将这个状态的模型保存下来,为一个checkpoint。)
所以每个checkpoint对应模型的一个状态,一组权重。大数据中检查点是一个数据库事件,存在的根本意义是减少崩溃时间。即减少因为意外情况数据库崩溃后重新恢复的时间。
The Inference API
Model Hub(模型中心)包含多语言模型的checkpoints。您可以通过单击语言标签来优化对模型的搜索,然后选择生成另一种语言文本的模型。
通过单击选择模型后,您会看到有一个小部件——Inference API(支持在线试用)。即您可以直接在此页面上使用各种模型,通过输入自定义文本就可以看到模型处理输入数据后的结果。 通过这种方式,您可以在下载模型之前快速测试模型的功能。
2. 用pipeline处理NLP问题
在本节中,我们将看看 Transformer 模型可以做什么,并使用 🤗 Transformers 库中的第一个工具:管道pipeline。
🤗 Transformers 库提供了创建和使用共享模型的功能.。Model Hub包含数千个所有人都可以下载和使用的预训练模型。 您也可以将自己的模型上传到 Hub!
🤗 Transformers 库中最基本的对象是pipeline。 它将模型与其必要的预处理和后处理步骤连接起来,使我们能够直接输入任何文本并获得可理解的答案:
from transformers import pipeline
classifier = pipeline("sentiment-analysis")
classifier("I've been waiting for a HuggingFace course my whole life.")
[{
'label': 'POSITIVE', 'score': 0.9598047137260437}]
我们甚至可以传入几个句子!
classifier([
"I've been waiting for a HuggingFace course my whole life.",
"I hate this so much!"
])
[{
'label': 'POSITIVE', 'score': 0.9598047137260437},
{
'label': 'NEGATIVE', 'score': 0.9994558095932007}]
默认情况下,此管道选择一个特定的预训练模型,该模型已针对英语情感分析进行了微调。 创建分类器对象时,将下载并缓存模型。 如果您重新运行该命令,则将使用缓存的模型,无需再次下载模型。
将一些文本传递到管道时涉及三个主要步骤:
- 预处理:文本被预处理为模型可以理解的格式。
- 输入模型:构建模型,并将预处理的输入传递给模型。
- 后处理:模型的预测是经过后处理的,因此您可以理解它们。
目前可用的一些管道是:
- feature-extraction (获取文本的向量表示)
- fill-mask填充给定文本中的空白(完形填空)
- ner (named entity recognition)词性标注
- question-answering问答
- sentiment-analysis情感分析
- summarization摘要生成
- text-generation文本生成
- translation翻译
- zero-shot-classification零样本分类
您也可以从 Hub 中针对特定任务来选择特定模型的管道 例如,文本生成。转到 Model Hub并单击左侧的相应标签,页面将会仅显示文本生成任务支持的模型。
(除了模型要匹配任务,更进一步考虑的因素之一是:预训练模型训练时使用的数据集,要尽可能的接近你需要处理的任务所包含的数据集,两个数据集越接近越好。)
Transformers pipeline API 可以处理不同的 NLP 任务。您可以使用完整架构,也可以仅使用编码器或解码器,具体取决于您要解决的任务类型。 下表总结了这一点:
模型 | 例子 | 任务 |
---|---|---|
Encoder | ALBERT, BERT, DistilBERT, ELECTRA, RoBERTa | 句子分类、命名实体识别、抽取式问答 |
Decoder | CTRL, GPT, GPT-2, Transformer XL | 文本生成 |
Encoder-decoder | BART, T5, Marian, mBART | 摘要生成、翻译、生成式问答 |
以上显示的pipeline主要用于演示目的。 它们是为特定任务编程的,不能执行它们的变体。 在下一节中,您将了解管道内部的内容以及如何自定义其行为。
上面这几种管道的简单示例可以查看——Hugging Face主页课程第一篇《Transformer models》。
或单击Open in Colab以打开包含其它管道应用代码示例的 Google Colab 笔记本。
如果您想在本地运行示例,我们建议您查看设置。
3. Behind the pipeline
本节代码:Open in Colab (PyTorch)
YouTube视频:what happend inside the pipeline function
让我们从一个完整的例子开始,看看当我们在第1节中执行以下代码时,幕后发生了什么:
from transformers import pipeline
classifier = pipeline("sentiment-analysis")
classifier([
"I've been waiting for a HuggingFace course my whole life.",
"I hate this so much!",
])
[{
'label': 'POSITIVE', 'score': 0.9598047137260437},
{
'label': 'NEGATIVE', 'score': 0.9994558095932007}]
正如我们在第 1 章中看到的,这个管道将三个步骤组合在一起:预处理、通过模型传递输入和后处理:
让我们快速浏览一下这些内容。
tokenizer预处理
与其他神经网络一样,Transformer 模型不能直接处理原始文本,因此我们管道的第一步是将文本输入转换为模型可以理解的数字。为此,我们使用了一个分词器tokenizer,它将负责:
- 将输入拆分为称为标记的单词、子词subword或符号symbols(如标点符号)
- 将每个标记映射到一个整数
- 添加可能对模型有用的其他输入
使用 AutoTokenizer 类及其 from_pretrained 方法,以保证所有这些预处理都以与模型预训练时完全相同的方式完成。设定模型的 checkpoint名称,它会自动获取与模型的Tokenizer关联的数据并缓存它(所以它只在你第一次运行下面的代码时下载)。
由于情感分析管道的默认检查点是 distilbert-base-uncased-finetuned-sst-2-english,我们可以运行以下命令得到我们需要的tokenizer:
from transformers import AutoTokenizer
checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
raw_inputs = [
"I've been waiting for a HuggingFace course my whole life.",
"I hate this so much!",
]
inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
#return_tensors="pt"表示返回Pytorch张量。文本转换为数字之后必须再转换成张量tensors才能输入模型。
#padding=True表示填充输入序列到最大长度,truncation=True表示过长序列被截断
print(inputs)
以下是 PyTorch 张量的结果:
{
'input_ids': tensor([
[ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102],
[ 101, 1045, 5223, 2023, 2061, 2172, 999, 102, 0, 0, 0,