2

I instantiate a hydra configuration from a python dataclass. For example

from dataclasses import dataclass
from typing import Any
from hydra.utils import instantiate

class Model():
    def __init__(self, x=1):
        self.x = x

@dataclass
class MyConfig:
    model: Any
    param: int

static_config = MyConfig(model=Model(x=2), param='whatever')
instantiated_config = instantiate(static_config)

Now, I would like to dump this configuration as a yaml, including the _target_ fields that Hydra uses to re-instantiate the objects pointed to inside the configuration. I would like to avoid having to write my own logic to write those _target_ fields, and I imagine there must be some hydra utility that does this, but I can't seem to find it in the documentation.

Mike
  • 444
  • 1
  • 8
  • 19
  • Your example `static_config` does not have a `_target_` field. – Jasha Apr 21 '22 at 09:15
  • @Jasha exactly, that's what I'm hoping there is a utility for. I don't want to manually write yaml files with`_target_` fields. Instead, I am hoping that a config that is loaded from a data class (that has inner python objects already instantiated), can somehow be dumped into a yaml with the `_target_` fields appropriately entered based on where the objects have been initiated from. I could try to engineer this myself, but the objects inside the config can be nested arbitrarily deeply, and I'm hoping a hydra dev has already solved this problem. – Mike Apr 21 '22 at 17:51

1 Answers1

1

See OmegaConf.to_yaml and OmegaConf.save:

from omegaconf import OmegaConf

# dumps to yaml string
yaml_data: str = OmegaConf.to_yaml(my_config)

# dumps to file:
with open("config.yaml", "w") as f:
    OmegaConf.save(my_config, f)

# OmegaConf.save can also accept a `str` or `pathlib.Path` instance:
OmegaConf.save(my_config, "config.yaml")

See also the Hydra-Zen project, which offers automatic generation of OmegaConf objects (which can be saved to yaml).

Jasha
  • 5,507
  • 2
  • 33
  • 44
  • Thank you for the answer. When I run the following given my sample code `OmegaConf.to_yaml(instantiated_config)` I get the following string `'model: !!python/object:__main__.Model\n x: 2\nparam: 2\n'` I haven't delved too deeply into OmegaConf and what syntax/conventions it uses to reference python objects, it looks like the Hydra team has used the `!!python/object ...` syntax to build their `_target_` functionality. I am hoping to actually output a yaml that uses the `_target_` fields instead of this `!!python/object` notation. – Mike Apr 21 '22 at 17:57
  • 1
    If I understand correctly, you'd like the `_target_` to be automatically generated based on the type of the object. `OmegaConf.to_yaml` is not really designed for serializing arbitrary python objects; it is designed for serializing OmegaConf objects such as `DictConfig` or `ListConfig`. You might want to check out the [Hydra-Zen](https://github.com/mit-ll-responsible-ai/hydra-zen) project, which offers automatic generation of OmegaConf objects (which can be saved to yaml). – Jasha Apr 21 '22 at 18:06
  • Wow, the very first page of the Hydra-Zen documentation answers precisely my question, how to do it in Hydra, and on top of it how they try to simplify that. Thanks! Technically that link is the answer, but I'll accept your answer here unless you feel like re-writing a one-liner with this link for other people to notice faster. – Mike Apr 21 '22 at 18:20
  • I'm glad you found what you needed! I've added the link to the answer above. – Jasha Apr 21 '22 at 18:53
  • Why is this an accepted answer? It doesn't answer the question. `to_yaml` won't produce `_target_` fields. – ubadub May 10 '23 at 13:47