Hydra扫参时函数配置被识别为字符串的问题求助
使用Hydra进行参数扫描时,遍历通过hydra.utils.call(或hydra.utils.instantiate)实例化的Python函数,扫参过程中Hydra将目标参数识别为字符串,而非可在脚本中实例化的DictConfig对象,导致调用失败。
项目文件结构:
├── config │ ├── main.yaml │ └── optimization │ ├── main.yaml │ └── utility_function │ ├── eig.yaml │ └── ucb.yaml ├── main.py └── utils.py
当前主配置config/main.yaml的扫参设置:
defaults: - _self_ - optimization: main hydra: sweeper: params: optimization.utility_function: eig, ucb
执行扫参命令python main.py -m时,cfg.optimization.utility_function被解析为字符串"eig"或"ucb",而非包含_target_字段的DictConfig,触发报错:
Cannot instantiate config of type str. Top level config must be an OmegaConf DictConfig/ListConfig object, a plain dict/list, or a Structured Config class or instance.
但直接运行python main.py时,配置加载正常,能正确实例化函数并输出结果。
问题根源是扫参时的参数指定方式错误:optimization.utility_function是Hydra配置组,而非普通字符串参数,需使用配置组专属的扫参语法:
方式1:扫描配置组下所有子配置
修改config/main.yaml中的sweeper配置:
hydra: sweeper: params: optimization.utility_function: ?
?表示自动扫描该配置组下的所有可用子配置(即eig和ucb)。
方式2:扫描指定的子配置
若只需扫描特定子配置,可显式指定(注意参数值无空格,或用引号包裹):
hydra: sweeper: params: optimization.utility_function: eig,ucb
或:
hydra: sweeper: params: optimization.utility_function: "eig, ucb"
验证效果
修改后执行python main.py -m,cfg.optimization.utility_function会正确加载对应子配置(DictConfig类型),包含_target_和_partial_字段,hydra.utils.call可正常调用函数,输出如下:
cfg.optimization.utility={'_target_': 'utils.eig', '_partial_': True}. type(cfg.optimization.utility)=<class 'omegaconf.dictconfig.DictConfig'>. This is the EIG function
原理说明
原配置中eig, ucb被Hydra当作普通字符串值覆盖配置项,而非加载对应的配置组子文件。使用?或正确的配置组扫参语法后,Hydra会解析为加载指定的子配置文件,生成包含实例化信息的DictConfig对象,从而支持call或instantiate调用。
内容的提问来源于stack exchange,提问作者Nazaal

