NNI 超参搜索

想用 NNI 在平台上做超参数自动搜索(编写可接收超参的代码、配置参数空间与算法、启动并查看搜索结果)时阅读

平台使用 / 任务流与训练
超参搜索超参数优化NNInniAutoMLHPOhyperparametertunerTPE参数空间search spacereport_final_resultreport_intermediate_resulttrial

NNI 超参搜索介绍

NNI(Neural Network Intelligence)是微软开源的一个 AutoML 工具包,用于超参数优化、神经架构搜索、模型压缩和特征工程。

NNI 的超参搜索支持更多的算法。同时在 pipeline 中也支持了"边训练边超参搜索"的模板。只需要用户的代码能接受超参数作为输入,同时上报作为超参算法的目标值即可。

每个用户可以启动多个超参搜索的实例,通过 url prefix(/nni/<实验名>/)作为前端的路由(路由前缀实现见 myapp/views/view_nni.py:434,nni web 服务监听容器内 8888 端口)。

可以参考 NNI 官网 的书写方式。

NNI 超参搜索

1、编写超参搜索代码

参数接收

启动超参搜索时,会根据用户配置的超参搜索算法选择好超参的可选值,并将选择值传递给用户的容器。例如下面的超参定义会在用户 docker 运行时传递下面的参数。所以用户不需要在启动命令或参数中添加这些变量,系统会自动添加,用户只需要在自己的业务代码中接收这些参数,并根据这些参数输出值即可。

--lr=0.021593113434583065 --num-layers=5 --optimizer=ftrl

结果上报

业务方容器和代码启动接收超参进行迭代计算,通过主动上报结果来进行迭代。示例如下:用户代码需要能接受超参可取值为输入参数,同时每次迭代通过 nni.report_intermediate_result 上报每次 epoch 的结果值,并使用 nni.report_final_result 上报每次实例的最终结果值。

import os
import argparse
import logging, random, time
import nni
from nni.utils import merge_parameter

logger = logging.getLogger('mnist_AutoML')

def main(args):
    test_acc = random.randint(30, 50)
    for epoch in range(1, 11):
        test_acc_epoch = random.randint(3, 5)
        time.sleep(3)
        test_acc += test_acc_epoch
        # 上报当前迭代目标值
        nni.report_intermediate_result(test_acc)
    # 上报最终目标值
    nni.report_final_result(test_acc)


def get_params():
    # 必须接收超参数为输入参数
    parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
    parser.add_argument('--batch_size', type=int, default=64, help='input batch size for training (default: 64)')

    args, _ = parser.parse_known_args()
    return args


if __name__ == '__main__':
    try:
        # get parameters form tuner
        tuner_params = nni.get_next_parameter()
        params = vars(merge_parameter(get_params(), tuner_params))
        print(tuner_params, params)
        main(params)
    except Exception as exception:
        logger.exception(exception)
        raise

2、添加一个超参搜索实验

在这里插入图片描述

创建实验时需要配置:搜索算法、目标函数类型(maximize/minimize)、目标指标名、超参数(搜索空间)、任务镜像、工作目录、启动命令、资源(cpu/memory/gpu)、任务并行数、最大任务数、最大运行时长、任务并行方式等。

平台实际可选的搜索算法(myapp/views/view_nni.py:191-206):TPE、Random、Anneal、Evolution、SMAC、BatchTuner、GridSearch、Hyperband、NetworkMorphism、MetisTuner、BOHB、GPTuner、PPOTuner、PBTTuner。

任务并行方式(parallel_trial_type)有两种(view_nni.py:132-138):

  • multi-process:单机多进程,平台创建单个 nni Pod 运行(make_nnijob);
  • multi-machine:多机多进程,平台创建 Volcano Job 拉起 master + 多个 worker(make_volcanojob)。

不同超参算法支持不同的超参空间

下表为 NNI 各 Tuner 对不同搜索空间类型的支持情况(参考 NNI 官方文档):

Tuner choice choice(nested) randint uniform quniform loguniform qloguniform normal qnormal lognormal qlognormal
TPE Tuner ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
Random Search Tuner ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
Anneal Tuner ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
Evolution Tuner ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
SMAC Tuner ✓ ✓ ✓ ✓ ✓
Batch Tuner ✓
Grid Search Tuner ✓ ✓ ✓
Hyperband Advisor ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
Metis Tuner ✓ ✓ ✓ ✓
GP Tuner ✓ ✓ ✓ ✓ ✓ ✓

超参空间

必须是标准的 json。示例:

{
    "batch_size": {"_type":"choice", "_value": [16, 32, 64, 128]},
    "hidden_size":{"_type":"choice","_value":[128, 256, 512, 1024]},
    "lr":{"_type":"choice","_value":[0.0001, 0.001, 0.01, 0.1]},
    "momentum":{"_type":"uniform","_value":[0, 1]}
}

该示例即平台内置的搜索空间示例 core.nni_parameters_demo()(myapp/utils/core.py:574)。

3、启动超参搜索

点击 运行 | 容器 | 日志 | 清理 中的 运行 按钮:

  • 运行按钮:启动搜索实验(部署 nni 服务,接口 /nni_modelview/api/run/<nni_id>,view_nni.py:791);
  • 容器按钮:查看搜索实验容器运行状况;
  • 日志按钮:查看平台日志(这里不是业务代码日志,接口 /nni_modelview/api/log/<nni_id>,view_nni.py:925);
  • 清理按钮:删除清理实验(接口 /nni_modelview/api/stop/<nni_id>,view_nni.py:776)。

4、查看超参搜索进度和结果

等待全部容器运行中时,点击名称,进入 web 界面查看实验进度和日志(跳转到 /nni/<实验名>/,view_nni.py:938-954)。

web 查看搜索效果

总览界面可以看到实验的 id 和当前实例运行的状态。

输入图片说明

输入图片说明

可以看每次 trial 的运行情况、计算出来的目标值。

输入图片说明

也可以看某次 trial 中每次 epoch 得到的结果值。

分布式超参搜索日志查看

由于是分布式进行超参数搜索,日志保存在分布式存储。想看某次搜索运行实例的日志:

在这里插入图片描述

在 web 界面看到的日志地址为:

Trial stdout: file://test-worker-2.test:/tmp/nni-experiments/$实验名/envs/$任务名

则对应分布式存储日志路径地址为:

/mnt/$用户名/nni/$nni名称/log/$实验名/envs/$任务名

说明:nni 代码、配置和 log 都在 /mnt/${username}/nni/ 目录下。实验工作目录为 /mnt/<username>/nni/<name>/log/,容器内 /tmp/nni-experiments/ 挂载到该 log 目录(view_nni.py:393/489/834)。

在这里插入图片描述

5、清理超参搜索实验

点击 运行 | 容器 | 日志 | 清理 中的 清理 按钮。运行结束后记得主动清理,以释放集群资源。

最后更新 2026-08-11完整文档以官方仓库为准:GitHub Wiki