-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support merge keys (YAML >> tag), also with interpolation #469
Comments
This looks like a bug. we will have to take a closer look.
This is not happening. pyyaml is handling tag merging at load time. it will not know how to handle with the OmegaConf interpolation. because pyyaml is handling tags at load time, it cannot support merging across different config files. Same way it cannot support accessing anchors from different config files (this is actually the primary reason OmegaConf have interpolation). |
Your entire bug report does not talk about lists. then you pop them up in the alternative. |
OK yeah that should've been obvious if I'd only thought about it for another minute... :) Let me rephrase the feature request then: is there any conceivable way of combining interpolation with a key merge in OmegeConf? I would like to compose a config section by merging in previously defined sections, then adding or overriding some keys. Exactly what the
Yeah sorry, that was inspired by your suggestion in #442, and then I elided the explanation... let me backtrack. What I'd really like is to be able to merge two configs: file1.yml
and file2.yml:
The only workaround I can think of at present is:
...and then have explicit code in the application itself which loops over the elements of |
Having looked a bit, it looks like the yaml loaded OmegaConf is using is messing up with the merge loader. that's not intentional but after spending 30 minutes trying to fix it I am officially parking it. I don't have time for it at the moment.
pyyaml doing everything in load times means it's hostile to mixing with things that happens afterwards. OmegaConf supports that directly via an API. cfg = OmegaConf.create({"foo": {"bar" : 10}})
OmegaConf.merge(cfg, {"foo": {"X" : 20}})
# {'foo': {'bar': 10, 'X': 20}} Or via the somewhat internal merge_with: cfg = OmegaConf.create({"foo": {"bar" : 10}})
cfg.foo.merge_with({"x": 20})
# {'foo': {'bar': 10, 'x': 20}} |
Yeah I was playing with that too... but then it's the application code then that has to decide which sections to merge in. If I go back to the single-file YML example using anchors: a1: &FOO
x: 1
y: 2
a2: &BAR
x: 'a'
y: 'b'
b:
<<: *FOO
y: 3 ...whether the "base section" for I suppose I could have the application scan the whole config for a magic key in each section, and trigger a merge based on its value. Something like: b:
_merge: a1 ...would work. Anyway, I just wanted to check if you thought it was simple or worthwhile adding this functionality to the core omegaconf... which from the sound of it it isn't. |
If you aren't using it, I suggest you take a look at Hydra. Can you please file a separate clean bug report for the tag issue? I think we can close this feature request once you do. |
I did start with Hydra actually, but it wasn't quite right for the job, but that led me to omegaconf, which is elegant, and already practically perfect. Thanks for a very useful library, by the way (I should have started with this)! It was actually a quick job to add a function to the app code to recursively scan the config and act on "_merge" keys. So this now works for me and I'm very happy with it. Even the syntax feels similar to a1:
x: 1
a2:
y: 2
b:
_merge: a1, a2
z: 3 There's only one wrinkle: iterating over |
Bug is #470. |
Once you get to do config composition like that you are going to hit some internal functions. I do not plan to promote the special iterators to be a public API at this time but you should feel comfortable relaying on them. (Hydra is also using them). I would be happy to hear what you think about Hydra 1.1 upcoming support for nested default lists. Keep in mind that the support in Hydra need to meet a very high quality bar (specifically, it needs to play out properly with everything else Hydra is doing and should be very well tested). This is significantly more powerful than your current |
Looks very powerful... still trying to wrap my head around all of it, so I'll just have to ponder it into next year... If I understand correctly though, the composition in Hydra only happens at the I think I'm converging on a nice solution with just omegaconf though. And now I see you've even implemented relative interpolation targets, wonderful! Anyway, thanks for all the help, and down with 2020! |
The definition of the composition can only happen in the defaults. this is the alternative to having scattered merge magic in config file. In terms of expressive power, this is similar because it let's you compose into a specific package (the terminology in Hydra for the path in the config). That single list is used by starting with an empty config and then calling Another advantage of Hydra is that the config discovery is abstracted from the process. Hydra supports a config search path and configs can be in the file system, in Python packages and also in the config store (which is an in-memory store typically used to store Structured Configs acting as schema).
Yup, this makes interpolation more practical in the presence of dynamic composition :).
Happy new year! |
Hi @omry, Is there a way to use the interpolation in the same config file, with merge? I am unable to find the correct syntax. What I want is the omegaconf syntax for regular YAML merge. I am using interpolations in the same file. Example: main_config: &main
seed: 42
device: cuda
train_config:
<<: *main
epochs: 2
optimizer: adam I'll appreciate any help with this. Thanks, |
yaml merge is a load time feature and interpolation is a runtime feature. The only equivalent to yaml merge is OmegaConf.merge(), which is an API you have to call in your code. |
Hi @omry, Thanks a lot. I built omegaconf from source, and now I am facing an issue with variable interpolation (it doesn't work), even when there is no merge syntax used. Is this expected? |
Since it has nothing at all to do with this issue, can you not hijack it? |
Is your feature request related to a problem? Please describe.
I would like to be able to merge one config section into another, and augment the result with new keys. In vanilla YAML, this is straightforwardly accomplished via anchors and the merge key tag. The following piece of code illustrates this:
results in
Loading the same YAML into omegaconf results in an exception:
Describe the solution you'd like
Well it would be nice if the vanilla YAML merge key worked. However, this whole anchor/alias business is rather clumsy. Top prize would be if this could work with the interpolation feature, like so:
Even better would be if this worked across a merge of configs (similar to what's discussed in #442). I.e.
Describe alternatives you've considered
I could use lists with nested mappings in them, and merge the keys in the code. Seems ugly though. I don't see any other way around it.
Additional context
Current onegaconf master, python 3.6.9.
The text was updated successfully, but these errors were encountered: