Base Configurations#

We can integrate tyro.cli() into common configuration patterns: here, we select one of multiple possible base configurations, create a subcommand for each one, and then use the CLI to either override (existing) or fill in (missing) values.

 1from dataclasses import dataclass
 2from typing import Callable, Literal
 3
 4from torch import nn
 5
 6import tyro
 7
 8
 9@dataclass(frozen=True)
10class AdamOptimizer:
11    learning_rate: float = 1e-3
12    betas: tuple[float, float] = (0.9, 0.999)
13
14
15@dataclass(frozen=True)
16class ExperimentConfig:
17    # Dataset to run experiment on.
18    dataset: Literal["mnist", "imagenet-50"]
19
20    # Optimizer parameters.
21    optimizer: AdamOptimizer
22
23    # Model size.
24    num_layers: int
25    units: int
26
27    # Batch size.
28    batch_size: int
29
30    # Total number of training steps.
31    train_steps: int
32
33    # Random seed. This is helpful for making sure that our experiments are all
34    # reproducible!
35    seed: int
36
37    # Activation to use. Not specifiable via the commandline.
38    activation: Callable[[], nn.Module]
39
40
41# Note that we could also define this library using separate YAML files (similar to
42# `config_path`/`config_name` in Hydra), but staying in Python enables seamless type
43# checking + IDE support.
44Configs = tyro.extras.subcommand_type_from_defaults(
45    {
46        "small": ExperimentConfig(
47            dataset="mnist",
48            optimizer=AdamOptimizer(),
49            batch_size=2048,
50            num_layers=4,
51            units=64,
52            train_steps=30_000,
53            seed=0,
54            activation=nn.ReLU,
55        ),
56        "big": ExperimentConfig(
57            dataset="imagenet-50",
58            optimizer=AdamOptimizer(),
59            batch_size=32,
60            num_layers=8,
61            units=256,
62            train_steps=100_000,
63            seed=0,
64            activation=nn.GELU,
65        ),
66    }
67)
68
69if __name__ == "__main__":
70    config = tyro.cli(Configs)
71    print(config)

python 03_config_systems/01_base_configs.py --help
usage: 01_base_configs.py [-h] {small,big}

╭─ options ──────────────────────────────────────────╮
│ -h, --help         show this help message and exit │
╰────────────────────────────────────────────────────╯
╭─ subcommands ──────────────────────────────────────╮
│ {small,big}                                        │
│     small                                          │
│     big                                            │
╰────────────────────────────────────────────────────╯

python 03_config_systems/01_base_configs.py small --help
usage: 01_base_configs.py small [-h] [SMALL OPTIONS]

╭─ options ──────────────────────────────────────────────────────────────────╮
│ -h, --help              show this help message and exit                    │
│ --dataset {mnist,imagenet-50}                                              │
│                         Dataset to run experiment on. (default: mnist)     │
│ --num-layers INT        Model size. (default: 4)                           │
│ --units INT             Model size. (default: 64)                          │
│ --batch-size INT        Batch size. (default: 2048)                        │
│ --train-steps INT       Total number of training steps. (default: 30000)   │
│ --seed INT              Random seed. This is helpful for making sure that  │
│                         our experiments are all reproducible! (default: 0) │
│ --activation {fixed}    Activation to use. Not specifiable via the         │
│                         commandline. (fixed to: <class                     │
│                         'torch.nn.modules.activation.ReLU'>)               │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ optimizer options ────────────────────────────────────────────────────────╮
│ Optimizer parameters.                                                      │
│ ────────────────────────────────────────────                               │
│ --optimizer.learning-rate FLOAT                                            │
│                         (default: 0.001)                                   │
│ --optimizer.betas FLOAT FLOAT                                              │
│                         (default: 0.9 0.999)                               │
╰────────────────────────────────────────────────────────────────────────────╯

python 03_config_systems/01_base_configs.py small --seed 94720
ExperimentConfig(dataset='mnist', optimizer=AdamOptimizer(learning_rate=0.001, betas=(0.9, 0.999)), num_layers=4, units=64, batch_size=2048, train_steps=30000, seed=94720, activation=<class 'torch.nn.modules.activation.ReLU'>)

python 03_config_systems/01_base_configs.py big --help
usage: 01_base_configs.py big [-h] [BIG OPTIONS]

╭─ options ──────────────────────────────────────────────────────────────────╮
│ -h, --help              show this help message and exit                    │
│ --dataset {mnist,imagenet-50}                                              │
│                         Dataset to run experiment on. (default:            │
│                         imagenet-50)                                       │
│ --num-layers INT        Model size. (default: 8)                           │
│ --units INT             Model size. (default: 256)                         │
│ --batch-size INT        Batch size. (default: 32)                          │
│ --train-steps INT       Total number of training steps. (default: 100000)  │
│ --seed INT              Random seed. This is helpful for making sure that  │
│                         our experiments are all reproducible! (default: 0) │
│ --activation {fixed}    Activation to use. Not specifiable via the         │
│                         commandline. (fixed to: <class                     │
│                         'torch.nn.modules.activation.GELU'>)               │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ optimizer options ────────────────────────────────────────────────────────╮
│ Optimizer parameters.                                                      │
│ ────────────────────────────────────────────                               │
│ --optimizer.learning-rate FLOAT                                            │
│                         (default: 0.001)                                   │
│ --optimizer.betas FLOAT FLOAT                                              │
│                         (default: 0.9 0.999)                               │
╰────────────────────────────────────────────────────────────────────────────╯

python 03_config_systems/01_base_configs.py big --seed 94720
ExperimentConfig(dataset='imagenet-50', optimizer=AdamOptimizer(learning_rate=0.001, betas=(0.9, 0.999)), num_layers=8, units=256, batch_size=32, train_steps=100000, seed=94720, activation=<class 'torch.nn.modules.activation.GELU'>)