Declarative hyperparameter management for ML/AI experiments...
Declarative hyperparameter management for ML experiments with automatic CLI generation.
pip install params-proto==3.2.0
| Decorator | Purpose | Access Pattern |
|---|---|---|
@proto.cli |
CLI entry point | Parses sys.argv automatically |
@proto.prefix |
Singleton config | ClassName.attr (class-level) |
@proto |
Multi-instance | instance.attr (object-level) |
from params_proto import proto
@proto.cli
def train(
lr: float = 0.001, # Learning rate (inline comment = help text)
batch_size: int = 32, # Batch size
epochs: int = 100, # Number of epochs
):
"""Train a model.""" # Docstring = CLI description
print(f"Training with lr={lr}")
if __name__ == "__main__":
train()
python train.py --lr 0.01 --batch-size 64
python train.py --help
@proto.prefix
class Model:
name: str = "resnet50" # Architecture
dropout: float = 0.5 # Dropout rate
@proto.prefix
class Training:
lr: float = 0.001 # Learning rate
epochs: int = 100 # Epochs
@proto.cli
def main(seed: int = 42):
"""Train with namespaced config."""
print(f"Model: {Model.name}, LR: {Training.lr}")
# CLI: python train.py --model.name vit --training.lr 0.01
from params_proto import proto, EnvVar
@proto.cli
def train(
lr: float = EnvVar @ "LEARNING_RATE" | 0.001, # Env var with default
api_key: str = EnvVar @ "API_KEY", # Required env var (no default)
# OR operation: try multiple env vars in order
token: str = EnvVar @ "API_TOKEN" @ "AUTH_TOKEN" | "default",
): ...
from dataclasses import dataclass
@dataclass
class Adam:
lr: float = 0.001
beta1: float = 0.9
@dataclass
class SGD:
lr: float = 0.01
momentum: float = 0.9
@proto.cli
def train(optimizer: Adam | SGD):
"""Train with selected optimizer."""
print(f"Using {type(optimizer).__name__}")
# CLI: python train.py adam --lr 0.001
# CLI: python train.py sgd --momentum 0.95
from params_proto.hyper import piter
# Zip (default): pairs values element-wise
configs = piter @ {"lr": [0.001, 0.01], "batch_size": [32, 64]}
# 2 configs: (0.001, 32), (0.01, 64)
# Cartesian product with * (only first needs piter @)
configs = piter @ {"lr": [0.001, 0.01]} * {"batch_size": [32, 64]}
# 4 configs: all combinations
# Override with fixed values using %
configs = piter @ {"lr": [0.001, 0.01]} * {"batch_size": [32, 64]} % {"seed": 42}
# Repeat for multiple trials using **
configs = (piter @ {"lr": [0.001, 0.01]}) ** 3 # 2 configs x 3 trials
for config in configs:
train(**config)
| Type | CLI Display | Example |
|---|---|---|
int |
INT |
count: int = 10 |
float |
FLOAT |
lr: float = 0.001 |
str |
STR |
name: str = "default" |
bool |
BOOL |
debug: bool = False |
Enum |
{A,B,C} |
opt: Optimizer = Optimizer.ADAM |
Literal |
VALUE |
mode: Literal["a", "b"] = "a" |
List[T] |
VALUE |
ids: List[int] = [1, 2] |
Tuple[T, ...] |
VALUE |
dims: Tuple[int, ...] = (224, 224) |
Optional[T] |
VALUE |
path: str | None = None |
@proto.cli
def train(
verbose: bool = False, # --verbose sets True
cuda: bool = True, # --no-cuda sets False
): ...
Config.lr = 0.01)with proto.bind(Config, lr=0.01): ...)Config._dict # โ {'lr': 0.001, 'batch_size': 32}
dict(Config) # โ same (works for classes and functions)
For detailed documentation, see: