NNI自动调参使用简介
前言
- NNI是微软于2021年8月推出的一款用于支持机器学习实验的工具,它可以以自动化的方式辅助用户进行神经网络架构的设计、模型参数的调节等。NNI具有方便易用、可扩展性强、灵活度高和调节效率高等优点。
- NNI有中英文官方文档中文地址, 英文地址,其中有详细的使用介绍。这里我们只需要使用其自动调参功能,因此,本文将结合NNI, 基于Pytorch,就自动调参这一需求作详细介绍。使用NNI进行自动架构搜索等内容不再本文讨论范围之内。
-
NNI的整体架构如图所示:
使用概述
-
NNI式一款非侵入的工具,简而言之就是,几乎不用改变原代码的任何内容,就可以实现自动调参、自动架构搜索等功能。如下图所示,假设我们已经有了一个完整的机器学习模型,我们现在需要对部分参数进行网格搜索来确定其最优值,我们可以按照下面的步骤进行:
- 确定搜索空间,在search_space.json文件中写下参数名和取值范围
- 更新代码,在原代码中加入少量几行代码,将参数传入模型
- 编辑配置文件,config.yaml,确定自动调参一些参数,如是否使用GPU,最大搜索轮次等
- 执行自动搜索,打开WebUI即可实时查看参数搜索的过程
详细介绍
- 在本节中,我们将对上述几个步骤作详细介绍
- 确定参数搜索空间
search_space.json
在让框架进行自动参数搜索之前,每一个参数我们可以确定几个候选值或者一定的搜索范围。每一个key代表参数的名称。
可选的类型有离散和连续等,离散值就是在_value的候选中选择,例如dropout_rate
的可选值有0.1
和0.5
连续值就是一个均匀分布,例如lr
的可选值就是上下界为0.0001
和0.1
的均匀分布
{
"dropout_rate": {"_type": "uniform", "_value": [0.1, 0.5]},
"conv_size": {"_type": "choice", "_value": [2, 3, 5, 7]},
"hidden_size": {"_type": "choice", "_value": [124, 512, 1024]},
"batch_size": {"_type": "choice", "_value": [50, 250, 500]},
"lr": {"_type": "uniform", "_value": [0.0001, 0.1]}
}
- 更新代码
由于nni是非侵入的,即只需要在原代码中添加数行由于引入可变参数,而无需删除或者修改原来的代码。
假设我们原来的代码中,参数都存储在名为config
的字典(dict
)对象中,而我们使用以下方式来传递参数
optimizer = AdamW(optimizer_grouped_parameters, lr=config['lr'])
那么使用NNI,只需要将NNI得到的参数名和参数值更新到原来的config
中即可,如下所示:
import nni
params = nni.get_next_parameter()
for k, v in params.items():
config[k] = v
后续我们再使用下面代码时,config['lr']
存储的就是nni传入的参数值
optimizer = AdamW(optimizer_grouped_parameters, lr=config['lr'])
除了参数部分,我们还需要报告当前模型的结果,包括每一个epoch的中间结果和本次实验的最终结果:
# 以下两行看情况插入原代码的合适位置
nni.report_intermediate_result(cur_f1) # 打印每一轮的F1
nni.report_final_result(best_f1)# 打印最终的F1
- 编辑配置文件
在使用NNI使用,除了确定模型的参数范围,NNI调参过程本身也有一些参数可以控制,一个典型的配置文件config.yaml
内容如下所示:
authorName: unik
experimentName: example_mnist
trialConcurrency: 2
maxExecDuration: 100h
maxTrialNum: 200
trainingServicePlatform: local
searchSpacePath: search_space.json
useAnnotation: false
tuner:
builtinTunerName: TPE
trial:
#command: CUDA_VISIBLE_DEVICES=0 python main.py
command: python main.py
codeDir: .
gpuNum: 1
localConfig:
useActiveGpu: true
maxTrialNumPerGpu: 1
其中
-
command: python main.py
代表模型运行的入口,和手动运行模型的使用的命令保持一致 -
gpuNum
: 代表单个实例使用的GPU数量 -
maxTrialNumPerGpu
代表一块gpu上最多可以运行几个实例
其他参数的详细意义可以查阅官网,上述参数配置可以实现利用机器上的多块GPU同时进行多个实例的训练。
需要注意的是,我们建议在模型中使用下面的方式将模型迁移到cuda
device = torch.device('cuda:0')
model.to(device)
- 执行自动搜索
使用以下命令,开启自动搜索
nnictl create --config config.yaml
打开浏览器,输入http://127.0.0.1:8080即可查看调参过程。网页界面比较友好,功能比较齐全,这里就不做过多介绍。
示例代码
为了方面大家进行后续的探索,笔者实现了一个基本的示例代码,使用NNI+PyTorch框架,对文本情感分类任务进行自动参数调节。
完整代码见 https://github.com/unikcc/nni_experiment