-
-
Notifications
You must be signed in to change notification settings - Fork 609
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
Replace dictionary (instead of merging) from command line #2091
Comments
@slerman12 usually writing |
I thought I did, but I will try to be more specific for you. Create a import hydra
@hydra.main(config_path='./', config_name='Config')
def main(args):
pass
if __name__ == '__main__':
main() Then create a
Now run the following:
And the issue I am having is that I do not know how to standardly pass in a dict argument and have a default one defined in my config yaml at the same time, as above. I get the following error:
Hope that's clearer. |
Got it, thanks for the additional details. I am having success with the following:
The difference here is that I've used a plus symbol before To see why this is necessary, take a look at the error message that results from not using a plus:
Hydra has been designed to prevent accidentally adding new keys to the config via CLI overrides. Since the key See the Hydra docs on quoted values for more tips on CLI overrides. |
Note also that in this case, all three of the following are equivalent:
The last two are equivalent because the CLI override gets merged into the contents of |
Oh... this is not the desired behavior though. I need to be able to override the default argument completely. I don't want to have to ask the user to redeclare I also have a second question, as listed in my original post, but for now I'm mostly concerned about just this basic use case. |
Can you tell me how Hydra or OnegaConf processes the argument in the case where the Config.yaml file is as follows:
In this case I get the desired behavior from running:
|
Essentially, Hydra works by calling >>> config_yaml = OmegaConf.create("argument: null")
>>> cli_overrides = OmegaConf.create("argument: {aaa: {bbb: 1, ccc: 2}, ddd: {eee: 3}}")
>>> composed_config = OmegaConf.merge(config_yaml, cli_overrides)
>>> print(composed_config)
{'argument': {'aaa': {'bbb': 1, 'ccc': 2}, 'ddd': {'eee': 3}}} To give another example, here is the case where initially >>> config_yaml = OmegaConf.create("argument: {aaa: {bbb: 1, ccc: 2}}")
>>> cli_overrides = OmegaConf.create("argument: {ddd: {eee: 3}}")
>>> composed_config = OmegaConf.merge(config_yaml, cli_overrides)
>>> print(composed_config)
{'argument': {'aaa': {'bbb': 1, 'ccc': 2}, 'ddd': {'eee': 3}}}
Hmm, I see. So you want I don't think it's possible to achieve this exact user experience with Hydra presently, though a few things do come to mind which might bring you closer to that target:
Deleting
Note that order of CLI args matters:
|
Sorry I missed the second question. Yes, you can pass variable interpolations via the command line. Here is a working example: # run.py
import hydra
@hydra.main(config_path='./', config_name='Config')
def main(args):
print(args)
print(f"{args.argument.aaa=}")
if __name__ == '__main__':
main() # Config.yaml
variable: "foo"
argument: null
hydra:
job:
chdir: True
|
I just made the default a string
and do the following in-code:
That way, the user can provide a dict as argument and override the default, or otherwise the default gets translated into a dict anyway. |
Hi, I'm also trying to figure out how to replace a dict rather than merge. A typical use case is that you have, say, two learning rate schedulers that take different arguments, and you want to override one with another. I guess one solution could be to put the different schedulers into different subconfigs and use the defaults list, and maybe that is fine as a solution, but some people in our organization were wanting to do an override when they hadn't used the defaults list this way. If it seems like a valid use case to you, a possible way to implement it would be that if a dict has the From the command line, deleting and then adding a new dict works, as you suggest @Jasha10. It's just a question of how to do it from YAML. |
Related is issue #2227. |
I define a default value for an argument, let's call it
argument
, as a dict in myConfig.cfg
file:argument: {aaa: {bbb: 1, ccc: 2}}
Then I try to pass a different dict as an argument via the command line:
argument="{aaa: {bbb: 1, ccc: 2}, ddd: {eee: 3}}"
And. I get this error:
Could not override 'argument'. To append to your config use +argument={aaa: {bbb: 1, ccc: 2}, ddd: {eee: 3}}
I have two questions:
argument="{aaa: {bbb: ${variable1}, ccc: 2}, ddd: {eee: 3}}"
?The text was updated successfully, but these errors were encountered: