超参搜索任务模板
平台提供两种超参搜索算子,均在流水线节点内运行 launcher.py,产出结果 CSV 与平台可视化的平行坐标图(/metric.json):
| 算子目录 | 框架 | 适用 |
|---|---|---|
hyperparameter-search-nni |
NNI | 通用超参实验,trial 脚本按 NNI 约定上报指标 |
hyperparameter-search-ray |
Ray Tune + ASHA | 驱动外部训练命令做多轮搜索,从评估 JSON 读指标 |
面向使用者的功能说明另见 03-平台使用/06-任务流与训练/超参搜索.md;本篇侧重算子设计与参数核对。
hyperparameter-search-nni(基于 NNI)
镜像(以 build.sh 为准):ccr.ccs.tencentyun.com/cube-studio/hyperparameter-search-nni:20250301;注意 README 与模板注册 JSON 里默认值仍写旧镜像名 ccr.ccs.tencentyun.com/cube-studio/hyperparam_search:nni-20230801(README.md:5,86,已过时,二者并存,以 build.sh 实际构建的 hyperparameter-search-nni:20250301 为准)。启动命令 python launcher.py(核对 hyperparameter-search-nni/launcher.py、build.sh)。
执行流程
- 解析参数:
launcher.py用argparse.parse_known_args()把平台传入的--key value收成字典并封成nni对象(launcher.py:113-122)。 - 生成配置
make_config(nni):拼出 NNI 的controll_template.yaml(写到nni.workdir下),包含:searchSpace:由--parameters(JSON)转成 YAML 搜索空间(choice/uniform/loguniform 等)。trialConcurrency=parallel_trial_count、trialCommand=command、trialCodeDirectory=workdir、maxExperimentDuration={max_exec_duration}s、maxTrialNumber=max_trial_count。trialGpuNumber:取环境变量KFJ_TASK_RESOURCE_GPU(含(时只取括号前数字)。tuner.name=algorithm_name、tuner.classArgs.optimize_mode=objective_type。trainingService.platform=local,useActiveGpu:GPU 为0/空则false,否则true。
- 启动 NNI:
nnictl create --config <controll_template.yaml> --foreground -p {PORT}(前台运行直至结束)。PORT取环境变量PORT1,默认80(launcher.py:13)。 - 收集结果
get_nni_result(nni):从 NNI sqlite 库/root/nni-experiments/_latest/db/nni.sqlite读MetricData(type=FINAL) 与TrialJobEvent,把各 trial 的参数+最终指标汇总,写workdir/nni-result.csv(每行一个 trial,末列result),并draw_parallel生成平行坐标图配置写/metric.json。
启动参数
| 参数 | 含义 | Launcher 用途 | 示例默认 |
|---|---|---|---|
--workdir |
代码/工作目录 | trialCodeDirectory,结果 CSV 也写此目录 |
/mnt/admin/pipeline/example/nni |
--command |
每个 trial 的启动命令 | trialCommand |
python demo.py |
--parameters |
NNI 搜索空间(JSON) | searchSpace |
{"lr":{"_type":"choice","_value":[0.0001,0.001,0.01,0.1]},...} |
--parallel_trial_count |
并行 trial 数 | trialConcurrency |
3 |
--max_trial_count |
最大 trial 数 | maxTrialNumber |
12 |
--max_exec_duration |
最大实验时长(秒) | maxExperimentDuration |
86400 |
--objective_type |
目标方向 maximize/minimize | optimize_mode |
maximize |
--algorithm_name |
搜索算法 | tuner.name |
Random(README 注册 choice:TPE/Random/Anneal/Evolution/SMAC/BatchTuner/GridSearch/Hyperband/NetworkMorphism/MetisTuner/BOHB/GPTuner/PPOTuner/PBTTuner,见 README.md:204) |
--algorithm_setting |
算法额外配置 | 当前 launcher 未使用,预留 | 空 |
--objective_goal / --objective_metric_name / --objective_additional_metric_names |
目标值/指标名 | 当前 launcher 未写入 NNI,预留 | — |
已核实:
make_config仅用到 parameters / parallel_trial_count / command / workdir / max_exec_duration / max_trial_count / algorithm_name / objective_type;algorithm_setting、objective_goal、objective_metric_name、objective_additional_metric_names确实未被写入 NNI 配置(launcher.py:16-48),属预留参数。
Trial 脚本约定与查看结果
- 每个 trial 由 NNI 在
workdir下执行command(如python demo.py)。脚本需用 NNI API/环境变量接收当次超参,并上报最终指标(FINAL),否则 launcher 无法从 sqlite 汇总结果。具体写法见 NNI 官方文档。 - 结果:
workdir/nni-result.csv(每行一个 trial)+/metric.json(平台据此展示超参与结果的平行坐标图)。 - 可在任务模板环境变量里配
TASK_RESOURCE_GPU=1、NO_RESOURCE_CHECK=true等固定资源/跳过校验。
hyperparameter-search-ray(基于 Ray Tune + ASHA)
镜像(以 build.sh 为准):ccr.ccs.tencentyun.com/cube-studio/hyperparameter-search-ray:20260301;注意 README/注册默认值仍写旧镜像名 ccr.ccs.tencentyun.com/cube-studio/hyperparam_search:20230530(README.md:47,已过时,以 build.sh 实际构建的 hyperparameter-search-ray:20260301 为准)。工作目录 job-template/job/hyperparameter-search-ray,启动命令 python launcher.py(核对 hyperparameter-search-ray/launcher.py、示例 train-decision-tree.py、build.sh)。
执行流程(以代码为准)
- 解析参数:argparse 读
--workdir、--command、--params、--outfile、--metric、--mode、--num_samples、--result_save_path(launcher.py:144-152)。--params用eval()解析为 Ray Tune 搜索空间字典。 - 每个 trial 调
train_model(config)(launcher.py:38-74):- 拼命令
cd {workdir} && {command},然后把本 trial 采样到的每个超参逐个追加为--{key} {value}(launcher.py:51-53),os.system执行。 - 执行后若
outfile不存在则报错退出;存在则把outfile复制一份到outfile去掉.json再拼_<params_json>.json的副本(区分各 trial 结果,launcher.py:68)。 - 读
outfile的 JSON,若含metric(单个指标名)则tune.report({metric: result[metric]})。
- 拼命令
- 搜索:
tune.run(train_model, config=params, metric=metric, mode=mode, num_samples=..., scheduler=ASHAScheduler(), ...),关闭 dashboard(include_dashboard=False,规避 pydantic 版本冲突)。 - 产出:取
analysis.results_df中所有config/*列 + metric 列写result_save_path(CSV);另写<结果文件名>_best.json(最佳配置)与/metric.json(metric_type=echart-parallel,file_path指向 CSV)。
启动参数
| 参数 | 必填 | 含义 |
|---|---|---|
--workdir |
否 | 命令执行目录(相对路径会基于它解析 outfile/result_save_path) |
--command |
否 | 训练命令;launcher 会在其后追加各超参 --{key} {value} |
--params |
否 | Ray Tune 搜索空间,字典字符串(tune.grid_search/tune.choice/tune.uniform/...),如 {"max_depth": tune.grid_search([3,4,5])} |
--outfile |
是 | 训练脚本写出的评估结果 JSON 路径 |
--metric |
否 | 评估指标名(在 outfile JSON 中读该 key) |
--mode |
否 | max / min |
--num_samples |
否 | 采样 trial 次数(grid_search 时通常 1) |
--result_save_path |
否 | 结果 CSV 保存路径 |
命令行示例(取自 launcher.py 注释):
python launcher.py \
--workdir '/mnt/admin/pipeline/example/ray' \
--command 'python train-decision-tree.py --save_model_dir decision_tree --train_dataset /mnt/admin/pipeline/example/ml/train.csv --label_columns y --feature_columns age,duration,campaign,pdays,previous,emp_var_rate,cons_price_idx,cons_conf_idx,euribor3m,nr_employed' \
--params '{"max_depth": tune.grid_search([3,4,5]),"min_samples_split": tune.grid_search([5,10,20])}' \
--outfile 'decision_tree/val_result.json' \
--metric "test_auc" --mode 'max' --num_samples '1' \
--result_save_path 'automl_result.csv'
被搜索的训练脚本需要:
- 接受被搜索的每个超参作为独立 CLI 参数(如
--max_depth、--min_samples_split),launcher 逐个追加。 - 把评估指标写入
--outfile指定的 JSON(键名与--metric一致)。train-decision-tree.py即此约定的参考实现。
注意(README 与当前代码不一致,正文已按代码
launcher.py描述):随算子附带的hyperparameter-search-ray/README.md声称——(1) launcher 在命令后追加--model_params '<json>'整体传超参;(2)--metric是列表且取metric[-1]为优化目标;(3) 会把命令/outfile 中的子串val_result替换为val_result<params_json>。但当前launcher.py实际是——(1) 把每个超参拆成独立--key value追加(launcher.py:51-53);(2)--metric当作单个指标名字符串使用(launcher.py:166,71-73);(3) 训练脚本仍写固定outfile,launcher 读取后再复制成_<params_json>.json的副本(launcher.py:68,无val_result子串替换逻辑)。请确认 README 描述的是旧版接口还是预期行为;以仓库当前launcher.py为准。
注意事项
- 多 trial 并发会向同一个
outfile写入,launcher 用time.sleep(random.randint(1,100)/10)错开并在读后复制备份;高并发下仍可能有写入竞争,建议训练脚本自身按超参生成唯一结果路径以彻底规避。 - 结果 CSV 在
result_save_path,平台据/metric.json(echart-parallel)展示平行坐标图。
本篇为知识库导航/核对稿,具体参数与行为以各算子源码(job-template/job/...)为准。