使用Transformers和Ray Tune进行超参数搜索

使用Transformers和Ray Tune进行超参数搜索

Anyscale 团队的 Richard Liaw 的客座博客文章

凭借先进的研究实施和数千个经过训练的模型的便捷访问,Hugging Face Transformers库已经成为当今自然语言处理成功和增长的关键。

要使任何机器学习模型实现良好的性能,用户通常需要实现某种形式的参数调整。然而,几乎每个人(1,2)最终要么忽略超参数调整,要么选择使用具有小搜索空间的简单网格搜索。

然而,简单的实验能够展示使用先进的调整技术的好处。下面是最近在 Hugging Face Transformers 上的 BERT 模型在 RTE 数据集上运行的实验。与标准超参数优化技术相比,基于遗传优化的技术如 PBT 可以提供大幅度的性能提升。

算法 最佳验证准确率 最佳测试准确率 总 GPU 时间 总花费
网格搜索 74% 65.4% 45 分钟 $2.30
贝叶斯优化+提前停止 77% 66.9% 104 分钟 $5.30
基于人口的训练 78% 70.5% 48 分钟 $2.45

如果您正在使用 Transformers,您将希望能够轻松访问强大的超参数调整解决方案,同时不放弃 Transformers 框架的可定制性。

在 Transformers 3.1 版本中,Hugging Face Transformers 和 Ray Tune 合作提供了一种简单而强大的集成。Ray Tune 是一个流行的用于超参数调整的 Python 库,它提供了许多最先进的算法,以及与最佳工具的集成,如 Weights and Biases 和 tensorboard。

为了演示这个新的 Hugging Face + Ray Tune 集成,我们利用 Hugging Face Datasets 库对 MRPC 上的 BERT 进行微调。

要运行此示例,请首先运行:

pip install "ray[tune]" transformers datasets scipy sklearn torch

只需添加几行代码即可插入 Ray 的标准调整算法。

from datasets import load_dataset, load_metric
from transformers import (AutoModelForSequenceClassification, AutoTokenizer,
                          Trainer, TrainingArguments)

tokenizer = AutoTokenizer.from_pretrained('distilbert-base-uncased')
dataset = load_dataset('glue', 'mrpc')
metric = load_metric('glue', 'mrpc')

def encode(examples):
    outputs = tokenizer(
        examples['sentence1'], examples['sentence2'], truncation=True)
    return outputs

encoded_dataset = dataset.map(encode, batched=True)

def model_init():
    return AutoModelForSequenceClassification.from_pretrained(
        'distilbert-base-uncased', return_dict=True)

def compute_metrics(eval_pred):
    predictions, labels = eval_pred
    predictions = predictions.argmax(axis=-1)
    return metric.compute(predictions=predictions, references=labels)

# 在训练期间进行评估,并且比默认值更频繁地进行评估,以便能够尽早修剪不良试验。禁用 tqdm 是一种偏好。
training_args = TrainingArguments(
    "test", evaluation_strategy="steps", eval_steps=500, disable_tqdm=True)
trainer = Trainer(
    args=training_args,
    tokenizer=tokenizer,
    train_dataset=encoded_dataset["train"],
    eval_dataset=encoded_dataset["validation"],
    model_init=model_init,
    compute_metrics=compute_metrics,
)

# 默认目标是提供所有指标的总和,当提供了指标时,我们必须最大化它。
trainer.hyperparameter_search(
    direction="maximize", 
    backend="ray", 
    n_trials=10 # 试验数量
)

默认情况下,每个试验将使用1个CPU,如果有的话还可以选择使用1个GPU。您可以通过传递resources_per_trial参数来利用多个GPU进行并行的超参数搜索。

您还可以轻松地切换不同的参数调整算法,如HyperBand、贝叶斯优化、基于种群的训练:

要运行此示例,请先运行:pip install hyperopt

from ray.tune.suggest.hyperopt import HyperOptSearch
from ray.tune.schedulers import ASHAScheduler

trainer = Trainer(
    args=training_args,
    tokenizer=tokenizer,
    train_dataset=encoded_dataset["train"],
    eval_dataset=encoded_dataset["validation"],
    model_init=model_init,
    compute_metrics=compute_metrics,
)

best_trial = trainer.hyperparameter_search(
    direction="maximize",
    backend="ray",
    # 在众多库中进行选择:
    # https://docs.ray.io/en/latest/tune/api_docs/suggestion.html
    search_alg=HyperOptSearch(metric="objective", mode="max"),
    # 在调度器中进行选择:
    # https://docs.ray.io/en/latest/tune/api_docs/schedulers.html
    scheduler=ASHAScheduler(metric="objective", mode="max"))

它还可以与 Weights and Biases 无缝集成!

立即尝试:

  • pip install -U ray
  • pip install -U transformers datasets
  • 查看 Hugging Face 文档和讨论主题
  • 使用 Hugging Face 进行文本分类的端到端示例

如果您喜欢这篇博文,请务必查看以下内容:

  • Transformers + GLUE + Ray Tune 示例
  • 我们关于 Transformers 的超参数优化的 Weights and Biases 报告
  • 从头开始为您的 NLP 模型提供服务的最简单方法