Skip to main content

Slayer of Hydra

Project description

Heracls - Slayer of Hydra

heracls is a tiny utility package to instantiate typed dataclasses from flexible config sources (dictionary, OmegaConf, YAML, dotlist, CLI, ...). It is designed for projects that want strict, typed config objects while supporting the dynamic overrides commonly used in scripts and experiments.

Installation

The heracls package is available on PyPi and can be installed with pip.

pip install heracls

Alternatively, if you need the latest features, you can install it from source.

pip install git+https://github.com/francois-rozet/heracls

Getting started

The following example demonstrates how to declare a nested dataclass config, instantiate it from command line arguments, serialize it to YAML, and use it in a script. The heracls.ArgumentParser is a thin wrapper around simple-parsing, which populates the parser arguments from the config structure and types.

import heracls

from dataclasses import dataclass, field
from typing import Literal, Tuple, Union

@dataclass
class ModelConfig:
    depth: int = 3
    width: int = 256

@dataclass
class AdamConfig:
    name: Literal["adam"] = "adam"
    betas: Tuple[float, float] = (0.95, 0.95)
    learning_rate: float = 1e-3
    weight_decay: float = 0.0

@dataclass
class SGDConfig:
    name: Literal["sgd"] = "sgd"
    momentum: float = 0.0
    learning_rate: float = 1e-3
    weight_decay: float = 0.0

@dataclass
class TrainConfig:
    model: ModelConfig = field(default_factory=ModelConfig)
    optimizer: Union[AdamConfig, SGDConfig] = heracls.choice(
        {"adam": AdamConfig, "sgd": SGDConfig},
        default="adam",
    )
    dataset: str = "mnist"
    data_splits: Tuple[float, float] = (0.8, 0.1)
    n_epochs: int = 1024
    n_steps_per_epoch: int = 256

def main():
    parser = heracls.ArgumentParser()
    parser.add_argument("--dry", action="store_true", help="dry run")
    parser.add_arguments(TrainConfig, "train")

    args = parser.parse_args()

    print(heracls.to_yaml(args.train))

    if args.dry:
        return

    trainset, validset, testset = load_dataset(args.train.data_splits)

    for epoch in range(args.train.n_epochs):
        ...

if __name__ == "__main__":
    main()
$ python train.py --dry --depth 5 --optimizer sgd --data_splits 0.7 0.2
model:
  depth: 5
  width: 256
optimizer:
  name: sgd
  momentum: 0.0
  learning_rate: 0.001
  weight_decay: 0.0
dataset: mnist
data_splits:
- 0.7
- 0.2
n_epochs: 1024
n_steps_per_epoch: 256
$ python train.yaml --help
usage: train.py [-h] [--dry] [--optimizer {adam,sgd}] [--dataset str] [--data_splits float float] [--n_epochs int]
                [--n_steps_per_epoch int] [--depth int] [--width int] [--name {adam}] [--betas float float]
                [--learning_rate float] [--weight_decay float]

options:
  -h, --help                 show this help message and exit
  --dry                      dry run (default: False)

TrainConfig ['train']:
  TrainConfig(model: __main__.ModelConfig = <factory>, optimizer: Union[__main__.AdamConfig, __main__.SGDConfig] = <factory>, dataset: str = 'mnist', data_splits: Tuple[float, float] = (0.8, 0.1), n_epochs: int = 1024, n_steps_per_epoch: int = 256)

  --optimizer {adam,sgd}     (default: adam)
  --dataset str              (default: mnist)
  --data_splits float float  (default: (0.8, 0.1))
  --n_epochs int             (default: 1024)
  --n_steps_per_epoch int    (default: 256)

ModelConfig ['train.model']:
  ModelConfig(depth: int = 3, width: int = 256)

  --depth int                (default: 3)
  --width int                (default: 256)

AdamConfig ['train.optimizer']:
  AdamConfig(name: Literal['adam'] = 'adam', betas: Tuple[float, float] = (0.95, 0.95), learning_rate: float = 0.001, weight_decay: float = 0.0)

  --name {adam}              (default: adam)
  --betas float float        (default: (0.95, 0.95))
  --learning_rate float      (default: 0.001)
  --weight_decay float       (default: 0.0)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

heracls-0.2.0.tar.gz (6.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

heracls-0.2.0-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file heracls-0.2.0.tar.gz.

File metadata

  • Download URL: heracls-0.2.0.tar.gz
  • Upload date:
  • Size: 6.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.15 {"installer":{"name":"uv","version":"0.9.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for heracls-0.2.0.tar.gz
Algorithm Hash digest
SHA256 11c514e33c183c160f4127aeb4cbeff2212b924471c40f4eb07ce31a36f58262
MD5 f9d1f0e0ecb69ff22ce53444064bfcce
BLAKE2b-256 d93c863573aa6a551dc82e96e0778922998901eab63ae7e06131b35ff0e3b46e

See more details on using hashes here.

File details

Details for the file heracls-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: heracls-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.15 {"installer":{"name":"uv","version":"0.9.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for heracls-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8a4f380e265775b0e35f74258dc439f9a89f1b8f327384612ab53de434ec4eb9
MD5 ea4cc3abbfdc3c4bdbee38b1c5cbeb6b
BLAKE2b-256 4e7be91aeb5056cb517811a0d2d5e681d20d39a74d64b9bed5f20137d2841ae2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page