[{"data":1,"prerenderedAt":3278},["ShallowReactive",2],{"navigation":3,"api-navigation":184,"\u002Flearn\u002Ftutorials\u002Flazy-call-and-partial":206,"docyard:crossref-index":3277},[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":31,"body":208,"description":3271,"extension":3272,"meta":3273,"navigation":3274,"path":32,"seo":3275,"stem":33,"__hash__":3276},"content\u002F2.learn\u002F1.tutorials\u002F03.lazy-call-and-partial.md",{"type":209,"value":210,"toc":3250},"minimark",[211,215,256,259,283,286,377,388,474,479,482,555,560,690,693,698,751,759,772,793,796,995,998,1006,1017,1115,1118,1121,1128,1135,1141,1152,1163,1207,1210,1217,1235,1355,1358,1569,1572,1575,1604,1607,1611,1614,1680,1691,1698,1711,1919,1922,1941,1947,1954,1966,2061,2064,2202,2205,2294,2297,2306,2312,2376,2390,2398,2407,3008,3011,3177,3180,3184,3233,3246],[212,213,31],"h1",{"id":214},"lazy-call-and-partial",[216,217,218,222,223,226,229,230,234,235,238,239,241,229,244,247,248,251,252,255],"p",{},[219,220,221],"strong",{},"Series:"," laco tutorial notebooks",[224,225],"br",{},[219,227,228],{},"Prerequisites:"," ",[231,232,233],"code",{},"01.why-laco.ipynb"," (motivation), ",[231,236,237],{},"02.first-steps.ipynb"," (config basics)",[224,240],{},[219,242,243],{},"Dependencies:",[231,245,246],{},"torch"," (for ",[231,249,250],{},"nn.Linear",", ",[231,253,254],{},"optim.Adam",")",[257,258],"hr",{},[216,260,261,262,265,266,270,271,274,275,278,279,282],{},"Python builds objects the moment you call their constructor. ",[231,263,264],{},"nn.Linear(784, 10)"," runs ",[267,268,269],"em",{},"right now",". laco lets you write the same constructor call but defer it: the result is a plain data structure (an OmegaConf ",[231,272,273],{},"DictConfig",") that describes ",[219,276,277],{},"how"," to build something without ",[219,280,281],{},"doing"," it.",[216,284,285],{},"This notebook covers:",[287,288,289,305],"table",{},[290,291,292],"thead",{},[293,294,295,299,302],"tr",{},[296,297,298],"th",{},"Construct",[296,300,301],{},"What it produces at runtime",[296,303,304],{},"What it types as (IDE)",[306,307,308,326,346,361],"tbody",{},[293,309,310,316,321],{},[311,312,313],"td",{},[231,314,315],{},"L.call(T)(**kw)",[311,317,318,320],{},[231,319,273],{}," node",[311,322,323],{},[231,324,325],{},"T",[293,327,328,333,341],{},[311,329,330],{},[231,331,332],{},"L.partial(fn)(**kw)",[311,334,335,337,338],{},[231,336,273],{}," with ",[231,339,340],{},"_partial_: true",[311,342,343],{},[231,344,345],{},"functools.partial[T]",[293,347,348,353,356],{},[311,349,350],{},[231,351,352],{},"L.just(value)",[311,354,355],{},"identity-instantiated node",[311,357,358],{},[231,359,360],{},"type(value)",[293,362,363,368,373],{},[311,364,365],{},[231,366,367],{},"L.required[T]()",[311,369,370],{},[231,371,372],{},"omegaconf.MISSING",[311,374,375],{},[231,376,325],{},[216,378,379,380,383,384,387],{},"By the end you will understand why a PyTorch optimizer ",[267,381,382],{},"must"," use ",[231,385,386],{},"L.partial",", and how the timing table separates config-build time from run time.",[389,390,395],"pre",{"className":391,"code":392,"language":393,"meta":394,"style":394},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","import laco\nimport laco.language as L\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\n","python","",[231,396,397,410,431,439,457],{"__ignoreMap":394},[398,399,402,406],"span",{"class":400,"line":401},"line",1,[398,403,405],{"class":404},"sVHd0","import",[398,407,409],{"class":408},"su5hD"," laco\n",[398,411,413,415,418,422,425,428],{"class":400,"line":412},2,[398,414,405],{"class":404},[398,416,417],{"class":408}," laco",[398,419,421],{"class":420},"sP7_E",".",[398,423,198],{"class":424},"skxfh",[398,426,427],{"class":404}," as",[398,429,430],{"class":408}," L\n",[398,432,434,436],{"class":400,"line":433},3,[398,435,405],{"class":404},[398,437,438],{"class":408}," torch\n",[398,440,442,444,447,449,452,454],{"class":400,"line":441},4,[398,443,405],{"class":404},[398,445,446],{"class":408}," torch",[398,448,421],{"class":420},[398,450,451],{"class":424},"nn",[398,453,427],{"class":404},[398,455,456],{"class":408}," nn\n",[398,458,460,462,464,466,469,471],{"class":400,"line":459},5,[398,461,405],{"class":404},[398,463,446],{"class":408},[398,465,421],{"class":420},[398,467,468],{"class":424},"optim",[398,470,427],{"class":404},[398,472,473],{"class":408}," optim\n",[475,476,478],"h2",{"id":477},"section-1-when-does-construction-happen","Section 1: When does construction happen?",[216,480,481],{},"With plain Python, construction happens on the line where you call the constructor. There is no separation between \"describe what to build\" and \"build it\".",[389,483,485],{"className":391,"code":484,"language":393,"meta":394,"style":394},"# --- Plain Python (eager) ---\n# The model exists the instant this line runs.\nmodel_eager = nn.Linear(784, 10)\nprint(type(model_eager))  # \u003Cclass 'torch.nn.modules.linear.Linear'>\n",[231,486,487,493,498,532],{"__ignoreMap":394},[398,488,489],{"class":400,"line":401},[398,490,492],{"class":491},"sutJx","# --- Plain Python (eager) ---\n",[398,494,495],{"class":400,"line":412},[398,496,497],{"class":491},"# The model exists the instant this line runs.\n",[398,499,500,503,507,510,512,516,519,523,526,529],{"class":400,"line":433},[398,501,502],{"class":408},"model_eager ",[398,504,506],{"class":505},"smGrS","=",[398,508,509],{"class":408}," nn",[398,511,421],{"class":420},[398,513,515],{"class":514},"slqww","Linear",[398,517,518],{"class":420},"(",[398,520,522],{"class":521},"srdBf","784",[398,524,525],{"class":420},",",[398,527,528],{"class":521}," 10",[398,530,531],{"class":420},")\n",[398,533,534,538,540,544,546,549,552],{"class":400,"line":441},[398,535,537],{"class":536},"sptTA","print",[398,539,518],{"class":420},[398,541,543],{"class":542},"sZMiF","type",[398,545,518],{"class":420},[398,547,548],{"class":514},"model_eager",[398,550,551],{"class":420},"))",[398,553,554],{"class":491},"  # \u003Cclass 'torch.nn.modules.linear.Linear'>\n",[556,557],"docyard-notebook-output",{"data":558,"kind":559},"PGNsYXNzICd0b3JjaC5ubi5tb2R1bGVzLmxpbmVhci5MaW5lYXInPgo=","stream",[389,561,563],{"className":391,"code":562,"language":393,"meta":394,"style":394},"# --- laco (lazy) ---\n# L.call returns a DictConfig — a recipe, not a model.\ncfg = L.call(nn.Linear)(in_features=784, out_features=10)\nprint(type(cfg))  # \u003Cclass 'omegaconf.DictConfig'>\n\n# Construction happens here:\nmodel_lazy = laco.instantiate(cfg)\nprint(type(model_lazy))  # \u003Cclass 'torch.nn.modules.linear.Linear'>\n",[231,564,565,570,575,621,639,645,651,672],{"__ignoreMap":394},[398,566,567],{"class":400,"line":401},[398,568,569],{"class":491},"# --- laco (lazy) ---\n",[398,571,572],{"class":400,"line":412},[398,573,574],{"class":491},"# L.call returns a DictConfig — a recipe, not a model.\n",[398,576,577,580,582,585,587,590,592,594,596,598,601,605,607,609,611,614,616,619],{"class":400,"line":433},[398,578,579],{"class":408},"cfg ",[398,581,506],{"class":505},[398,583,584],{"class":408}," L",[398,586,421],{"class":420},[398,588,589],{"class":514},"call",[398,591,518],{"class":420},[398,593,451],{"class":514},[398,595,421],{"class":420},[398,597,515],{"class":424},[398,599,600],{"class":420},")(",[398,602,604],{"class":603},"s99_P","in_features",[398,606,506],{"class":505},[398,608,522],{"class":521},[398,610,525],{"class":420},[398,612,613],{"class":603}," out_features",[398,615,506],{"class":505},[398,617,618],{"class":521},"10",[398,620,531],{"class":420},[398,622,623,625,627,629,631,634,636],{"class":400,"line":441},[398,624,537],{"class":536},[398,626,518],{"class":420},[398,628,543],{"class":542},[398,630,518],{"class":420},[398,632,633],{"class":514},"cfg",[398,635,551],{"class":420},[398,637,638],{"class":491},"  # \u003Cclass 'omegaconf.DictConfig'>\n",[398,640,641],{"class":400,"line":459},[398,642,644],{"emptyLinePlaceholder":643},true,"\n",[398,646,648],{"class":400,"line":647},6,[398,649,650],{"class":491},"# Construction happens here:\n",[398,652,654,657,659,661,663,666,668,670],{"class":400,"line":653},7,[398,655,656],{"class":408},"model_lazy ",[398,658,506],{"class":505},[398,660,417],{"class":408},[398,662,421],{"class":420},[398,664,665],{"class":514},"instantiate",[398,667,518],{"class":420},[398,669,633],{"class":514},[398,671,531],{"class":420},[398,673,675,677,679,681,683,686,688],{"class":400,"line":674},8,[398,676,537],{"class":536},[398,678,518],{"class":420},[398,680,543],{"class":542},[398,682,518],{"class":420},[398,684,685],{"class":514},"model_lazy",[398,687,551],{"class":420},[398,689,554],{"class":491},[556,691],{"data":692,"kind":559},"PGNsYXNzICdvbWVnYWNvbmYuZGljdGNvbmZpZy5EaWN0Q29uZmlnJz4KPGNsYXNzICd0b3JjaC5ubi5tb2R1bGVzLmxpbmVhci5MaW5lYXInPgo=",[216,694,695],{},[219,696,697],{},"Why would you want to delay construction?",[699,700,701,715,733],"ol",{},[702,703,704,707,708,710,711,714],"li",{},[219,705,706],{},"Serializable."," A ",[231,709,273],{}," can be saved to YAML and loaded back on another machine. A live ",[231,712,713],{},"nn.Module"," cannot.",[702,716,717,720,721,724,725,728,729,732],{},[219,718,719],{},"Overridable."," Before calling ",[231,722,723],{},"laco.instantiate",", you can swap ",[231,726,727],{},"in_features=784"," for ",[231,730,731],{},"in_features=512"," with a one-liner: no re-import, no find-and-replace.",[702,734,735,738,739,742,743,746,747,750],{},[219,736,737],{},"Composable."," Config nodes nest: a ",[231,740,741],{},"model_cfg"," can contain an ",[231,744,745],{},"encoder_cfg"," which contains a ",[231,748,749],{},"layer_cfg",". The whole tree is a dict you can inspect, diff, and version-control.",[475,752,754,755,758],{"id":753},"section-2-lcall-in-detail","Section 2: ",[231,756,757],{},"L.call"," in detail",[216,760,761,762,765,766,768,769,771],{},"When you call ",[231,763,764],{},"L.call(nn.Linear)(in_features=784, out_features=10)",", laco builds a ",[231,767,273],{}," with special keys that Hydra (and ",[231,770,723],{},") understand:",[773,774,775,781,790],"ul",{},[702,776,777,780],{},[231,778,779],{},"_target_",": the dotted import path of the class to construct",[702,782,783,786,787,255],{},[231,784,785],{},"_convert_",": how to convert OmegaConf containers (default: ",[231,788,789],{},"\"all\"",[702,791,792],{},"everything else: the constructor keyword arguments",[216,794,795],{},"Let's inspect the raw node:",[389,797,799],{"className":391,"code":798,"language":393,"meta":394,"style":394},"cfg = L.call(nn.Linear)(in_features=784, out_features=10)\n\nprint(\"_target_ :\", cfg._target_)    # noqa: LACO001\nprint(\"_convert_:\", cfg._convert_)   # noqa: LACO001\nprint(\"in_features :\", cfg.in_features)   # noqa: LACO001\nprint(\"out_features:\", cfg.out_features)  # noqa: LACO001\nprint()\nprint(\"--- laco.dump (YAML) ---\")\nprint(laco.dump(cfg))\n",[231,800,801,839,843,873,899,924,951,958,973],{"__ignoreMap":394},[398,802,803,805,807,809,811,813,815,817,819,821,823,825,827,829,831,833,835,837],{"class":400,"line":401},[398,804,579],{"class":408},[398,806,506],{"class":505},[398,808,584],{"class":408},[398,810,421],{"class":420},[398,812,589],{"class":514},[398,814,518],{"class":420},[398,816,451],{"class":514},[398,818,421],{"class":420},[398,820,515],{"class":424},[398,822,600],{"class":420},[398,824,604],{"class":603},[398,826,506],{"class":505},[398,828,522],{"class":521},[398,830,525],{"class":420},[398,832,613],{"class":603},[398,834,506],{"class":505},[398,836,618],{"class":521},[398,838,531],{"class":420},[398,840,841],{"class":400,"line":412},[398,842,644],{"emptyLinePlaceholder":643},[398,844,845,847,849,853,857,859,861,864,866,868,870],{"class":400,"line":433},[398,846,537],{"class":536},[398,848,518],{"class":420},[398,850,852],{"class":851},"sjJ54","\"",[398,854,856],{"class":855},"s_sjI","_target_ :",[398,858,852],{"class":851},[398,860,525],{"class":420},[398,862,863],{"class":514}," cfg",[398,865,421],{"class":420},[398,867,779],{"class":424},[398,869,255],{"class":420},[398,871,872],{"class":491},"    # noqa: LACO001\n",[398,874,875,877,879,881,884,886,888,890,892,894,896],{"class":400,"line":441},[398,876,537],{"class":536},[398,878,518],{"class":420},[398,880,852],{"class":851},[398,882,883],{"class":855},"_convert_:",[398,885,852],{"class":851},[398,887,525],{"class":420},[398,889,863],{"class":514},[398,891,421],{"class":420},[398,893,785],{"class":424},[398,895,255],{"class":420},[398,897,898],{"class":491},"   # noqa: LACO001\n",[398,900,901,903,905,907,910,912,914,916,918,920,922],{"class":400,"line":459},[398,902,537],{"class":536},[398,904,518],{"class":420},[398,906,852],{"class":851},[398,908,909],{"class":855},"in_features :",[398,911,852],{"class":851},[398,913,525],{"class":420},[398,915,863],{"class":514},[398,917,421],{"class":420},[398,919,604],{"class":424},[398,921,255],{"class":420},[398,923,898],{"class":491},[398,925,926,928,930,932,935,937,939,941,943,946,948],{"class":400,"line":647},[398,927,537],{"class":536},[398,929,518],{"class":420},[398,931,852],{"class":851},[398,933,934],{"class":855},"out_features:",[398,936,852],{"class":851},[398,938,525],{"class":420},[398,940,863],{"class":514},[398,942,421],{"class":420},[398,944,945],{"class":424},"out_features",[398,947,255],{"class":420},[398,949,950],{"class":491},"  # noqa: LACO001\n",[398,952,953,955],{"class":400,"line":653},[398,954,537],{"class":536},[398,956,957],{"class":420},"()\n",[398,959,960,962,964,966,969,971],{"class":400,"line":674},[398,961,537],{"class":536},[398,963,518],{"class":420},[398,965,852],{"class":851},[398,967,968],{"class":855},"--- laco.dump (YAML) ---",[398,970,852],{"class":851},[398,972,531],{"class":420},[398,974,976,978,980,983,985,988,990,992],{"class":400,"line":975},9,[398,977,537],{"class":536},[398,979,518],{"class":420},[398,981,982],{"class":514},"laco",[398,984,421],{"class":420},[398,986,987],{"class":514},"dump",[398,989,518],{"class":420},[398,991,633],{"class":514},[398,993,994],{"class":420},"))\n",[556,996],{"data":997,"kind":559},"X3RhcmdldF8gOiB0b3JjaC5ubi5MaW5lYXIKX2NvbnZlcnRfOiBhbGwKaW5fZmVhdHVyZXMgOiA3ODQKb3V0X2ZlYXR1cmVzOiAxMAoKLS0tIGxhY28uZHVtcCAoWUFNTCkgLS0tCntfY29udmVydF86IGFsbCwgX2xhY29fOiAxLCBfdGFyZ2V0XzogdG9yY2gubm4uTGluZWFyLCBpbl9mZWF0dXJlczogNzg0LCBvdXRfZmVhdHVyZXM6IDEwfQoK",[999,1000,1002,1005],"h3",{"id":1001},"stricttrue-catching-typos-at-config-build-time",[231,1003,1004],{},"strict=True",": catching typos at config-build time",[216,1007,1008,1009,1011,1012,1014,1015,421],{},"By default ",[231,1010,757],{}," is strict: it validates your keyword arguments against the target's signature ",[267,1013,269],{},", not later at instantiation. A typo surfaces immediately with a clear error message pointing at the config file line, instead of being buried inside a traceback from ",[231,1016,723],{},[389,1018,1020],{"className":391,"code":1019,"language":393,"meta":394,"style":394},"try:\n    bad_cfg = L.call(nn.Linear)(in_featurez=784, out_features=10)  # typo!\nexcept TypeError as e:\n    print(\"TypeError caught:\")\n    print(e)\n",[231,1021,1022,1030,1073,1088,1104],{"__ignoreMap":394},[398,1023,1024,1027],{"class":400,"line":401},[398,1025,1026],{"class":404},"try",[398,1028,1029],{"class":420},":\n",[398,1031,1032,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053,1056,1058,1060,1062,1064,1066,1068,1070],{"class":400,"line":412},[398,1033,1034],{"class":408},"    bad_cfg ",[398,1036,506],{"class":505},[398,1038,584],{"class":408},[398,1040,421],{"class":420},[398,1042,589],{"class":514},[398,1044,518],{"class":420},[398,1046,451],{"class":514},[398,1048,421],{"class":420},[398,1050,515],{"class":424},[398,1052,600],{"class":420},[398,1054,1055],{"class":603},"in_featurez",[398,1057,506],{"class":505},[398,1059,522],{"class":521},[398,1061,525],{"class":420},[398,1063,613],{"class":603},[398,1065,506],{"class":505},[398,1067,618],{"class":521},[398,1069,255],{"class":420},[398,1071,1072],{"class":491},"  # typo!\n",[398,1074,1075,1078,1081,1083,1086],{"class":400,"line":433},[398,1076,1077],{"class":404},"except",[398,1079,1080],{"class":542}," TypeError",[398,1082,427],{"class":404},[398,1084,1085],{"class":408}," e",[398,1087,1029],{"class":420},[398,1089,1090,1093,1095,1097,1100,1102],{"class":400,"line":441},[398,1091,1092],{"class":536},"    print",[398,1094,518],{"class":420},[398,1096,852],{"class":851},[398,1098,1099],{"class":855},"TypeError caught:",[398,1101,852],{"class":851},[398,1103,531],{"class":420},[398,1105,1106,1108,1110,1113],{"class":400,"line":459},[398,1107,1092],{"class":536},[398,1109,518],{"class":420},[398,1111,1112],{"class":514},"e",[398,1114,531],{"class":420},[556,1116],{"data":1117,"kind":559},"VHlwZUVycm9yIGNhdWdodDoKTC5jYWxsKExpbmVhciwgc3RyaWN0PVRydWUpOiB1bmtub3duIGtleXdvcmQgYXJndW1lbnQocykgWydpbl9mZWF0dXJleiddIOKAlCBub3QgaW4gdGFyZ2V0IHNpZ25hdHVyZS4gS25vd24gcGFyYW1ldGVyczogWydiaWFzJywgJ2RldmljZScsICdkdHlwZScsICdpbl9mZWF0dXJlcycsICdvdXRfZmVhdHVyZXMnXS4gUGFzcyBgc3RyaWN0PUZhbHNlYCB0byBMLmNhbGwoLi4uKSAob3IgYEwucGFydGlhbCguLi4sIHN0cmljdD1GYWxzZSlgKSB0byBvcHQgb3V0Lgo=",[216,1119,1120],{},"The error names the offending kwarg and lists the known parameters. Compare this with the alternative: if validation only happened at instantiation, the typo would survive serialization, config merges, and overrides, only failing when the object is finally constructed, possibly far from where the mistake was made.",[216,1122,1123,1124,1127],{},"If you have a dynamic target whose signature can't be introspected (C-extensions, for example), pass ",[231,1125,1126],{},"strict=False"," to opt out.",[475,1129,1131,1132,1134],{"id":1130},"section-3-why-lpartial-exists","Section 3: Why ",[231,1133,386],{}," exists",[216,1136,1137,1138,1140],{},"Here is a concrete example of a construction problem that ",[231,1139,757],{}," alone cannot solve.",[216,1142,1143,1144,1147,1148,1151],{},"You want to configure an Adam optimizer with a specific learning rate and weight decay. But ",[231,1145,1146],{},"torch.optim.Adam"," requires ",[231,1149,1150],{},"model.parameters()"," as its first argument, and the model doesn't exist yet at config-build time.",[216,1153,1154,1155,1158,1159,1162],{},"Calling ",[231,1156,1157],{},"L.call(optim.Adam)(params=???, lr=1e-3)"," is a dead end: there is no sensible value for ",[231,1160,1161],{},"params"," until after the model has been instantiated.",[389,1164,1166],{"className":391,"code":1165,"language":393,"meta":394,"style":394},"# WRONG: can't do this at config time — model doesn't exist yet!\n#\n# optimizer = optim.Adam(model.parameters(), lr=1e-3)  # model is not defined here\n#\n# This is a plain Python problem: Adam needs params that only exist post-construction.\nprint(\"(skipped — intentionally broken approach)\")\n",[231,1167,1168,1173,1178,1183,1187,1192],{"__ignoreMap":394},[398,1169,1170],{"class":400,"line":401},[398,1171,1172],{"class":491},"# WRONG: can't do this at config time — model doesn't exist yet!\n",[398,1174,1175],{"class":400,"line":412},[398,1176,1177],{"class":491},"#\n",[398,1179,1180],{"class":400,"line":433},[398,1181,1182],{"class":491},"# optimizer = optim.Adam(model.parameters(), lr=1e-3)  # model is not defined here\n",[398,1184,1185],{"class":400,"line":441},[398,1186,1177],{"class":491},[398,1188,1189],{"class":400,"line":459},[398,1190,1191],{"class":491},"# This is a plain Python problem: Adam needs params that only exist post-construction.\n",[398,1193,1194,1196,1198,1200,1203,1205],{"class":400,"line":647},[398,1195,537],{"class":536},[398,1197,518],{"class":420},[398,1199,852],{"class":851},[398,1201,1202],{"class":855},"(skipped — intentionally broken approach)",[398,1204,852],{"class":851},[398,1206,531],{"class":420},[556,1208],{"data":1209,"kind":559},"KHNraXBwZWQg4oCUIGludGVudGlvbmFsbHkgYnJva2VuIGFwcHJvYWNoKQo=",[216,1211,1212],{},[219,1213,1214,1215,421],{},"The solution: ",[231,1216,386],{},[216,1218,1219,1221,1222,1224,1225,1227,1228,1231,1232,1234],{},[231,1220,332],{}," produces a config node with ",[231,1223,340],{},". When ",[231,1226,723],{}," sees that flag, it returns a ",[231,1229,1230],{},"functools.partial"," object instead of calling the function. You supply the missing ",[231,1233,1161],{}," argument later, after the model exists.",[389,1236,1238],{"className":391,"code":1237,"language":393,"meta":394,"style":394},"# Build the optimizer config — no model needed yet.\noptimizer_cfg = L.partial(optim.Adam)(lr=1e-3, weight_decay=1e-5)\n\nprint(\"--- optimizer config (YAML) ---\")\nprint(laco.dump(optimizer_cfg))\nprint(\"_partial_ field:\", optimizer_cfg._partial_)  # noqa: LACO001\n",[231,1239,1240,1245,1290,1294,1309,1328],{"__ignoreMap":394},[398,1241,1242],{"class":400,"line":401},[398,1243,1244],{"class":491},"# Build the optimizer config — no model needed yet.\n",[398,1246,1247,1250,1252,1254,1256,1259,1261,1263,1265,1268,1270,1273,1275,1278,1280,1283,1285,1288],{"class":400,"line":412},[398,1248,1249],{"class":408},"optimizer_cfg ",[398,1251,506],{"class":505},[398,1253,584],{"class":408},[398,1255,421],{"class":420},[398,1257,1258],{"class":514},"partial",[398,1260,518],{"class":420},[398,1262,468],{"class":514},[398,1264,421],{"class":420},[398,1266,1267],{"class":424},"Adam",[398,1269,600],{"class":420},[398,1271,1272],{"class":603},"lr",[398,1274,506],{"class":505},[398,1276,1277],{"class":521},"1e-3",[398,1279,525],{"class":420},[398,1281,1282],{"class":603}," weight_decay",[398,1284,506],{"class":505},[398,1286,1287],{"class":521},"1e-5",[398,1289,531],{"class":420},[398,1291,1292],{"class":400,"line":433},[398,1293,644],{"emptyLinePlaceholder":643},[398,1295,1296,1298,1300,1302,1305,1307],{"class":400,"line":441},[398,1297,537],{"class":536},[398,1299,518],{"class":420},[398,1301,852],{"class":851},[398,1303,1304],{"class":855},"--- optimizer config (YAML) ---",[398,1306,852],{"class":851},[398,1308,531],{"class":420},[398,1310,1311,1313,1315,1317,1319,1321,1323,1326],{"class":400,"line":459},[398,1312,537],{"class":536},[398,1314,518],{"class":420},[398,1316,982],{"class":514},[398,1318,421],{"class":420},[398,1320,987],{"class":514},[398,1322,518],{"class":420},[398,1324,1325],{"class":514},"optimizer_cfg",[398,1327,994],{"class":420},[398,1329,1330,1332,1334,1336,1339,1341,1343,1346,1348,1351,1353],{"class":400,"line":647},[398,1331,537],{"class":536},[398,1333,518],{"class":420},[398,1335,852],{"class":851},[398,1337,1338],{"class":855},"_partial_ field:",[398,1340,852],{"class":851},[398,1342,525],{"class":420},[398,1344,1345],{"class":514}," optimizer_cfg",[398,1347,421],{"class":420},[398,1349,1350],{"class":424},"_partial_",[398,1352,255],{"class":420},[398,1354,950],{"class":491},[556,1356],{"data":1357,"kind":559},"LS0tIG9wdGltaXplciBjb25maWcgKFlBTUwpIC0tLQp7X2NvbnZlcnRfOiBhbGwsIF9sYWNvXzogMSwgX3BhcnRpYWxfOiB0cnVlLCBfdGFyZ2V0XzogdG9yY2gub3B0aW0uQWRhbSwgbHI6IDAuMDAxLAogIHdlaWdodF9kZWNheTogMS4wZS0wNX0KCl9wYXJ0aWFsXyBmaWVsZDogVHJ1ZQo=",[389,1359,1361],{"className":391,"code":1360,"language":393,"meta":394,"style":394},"# Build the model config and instantiate it.\nmodel_cfg = L.call(nn.Linear)(in_features=784, out_features=10)\nmodel = laco.instantiate(model_cfg)  # nn.Linear is created here\n\n# Instantiate the optimizer config → we get a functools.partial, not an Adam yet.\noptimizer_factory = laco.instantiate(optimizer_cfg)\nprint(type(optimizer_factory))  # \u003Cclass 'functools.partial'>\n\n# Now supply model.parameters() — Adam is created here.\noptimizer = optimizer_factory(model.parameters())\nprint(type(optimizer))          # \u003Cclass 'torch.optim.adam.Adam'>\nprint(\"lr =\", optimizer.param_groups[0][\"lr\"])\n",[231,1362,1363,1368,1407,1429,1433,1438,1457,1475,1479,1484,1508,1527],{"__ignoreMap":394},[398,1364,1365],{"class":400,"line":401},[398,1366,1367],{"class":491},"# Build the model config and instantiate it.\n",[398,1369,1370,1373,1375,1377,1379,1381,1383,1385,1387,1389,1391,1393,1395,1397,1399,1401,1403,1405],{"class":400,"line":412},[398,1371,1372],{"class":408},"model_cfg ",[398,1374,506],{"class":505},[398,1376,584],{"class":408},[398,1378,421],{"class":420},[398,1380,589],{"class":514},[398,1382,518],{"class":420},[398,1384,451],{"class":514},[398,1386,421],{"class":420},[398,1388,515],{"class":424},[398,1390,600],{"class":420},[398,1392,604],{"class":603},[398,1394,506],{"class":505},[398,1396,522],{"class":521},[398,1398,525],{"class":420},[398,1400,613],{"class":603},[398,1402,506],{"class":505},[398,1404,618],{"class":521},[398,1406,531],{"class":420},[398,1408,1409,1412,1414,1416,1418,1420,1422,1424,1426],{"class":400,"line":433},[398,1410,1411],{"class":408},"model ",[398,1413,506],{"class":505},[398,1415,417],{"class":408},[398,1417,421],{"class":420},[398,1419,665],{"class":514},[398,1421,518],{"class":420},[398,1423,741],{"class":514},[398,1425,255],{"class":420},[398,1427,1428],{"class":491},"  # nn.Linear is created here\n",[398,1430,1431],{"class":400,"line":441},[398,1432,644],{"emptyLinePlaceholder":643},[398,1434,1435],{"class":400,"line":459},[398,1436,1437],{"class":491},"# Instantiate the optimizer config → we get a functools.partial, not an Adam yet.\n",[398,1439,1440,1443,1445,1447,1449,1451,1453,1455],{"class":400,"line":647},[398,1441,1442],{"class":408},"optimizer_factory ",[398,1444,506],{"class":505},[398,1446,417],{"class":408},[398,1448,421],{"class":420},[398,1450,665],{"class":514},[398,1452,518],{"class":420},[398,1454,1325],{"class":514},[398,1456,531],{"class":420},[398,1458,1459,1461,1463,1465,1467,1470,1472],{"class":400,"line":653},[398,1460,537],{"class":536},[398,1462,518],{"class":420},[398,1464,543],{"class":542},[398,1466,518],{"class":420},[398,1468,1469],{"class":514},"optimizer_factory",[398,1471,551],{"class":420},[398,1473,1474],{"class":491},"  # \u003Cclass 'functools.partial'>\n",[398,1476,1477],{"class":400,"line":674},[398,1478,644],{"emptyLinePlaceholder":643},[398,1480,1481],{"class":400,"line":975},[398,1482,1483],{"class":491},"# Now supply model.parameters() — Adam is created here.\n",[398,1485,1487,1490,1492,1495,1497,1500,1502,1505],{"class":400,"line":1486},10,[398,1488,1489],{"class":408},"optimizer ",[398,1491,506],{"class":505},[398,1493,1494],{"class":514}," optimizer_factory",[398,1496,518],{"class":420},[398,1498,1499],{"class":514},"model",[398,1501,421],{"class":420},[398,1503,1504],{"class":514},"parameters",[398,1506,1507],{"class":420},"())\n",[398,1509,1511,1513,1515,1517,1519,1522,1524],{"class":400,"line":1510},11,[398,1512,537],{"class":536},[398,1514,518],{"class":420},[398,1516,543],{"class":542},[398,1518,518],{"class":420},[398,1520,1521],{"class":514},"optimizer",[398,1523,551],{"class":420},[398,1525,1526],{"class":491},"          # \u003Cclass 'torch.optim.adam.Adam'>\n",[398,1528,1530,1532,1534,1536,1539,1541,1543,1546,1548,1551,1554,1557,1560,1562,1564,1566],{"class":400,"line":1529},12,[398,1531,537],{"class":536},[398,1533,518],{"class":420},[398,1535,852],{"class":851},[398,1537,1538],{"class":855},"lr =",[398,1540,852],{"class":851},[398,1542,525],{"class":420},[398,1544,1545],{"class":514}," optimizer",[398,1547,421],{"class":420},[398,1549,1550],{"class":424},"param_groups",[398,1552,1553],{"class":420},"[",[398,1555,1556],{"class":521},"0",[398,1558,1559],{"class":420},"][",[398,1561,852],{"class":851},[398,1563,1272],{"class":855},[398,1565,852],{"class":851},[398,1567,1568],{"class":420},"])\n",[556,1570],{"data":1571,"kind":559},"PGNsYXNzICdmdW5jdG9vbHMucGFydGlhbCc+CjxjbGFzcyAndG9yY2gub3B0aW0uYWRhbS5BZGFtJz4KbHIgPSAwLjAwMQo=",[216,1573,1574],{},"The call chain has three steps:",[699,1576,1577,1587,1595],{},[702,1578,1579,1582,1583,337,1585],{},[231,1580,1581],{},"L.partial(Adam)(lr=1e-3)"," → ",[231,1584,273],{},[231,1586,340],{},[702,1588,1589,1582,1592],{},[231,1590,1591],{},"laco.instantiate(optimizer_cfg)",[231,1593,1594],{},"functools.partial(Adam, lr=1e-3)",[702,1596,1597,1600,1601,1603],{},[231,1598,1599],{},"optimizer_factory(model.parameters())"," → actual ",[231,1602,1267],{}," instance",[216,1605,1606],{},"Steps 1 and 2 happen at config time (before the training loop); step 3 happens at run time (after the model is built).",[475,1608,1610],{"id":1609},"section-4-config-build-time-vs-run-time","Section 4: Config-build time vs. run time",[216,1612,1613],{},"The key insight from this notebook, laid out explicitly. Config-build time is\nusually import time of your config file. Run time is the training script.",[287,1615,1616,1626],{},[290,1617,1618],{},[293,1619,1620,1623],{},[296,1621,1622],{},"When",[296,1624,1625],{},"Event",[306,1627,1628,1638,1646,1658,1669],{},[293,1629,1630,1633],{},[311,1631,1632],{},"Config-build time",[311,1634,1635],{},[231,1636,1637],{},"L.call(nn.Linear)(in_features=784)",[293,1639,1640,1642],{},[311,1641,1632],{},[311,1643,1644],{},[231,1645,1581],{},[293,1647,1648,1651],{},[311,1649,1650],{},"Run time",[311,1652,1653,1582,1656],{},[231,1654,1655],{},"laco.instantiate(model_cfg)",[231,1657,250],{},[293,1659,1660,1662],{},[311,1661,1650],{},[311,1663,1664,1582,1667],{},[231,1665,1666],{},"laco.instantiate(optim_cfg)",[231,1668,1230],{},[293,1670,1671,1673],{},[311,1672,1650],{},[311,1674,1675,1582,1678],{},[231,1676,1677],{},"factory(model.parameters())",[231,1679,1267],{},[216,1681,1682,1683,1685,1686,1688,1689,421],{},"Both lazy constructs are declared once, at config-build time (usually import time\nof your config file). ",[231,1684,723],{}," executes them at run time (inside the\ntraining script) — the partial only becomes a real ",[231,1687,1267],{}," once it's called with\n",[231,1690,1150],{},[475,1692,1694,1695],{"id":1693},"section-5-wrapping-an-existing-value-with-ljust","Section 5: Wrapping an existing value with ",[231,1696,1697],{},"L.just",[216,1699,1700,1701,1703,1704,1706,1707,1710],{},"Sometimes you already have a Python object, such as a pre-computed tensor or a constant, and you want to embed it inside a config tree so it participates in composition. ",[231,1702,352],{}," wraps it in a node whose ",[231,1705,779],{}," is ",[231,1708,1709],{},"laco.ops.identity",", the built-in pass-through function. Instantiating the node returns the original value unchanged.",[389,1712,1714],{"className":391,"code":1713,"language":393,"meta":394,"style":394},"pretrained_weights = torch.zeros(10, 5)  # some pre-computed tensor\n\ncfg_just = L.just(pretrained_weights)\n\nprint(\"_target_:\", cfg_just._target_)  # noqa: LACO001  → 'laco.ops.identity'\nprint(\"value   :\", type(cfg_just.value))  # noqa: LACO001  → torch.Tensor\nprint()\n\nrecovered = laco.instantiate(cfg_just)\nprint(\"recovered type  :\", type(recovered))\nprint(\"values identical:\", torch.equal(recovered, pretrained_weights))\n",[231,1715,1716,1744,1748,1769,1773,1800,1833,1839,1843,1862,1886],{"__ignoreMap":394},[398,1717,1718,1721,1723,1725,1727,1730,1732,1734,1736,1739,1741],{"class":400,"line":401},[398,1719,1720],{"class":408},"pretrained_weights ",[398,1722,506],{"class":505},[398,1724,446],{"class":408},[398,1726,421],{"class":420},[398,1728,1729],{"class":514},"zeros",[398,1731,518],{"class":420},[398,1733,618],{"class":521},[398,1735,525],{"class":420},[398,1737,1738],{"class":521}," 5",[398,1740,255],{"class":420},[398,1742,1743],{"class":491},"  # some pre-computed tensor\n",[398,1745,1746],{"class":400,"line":412},[398,1747,644],{"emptyLinePlaceholder":643},[398,1749,1750,1753,1755,1757,1759,1762,1764,1767],{"class":400,"line":433},[398,1751,1752],{"class":408},"cfg_just ",[398,1754,506],{"class":505},[398,1756,584],{"class":408},[398,1758,421],{"class":420},[398,1760,1761],{"class":514},"just",[398,1763,518],{"class":420},[398,1765,1766],{"class":514},"pretrained_weights",[398,1768,531],{"class":420},[398,1770,1771],{"class":400,"line":441},[398,1772,644],{"emptyLinePlaceholder":643},[398,1774,1775,1777,1779,1781,1784,1786,1788,1791,1793,1795,1797],{"class":400,"line":459},[398,1776,537],{"class":536},[398,1778,518],{"class":420},[398,1780,852],{"class":851},[398,1782,1783],{"class":855},"_target_:",[398,1785,852],{"class":851},[398,1787,525],{"class":420},[398,1789,1790],{"class":514}," cfg_just",[398,1792,421],{"class":420},[398,1794,779],{"class":424},[398,1796,255],{"class":420},[398,1798,1799],{"class":491},"  # noqa: LACO001  → 'laco.ops.identity'\n",[398,1801,1802,1804,1806,1808,1811,1813,1815,1818,1820,1823,1825,1828,1830],{"class":400,"line":647},[398,1803,537],{"class":536},[398,1805,518],{"class":420},[398,1807,852],{"class":851},[398,1809,1810],{"class":855},"value   :",[398,1812,852],{"class":851},[398,1814,525],{"class":420},[398,1816,1817],{"class":542}," type",[398,1819,518],{"class":420},[398,1821,1822],{"class":514},"cfg_just",[398,1824,421],{"class":420},[398,1826,1827],{"class":424},"value",[398,1829,551],{"class":420},[398,1831,1832],{"class":491},"  # noqa: LACO001  → torch.Tensor\n",[398,1834,1835,1837],{"class":400,"line":653},[398,1836,537],{"class":536},[398,1838,957],{"class":420},[398,1840,1841],{"class":400,"line":674},[398,1842,644],{"emptyLinePlaceholder":643},[398,1844,1845,1848,1850,1852,1854,1856,1858,1860],{"class":400,"line":975},[398,1846,1847],{"class":408},"recovered ",[398,1849,506],{"class":505},[398,1851,417],{"class":408},[398,1853,421],{"class":420},[398,1855,665],{"class":514},[398,1857,518],{"class":420},[398,1859,1822],{"class":514},[398,1861,531],{"class":420},[398,1863,1864,1866,1868,1870,1873,1875,1877,1879,1881,1884],{"class":400,"line":1486},[398,1865,537],{"class":536},[398,1867,518],{"class":420},[398,1869,852],{"class":851},[398,1871,1872],{"class":855},"recovered type  :",[398,1874,852],{"class":851},[398,1876,525],{"class":420},[398,1878,1817],{"class":542},[398,1880,518],{"class":420},[398,1882,1883],{"class":514},"recovered",[398,1885,994],{"class":420},[398,1887,1888,1890,1892,1894,1897,1899,1901,1903,1905,1908,1910,1912,1914,1917],{"class":400,"line":1510},[398,1889,537],{"class":536},[398,1891,518],{"class":420},[398,1893,852],{"class":851},[398,1895,1896],{"class":855},"values identical:",[398,1898,852],{"class":851},[398,1900,525],{"class":420},[398,1902,446],{"class":514},[398,1904,421],{"class":420},[398,1906,1907],{"class":514},"equal",[398,1909,518],{"class":420},[398,1911,1883],{"class":514},[398,1913,525],{"class":420},[398,1915,1916],{"class":514}," pretrained_weights",[398,1918,994],{"class":420},[556,1920],{"data":1921,"kind":559},"X3RhcmdldF86IGxhY28ub3BzLmlkZW50aXR5CnZhbHVlICAgOiA8Y2xhc3MgJ3RvcmNoLlRlbnNvcic+CgpyZWNvdmVyZWQgdHlwZSAgOiA8Y2xhc3MgJ3RvcmNoLlRlbnNvcic+CnZhbHVlcyBpZGVudGljYWw6IFRydWUK",[216,1923,1924,229,1927,1929,1930,1933,1934,1937,1938,1940],{},[219,1925,1926],{},"Important caveat.",[231,1928,1697],{}," keeps the value in memory. If you try to serialize the config with ",[231,1931,1932],{},"laco.dump"," and reload it from YAML, only OmegaConf-native types (ints, floats, strings, bools, lists, dicts) will survive the round-trip. A raw ",[231,1935,1936],{},"torch.Tensor"," stored via ",[231,1939,1697],{}," works for in-memory composition, but it does not survive YAML serialization to disk.",[475,1942,1944,1945],{"id":1943},"section-6-mandatory-fields-with-lrequiredt","Section 6: Mandatory fields with ",[231,1946,367],{},[216,1948,1949,1950,1953],{},"Some config fields genuinely have no sensible default. They must be provided by whoever loads the config: a vocabulary size, a number of classes, a path. Leaving them as ",[231,1951,1952],{},"None"," is misleading (that's a valid value for some fields), and hard-coding them defeats the purpose of a config.",[216,1955,1956,1957,1959,1960,1962,1963,1965],{},"laco's solution: ",[231,1958,367],{},". At runtime it returns ",[231,1961,372],{},", which OmegaConf treats as a sentinel meaning \"this value must be supplied before the config can be used\". In the IDE it types as ",[231,1964,325],{},", so your type-checker keeps working.",[389,1967,1969],{"className":391,"code":1968,"language":393,"meta":394,"style":394},"import omegaconf\n\n# Demonstrate what L.required[int]() actually returns at runtime:\nmissing_value = L.required[int]()\nprint(\"L.required[int]() is  :\", missing_value)\nprint(\"Is omegaconf.MISSING  :\", missing_value is omegaconf.MISSING)\n",[231,1970,1971,1978,1982,1987,2009,2029],{"__ignoreMap":394},[398,1972,1973,1975],{"class":400,"line":401},[398,1974,405],{"class":404},[398,1976,1977],{"class":408}," omegaconf\n",[398,1979,1980],{"class":400,"line":412},[398,1981,644],{"emptyLinePlaceholder":643},[398,1983,1984],{"class":400,"line":433},[398,1985,1986],{"class":491},"# Demonstrate what L.required[int]() actually returns at runtime:\n",[398,1988,1989,1992,1994,1996,1998,2001,2003,2006],{"class":400,"line":441},[398,1990,1991],{"class":408},"missing_value ",[398,1993,506],{"class":505},[398,1995,584],{"class":408},[398,1997,421],{"class":420},[398,1999,2000],{"class":424},"required",[398,2002,1553],{"class":420},[398,2004,2005],{"class":542},"int",[398,2007,2008],{"class":420},"]()\n",[398,2010,2011,2013,2015,2017,2020,2022,2024,2027],{"class":400,"line":459},[398,2012,537],{"class":536},[398,2014,518],{"class":420},[398,2016,852],{"class":851},[398,2018,2019],{"class":855},"L.required[int]() is  :",[398,2021,852],{"class":851},[398,2023,525],{"class":420},[398,2025,2026],{"class":514}," missing_value",[398,2028,531],{"class":420},[398,2030,2031,2033,2035,2037,2040,2042,2044,2047,2050,2053,2055,2059],{"class":400,"line":647},[398,2032,537],{"class":536},[398,2034,518],{"class":420},[398,2036,852],{"class":851},[398,2038,2039],{"class":855},"Is omegaconf.MISSING  :",[398,2041,852],{"class":851},[398,2043,525],{"class":420},[398,2045,2046],{"class":514}," missing_value ",[398,2048,2049],{"class":404},"is",[398,2051,2052],{"class":514}," omegaconf",[398,2054,421],{"class":420},[398,2056,2058],{"class":2057},"swQdS","MISSING",[398,2060,531],{"class":420},[556,2062],{"data":2063,"kind":559},"TC5yZXF1aXJlZFtpbnRdKCkgaXMgIDogPz8\u002FCklzIG9tZWdhY29uZi5NSVNTSU5HICA6IFRydWUK",[389,2065,2067],{"className":391,"code":2066,"language":393,"meta":394,"style":394},"# A config with a required field — modelled after text_classifier.py\ncfg_with_required = L.call(nn.Embedding)(\n    num_embeddings=L.required[int](),\n    embedding_dim=64,\n)\n\n# laco.dump walks the tree and resolves interpolations and mandatory values\n# as it goes, so dumping a node that still holds a MISSING field would raise\n# MissingMandatoryValue. To inspect the *unresolved* recipe, render it with\n# OmegaConf.to_yaml(...), which leaves the ??? sentinel in place.\nprint(\"--- YAML (note: num_embeddings shows as ???) ---\")\nprint(omegaconf.OmegaConf.to_yaml(cfg_with_required))\n",[231,2068,2069,2074,2099,2120,2133,2137,2141,2146,2151,2156,2161,2176],{"__ignoreMap":394},[398,2070,2071],{"class":400,"line":401},[398,2072,2073],{"class":491},"# A config with a required field — modelled after text_classifier.py\n",[398,2075,2076,2079,2081,2083,2085,2087,2089,2091,2093,2096],{"class":400,"line":412},[398,2077,2078],{"class":408},"cfg_with_required ",[398,2080,506],{"class":505},[398,2082,584],{"class":408},[398,2084,421],{"class":420},[398,2086,589],{"class":514},[398,2088,518],{"class":420},[398,2090,451],{"class":514},[398,2092,421],{"class":420},[398,2094,2095],{"class":424},"Embedding",[398,2097,2098],{"class":420},")(\n",[398,2100,2101,2104,2106,2109,2111,2113,2115,2117],{"class":400,"line":433},[398,2102,2103],{"class":603},"    num_embeddings",[398,2105,506],{"class":505},[398,2107,2108],{"class":514},"L",[398,2110,421],{"class":420},[398,2112,2000],{"class":424},[398,2114,1553],{"class":420},[398,2116,2005],{"class":542},[398,2118,2119],{"class":420},"](),\n",[398,2121,2122,2125,2127,2130],{"class":400,"line":441},[398,2123,2124],{"class":603},"    embedding_dim",[398,2126,506],{"class":505},[398,2128,2129],{"class":521},"64",[398,2131,2132],{"class":420},",\n",[398,2134,2135],{"class":400,"line":459},[398,2136,531],{"class":420},[398,2138,2139],{"class":400,"line":647},[398,2140,644],{"emptyLinePlaceholder":643},[398,2142,2143],{"class":400,"line":653},[398,2144,2145],{"class":491},"# laco.dump walks the tree and resolves interpolations and mandatory values\n",[398,2147,2148],{"class":400,"line":674},[398,2149,2150],{"class":491},"# as it goes, so dumping a node that still holds a MISSING field would raise\n",[398,2152,2153],{"class":400,"line":975},[398,2154,2155],{"class":491},"# MissingMandatoryValue. To inspect the *unresolved* recipe, render it with\n",[398,2157,2158],{"class":400,"line":1486},[398,2159,2160],{"class":491},"# OmegaConf.to_yaml(...), which leaves the ??? sentinel in place.\n",[398,2162,2163,2165,2167,2169,2172,2174],{"class":400,"line":1510},[398,2164,537],{"class":536},[398,2166,518],{"class":420},[398,2168,852],{"class":851},[398,2170,2171],{"class":855},"--- YAML (note: num_embeddings shows as ???) ---",[398,2173,852],{"class":851},[398,2175,531],{"class":420},[398,2177,2178,2180,2182,2185,2187,2190,2192,2195,2197,2200],{"class":400,"line":1529},[398,2179,537],{"class":536},[398,2181,518],{"class":420},[398,2183,2184],{"class":514},"omegaconf",[398,2186,421],{"class":420},[398,2188,2189],{"class":424},"OmegaConf",[398,2191,421],{"class":420},[398,2193,2194],{"class":514},"to_yaml",[398,2196,518],{"class":420},[398,2198,2199],{"class":514},"cfg_with_required",[398,2201,994],{"class":420},[556,2203],{"data":2204,"kind":559},"LS0tIFlBTUwgKG5vdGU6IG51bV9lbWJlZGRpbmdzIHNob3dzIGFzID8\u002FPykgLS0tCl90YXJnZXRfOiB0b3JjaC5ubi5FbWJlZGRpbmcKX2NvbnZlcnRfOiBhbGwKbnVtX2VtYmVkZGluZ3M6ID8\u002FPwplbWJlZGRpbmdfZGltOiA2NAoK",[389,2206,2208],{"className":391,"code":2207,"language":393,"meta":394,"style":394},"# Instantiating without filling in the required field raises immediately:\ntry:\n    laco.instantiate(cfg_with_required)\nexcept Exception as e:\n    print(type(e).__name__)  # MissingMandatoryValue\n    print(str(e)[:120])\n",[231,2209,2210,2215,2221,2236,2249,2273],{"__ignoreMap":394},[398,2211,2212],{"class":400,"line":401},[398,2213,2214],{"class":491},"# Instantiating without filling in the required field raises immediately:\n",[398,2216,2217,2219],{"class":400,"line":412},[398,2218,1026],{"class":404},[398,2220,1029],{"class":420},[398,2222,2223,2226,2228,2230,2232,2234],{"class":400,"line":433},[398,2224,2225],{"class":408},"    laco",[398,2227,421],{"class":420},[398,2229,665],{"class":514},[398,2231,518],{"class":420},[398,2233,2199],{"class":514},[398,2235,531],{"class":420},[398,2237,2238,2240,2243,2245,2247],{"class":400,"line":441},[398,2239,1077],{"class":404},[398,2241,2242],{"class":542}," Exception",[398,2244,427],{"class":404},[398,2246,1085],{"class":408},[398,2248,1029],{"class":420},[398,2250,2251,2253,2255,2257,2259,2261,2264,2268,2270],{"class":400,"line":459},[398,2252,1092],{"class":536},[398,2254,518],{"class":420},[398,2256,543],{"class":542},[398,2258,518],{"class":420},[398,2260,1112],{"class":514},[398,2262,2263],{"class":420},").",[398,2265,2267],{"class":2266},"s_hVV","__name__",[398,2269,255],{"class":420},[398,2271,2272],{"class":491},"  # MissingMandatoryValue\n",[398,2274,2275,2277,2279,2282,2284,2286,2289,2292],{"class":400,"line":647},[398,2276,1092],{"class":536},[398,2278,518],{"class":420},[398,2280,2281],{"class":542},"str",[398,2283,518],{"class":420},[398,2285,1112],{"class":514},[398,2287,2288],{"class":420},")[:",[398,2290,2291],{"class":521},"120",[398,2293,1568],{"class":420},[556,2295],{"data":2296,"kind":559},"TWlzc2luZ01hbmRhdG9yeVZhbHVlCk1pc3NpbmcgbWFuZGF0b3J5IHZhbHVlOiBudW1fZW1iZWRkaW5ncwogICAgZnVsbF9rZXk6IG51bV9lbWJlZGRpbmdzCiAgICBvYmplY3RfdHlwZT1kaWN0Cg==",[999,2298,2300,2302,2303,2305],{"id":2299},"lrequiredt-vs-omegaconfmissing-the-typing-difference",[231,2301,367],{}," vs ",[231,2304,372],{},": the typing difference",[216,2307,2308,2309,2311],{},"Why not write ",[231,2310,372],{}," directly? You can, but you lose static type information:",[287,2313,2314,2327],{},[290,2315,2316],{},[293,2317,2318,2321,2324],{},[296,2319,2320],{},"Expression",[296,2322,2323],{},"Runtime value",[296,2325,2326],{},"Static type (IDE\u002Fpyright)",[306,2328,2329,2344,2360],{},[293,2330,2331,2336,2340],{},[311,2332,2333],{},[231,2334,2335],{},"L.required[int]()",[311,2337,2338],{},[231,2339,372],{},[311,2341,2342],{},[231,2343,2005],{},[293,2345,2346,2351,2355],{},[311,2347,2348],{},[231,2349,2350],{},"L.required[float]()",[311,2352,2353],{},[231,2354,372],{},[311,2356,2357],{},[231,2358,2359],{},"float",[293,2361,2362,2366,2370],{},[311,2363,2364],{},[231,2365,372],{},[311,2367,2368],{},[231,2369,372],{},[311,2371,2372,2375],{},[231,2373,2374],{},"Any"," (no type info)",[216,2377,2378,2379,2381,2382,2385,2386,2389],{},"The runtime behavior is identical: both produce the ",[231,2380,2058],{}," sentinel and will raise ",[231,2383,2384],{},"MissingMandatoryValue"," if not overridden. The difference lives entirely in the type checker. Callers who load the config with ",[231,2387,2388],{},"laco.load(\"...\", \"num_embeddings=1000\")"," supply the value before instantiation, so they never see the error.",[475,2391,2393,2394,2397],{"id":2392},"section-7-linear_regressionpy-walkthrough","Section 7: ",[231,2395,2396],{},"linear_regression.py"," walkthrough",[216,2399,2400,2401,2403,2404,2406],{},"Let's walk through the actual ",[231,2402,2396],{}," example file line by line, applying everything learned in this notebook. The file defines a single ",[231,2405,250],{}," model and a partially-applied SGD optimizer: the smallest realistic laco config.",[389,2408,2410],{"className":391,"code":2409,"language":393,"meta":394,"style":394},"# === linear_regression.py (annotated) ===\n\nimport laco.language as L             # the config DSL\nfrom torch import nn, optim\n\n# --- 1. Hyperparameters ---\n# @L.params wraps the class so that attribute access returns OmegaConf\n# interpolation strings like \"${hps.in_features}\" instead of the bare int.\n# The IDE still sees `int` thanks to @dataclass_transform.\n# (Full coverage of @L.params in NB03.)\n@L.params\nclass hps:\n    in_features:    int   = 8\n    out_features:   int   = 1\n    bias:           bool  = True\n    learning_rate:  float = 1e-2\n    momentum:       float = 0.9\n\n# --- 2. Model config ---\n# L.call(nn.Linear) returns a factory.  Calling it with kwargs produces a\n# DictConfig.  root=True is a hint for the type checker (makes the IDE see\n# the return as DictConfig rather than nn.Linear; useful for the top-level\n# exported symbol).\n#\n# hps.in_features is \"${hps.in_features}\" at runtime — an interpolation string\n# that OmegaConf resolves to 8 only when the hps node is present *as a sibling*\n# in the same config tree.\nmodel = L.call(nn.Linear, root=True)(\n    in_features  = hps.in_features,\n    out_features = hps.out_features,\n    bias         = hps.bias,\n)\n\n# --- 3. Optimizer config ---\n# L.partial because SGD needs model.parameters() — unavailable at config time.\n# laco.instantiate(optimizer) gives back functools.partial(SGD, lr=..., momentum=...).\n# The training script then calls optimizer_factory(model.parameters()) to get the\n# real SGD instance.\noptimizer = L.partial(optim.SGD)(\n    lr       = hps.learning_rate,\n    momentum = hps.momentum,\n)\n\n# --- 4. Bundle the tree ---\n# In the real file, `__all__ = [\"model\", \"optimizer\", \"hps\"]` exports all three;\n# laco.load assembles them into one DictConfig, which is what lets the\n# \"${hps.*}\" interpolations in `model`\u002F`optimizer` resolve against the `hps`\n# node.  Here we reproduce that bundling explicitly.  Dumping `model` on its own\n# would raise InterpolationKeyError, because its \"${hps.*}\" references have no\n# `hps` sibling to point at.\nimport omegaconf\n\ncfg = omegaconf.OmegaConf.create(\n    {\"hps\": hps(), \"model\": model, \"optimizer\": optimizer}\n)\n\nprint(\"=== full config (model + optimizer + hps) ===\")\nprint(laco.dump(cfg))\n",[231,2411,2412,2417,2421,2439,2455,2459,2464,2469,2474,2479,2484,2498,2510,2528,2544,2562,2579,2595,2600,2606,2612,2618,2624,2630,2635,2641,2647,2653,2686,2701,2716,2733,2738,2743,2749,2755,2761,2767,2773,2797,2815,2831,2836,2841,2847,2853,2859,2865,2871,2877,2883,2890,2895,2916,2963,2968,2973,2989],{"__ignoreMap":394},[398,2413,2414],{"class":400,"line":401},[398,2415,2416],{"class":491},"# === linear_regression.py (annotated) ===\n",[398,2418,2419],{"class":400,"line":412},[398,2420,644],{"emptyLinePlaceholder":643},[398,2422,2423,2425,2427,2429,2431,2433,2436],{"class":400,"line":433},[398,2424,405],{"class":404},[398,2426,417],{"class":408},[398,2428,421],{"class":420},[398,2430,198],{"class":424},[398,2432,427],{"class":404},[398,2434,2435],{"class":408}," L             ",[398,2437,2438],{"class":491},"# the config DSL\n",[398,2440,2441,2444,2447,2449,2451,2453],{"class":400,"line":441},[398,2442,2443],{"class":404},"from",[398,2445,2446],{"class":408}," torch ",[398,2448,405],{"class":404},[398,2450,509],{"class":408},[398,2452,525],{"class":420},[398,2454,473],{"class":408},[398,2456,2457],{"class":400,"line":459},[398,2458,644],{"emptyLinePlaceholder":643},[398,2460,2461],{"class":400,"line":647},[398,2462,2463],{"class":491},"# --- 1. Hyperparameters ---\n",[398,2465,2466],{"class":400,"line":653},[398,2467,2468],{"class":491},"# @L.params wraps the class so that attribute access returns OmegaConf\n",[398,2470,2471],{"class":400,"line":674},[398,2472,2473],{"class":491},"# interpolation strings like \"${hps.in_features}\" instead of the bare int.\n",[398,2475,2476],{"class":400,"line":975},[398,2477,2478],{"class":491},"# The IDE still sees `int` thanks to @dataclass_transform.\n",[398,2480,2481],{"class":400,"line":1486},[398,2482,2483],{"class":491},"# (Full coverage of @L.params in NB03.)\n",[398,2485,2486,2490,2493,2495],{"class":400,"line":1510},[398,2487,2489],{"class":2488},"stp6e","@",[398,2491,2108],{"class":2492},"sGLFI",[398,2494,421],{"class":2488},[398,2496,2497],{"class":2492},"params\n",[398,2499,2500,2504,2508],{"class":400,"line":1529},[398,2501,2503],{"class":2502},"sbsja","class",[398,2505,2507],{"class":2506},"sbgvK"," hps",[398,2509,1029],{"class":420},[398,2511,2513,2516,2519,2522,2525],{"class":400,"line":2512},13,[398,2514,2515],{"class":408},"    in_features",[398,2517,2518],{"class":420},":",[398,2520,2521],{"class":542},"    int",[398,2523,2524],{"class":505},"   =",[398,2526,2527],{"class":521}," 8\n",[398,2529,2531,2534,2536,2539,2541],{"class":400,"line":2530},14,[398,2532,2533],{"class":408},"    out_features",[398,2535,2518],{"class":420},[398,2537,2538],{"class":542},"   int",[398,2540,2524],{"class":505},[398,2542,2543],{"class":521}," 1\n",[398,2545,2547,2550,2552,2555,2558],{"class":400,"line":2546},15,[398,2548,2549],{"class":408},"    bias",[398,2551,2518],{"class":420},[398,2553,2554],{"class":542},"           bool",[398,2556,2557],{"class":505},"  =",[398,2559,2561],{"class":2560},"s39Yj"," True\n",[398,2563,2565,2568,2570,2573,2576],{"class":400,"line":2564},16,[398,2566,2567],{"class":408},"    learning_rate",[398,2569,2518],{"class":420},[398,2571,2572],{"class":542},"  float",[398,2574,2575],{"class":505}," =",[398,2577,2578],{"class":521}," 1e-2\n",[398,2580,2582,2585,2587,2590,2592],{"class":400,"line":2581},17,[398,2583,2584],{"class":408},"    momentum",[398,2586,2518],{"class":420},[398,2588,2589],{"class":542},"       float",[398,2591,2575],{"class":505},[398,2593,2594],{"class":521}," 0.9\n",[398,2596,2598],{"class":400,"line":2597},18,[398,2599,644],{"emptyLinePlaceholder":643},[398,2601,2603],{"class":400,"line":2602},19,[398,2604,2605],{"class":491},"# --- 2. Model config ---\n",[398,2607,2609],{"class":400,"line":2608},20,[398,2610,2611],{"class":491},"# L.call(nn.Linear) returns a factory.  Calling it with kwargs produces a\n",[398,2613,2615],{"class":400,"line":2614},21,[398,2616,2617],{"class":491},"# DictConfig.  root=True is a hint for the type checker (makes the IDE see\n",[398,2619,2621],{"class":400,"line":2620},22,[398,2622,2623],{"class":491},"# the return as DictConfig rather than nn.Linear; useful for the top-level\n",[398,2625,2627],{"class":400,"line":2626},23,[398,2628,2629],{"class":491},"# exported symbol).\n",[398,2631,2633],{"class":400,"line":2632},24,[398,2634,1177],{"class":491},[398,2636,2638],{"class":400,"line":2637},25,[398,2639,2640],{"class":491},"# hps.in_features is \"${hps.in_features}\" at runtime — an interpolation string\n",[398,2642,2644],{"class":400,"line":2643},26,[398,2645,2646],{"class":491},"# that OmegaConf resolves to 8 only when the hps node is present *as a sibling*\n",[398,2648,2650],{"class":400,"line":2649},27,[398,2651,2652],{"class":491},"# in the same config tree.\n",[398,2654,2656,2658,2660,2662,2664,2666,2668,2670,2672,2674,2676,2679,2681,2684],{"class":400,"line":2655},28,[398,2657,1411],{"class":408},[398,2659,506],{"class":505},[398,2661,584],{"class":408},[398,2663,421],{"class":420},[398,2665,589],{"class":514},[398,2667,518],{"class":420},[398,2669,451],{"class":514},[398,2671,421],{"class":420},[398,2673,515],{"class":424},[398,2675,525],{"class":420},[398,2677,2678],{"class":603}," root",[398,2680,506],{"class":505},[398,2682,2683],{"class":2560},"True",[398,2685,2098],{"class":420},[398,2687,2689,2691,2693,2695,2697,2699],{"class":400,"line":2688},29,[398,2690,2515],{"class":603},[398,2692,2557],{"class":505},[398,2694,2507],{"class":514},[398,2696,421],{"class":420},[398,2698,604],{"class":424},[398,2700,2132],{"class":420},[398,2702,2704,2706,2708,2710,2712,2714],{"class":400,"line":2703},30,[398,2705,2533],{"class":603},[398,2707,2575],{"class":505},[398,2709,2507],{"class":514},[398,2711,421],{"class":420},[398,2713,945],{"class":424},[398,2715,2132],{"class":420},[398,2717,2719,2721,2724,2726,2728,2731],{"class":400,"line":2718},31,[398,2720,2549],{"class":603},[398,2722,2723],{"class":505},"         =",[398,2725,2507],{"class":514},[398,2727,421],{"class":420},[398,2729,2730],{"class":424},"bias",[398,2732,2132],{"class":420},[398,2734,2736],{"class":400,"line":2735},32,[398,2737,531],{"class":420},[398,2739,2741],{"class":400,"line":2740},33,[398,2742,644],{"emptyLinePlaceholder":643},[398,2744,2746],{"class":400,"line":2745},34,[398,2747,2748],{"class":491},"# --- 3. Optimizer config ---\n",[398,2750,2752],{"class":400,"line":2751},35,[398,2753,2754],{"class":491},"# L.partial because SGD needs model.parameters() — unavailable at config time.\n",[398,2756,2758],{"class":400,"line":2757},36,[398,2759,2760],{"class":491},"# laco.instantiate(optimizer) gives back functools.partial(SGD, lr=..., momentum=...).\n",[398,2762,2764],{"class":400,"line":2763},37,[398,2765,2766],{"class":491},"# The training script then calls optimizer_factory(model.parameters()) to get the\n",[398,2768,2770],{"class":400,"line":2769},38,[398,2771,2772],{"class":491},"# real SGD instance.\n",[398,2774,2776,2778,2780,2782,2784,2786,2788,2790,2792,2795],{"class":400,"line":2775},39,[398,2777,1489],{"class":408},[398,2779,506],{"class":505},[398,2781,584],{"class":408},[398,2783,421],{"class":420},[398,2785,1258],{"class":514},[398,2787,518],{"class":420},[398,2789,468],{"class":514},[398,2791,421],{"class":420},[398,2793,2794],{"class":2057},"SGD",[398,2796,2098],{"class":420},[398,2798,2800,2803,2806,2808,2810,2813],{"class":400,"line":2799},40,[398,2801,2802],{"class":603},"    lr",[398,2804,2805],{"class":505},"       =",[398,2807,2507],{"class":514},[398,2809,421],{"class":420},[398,2811,2812],{"class":424},"learning_rate",[398,2814,2132],{"class":420},[398,2816,2818,2820,2822,2824,2826,2829],{"class":400,"line":2817},41,[398,2819,2584],{"class":603},[398,2821,2575],{"class":505},[398,2823,2507],{"class":514},[398,2825,421],{"class":420},[398,2827,2828],{"class":424},"momentum",[398,2830,2132],{"class":420},[398,2832,2834],{"class":400,"line":2833},42,[398,2835,531],{"class":420},[398,2837,2839],{"class":400,"line":2838},43,[398,2840,644],{"emptyLinePlaceholder":643},[398,2842,2844],{"class":400,"line":2843},44,[398,2845,2846],{"class":491},"# --- 4. Bundle the tree ---\n",[398,2848,2850],{"class":400,"line":2849},45,[398,2851,2852],{"class":491},"# In the real file, `__all__ = [\"model\", \"optimizer\", \"hps\"]` exports all three;\n",[398,2854,2856],{"class":400,"line":2855},46,[398,2857,2858],{"class":491},"# laco.load assembles them into one DictConfig, which is what lets the\n",[398,2860,2862],{"class":400,"line":2861},47,[398,2863,2864],{"class":491},"# \"${hps.*}\" interpolations in `model`\u002F`optimizer` resolve against the `hps`\n",[398,2866,2868],{"class":400,"line":2867},48,[398,2869,2870],{"class":491},"# node.  Here we reproduce that bundling explicitly.  Dumping `model` on its own\n",[398,2872,2874],{"class":400,"line":2873},49,[398,2875,2876],{"class":491},"# would raise InterpolationKeyError, because its \"${hps.*}\" references have no\n",[398,2878,2880],{"class":400,"line":2879},50,[398,2881,2882],{"class":491},"# `hps` sibling to point at.\n",[398,2884,2886,2888],{"class":400,"line":2885},51,[398,2887,405],{"class":404},[398,2889,1977],{"class":408},[398,2891,2893],{"class":400,"line":2892},52,[398,2894,644],{"emptyLinePlaceholder":643},[398,2896,2898,2900,2902,2904,2906,2908,2910,2913],{"class":400,"line":2897},53,[398,2899,579],{"class":408},[398,2901,506],{"class":505},[398,2903,2052],{"class":408},[398,2905,421],{"class":420},[398,2907,2189],{"class":424},[398,2909,421],{"class":420},[398,2911,2912],{"class":514},"create",[398,2914,2915],{"class":420},"(\n",[398,2917,2919,2922,2924,2927,2929,2931,2933,2936,2939,2941,2943,2945,2948,2950,2952,2954,2956,2958,2960],{"class":400,"line":2918},54,[398,2920,2921],{"class":420},"    {",[398,2923,852],{"class":851},[398,2925,2926],{"class":855},"hps",[398,2928,852],{"class":851},[398,2930,2518],{"class":420},[398,2932,2507],{"class":514},[398,2934,2935],{"class":420},"(),",[398,2937,2938],{"class":851}," \"",[398,2940,1499],{"class":855},[398,2942,852],{"class":851},[398,2944,2518],{"class":420},[398,2946,2947],{"class":514}," model",[398,2949,525],{"class":420},[398,2951,2938],{"class":851},[398,2953,1521],{"class":855},[398,2955,852],{"class":851},[398,2957,2518],{"class":420},[398,2959,1545],{"class":514},[398,2961,2962],{"class":420},"}\n",[398,2964,2966],{"class":400,"line":2965},55,[398,2967,531],{"class":420},[398,2969,2971],{"class":400,"line":2970},56,[398,2972,644],{"emptyLinePlaceholder":643},[398,2974,2976,2978,2980,2982,2985,2987],{"class":400,"line":2975},57,[398,2977,537],{"class":536},[398,2979,518],{"class":420},[398,2981,852],{"class":851},[398,2983,2984],{"class":855},"=== full config (model + optimizer + hps) ===",[398,2986,852],{"class":851},[398,2988,531],{"class":420},[398,2990,2992,2994,2996,2998,3000,3002,3004,3006],{"class":400,"line":2991},58,[398,2993,537],{"class":536},[398,2995,518],{"class":420},[398,2997,982],{"class":514},[398,2999,421],{"class":420},[398,3001,987],{"class":514},[398,3003,518],{"class":420},[398,3005,633],{"class":514},[398,3007,994],{"class":420},[556,3009],{"data":3010,"kind":559},"PT09IGZ1bGwgY29uZmlnIChtb2RlbCArIG9wdGltaXplciArIGhwcykgPT09Cl9sYWNvXzogMQpocHM6IHtiaWFzOiB0cnVlLCBpbl9mZWF0dXJlczogOCwgbGVhcm5pbmdfcmF0ZTogMC4wMSwgbW9tZW50dW06IDAuOSwgb3V0X2ZlYXR1cmVzOiAxfQptb2RlbDoge19jb252ZXJ0XzogYWxsLCBfdGFyZ2V0XzogdG9yY2gubm4uTGluZWFyLCBiaWFzOiAnJHtocHMuYmlhc30nLCBpbl9mZWF0dXJlczogJyR7aHBzLmluX2ZlYXR1cmVzfScsCiAgb3V0X2ZlYXR1cmVzOiAnJHtocHMub3V0X2ZlYXR1cmVzfSd9Cm9wdGltaXplcjoge19jb252ZXJ0XzogYWxsLCBfcGFydGlhbF86IHRydWUsIF90YXJnZXRfOiB0b3JjaC5vcHRpbS5TR0QsIGxyOiAnJHtocHMubGVhcm5pbmdfcmF0ZX0nLAogIG1vbWVudHVtOiAnJHtocHMubW9tZW50dW19J30KCg==",[389,3012,3014],{"className":391,"code":3013,"language":393,"meta":394,"style":394},"# Load the real file and instantiate the model:\ncfg = laco.load(\"configs:\u002F\u002Fexamples\u002Flinear_regression.py#model\")\nbuilt_model = laco.instantiate(cfg)\nprint(built_model)  # Linear(in_features=8, out_features=1, bias=True)\n\n# Load with an override — change in_features without editing the file:\ncfg_wide = laco.load(\n    \"configs:\u002F\u002Fexamples\u002Flinear_regression.py\",\n    \"hps.in_features=32\",\n    key=\"model\"\n)\nbuilt_wide = laco.instantiate(cfg_wide)\nprint(built_wide)   # Linear(in_features=32, out_features=1, bias=True)\n",[231,3015,3016,3021,3045,3064,3078,3082,3087,3102,3114,3125,3139,3143,3163],{"__ignoreMap":394},[398,3017,3018],{"class":400,"line":401},[398,3019,3020],{"class":491},"# Load the real file and instantiate the model:\n",[398,3022,3023,3025,3027,3029,3031,3034,3036,3038,3041,3043],{"class":400,"line":412},[398,3024,579],{"class":408},[398,3026,506],{"class":505},[398,3028,417],{"class":408},[398,3030,421],{"class":420},[398,3032,3033],{"class":514},"load",[398,3035,518],{"class":420},[398,3037,852],{"class":851},[398,3039,3040],{"class":855},"configs:\u002F\u002Fexamples\u002Flinear_regression.py#model",[398,3042,852],{"class":851},[398,3044,531],{"class":420},[398,3046,3047,3050,3052,3054,3056,3058,3060,3062],{"class":400,"line":433},[398,3048,3049],{"class":408},"built_model ",[398,3051,506],{"class":505},[398,3053,417],{"class":408},[398,3055,421],{"class":420},[398,3057,665],{"class":514},[398,3059,518],{"class":420},[398,3061,633],{"class":514},[398,3063,531],{"class":420},[398,3065,3066,3068,3070,3073,3075],{"class":400,"line":441},[398,3067,537],{"class":536},[398,3069,518],{"class":420},[398,3071,3072],{"class":514},"built_model",[398,3074,255],{"class":420},[398,3076,3077],{"class":491},"  # Linear(in_features=8, out_features=1, bias=True)\n",[398,3079,3080],{"class":400,"line":459},[398,3081,644],{"emptyLinePlaceholder":643},[398,3083,3084],{"class":400,"line":647},[398,3085,3086],{"class":491},"# Load with an override — change in_features without editing the file:\n",[398,3088,3089,3092,3094,3096,3098,3100],{"class":400,"line":653},[398,3090,3091],{"class":408},"cfg_wide ",[398,3093,506],{"class":505},[398,3095,417],{"class":408},[398,3097,421],{"class":420},[398,3099,3033],{"class":514},[398,3101,2915],{"class":420},[398,3103,3104,3107,3110,3112],{"class":400,"line":674},[398,3105,3106],{"class":851},"    \"",[398,3108,3109],{"class":855},"configs:\u002F\u002Fexamples\u002Flinear_regression.py",[398,3111,852],{"class":851},[398,3113,2132],{"class":420},[398,3115,3116,3118,3121,3123],{"class":400,"line":975},[398,3117,3106],{"class":851},[398,3119,3120],{"class":855},"hps.in_features=32",[398,3122,852],{"class":851},[398,3124,2132],{"class":420},[398,3126,3127,3130,3132,3134,3136],{"class":400,"line":1486},[398,3128,3129],{"class":603},"    key",[398,3131,506],{"class":505},[398,3133,852],{"class":851},[398,3135,1499],{"class":855},[398,3137,3138],{"class":851},"\"\n",[398,3140,3141],{"class":400,"line":1510},[398,3142,531],{"class":420},[398,3144,3145,3148,3150,3152,3154,3156,3158,3161],{"class":400,"line":1529},[398,3146,3147],{"class":408},"built_wide ",[398,3149,506],{"class":505},[398,3151,417],{"class":408},[398,3153,421],{"class":420},[398,3155,665],{"class":514},[398,3157,518],{"class":420},[398,3159,3160],{"class":514},"cfg_wide",[398,3162,531],{"class":420},[398,3164,3165,3167,3169,3172,3174],{"class":400,"line":2512},[398,3166,537],{"class":536},[398,3168,518],{"class":420},[398,3170,3171],{"class":514},"built_wide",[398,3173,255],{"class":420},[398,3175,3176],{"class":491},"   # Linear(in_features=32, out_features=1, bias=True)\n",[556,3178],{"data":3179,"kind":559},"TGluZWFyKGluX2ZlYXR1cmVzPTgsIG91dF9mZWF0dXJlcz0xLCBiaWFzPVRydWUpCkxpbmVhcihpbl9mZWF0dXJlcz0zMiwgb3V0X2ZlYXR1cmVzPTEsIGJpYXM9VHJ1ZSkK",[475,3181,3183],{"id":3182},"recap","Recap",[287,3185,3186,3195],{},[290,3187,3188],{},[293,3189,3190,3192],{},[296,3191,298],{},[296,3193,3194],{},"Use it when…",[306,3196,3197,3206,3215,3224],{},[293,3198,3199,3203],{},[311,3200,3201],{},[231,3202,315],{},[311,3204,3205],{},"You want a full object, no deferred arguments",[293,3207,3208,3212],{},[311,3209,3210],{},[231,3211,332],{},[311,3213,3214],{},"The object needs an argument that only exists after another object is built (classic: optimizer needing model parameters)",[293,3216,3217,3221],{},[311,3218,3219],{},[231,3220,352],{},[311,3222,3223],{},"You have an in-memory object and want to embed it in a config tree",[293,3225,3226,3230],{},[311,3227,3228],{},[231,3229,367],{},[311,3231,3232],{},"A field is genuinely mandatory, no sensible default exists",[216,3234,3235,229,3238,3241,3242,3245],{},[219,3236,3237],{},"Next:",[231,3239,3240],{},"04.hyperparameters-and-interpolation.ipynb"," covers ",[231,3243,3244],{},"@L.params"," and the interpolation system that makes sweeping hyperparameters across a whole config tree a one-liner.",[3247,3248,3249],"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 .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 .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .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 .swQdS, html code.shiki .swQdS{--shiki-light:#E53935;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":394,"searchDepth":433,"depth":433,"links":3251},[3252,3253,3258,3260,3261,3263,3268,3270],{"id":477,"depth":412,"text":478},{"id":753,"depth":412,"text":3254,"children":3255},"Section 2: L.call in detail",[3256],{"id":1001,"depth":433,"text":3257},"strict=True: catching typos at config-build time",{"id":1130,"depth":412,"text":3259},"Section 3: Why L.partial exists",{"id":1609,"depth":412,"text":1610},{"id":1693,"depth":412,"text":3262},"Section 5: Wrapping an existing value with L.just",{"id":1943,"depth":412,"text":3264,"children":3265},"Section 6: Mandatory fields with L.required[T]()",[3266],{"id":2299,"depth":433,"text":3267},"L.required[T]() vs omegaconf.MISSING: the typing difference",{"id":2392,"depth":412,"text":3269},"Section 7: linear_regression.py walkthrough",{"id":3182,"depth":412,"text":3183},"Series: laco tutorial notebooksPrerequisites: 01.why-laco.ipynb (motivation), 02.first-steps.ipynb (config basics)Dependencies: torch (for nn.Linear, optim.Adam)","md",{"notebook":643},{"icon":25},{"title":31,"description":3271},"3e7xDtqza7x1fNO6n_CB_laxmbt1jCnNHIxYvHgQQCw",{},1785687301738]