Skip to content

Merging/overriding configs with same format in monai bundle run #5899

Closed
@surajpaib

Description

@surajpaib

Is your feature request related to a problem? Please describe.
Currently, overriding config can be done through an args_file argument pointing to a json/yaml provided to the run script. However, it only merges configs at the base level, and to override nested structures, the # format must be used.

Example,

monai.bundle.run("", **{
    "args_file": "./config2.json",
    "config_file": "./config1.json", 
    
})
```
config1.json
```
{
    "trainer":
    {
        "max_epochs": 5

    }
}
```
config2.json
```
{
    "trainer#devices": 1
}

This gives the output,

[{'_meta_': {}, 'trainer': {'max_epochs': 5, 'devices': 1}}]

However, if the config provided to args_file is in the same format (shown below) as the config_file, it does not do the merge,

```
config2.json
```
{
    "trainer":
    {
        "devices": 1

    }
}

Describe the solution you'd like
It would be beneficial to have the ability to merge these two configs when they are in the same format to allow for use cases where a default config is set to have good parameter definitions, and the user only needs to define/override specific fields.

Describe alternatives you've considered
I tried specifying two of these configs as a list in this form as well,

monai.bundle.run("", **{
    "config_file": ["./config1.json", "./config2.json"], 
    
})

But it doesn't seem to handle overriding keys, although it merges non-conflicting keys.

My temporary fix
To achieve the functionality I needed, I've changed the following,

def update(self, pairs: dict[str, Any]):

to

    def update(self, pairs: dict[str, Any]):
        """
        Set the ``id`` and the corresponding config content in pairs, see also :py:meth:`__setitem__`.
        For example, ``parser.update({"train#epoch": 100, "train#lr": 0.02})``

        Args:
            pairs: dictionary of `id` and config pairs.

        """
        for k, v in pairs.items():
            if isinstance(v, dict):
                self.update({f'{k}#{_k}': _v for _k, _v in v.items()})
                return 
                
            self[k] = v

Additional context
Ideally, it would be nice to have the ability to merge configs in the config_file list. Is there a way to do this, and am potentially missing something?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions