eladrich / pyrallis

Pyrallis is a framework for structured configuration parsing from both cmd and files. Simply define your desired configuration structure as a dataclass and let pyrallis do the rest!
https://eladrich.github.io/pyrallis/
MIT License
189 stars 7 forks source link

idiomatic way to choose and init sub-config during parsing #13

Closed Howuhh closed 2 years ago

Howuhh commented 2 years ago

I would like to be able to choose a model config if there are several different models. Example:

# main.py
@dataclass
class Model0Config:
    input_dim: int = 32
    output_dim: int = 32
    hidden_dim: int = 32

@dataclass
class Model1Config:
    input_dim: int = 32
    some_other_arg: str = "test_arg"

class ModelConfigs(Enum):
    model0 = Model0Config
    model1 = Model1Config

@dataclass
class TrainConfig:
    wandb_name: str = "some default name"
    model_config: ModelConfigs = field(default=ModelConfigs.model0)

Problem here is than I cannot setup sub-config for model is this way, as this will raise an error:

python main.py --model_config=model1 --model_config.input_dim=128

How would you implement something like this? Perhaps there is some other way? Thanks!

eladrich commented 2 years ago

Hi @Howuhh, that's a great question and it's actually a pattern we considered when designing pyrallis. Unfortunately, after some thought, we decided that dynamically choosing sub-configs would overcomplicate pyrallis and would be problematic for static analysis of the configuration, and is therefore not supported.

My advice would be to either to go with a slightly different design or check out more advanced configuration libraries such as hydra which might be more suited for such usecases.

As to a pyrallis-compatible design, one can define ModelConfigs as a regular subconfig where each model has it's own set of parameters and possibly put duplicated parameters that have the same initialization values directly in model_config.

python main.py --model_config=model_b --model_config.input_dim=12 --model_config.model_b.some_other_arg=arg_value 
Howuhh commented 2 years ago

Make sense! Thanks for the answer, I will stick with that design