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

发布于 2020 年 11 月 2 日
在 GitHub 上更新
Anyscale 团队 Richard Liaw 的客座博客文章

Hugging Face 的 transformers 库拥有前沿的研究实现和数千个易于访问的预训练模型,已成为当今自然语言处理成功和发展的关键。

为了使任何机器学习模型都能取得良好的性能,用户通常需要实施某种形式的参数调整。然而,几乎所有人(1, 2)最终都忽略了超参数调优,或者选择使用小搜索空间进行简单的网格搜索。

然而,简单的实验就能证明使用高级调优技术的好处。以下是 Hugging Face transformersRTE 数据集上对 BERT 模型进行 最新实验的结果。与标准超参数优化技术相比,像 PBT 这样的遗传优化技术可以提供巨大的性能改进。

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

如果您正在使用 Transformers,您会希望有一种方法可以轻松访问强大的超参数调优解决方案,同时又不放弃 Transformers 框架的可定制性。

alt_text

在 Transformers 3.1 版本中,Hugging Face TransformersRay 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)

# Evaluate during training and a bit more often
# than the default to be able to prune bad trials early.
# Disabling tqdm is a matter of preference.
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,
)

# Default objective is the sum of all metrics
# when metrics are provided, so we have to maximize it.
trainer.hyperparameter_search(
    direction="maximize", 
    backend="ray", 
    n_trials=10 # number of trials
)

默认情况下,每个试验将使用 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",
    # Choose among many libraries:
    # https://docs.rayai.org.cn/en/latest/tune/api_docs/suggestion.html
    search_alg=HyperOptSearch(metric="objective", mode="max"),
    # Choose among schedulers:
    # https://docs.rayai.org.cn/en/latest/tune/api_docs/schedulers.html
    scheduler=ASHAScheduler(metric="objective", mode="max"))

它也与 Weights and Biases 开箱即用!

alt_text

立即试用:

如果您喜欢这篇博客文章,请务必查看

社区

注册登录发表评论