首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从OmegaConf自定义解析器解析的元组的Hydra实例化对于嵌套配置文件失败

从OmegaConf自定义解析器解析的元组的Hydra实例化对于嵌套配置文件失败
EN

Stack Overflow用户
提问于 2021-10-20 18:16:41
回答 1查看 1.5K关注 0票数 1

OmegaConf允许您注册自定义解析器。下面是一个解析元组的示例。

代码语言:javascript
运行
复制
def resolve_tuple(*args):
    return tuple(args)

OmegaConf.register_new_resolver("tuple", resolve_tuple)

这可以用于将配置文件中的值解析为元组(1, 2),配置文件的结构类似于(1, 2)。与hydra.utils.instantiate一起,这可以用于创建包含或使用元组的对象。例如:

config.yaml

代码语言:javascript
运行
复制
obj:
  tuple: ${tuple:1,2}

test.py

代码语言:javascript
运行
复制
import hydra
import hydra.utils as hu

from omegaconf import OmegaConf


def resolve_tuple(*args):
    return tuple(args)


OmegaConf.register_new_resolver('tuple', resolve_tuple)


@hydra.main(config_path='conf', config_name='config_test')
def main(cfg):
    obj = hu.instantiate(cfg.obj, _convert_='partial')
    print(obj)


if __name__ == '__main__':
    main()

运行此示例将返回:

代码语言:javascript
运行
复制
$ python test.py
{'tuple': (1, 2)}

但是,假设您的配置结构要复杂得多。您可能想要使用内插从其他文件,如这样带来信任。

元组/碱基

代码语言:javascript
运行
复制
tuple: ${tuple:1,2}

config.yaml

代码语言:javascript
运行
复制
defaults:
  - tuple: base
  - _self_

obj:
  tuple: ${tuple}

运行此示例将得到一个错误:

代码语言:javascript
运行
复制
$ python test.py
Error executing job with overrides: []
Traceback (most recent call last):
  File "test.py", line 16, in main
    obj = hu.instantiate(cfg.obj, _convert_='partial')
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/_internal/instantiate/_instantiate2.py", line 175, in instantiate
    OmegaConf.resolve(config)
omegaconf.errors.UnsupportedValueType: Value 'tuple' is not a supported primitive type

Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.

水龙头的全部回溯是:

代码语言:javascript
运行
复制
Error executing job with overrides: []
Traceback (most recent call last):
  File "test.py", line 21, in <module>
    main()
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/main.py", line 52, in decorated_main
    config_name=config_name,
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/_internal/utils.py", line 378, in _run_hydra
    lambda: hydra.run(
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/_internal/utils.py", line 214, in run_and_report
    raise ex
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/_internal/utils.py", line 211, in run_and_report

    return func()
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/_internal/utils.py", line 381, in <lambda>
    overrides=args.overrides,
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/_internal/hydra.py", line 111, in run
    _ = ret.return_value
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/core/utils.py", line 233, in return_value
    raise self._return_value
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/core/utils.py", line 160, in run_job
    ret.return_value = task_function(task_cfg)
  File "test.py", line 17, in main
    model = hu.instantiate(cfg.obj, _convert_='partial')
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/hydra/_internal/instantiate/_instantiate2.py", line 175, in instantiate
    OmegaConf.resolve(config)
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/omegaconf/omegaconf.py", line 792, in resolve
    omegaconf._impl._resolve(cfg)
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/omegaconf/_impl.py", line 40, in _resolve
    _resolve_container_value(cfg, k)
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/omegaconf/_impl.py", line 19, in _resolve_container_value
    _resolve(resolved)
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/omegaconf/_impl.py", line 40, in _resolve
    _resolve_container_value(cfg, k)
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/omegaconf/_impl.py", line 23, in _resolve_container_value
    node._set_value(resolved._value())
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/omegaconf/nodes.py", line 44, in _set_value
    self._val = self.validate_and_convert(value)
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/omegaconf/nodes.py", line 57, in validate_and_convert
    return self._validate_and_convert_impl(value)
  File "/Users/me/anaconda3/envs/my_env/lib/python3.7/site-packages/omegaconf/nodes.py", line 134, in _validate_and_convert_impl
    f"Value '{t.__name__}' is not a supported primitive type"
omegaconf.errors.UnsupportedValueType: Value 'tuple' is not a supported primitive type

如果您在跟踪中仔细研究omegaconf代码,您会发现配置对象allow_objects的标志是True,在传递的示例中是True,而在没有传递的示例中有None。有趣的是,在调用_instantaite2.py之前的Omegaconf.resolve(config)文件中设置了几个标志,其中一个是allow_objects作为True

这些内插/解析值的预期行为是否从单独的文件中填充以覆盖此标志?如果是这样的话,是否有什么方法可以确保allow_objects标志对于所有解析和插值的值都是真的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-20 23:22:09

我认为存在一些混淆,因为您使用tuple一词是为了多个不同的目的:)

下面是一个对我有用的例子:

代码语言:javascript
运行
复制
# my_app.py
import hydra
import hydra.utils as hu

from omegaconf import OmegaConf

def resolve_tuple(*args):
    return tuple(args)

OmegaConf.register_new_resolver('as_tuple', resolve_tuple)

@hydra.main(config_path='conf', config_name='config')
def main(cfg):
    obj = hu.instantiate(cfg.obj, _convert_='partial')
    print(obj)

if __name__ == '__main__':
    main()
代码语言:javascript
运行
复制
# conf/config.yaml
defaults:
  - subdir: base
  - _self_

obj:
  a_tuple: ${subdir.my_tuple}
代码语言:javascript
运行
复制
# conf/subdir/base.yaml
my_tuple: ${as_tuple:1,2}
代码语言:javascript
运行
复制
$ python my_app.py  # at the command line:
{'a_tuple': (1, 2)}

这里的主要区别是我们使用的是a_tuple: ${subdir.my_tuple}而不是a_tuple: ${my_tuple}

备注:

在将来的某个时候,

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69651138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档