如何使用W&B微调HuggingFace Tranformer?
🤗 导言
在此报告中,我们将快速浏览HuggingFace Transformers库的功能。该库提供了很多好用的API,可用于下载、训练和推断用于自然语言理解(NLU)和自然语言生成(NLG)任务的最新的预训练模型。其中包括情感分析、问题解答、文本摘要等。在此处获得HuggingFace支持的常见NLP任务汇总。
我们将对IMDB数据集上用于情感分析(二元分类)的DistilBERT transformer
进行微调。如果您感兴趣,请查看链接的Colab笔记本。
⏳ 安装和导入
对于本教程,我们将需要HuggingFace(很明显!)以及Weights and Biases。
# Install HuggingFace
!pip install transformers -q
我们将很快查看与HuggingFace相关的导入及其含义。
我们将使用Weights and Biases自动记录损失、评估指标、模型拓扑和梯度(仅适用于Trainer
)。要使用Weights and Biases,
# Install Weights and Biases
!pip install wandb -q
# Import wandb
import wandb
# Login with your authentication key
wandb.login()
# setup wandb environment variables
%env WANDB_ENTITY=your-username/your-team-name
%env WANDB_PROJECT=your-project-name
现在我们已经准备好了所需的安装,让我们来看看,在任何任务的任何数据集上,微调HuggingFace Transformer是多么容易。
🔧 使用🤗轻松进行数据预处理
在本节中,我们将看到对数据进行预处理以进行训练或推理有多么容易。用于此目的的主要工具是tokenizer,它负责为模型准备输入。该库包含所有模型的tokenizers,或者我们可以使用AutoTokenizer
(稍后将对此进行详细介绍)。
关于Tokenizer的两个词(tokenization(标记化))
将文本Tokenizing(标记化)是指将文本拆分为单词或子词,然后通过查找表将其转换为ID。实际上,将���本分割成较小的块并没有看上去的那么容易。比如,这个句子“Don't you love Weights and Biases for experiment tracking?”
。我们可以用空格将句子分开,这将得出:
["Don't", "you", "love", "Weights" , "and" , "Biases", "for", "experiment", "tracking?"]
这看起来很合理,但是如果我们看一下 “ tracking?”这个token(标记),就会注意到它后面还跟着一个标点符号,这可能会混淆模型的判断。 “ Don't”代表do not ,因此可以将其标记为[“ Do”,“ n't”]。这就是事情开始变得复杂的地方,也是每个模型都有自己的tokenizer的部分原因。
因此,我们需要为所选模型导入正确的tokenizer。对此,我们可以看看这篇tokenizer摘要,写得很好。
通过查找表将tokens转换为ID这个过程取决于词汇表(使用的所有唯一单词和tokens的集合),该词汇表取决于数据集、任务以及得到的预训练模型。 HuggingFace tokenizer会自动下载在预训练或微调给定模型期间使用的词汇。我们无需根据数据集创建自己的词汇表来进行微调。
要构建tokenizer,我们可以使用与我们希望在自定义数据集上微调的模型关联的tokenizer类,或者直接使用AutoTokenizer类。AutoTokenizer.from_pretrained
方法采用模型名称来构建适当的tokenizer。
下载并准备数据集
在本教程中,我们将使用IMDB数据集。您可以使用任何其他数据集,但总体的步骤将保持不变。
-
您需要下载数据集。 HuggingFace Hub上提供了135多个用于多种NLP任务的数据集,例如文本分类、问题解答、语言建模等,并且可以使用HuggingFace数据集查看器在线查看和浏览。我们将在另一个教程中查看HuggingFace数据集。
!wget http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz !tar -xf aclImdb_v1.tar.gz
-
我们可能需要做一些小的预处理,例如测试和训练集拆分、文本和标签的分离、文本的合并等。在我们的例子中,
read_imdb_split
函数将文本和标签分离。train_texts, train_labels = read_imdb_split('aclImdb/train') test_texts, test_labels = read_imdb_split('aclImdb/test')
-
我们还将创建一个训练-验证拆分。
train_texts, val_texts, train_labels, val_labels = train_test_split(train_texts, train_labels, test_size=.2)
-
HuggingFace tokenizer将完成繁重的工作。我们可以使用
AutoTokenizer
,它可以在后台调用与模型名称关联的正确的tokenization类,也可以直接导入与模型关联的tokenizer(在本例中为DistilBERT)。另外,请注意,tokenizer有两种版本:完整的python实现和“快速”实现。
```Python
MODEL_NAME = 'distilbert-base-uncased'
tokenizer = DistilBertTokenizerFast.from_pretrained(MODEL_NAME )
```
我们将把句子(文本)输入到tokenizer中,tokenizer将返回编码器 文本(将tokens转换为ID)。
```Python
train_encodings = tokenizer(train_texts, truncation=True, padding=True)
val_encodings = tokenizer(val_texts, truncation=True, padding=True)
test_encodings = tokenizer(test_texts, truncation=True, padding=True)
```
三个关键参数是:`padding`、`truncation` 和`max_length`。我强烈建议您读一下这篇文章[everything you always wanted to know about padding and truncation(你一直想知道的关于填充和截断的所有知识)](https://huggingface.co/transformers/preprocessing.html#everything-you-always-wanted-to-know-about-padding-and-truncation)。
l 如果您使用TensorFlow后端来微调transformer,则创建 TF 数据集。如果使用的是PyTorch,则创建PyTorch 数据加载器。
- 三个关键参数是:padding,truncation 和max_length。我强烈建议您检查一下everything you always wanted to know about padding and truncation。
```Python
train_dataset = tf.data.Dataset.from_tensor_slices((
dict(train_encodings),
train_labels
))
```
上述步骤可能会根据任务和数据集而有所不同,但是准备数据集的总体方法保持不变。您可以在此处了解有关预处理数据的更多信息。
🎨 HuggingFace Transformer模型
HuggingFace Transformer模型与本机PyTorch和TensorFlow 2.x兼容。模型是标准的torch.nn.Module或tf.keras.Model,具体取决于模型类名称的前缀。如果以TF开头,则为tf.keras.Model。注意,tokenizers与框架无关。查看Huggingface Transformers中可用模型的总结。
下载预训练的Transformer模型的最简单方法是使用适当的AutoModel(在本例中为TFAutoModelForSequenceClassification)。 from_pretrained用于从本地文件或目录或从HuggingFace提供的预训练模型配置中加载模型。您可以在此处找到预训练模型的列表。
- 由于我们正在微调DistilBERT transformer,因此我们将导入
TFDistilBertForSequenceClassification
。这将下载预训练的模型以及分类头。
```Python
# Import required model class
from transformers import TFDistilBertForSequenceClassification
# Download pre-trained model
model = TFDistilBertForSequenceClassification.from_pretrained(MODEL_NAME)
```
- 假设我们需要输出层(头)具有3个neurons(神经元),我们可以通过将
num_labels = 3
传递给模型类来对其进行初始化。它将创建一个DistilBERT
模型(在本例中)实例,该实例具有从distilbert-base-uncased模型复制的编码器权重,并在编码器顶部随机初始化了序列分类头,输出大小为3。
```Python
model = TFDistilBertForSequenceClassification.from_pretrained(MODEL_NAME,
num_labels=3)
```
-
如果需要,我们还可以要求模型返回所有hidden states和所有注意力权重:
model = TFDistilBertForSequenceClassification.from_pretrained(MODEL_NAME, output_hidden_states=True, output_attentions=True)
-
我们可以通过自定义配置类来更改模型本身的构建方式。每个体系结构都有自己的相关配置(在
DistilBERT
中是DistilBertConfig
),这使我们能够指定任何隐藏的维度、丢弃率等。但是,这样做,我们将不得不从头开始训练模型。我们将在另一个教程中对此进行介绍。
```Python
from transformers import DistilBertConfig
config = DistilBertConfig(n_heads=8, dim=512, hidden_dim=4*512)
model = TFDistilBertForSequenceClassification(config)
```
🎺 功能齐全的Trainer / TFTrainer
您可以使用本机PyTorch和TensorFlow 2来微调HuggingFace Transformer。HuggingFace通过Trainer()
/ TFTrainer()
提供了一个简单但功能齐全的训练和评估界面。
我们可以通过多种多样的训练选项以及指标记录、梯度累积和混合精度等内置功能来训练、微调和评估任何HuggingFace Transformers模型。它可以用来训练分布式策略(甚至在TPU上)。
训练参数
在实例化Trainer
/ TFTrainer
之前,我们需要创建一个TrainingArguments / TFTrainingArguments
来访问训练期间的所有定制点。
training_args = TFTrainingArguments(
output_dir='./results',
num_train_epochs=3,
per_device_train_batch_size=16,
per_device_eval_batch_size=64,
warmup_steps=500,
weight_decay=0.01,
logging_dir='./logs',
logging_steps=10,
)
一些值得注意的参数是:
-
per_device_train_batch_size
: 用于训练的每个GPU / TPU内核/ CPU的批处理大小。 -
gradient_accumulation_steps
: 在执行向后/更新传递之前,要为其累积梯度的更新步骤数。 -
learning_rate
: Adam的初始学习率。 -
weight_decay
: 要应用的权重衰减(如果不为零)。 -
num_train_epochs
: 要执行的训练epochs的总数。 -
run_name
: 用于Weights and Biases日志记录的运行的描述符。您可以在此处了解更多有关参数的信息。
如果您使用的是PyTorch DataLoader,则使用TrainingArguments。您可以在此处了解更多有关参数的信息。请注意,您可以将一些其他功能与TrainingArguments一起使用,例如早停止(early stopping)和标签平滑(label smoothing)。
Trainer(训练器)
Trainer
/ TFTrainer
如果安装了Weights and Biases,它将自动将所有指标记录到W&B项目的仪表板中。
trainer = TFTrainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=val_dataset
)
trainer.train()
用于训练模型,而trainer.eval()
用于评估模型。
如果安装了Weights and Biases,它将自动将所有指标记录到W&B项目的仪表板中。
🎇 结果
💭 总结与资源
希望这份报告对您有所帮助。您也可以选择一个数据集,试一试微调HuggingFace transformer。
以下是有关HuggingFace Transformers的其他一些报告: