[{"data":1,"prerenderedAt":3777},["ShallowReactive",2],{"navigation":3,"api-navigation":184,"\u002Flearn\u002Fexamples\u002Fpipelines":206,"docyard:crossref-index":3776},[4,8,155,174,180],{"title":5,"path":6,"stem":7},"Getting Started","\u002Fgetting-started","1.getting-started",{"title":9,"path":10,"stem":11,"children":12},"Learn","\u002Flearn","2.learn",[13,15,66,99,133],{"title":9,"path":10,"stem":14},"2.learn\u002Findex",{"title":16,"path":17,"stem":18,"children":19},"Tutorials","\u002Flearn\u002Ftutorials","2.learn\u002F1.tutorials\u002Findex",[20,21,26,30,34,38,42,46,50,54,58,62],{"title":16,"path":17,"stem":18},{"title":22,"path":23,"stem":24,"icon":25},"Why Laco?","\u002Flearn\u002Ftutorials\u002Fwhy-laco","2.learn\u002F1.tutorials\u002F01.why-laco","i-lucide-notebook",{"title":27,"path":28,"stem":29,"icon":25},"First Steps with Laco","\u002Flearn\u002Ftutorials\u002Ffirst-steps","2.learn\u002F1.tutorials\u002F02.first-steps",{"title":31,"path":32,"stem":33,"icon":25},"Lazy Call and Partial","\u002Flearn\u002Ftutorials\u002Flazy-call-and-partial","2.learn\u002F1.tutorials\u002F03.lazy-call-and-partial",{"title":35,"path":36,"stem":37,"icon":25},"Hyperparameters and Interpolation","\u002Flearn\u002Ftutorials\u002Fhyperparameters-and-interpolation","2.learn\u002F1.tutorials\u002F04.hyperparameters-and-interpolation",{"title":39,"path":40,"stem":41,"icon":25},"Loading, Saving, and the CLI","\u002Flearn\u002Ftutorials\u002Floading-saving-cli","2.learn\u002F1.tutorials\u002F05.loading-saving-cli",{"title":43,"path":44,"stem":45,"icon":25},"Nested Configs and Containers","\u002Flearn\u002Ftutorials\u002Fnested-configs-and-containers","2.learn\u002F1.tutorials\u002F06.nested-configs-and-containers",{"title":47,"path":48,"stem":49,"icon":25},"Typed Groups and Schemas","\u002Flearn\u002Ftutorials\u002Ftyped-groups-and-schemas","2.learn\u002F1.tutorials\u002F07.typed-groups-and-schemas",{"title":51,"path":52,"stem":53,"icon":25},"Pipeline Configs","\u002Flearn\u002Ftutorials\u002Fpipeline-configs","2.learn\u002F1.tutorials\u002F08.pipeline-configs",{"title":55,"path":56,"stem":57,"icon":25},"Tasks and the App Loop","\u002Flearn\u002Ftutorials\u002Ftasks-and-app-loop","2.learn\u002F1.tutorials\u002F09.tasks-and-app-loop",{"title":59,"path":60,"stem":61,"icon":25},"Tracing","\u002Flearn\u002Ftutorials\u002Ftracing","2.learn\u002F1.tutorials\u002F10.tracing",{"title":63,"path":64,"stem":65,"icon":25},"Production Patterns","\u002Flearn\u002Ftutorials\u002Fproduction-patterns","2.learn\u002F1.tutorials\u002F11.production-patterns",{"title":67,"path":68,"stem":69,"children":70},"Concepts","\u002Flearn\u002Fconcepts","2.learn\u002F2.concepts\u002Findex",[71,72,76,80,84,88,92,95],{"title":67,"path":68,"stem":69},{"title":73,"path":74,"stem":75},"Config as Python","\u002Flearn\u002Fconcepts\u002Fconfig-as-python","2.learn\u002F2.concepts\u002F1.config-as-python",{"title":77,"path":78,"stem":79},"Lazy Construction","\u002Flearn\u002Fconcepts\u002Flazy-construction","2.learn\u002F2.concepts\u002F2.lazy-construction",{"title":81,"path":82,"stem":83},"Lie-Typing","\u002Flearn\u002Fconcepts\u002Flie-typing","2.learn\u002F2.concepts\u002F3.lie-typing",{"title":85,"path":86,"stem":87},"Interpolation","\u002Flearn\u002Fconcepts\u002Finterpolation","2.learn\u002F2.concepts\u002F4.interpolation",{"title":89,"path":90,"stem":91},"Typed Groups","\u002Flearn\u002Fconcepts\u002Ftyped-groups","2.learn\u002F2.concepts\u002F5.typed-groups",{"title":59,"path":93,"stem":94},"\u002Flearn\u002Fconcepts\u002Ftracing","2.learn\u002F2.concepts\u002F6.tracing",{"title":96,"path":97,"stem":98},"App Loop","\u002Flearn\u002Fconcepts\u002Fapp-loop","2.learn\u002F2.concepts\u002F7.app-loop",{"title":100,"path":101,"stem":102,"children":103},"How-To Guides","\u002Flearn\u002Fhow-to","2.learn\u002F3.how-to\u002Findex",[104,105,109,113,117,121,125,129],{"title":100,"path":101,"stem":102},{"title":106,"path":107,"stem":108},"Override Configs","\u002Flearn\u002Fhow-to\u002Foverride-configs","2.learn\u002F3.how-to\u002F1.override-configs",{"title":110,"path":111,"stem":112},"Safe Loading","\u002Flearn\u002Fhow-to\u002Fsafe-loading","2.learn\u002F3.how-to\u002F2.safe-loading",{"title":114,"path":115,"stem":116},"Custom Resolvers","\u002Flearn\u002Fhow-to\u002Fcustom-resolvers","2.learn\u002F3.how-to\u002F3.custom-resolvers",{"title":118,"path":119,"stem":120},"Lint and Strict Mode","\u002Flearn\u002Fhow-to\u002Flint-and-strict","2.learn\u002F3.how-to\u002F4.lint-and-strict",{"title":122,"path":123,"stem":124},"Publishing a reproducible app with laco app","\u002Flearn\u002Fhow-to\u002Flaco-app","2.learn\u002F3.how-to\u002F5.laco-app",{"title":126,"path":127,"stem":128},"Reproduce an Experiment","\u002Flearn\u002Fhow-to\u002Freproduce-experiment","2.learn\u002F3.how-to\u002F6.reproduce-experiment",{"title":130,"path":131,"stem":132},"Migrate from argparse","\u002Flearn\u002Fhow-to\u002Fmigrate-from-argparse","2.learn\u002F3.how-to\u002F7.migrate-from-argparse",{"title":134,"path":135,"stem":136,"children":137},"Examples Curriculum","\u002Flearn\u002Fexamples","2.learn\u002F4.examples\u002Findex",[138,139,143,147,151],{"title":134,"path":135,"stem":136},{"title":140,"path":141,"stem":142},"Foundation Examples","\u002Flearn\u002Fexamples\u002Ffoundations","2.learn\u002F4.examples\u002F1.foundations",{"title":144,"path":145,"stem":146},"Building Blocks","\u002Flearn\u002Fexamples\u002Fbuilding-blocks","2.learn\u002F4.examples\u002F2.building-blocks",{"title":148,"path":149,"stem":150},"Typed-Group Variants","\u002Flearn\u002Fexamples\u002Ftyped-variants","2.learn\u002F4.examples\u002F3.typed-variants",{"title":152,"path":153,"stem":154},"End-to-End Pipelines","\u002Flearn\u002Fexamples\u002Fpipelines","2.learn\u002F4.examples\u002F4.pipelines",{"title":156,"path":157,"stem":158,"children":159},"Resources","\u002Fresources","3.resources",[160,162,166,170],{"title":156,"path":157,"stem":161},"3.resources\u002Findex",{"title":163,"path":164,"stem":165},"Integrations","\u002Fresources\u002Fintegrations","3.resources\u002F1.integrations",{"title":167,"path":168,"stem":169},"Migration guide: Laco 0.x → 1.0","\u002Fresources\u002Fmigration-0.x-to-1.0","3.resources\u002F2.migration-0.x-to-1.0",{"title":171,"path":172,"stem":173},"Laco vs hydra-zen","\u002Fresources\u002Flaco-vs-hydra-zen","3.resources\u002F3.laco-vs-hydra-zen",{"title":175,"path":176,"stem":177,"children":178},"API Reference","\u002Fapi","4.api\u002Findex",[179],{"title":175,"path":176,"stem":177},{"title":181,"path":182,"stem":183},"Lazy Configuration for Python","\u002F","index",[185,188,191,194,197,200,203],{"title":186,"path":187},"cli","\u002Fapi\u002Fcli",{"title":189,"path":190},"compat","\u002Fapi\u002Fcompat",{"title":192,"path":193},"handler","\u002Fapi\u002Fhandler",{"title":195,"path":196},"keys","\u002Fapi\u002Fkeys",{"title":198,"path":199},"language","\u002Fapi\u002Flanguage",{"title":201,"path":202},"ops","\u002Fapi\u002Fops",{"title":204,"path":205},"utils","\u002Fapi\u002Futils",{"id":207,"title":152,"body":208,"description":287,"extension":3772,"meta":3773,"navigation":416,"path":153,"seo":3774,"stem":154,"__hash__":3775},"content\u002F2.learn\u002F4.examples\u002F4.pipelines.md",{"type":209,"value":210,"toc":3746},"minimark",[211,215,227,234,237,246,258,276,281,1675,1679,1694,1710,1728,1746,1769,1793,1809,1831,1849,1867,1875,1917,1935,1939,2114,2118,2281,2285,2377,2381,2425,2427,2435,2445,2459,2463,3226,3230,3270,3272,3276,3279,3286,3349,3354,3375,3382,3440,3446,3453,3557,3565,3569,3636,3648,3652,3733,3742],[212,213,152],"h1",{"id":214},"end-to-end-pipelines",[216,217,218],"blockquote",{},[219,220,221,222,226],"p",{},"Tier 6: pipeline configs wire together every component (model, optimizer, loss, data) into a complete experiment config with a ",[223,224,225],"code",{},"@L.task"," entry point. They are the top of the example curriculum and demonstrate the full laco composition model.",[219,228,229,230,233],{},"All source files live under ",[223,231,232],{},"sources\u002Flaco\u002Fexamples\u002Fpipelines\u002F",".",[235,236],"hr",{},[238,239,241,242,245],"h2",{"id":240},"_1-pipelinesmnist_trainpy-mnist-training-pipeline","1. ",[223,243,244],{},"pipelines\u002Fmnist_train.py",": MNIST training pipeline",[216,247,248],{},[219,249,250,251],{},"Source: ",[252,253,255],"a",{"href":254},"..\u002F..\u002Fsources\u002Flaco\u002Fexamples\u002Fpipelines\u002Fmnist_train.py",[223,256,257],{},"sources\u002Flaco\u002Fexamples\u002Fpipelines\u002Fmnist_train.py",[219,259,260,261,264,265,268,269,272,273,275],{},"Wires the Tier-1 ",[223,262,263],{},"cnn_classifier"," model together with an Adam optimizer, ",[223,266,267],{},"CrossEntropyLoss",", a torchvision MNIST dataset, and a ",[223,270,271],{},"DataLoader",", all as config nodes. A ",[223,274,225],{},"-decorated function provides the training loop entry point.",[277,278,280],"h3",{"id":279},"full-source","Full source",[282,283,288],"pre",{"className":284,"code":285,"language":286,"meta":287,"style":287},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","import laco.language as L\nfrom laco.examples.cnn_classifier import make_cnn_classifier\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader\nfrom torchvision import transforms\nfrom torchvision.datasets import MNIST\n\n__all__ = [\"model\", \"optimizer\", \"loss\", \"dataset\", \"loader\", \"train\", \"hps\"]\n\n\n@L.params\nclass hps:\n    data_root: str = \".\u002Fdata\"\n    batch_size: int = 64\n    learning_rate: float = 1e-3\n    num_workers: int = 0\n    in_channels: int = 1\n    base_channels: int = 32\n    num_stages: int = 3\n    num_classes: int = 10\n\n\nmodel = make_cnn_classifier(\n    in_channels=hps.in_channels,\n    base_channels=hps.base_channels,\n    num_stages=hps.num_stages,\n    num_classes=hps.num_classes,\n)\n\noptimizer = L.partial(optim.Adam)(lr=hps.learning_rate)\nloss = L.call(nn.CrossEntropyLoss)()\n\n_transform = L.call(transforms.Compose)(\n    L.List(\n        L.call(transforms.ToTensor)(),\n        L.call(transforms.Normalize)(mean=L.List(0.1307), std=L.List(0.3081)),\n    )\n)\n\ndataset = L.call(MNIST)(\n    root=hps.data_root,\n    train=True,\n    download=True,\n    transform=_transform,\n)\n\nloader = L.call(DataLoader)(\n    dataset=dataset,\n    batch_size=hps.batch_size,\n    shuffle=True,\n    num_workers=hps.num_workers,\n)\n\ntrain = L.Dict(\n    model=model,\n    optimizer=optimizer,\n    loss=loss,\n    loader=loader,\n)\n\n\n@L.task\ndef task(\n    model: nn.Module,\n    optimizer: optim.Optimizer,\n    loss: nn.Module,\n    loader: DataLoader,\n    num_steps: int = 1,\n) -> None:\n    opt = optimizer(model.parameters())\n    model.train()\n    loader_iter = iter(loader)\n    for step in range(num_steps):\n        try:\n            images, labels = next(loader_iter)\n        except StopIteration:\n            loader_iter = iter(loader)\n            images, labels = next(loader_iter)\n        opt.zero_grad()\n        out = model(images)\n        loss_val = loss(out, labels)\n        loss_val.backward()\n        opt.step()\n\n\nif __name__ == \"__main__\":\n    import laco\n\n    cfg = laco.load(__file__ + \"#train\")\n    task(cfg)\n","python","",[223,289,290,315,338,357,379,392,411,418,499,504,509,525,539,562,579,595,610,625,640,655,670,675,680,696,714,730,746,762,768,773,817,844,849,876,889,911,969,975,980,985,1007,1024,1038,1050,1063,1068,1073,1093,1105,1121,1133,1149,1154,1159,1176,1188,1200,1212,1224,1229,1234,1239,1251,1262,1279,1296,1311,1323,1340,1354,1377,1389,1406,1429,1437,1460,1471,1487,1506,1519,1537,1560,1573,1585,1590,1595,1616,1625,1630,1662],{"__ignoreMap":287},[291,292,295,299,303,306,309,312],"span",{"class":293,"line":294},"line",1,[291,296,298],{"class":297},"sVHd0","import",[291,300,302],{"class":301},"su5hD"," laco",[291,304,233],{"class":305},"sP7_E",[291,307,198],{"class":308},"skxfh",[291,310,311],{"class":297}," as",[291,313,314],{"class":301}," L\n",[291,316,318,321,323,325,328,330,333,335],{"class":293,"line":317},2,[291,319,320],{"class":297},"from",[291,322,302],{"class":301},[291,324,233],{"class":305},[291,326,327],{"class":301},"examples",[291,329,233],{"class":305},[291,331,332],{"class":301},"cnn_classifier ",[291,334,298],{"class":297},[291,336,337],{"class":301}," make_cnn_classifier\n",[291,339,341,343,346,348,351,354],{"class":293,"line":340},3,[291,342,320],{"class":297},[291,344,345],{"class":301}," torch ",[291,347,298],{"class":297},[291,349,350],{"class":301}," nn",[291,352,353],{"class":305},",",[291,355,356],{"class":301}," optim\n",[291,358,360,362,365,367,369,371,374,376],{"class":293,"line":359},4,[291,361,320],{"class":297},[291,363,364],{"class":301}," torch",[291,366,233],{"class":305},[291,368,204],{"class":301},[291,370,233],{"class":305},[291,372,373],{"class":301},"data ",[291,375,298],{"class":297},[291,377,378],{"class":301}," DataLoader\n",[291,380,382,384,387,389],{"class":293,"line":381},5,[291,383,320],{"class":297},[291,385,386],{"class":301}," torchvision ",[291,388,298],{"class":297},[291,390,391],{"class":301}," transforms\n",[291,393,395,397,400,402,405,407],{"class":293,"line":394},6,[291,396,320],{"class":297},[291,398,399],{"class":301}," torchvision",[291,401,233],{"class":305},[291,403,404],{"class":301},"datasets ",[291,406,298],{"class":297},[291,408,410],{"class":409},"s_hVV"," MNIST\n",[291,412,414],{"class":293,"line":413},7,[291,415,417],{"emptyLinePlaceholder":416},true,"\n",[291,419,421,424,428,431,435,439,441,443,446,449,451,453,455,458,460,462,464,467,469,471,473,476,478,480,482,485,487,489,491,494,496],{"class":293,"line":420},8,[291,422,423],{"class":409},"__all__",[291,425,427],{"class":426},"smGrS"," =",[291,429,430],{"class":305}," [",[291,432,434],{"class":433},"sjJ54","\"",[291,436,438],{"class":437},"s_sjI","model",[291,440,434],{"class":433},[291,442,353],{"class":305},[291,444,445],{"class":433}," \"",[291,447,448],{"class":437},"optimizer",[291,450,434],{"class":433},[291,452,353],{"class":305},[291,454,445],{"class":433},[291,456,457],{"class":437},"loss",[291,459,434],{"class":433},[291,461,353],{"class":305},[291,463,445],{"class":433},[291,465,466],{"class":437},"dataset",[291,468,434],{"class":433},[291,470,353],{"class":305},[291,472,445],{"class":433},[291,474,475],{"class":437},"loader",[291,477,434],{"class":433},[291,479,353],{"class":305},[291,481,445],{"class":433},[291,483,484],{"class":437},"train",[291,486,434],{"class":433},[291,488,353],{"class":305},[291,490,445],{"class":433},[291,492,493],{"class":437},"hps",[291,495,434],{"class":433},[291,497,498],{"class":305},"]\n",[291,500,502],{"class":293,"line":501},9,[291,503,417],{"emptyLinePlaceholder":416},[291,505,507],{"class":293,"line":506},10,[291,508,417],{"emptyLinePlaceholder":416},[291,510,512,516,520,522],{"class":293,"line":511},11,[291,513,515],{"class":514},"stp6e","@",[291,517,519],{"class":518},"sGLFI","L",[291,521,233],{"class":514},[291,523,524],{"class":518},"params\n",[291,526,528,532,536],{"class":293,"line":527},12,[291,529,531],{"class":530},"sbsja","class",[291,533,535],{"class":534},"sbgvK"," hps",[291,537,538],{"class":305},":\n",[291,540,542,545,548,552,554,556,559],{"class":293,"line":541},13,[291,543,544],{"class":301},"    data_root",[291,546,547],{"class":305},":",[291,549,551],{"class":550},"sZMiF"," str",[291,553,427],{"class":426},[291,555,445],{"class":433},[291,557,558],{"class":437},".\u002Fdata",[291,560,561],{"class":433},"\"\n",[291,563,565,568,570,573,575],{"class":293,"line":564},14,[291,566,567],{"class":301},"    batch_size",[291,569,547],{"class":305},[291,571,572],{"class":550}," int",[291,574,427],{"class":426},[291,576,578],{"class":577},"srdBf"," 64\n",[291,580,582,585,587,590,592],{"class":293,"line":581},15,[291,583,584],{"class":301},"    learning_rate",[291,586,547],{"class":305},[291,588,589],{"class":550}," float",[291,591,427],{"class":426},[291,593,594],{"class":577}," 1e-3\n",[291,596,598,601,603,605,607],{"class":293,"line":597},16,[291,599,600],{"class":301},"    num_workers",[291,602,547],{"class":305},[291,604,572],{"class":550},[291,606,427],{"class":426},[291,608,609],{"class":577}," 0\n",[291,611,613,616,618,620,622],{"class":293,"line":612},17,[291,614,615],{"class":301},"    in_channels",[291,617,547],{"class":305},[291,619,572],{"class":550},[291,621,427],{"class":426},[291,623,624],{"class":577}," 1\n",[291,626,628,631,633,635,637],{"class":293,"line":627},18,[291,629,630],{"class":301},"    base_channels",[291,632,547],{"class":305},[291,634,572],{"class":550},[291,636,427],{"class":426},[291,638,639],{"class":577}," 32\n",[291,641,643,646,648,650,652],{"class":293,"line":642},19,[291,644,645],{"class":301},"    num_stages",[291,647,547],{"class":305},[291,649,572],{"class":550},[291,651,427],{"class":426},[291,653,654],{"class":577}," 3\n",[291,656,658,661,663,665,667],{"class":293,"line":657},20,[291,659,660],{"class":301},"    num_classes",[291,662,547],{"class":305},[291,664,572],{"class":550},[291,666,427],{"class":426},[291,668,669],{"class":577}," 10\n",[291,671,673],{"class":293,"line":672},21,[291,674,417],{"emptyLinePlaceholder":416},[291,676,678],{"class":293,"line":677},22,[291,679,417],{"emptyLinePlaceholder":416},[291,681,683,686,689,693],{"class":293,"line":682},23,[291,684,685],{"class":301},"model ",[291,687,688],{"class":426},"=",[291,690,692],{"class":691},"slqww"," make_cnn_classifier",[291,694,695],{"class":305},"(\n",[291,697,699,702,704,706,708,711],{"class":293,"line":698},24,[291,700,615],{"class":701},"s99_P",[291,703,688],{"class":426},[291,705,493],{"class":691},[291,707,233],{"class":305},[291,709,710],{"class":308},"in_channels",[291,712,713],{"class":305},",\n",[291,715,717,719,721,723,725,728],{"class":293,"line":716},25,[291,718,630],{"class":701},[291,720,688],{"class":426},[291,722,493],{"class":691},[291,724,233],{"class":305},[291,726,727],{"class":308},"base_channels",[291,729,713],{"class":305},[291,731,733,735,737,739,741,744],{"class":293,"line":732},26,[291,734,645],{"class":701},[291,736,688],{"class":426},[291,738,493],{"class":691},[291,740,233],{"class":305},[291,742,743],{"class":308},"num_stages",[291,745,713],{"class":305},[291,747,749,751,753,755,757,760],{"class":293,"line":748},27,[291,750,660],{"class":701},[291,752,688],{"class":426},[291,754,493],{"class":691},[291,756,233],{"class":305},[291,758,759],{"class":308},"num_classes",[291,761,713],{"class":305},[291,763,765],{"class":293,"line":764},28,[291,766,767],{"class":305},")\n",[291,769,771],{"class":293,"line":770},29,[291,772,417],{"emptyLinePlaceholder":416},[291,774,776,779,781,784,786,789,792,795,797,800,803,806,808,810,812,815],{"class":293,"line":775},30,[291,777,778],{"class":301},"optimizer ",[291,780,688],{"class":426},[291,782,783],{"class":301}," L",[291,785,233],{"class":305},[291,787,788],{"class":691},"partial",[291,790,791],{"class":305},"(",[291,793,794],{"class":691},"optim",[291,796,233],{"class":305},[291,798,799],{"class":308},"Adam",[291,801,802],{"class":305},")(",[291,804,805],{"class":701},"lr",[291,807,688],{"class":426},[291,809,493],{"class":691},[291,811,233],{"class":305},[291,813,814],{"class":308},"learning_rate",[291,816,767],{"class":305},[291,818,820,823,825,827,829,832,834,837,839,841],{"class":293,"line":819},31,[291,821,822],{"class":301},"loss ",[291,824,688],{"class":426},[291,826,783],{"class":301},[291,828,233],{"class":305},[291,830,831],{"class":691},"call",[291,833,791],{"class":305},[291,835,836],{"class":691},"nn",[291,838,233],{"class":305},[291,840,267],{"class":308},[291,842,843],{"class":305},")()\n",[291,845,847],{"class":293,"line":846},32,[291,848,417],{"emptyLinePlaceholder":416},[291,850,852,855,857,859,861,863,865,868,870,873],{"class":293,"line":851},33,[291,853,854],{"class":301},"_transform ",[291,856,688],{"class":426},[291,858,783],{"class":301},[291,860,233],{"class":305},[291,862,831],{"class":691},[291,864,791],{"class":305},[291,866,867],{"class":691},"transforms",[291,869,233],{"class":305},[291,871,872],{"class":308},"Compose",[291,874,875],{"class":305},")(\n",[291,877,879,882,884,887],{"class":293,"line":878},34,[291,880,881],{"class":691},"    L",[291,883,233],{"class":305},[291,885,886],{"class":691},"List",[291,888,695],{"class":305},[291,890,892,895,897,899,901,903,905,908],{"class":293,"line":891},35,[291,893,894],{"class":691},"        L",[291,896,233],{"class":305},[291,898,831],{"class":691},[291,900,791],{"class":305},[291,902,867],{"class":691},[291,904,233],{"class":305},[291,906,907],{"class":308},"ToTensor",[291,909,910],{"class":305},")(),\n",[291,912,914,916,918,920,922,924,926,929,931,934,936,938,940,942,944,947,950,953,955,957,959,961,963,966],{"class":293,"line":913},36,[291,915,894],{"class":691},[291,917,233],{"class":305},[291,919,831],{"class":691},[291,921,791],{"class":305},[291,923,867],{"class":691},[291,925,233],{"class":305},[291,927,928],{"class":308},"Normalize",[291,930,802],{"class":305},[291,932,933],{"class":701},"mean",[291,935,688],{"class":426},[291,937,519],{"class":691},[291,939,233],{"class":305},[291,941,886],{"class":691},[291,943,791],{"class":305},[291,945,946],{"class":577},"0.1307",[291,948,949],{"class":305},"),",[291,951,952],{"class":701}," std",[291,954,688],{"class":426},[291,956,519],{"class":691},[291,958,233],{"class":305},[291,960,886],{"class":691},[291,962,791],{"class":305},[291,964,965],{"class":577},"0.3081",[291,967,968],{"class":305},")),\n",[291,970,972],{"class":293,"line":971},37,[291,973,974],{"class":305},"    )\n",[291,976,978],{"class":293,"line":977},38,[291,979,767],{"class":305},[291,981,983],{"class":293,"line":982},39,[291,984,417],{"emptyLinePlaceholder":416},[291,986,988,991,993,995,997,999,1001,1005],{"class":293,"line":987},40,[291,989,990],{"class":301},"dataset ",[291,992,688],{"class":426},[291,994,783],{"class":301},[291,996,233],{"class":305},[291,998,831],{"class":691},[291,1000,791],{"class":305},[291,1002,1004],{"class":1003},"sptTA","MNIST",[291,1006,875],{"class":305},[291,1008,1010,1013,1015,1017,1019,1022],{"class":293,"line":1009},41,[291,1011,1012],{"class":701},"    root",[291,1014,688],{"class":426},[291,1016,493],{"class":691},[291,1018,233],{"class":305},[291,1020,1021],{"class":308},"data_root",[291,1023,713],{"class":305},[291,1025,1027,1030,1032,1036],{"class":293,"line":1026},42,[291,1028,1029],{"class":701},"    train",[291,1031,688],{"class":426},[291,1033,1035],{"class":1034},"s39Yj","True",[291,1037,713],{"class":305},[291,1039,1041,1044,1046,1048],{"class":293,"line":1040},43,[291,1042,1043],{"class":701},"    download",[291,1045,688],{"class":426},[291,1047,1035],{"class":1034},[291,1049,713],{"class":305},[291,1051,1053,1056,1058,1061],{"class":293,"line":1052},44,[291,1054,1055],{"class":701},"    transform",[291,1057,688],{"class":426},[291,1059,1060],{"class":691},"_transform",[291,1062,713],{"class":305},[291,1064,1066],{"class":293,"line":1065},45,[291,1067,767],{"class":305},[291,1069,1071],{"class":293,"line":1070},46,[291,1072,417],{"emptyLinePlaceholder":416},[291,1074,1076,1079,1081,1083,1085,1087,1089,1091],{"class":293,"line":1075},47,[291,1077,1078],{"class":301},"loader ",[291,1080,688],{"class":426},[291,1082,783],{"class":301},[291,1084,233],{"class":305},[291,1086,831],{"class":691},[291,1088,791],{"class":305},[291,1090,271],{"class":691},[291,1092,875],{"class":305},[291,1094,1096,1099,1101,1103],{"class":293,"line":1095},48,[291,1097,1098],{"class":701},"    dataset",[291,1100,688],{"class":426},[291,1102,466],{"class":691},[291,1104,713],{"class":305},[291,1106,1108,1110,1112,1114,1116,1119],{"class":293,"line":1107},49,[291,1109,567],{"class":701},[291,1111,688],{"class":426},[291,1113,493],{"class":691},[291,1115,233],{"class":305},[291,1117,1118],{"class":308},"batch_size",[291,1120,713],{"class":305},[291,1122,1124,1127,1129,1131],{"class":293,"line":1123},50,[291,1125,1126],{"class":701},"    shuffle",[291,1128,688],{"class":426},[291,1130,1035],{"class":1034},[291,1132,713],{"class":305},[291,1134,1136,1138,1140,1142,1144,1147],{"class":293,"line":1135},51,[291,1137,600],{"class":701},[291,1139,688],{"class":426},[291,1141,493],{"class":691},[291,1143,233],{"class":305},[291,1145,1146],{"class":308},"num_workers",[291,1148,713],{"class":305},[291,1150,1152],{"class":293,"line":1151},52,[291,1153,767],{"class":305},[291,1155,1157],{"class":293,"line":1156},53,[291,1158,417],{"emptyLinePlaceholder":416},[291,1160,1162,1165,1167,1169,1171,1174],{"class":293,"line":1161},54,[291,1163,1164],{"class":301},"train ",[291,1166,688],{"class":426},[291,1168,783],{"class":301},[291,1170,233],{"class":305},[291,1172,1173],{"class":691},"Dict",[291,1175,695],{"class":305},[291,1177,1179,1182,1184,1186],{"class":293,"line":1178},55,[291,1180,1181],{"class":701},"    model",[291,1183,688],{"class":426},[291,1185,438],{"class":691},[291,1187,713],{"class":305},[291,1189,1191,1194,1196,1198],{"class":293,"line":1190},56,[291,1192,1193],{"class":701},"    optimizer",[291,1195,688],{"class":426},[291,1197,448],{"class":691},[291,1199,713],{"class":305},[291,1201,1203,1206,1208,1210],{"class":293,"line":1202},57,[291,1204,1205],{"class":701},"    loss",[291,1207,688],{"class":426},[291,1209,457],{"class":691},[291,1211,713],{"class":305},[291,1213,1215,1218,1220,1222],{"class":293,"line":1214},58,[291,1216,1217],{"class":701},"    loader",[291,1219,688],{"class":426},[291,1221,475],{"class":691},[291,1223,713],{"class":305},[291,1225,1227],{"class":293,"line":1226},59,[291,1228,767],{"class":305},[291,1230,1232],{"class":293,"line":1231},60,[291,1233,417],{"emptyLinePlaceholder":416},[291,1235,1237],{"class":293,"line":1236},61,[291,1238,417],{"emptyLinePlaceholder":416},[291,1240,1242,1244,1246,1248],{"class":293,"line":1241},62,[291,1243,515],{"class":514},[291,1245,519],{"class":518},[291,1247,233],{"class":514},[291,1249,1250],{"class":518},"task\n",[291,1252,1254,1257,1260],{"class":293,"line":1253},63,[291,1255,1256],{"class":530},"def",[291,1258,1259],{"class":518}," task",[291,1261,695],{"class":305},[291,1263,1265,1268,1270,1272,1274,1277],{"class":293,"line":1264},64,[291,1266,1181],{"class":1267},"sFwrP",[291,1269,547],{"class":305},[291,1271,350],{"class":301},[291,1273,233],{"class":305},[291,1275,1276],{"class":308},"Module",[291,1278,713],{"class":305},[291,1280,1282,1284,1286,1289,1291,1294],{"class":293,"line":1281},65,[291,1283,1193],{"class":1267},[291,1285,547],{"class":305},[291,1287,1288],{"class":301}," optim",[291,1290,233],{"class":305},[291,1292,1293],{"class":308},"Optimizer",[291,1295,713],{"class":305},[291,1297,1299,1301,1303,1305,1307,1309],{"class":293,"line":1298},66,[291,1300,1205],{"class":1267},[291,1302,547],{"class":305},[291,1304,350],{"class":301},[291,1306,233],{"class":305},[291,1308,1276],{"class":308},[291,1310,713],{"class":305},[291,1312,1314,1316,1318,1321],{"class":293,"line":1313},67,[291,1315,1217],{"class":1267},[291,1317,547],{"class":305},[291,1319,1320],{"class":301}," DataLoader",[291,1322,713],{"class":305},[291,1324,1326,1329,1331,1333,1335,1338],{"class":293,"line":1325},68,[291,1327,1328],{"class":1267},"    num_steps",[291,1330,547],{"class":305},[291,1332,572],{"class":550},[291,1334,427],{"class":426},[291,1336,1337],{"class":577}," 1",[291,1339,713],{"class":305},[291,1341,1343,1346,1349,1352],{"class":293,"line":1342},69,[291,1344,1345],{"class":305},")",[291,1347,1348],{"class":305}," ->",[291,1350,1351],{"class":1034}," None",[291,1353,538],{"class":305},[291,1355,1357,1360,1362,1365,1367,1369,1371,1374],{"class":293,"line":1356},70,[291,1358,1359],{"class":301},"    opt ",[291,1361,688],{"class":426},[291,1363,1364],{"class":691}," optimizer",[291,1366,791],{"class":305},[291,1368,438],{"class":691},[291,1370,233],{"class":305},[291,1372,1373],{"class":691},"parameters",[291,1375,1376],{"class":305},"())\n",[291,1378,1380,1382,1384,1386],{"class":293,"line":1379},71,[291,1381,1181],{"class":301},[291,1383,233],{"class":305},[291,1385,484],{"class":691},[291,1387,1388],{"class":305},"()\n",[291,1390,1392,1395,1397,1400,1402,1404],{"class":293,"line":1391},72,[291,1393,1394],{"class":301},"    loader_iter ",[291,1396,688],{"class":426},[291,1398,1399],{"class":1003}," iter",[291,1401,791],{"class":305},[291,1403,475],{"class":691},[291,1405,767],{"class":305},[291,1407,1409,1412,1415,1418,1421,1423,1426],{"class":293,"line":1408},73,[291,1410,1411],{"class":297},"    for",[291,1413,1414],{"class":301}," step ",[291,1416,1417],{"class":297},"in",[291,1419,1420],{"class":1003}," range",[291,1422,791],{"class":305},[291,1424,1425],{"class":691},"num_steps",[291,1427,1428],{"class":305},"):\n",[291,1430,1432,1435],{"class":293,"line":1431},74,[291,1433,1434],{"class":297},"        try",[291,1436,538],{"class":305},[291,1438,1440,1443,1445,1448,1450,1453,1455,1458],{"class":293,"line":1439},75,[291,1441,1442],{"class":301},"            images",[291,1444,353],{"class":305},[291,1446,1447],{"class":301}," labels ",[291,1449,688],{"class":426},[291,1451,1452],{"class":1003}," next",[291,1454,791],{"class":305},[291,1456,1457],{"class":691},"loader_iter",[291,1459,767],{"class":305},[291,1461,1463,1466,1469],{"class":293,"line":1462},76,[291,1464,1465],{"class":297},"        except",[291,1467,1468],{"class":550}," StopIteration",[291,1470,538],{"class":305},[291,1472,1474,1477,1479,1481,1483,1485],{"class":293,"line":1473},77,[291,1475,1476],{"class":301},"            loader_iter ",[291,1478,688],{"class":426},[291,1480,1399],{"class":1003},[291,1482,791],{"class":305},[291,1484,475],{"class":691},[291,1486,767],{"class":305},[291,1488,1490,1492,1494,1496,1498,1500,1502,1504],{"class":293,"line":1489},78,[291,1491,1442],{"class":301},[291,1493,353],{"class":305},[291,1495,1447],{"class":301},[291,1497,688],{"class":426},[291,1499,1452],{"class":1003},[291,1501,791],{"class":305},[291,1503,1457],{"class":691},[291,1505,767],{"class":305},[291,1507,1509,1512,1514,1517],{"class":293,"line":1508},79,[291,1510,1511],{"class":301},"        opt",[291,1513,233],{"class":305},[291,1515,1516],{"class":691},"zero_grad",[291,1518,1388],{"class":305},[291,1520,1522,1525,1527,1530,1532,1535],{"class":293,"line":1521},80,[291,1523,1524],{"class":301},"        out ",[291,1526,688],{"class":426},[291,1528,1529],{"class":691}," model",[291,1531,791],{"class":305},[291,1533,1534],{"class":691},"images",[291,1536,767],{"class":305},[291,1538,1540,1543,1545,1548,1550,1553,1555,1558],{"class":293,"line":1539},81,[291,1541,1542],{"class":301},"        loss_val ",[291,1544,688],{"class":426},[291,1546,1547],{"class":691}," loss",[291,1549,791],{"class":305},[291,1551,1552],{"class":691},"out",[291,1554,353],{"class":305},[291,1556,1557],{"class":691}," labels",[291,1559,767],{"class":305},[291,1561,1563,1566,1568,1571],{"class":293,"line":1562},82,[291,1564,1565],{"class":301},"        loss_val",[291,1567,233],{"class":305},[291,1569,1570],{"class":691},"backward",[291,1572,1388],{"class":305},[291,1574,1576,1578,1580,1583],{"class":293,"line":1575},83,[291,1577,1511],{"class":301},[291,1579,233],{"class":305},[291,1581,1582],{"class":691},"step",[291,1584,1388],{"class":305},[291,1586,1588],{"class":293,"line":1587},84,[291,1589,417],{"emptyLinePlaceholder":416},[291,1591,1593],{"class":293,"line":1592},85,[291,1594,417],{"emptyLinePlaceholder":416},[291,1596,1598,1601,1604,1607,1609,1612,1614],{"class":293,"line":1597},86,[291,1599,1600],{"class":297},"if",[291,1602,1603],{"class":409}," __name__",[291,1605,1606],{"class":426}," ==",[291,1608,445],{"class":433},[291,1610,1611],{"class":437},"__main__",[291,1613,434],{"class":433},[291,1615,538],{"class":305},[291,1617,1619,1622],{"class":293,"line":1618},87,[291,1620,1621],{"class":297},"    import",[291,1623,1624],{"class":301}," laco\n",[291,1626,1628],{"class":293,"line":1627},88,[291,1629,417],{"emptyLinePlaceholder":416},[291,1631,1633,1636,1638,1640,1642,1645,1647,1650,1653,1655,1658,1660],{"class":293,"line":1632},89,[291,1634,1635],{"class":301},"    cfg ",[291,1637,688],{"class":426},[291,1639,302],{"class":301},[291,1641,233],{"class":305},[291,1643,1644],{"class":691},"load",[291,1646,791],{"class":305},[291,1648,1649],{"class":409},"__file__",[291,1651,1652],{"class":426}," +",[291,1654,445],{"class":433},[291,1656,1657],{"class":437},"#train",[291,1659,434],{"class":433},[291,1661,767],{"class":305},[291,1663,1665,1668,1670,1673],{"class":293,"line":1664},90,[291,1666,1667],{"class":691},"    task",[291,1669,791],{"class":305},[291,1671,1672],{"class":691},"cfg",[291,1674,767],{"class":305},[277,1676,1678],{"id":1677},"annotated-walkthrough","Annotated walkthrough",[219,1680,1681,1687,1688,1690,1691,1693],{},[1682,1683,1684],"strong",{},[223,1685,1686],{},"@L.params class hps","\nAll scalar hyperparameters in one flat namespace. The pipeline owns all of them, including model architecture parameters (",[223,1689,710],{},", ",[223,1692,727],{},", etc.), so overrides are uniform regardless of whether the hps affect the model, optimizer, or data loader.",[219,1695,1696,1701,1702,1705,1706,1709],{},[1682,1697,1698],{},[223,1699,1700],{},"model = make_cnn_classifier(...)","\nImports the factory from ",[223,1703,1704],{},"laco.examples.cnn_classifier"," and calls it with hps values. This is the standard way to compose Tier-1 building blocks into a pipeline: the model config node is identical to what ",[223,1707,1708],{},"cnn_classifier.py"," produces directly; the pipeline just supplies different hps.",[219,1711,1712,1717,1720,1721,1724,1725,1727],{},[1682,1713,1714],{},[223,1715,1716],{},"optimizer = L.partial(optim.Adam)(lr=hps.learning_rate)",[223,1718,1719],{},"L.partial"," for the optimizer: the factory receives ",[223,1722,1723],{},"model.parameters()"," inside ",[223,1726,225],{},", not here. This is the correct pattern for any object that needs live tensors.",[219,1729,1730,1735,1738,1739,1742,1743,1745],{},[1682,1731,1732],{},[223,1733,1734],{},"loss = L.call(nn.CrossEntropyLoss)()",[223,1736,1737],{},"L.call"," with no arguments (",[223,1740,1741],{},"()",") at the end constructs the loss config with all defaults. The trailing ",[223,1744,1741],{}," is the keyword-argument call, required even when empty.",[219,1747,1748,1754,1757,1758,1761,1762,1764,1765,1768],{},[1682,1749,1750,1753],{},[223,1751,1752],{},"L.List(...)"," for the transform pipeline",[223,1755,1756],{},"transforms.Compose"," takes a Python list. ",[223,1759,1760],{},"L.List(node, node, ...)"," is the laco list literal: it produces a config list that instantiates each element before passing it to ",[223,1763,872],{},". Nested structures (",[223,1766,1767],{},"mean=L.List(0.1307)",") work the same way.",[219,1770,1771,1776,1777,1779,1780,1782,1783,1785,1786,1789,1790,233],{},[1682,1772,1773],{},[223,1774,1775],{},"dataset = L.call(MNIST)(..., transform=_transform)","\nThe dataset config references the ",[223,1778,1060],{}," config node. During instantiation, laco resolves ",[223,1781,1060],{}," first (producing a ",[223,1784,872],{}," object), then passes it as the ",[223,1787,1788],{},"transform"," argument to ",[223,1791,1792],{},"MNIST.__init__",[219,1794,1795,1800,1801,1803,1804,1806,1807,233],{},[1682,1796,1797],{},[223,1798,1799],{},"loader = L.call(DataLoader)(dataset=dataset, ...)","\nThe loader config references the ",[223,1802,466],{}," config node. Instantiation order is resolved automatically: ",[223,1805,466],{}," is fully instantiated before it is passed to ",[223,1808,271],{},[219,1810,1811,1816,1819,1820,1823,1824,1827,1828,1830],{},[1682,1812,1813],{},[223,1814,1815],{},"train = L.Dict(model=model, optimizer=optimizer, loss=loss, loader=loader)",[223,1817,1818],{},"L.Dict"," assembles a named bundle. This is the pipeline root: loading ",[223,1821,1822],{},"\"...#train\""," returns this dict, and ",[223,1825,1826],{},"laco.instantiate(train_cfg)"," instantiates all four components in dependency order. The ",[223,1829,1657],{}," fragment selector targets this node specifically.",[219,1832,1833,1838,1839,1841,1842,1844,1845,1848],{},[1682,1834,1835],{},[223,1836,1837],{},"@L.task def task(...)","\nThe entry point. ",[223,1840,225],{}," marks a function as a laco task: when invoked with a config dict (e.g. the instantiated ",[223,1843,484],{}," bundle), laco maps config keys to function parameters by name, instantiating any nodes that have not been instantiated yet. ",[223,1846,1847],{},"num_steps: int = 1"," is a task-local parameter that can be overridden from the CLI.",[219,1850,1851,1852,1690,1855,1857,1858,1860,1861,1863,1864,1866],{},"Inside ",[223,1853,1854],{},"task",[223,1856,448],{}," arrives as a partial (returned by ",[223,1859,1719],{},"); it is called with ",[223,1862,1723],{}," to produce the actual ",[223,1865,799],{}," instance.",[219,1868,1869],{},[1682,1870,1871,1874],{},[223,1872,1873],{},"if __name__ == \"__main__\":",", self-loading pattern",[282,1876,1878],{"className":284,"code":1877,"language":286,"meta":287,"style":287},"cfg = laco.load(__file__ + \"#train\")\ntask(cfg)\n",[223,1879,1880,1907],{"__ignoreMap":287},[291,1881,1882,1885,1887,1889,1891,1893,1895,1897,1899,1901,1903,1905],{"class":293,"line":294},[291,1883,1884],{"class":301},"cfg ",[291,1886,688],{"class":426},[291,1888,302],{"class":301},[291,1890,233],{"class":305},[291,1892,1644],{"class":691},[291,1894,791],{"class":305},[291,1896,1649],{"class":409},[291,1898,1652],{"class":426},[291,1900,445],{"class":433},[291,1902,1657],{"class":437},[291,1904,434],{"class":433},[291,1906,767],{"class":305},[291,1908,1909,1911,1913,1915],{"class":293,"line":317},[291,1910,1854],{"class":691},[291,1912,791],{"class":305},[291,1914,1672],{"class":691},[291,1916,767],{"class":305},[219,1918,1919,1920,1924,1925,1927,1928,1930,1931,1934],{},"The file loads ",[1921,1922,1923],"em",{},"itself"," as a config, selects the ",[223,1926,484],{}," bundle, and calls ",[223,1929,1854],{},". This means the file can be run directly (",[223,1932,1933],{},"python -m laco.examples.pipelines.mnist_train",") or loaded as a config from another file: the same source code serves both roles.",[277,1936,1938],{"id":1937},"load-and-inspect","Load and inspect",[282,1940,1942],{"className":284,"code":1941,"language":286,"meta":287,"style":287},"import laco\n\n# Load the full pipeline config\ncfg = laco.load(\"configs:\u002F\u002Fexamples\u002Fpipelines\u002Fmnist_train.py\")\nprint(list(cfg.keys()))\n# ['hps', 'model', 'optimizer', 'loss', 'dataset', 'loader', 'train']\n\n# Load only the training bundle\ntrain_cfg = laco.load(\"configs:\u002F\u002Fexamples\u002Fpipelines\u002Fmnist_train.py#train\")\nprint(list(train_cfg.keys()))\n# ['model', 'optimizer', 'loss', 'loader']\n\n# Instantiate everything in the bundle\ntrain = laco.instantiate(train_cfg)\n# train.model     → nn.Sequential (the CNN)\n# train.optimizer → functools.partial wrapping Adam\n# train.loss      → nn.CrossEntropyLoss()\n# train.loader    → DataLoader (dataset instantiated as part of this step)\n",[223,1943,1944,1950,1954,1960,1983,2004,2009,2013,2018,2042,2061,2066,2070,2075,2094,2099,2104,2109],{"__ignoreMap":287},[291,1945,1946,1948],{"class":293,"line":294},[291,1947,298],{"class":297},[291,1949,1624],{"class":301},[291,1951,1952],{"class":293,"line":317},[291,1953,417],{"emptyLinePlaceholder":416},[291,1955,1956],{"class":293,"line":340},[291,1957,1959],{"class":1958},"sutJx","# Load the full pipeline config\n",[291,1961,1962,1964,1966,1968,1970,1972,1974,1976,1979,1981],{"class":293,"line":359},[291,1963,1884],{"class":301},[291,1965,688],{"class":426},[291,1967,302],{"class":301},[291,1969,233],{"class":305},[291,1971,1644],{"class":691},[291,1973,791],{"class":305},[291,1975,434],{"class":433},[291,1977,1978],{"class":437},"configs:\u002F\u002Fexamples\u002Fpipelines\u002Fmnist_train.py",[291,1980,434],{"class":433},[291,1982,767],{"class":305},[291,1984,1985,1988,1990,1993,1995,1997,1999,2001],{"class":293,"line":381},[291,1986,1987],{"class":1003},"print",[291,1989,791],{"class":305},[291,1991,1992],{"class":550},"list",[291,1994,791],{"class":305},[291,1996,1672],{"class":691},[291,1998,233],{"class":305},[291,2000,195],{"class":691},[291,2002,2003],{"class":305},"()))\n",[291,2005,2006],{"class":293,"line":394},[291,2007,2008],{"class":1958},"# ['hps', 'model', 'optimizer', 'loss', 'dataset', 'loader', 'train']\n",[291,2010,2011],{"class":293,"line":413},[291,2012,417],{"emptyLinePlaceholder":416},[291,2014,2015],{"class":293,"line":420},[291,2016,2017],{"class":1958},"# Load only the training bundle\n",[291,2019,2020,2023,2025,2027,2029,2031,2033,2035,2038,2040],{"class":293,"line":501},[291,2021,2022],{"class":301},"train_cfg ",[291,2024,688],{"class":426},[291,2026,302],{"class":301},[291,2028,233],{"class":305},[291,2030,1644],{"class":691},[291,2032,791],{"class":305},[291,2034,434],{"class":433},[291,2036,2037],{"class":437},"configs:\u002F\u002Fexamples\u002Fpipelines\u002Fmnist_train.py#train",[291,2039,434],{"class":433},[291,2041,767],{"class":305},[291,2043,2044,2046,2048,2050,2052,2055,2057,2059],{"class":293,"line":506},[291,2045,1987],{"class":1003},[291,2047,791],{"class":305},[291,2049,1992],{"class":550},[291,2051,791],{"class":305},[291,2053,2054],{"class":691},"train_cfg",[291,2056,233],{"class":305},[291,2058,195],{"class":691},[291,2060,2003],{"class":305},[291,2062,2063],{"class":293,"line":511},[291,2064,2065],{"class":1958},"# ['model', 'optimizer', 'loss', 'loader']\n",[291,2067,2068],{"class":293,"line":527},[291,2069,417],{"emptyLinePlaceholder":416},[291,2071,2072],{"class":293,"line":541},[291,2073,2074],{"class":1958},"# Instantiate everything in the bundle\n",[291,2076,2077,2079,2081,2083,2085,2088,2090,2092],{"class":293,"line":564},[291,2078,1164],{"class":301},[291,2080,688],{"class":426},[291,2082,302],{"class":301},[291,2084,233],{"class":305},[291,2086,2087],{"class":691},"instantiate",[291,2089,791],{"class":305},[291,2091,2054],{"class":691},[291,2093,767],{"class":305},[291,2095,2096],{"class":293,"line":581},[291,2097,2098],{"class":1958},"# train.model     → nn.Sequential (the CNN)\n",[291,2100,2101],{"class":293,"line":597},[291,2102,2103],{"class":1958},"# train.optimizer → functools.partial wrapping Adam\n",[291,2105,2106],{"class":293,"line":612},[291,2107,2108],{"class":1958},"# train.loss      → nn.CrossEntropyLoss()\n",[291,2110,2111],{"class":293,"line":627},[291,2112,2113],{"class":1958},"# train.loader    → DataLoader (dataset instantiated as part of this step)\n",[277,2115,2117],{"id":2116},"override-demo","Override demo",[282,2119,2121],{"className":284,"code":2120,"language":286,"meta":287,"style":287},"import laco\n\n# Tune learning rate and batch size\ncfg = laco.load(\n    \"configs:\u002F\u002Fexamples\u002Fpipelines\u002Fmnist_train.py\",\n    \"hps.learning_rate=5e-4\",\n    \"hps.batch_size=128\",\n)\n\n# Shrink model for a smoke run\ncfg = laco.load(\n    \"configs:\u002F\u002Fexamples\u002Fpipelines\u002Fmnist_train.py\",\n    \"hps.base_channels=8\",\n    \"hps.num_stages=1\",\n    \"hps.num_classes=10\",\n)\ntrain = laco.instantiate(cfg.train)\n",[223,2122,2123,2129,2133,2138,2152,2163,2174,2185,2189,2193,2198,2212,2222,2233,2244,2255,2259],{"__ignoreMap":287},[291,2124,2125,2127],{"class":293,"line":294},[291,2126,298],{"class":297},[291,2128,1624],{"class":301},[291,2130,2131],{"class":293,"line":317},[291,2132,417],{"emptyLinePlaceholder":416},[291,2134,2135],{"class":293,"line":340},[291,2136,2137],{"class":1958},"# Tune learning rate and batch size\n",[291,2139,2140,2142,2144,2146,2148,2150],{"class":293,"line":359},[291,2141,1884],{"class":301},[291,2143,688],{"class":426},[291,2145,302],{"class":301},[291,2147,233],{"class":305},[291,2149,1644],{"class":691},[291,2151,695],{"class":305},[291,2153,2154,2157,2159,2161],{"class":293,"line":381},[291,2155,2156],{"class":433},"    \"",[291,2158,1978],{"class":437},[291,2160,434],{"class":433},[291,2162,713],{"class":305},[291,2164,2165,2167,2170,2172],{"class":293,"line":394},[291,2166,2156],{"class":433},[291,2168,2169],{"class":437},"hps.learning_rate=5e-4",[291,2171,434],{"class":433},[291,2173,713],{"class":305},[291,2175,2176,2178,2181,2183],{"class":293,"line":413},[291,2177,2156],{"class":433},[291,2179,2180],{"class":437},"hps.batch_size=128",[291,2182,434],{"class":433},[291,2184,713],{"class":305},[291,2186,2187],{"class":293,"line":420},[291,2188,767],{"class":305},[291,2190,2191],{"class":293,"line":501},[291,2192,417],{"emptyLinePlaceholder":416},[291,2194,2195],{"class":293,"line":506},[291,2196,2197],{"class":1958},"# Shrink model for a smoke run\n",[291,2199,2200,2202,2204,2206,2208,2210],{"class":293,"line":511},[291,2201,1884],{"class":301},[291,2203,688],{"class":426},[291,2205,302],{"class":301},[291,2207,233],{"class":305},[291,2209,1644],{"class":691},[291,2211,695],{"class":305},[291,2213,2214,2216,2218,2220],{"class":293,"line":527},[291,2215,2156],{"class":433},[291,2217,1978],{"class":437},[291,2219,434],{"class":433},[291,2221,713],{"class":305},[291,2223,2224,2226,2229,2231],{"class":293,"line":541},[291,2225,2156],{"class":433},[291,2227,2228],{"class":437},"hps.base_channels=8",[291,2230,434],{"class":433},[291,2232,713],{"class":305},[291,2234,2235,2237,2240,2242],{"class":293,"line":564},[291,2236,2156],{"class":433},[291,2238,2239],{"class":437},"hps.num_stages=1",[291,2241,434],{"class":433},[291,2243,713],{"class":305},[291,2245,2246,2248,2251,2253],{"class":293,"line":581},[291,2247,2156],{"class":433},[291,2249,2250],{"class":437},"hps.num_classes=10",[291,2252,434],{"class":433},[291,2254,713],{"class":305},[291,2256,2257],{"class":293,"line":597},[291,2258,767],{"class":305},[291,2260,2261,2263,2265,2267,2269,2271,2273,2275,2277,2279],{"class":293,"line":612},[291,2262,1164],{"class":301},[291,2264,688],{"class":426},[291,2266,302],{"class":301},[291,2268,233],{"class":305},[291,2270,2087],{"class":691},[291,2272,791],{"class":305},[291,2274,1672],{"class":691},[291,2276,233],{"class":305},[291,2278,484],{"class":308},[291,2280,767],{"class":305},[277,2282,2284],{"id":2283},"run-from-the-command-line","Run from the command line",[282,2286,2290],{"className":2287,"code":2288,"language":2289,"meta":287,"style":287},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","# Smoke run (1 step, no MNIST download required for model\u002Foptimizer\u002Floss):\npython -m laco.examples.pipelines.mnist_train\n\n# Five steps:\npython -m laco.examples.pipelines.mnist_train num_steps=5\n\n# Tune hyperparameters:\npython -m laco.examples.pipelines.mnist_train \\\n    hps.learning_rate=5e-4 \\\n    hps.batch_size=128 \\\n    num_steps=10\n","bash",[223,2291,2292,2297,2308,2312,2317,2332,2336,2341,2352,2359,2369],{"__ignoreMap":287},[291,2293,2294],{"class":293,"line":294},[291,2295,2296],{"class":1958},"# Smoke run (1 step, no MNIST download required for model\u002Foptimizer\u002Floss):\n",[291,2298,2299,2301,2305],{"class":293,"line":317},[291,2300,286],{"class":534},[291,2302,2304],{"class":2303},"stzsN"," -m",[291,2306,2307],{"class":437}," laco.examples.pipelines.mnist_train\n",[291,2309,2310],{"class":293,"line":340},[291,2311,417],{"emptyLinePlaceholder":416},[291,2313,2314],{"class":293,"line":359},[291,2315,2316],{"class":1958},"# Five steps:\n",[291,2318,2319,2321,2323,2326,2329],{"class":293,"line":381},[291,2320,286],{"class":534},[291,2322,2304],{"class":2303},[291,2324,2325],{"class":437}," laco.examples.pipelines.mnist_train",[291,2327,2328],{"class":437}," num_steps=",[291,2330,2331],{"class":577},"5\n",[291,2333,2334],{"class":293,"line":394},[291,2335,417],{"emptyLinePlaceholder":416},[291,2337,2338],{"class":293,"line":413},[291,2339,2340],{"class":1958},"# Tune hyperparameters:\n",[291,2342,2343,2345,2347,2349],{"class":293,"line":420},[291,2344,286],{"class":534},[291,2346,2304],{"class":2303},[291,2348,2325],{"class":437},[291,2350,2351],{"class":409}," \\\n",[291,2353,2354,2357],{"class":293,"line":501},[291,2355,2356],{"class":437},"    hps.learning_rate=5e-4",[291,2358,2351],{"class":409},[291,2360,2361,2364,2367],{"class":293,"line":506},[291,2362,2363],{"class":437},"    hps.batch_size=",[291,2365,2366],{"class":577},"128",[291,2368,2351],{"class":409},[291,2370,2371,2374],{"class":293,"line":511},[291,2372,2373],{"class":437},"    num_steps=",[291,2375,2376],{"class":577},"10\n",[277,2378,2380],{"id":2379},"what-this-demonstrates","What this demonstrates",[2382,2383,2384,2392,2400,2408,2413,2418],"ul",{},[2385,2386,2387,2388,2391],"li",{},"Importing a Tier-1 config factory (",[223,2389,2390],{},"make_cnn_classifier",") into a pipeline",[2385,2393,2394,2397,2398,1345],{},[223,2395,2396],{},"L.List"," for list-valued constructor arguments (",[223,2399,1756],{},[2385,2401,2402,2404,2405,2407],{},[223,2403,1818],{}," as the pipeline root: enables ",[223,2406,1657],{}," fragment selection",[2385,2409,2410,2412],{},[223,2411,225],{}," entry point: maps config keys to typed function parameters",[2385,2414,2415,2417],{},[223,2416,1719],{}," for objects that need live tensors at call time (optimizer)",[2385,2419,2420,2421,2424],{},"Self-loading pattern: ",[223,2422,2423],{},"laco.load(__file__ + \"#train\")"," for direct execution",[235,2426],{},[238,2428,2430,2431,2434],{"id":2429},"_2-pipelinesclm_finetunepy-causal-lm-fine-tuning-pipeline","2. ",[223,2432,2433],{},"pipelines\u002Fclm_finetune.py",": Causal-LM fine-tuning pipeline",[216,2436,2437],{},[219,2438,250,2439],{},[252,2440,2442],{"href":2441},"..\u002F..\u002Fsources\u002Flaco\u002Fexamples\u002Fpipelines\u002Fclm_finetune.py",[223,2443,2444],{},"sources\u002Flaco\u002Fexamples\u002Fpipelines\u002Fclm_finetune.py",[219,2446,2447,2448,2451,2452,1690,2455,2458],{},"Wires together a Qwen3-architecture language model (built via ",[223,2449,2450],{},"make_qwen3","), a HuggingFace tokenizer, a HuggingFace dataset slice, an AdamW optimizer partial, and a linear learning-rate scheduler partial. Demonstrates how laco handles non-PyTorch components (HF ",[223,2453,2454],{},"datasets",[223,2456,2457],{},"transformers",") alongside the standard torch stack.",[277,2460,2462],{"id":2461},"key-source-patterns","Key source patterns",[282,2464,2466],{"className":284,"code":2465,"language":286,"meta":287,"style":287},"import laco.language as L\nfrom laco.examples.models.qwen3 import make_qwen3\nfrom datasets import load_dataset\nfrom torch import optim\nfrom torch.optim import lr_scheduler\nfrom transformers import AutoTokenizer\n\n@L.params\nclass hps:\n    tokenizer_name: str = \"hf-internal-testing\u002Ftiny-random-Qwen2ForCausalLM\"\n    dataset_name: str = \"wikitext\"\n    dataset_config: str = \"wikitext-2-raw-v1\"\n    dataset_split: str = \"train[:100]\"\n    learning_rate: float = 5e-5\n    weight_decay: float = 0.01\n    warmup_steps: int = 100\n    vocab_size: int = 151_936\n    hidden_size: int = 1024\n    num_layers: int = 28\n    num_heads: int = 16\n    num_kv_heads: int = 8\n    intermediate_size: int = 3072\n\n\nmodel = make_qwen3(\n    vocab_size=hps.vocab_size,\n    hidden_size=hps.hidden_size,\n    num_layers=hps.num_layers,\n    num_heads=hps.num_heads,\n    num_kv_heads=hps.num_kv_heads,\n    intermediate_size=hps.intermediate_size,\n)\n\ntokenizer = L.call(AutoTokenizer.from_pretrained)(\n    pretrained_model_name_or_path=hps.tokenizer_name,\n)\n\ndataset = L.call(load_dataset)(\n    path=hps.dataset_name,\n    name=hps.dataset_config,\n    split=hps.dataset_split,\n)\n\noptimizer_partial = L.partial(optim.AdamW)(\n    lr=hps.learning_rate,\n    weight_decay=hps.weight_decay,\n)\n\nscheduler_partial = L.partial(lr_scheduler.LinearLR)(\n    start_factor=1e-6,\n    end_factor=1.0,\n    total_iters=hps.warmup_steps,\n)\n\ntrain = L.Dict(\n    model=model,\n    tokenizer=tokenizer,\n    dataset=dataset,\n    optimizer_partial=optimizer_partial,\n    scheduler_partial=scheduler_partial,\n)\n",[223,2467,2468,2482,2507,2519,2529,2545,2557,2561,2571,2579,2597,2615,2633,2651,2664,2678,2692,2706,2720,2734,2748,2762,2776,2780,2784,2795,2810,2825,2840,2855,2870,2885,2889,2893,2918,2934,2938,2942,2961,2977,2993,3009,3013,3017,3041,3056,3071,3075,3079,3104,3116,3128,3144,3148,3152,3166,3176,3188,3198,3210,3222],{"__ignoreMap":287},[291,2469,2470,2472,2474,2476,2478,2480],{"class":293,"line":294},[291,2471,298],{"class":297},[291,2473,302],{"class":301},[291,2475,233],{"class":305},[291,2477,198],{"class":308},[291,2479,311],{"class":297},[291,2481,314],{"class":301},[291,2483,2484,2486,2488,2490,2492,2494,2497,2499,2502,2504],{"class":293,"line":317},[291,2485,320],{"class":297},[291,2487,302],{"class":301},[291,2489,233],{"class":305},[291,2491,327],{"class":301},[291,2493,233],{"class":305},[291,2495,2496],{"class":301},"models",[291,2498,233],{"class":305},[291,2500,2501],{"class":301},"qwen3 ",[291,2503,298],{"class":297},[291,2505,2506],{"class":301}," make_qwen3\n",[291,2508,2509,2511,2514,2516],{"class":293,"line":340},[291,2510,320],{"class":297},[291,2512,2513],{"class":301}," datasets ",[291,2515,298],{"class":297},[291,2517,2518],{"class":301}," load_dataset\n",[291,2520,2521,2523,2525,2527],{"class":293,"line":359},[291,2522,320],{"class":297},[291,2524,345],{"class":301},[291,2526,298],{"class":297},[291,2528,356],{"class":301},[291,2530,2531,2533,2535,2537,2540,2542],{"class":293,"line":381},[291,2532,320],{"class":297},[291,2534,364],{"class":301},[291,2536,233],{"class":305},[291,2538,2539],{"class":301},"optim ",[291,2541,298],{"class":297},[291,2543,2544],{"class":301}," lr_scheduler\n",[291,2546,2547,2549,2552,2554],{"class":293,"line":394},[291,2548,320],{"class":297},[291,2550,2551],{"class":301}," transformers ",[291,2553,298],{"class":297},[291,2555,2556],{"class":301}," AutoTokenizer\n",[291,2558,2559],{"class":293,"line":413},[291,2560,417],{"emptyLinePlaceholder":416},[291,2562,2563,2565,2567,2569],{"class":293,"line":420},[291,2564,515],{"class":514},[291,2566,519],{"class":518},[291,2568,233],{"class":514},[291,2570,524],{"class":518},[291,2572,2573,2575,2577],{"class":293,"line":501},[291,2574,531],{"class":530},[291,2576,535],{"class":534},[291,2578,538],{"class":305},[291,2580,2581,2584,2586,2588,2590,2592,2595],{"class":293,"line":506},[291,2582,2583],{"class":301},"    tokenizer_name",[291,2585,547],{"class":305},[291,2587,551],{"class":550},[291,2589,427],{"class":426},[291,2591,445],{"class":433},[291,2593,2594],{"class":437},"hf-internal-testing\u002Ftiny-random-Qwen2ForCausalLM",[291,2596,561],{"class":433},[291,2598,2599,2602,2604,2606,2608,2610,2613],{"class":293,"line":511},[291,2600,2601],{"class":301},"    dataset_name",[291,2603,547],{"class":305},[291,2605,551],{"class":550},[291,2607,427],{"class":426},[291,2609,445],{"class":433},[291,2611,2612],{"class":437},"wikitext",[291,2614,561],{"class":433},[291,2616,2617,2620,2622,2624,2626,2628,2631],{"class":293,"line":527},[291,2618,2619],{"class":301},"    dataset_config",[291,2621,547],{"class":305},[291,2623,551],{"class":550},[291,2625,427],{"class":426},[291,2627,445],{"class":433},[291,2629,2630],{"class":437},"wikitext-2-raw-v1",[291,2632,561],{"class":433},[291,2634,2635,2638,2640,2642,2644,2646,2649],{"class":293,"line":541},[291,2636,2637],{"class":301},"    dataset_split",[291,2639,547],{"class":305},[291,2641,551],{"class":550},[291,2643,427],{"class":426},[291,2645,445],{"class":433},[291,2647,2648],{"class":437},"train[:100]",[291,2650,561],{"class":433},[291,2652,2653,2655,2657,2659,2661],{"class":293,"line":564},[291,2654,584],{"class":301},[291,2656,547],{"class":305},[291,2658,589],{"class":550},[291,2660,427],{"class":426},[291,2662,2663],{"class":577}," 5e-5\n",[291,2665,2666,2669,2671,2673,2675],{"class":293,"line":581},[291,2667,2668],{"class":301},"    weight_decay",[291,2670,547],{"class":305},[291,2672,589],{"class":550},[291,2674,427],{"class":426},[291,2676,2677],{"class":577}," 0.01\n",[291,2679,2680,2683,2685,2687,2689],{"class":293,"line":597},[291,2681,2682],{"class":301},"    warmup_steps",[291,2684,547],{"class":305},[291,2686,572],{"class":550},[291,2688,427],{"class":426},[291,2690,2691],{"class":577}," 100\n",[291,2693,2694,2697,2699,2701,2703],{"class":293,"line":612},[291,2695,2696],{"class":301},"    vocab_size",[291,2698,547],{"class":305},[291,2700,572],{"class":550},[291,2702,427],{"class":426},[291,2704,2705],{"class":577}," 151_936\n",[291,2707,2708,2711,2713,2715,2717],{"class":293,"line":627},[291,2709,2710],{"class":301},"    hidden_size",[291,2712,547],{"class":305},[291,2714,572],{"class":550},[291,2716,427],{"class":426},[291,2718,2719],{"class":577}," 1024\n",[291,2721,2722,2725,2727,2729,2731],{"class":293,"line":642},[291,2723,2724],{"class":301},"    num_layers",[291,2726,547],{"class":305},[291,2728,572],{"class":550},[291,2730,427],{"class":426},[291,2732,2733],{"class":577}," 28\n",[291,2735,2736,2739,2741,2743,2745],{"class":293,"line":657},[291,2737,2738],{"class":301},"    num_heads",[291,2740,547],{"class":305},[291,2742,572],{"class":550},[291,2744,427],{"class":426},[291,2746,2747],{"class":577}," 16\n",[291,2749,2750,2753,2755,2757,2759],{"class":293,"line":672},[291,2751,2752],{"class":301},"    num_kv_heads",[291,2754,547],{"class":305},[291,2756,572],{"class":550},[291,2758,427],{"class":426},[291,2760,2761],{"class":577}," 8\n",[291,2763,2764,2767,2769,2771,2773],{"class":293,"line":677},[291,2765,2766],{"class":301},"    intermediate_size",[291,2768,547],{"class":305},[291,2770,572],{"class":550},[291,2772,427],{"class":426},[291,2774,2775],{"class":577}," 3072\n",[291,2777,2778],{"class":293,"line":682},[291,2779,417],{"emptyLinePlaceholder":416},[291,2781,2782],{"class":293,"line":698},[291,2783,417],{"emptyLinePlaceholder":416},[291,2785,2786,2788,2790,2793],{"class":293,"line":716},[291,2787,685],{"class":301},[291,2789,688],{"class":426},[291,2791,2792],{"class":691}," make_qwen3",[291,2794,695],{"class":305},[291,2796,2797,2799,2801,2803,2805,2808],{"class":293,"line":732},[291,2798,2696],{"class":701},[291,2800,688],{"class":426},[291,2802,493],{"class":691},[291,2804,233],{"class":305},[291,2806,2807],{"class":308},"vocab_size",[291,2809,713],{"class":305},[291,2811,2812,2814,2816,2818,2820,2823],{"class":293,"line":748},[291,2813,2710],{"class":701},[291,2815,688],{"class":426},[291,2817,493],{"class":691},[291,2819,233],{"class":305},[291,2821,2822],{"class":308},"hidden_size",[291,2824,713],{"class":305},[291,2826,2827,2829,2831,2833,2835,2838],{"class":293,"line":764},[291,2828,2724],{"class":701},[291,2830,688],{"class":426},[291,2832,493],{"class":691},[291,2834,233],{"class":305},[291,2836,2837],{"class":308},"num_layers",[291,2839,713],{"class":305},[291,2841,2842,2844,2846,2848,2850,2853],{"class":293,"line":770},[291,2843,2738],{"class":701},[291,2845,688],{"class":426},[291,2847,493],{"class":691},[291,2849,233],{"class":305},[291,2851,2852],{"class":308},"num_heads",[291,2854,713],{"class":305},[291,2856,2857,2859,2861,2863,2865,2868],{"class":293,"line":775},[291,2858,2752],{"class":701},[291,2860,688],{"class":426},[291,2862,493],{"class":691},[291,2864,233],{"class":305},[291,2866,2867],{"class":308},"num_kv_heads",[291,2869,713],{"class":305},[291,2871,2872,2874,2876,2878,2880,2883],{"class":293,"line":819},[291,2873,2766],{"class":701},[291,2875,688],{"class":426},[291,2877,493],{"class":691},[291,2879,233],{"class":305},[291,2881,2882],{"class":308},"intermediate_size",[291,2884,713],{"class":305},[291,2886,2887],{"class":293,"line":846},[291,2888,767],{"class":305},[291,2890,2891],{"class":293,"line":851},[291,2892,417],{"emptyLinePlaceholder":416},[291,2894,2895,2898,2900,2902,2904,2906,2908,2911,2913,2916],{"class":293,"line":878},[291,2896,2897],{"class":301},"tokenizer ",[291,2899,688],{"class":426},[291,2901,783],{"class":301},[291,2903,233],{"class":305},[291,2905,831],{"class":691},[291,2907,791],{"class":305},[291,2909,2910],{"class":691},"AutoTokenizer",[291,2912,233],{"class":305},[291,2914,2915],{"class":308},"from_pretrained",[291,2917,875],{"class":305},[291,2919,2920,2923,2925,2927,2929,2932],{"class":293,"line":891},[291,2921,2922],{"class":701},"    pretrained_model_name_or_path",[291,2924,688],{"class":426},[291,2926,493],{"class":691},[291,2928,233],{"class":305},[291,2930,2931],{"class":308},"tokenizer_name",[291,2933,713],{"class":305},[291,2935,2936],{"class":293,"line":913},[291,2937,767],{"class":305},[291,2939,2940],{"class":293,"line":971},[291,2941,417],{"emptyLinePlaceholder":416},[291,2943,2944,2946,2948,2950,2952,2954,2956,2959],{"class":293,"line":977},[291,2945,990],{"class":301},[291,2947,688],{"class":426},[291,2949,783],{"class":301},[291,2951,233],{"class":305},[291,2953,831],{"class":691},[291,2955,791],{"class":305},[291,2957,2958],{"class":691},"load_dataset",[291,2960,875],{"class":305},[291,2962,2963,2966,2968,2970,2972,2975],{"class":293,"line":982},[291,2964,2965],{"class":701},"    path",[291,2967,688],{"class":426},[291,2969,493],{"class":691},[291,2971,233],{"class":305},[291,2973,2974],{"class":308},"dataset_name",[291,2976,713],{"class":305},[291,2978,2979,2982,2984,2986,2988,2991],{"class":293,"line":987},[291,2980,2981],{"class":701},"    name",[291,2983,688],{"class":426},[291,2985,493],{"class":691},[291,2987,233],{"class":305},[291,2989,2990],{"class":308},"dataset_config",[291,2992,713],{"class":305},[291,2994,2995,2998,3000,3002,3004,3007],{"class":293,"line":1009},[291,2996,2997],{"class":701},"    split",[291,2999,688],{"class":426},[291,3001,493],{"class":691},[291,3003,233],{"class":305},[291,3005,3006],{"class":308},"dataset_split",[291,3008,713],{"class":305},[291,3010,3011],{"class":293,"line":1026},[291,3012,767],{"class":305},[291,3014,3015],{"class":293,"line":1040},[291,3016,417],{"emptyLinePlaceholder":416},[291,3018,3019,3022,3024,3026,3028,3030,3032,3034,3036,3039],{"class":293,"line":1052},[291,3020,3021],{"class":301},"optimizer_partial ",[291,3023,688],{"class":426},[291,3025,783],{"class":301},[291,3027,233],{"class":305},[291,3029,788],{"class":691},[291,3031,791],{"class":305},[291,3033,794],{"class":691},[291,3035,233],{"class":305},[291,3037,3038],{"class":308},"AdamW",[291,3040,875],{"class":305},[291,3042,3043,3046,3048,3050,3052,3054],{"class":293,"line":1065},[291,3044,3045],{"class":701},"    lr",[291,3047,688],{"class":426},[291,3049,493],{"class":691},[291,3051,233],{"class":305},[291,3053,814],{"class":308},[291,3055,713],{"class":305},[291,3057,3058,3060,3062,3064,3066,3069],{"class":293,"line":1070},[291,3059,2668],{"class":701},[291,3061,688],{"class":426},[291,3063,493],{"class":691},[291,3065,233],{"class":305},[291,3067,3068],{"class":308},"weight_decay",[291,3070,713],{"class":305},[291,3072,3073],{"class":293,"line":1075},[291,3074,767],{"class":305},[291,3076,3077],{"class":293,"line":1095},[291,3078,417],{"emptyLinePlaceholder":416},[291,3080,3081,3084,3086,3088,3090,3092,3094,3097,3099,3102],{"class":293,"line":1107},[291,3082,3083],{"class":301},"scheduler_partial ",[291,3085,688],{"class":426},[291,3087,783],{"class":301},[291,3089,233],{"class":305},[291,3091,788],{"class":691},[291,3093,791],{"class":305},[291,3095,3096],{"class":691},"lr_scheduler",[291,3098,233],{"class":305},[291,3100,3101],{"class":308},"LinearLR",[291,3103,875],{"class":305},[291,3105,3106,3109,3111,3114],{"class":293,"line":1123},[291,3107,3108],{"class":701},"    start_factor",[291,3110,688],{"class":426},[291,3112,3113],{"class":577},"1e-6",[291,3115,713],{"class":305},[291,3117,3118,3121,3123,3126],{"class":293,"line":1135},[291,3119,3120],{"class":701},"    end_factor",[291,3122,688],{"class":426},[291,3124,3125],{"class":577},"1.0",[291,3127,713],{"class":305},[291,3129,3130,3133,3135,3137,3139,3142],{"class":293,"line":1151},[291,3131,3132],{"class":701},"    total_iters",[291,3134,688],{"class":426},[291,3136,493],{"class":691},[291,3138,233],{"class":305},[291,3140,3141],{"class":308},"warmup_steps",[291,3143,713],{"class":305},[291,3145,3146],{"class":293,"line":1156},[291,3147,767],{"class":305},[291,3149,3150],{"class":293,"line":1161},[291,3151,417],{"emptyLinePlaceholder":416},[291,3153,3154,3156,3158,3160,3162,3164],{"class":293,"line":1178},[291,3155,1164],{"class":301},[291,3157,688],{"class":426},[291,3159,783],{"class":301},[291,3161,233],{"class":305},[291,3163,1173],{"class":691},[291,3165,695],{"class":305},[291,3167,3168,3170,3172,3174],{"class":293,"line":1190},[291,3169,1181],{"class":701},[291,3171,688],{"class":426},[291,3173,438],{"class":691},[291,3175,713],{"class":305},[291,3177,3178,3181,3183,3186],{"class":293,"line":1202},[291,3179,3180],{"class":701},"    tokenizer",[291,3182,688],{"class":426},[291,3184,3185],{"class":691},"tokenizer",[291,3187,713],{"class":305},[291,3189,3190,3192,3194,3196],{"class":293,"line":1214},[291,3191,1098],{"class":701},[291,3193,688],{"class":426},[291,3195,466],{"class":691},[291,3197,713],{"class":305},[291,3199,3200,3203,3205,3208],{"class":293,"line":1226},[291,3201,3202],{"class":701},"    optimizer_partial",[291,3204,688],{"class":426},[291,3206,3207],{"class":691},"optimizer_partial",[291,3209,713],{"class":305},[291,3211,3212,3215,3217,3220],{"class":293,"line":1231},[291,3213,3214],{"class":701},"    scheduler_partial",[291,3216,688],{"class":426},[291,3218,3219],{"class":691},"scheduler_partial",[291,3221,713],{"class":305},[291,3223,3224],{"class":293,"line":1236},[291,3225,767],{"class":305},[277,3227,3229],{"id":3228},"what-this-additionally-demonstrates-beyond-mnist","What this additionally demonstrates (beyond MNIST)",[2382,3231,3232,3238,3247,3258],{},[2385,3233,3234,3237],{},[223,3235,3236],{},"L.call(AutoTokenizer.from_pretrained)",": any callable (including class methods and module-level functions) as a config target",[2385,3239,3240,3243,3244,3246],{},[223,3241,3242],{},"L.call(load_dataset)",": HuggingFace ",[223,3245,2454],{}," API as a first-class config node",[2385,3248,3249,3250,3252,3253,3255,3256,1345],{},"Two-partial pattern: ",[223,3251,3207],{}," and ",[223,3254,3219],{}," are both deferred factories, because the scheduler also needs the optimizer object (itself needing ",[223,3257,1723],{},[2385,3259,3260,3262,3263,3265,3266,3269],{},[223,3261,2807],{}," as an ",[223,3264,493],{}," field that is both a model architecture parameter ",[1921,3267,3268],{},"and"," a tokenizer-derived value: the pipeline owns the alignment between the two",[235,3271],{},[238,3273,3275],{"id":3274},"pipeline-patterns","Pipeline patterns",[219,3277,3278],{},"The following conventions apply to all Tier-6 pipeline files.",[277,3280,3282,3283,3285],{"id":3281},"_1-use-ldict-as-the-pipeline-root","1. Use ",[223,3284,1818],{}," as the pipeline root",[282,3287,3289],{"className":284,"code":3288,"language":286,"meta":287,"style":287},"train = L.Dict(\n    model=model,\n    optimizer=optimizer,\n    loss=loss,\n    loader=loader,\n)\n",[223,3290,3291,3305,3315,3325,3335,3345],{"__ignoreMap":287},[291,3292,3293,3295,3297,3299,3301,3303],{"class":293,"line":294},[291,3294,1164],{"class":301},[291,3296,688],{"class":426},[291,3298,783],{"class":301},[291,3300,233],{"class":305},[291,3302,1173],{"class":691},[291,3304,695],{"class":305},[291,3306,3307,3309,3311,3313],{"class":293,"line":317},[291,3308,1181],{"class":701},[291,3310,688],{"class":426},[291,3312,438],{"class":691},[291,3314,713],{"class":305},[291,3316,3317,3319,3321,3323],{"class":293,"line":340},[291,3318,1193],{"class":701},[291,3320,688],{"class":426},[291,3322,448],{"class":691},[291,3324,713],{"class":305},[291,3326,3327,3329,3331,3333],{"class":293,"line":359},[291,3328,1205],{"class":701},[291,3330,688],{"class":426},[291,3332,457],{"class":691},[291,3334,713],{"class":305},[291,3336,3337,3339,3341,3343],{"class":293,"line":381},[291,3338,1217],{"class":701},[291,3340,688],{"class":426},[291,3342,475],{"class":691},[291,3344,713],{"class":305},[291,3346,3347],{"class":293,"line":394},[291,3348,767],{"class":305},[219,3350,3351,3353],{},[223,3352,1818],{}," produces a named mapping as the pipeline root. This enables:",[2382,3355,3356,3363,3369],{},[2385,3357,3358,3359,3362],{},"Fragment selection: ",[223,3360,3361],{},"laco.load(\"...#train\")"," returns only the training bundle",[2385,3364,3365,3366,3368],{},"Clean instantiation: ",[223,3367,1826],{}," instantiates all components",[2385,3370,3371,3372,3374],{},"Partial loading: a downstream config can embed ",[223,3373,484],{}," as a sub-tree",[277,3376,3378,3379,3381],{"id":3377},"_2-use-lpartial-for-objects-that-need-runtime-tensors","2. Use ",[223,3380,1719],{}," for objects that need runtime tensors",[282,3383,3385],{"className":284,"code":3384,"language":286,"meta":287,"style":287},"# Correct: optimizer receives model.parameters() inside @L.task\noptimizer = L.partial(optim.Adam)(lr=hps.learning_rate)\n\n# Wrong: model.parameters() does not exist at config-build time\n# optimizer = L.call(optim.Adam)(params=model.parameters(), ...)\n",[223,3386,3387,3392,3426,3430,3435],{"__ignoreMap":287},[291,3388,3389],{"class":293,"line":294},[291,3390,3391],{"class":1958},"# Correct: optimizer receives model.parameters() inside @L.task\n",[291,3393,3394,3396,3398,3400,3402,3404,3406,3408,3410,3412,3414,3416,3418,3420,3422,3424],{"class":293,"line":317},[291,3395,778],{"class":301},[291,3397,688],{"class":426},[291,3399,783],{"class":301},[291,3401,233],{"class":305},[291,3403,788],{"class":691},[291,3405,791],{"class":305},[291,3407,794],{"class":691},[291,3409,233],{"class":305},[291,3411,799],{"class":308},[291,3413,802],{"class":305},[291,3415,805],{"class":701},[291,3417,688],{"class":426},[291,3419,493],{"class":691},[291,3421,233],{"class":305},[291,3423,814],{"class":308},[291,3425,767],{"class":305},[291,3427,3428],{"class":293,"line":340},[291,3429,417],{"emptyLinePlaceholder":416},[291,3431,3432],{"class":293,"line":359},[291,3433,3434],{"class":1958},"# Wrong: model.parameters() does not exist at config-build time\n",[291,3436,3437],{"class":293,"line":381},[291,3438,3439],{"class":1958},"# optimizer = L.call(optim.Adam)(params=model.parameters(), ...)\n",[219,3441,3442,3443,3445],{},"Optimizers and LR schedulers always use ",[223,3444,1719],{},". The partial is called inside the task function after the model has been instantiated.",[277,3447,3449,3450,3452],{"id":3448},"_3-annotate-the-ltask-entry-point-with-types","3. Annotate the ",[223,3451,225],{}," entry point with types",[282,3454,3456],{"className":284,"code":3455,"language":286,"meta":287,"style":287},"@L.task\ndef task(\n    model: nn.Module,\n    optimizer: optim.Optimizer,\n    loss: nn.Module,\n    loader: DataLoader,\n    num_steps: int = 1,\n) -> None:\n    ...\n",[223,3457,3458,3468,3476,3490,3504,3518,3528,3542,3552],{"__ignoreMap":287},[291,3459,3460,3462,3464,3466],{"class":293,"line":294},[291,3461,515],{"class":514},[291,3463,519],{"class":518},[291,3465,233],{"class":514},[291,3467,1250],{"class":518},[291,3469,3470,3472,3474],{"class":293,"line":317},[291,3471,1256],{"class":530},[291,3473,1259],{"class":518},[291,3475,695],{"class":305},[291,3477,3478,3480,3482,3484,3486,3488],{"class":293,"line":340},[291,3479,1181],{"class":1267},[291,3481,547],{"class":305},[291,3483,350],{"class":301},[291,3485,233],{"class":305},[291,3487,1276],{"class":308},[291,3489,713],{"class":305},[291,3491,3492,3494,3496,3498,3500,3502],{"class":293,"line":359},[291,3493,1193],{"class":1267},[291,3495,547],{"class":305},[291,3497,1288],{"class":301},[291,3499,233],{"class":305},[291,3501,1293],{"class":308},[291,3503,713],{"class":305},[291,3505,3506,3508,3510,3512,3514,3516],{"class":293,"line":381},[291,3507,1205],{"class":1267},[291,3509,547],{"class":305},[291,3511,350],{"class":301},[291,3513,233],{"class":305},[291,3515,1276],{"class":308},[291,3517,713],{"class":305},[291,3519,3520,3522,3524,3526],{"class":293,"line":394},[291,3521,1217],{"class":1267},[291,3523,547],{"class":305},[291,3525,1320],{"class":301},[291,3527,713],{"class":305},[291,3529,3530,3532,3534,3536,3538,3540],{"class":293,"line":413},[291,3531,1328],{"class":1267},[291,3533,547],{"class":305},[291,3535,572],{"class":550},[291,3537,427],{"class":426},[291,3539,1337],{"class":577},[291,3541,713],{"class":305},[291,3543,3544,3546,3548,3550],{"class":293,"line":420},[291,3545,1345],{"class":305},[291,3547,1348],{"class":305},[291,3549,1351],{"class":1034},[291,3551,538],{"class":305},[291,3553,3554],{"class":293,"line":501},[291,3555,3556],{"class":409},"    ...\n",[219,3558,3559,3561,3562,3564],{},[223,3560,225],{}," uses the parameter names to match config keys. Type annotations are used for static checking and are not enforced at runtime by laco. Parameters with default values (like ",[223,3563,1425],{},") can be overridden from the CLI without appearing in the config root.",[277,3566,3568],{"id":3567},"_4-use-the-self-loading-pattern-for-direct-execution","4. Use the self-loading pattern for direct execution",[282,3570,3572],{"className":284,"code":3571,"language":286,"meta":287,"style":287},"if __name__ == \"__main__\":\n    import laco\n\n    cfg = laco.load(__file__ + \"#train\")\n    task(cfg)\n",[223,3573,3574,3590,3596,3600,3626],{"__ignoreMap":287},[291,3575,3576,3578,3580,3582,3584,3586,3588],{"class":293,"line":294},[291,3577,1600],{"class":297},[291,3579,1603],{"class":409},[291,3581,1606],{"class":426},[291,3583,445],{"class":433},[291,3585,1611],{"class":437},[291,3587,434],{"class":433},[291,3589,538],{"class":305},[291,3591,3592,3594],{"class":293,"line":317},[291,3593,1621],{"class":297},[291,3595,1624],{"class":301},[291,3597,3598],{"class":293,"line":340},[291,3599,417],{"emptyLinePlaceholder":416},[291,3601,3602,3604,3606,3608,3610,3612,3614,3616,3618,3620,3622,3624],{"class":293,"line":359},[291,3603,1635],{"class":301},[291,3605,688],{"class":426},[291,3607,302],{"class":301},[291,3609,233],{"class":305},[291,3611,1644],{"class":691},[291,3613,791],{"class":305},[291,3615,1649],{"class":409},[291,3617,1652],{"class":426},[291,3619,445],{"class":433},[291,3621,1657],{"class":437},[291,3623,434],{"class":433},[291,3625,767],{"class":305},[291,3627,3628,3630,3632,3634],{"class":293,"line":381},[291,3629,1667],{"class":691},[291,3631,791],{"class":305},[291,3633,1672],{"class":691},[291,3635,767],{"class":305},[219,3637,3638,3640,3641,3644,3645,3647],{},[223,3639,1649],{}," resolves to the absolute path of the current module. Appending ",[223,3642,3643],{},"\"#train\""," selects the ",[223,3646,484],{}," bundle. This pattern allows the file to be both a laco config (importable by other pipelines) and a runnable script.",[277,3649,3651],{"id":3650},"_5-import-config-factories-from-sibling-files-with-absolute-style-imports","5. Import config factories from sibling files with absolute-style imports",[282,3653,3655],{"className":284,"code":3654,"language":286,"meta":287,"style":287},"# Pipeline imports the factory, not the instantiated model\nfrom laco.examples.cnn_classifier import make_cnn_classifier\nfrom laco.examples.models.qwen3 import make_qwen3\n\nmodel = make_cnn_classifier(in_channels=hps.in_channels, ...)\n",[223,3656,3657,3662,3680,3702,3706],{"__ignoreMap":287},[291,3658,3659],{"class":293,"line":294},[291,3660,3661],{"class":1958},"# Pipeline imports the factory, not the instantiated model\n",[291,3663,3664,3666,3668,3670,3672,3674,3676,3678],{"class":293,"line":317},[291,3665,320],{"class":297},[291,3667,302],{"class":301},[291,3669,233],{"class":305},[291,3671,327],{"class":301},[291,3673,233],{"class":305},[291,3675,332],{"class":301},[291,3677,298],{"class":297},[291,3679,337],{"class":301},[291,3681,3682,3684,3686,3688,3690,3692,3694,3696,3698,3700],{"class":293,"line":340},[291,3683,320],{"class":297},[291,3685,302],{"class":301},[291,3687,233],{"class":305},[291,3689,327],{"class":301},[291,3691,233],{"class":305},[291,3693,2496],{"class":301},[291,3695,233],{"class":305},[291,3697,2501],{"class":301},[291,3699,298],{"class":297},[291,3701,2506],{"class":301},[291,3703,3704],{"class":293,"line":359},[291,3705,417],{"emptyLinePlaceholder":416},[291,3707,3708,3710,3712,3714,3716,3718,3720,3722,3724,3726,3728,3731],{"class":293,"line":381},[291,3709,685],{"class":301},[291,3711,688],{"class":426},[291,3713,692],{"class":691},[291,3715,791],{"class":305},[291,3717,710],{"class":701},[291,3719,688],{"class":426},[291,3721,493],{"class":691},[291,3723,233],{"class":305},[291,3725,710],{"class":308},[291,3727,353],{"class":305},[291,3729,3730],{"class":1003}," ...",[291,3732,767],{"class":305},[219,3734,3735,3736,3738,3739,3741],{},"Always import the factory function, not the module-level ",[223,3737,438],{}," variable. The module-level variable is built with that module's own ",[223,3740,493],{}," defaults; the factory lets the pipeline supply its own.",[3743,3744,3745],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .stp6e, html code.shiki .stp6e{--shiki-light:#39ADB5;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sFwrP, html code.shiki .sFwrP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":287,"searchDepth":340,"depth":340,"links":3747},[3748,3757,3762],{"id":240,"depth":317,"text":3749,"children":3750},"1. pipelines\u002Fmnist_train.py: MNIST training pipeline",[3751,3752,3753,3754,3755,3756],{"id":279,"depth":340,"text":280},{"id":1677,"depth":340,"text":1678},{"id":1937,"depth":340,"text":1938},{"id":2116,"depth":340,"text":2117},{"id":2283,"depth":340,"text":2284},{"id":2379,"depth":340,"text":2380},{"id":2429,"depth":317,"text":3758,"children":3759},"2. pipelines\u002Fclm_finetune.py: Causal-LM fine-tuning pipeline",[3760,3761],{"id":2461,"depth":340,"text":2462},{"id":3228,"depth":340,"text":3229},{"id":3274,"depth":317,"text":3275,"children":3763},[3764,3766,3768,3770,3771],{"id":3281,"depth":340,"text":3765},"1. Use L.Dict as the pipeline root",{"id":3377,"depth":340,"text":3767},"2. Use L.partial for objects that need runtime tensors",{"id":3448,"depth":340,"text":3769},"3. Annotate the @L.task entry point with types",{"id":3567,"depth":340,"text":3568},{"id":3650,"depth":340,"text":3651},"md",{},{"title":152,"description":287},"NaO_pX4SBr_pRmuslFZYq8vOahTDYRZpTzlT13ScmCk",{},1785687297284]