Migrate from argparse
Migrate from argparse
Tutorial: Why Laco?See also: Getting Started
Before: argparse
# train.py (argparse version)
import argparse, torch, torch.nn as nn
def main():
p = argparse.ArgumentParser()
p.add_argument("--lr", type=float, default=1e-3)
p.add_argument("--hidden", type=int, default=256)
p.add_argument("--epochs", type=int, default=10)
args = p.parse_args()
model = nn.Sequential(
nn.Linear(784, args.hidden),
nn.ReLU(),
nn.Linear(args.hidden, 10),
)
optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)
for epoch in range(args.epochs):
... # training loop
if __name__ == "__main__":
main()
Step 1: Extract Hyperparameters
Create a config file with @L.params for the scalar hyperparameters:
# configs/train.py
import laco.language as L
import torch.nn as nn, torch.optim as optim
@L.params
class hps:
lr: float = 1e-3
hidden: int = 256
epochs: int = 10
model = L.call(nn.Sequential)(
L.call(nn.Linear)(in_features=784, out_features=hps.hidden),
L.call(nn.ReLU)(),
L.call(nn.Linear)(in_features=hps.hidden, out_features=10),
)
optimizer = L.partial(optim.Adam)(lr=hps.lr)
Step 2: Load and Instantiate
# train.py
import laco
cfg = laco.load("configs/train.py")
model = laco.instantiate(cfg.model)
optimizer_factory = laco.instantiate(cfg.optimizer)
optimizer = optimizer_factory(params=model.parameters())
epochs = cfg.hps.epochs
Override from CLI:
python train.py # uses defaults
laco run configs/train.py hps.lr=5e-4 hps.hidden=512
Step 3: Add @L.task
# configs/train.py (updated)
import laco.language as L
import torch.nn as nn, torch.optim as optim
@L.params
class hps:
lr: float = 1e-3
hidden: int = 256
epochs: int = 10
model = L.call(nn.Sequential)(
L.call(nn.Linear)(in_features=784, out_features=hps.hidden),
L.call(nn.ReLU)(),
L.call(nn.Linear)(in_features=hps.hidden, out_features=10),
)
optimizer = L.partial(optim.Adam)(lr=hps.lr)
@L.task
def task(model, optimizer, hps):
opt = optimizer(params=model.parameters())
for epoch in range(hps.epochs):
... # training loop
laco run configs/train.py hps.lr=5e-4
Step 4: Full Hydra App (Optional)
# train.py
import laco
def run(model, optimizer, hps): ...
if __name__ == "__main__":
laco.main("train", config_path="configs")(run)()
python train.py hps.lr=5e-4
python train.py -m hps.lr=1e-3,1e-4 # sweep
Common Pitfalls
- Hard-coded class strings: replace
"torch.nn.ReLU"magic strings with real imports:L.call(nn.ReLU)(). - Mutable defaults: use
L.call(list)()instead ofdefault=[]in@L.params. - Positional args:
@L.taskskips*args; use keyword-only params.