Lazy configurations for reproducible deep learning experiments.
Project description
Laco — Lazy Configuration for Reproducible ML
LAzy COnfiguration (Laco) is a Python-first configuration system that gives you type-checked, IDE-navigable configs with zero magic strings. It is compatible with Hydra and a drop-in alternative to hydra-zen.
Key ideas
| Construct | Static type | What you get |
|---|---|---|
L.call(T)(**kw) |
T |
lazy _target_: node |
L.partial(T)(**kw) |
functools.partial[T] |
lazy _partial_: true node |
L.just(obj) |
type(obj) |
identity-instantiated node |
L.required[T]() |
T |
MISSING sentinel |
class G(L.Group[T]) |
typed group | registers in Hydra ConfigStore |
@L.config class S |
dataclass schema | structured-config target |
@L.task |
task wrapper | auto-instantiates config fields |
@laco.main(config_name=…) |
Hydra app | composes config + runs task |
L.trace(lambda: …) |
R |
records a config tree from Python |
30-second example
import laco
import laco.language as L
from torch import nn, optim
# --- Groups: swappable variants ---
class OptimGroup(L.Group[optim.Optimizer]):
sgd = L.partial(optim.SGD)(lr=L.required[float](), momentum=0.9)
adam = L.partial(optim.Adam)(lr=1e-3)
# --- Schema: typed config ---
@L.config
class TrainSchema:
epochs: int = 10
optimizer: optim.Optimizer = L.slot(OptimGroup)
# --- Model ---
model_cfg = L.call(nn.Linear)(in_features=784, out_features=10)
# --- Task: runs with a composed config ---
@laco.main(config_name="train")
@L.task
def run(model: nn.Module, optimizer: optim.Optimizer, epochs: int = 10):
opt = optimizer(model.parameters())
# ... training loop ...
if __name__ == "__main__":
run()
Override from the CLI:
python train.py optimizer=adam epochs=20
python train.py -m optimizer=sgd,adam optimizer.lr=1e-2,1e-3 # multirun
Tracing
@L.configurable
class Encoder:
def __init__(self, depth: int) -> None: ...
# Records a config tree — no constructors run:
cfg = L.trace(lambda: Encoder(depth=24))
# Reproduce the object:
enc = laco.instantiate(cfg)
Examples
The sources/laco/examples/ directory contains a curriculum of examples:
| Tier | Files | What it demonstrates |
|---|---|---|
| 0–1 | mlp.py, linear_regression.py, cnn_classifier.py, text_classifier.py |
Basics: L.call, L.params, L.required |
| 2 | blocks/residual.py, blocks/transformer.py, blocks/decoder.py |
Building blocks |
| 3–4 | models/ |
Vision & language model configs |
| 5 | integrations/ |
Lightning, Transformers, TensorDict |
| 6 | pipelines/mnist_train.py, pipelines/clm_finetune.py |
End-to-end training pipelines with @L.task |
Typed-group variants live in examples/typed/ (same models, @L.config + L.Group API).
CLI
laco compose configs/train.py # load & dump YAML
laco compose configs/train.py lr=1e-3 # with overrides
laco show configs/train.py --groups # list registered groups
laco run configs/train.py # run the @L.task entry point
laco diff configs/a.py configs/b.py # diff two config files
laco app my-project train --lr 1e-4 # run a laco.apps entry point
laco app — simple argparse CLI for published configs
Researchers and collaborators can reproduce experiments without knowing Hydra:
laco app my-project train --help # show all available flags
laco app my-project train --lr 1e-4 # override a hyperparameter
laco app my-project train --dry-run # preview resolved config as YAML
laco app my-project train --save-dir out/ # save config.yaml before running
Flags are derived from @L.params blocks and L.param() declarations in
the config file. Authors register the entry point in pyproject.toml:
[project.entry-points."laco.apps"]
train = "my_project.train:run"
See docs/how-to/laco-app.md for the full author and user guide.
Migration from 0.x
Add import laco.compat once at startup to enable deprecation warnings
for legacy _target_: laco.ops.partial configs. Run laco fix <dir> to
rewrite them in-place.
Linting
Two lint passes run in CI and are available locally:
nix run .#lint— ruff oversources/andtests/.nix run .#lie-lint(orlaco-lint sources/) — LACO001, a heuristic AST check for attribute access on lie-typed Laco nodes. Suppress with# noqa: LACO001.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file laco-1.0.0.tar.gz.
File metadata
- Download URL: laco-1.0.0.tar.gz
- Upload date:
- Size: 412.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.11","id":"zokor","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
345d4d456d94bee7c2a882b998d7d0609e5a3bbe3a7bc8b8e6964771a786ea18
|
|
| MD5 |
ac2f12b567f0a00fd4e89242b6c3e2c0
|
|
| BLAKE2b-256 |
e091daf63ceb7495b278c880be8cafa68e0666465379dc6a785b7288ca0ec78e
|
File details
Details for the file laco-1.0.0-py3-none-any.whl.
File metadata
- Download URL: laco-1.0.0-py3-none-any.whl
- Upload date:
- Size: 104.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.11","id":"zokor","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6889acf731c416349a7b50e7925df38ce804c06344ecaa4e3a81e9ea6a09d8c
|
|
| MD5 |
32dfb90d728ab62152c37199d1a218cc
|
|
| BLAKE2b-256 |
59b91b5e2d237ccc6200177834a12920b7e7c6750f4903b2b42a184dc3377b32
|