0. 简介

RUNX 是 NVIDIA 开发的一款实验管理工具,旨在自动化执行一系列命令行任务,主要功能包括:

  • 超参数调优/消融实验分析:以不同参数运行实验代码,再进行性能比较
  • 日志记录:管理过程中的日志,支持文本、TensorBoard等
  • 模型检查点:保存管理 checkpoints
  • 实验总结:对运行不同参数得到的结果生成列表总结
  • 代码备份:不同参数运行时将代码备份到各自文件夹,方便 debugging

1. 主要组件

  • runx.runx

    该组件对实验中的超参数进行处理,根据不同的超参数组合,生成一系列运行命令,对每个命令建立独立的运行文件夹,备份代码至相关文件夹,并将当前运行环境配置、运行超参数等以 yaml 文件形式写入相关文件夹

  • runx.logx

    该组件记录和管理实验过程中的日志,主要包括 metrics、messages、checkpoints 等部分,可替代日常使用的 logging、torch.save、SummaryWriter、print 等日志和模型存放方式

  • runx.sumx

    该组件对不同运行配置得到的结果进行分析整理,根据预先定义的指标对模型进行排序,便于分析/选择最优模型

2. 安装配置

通过 pip 安装:

1
2
3
git clone https://github.com/NVIDIA/runx
cd runx
python setup.py install --user

通过源码安装:

1
git clone 

3. 基本使用教程

3.0. 基本假设

  • 假定代码运行时有 param1param2 两个参数,运行命令为:
1
python main.py --param1 p1 --param2 p2 --logdir ./logs
  • 代码 main.py 中包含对超参数的处理,日志、模型等保存在参数 logdir 指定的目录下

3.1. runx 基本配置

  • 在 main.py 所在目录下新建一个隐藏文件 ./.runx
1
touch ./.runx
  • 修改 ./.runx 文件内容,注意必须配置 LOGROOT, 该配置为存放所有记录文件的目录路径,注意该路径不能在当前路径下(否则代码备份时会陷入无限循环)。例如:
1
LOGROOT: /OtherPath/RUNX-LOGS

3.2. 使用 runx.runx

  • 在 main.py 所在目录下新建一个文件 experiment.yml,注意此处的 experiment 为运行的实验名,可以根据需要进行修改,例如可新建为 tune-lr.yml。实验名为最终生成的根目录,若上述的 LOGROOT 设置为 /OtherPath/RUNX-LOGS,实验名设置为 exp,则最终所有运行的实验都在目录 /OtherPath/RUNX-LOGS/exp 中
1
touch ./experiment.yml
  • 修改 ./experiment.yml 文件内容,将 CMD 参数设置为运行的基础命令,将运行过程中的其他超参数在 HPARAMS 中进行设置,例如:
1
2
3
4
5
6
CMD: 'python main.py'
HPARAMS:
  param1: [0.01, 0.02]
  param2: ['str1', 'str2']
  logdir: LOGDIR
  # LOGDIR 表示在当前的日志目录下

完成上述配置后,可以通过运行 python -m runx.runx experiment.yml -i 开始实验,此时如果是在本地运行(非集群/任务)记得加上 -i 选项(interactive mode)。当然,也可以加上 -n 选项,此时只打印将运行的批处理命令而不实际运行这些命令。

由于运行的目标是单独存放每个参数配置的实验结果,runx 会给每次运行的代码、日志、tensorboard记录文件等单独创建一个文件夹,在 .yml 配置文件中可以通过 LOGDIR 访问该目录(如上述的例子中使用 LOGDIR 作为参数 logdir 的实际取值)。

3.3. 使用 runx.logx

为了便于观察实验运行状况、调试代码、对实验结果进行分析,需要对代码运行过程中的一些状态值进行记录,经过一定阶段,还需要进行模型保存等操作,为此 runx 提供了 logx 模块,runx.logx 可以完成诸如 printlogging 的基础日志/输出功能,还可以完成 tensorboard 等高级日志记录工具的功能;此外,由于后续需要根据运行结果选择最优超参数,runx.logx 可以记录模型运行过程中的评测指标(metric),为后续 runx.sumx 的整理分析提供数据支持。

  • 使用 runx.logx 之前需要进行导入和初始化:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from runx.logx import logx

# args 为 argparse 模块提供的参数解析 NameSpace

logx.initialize(
    logdir=args.logdir, 
    coolname=True, 
    tensorboard=True,
    hparams=vars(args)
)
  • 训练过程中可以保存运行状态的值:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
logx.metric(
    phase='train', 
    metrics={'loss': 10.0}, 
    epoch=5
)
logx.metric(
    phase='val', 
    metrics={'accuracy': 100.0}, 
    epoch=5
)
  • 训练过程中保存模型:
1
2
3
4
5
6
7
# model 为网络模型
save_model(
    {'state_dict': model.state_dict()}, 
    metric={'accuracy': 100.0},
    epoch=5, 
    higher_better=True
)
  • 训练过程中代替 print 等进行训练日志输出:
1
logx.msg("string to print")
  • 训练过程中的替代总结:
原始函数替代函数功能
print()logx.msg()输出信息
writer.add_scalar()logx.add_scalar()记录标量值 (TensorBoard)
writer.add_image()logx.add_image()记录图像 (TensorBoard)
torch.save()logx.save_model()保存最近的/最好的模型参数

3.4. 使用 runx.sumx

运行 runx.runx 后,在 runx 指定的日志根目录下会生成一个 exepriment 目录 (该目录名由配置文件名指定),目录下有若干个子目录,每个子目录代表一种超参数配置下的代码及运行结果。

为了对这些实验结果进行分析,知道每个 epoch 平均运行时间、测试精度等,选择最优的参数组合,runx 提供了对运行结果进行整理分析的模块,即 runx.sumx

在前述的 runx.runx 运行目录下,runx.sumx 可以访问实验的根目录,即 LOGROOT,要使用 runx.sumx,只需要指定实验中想进行评估的指标即可。

例如上述的 runx.logx 记录了名为 accuracy 的性能指标,则此时可以分析:

1
python -m runx.sumx experiment --sortwith accuracy

此时可以得到输出,例如官方示例给出的输出:

1
2
3
4
5
6
python -m runx.sumx experiment --sortwith accuracy
        lr    solver  accuracy   epoch  epoch_time
run4    0.02  adam    99.1       10     5:21
run3    0.02  sgd     99.0       10     5:02
run1    0.01  sgd     98.2       10     5:40
run2    0.01  adam    98.1       10     5:25