Skip to main content

如何使用W&B微调HuggingFace Tranformer?

在此报告中,我们将学习如何轻松地在自定义数据集上微调HuggingFace Transformer。
Created on March 5|Last edited on July 12

🤗 导言

在此报告中,我们将快速浏览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: 用于训练的每个G​​PU / 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项目的仪表板中。



🎇 结果




Run set
1


💭 总结与资源

希望这份报告对您有所帮助。您也可以选择一个数据集,试一试微调HuggingFace transformer。

以下是有关HuggingFace Transformers的其他一些报告: