[{"data":1,"prerenderedAt":4935},["ShallowReactive",2],{"navigation":3,"api-navigation":184,"\u002Flearn\u002Fexamples\u002Fbuilding-blocks":206,"docyard:crossref-index":4934},[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":144,"body":208,"description":345,"extension":4930,"meta":4931,"navigation":392,"path":145,"seo":4932,"stem":146,"__hash__":4933},"content\u002F2.learn\u002F4.examples\u002F2.building-blocks.md",{"type":209,"value":210,"toc":4899},"minimark",[211,215,222,230,233,238,241,280,291,293,301,313,334,339,1906,1910,1923,1944,1964,1978,1982,2240,2244,2272,2274,2282,2292,2299,2302,2959,2962,2979,2998,3017,3029,3032,3193,3196,3221,3223,3230,3240,3253,3256,3997,4000,4009,4024,4045,4048,4432,4435,4465,4467,4471,4475,4606,4612,4618,4698,4715,4719,4728,4856,4860,4889,4895],[212,213,144],"h1",{"id":214},"building-blocks",[216,217,218],"blockquote",{},[219,220,221],"p",{},"Tier 2: reusable neural-network building blocks expressed as config factory functions. Each file provides a plain Python function that returns a laco config node, not a live module, so it can be composed into larger config trees without instantiation.",[219,223,224,225,229],{},"All source files live under ",[226,227,228],"code",{},"sources\u002Flaco\u002Fexamples\u002Fblocks\u002F",".",[231,232],"hr",{},[234,235,237],"h2",{"id":236},"design-philosophy","Design philosophy",[219,239,240],{},"Building-block files follow a strict convention:",[242,243,244,256,270],"ol",{},[245,246,247,255],"li",{},[248,249,250,251,254],"strong",{},"Define a plain ",[226,252,253],{},"nn.Module"," class",": the implementation, written without any laco awareness.",[245,257,258,261,262,265,266,269],{},[248,259,260],{},"Expose a config factory function",": a short function (e.g. ",[226,263,264],{},"basic_block(...)",") that calls ",[226,267,268],{},"L.call(TheModule)(...)"," with the given arguments and returns the resulting config node.",[245,271,272,275,276,279],{},[248,273,274],{},"Export both"," via ",[226,277,278],{},"__all__",": callers can import either the class (for direct use in custom code) or the factory (for laco composition).",[219,281,282,283,286,287,290],{},"The factory function is the laco entry point. Calling it is pure Python; it runs at config-build time and produces a config node that will instantiate ",[226,284,285],{},"TheModule"," when ",[226,288,289],{},"laco.instantiate"," is called.",[231,292],{},[234,294,296,297,300],{"id":295},"_1-blocksresidualpy-resnet-style-residual-blocks","1. ",[226,298,299],{},"blocks\u002Fresidual.py",": ResNet-style residual blocks",[216,302,303],{},[219,304,305,306],{},"Source: ",[307,308,310],"a",{"href":309},"..\u002F..\u002Fsources\u002Flaco\u002Fexamples\u002Fblocks\u002Fresidual.py",[226,311,312],{},"sources\u002Flaco\u002Fexamples\u002Fblocks\u002Fresidual.py",[219,314,315,316,319,320,323,324,319,327,330,331,229],{},"Provides two block variants (",[226,317,318],{},"BasicBlock",", ",[226,321,322],{},"Bottleneck",") and their corresponding config factories (",[226,325,326],{},"basic_block",[226,328,329],{},"bottleneck_block","). Used by ",[226,332,333],{},"laco.examples.models.resnet",[335,336,338],"h3",{"id":337},"key-source-patterns","Key source patterns",[340,341,346],"pre",{"className":342,"code":343,"language":344,"meta":345,"style":345},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","import laco.language as L\nfrom torch import nn\n\n__all__ = [\"basic_block\", \"bottleneck_block\", \"BasicBlock\", \"Bottleneck\"]\n\n\nclass BasicBlock(nn.Module):\n    expansion: int = 1\n\n    def __init__(self, in_channels: int, channels: int, stride: int = 1):\n        super().__init__()\n        self.conv1 = nn.Conv2d(\n            in_channels, channels, 3, stride=stride, padding=1, bias=False\n        )\n        self.bn1 = nn.BatchNorm2d(channels)\n        self.conv2 = nn.Conv2d(channels, channels, 3, padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(channels)\n        self.relu = nn.ReLU(inplace=True)\n        if stride != 1 or in_channels != channels:\n            self.downsample = nn.Sequential(\n                nn.Conv2d(in_channels, channels, 1, stride=stride, bias=False),\n                nn.BatchNorm2d(channels),\n            )\n        else:\n            self.downsample = nn.Identity()\n\n    def forward(self, x):\n        identity = self.downsample(x)\n        out = self.relu(self.bn1(self.conv1(x)))\n        out = self.bn2(self.conv2(out))\n        return self.relu(out + identity)\n\n\nclass Bottleneck(nn.Module):\n    expansion: int = 4\n\n    def __init__(self, in_channels: int, channels: int, stride: int = 1):\n        super().__init__()\n        out_channels = channels * self.expansion\n        self.conv1 = nn.Conv2d(in_channels, channels, 1, bias=False)\n        self.bn1 = nn.BatchNorm2d(channels)\n        self.conv2 = nn.Conv2d(\n            channels, channels, 3, stride=stride, padding=1, bias=False\n        )\n        self.bn2 = nn.BatchNorm2d(channels)\n        self.conv3 = nn.Conv2d(channels, out_channels, 1, bias=False)\n        self.bn3 = nn.BatchNorm2d(out_channels)\n        self.relu = nn.ReLU(inplace=True)\n        if stride != 1 or in_channels != out_channels:\n            self.downsample = nn.Sequential(\n                nn.Conv2d(in_channels, out_channels, 1, stride=stride, bias=False),\n                nn.BatchNorm2d(out_channels),\n            )\n        else:\n            self.downsample = nn.Identity()\n\n    def forward(self, x):\n        identity = self.downsample(x)\n        out = self.relu(self.bn1(self.conv1(x)))\n        out = self.relu(self.bn2(self.conv2(out)))\n        out = self.bn3(self.conv3(out))\n        return self.relu(out + identity)\n\n\n# Config factory functions: these are what downstream configs import\ndef basic_block(in_channels: int, channels: int, stride: int = 1):\n    return L.call(BasicBlock)(\n        in_channels=in_channels, channels=channels, stride=stride\n    )\n\n\ndef bottleneck_block(in_channels: int, channels: int, stride: int = 1):\n    return L.call(Bottleneck)(\n        in_channels=in_channels, channels=channels, stride=stride\n    )\n","python","",[226,347,348,373,387,394,445,450,455,480,499,504,555,570,595,642,648,675,724,748,779,806,828,870,885,891,899,919,924,944,966,1003,1032,1057,1062,1067,1085,1099,1104,1145,1156,1177,1216,1239,1258,1296,1301,1324,1365,1390,1417,1438,1457,1496,1511,1516,1523,1542,1547,1564,1583,1618,1653,1680,1701,1706,1711,1718,1757,1778,1805,1811,1816,1821,1859,1876,1901],{"__ignoreMap":345},[349,350,353,357,361,364,367,370],"span",{"class":351,"line":352},"line",1,[349,354,356],{"class":355},"sVHd0","import",[349,358,360],{"class":359},"su5hD"," laco",[349,362,229],{"class":363},"sP7_E",[349,365,198],{"class":366},"skxfh",[349,368,369],{"class":355}," as",[349,371,372],{"class":359}," L\n",[349,374,376,379,382,384],{"class":351,"line":375},2,[349,377,378],{"class":355},"from",[349,380,381],{"class":359}," torch ",[349,383,356],{"class":355},[349,385,386],{"class":359}," nn\n",[349,388,390],{"class":351,"line":389},3,[349,391,393],{"emptyLinePlaceholder":392},true,"\n",[349,395,397,400,404,407,411,414,416,419,422,424,426,428,430,432,434,436,438,440,442],{"class":351,"line":396},4,[349,398,278],{"class":399},"s_hVV",[349,401,403],{"class":402},"smGrS"," =",[349,405,406],{"class":363}," [",[349,408,410],{"class":409},"sjJ54","\"",[349,412,326],{"class":413},"s_sjI",[349,415,410],{"class":409},[349,417,418],{"class":363},",",[349,420,421],{"class":409}," \"",[349,423,329],{"class":413},[349,425,410],{"class":409},[349,427,418],{"class":363},[349,429,421],{"class":409},[349,431,318],{"class":413},[349,433,410],{"class":409},[349,435,418],{"class":363},[349,437,421],{"class":409},[349,439,322],{"class":413},[349,441,410],{"class":409},[349,443,444],{"class":363},"]\n",[349,446,448],{"class":351,"line":447},5,[349,449,393],{"emptyLinePlaceholder":392},[349,451,453],{"class":351,"line":452},6,[349,454,393],{"emptyLinePlaceholder":392},[349,456,458,462,466,469,472,474,477],{"class":351,"line":457},7,[349,459,461],{"class":460},"sbsja","class",[349,463,465],{"class":464},"sbgvK"," BasicBlock",[349,467,468],{"class":363},"(",[349,470,471],{"class":464},"nn",[349,473,229],{"class":363},[349,475,476],{"class":464},"Module",[349,478,479],{"class":363},"):\n",[349,481,483,486,489,493,495],{"class":351,"line":482},8,[349,484,485],{"class":359},"    expansion",[349,487,488],{"class":363},":",[349,490,492],{"class":491},"sZMiF"," int",[349,494,403],{"class":402},[349,496,498],{"class":497},"srdBf"," 1\n",[349,500,502],{"class":351,"line":501},9,[349,503,393],{"emptyLinePlaceholder":392},[349,505,507,510,514,516,520,522,526,528,530,532,535,537,539,541,544,546,548,550,553],{"class":351,"line":506},10,[349,508,509],{"class":460},"    def",[349,511,513],{"class":512},"sptTA"," __init__",[349,515,468],{"class":363},[349,517,519],{"class":518},"smCYv","self",[349,521,418],{"class":363},[349,523,525],{"class":524},"sFwrP"," in_channels",[349,527,488],{"class":363},[349,529,492],{"class":491},[349,531,418],{"class":363},[349,533,534],{"class":524}," channels",[349,536,488],{"class":363},[349,538,492],{"class":491},[349,540,418],{"class":363},[349,542,543],{"class":524}," stride",[349,545,488],{"class":363},[349,547,492],{"class":491},[349,549,403],{"class":402},[349,551,552],{"class":497}," 1",[349,554,479],{"class":363},[349,556,558,561,564,567],{"class":351,"line":557},11,[349,559,560],{"class":491},"        super",[349,562,563],{"class":363},"().",[349,565,566],{"class":512},"__init__",[349,568,569],{"class":363},"()\n",[349,571,573,576,578,581,583,586,588,592],{"class":351,"line":572},12,[349,574,575],{"class":399},"        self",[349,577,229],{"class":363},[349,579,580],{"class":366},"conv1",[349,582,403],{"class":402},[349,584,585],{"class":359}," nn",[349,587,229],{"class":363},[349,589,591],{"class":590},"slqww","Conv2d",[349,593,594],{"class":363},"(\n",[349,596,598,601,603,605,607,610,612,615,618,621,623,626,628,631,633,636,638],{"class":351,"line":597},13,[349,599,600],{"class":590},"            in_channels",[349,602,418],{"class":363},[349,604,534],{"class":590},[349,606,418],{"class":363},[349,608,609],{"class":497}," 3",[349,611,418],{"class":363},[349,613,543],{"class":614},"s99_P",[349,616,617],{"class":402},"=",[349,619,620],{"class":590},"stride",[349,622,418],{"class":363},[349,624,625],{"class":614}," padding",[349,627,617],{"class":402},[349,629,630],{"class":497},"1",[349,632,418],{"class":363},[349,634,635],{"class":614}," bias",[349,637,617],{"class":402},[349,639,641],{"class":640},"s39Yj","False\n",[349,643,645],{"class":351,"line":644},14,[349,646,647],{"class":363},"        )\n",[349,649,651,653,655,658,660,662,664,667,669,672],{"class":351,"line":650},15,[349,652,575],{"class":399},[349,654,229],{"class":363},[349,656,657],{"class":366},"bn1",[349,659,403],{"class":402},[349,661,585],{"class":359},[349,663,229],{"class":363},[349,665,666],{"class":590},"BatchNorm2d",[349,668,468],{"class":363},[349,670,671],{"class":590},"channels",[349,673,674],{"class":363},")\n",[349,676,678,680,682,685,687,689,691,693,695,697,699,701,703,705,707,709,711,713,715,717,719,722],{"class":351,"line":677},16,[349,679,575],{"class":399},[349,681,229],{"class":363},[349,683,684],{"class":366},"conv2",[349,686,403],{"class":402},[349,688,585],{"class":359},[349,690,229],{"class":363},[349,692,591],{"class":590},[349,694,468],{"class":363},[349,696,671],{"class":590},[349,698,418],{"class":363},[349,700,534],{"class":590},[349,702,418],{"class":363},[349,704,609],{"class":497},[349,706,418],{"class":363},[349,708,625],{"class":614},[349,710,617],{"class":402},[349,712,630],{"class":497},[349,714,418],{"class":363},[349,716,635],{"class":614},[349,718,617],{"class":402},[349,720,721],{"class":640},"False",[349,723,674],{"class":363},[349,725,727,729,731,734,736,738,740,742,744,746],{"class":351,"line":726},17,[349,728,575],{"class":399},[349,730,229],{"class":363},[349,732,733],{"class":366},"bn2",[349,735,403],{"class":402},[349,737,585],{"class":359},[349,739,229],{"class":363},[349,741,666],{"class":590},[349,743,468],{"class":363},[349,745,671],{"class":590},[349,747,674],{"class":363},[349,749,751,753,755,758,760,762,764,767,769,772,774,777],{"class":351,"line":750},18,[349,752,575],{"class":399},[349,754,229],{"class":363},[349,756,757],{"class":366},"relu",[349,759,403],{"class":402},[349,761,585],{"class":359},[349,763,229],{"class":363},[349,765,766],{"class":590},"ReLU",[349,768,468],{"class":363},[349,770,771],{"class":614},"inplace",[349,773,617],{"class":402},[349,775,776],{"class":640},"True",[349,778,674],{"class":363},[349,780,782,785,788,791,793,796,799,801,803],{"class":351,"line":781},19,[349,783,784],{"class":355},"        if",[349,786,787],{"class":359}," stride ",[349,789,790],{"class":402},"!=",[349,792,552],{"class":497},[349,794,795],{"class":402}," or",[349,797,798],{"class":359}," in_channels ",[349,800,790],{"class":402},[349,802,534],{"class":359},[349,804,805],{"class":363},":\n",[349,807,809,812,814,817,819,821,823,826],{"class":351,"line":808},20,[349,810,811],{"class":399},"            self",[349,813,229],{"class":363},[349,815,816],{"class":366},"downsample",[349,818,403],{"class":402},[349,820,585],{"class":359},[349,822,229],{"class":363},[349,824,825],{"class":590},"Sequential",[349,827,594],{"class":363},[349,829,831,834,836,838,840,843,845,847,849,851,853,855,857,859,861,863,865,867],{"class":351,"line":830},21,[349,832,833],{"class":590},"                nn",[349,835,229],{"class":363},[349,837,591],{"class":590},[349,839,468],{"class":363},[349,841,842],{"class":590},"in_channels",[349,844,418],{"class":363},[349,846,534],{"class":590},[349,848,418],{"class":363},[349,850,552],{"class":497},[349,852,418],{"class":363},[349,854,543],{"class":614},[349,856,617],{"class":402},[349,858,620],{"class":590},[349,860,418],{"class":363},[349,862,635],{"class":614},[349,864,617],{"class":402},[349,866,721],{"class":640},[349,868,869],{"class":363},"),\n",[349,871,873,875,877,879,881,883],{"class":351,"line":872},22,[349,874,833],{"class":590},[349,876,229],{"class":363},[349,878,666],{"class":590},[349,880,468],{"class":363},[349,882,671],{"class":590},[349,884,869],{"class":363},[349,886,888],{"class":351,"line":887},23,[349,889,890],{"class":363},"            )\n",[349,892,894,897],{"class":351,"line":893},24,[349,895,896],{"class":355},"        else",[349,898,805],{"class":363},[349,900,902,904,906,908,910,912,914,917],{"class":351,"line":901},25,[349,903,811],{"class":399},[349,905,229],{"class":363},[349,907,816],{"class":366},[349,909,403],{"class":402},[349,911,585],{"class":359},[349,913,229],{"class":363},[349,915,916],{"class":590},"Identity",[349,918,569],{"class":363},[349,920,922],{"class":351,"line":921},26,[349,923,393],{"emptyLinePlaceholder":392},[349,925,927,929,933,935,937,939,942],{"class":351,"line":926},27,[349,928,509],{"class":460},[349,930,932],{"class":931},"sGLFI"," forward",[349,934,468],{"class":363},[349,936,519],{"class":518},[349,938,418],{"class":363},[349,940,941],{"class":524}," x",[349,943,479],{"class":363},[349,945,947,950,952,955,957,959,961,964],{"class":351,"line":946},28,[349,948,949],{"class":359},"        identity ",[349,951,617],{"class":402},[349,953,954],{"class":399}," self",[349,956,229],{"class":363},[349,958,816],{"class":590},[349,960,468],{"class":363},[349,962,963],{"class":590},"x",[349,965,674],{"class":363},[349,967,969,972,974,976,978,980,982,984,986,988,990,992,994,996,998,1000],{"class":351,"line":968},29,[349,970,971],{"class":359},"        out ",[349,973,617],{"class":402},[349,975,954],{"class":399},[349,977,229],{"class":363},[349,979,757],{"class":590},[349,981,468],{"class":363},[349,983,519],{"class":399},[349,985,229],{"class":363},[349,987,657],{"class":590},[349,989,468],{"class":363},[349,991,519],{"class":399},[349,993,229],{"class":363},[349,995,580],{"class":590},[349,997,468],{"class":363},[349,999,963],{"class":590},[349,1001,1002],{"class":363},")))\n",[349,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,1026,1029],{"class":351,"line":1005},30,[349,1007,971],{"class":359},[349,1009,617],{"class":402},[349,1011,954],{"class":399},[349,1013,229],{"class":363},[349,1015,733],{"class":590},[349,1017,468],{"class":363},[349,1019,519],{"class":399},[349,1021,229],{"class":363},[349,1023,684],{"class":590},[349,1025,468],{"class":363},[349,1027,1028],{"class":590},"out",[349,1030,1031],{"class":363},"))\n",[349,1033,1035,1038,1040,1042,1044,1046,1049,1052,1055],{"class":351,"line":1034},31,[349,1036,1037],{"class":355},"        return",[349,1039,954],{"class":399},[349,1041,229],{"class":363},[349,1043,757],{"class":590},[349,1045,468],{"class":363},[349,1047,1048],{"class":590},"out ",[349,1050,1051],{"class":402},"+",[349,1053,1054],{"class":590}," identity",[349,1056,674],{"class":363},[349,1058,1060],{"class":351,"line":1059},32,[349,1061,393],{"emptyLinePlaceholder":392},[349,1063,1065],{"class":351,"line":1064},33,[349,1066,393],{"emptyLinePlaceholder":392},[349,1068,1070,1072,1075,1077,1079,1081,1083],{"class":351,"line":1069},34,[349,1071,461],{"class":460},[349,1073,1074],{"class":464}," Bottleneck",[349,1076,468],{"class":363},[349,1078,471],{"class":464},[349,1080,229],{"class":363},[349,1082,476],{"class":464},[349,1084,479],{"class":363},[349,1086,1088,1090,1092,1094,1096],{"class":351,"line":1087},35,[349,1089,485],{"class":359},[349,1091,488],{"class":363},[349,1093,492],{"class":491},[349,1095,403],{"class":402},[349,1097,1098],{"class":497}," 4\n",[349,1100,1102],{"class":351,"line":1101},36,[349,1103,393],{"emptyLinePlaceholder":392},[349,1105,1107,1109,1111,1113,1115,1117,1119,1121,1123,1125,1127,1129,1131,1133,1135,1137,1139,1141,1143],{"class":351,"line":1106},37,[349,1108,509],{"class":460},[349,1110,513],{"class":512},[349,1112,468],{"class":363},[349,1114,519],{"class":518},[349,1116,418],{"class":363},[349,1118,525],{"class":524},[349,1120,488],{"class":363},[349,1122,492],{"class":491},[349,1124,418],{"class":363},[349,1126,534],{"class":524},[349,1128,488],{"class":363},[349,1130,492],{"class":491},[349,1132,418],{"class":363},[349,1134,543],{"class":524},[349,1136,488],{"class":363},[349,1138,492],{"class":491},[349,1140,403],{"class":402},[349,1142,552],{"class":497},[349,1144,479],{"class":363},[349,1146,1148,1150,1152,1154],{"class":351,"line":1147},38,[349,1149,560],{"class":491},[349,1151,563],{"class":363},[349,1153,566],{"class":512},[349,1155,569],{"class":363},[349,1157,1159,1162,1164,1167,1170,1172,1174],{"class":351,"line":1158},39,[349,1160,1161],{"class":359},"        out_channels ",[349,1163,617],{"class":402},[349,1165,1166],{"class":359}," channels ",[349,1168,1169],{"class":402},"*",[349,1171,954],{"class":399},[349,1173,229],{"class":363},[349,1175,1176],{"class":366},"expansion\n",[349,1178,1180,1182,1184,1186,1188,1190,1192,1194,1196,1198,1200,1202,1204,1206,1208,1210,1212,1214],{"class":351,"line":1179},40,[349,1181,575],{"class":399},[349,1183,229],{"class":363},[349,1185,580],{"class":366},[349,1187,403],{"class":402},[349,1189,585],{"class":359},[349,1191,229],{"class":363},[349,1193,591],{"class":590},[349,1195,468],{"class":363},[349,1197,842],{"class":590},[349,1199,418],{"class":363},[349,1201,534],{"class":590},[349,1203,418],{"class":363},[349,1205,552],{"class":497},[349,1207,418],{"class":363},[349,1209,635],{"class":614},[349,1211,617],{"class":402},[349,1213,721],{"class":640},[349,1215,674],{"class":363},[349,1217,1219,1221,1223,1225,1227,1229,1231,1233,1235,1237],{"class":351,"line":1218},41,[349,1220,575],{"class":399},[349,1222,229],{"class":363},[349,1224,657],{"class":366},[349,1226,403],{"class":402},[349,1228,585],{"class":359},[349,1230,229],{"class":363},[349,1232,666],{"class":590},[349,1234,468],{"class":363},[349,1236,671],{"class":590},[349,1238,674],{"class":363},[349,1240,1242,1244,1246,1248,1250,1252,1254,1256],{"class":351,"line":1241},42,[349,1243,575],{"class":399},[349,1245,229],{"class":363},[349,1247,684],{"class":366},[349,1249,403],{"class":402},[349,1251,585],{"class":359},[349,1253,229],{"class":363},[349,1255,591],{"class":590},[349,1257,594],{"class":363},[349,1259,1261,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282,1284,1286,1288,1290,1292,1294],{"class":351,"line":1260},43,[349,1262,1263],{"class":590},"            channels",[349,1265,418],{"class":363},[349,1267,534],{"class":590},[349,1269,418],{"class":363},[349,1271,609],{"class":497},[349,1273,418],{"class":363},[349,1275,543],{"class":614},[349,1277,617],{"class":402},[349,1279,620],{"class":590},[349,1281,418],{"class":363},[349,1283,625],{"class":614},[349,1285,617],{"class":402},[349,1287,630],{"class":497},[349,1289,418],{"class":363},[349,1291,635],{"class":614},[349,1293,617],{"class":402},[349,1295,641],{"class":640},[349,1297,1299],{"class":351,"line":1298},44,[349,1300,647],{"class":363},[349,1302,1304,1306,1308,1310,1312,1314,1316,1318,1320,1322],{"class":351,"line":1303},45,[349,1305,575],{"class":399},[349,1307,229],{"class":363},[349,1309,733],{"class":366},[349,1311,403],{"class":402},[349,1313,585],{"class":359},[349,1315,229],{"class":363},[349,1317,666],{"class":590},[349,1319,468],{"class":363},[349,1321,671],{"class":590},[349,1323,674],{"class":363},[349,1325,1327,1329,1331,1334,1336,1338,1340,1342,1344,1346,1348,1351,1353,1355,1357,1359,1361,1363],{"class":351,"line":1326},46,[349,1328,575],{"class":399},[349,1330,229],{"class":363},[349,1332,1333],{"class":366},"conv3",[349,1335,403],{"class":402},[349,1337,585],{"class":359},[349,1339,229],{"class":363},[349,1341,591],{"class":590},[349,1343,468],{"class":363},[349,1345,671],{"class":590},[349,1347,418],{"class":363},[349,1349,1350],{"class":590}," out_channels",[349,1352,418],{"class":363},[349,1354,552],{"class":497},[349,1356,418],{"class":363},[349,1358,635],{"class":614},[349,1360,617],{"class":402},[349,1362,721],{"class":640},[349,1364,674],{"class":363},[349,1366,1368,1370,1372,1375,1377,1379,1381,1383,1385,1388],{"class":351,"line":1367},47,[349,1369,575],{"class":399},[349,1371,229],{"class":363},[349,1373,1374],{"class":366},"bn3",[349,1376,403],{"class":402},[349,1378,585],{"class":359},[349,1380,229],{"class":363},[349,1382,666],{"class":590},[349,1384,468],{"class":363},[349,1386,1387],{"class":590},"out_channels",[349,1389,674],{"class":363},[349,1391,1393,1395,1397,1399,1401,1403,1405,1407,1409,1411,1413,1415],{"class":351,"line":1392},48,[349,1394,575],{"class":399},[349,1396,229],{"class":363},[349,1398,757],{"class":366},[349,1400,403],{"class":402},[349,1402,585],{"class":359},[349,1404,229],{"class":363},[349,1406,766],{"class":590},[349,1408,468],{"class":363},[349,1410,771],{"class":614},[349,1412,617],{"class":402},[349,1414,776],{"class":640},[349,1416,674],{"class":363},[349,1418,1420,1422,1424,1426,1428,1430,1432,1434,1436],{"class":351,"line":1419},49,[349,1421,784],{"class":355},[349,1423,787],{"class":359},[349,1425,790],{"class":402},[349,1427,552],{"class":497},[349,1429,795],{"class":402},[349,1431,798],{"class":359},[349,1433,790],{"class":402},[349,1435,1350],{"class":359},[349,1437,805],{"class":363},[349,1439,1441,1443,1445,1447,1449,1451,1453,1455],{"class":351,"line":1440},50,[349,1442,811],{"class":399},[349,1444,229],{"class":363},[349,1446,816],{"class":366},[349,1448,403],{"class":402},[349,1450,585],{"class":359},[349,1452,229],{"class":363},[349,1454,825],{"class":590},[349,1456,594],{"class":363},[349,1458,1460,1462,1464,1466,1468,1470,1472,1474,1476,1478,1480,1482,1484,1486,1488,1490,1492,1494],{"class":351,"line":1459},51,[349,1461,833],{"class":590},[349,1463,229],{"class":363},[349,1465,591],{"class":590},[349,1467,468],{"class":363},[349,1469,842],{"class":590},[349,1471,418],{"class":363},[349,1473,1350],{"class":590},[349,1475,418],{"class":363},[349,1477,552],{"class":497},[349,1479,418],{"class":363},[349,1481,543],{"class":614},[349,1483,617],{"class":402},[349,1485,620],{"class":590},[349,1487,418],{"class":363},[349,1489,635],{"class":614},[349,1491,617],{"class":402},[349,1493,721],{"class":640},[349,1495,869],{"class":363},[349,1497,1499,1501,1503,1505,1507,1509],{"class":351,"line":1498},52,[349,1500,833],{"class":590},[349,1502,229],{"class":363},[349,1504,666],{"class":590},[349,1506,468],{"class":363},[349,1508,1387],{"class":590},[349,1510,869],{"class":363},[349,1512,1514],{"class":351,"line":1513},53,[349,1515,890],{"class":363},[349,1517,1519,1521],{"class":351,"line":1518},54,[349,1520,896],{"class":355},[349,1522,805],{"class":363},[349,1524,1526,1528,1530,1532,1534,1536,1538,1540],{"class":351,"line":1525},55,[349,1527,811],{"class":399},[349,1529,229],{"class":363},[349,1531,816],{"class":366},[349,1533,403],{"class":402},[349,1535,585],{"class":359},[349,1537,229],{"class":363},[349,1539,916],{"class":590},[349,1541,569],{"class":363},[349,1543,1545],{"class":351,"line":1544},56,[349,1546,393],{"emptyLinePlaceholder":392},[349,1548,1550,1552,1554,1556,1558,1560,1562],{"class":351,"line":1549},57,[349,1551,509],{"class":460},[349,1553,932],{"class":931},[349,1555,468],{"class":363},[349,1557,519],{"class":518},[349,1559,418],{"class":363},[349,1561,941],{"class":524},[349,1563,479],{"class":363},[349,1565,1567,1569,1571,1573,1575,1577,1579,1581],{"class":351,"line":1566},58,[349,1568,949],{"class":359},[349,1570,617],{"class":402},[349,1572,954],{"class":399},[349,1574,229],{"class":363},[349,1576,816],{"class":590},[349,1578,468],{"class":363},[349,1580,963],{"class":590},[349,1582,674],{"class":363},[349,1584,1586,1588,1590,1592,1594,1596,1598,1600,1602,1604,1606,1608,1610,1612,1614,1616],{"class":351,"line":1585},59,[349,1587,971],{"class":359},[349,1589,617],{"class":402},[349,1591,954],{"class":399},[349,1593,229],{"class":363},[349,1595,757],{"class":590},[349,1597,468],{"class":363},[349,1599,519],{"class":399},[349,1601,229],{"class":363},[349,1603,657],{"class":590},[349,1605,468],{"class":363},[349,1607,519],{"class":399},[349,1609,229],{"class":363},[349,1611,580],{"class":590},[349,1613,468],{"class":363},[349,1615,963],{"class":590},[349,1617,1002],{"class":363},[349,1619,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639,1641,1643,1645,1647,1649,1651],{"class":351,"line":1620},60,[349,1622,971],{"class":359},[349,1624,617],{"class":402},[349,1626,954],{"class":399},[349,1628,229],{"class":363},[349,1630,757],{"class":590},[349,1632,468],{"class":363},[349,1634,519],{"class":399},[349,1636,229],{"class":363},[349,1638,733],{"class":590},[349,1640,468],{"class":363},[349,1642,519],{"class":399},[349,1644,229],{"class":363},[349,1646,684],{"class":590},[349,1648,468],{"class":363},[349,1650,1028],{"class":590},[349,1652,1002],{"class":363},[349,1654,1656,1658,1660,1662,1664,1666,1668,1670,1672,1674,1676,1678],{"class":351,"line":1655},61,[349,1657,971],{"class":359},[349,1659,617],{"class":402},[349,1661,954],{"class":399},[349,1663,229],{"class":363},[349,1665,1374],{"class":590},[349,1667,468],{"class":363},[349,1669,519],{"class":399},[349,1671,229],{"class":363},[349,1673,1333],{"class":590},[349,1675,468],{"class":363},[349,1677,1028],{"class":590},[349,1679,1031],{"class":363},[349,1681,1683,1685,1687,1689,1691,1693,1695,1697,1699],{"class":351,"line":1682},62,[349,1684,1037],{"class":355},[349,1686,954],{"class":399},[349,1688,229],{"class":363},[349,1690,757],{"class":590},[349,1692,468],{"class":363},[349,1694,1048],{"class":590},[349,1696,1051],{"class":402},[349,1698,1054],{"class":590},[349,1700,674],{"class":363},[349,1702,1704],{"class":351,"line":1703},63,[349,1705,393],{"emptyLinePlaceholder":392},[349,1707,1709],{"class":351,"line":1708},64,[349,1710,393],{"emptyLinePlaceholder":392},[349,1712,1714],{"class":351,"line":1713},65,[349,1715,1717],{"class":1716},"sutJx","# Config factory functions: these are what downstream configs import\n",[349,1719,1721,1724,1727,1729,1731,1733,1735,1737,1739,1741,1743,1745,1747,1749,1751,1753,1755],{"class":351,"line":1720},66,[349,1722,1723],{"class":460},"def",[349,1725,1726],{"class":931}," basic_block",[349,1728,468],{"class":363},[349,1730,842],{"class":524},[349,1732,488],{"class":363},[349,1734,492],{"class":491},[349,1736,418],{"class":363},[349,1738,534],{"class":524},[349,1740,488],{"class":363},[349,1742,492],{"class":491},[349,1744,418],{"class":363},[349,1746,543],{"class":524},[349,1748,488],{"class":363},[349,1750,492],{"class":491},[349,1752,403],{"class":402},[349,1754,552],{"class":497},[349,1756,479],{"class":363},[349,1758,1760,1763,1766,1768,1771,1773,1775],{"class":351,"line":1759},67,[349,1761,1762],{"class":355},"    return",[349,1764,1765],{"class":359}," L",[349,1767,229],{"class":363},[349,1769,1770],{"class":590},"call",[349,1772,468],{"class":363},[349,1774,318],{"class":590},[349,1776,1777],{"class":363},")(\n",[349,1779,1781,1784,1786,1788,1790,1792,1794,1796,1798,1800,1802],{"class":351,"line":1780},68,[349,1782,1783],{"class":614},"        in_channels",[349,1785,617],{"class":402},[349,1787,842],{"class":590},[349,1789,418],{"class":363},[349,1791,534],{"class":614},[349,1793,617],{"class":402},[349,1795,671],{"class":590},[349,1797,418],{"class":363},[349,1799,543],{"class":614},[349,1801,617],{"class":402},[349,1803,1804],{"class":590},"stride\n",[349,1806,1808],{"class":351,"line":1807},69,[349,1809,1810],{"class":363},"    )\n",[349,1812,1814],{"class":351,"line":1813},70,[349,1815,393],{"emptyLinePlaceholder":392},[349,1817,1819],{"class":351,"line":1818},71,[349,1820,393],{"emptyLinePlaceholder":392},[349,1822,1824,1826,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847,1849,1851,1853,1855,1857],{"class":351,"line":1823},72,[349,1825,1723],{"class":460},[349,1827,1828],{"class":931}," bottleneck_block",[349,1830,468],{"class":363},[349,1832,842],{"class":524},[349,1834,488],{"class":363},[349,1836,492],{"class":491},[349,1838,418],{"class":363},[349,1840,534],{"class":524},[349,1842,488],{"class":363},[349,1844,492],{"class":491},[349,1846,418],{"class":363},[349,1848,543],{"class":524},[349,1850,488],{"class":363},[349,1852,492],{"class":491},[349,1854,403],{"class":402},[349,1856,552],{"class":497},[349,1858,479],{"class":363},[349,1860,1862,1864,1866,1868,1870,1872,1874],{"class":351,"line":1861},73,[349,1863,1762],{"class":355},[349,1865,1765],{"class":359},[349,1867,229],{"class":363},[349,1869,1770],{"class":590},[349,1871,468],{"class":363},[349,1873,322],{"class":590},[349,1875,1777],{"class":363},[349,1877,1879,1881,1883,1885,1887,1889,1891,1893,1895,1897,1899],{"class":351,"line":1878},74,[349,1880,1783],{"class":614},[349,1882,617],{"class":402},[349,1884,842],{"class":590},[349,1886,418],{"class":363},[349,1888,534],{"class":614},[349,1890,617],{"class":402},[349,1892,671],{"class":590},[349,1894,418],{"class":363},[349,1896,543],{"class":614},[349,1898,617],{"class":402},[349,1900,1804],{"class":590},[349,1902,1904],{"class":351,"line":1903},75,[349,1905,1810],{"class":363},[335,1907,1909],{"id":1908},"annotated-walkthrough","Annotated walkthrough",[219,1911,1912,1919,1920,1922],{},[248,1913,1914,1916,1917],{},[226,1915,318],{}," and ",[226,1918,322],{}," are ordinary ",[226,1921,253],{}," subclasses. They contain no laco imports; this separation is intentional. The module implementation is testable without a config system.",[219,1924,1925,1930,1933,1934,1937,1938,1940,1941,1943],{},[248,1926,1927,1928],{},"Conditional downsample in ",[226,1929,566],{},[226,1931,1932],{},"nn.Identity()"," vs. ",[226,1935,1936],{},"nn.Sequential(Conv2d, BN)"," is chosen at construction time based on ",[226,1939,620],{}," and channel dimensions. This is standard PyTorch: laco does not interfere with the ",[226,1942,566],{}," body.",[219,1945,1946,1952,1953,1956,1957,1959,1960,1963],{},[248,1947,1948,1951],{},[226,1949,1950],{},"basic_block(in_channels, channels, stride)",": the factory","\nA single-line wrapper: ",[226,1954,1955],{},"return L.call(BasicBlock)(in_channels=in_channels, ...)",". The return value is a config node, not a ",[226,1958,318],{}," instance. Callers can embed it in a larger config tree, pass it to ",[226,1961,1962],{},"L.repeat",", or override its fields before instantiation.",[219,1965,1966,1970,1971,1974,1975,1977],{},[248,1967,1968],{},[226,1969,329],{}," follows the same pattern with ",[226,1972,1973],{},"expansion=4"," (four times as many output channels as ",[226,1976,671],{},").",[335,1979,1981],{"id":1980},"composing-into-a-larger-config","Composing into a larger config",[340,1983,1985],{"className":342,"code":1984,"language":344,"meta":345,"style":345},"from laco.examples.blocks.residual import basic_block\nimport laco.language as L\nfrom torch import nn\n\n# Stack four identical residual blocks\nbackbone = L.call(nn.Sequential, expand_args=True)(\n    L.repeat(4, basic_block(in_channels=64, channels=64))\n)\n\n# Mix strides for a ResNet-style stage\nstage = L.call(nn.Sequential)(\n    basic_block(in_channels=64, channels=128, stride=2),  # downsample\n    basic_block(in_channels=128, channels=128),            # maintain\n    basic_block(in_channels=128, channels=128),\n)\n",[226,1986,1987,2013,2027,2037,2041,2046,2078,2116,2120,2124,2129,2152,2189,2214,2236],{"__ignoreMap":345},[349,1988,1989,1991,1993,1995,1998,2000,2003,2005,2008,2010],{"class":351,"line":352},[349,1990,378],{"class":355},[349,1992,360],{"class":359},[349,1994,229],{"class":363},[349,1996,1997],{"class":359},"examples",[349,1999,229],{"class":363},[349,2001,2002],{"class":359},"blocks",[349,2004,229],{"class":363},[349,2006,2007],{"class":359},"residual ",[349,2009,356],{"class":355},[349,2011,2012],{"class":359}," basic_block\n",[349,2014,2015,2017,2019,2021,2023,2025],{"class":351,"line":375},[349,2016,356],{"class":355},[349,2018,360],{"class":359},[349,2020,229],{"class":363},[349,2022,198],{"class":366},[349,2024,369],{"class":355},[349,2026,372],{"class":359},[349,2028,2029,2031,2033,2035],{"class":351,"line":389},[349,2030,378],{"class":355},[349,2032,381],{"class":359},[349,2034,356],{"class":355},[349,2036,386],{"class":359},[349,2038,2039],{"class":351,"line":396},[349,2040,393],{"emptyLinePlaceholder":392},[349,2042,2043],{"class":351,"line":447},[349,2044,2045],{"class":1716},"# Stack four identical residual blocks\n",[349,2047,2048,2051,2053,2055,2057,2059,2061,2063,2065,2067,2069,2072,2074,2076],{"class":351,"line":452},[349,2049,2050],{"class":359},"backbone ",[349,2052,617],{"class":402},[349,2054,1765],{"class":359},[349,2056,229],{"class":363},[349,2058,1770],{"class":590},[349,2060,468],{"class":363},[349,2062,471],{"class":590},[349,2064,229],{"class":363},[349,2066,825],{"class":366},[349,2068,418],{"class":363},[349,2070,2071],{"class":614}," expand_args",[349,2073,617],{"class":402},[349,2075,776],{"class":640},[349,2077,1777],{"class":363},[349,2079,2080,2083,2085,2088,2090,2093,2095,2097,2099,2101,2103,2106,2108,2110,2112,2114],{"class":351,"line":457},[349,2081,2082],{"class":590},"    L",[349,2084,229],{"class":363},[349,2086,2087],{"class":590},"repeat",[349,2089,468],{"class":363},[349,2091,2092],{"class":497},"4",[349,2094,418],{"class":363},[349,2096,1726],{"class":590},[349,2098,468],{"class":363},[349,2100,842],{"class":614},[349,2102,617],{"class":402},[349,2104,2105],{"class":497},"64",[349,2107,418],{"class":363},[349,2109,534],{"class":614},[349,2111,617],{"class":402},[349,2113,2105],{"class":497},[349,2115,1031],{"class":363},[349,2117,2118],{"class":351,"line":482},[349,2119,674],{"class":363},[349,2121,2122],{"class":351,"line":501},[349,2123,393],{"emptyLinePlaceholder":392},[349,2125,2126],{"class":351,"line":506},[349,2127,2128],{"class":1716},"# Mix strides for a ResNet-style stage\n",[349,2130,2131,2134,2136,2138,2140,2142,2144,2146,2148,2150],{"class":351,"line":557},[349,2132,2133],{"class":359},"stage ",[349,2135,617],{"class":402},[349,2137,1765],{"class":359},[349,2139,229],{"class":363},[349,2141,1770],{"class":590},[349,2143,468],{"class":363},[349,2145,471],{"class":590},[349,2147,229],{"class":363},[349,2149,825],{"class":366},[349,2151,1777],{"class":363},[349,2153,2154,2157,2159,2161,2163,2165,2167,2169,2171,2174,2176,2178,2180,2183,2186],{"class":351,"line":572},[349,2155,2156],{"class":590},"    basic_block",[349,2158,468],{"class":363},[349,2160,842],{"class":614},[349,2162,617],{"class":402},[349,2164,2105],{"class":497},[349,2166,418],{"class":363},[349,2168,534],{"class":614},[349,2170,617],{"class":402},[349,2172,2173],{"class":497},"128",[349,2175,418],{"class":363},[349,2177,543],{"class":614},[349,2179,617],{"class":402},[349,2181,2182],{"class":497},"2",[349,2184,2185],{"class":363},"),",[349,2187,2188],{"class":1716},"  # downsample\n",[349,2190,2191,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211],{"class":351,"line":597},[349,2192,2156],{"class":590},[349,2194,468],{"class":363},[349,2196,842],{"class":614},[349,2198,617],{"class":402},[349,2200,2173],{"class":497},[349,2202,418],{"class":363},[349,2204,534],{"class":614},[349,2206,617],{"class":402},[349,2208,2173],{"class":497},[349,2210,2185],{"class":363},[349,2212,2213],{"class":1716},"            # maintain\n",[349,2215,2216,2218,2220,2222,2224,2226,2228,2230,2232,2234],{"class":351,"line":644},[349,2217,2156],{"class":590},[349,2219,468],{"class":363},[349,2221,842],{"class":614},[349,2223,617],{"class":402},[349,2225,2173],{"class":497},[349,2227,418],{"class":363},[349,2229,534],{"class":614},[349,2231,617],{"class":402},[349,2233,2173],{"class":497},[349,2235,869],{"class":363},[349,2237,2238],{"class":351,"line":650},[349,2239,674],{"class":363},[335,2241,2243],{"id":2242},"what-this-demonstrates","What this demonstrates",[2245,2246,2247,2257,2266,2269],"ul",{},[245,2248,2249,2250,2252,2253,2256],{},"Config factory over bare ",[226,2251,253],{},": ",[226,2254,2255],{},"L.call(BasicBlock)(...)"," returns a config node",[245,2258,2259,2262,2263,2265],{},[226,2260,2261],{},"expansion"," class attribute propagates through ",[226,2264,566],{}," without laco involvement",[245,2267,2268],{},"Conditional construction (downsample path) is pure Python, not a laco concern",[245,2270,2271],{},"Both factory and class are exported; downstream code chooses the right entry point",[231,2273],{},[234,2275,2277,2278,2281],{"id":2276},"_2-blockstransformerpy-pre-norm-transformer-encoder-block","2. ",[226,2279,2280],{},"blocks\u002Ftransformer.py",": Pre-norm Transformer encoder block",[216,2283,2284],{},[219,2285,305,2286],{},[307,2287,2289],{"href":2288},"..\u002F..\u002Fsources\u002Flaco\u002Fexamples\u002Fblocks\u002Ftransformer.py",[226,2290,2291],{},"sources\u002Flaco\u002Fexamples\u002Fblocks\u002Ftransformer.py",[219,2293,2294,2295,2298],{},"Vision-style pre-norm Transformer encoder block: ",[226,2296,2297],{},"LayerNorm → MultiheadAttention → residual → LayerNorm → MLP → residual",". Used by ViT-style image encoders.",[335,2300,338],{"id":2301},"key-source-patterns-1",[340,2303,2305],{"className":342,"code":2304,"language":344,"meta":345,"style":345},"import laco.language as L\nfrom torch import nn\n\n__all__ = [\"transformer_block\", \"TransformerBlock\"]\n\n\nclass TransformerBlock(nn.Module):\n    def __init__(\n        self,\n        hidden_size: int,\n        num_heads: int,\n        mlp_ratio: float = 4.0,\n        dropout: float = 0.0,\n    ):\n        super().__init__()\n        self.norm1 = nn.LayerNorm(hidden_size)\n        self.attn = nn.MultiheadAttention(\n            hidden_size, num_heads, dropout=dropout, batch_first=True\n        )\n        self.norm2 = nn.LayerNorm(hidden_size)\n        intermediate = int(hidden_size * mlp_ratio)\n        self.mlp = nn.Sequential(\n            nn.Linear(hidden_size, intermediate),\n            nn.GELU(),\n            nn.Dropout(dropout),\n            nn.Linear(intermediate, hidden_size),\n            nn.Dropout(dropout),\n        )\n\n    def forward(self, x):\n        h = self.norm1(x)\n        attn_out, _ = self.attn(h, h, h, need_weights=False)\n        x = x + attn_out\n        return x + self.mlp(self.norm2(x))\n\n\ndef transformer_block(\n    hidden_size: int,\n    num_heads: int,\n    mlp_ratio: float = 4.0,\n    dropout: float = 0.0,\n):\n    return L.call(TransformerBlock)(\n        hidden_size=hidden_size,\n        num_heads=num_heads,\n        mlp_ratio=mlp_ratio,\n        dropout=dropout,\n    )\n",[226,2306,2307,2321,2331,2335,2361,2365,2369,2386,2394,2401,2412,2423,2440,2456,2461,2471,2496,2516,2546,2550,2573,2594,2613,2634,2646,2661,2681,2695,2699,2703,2719,2738,2781,2796,2824,2828,2832,2841,2852,2863,2878,2893,2897,2913,2923,2934,2945,2955],{"__ignoreMap":345},[349,2308,2309,2311,2313,2315,2317,2319],{"class":351,"line":352},[349,2310,356],{"class":355},[349,2312,360],{"class":359},[349,2314,229],{"class":363},[349,2316,198],{"class":366},[349,2318,369],{"class":355},[349,2320,372],{"class":359},[349,2322,2323,2325,2327,2329],{"class":351,"line":375},[349,2324,378],{"class":355},[349,2326,381],{"class":359},[349,2328,356],{"class":355},[349,2330,386],{"class":359},[349,2332,2333],{"class":351,"line":389},[349,2334,393],{"emptyLinePlaceholder":392},[349,2336,2337,2339,2341,2343,2345,2348,2350,2352,2354,2357,2359],{"class":351,"line":396},[349,2338,278],{"class":399},[349,2340,403],{"class":402},[349,2342,406],{"class":363},[349,2344,410],{"class":409},[349,2346,2347],{"class":413},"transformer_block",[349,2349,410],{"class":409},[349,2351,418],{"class":363},[349,2353,421],{"class":409},[349,2355,2356],{"class":413},"TransformerBlock",[349,2358,410],{"class":409},[349,2360,444],{"class":363},[349,2362,2363],{"class":351,"line":447},[349,2364,393],{"emptyLinePlaceholder":392},[349,2366,2367],{"class":351,"line":452},[349,2368,393],{"emptyLinePlaceholder":392},[349,2370,2371,2373,2376,2378,2380,2382,2384],{"class":351,"line":457},[349,2372,461],{"class":460},[349,2374,2375],{"class":464}," TransformerBlock",[349,2377,468],{"class":363},[349,2379,471],{"class":464},[349,2381,229],{"class":363},[349,2383,476],{"class":464},[349,2385,479],{"class":363},[349,2387,2388,2390,2392],{"class":351,"line":482},[349,2389,509],{"class":460},[349,2391,513],{"class":512},[349,2393,594],{"class":363},[349,2395,2396,2398],{"class":351,"line":501},[349,2397,575],{"class":518},[349,2399,2400],{"class":363},",\n",[349,2402,2403,2406,2408,2410],{"class":351,"line":506},[349,2404,2405],{"class":524},"        hidden_size",[349,2407,488],{"class":363},[349,2409,492],{"class":491},[349,2411,2400],{"class":363},[349,2413,2414,2417,2419,2421],{"class":351,"line":557},[349,2415,2416],{"class":524},"        num_heads",[349,2418,488],{"class":363},[349,2420,492],{"class":491},[349,2422,2400],{"class":363},[349,2424,2425,2428,2430,2433,2435,2438],{"class":351,"line":572},[349,2426,2427],{"class":524},"        mlp_ratio",[349,2429,488],{"class":363},[349,2431,2432],{"class":491}," float",[349,2434,403],{"class":402},[349,2436,2437],{"class":497}," 4.0",[349,2439,2400],{"class":363},[349,2441,2442,2445,2447,2449,2451,2454],{"class":351,"line":597},[349,2443,2444],{"class":524},"        dropout",[349,2446,488],{"class":363},[349,2448,2432],{"class":491},[349,2450,403],{"class":402},[349,2452,2453],{"class":497}," 0.0",[349,2455,2400],{"class":363},[349,2457,2458],{"class":351,"line":644},[349,2459,2460],{"class":363},"    ):\n",[349,2462,2463,2465,2467,2469],{"class":351,"line":650},[349,2464,560],{"class":491},[349,2466,563],{"class":363},[349,2468,566],{"class":512},[349,2470,569],{"class":363},[349,2472,2473,2475,2477,2480,2482,2484,2486,2489,2491,2494],{"class":351,"line":677},[349,2474,575],{"class":399},[349,2476,229],{"class":363},[349,2478,2479],{"class":366},"norm1",[349,2481,403],{"class":402},[349,2483,585],{"class":359},[349,2485,229],{"class":363},[349,2487,2488],{"class":590},"LayerNorm",[349,2490,468],{"class":363},[349,2492,2493],{"class":590},"hidden_size",[349,2495,674],{"class":363},[349,2497,2498,2500,2502,2505,2507,2509,2511,2514],{"class":351,"line":726},[349,2499,575],{"class":399},[349,2501,229],{"class":363},[349,2503,2504],{"class":366},"attn",[349,2506,403],{"class":402},[349,2508,585],{"class":359},[349,2510,229],{"class":363},[349,2512,2513],{"class":590},"MultiheadAttention",[349,2515,594],{"class":363},[349,2517,2518,2521,2523,2526,2528,2531,2533,2536,2538,2541,2543],{"class":351,"line":750},[349,2519,2520],{"class":590},"            hidden_size",[349,2522,418],{"class":363},[349,2524,2525],{"class":590}," num_heads",[349,2527,418],{"class":363},[349,2529,2530],{"class":614}," dropout",[349,2532,617],{"class":402},[349,2534,2535],{"class":590},"dropout",[349,2537,418],{"class":363},[349,2539,2540],{"class":614}," batch_first",[349,2542,617],{"class":402},[349,2544,2545],{"class":640},"True\n",[349,2547,2548],{"class":351,"line":781},[349,2549,647],{"class":363},[349,2551,2552,2554,2556,2559,2561,2563,2565,2567,2569,2571],{"class":351,"line":808},[349,2553,575],{"class":399},[349,2555,229],{"class":363},[349,2557,2558],{"class":366},"norm2",[349,2560,403],{"class":402},[349,2562,585],{"class":359},[349,2564,229],{"class":363},[349,2566,2488],{"class":590},[349,2568,468],{"class":363},[349,2570,2493],{"class":590},[349,2572,674],{"class":363},[349,2574,2575,2578,2580,2582,2584,2587,2589,2592],{"class":351,"line":830},[349,2576,2577],{"class":359},"        intermediate ",[349,2579,617],{"class":402},[349,2581,492],{"class":491},[349,2583,468],{"class":363},[349,2585,2586],{"class":590},"hidden_size ",[349,2588,1169],{"class":402},[349,2590,2591],{"class":590}," mlp_ratio",[349,2593,674],{"class":363},[349,2595,2596,2598,2600,2603,2605,2607,2609,2611],{"class":351,"line":872},[349,2597,575],{"class":399},[349,2599,229],{"class":363},[349,2601,2602],{"class":366},"mlp",[349,2604,403],{"class":402},[349,2606,585],{"class":359},[349,2608,229],{"class":363},[349,2610,825],{"class":590},[349,2612,594],{"class":363},[349,2614,2615,2618,2620,2623,2625,2627,2629,2632],{"class":351,"line":887},[349,2616,2617],{"class":590},"            nn",[349,2619,229],{"class":363},[349,2621,2622],{"class":590},"Linear",[349,2624,468],{"class":363},[349,2626,2493],{"class":590},[349,2628,418],{"class":363},[349,2630,2631],{"class":590}," intermediate",[349,2633,869],{"class":363},[349,2635,2636,2638,2640,2643],{"class":351,"line":893},[349,2637,2617],{"class":590},[349,2639,229],{"class":363},[349,2641,2642],{"class":590},"GELU",[349,2644,2645],{"class":363},"(),\n",[349,2647,2648,2650,2652,2655,2657,2659],{"class":351,"line":901},[349,2649,2617],{"class":590},[349,2651,229],{"class":363},[349,2653,2654],{"class":590},"Dropout",[349,2656,468],{"class":363},[349,2658,2535],{"class":590},[349,2660,869],{"class":363},[349,2662,2663,2665,2667,2669,2671,2674,2676,2679],{"class":351,"line":921},[349,2664,2617],{"class":590},[349,2666,229],{"class":363},[349,2668,2622],{"class":590},[349,2670,468],{"class":363},[349,2672,2673],{"class":590},"intermediate",[349,2675,418],{"class":363},[349,2677,2678],{"class":590}," hidden_size",[349,2680,869],{"class":363},[349,2682,2683,2685,2687,2689,2691,2693],{"class":351,"line":926},[349,2684,2617],{"class":590},[349,2686,229],{"class":363},[349,2688,2654],{"class":590},[349,2690,468],{"class":363},[349,2692,2535],{"class":590},[349,2694,869],{"class":363},[349,2696,2697],{"class":351,"line":946},[349,2698,647],{"class":363},[349,2700,2701],{"class":351,"line":968},[349,2702,393],{"emptyLinePlaceholder":392},[349,2704,2705,2707,2709,2711,2713,2715,2717],{"class":351,"line":1005},[349,2706,509],{"class":460},[349,2708,932],{"class":931},[349,2710,468],{"class":363},[349,2712,519],{"class":518},[349,2714,418],{"class":363},[349,2716,941],{"class":524},[349,2718,479],{"class":363},[349,2720,2721,2724,2726,2728,2730,2732,2734,2736],{"class":351,"line":1034},[349,2722,2723],{"class":359},"        h ",[349,2725,617],{"class":402},[349,2727,954],{"class":399},[349,2729,229],{"class":363},[349,2731,2479],{"class":590},[349,2733,468],{"class":363},[349,2735,963],{"class":590},[349,2737,674],{"class":363},[349,2739,2740,2743,2745,2748,2750,2752,2754,2756,2758,2761,2763,2766,2768,2770,2772,2775,2777,2779],{"class":351,"line":1059},[349,2741,2742],{"class":359},"        attn_out",[349,2744,418],{"class":363},[349,2746,2747],{"class":359}," _ ",[349,2749,617],{"class":402},[349,2751,954],{"class":399},[349,2753,229],{"class":363},[349,2755,2504],{"class":590},[349,2757,468],{"class":363},[349,2759,2760],{"class":590},"h",[349,2762,418],{"class":363},[349,2764,2765],{"class":590}," h",[349,2767,418],{"class":363},[349,2769,2765],{"class":590},[349,2771,418],{"class":363},[349,2773,2774],{"class":614}," need_weights",[349,2776,617],{"class":402},[349,2778,721],{"class":640},[349,2780,674],{"class":363},[349,2782,2783,2786,2788,2791,2793],{"class":351,"line":1064},[349,2784,2785],{"class":359},"        x ",[349,2787,617],{"class":402},[349,2789,2790],{"class":359}," x ",[349,2792,1051],{"class":402},[349,2794,2795],{"class":359}," attn_out\n",[349,2797,2798,2800,2802,2804,2806,2808,2810,2812,2814,2816,2818,2820,2822],{"class":351,"line":1069},[349,2799,1037],{"class":355},[349,2801,2790],{"class":359},[349,2803,1051],{"class":402},[349,2805,954],{"class":399},[349,2807,229],{"class":363},[349,2809,2602],{"class":590},[349,2811,468],{"class":363},[349,2813,519],{"class":399},[349,2815,229],{"class":363},[349,2817,2558],{"class":590},[349,2819,468],{"class":363},[349,2821,963],{"class":590},[349,2823,1031],{"class":363},[349,2825,2826],{"class":351,"line":1087},[349,2827,393],{"emptyLinePlaceholder":392},[349,2829,2830],{"class":351,"line":1101},[349,2831,393],{"emptyLinePlaceholder":392},[349,2833,2834,2836,2839],{"class":351,"line":1106},[349,2835,1723],{"class":460},[349,2837,2838],{"class":931}," transformer_block",[349,2840,594],{"class":363},[349,2842,2843,2846,2848,2850],{"class":351,"line":1147},[349,2844,2845],{"class":524},"    hidden_size",[349,2847,488],{"class":363},[349,2849,492],{"class":491},[349,2851,2400],{"class":363},[349,2853,2854,2857,2859,2861],{"class":351,"line":1158},[349,2855,2856],{"class":524},"    num_heads",[349,2858,488],{"class":363},[349,2860,492],{"class":491},[349,2862,2400],{"class":363},[349,2864,2865,2868,2870,2872,2874,2876],{"class":351,"line":1179},[349,2866,2867],{"class":524},"    mlp_ratio",[349,2869,488],{"class":363},[349,2871,2432],{"class":491},[349,2873,403],{"class":402},[349,2875,2437],{"class":497},[349,2877,2400],{"class":363},[349,2879,2880,2883,2885,2887,2889,2891],{"class":351,"line":1218},[349,2881,2882],{"class":524},"    dropout",[349,2884,488],{"class":363},[349,2886,2432],{"class":491},[349,2888,403],{"class":402},[349,2890,2453],{"class":497},[349,2892,2400],{"class":363},[349,2894,2895],{"class":351,"line":1241},[349,2896,479],{"class":363},[349,2898,2899,2901,2903,2905,2907,2909,2911],{"class":351,"line":1260},[349,2900,1762],{"class":355},[349,2902,1765],{"class":359},[349,2904,229],{"class":363},[349,2906,1770],{"class":590},[349,2908,468],{"class":363},[349,2910,2356],{"class":590},[349,2912,1777],{"class":363},[349,2914,2915,2917,2919,2921],{"class":351,"line":1298},[349,2916,2405],{"class":614},[349,2918,617],{"class":402},[349,2920,2493],{"class":590},[349,2922,2400],{"class":363},[349,2924,2925,2927,2929,2932],{"class":351,"line":1303},[349,2926,2416],{"class":614},[349,2928,617],{"class":402},[349,2930,2931],{"class":590},"num_heads",[349,2933,2400],{"class":363},[349,2935,2936,2938,2940,2943],{"class":351,"line":1326},[349,2937,2427],{"class":614},[349,2939,617],{"class":402},[349,2941,2942],{"class":590},"mlp_ratio",[349,2944,2400],{"class":363},[349,2946,2947,2949,2951,2953],{"class":351,"line":1367},[349,2948,2444],{"class":614},[349,2950,617],{"class":402},[349,2952,2535],{"class":590},[349,2954,2400],{"class":363},[349,2956,2957],{"class":351,"line":1392},[349,2958,1810],{"class":363},[335,2960,1909],{"id":2961},"annotated-walkthrough-1",[219,2963,2964,2967,2969,2970,2974,2975,2978],{},[248,2965,2966],{},"Pre-norm structure",[226,2968,2488],{}," is applied ",[2971,2972,2973],"em",{},"before"," attention and MLP (pre-norm), not after (post-norm). This is the ViT\u002FDINOv3 convention. The ",[226,2976,2977],{},"forward"," method is standard PyTorch; laco is not involved.",[219,2980,2981,2986,2989,2990,2992,2993,1916,2995,2997],{},[248,2982,2983,2985],{},[226,2984,2942],{},": derived dimension",[226,2987,2988],{},"intermediate = int(hidden_size * mlp_ratio)"," is computed in ",[226,2991,566],{},", not stored in the config. The config stores only ",[226,2994,2493],{},[226,2996,2942],{},"; the derived integer is an implementation detail.",[219,2999,3000,3006,3007,3009,3010,3013,3014,229],{},[248,3001,3002,3003],{},"Full self-attention with ",[226,3004,3005],{},"nn.MultiheadAttention","\nUses standard ",[226,3008,3005],{}," with ",[226,3011,3012],{},"batch_first=True"," (sequences first dimension). No RoPE or GQA; for LLM-style attention see ",[226,3015,3016],{},"blocks\u002Fdecoder.py",[219,3018,3019,3024,3025,3028],{},[248,3020,3021,1951],{},[226,3022,3023],{},"transformer_block(...)","\nFour arguments map directly to ",[226,3026,3027],{},"TransformerBlock.__init__",". The factory has default values matching the class, so callers only need to specify the required arguments.",[335,3030,1981],{"id":3031},"composing-into-a-larger-config-1",[340,3033,3035],{"className":342,"code":3034,"language":344,"meta":345,"style":345},"from laco.examples.blocks.transformer import transformer_block\nimport laco.language as L\nfrom torch import nn\n\n# 12-layer ViT encoder\nencoder = L.call(nn.Sequential, expand_args=True)(\n    L.repeat(\n        12,\n        transformer_block(hidden_size=768, num_heads=12, mlp_ratio=4.0, dropout=0.1),\n    )\n)\n",[226,3036,3037,3061,3075,3085,3089,3094,3125,3135,3142,3185,3189],{"__ignoreMap":345},[349,3038,3039,3041,3043,3045,3047,3049,3051,3053,3056,3058],{"class":351,"line":352},[349,3040,378],{"class":355},[349,3042,360],{"class":359},[349,3044,229],{"class":363},[349,3046,1997],{"class":359},[349,3048,229],{"class":363},[349,3050,2002],{"class":359},[349,3052,229],{"class":363},[349,3054,3055],{"class":359},"transformer ",[349,3057,356],{"class":355},[349,3059,3060],{"class":359}," transformer_block\n",[349,3062,3063,3065,3067,3069,3071,3073],{"class":351,"line":375},[349,3064,356],{"class":355},[349,3066,360],{"class":359},[349,3068,229],{"class":363},[349,3070,198],{"class":366},[349,3072,369],{"class":355},[349,3074,372],{"class":359},[349,3076,3077,3079,3081,3083],{"class":351,"line":389},[349,3078,378],{"class":355},[349,3080,381],{"class":359},[349,3082,356],{"class":355},[349,3084,386],{"class":359},[349,3086,3087],{"class":351,"line":396},[349,3088,393],{"emptyLinePlaceholder":392},[349,3090,3091],{"class":351,"line":447},[349,3092,3093],{"class":1716},"# 12-layer ViT encoder\n",[349,3095,3096,3099,3101,3103,3105,3107,3109,3111,3113,3115,3117,3119,3121,3123],{"class":351,"line":452},[349,3097,3098],{"class":359},"encoder ",[349,3100,617],{"class":402},[349,3102,1765],{"class":359},[349,3104,229],{"class":363},[349,3106,1770],{"class":590},[349,3108,468],{"class":363},[349,3110,471],{"class":590},[349,3112,229],{"class":363},[349,3114,825],{"class":366},[349,3116,418],{"class":363},[349,3118,2071],{"class":614},[349,3120,617],{"class":402},[349,3122,776],{"class":640},[349,3124,1777],{"class":363},[349,3126,3127,3129,3131,3133],{"class":351,"line":457},[349,3128,2082],{"class":590},[349,3130,229],{"class":363},[349,3132,2087],{"class":590},[349,3134,594],{"class":363},[349,3136,3137,3140],{"class":351,"line":482},[349,3138,3139],{"class":497},"        12",[349,3141,2400],{"class":363},[349,3143,3144,3147,3149,3151,3153,3156,3158,3160,3162,3165,3167,3169,3171,3174,3176,3178,3180,3183],{"class":351,"line":501},[349,3145,3146],{"class":590},"        transformer_block",[349,3148,468],{"class":363},[349,3150,2493],{"class":614},[349,3152,617],{"class":402},[349,3154,3155],{"class":497},"768",[349,3157,418],{"class":363},[349,3159,2525],{"class":614},[349,3161,617],{"class":402},[349,3163,3164],{"class":497},"12",[349,3166,418],{"class":363},[349,3168,2591],{"class":614},[349,3170,617],{"class":402},[349,3172,3173],{"class":497},"4.0",[349,3175,418],{"class":363},[349,3177,2530],{"class":614},[349,3179,617],{"class":402},[349,3181,3182],{"class":497},"0.1",[349,3184,869],{"class":363},[349,3186,3187],{"class":351,"line":506},[349,3188,1810],{"class":363},[349,3190,3191],{"class":351,"line":557},[349,3192,674],{"class":363},[335,3194,2243],{"id":3195},"what-this-demonstrates-1",[2245,3197,3198,3201,3210,3216],{},[245,3199,3200],{},"Attention + FFN composition expressed as a single config factory",[245,3202,3203,3204,3206,3207,3209],{},"Derived dimensions (",[226,3205,2673],{},") computed in ",[226,3208,566],{},", not in the config",[245,3211,3212,3213],{},"Pre-norm convention with ",[226,3214,3215],{},"nn.LayerNorm",[245,3217,3218,3220],{},[226,3219,1962],{}," for stacked encoder blocks in downstream configs",[231,3222],{},[234,3224,3226,3227,3229],{"id":3225},"_3-blocksdecoderpy-autoregressive-llm-decoder-block","3. ",[226,3228,3016],{},": Autoregressive LLM decoder block",[216,3231,3232],{},[219,3233,305,3234],{},[307,3235,3237],{"href":3236},"..\u002F..\u002Fsources\u002Flaco\u002Fexamples\u002Fblocks\u002Fdecoder.py",[226,3238,3239],{},"sources\u002Flaco\u002Fexamples\u002Fblocks\u002Fdecoder.py",[219,3241,3242,3243,3246,3247,1916,3250,229],{},"LLM-style pre-norm decoder block: ",[226,3244,3245],{},"RMSNorm → GroupedQueryAttention (causal, RoPE) → residual → RMSNorm → SwiGLU → residual",". Used by ",[226,3248,3249],{},"laco.examples.models.qwen3",[226,3251,3252],{},"laco.examples.models.gemma3",[335,3254,338],{"id":3255},"key-source-patterns-2",[340,3257,3259],{"className":342,"code":3258,"language":344,"meta":345,"style":345},"import laco.language as L\nfrom laco.examples.layers.gqa_attention import GroupedQueryAttention\nfrom laco.examples.layers.rms_norm import RMSNorm\nfrom laco.examples.layers.swiglu import SwiGLU\nfrom torch import nn\n\n__all__ = [\"decoder_block\", \"DecoderBlock\"]\n\n\nclass DecoderBlock(nn.Module):\n    def __init__(\n        self,\n        hidden_size: int,\n        num_heads: int,\n        num_kv_heads: int,\n        intermediate_size: int,\n        rms_norm_eps: float = 1e-6,\n        rope_base: float = 10_000.0,\n        sliding_window: int | None = None,\n    ):\n        super().__init__()\n        self.input_layernorm = RMSNorm(hidden_size, eps=rms_norm_eps)\n        self.self_attn = GroupedQueryAttention(\n            hidden_size=hidden_size,\n            num_heads=num_heads,\n            num_kv_heads=num_kv_heads,\n            causal=True,\n            use_rope=True,\n            rope_base=rope_base,\n            sliding_window=sliding_window,\n        )\n        self.post_attention_layernorm = RMSNorm(hidden_size, eps=rms_norm_eps)\n        self.mlp = SwiGLU(hidden_size, intermediate_size)\n\n    def forward(self, x):\n        x = x + self.self_attn(self.input_layernorm(x))\n        return x + self.mlp(self.post_attention_layernorm(x))\n\n\ndef decoder_block(\n    hidden_size: int,\n    num_heads: int,\n    num_kv_heads: int,\n    intermediate_size: int,\n    rms_norm_eps: float = 1e-6,\n    rope_base: float = 10_000.0,\n    sliding_window: int | None = None,\n):\n    return L.call(DecoderBlock)(\n        hidden_size=hidden_size,\n        num_heads=num_heads,\n        num_kv_heads=num_kv_heads,\n        intermediate_size=intermediate_size,\n        rms_norm_eps=rms_norm_eps,\n        rope_base=rope_base,\n        sliding_window=sliding_window,\n    )\n",[226,3260,3261,3275,3300,3324,3348,3358,3362,3388,3392,3396,3413,3421,3427,3437,3447,3458,3469,3485,3501,3522,3526,3536,3566,3582,3592,3603,3615,3626,3637,3649,3661,3665,3692,3716,3720,3736,3766,3794,3798,3802,3811,3821,3831,3842,3853,3868,3883,3902,3906,3922,3932,3942,3952,3963,3973,3983,3993],{"__ignoreMap":345},[349,3262,3263,3265,3267,3269,3271,3273],{"class":351,"line":352},[349,3264,356],{"class":355},[349,3266,360],{"class":359},[349,3268,229],{"class":363},[349,3270,198],{"class":366},[349,3272,369],{"class":355},[349,3274,372],{"class":359},[349,3276,3277,3279,3281,3283,3285,3287,3290,3292,3295,3297],{"class":351,"line":375},[349,3278,378],{"class":355},[349,3280,360],{"class":359},[349,3282,229],{"class":363},[349,3284,1997],{"class":359},[349,3286,229],{"class":363},[349,3288,3289],{"class":359},"layers",[349,3291,229],{"class":363},[349,3293,3294],{"class":359},"gqa_attention ",[349,3296,356],{"class":355},[349,3298,3299],{"class":359}," GroupedQueryAttention\n",[349,3301,3302,3304,3306,3308,3310,3312,3314,3316,3319,3321],{"class":351,"line":389},[349,3303,378],{"class":355},[349,3305,360],{"class":359},[349,3307,229],{"class":363},[349,3309,1997],{"class":359},[349,3311,229],{"class":363},[349,3313,3289],{"class":359},[349,3315,229],{"class":363},[349,3317,3318],{"class":359},"rms_norm ",[349,3320,356],{"class":355},[349,3322,3323],{"class":359}," RMSNorm\n",[349,3325,3326,3328,3330,3332,3334,3336,3338,3340,3343,3345],{"class":351,"line":396},[349,3327,378],{"class":355},[349,3329,360],{"class":359},[349,3331,229],{"class":363},[349,3333,1997],{"class":359},[349,3335,229],{"class":363},[349,3337,3289],{"class":359},[349,3339,229],{"class":363},[349,3341,3342],{"class":359},"swiglu ",[349,3344,356],{"class":355},[349,3346,3347],{"class":359}," SwiGLU\n",[349,3349,3350,3352,3354,3356],{"class":351,"line":447},[349,3351,378],{"class":355},[349,3353,381],{"class":359},[349,3355,356],{"class":355},[349,3357,386],{"class":359},[349,3359,3360],{"class":351,"line":452},[349,3361,393],{"emptyLinePlaceholder":392},[349,3363,3364,3366,3368,3370,3372,3375,3377,3379,3381,3384,3386],{"class":351,"line":457},[349,3365,278],{"class":399},[349,3367,403],{"class":402},[349,3369,406],{"class":363},[349,3371,410],{"class":409},[349,3373,3374],{"class":413},"decoder_block",[349,3376,410],{"class":409},[349,3378,418],{"class":363},[349,3380,421],{"class":409},[349,3382,3383],{"class":413},"DecoderBlock",[349,3385,410],{"class":409},[349,3387,444],{"class":363},[349,3389,3390],{"class":351,"line":482},[349,3391,393],{"emptyLinePlaceholder":392},[349,3393,3394],{"class":351,"line":501},[349,3395,393],{"emptyLinePlaceholder":392},[349,3397,3398,3400,3403,3405,3407,3409,3411],{"class":351,"line":506},[349,3399,461],{"class":460},[349,3401,3402],{"class":464}," DecoderBlock",[349,3404,468],{"class":363},[349,3406,471],{"class":464},[349,3408,229],{"class":363},[349,3410,476],{"class":464},[349,3412,479],{"class":363},[349,3414,3415,3417,3419],{"class":351,"line":557},[349,3416,509],{"class":460},[349,3418,513],{"class":512},[349,3420,594],{"class":363},[349,3422,3423,3425],{"class":351,"line":572},[349,3424,575],{"class":518},[349,3426,2400],{"class":363},[349,3428,3429,3431,3433,3435],{"class":351,"line":597},[349,3430,2405],{"class":524},[349,3432,488],{"class":363},[349,3434,492],{"class":491},[349,3436,2400],{"class":363},[349,3438,3439,3441,3443,3445],{"class":351,"line":644},[349,3440,2416],{"class":524},[349,3442,488],{"class":363},[349,3444,492],{"class":491},[349,3446,2400],{"class":363},[349,3448,3449,3452,3454,3456],{"class":351,"line":650},[349,3450,3451],{"class":524},"        num_kv_heads",[349,3453,488],{"class":363},[349,3455,492],{"class":491},[349,3457,2400],{"class":363},[349,3459,3460,3463,3465,3467],{"class":351,"line":677},[349,3461,3462],{"class":524},"        intermediate_size",[349,3464,488],{"class":363},[349,3466,492],{"class":491},[349,3468,2400],{"class":363},[349,3470,3471,3474,3476,3478,3480,3483],{"class":351,"line":726},[349,3472,3473],{"class":524},"        rms_norm_eps",[349,3475,488],{"class":363},[349,3477,2432],{"class":491},[349,3479,403],{"class":402},[349,3481,3482],{"class":497}," 1e-6",[349,3484,2400],{"class":363},[349,3486,3487,3490,3492,3494,3496,3499],{"class":351,"line":750},[349,3488,3489],{"class":524},"        rope_base",[349,3491,488],{"class":363},[349,3493,2432],{"class":491},[349,3495,403],{"class":402},[349,3497,3498],{"class":497}," 10_000.0",[349,3500,2400],{"class":363},[349,3502,3503,3506,3508,3510,3513,3516,3518,3520],{"class":351,"line":781},[349,3504,3505],{"class":524},"        sliding_window",[349,3507,488],{"class":363},[349,3509,492],{"class":491},[349,3511,3512],{"class":402}," |",[349,3514,3515],{"class":640}," None",[349,3517,403],{"class":402},[349,3519,3515],{"class":640},[349,3521,2400],{"class":363},[349,3523,3524],{"class":351,"line":808},[349,3525,2460],{"class":363},[349,3527,3528,3530,3532,3534],{"class":351,"line":830},[349,3529,560],{"class":491},[349,3531,563],{"class":363},[349,3533,566],{"class":512},[349,3535,569],{"class":363},[349,3537,3538,3540,3542,3545,3547,3550,3552,3554,3556,3559,3561,3564],{"class":351,"line":872},[349,3539,575],{"class":399},[349,3541,229],{"class":363},[349,3543,3544],{"class":366},"input_layernorm",[349,3546,403],{"class":402},[349,3548,3549],{"class":590}," RMSNorm",[349,3551,468],{"class":363},[349,3553,2493],{"class":590},[349,3555,418],{"class":363},[349,3557,3558],{"class":614}," eps",[349,3560,617],{"class":402},[349,3562,3563],{"class":590},"rms_norm_eps",[349,3565,674],{"class":363},[349,3567,3568,3570,3572,3575,3577,3580],{"class":351,"line":887},[349,3569,575],{"class":399},[349,3571,229],{"class":363},[349,3573,3574],{"class":366},"self_attn",[349,3576,403],{"class":402},[349,3578,3579],{"class":590}," GroupedQueryAttention",[349,3581,594],{"class":363},[349,3583,3584,3586,3588,3590],{"class":351,"line":893},[349,3585,2520],{"class":614},[349,3587,617],{"class":402},[349,3589,2493],{"class":590},[349,3591,2400],{"class":363},[349,3593,3594,3597,3599,3601],{"class":351,"line":901},[349,3595,3596],{"class":614},"            num_heads",[349,3598,617],{"class":402},[349,3600,2931],{"class":590},[349,3602,2400],{"class":363},[349,3604,3605,3608,3610,3613],{"class":351,"line":921},[349,3606,3607],{"class":614},"            num_kv_heads",[349,3609,617],{"class":402},[349,3611,3612],{"class":590},"num_kv_heads",[349,3614,2400],{"class":363},[349,3616,3617,3620,3622,3624],{"class":351,"line":926},[349,3618,3619],{"class":614},"            causal",[349,3621,617],{"class":402},[349,3623,776],{"class":640},[349,3625,2400],{"class":363},[349,3627,3628,3631,3633,3635],{"class":351,"line":946},[349,3629,3630],{"class":614},"            use_rope",[349,3632,617],{"class":402},[349,3634,776],{"class":640},[349,3636,2400],{"class":363},[349,3638,3639,3642,3644,3647],{"class":351,"line":968},[349,3640,3641],{"class":614},"            rope_base",[349,3643,617],{"class":402},[349,3645,3646],{"class":590},"rope_base",[349,3648,2400],{"class":363},[349,3650,3651,3654,3656,3659],{"class":351,"line":1005},[349,3652,3653],{"class":614},"            sliding_window",[349,3655,617],{"class":402},[349,3657,3658],{"class":590},"sliding_window",[349,3660,2400],{"class":363},[349,3662,3663],{"class":351,"line":1034},[349,3664,647],{"class":363},[349,3666,3667,3669,3671,3674,3676,3678,3680,3682,3684,3686,3688,3690],{"class":351,"line":1059},[349,3668,575],{"class":399},[349,3670,229],{"class":363},[349,3672,3673],{"class":366},"post_attention_layernorm",[349,3675,403],{"class":402},[349,3677,3549],{"class":590},[349,3679,468],{"class":363},[349,3681,2493],{"class":590},[349,3683,418],{"class":363},[349,3685,3558],{"class":614},[349,3687,617],{"class":402},[349,3689,3563],{"class":590},[349,3691,674],{"class":363},[349,3693,3694,3696,3698,3700,3702,3705,3707,3709,3711,3714],{"class":351,"line":1064},[349,3695,575],{"class":399},[349,3697,229],{"class":363},[349,3699,2602],{"class":366},[349,3701,403],{"class":402},[349,3703,3704],{"class":590}," SwiGLU",[349,3706,468],{"class":363},[349,3708,2493],{"class":590},[349,3710,418],{"class":363},[349,3712,3713],{"class":590}," intermediate_size",[349,3715,674],{"class":363},[349,3717,3718],{"class":351,"line":1069},[349,3719,393],{"emptyLinePlaceholder":392},[349,3721,3722,3724,3726,3728,3730,3732,3734],{"class":351,"line":1087},[349,3723,509],{"class":460},[349,3725,932],{"class":931},[349,3727,468],{"class":363},[349,3729,519],{"class":518},[349,3731,418],{"class":363},[349,3733,941],{"class":524},[349,3735,479],{"class":363},[349,3737,3738,3740,3742,3744,3746,3748,3750,3752,3754,3756,3758,3760,3762,3764],{"class":351,"line":1101},[349,3739,2785],{"class":359},[349,3741,617],{"class":402},[349,3743,2790],{"class":359},[349,3745,1051],{"class":402},[349,3747,954],{"class":399},[349,3749,229],{"class":363},[349,3751,3574],{"class":590},[349,3753,468],{"class":363},[349,3755,519],{"class":399},[349,3757,229],{"class":363},[349,3759,3544],{"class":590},[349,3761,468],{"class":363},[349,3763,963],{"class":590},[349,3765,1031],{"class":363},[349,3767,3768,3770,3772,3774,3776,3778,3780,3782,3784,3786,3788,3790,3792],{"class":351,"line":1106},[349,3769,1037],{"class":355},[349,3771,2790],{"class":359},[349,3773,1051],{"class":402},[349,3775,954],{"class":399},[349,3777,229],{"class":363},[349,3779,2602],{"class":590},[349,3781,468],{"class":363},[349,3783,519],{"class":399},[349,3785,229],{"class":363},[349,3787,3673],{"class":590},[349,3789,468],{"class":363},[349,3791,963],{"class":590},[349,3793,1031],{"class":363},[349,3795,3796],{"class":351,"line":1147},[349,3797,393],{"emptyLinePlaceholder":392},[349,3799,3800],{"class":351,"line":1158},[349,3801,393],{"emptyLinePlaceholder":392},[349,3803,3804,3806,3809],{"class":351,"line":1179},[349,3805,1723],{"class":460},[349,3807,3808],{"class":931}," decoder_block",[349,3810,594],{"class":363},[349,3812,3813,3815,3817,3819],{"class":351,"line":1218},[349,3814,2845],{"class":524},[349,3816,488],{"class":363},[349,3818,492],{"class":491},[349,3820,2400],{"class":363},[349,3822,3823,3825,3827,3829],{"class":351,"line":1241},[349,3824,2856],{"class":524},[349,3826,488],{"class":363},[349,3828,492],{"class":491},[349,3830,2400],{"class":363},[349,3832,3833,3836,3838,3840],{"class":351,"line":1260},[349,3834,3835],{"class":524},"    num_kv_heads",[349,3837,488],{"class":363},[349,3839,492],{"class":491},[349,3841,2400],{"class":363},[349,3843,3844,3847,3849,3851],{"class":351,"line":1298},[349,3845,3846],{"class":524},"    intermediate_size",[349,3848,488],{"class":363},[349,3850,492],{"class":491},[349,3852,2400],{"class":363},[349,3854,3855,3858,3860,3862,3864,3866],{"class":351,"line":1303},[349,3856,3857],{"class":524},"    rms_norm_eps",[349,3859,488],{"class":363},[349,3861,2432],{"class":491},[349,3863,403],{"class":402},[349,3865,3482],{"class":497},[349,3867,2400],{"class":363},[349,3869,3870,3873,3875,3877,3879,3881],{"class":351,"line":1326},[349,3871,3872],{"class":524},"    rope_base",[349,3874,488],{"class":363},[349,3876,2432],{"class":491},[349,3878,403],{"class":402},[349,3880,3498],{"class":497},[349,3882,2400],{"class":363},[349,3884,3885,3888,3890,3892,3894,3896,3898,3900],{"class":351,"line":1367},[349,3886,3887],{"class":524},"    sliding_window",[349,3889,488],{"class":363},[349,3891,492],{"class":491},[349,3893,3512],{"class":402},[349,3895,3515],{"class":640},[349,3897,403],{"class":402},[349,3899,3515],{"class":640},[349,3901,2400],{"class":363},[349,3903,3904],{"class":351,"line":1392},[349,3905,479],{"class":363},[349,3907,3908,3910,3912,3914,3916,3918,3920],{"class":351,"line":1419},[349,3909,1762],{"class":355},[349,3911,1765],{"class":359},[349,3913,229],{"class":363},[349,3915,1770],{"class":590},[349,3917,468],{"class":363},[349,3919,3383],{"class":590},[349,3921,1777],{"class":363},[349,3923,3924,3926,3928,3930],{"class":351,"line":1440},[349,3925,2405],{"class":614},[349,3927,617],{"class":402},[349,3929,2493],{"class":590},[349,3931,2400],{"class":363},[349,3933,3934,3936,3938,3940],{"class":351,"line":1459},[349,3935,2416],{"class":614},[349,3937,617],{"class":402},[349,3939,2931],{"class":590},[349,3941,2400],{"class":363},[349,3943,3944,3946,3948,3950],{"class":351,"line":1498},[349,3945,3451],{"class":614},[349,3947,617],{"class":402},[349,3949,3612],{"class":590},[349,3951,2400],{"class":363},[349,3953,3954,3956,3958,3961],{"class":351,"line":1513},[349,3955,3462],{"class":614},[349,3957,617],{"class":402},[349,3959,3960],{"class":590},"intermediate_size",[349,3962,2400],{"class":363},[349,3964,3965,3967,3969,3971],{"class":351,"line":1518},[349,3966,3473],{"class":614},[349,3968,617],{"class":402},[349,3970,3563],{"class":590},[349,3972,2400],{"class":363},[349,3974,3975,3977,3979,3981],{"class":351,"line":1525},[349,3976,3489],{"class":614},[349,3978,617],{"class":402},[349,3980,3646],{"class":590},[349,3982,2400],{"class":363},[349,3984,3985,3987,3989,3991],{"class":351,"line":1544},[349,3986,3505],{"class":614},[349,3988,617],{"class":402},[349,3990,3658],{"class":590},[349,3992,2400],{"class":363},[349,3994,3995],{"class":351,"line":1549},[349,3996,1810],{"class":363},[335,3998,1909],{"id":3999},"annotated-walkthrough-2",[219,4001,4002,4005,4008],{},[248,4003,4004],{},"GQA (Grouped-Query Attention)",[226,4006,4007],{},"num_kv_heads \u003C num_heads"," enables grouped-query attention (GQA). This reduces the KV-cache size proportionally. The ratio is stored explicitly in the config, so model-specific variants (Qwen3, Gemma3) can override it independently.",[219,4010,4011,4016,4019,4020,4023],{},[248,4012,4013],{},[226,4014,4015],{},"sliding_window: int | None",[226,4017,4018],{},"None"," → full causal attention (used by Qwen3 and Gemma3 odd-indexed layers). An integer value enables banded causal attention with that window size (used by Gemma3 even-indexed layers). Because ",[226,4021,4022],{},"L.call"," stores the value verbatim, a config override can switch this per-layer.",[219,4025,4026,4034,4035,4038,4039,4041,4042,4044],{},[248,4027,4028,1916,4031],{},[226,4029,4030],{},"RMSNorm",[226,4032,4033],{},"SwiGLU","\nCustom layer implementations from ",[226,4036,4037],{},"laco.examples.layers",". Like the ",[226,4040,3383],{}," itself, these are plain ",[226,4043,253],{}," subclasses; no laco awareness is required inside the implementation.",[335,4046,1981],{"id":4047},"composing-into-a-larger-config-2",[340,4049,4051],{"className":342,"code":4050,"language":344,"meta":345,"style":345},"from laco.examples.blocks.decoder import decoder_block\nimport laco.language as L\nfrom torch import nn\n\n# Uniform full-attention stack (Qwen3-style)\ndecoder_stack = L.call(nn.Sequential, expand_args=True)(\n    L.repeat(\n        28,\n        decoder_block(\n            hidden_size=1024,\n            num_heads=16,\n            num_kv_heads=8,\n            intermediate_size=3072,\n        ),\n    )\n)\n\n# Alternating sliding-window \u002F full-attention (Gemma3-style)\n# constructed with explicit Python iteration at config-build time\nimport laco.language as L\n\nlayers = []\nfor i in range(28):\n    window = None if i % 2 == 1 else 4096\n    layers.append(\n        decoder_block(\n            hidden_size=1024,\n            num_heads=16,\n            num_kv_heads=4,\n            intermediate_size=4096,\n            sliding_window=window,\n        )\n    )\ndecoder_stack = L.call(nn.Sequential, expand_args=True)(*layers)\n",[226,4052,4053,4077,4091,4101,4105,4110,4141,4151,4158,4165,4176,4187,4198,4210,4215,4219,4223,4227,4232,4237,4251,4255,4265,4286,4317,4329,4335,4345,4355,4365,4376,4387,4391,4395],{"__ignoreMap":345},[349,4054,4055,4057,4059,4061,4063,4065,4067,4069,4072,4074],{"class":351,"line":352},[349,4056,378],{"class":355},[349,4058,360],{"class":359},[349,4060,229],{"class":363},[349,4062,1997],{"class":359},[349,4064,229],{"class":363},[349,4066,2002],{"class":359},[349,4068,229],{"class":363},[349,4070,4071],{"class":359},"decoder ",[349,4073,356],{"class":355},[349,4075,4076],{"class":359}," decoder_block\n",[349,4078,4079,4081,4083,4085,4087,4089],{"class":351,"line":375},[349,4080,356],{"class":355},[349,4082,360],{"class":359},[349,4084,229],{"class":363},[349,4086,198],{"class":366},[349,4088,369],{"class":355},[349,4090,372],{"class":359},[349,4092,4093,4095,4097,4099],{"class":351,"line":389},[349,4094,378],{"class":355},[349,4096,381],{"class":359},[349,4098,356],{"class":355},[349,4100,386],{"class":359},[349,4102,4103],{"class":351,"line":396},[349,4104,393],{"emptyLinePlaceholder":392},[349,4106,4107],{"class":351,"line":447},[349,4108,4109],{"class":1716},"# Uniform full-attention stack (Qwen3-style)\n",[349,4111,4112,4115,4117,4119,4121,4123,4125,4127,4129,4131,4133,4135,4137,4139],{"class":351,"line":452},[349,4113,4114],{"class":359},"decoder_stack ",[349,4116,617],{"class":402},[349,4118,1765],{"class":359},[349,4120,229],{"class":363},[349,4122,1770],{"class":590},[349,4124,468],{"class":363},[349,4126,471],{"class":590},[349,4128,229],{"class":363},[349,4130,825],{"class":366},[349,4132,418],{"class":363},[349,4134,2071],{"class":614},[349,4136,617],{"class":402},[349,4138,776],{"class":640},[349,4140,1777],{"class":363},[349,4142,4143,4145,4147,4149],{"class":351,"line":457},[349,4144,2082],{"class":590},[349,4146,229],{"class":363},[349,4148,2087],{"class":590},[349,4150,594],{"class":363},[349,4152,4153,4156],{"class":351,"line":482},[349,4154,4155],{"class":497},"        28",[349,4157,2400],{"class":363},[349,4159,4160,4163],{"class":351,"line":501},[349,4161,4162],{"class":590},"        decoder_block",[349,4164,594],{"class":363},[349,4166,4167,4169,4171,4174],{"class":351,"line":506},[349,4168,2520],{"class":614},[349,4170,617],{"class":402},[349,4172,4173],{"class":497},"1024",[349,4175,2400],{"class":363},[349,4177,4178,4180,4182,4185],{"class":351,"line":557},[349,4179,3596],{"class":614},[349,4181,617],{"class":402},[349,4183,4184],{"class":497},"16",[349,4186,2400],{"class":363},[349,4188,4189,4191,4193,4196],{"class":351,"line":572},[349,4190,3607],{"class":614},[349,4192,617],{"class":402},[349,4194,4195],{"class":497},"8",[349,4197,2400],{"class":363},[349,4199,4200,4203,4205,4208],{"class":351,"line":597},[349,4201,4202],{"class":614},"            intermediate_size",[349,4204,617],{"class":402},[349,4206,4207],{"class":497},"3072",[349,4209,2400],{"class":363},[349,4211,4212],{"class":351,"line":644},[349,4213,4214],{"class":363},"        ),\n",[349,4216,4217],{"class":351,"line":650},[349,4218,1810],{"class":363},[349,4220,4221],{"class":351,"line":677},[349,4222,674],{"class":363},[349,4224,4225],{"class":351,"line":726},[349,4226,393],{"emptyLinePlaceholder":392},[349,4228,4229],{"class":351,"line":750},[349,4230,4231],{"class":1716},"# Alternating sliding-window \u002F full-attention (Gemma3-style)\n",[349,4233,4234],{"class":351,"line":781},[349,4235,4236],{"class":1716},"# constructed with explicit Python iteration at config-build time\n",[349,4238,4239,4241,4243,4245,4247,4249],{"class":351,"line":808},[349,4240,356],{"class":355},[349,4242,360],{"class":359},[349,4244,229],{"class":363},[349,4246,198],{"class":366},[349,4248,369],{"class":355},[349,4250,372],{"class":359},[349,4252,4253],{"class":351,"line":830},[349,4254,393],{"emptyLinePlaceholder":392},[349,4256,4257,4260,4262],{"class":351,"line":872},[349,4258,4259],{"class":359},"layers ",[349,4261,617],{"class":402},[349,4263,4264],{"class":363}," []\n",[349,4266,4267,4270,4273,4276,4279,4281,4284],{"class":351,"line":887},[349,4268,4269],{"class":355},"for",[349,4271,4272],{"class":359}," i ",[349,4274,4275],{"class":355},"in",[349,4277,4278],{"class":512}," range",[349,4280,468],{"class":363},[349,4282,4283],{"class":497},"28",[349,4285,479],{"class":363},[349,4287,4288,4291,4293,4295,4298,4300,4303,4306,4309,4311,4314],{"class":351,"line":893},[349,4289,4290],{"class":359},"    window ",[349,4292,617],{"class":402},[349,4294,3515],{"class":640},[349,4296,4297],{"class":355}," if",[349,4299,4272],{"class":359},[349,4301,4302],{"class":402},"%",[349,4304,4305],{"class":497}," 2",[349,4307,4308],{"class":402}," ==",[349,4310,552],{"class":497},[349,4312,4313],{"class":355}," else",[349,4315,4316],{"class":497}," 4096\n",[349,4318,4319,4322,4324,4327],{"class":351,"line":901},[349,4320,4321],{"class":359},"    layers",[349,4323,229],{"class":363},[349,4325,4326],{"class":590},"append",[349,4328,594],{"class":363},[349,4330,4331,4333],{"class":351,"line":921},[349,4332,4162],{"class":590},[349,4334,594],{"class":363},[349,4336,4337,4339,4341,4343],{"class":351,"line":926},[349,4338,2520],{"class":614},[349,4340,617],{"class":402},[349,4342,4173],{"class":497},[349,4344,2400],{"class":363},[349,4346,4347,4349,4351,4353],{"class":351,"line":946},[349,4348,3596],{"class":614},[349,4350,617],{"class":402},[349,4352,4184],{"class":497},[349,4354,2400],{"class":363},[349,4356,4357,4359,4361,4363],{"class":351,"line":968},[349,4358,3607],{"class":614},[349,4360,617],{"class":402},[349,4362,2092],{"class":497},[349,4364,2400],{"class":363},[349,4366,4367,4369,4371,4374],{"class":351,"line":1005},[349,4368,4202],{"class":614},[349,4370,617],{"class":402},[349,4372,4373],{"class":497},"4096",[349,4375,2400],{"class":363},[349,4377,4378,4380,4382,4385],{"class":351,"line":1034},[349,4379,3653],{"class":614},[349,4381,617],{"class":402},[349,4383,4384],{"class":590},"window",[349,4386,2400],{"class":363},[349,4388,4389],{"class":351,"line":1059},[349,4390,647],{"class":363},[349,4392,4393],{"class":351,"line":1064},[349,4394,1810],{"class":363},[349,4396,4397,4399,4401,4403,4405,4407,4409,4411,4413,4415,4417,4419,4421,4423,4426,4428,4430],{"class":351,"line":1069},[349,4398,4114],{"class":359},[349,4400,617],{"class":402},[349,4402,1765],{"class":359},[349,4404,229],{"class":363},[349,4406,1770],{"class":590},[349,4408,468],{"class":363},[349,4410,471],{"class":590},[349,4412,229],{"class":363},[349,4414,825],{"class":366},[349,4416,418],{"class":363},[349,4418,2071],{"class":614},[349,4420,617],{"class":402},[349,4422,776],{"class":640},[349,4424,4425],{"class":363},")(",[349,4427,1169],{"class":402},[349,4429,3289],{"class":590},[349,4431,674],{"class":363},[335,4433,2243],{"id":4434},"what-this-demonstrates-2",[2245,4436,4437,4446,4451,4462],{},[245,4438,4439,4440,4442,4443,4445],{},"GQA config with separate ",[226,4441,2931],{}," \u002F ",[226,4444,3612],{}," fields",[245,4447,4448,4450],{},[226,4449,4015],{},": optional field stored verbatim, overridable per-layer",[245,4452,4453,4454,319,4456,319,4458,4461],{},"Custom layer types (",[226,4455,4030],{},[226,4457,4033],{},[226,4459,4460],{},"GroupedQueryAttention",") as transparent config targets",[245,4463,4464],{},"Python-level iteration for heterogeneous stacks (alternating attention patterns)",[231,4466],{},[234,4468,4470],{"id":4469},"design-patterns-for-building-blocks","Design patterns for building blocks",[335,4472,4474],{"id":4473},"_1-factories-return-config-nodes-not-modules","1. Factories return config nodes, not modules",[340,4476,4478],{"className":342,"code":4477,"language":344,"meta":345,"style":345},"# Correct: returns a config node\ndef basic_block(in_channels, channels, stride=1):\n    return L.call(BasicBlock)(in_channels=in_channels, channels=channels, stride=stride)\n\n# Wrong: instantiates immediately, bypasses config system\ndef basic_block(in_channels, channels, stride=1):\n    return BasicBlock(in_channels, channels, stride)  # do not do this\n",[226,4479,4480,4485,4509,4549,4553,4558,4582],{"__ignoreMap":345},[349,4481,4482],{"class":351,"line":352},[349,4483,4484],{"class":1716},"# Correct: returns a config node\n",[349,4486,4487,4489,4491,4493,4495,4497,4499,4501,4503,4505,4507],{"class":351,"line":375},[349,4488,1723],{"class":460},[349,4490,1726],{"class":931},[349,4492,468],{"class":363},[349,4494,842],{"class":524},[349,4496,418],{"class":363},[349,4498,534],{"class":524},[349,4500,418],{"class":363},[349,4502,543],{"class":524},[349,4504,617],{"class":402},[349,4506,630],{"class":497},[349,4508,479],{"class":363},[349,4510,4511,4513,4515,4517,4519,4521,4523,4525,4527,4529,4531,4533,4535,4537,4539,4541,4543,4545,4547],{"class":351,"line":389},[349,4512,1762],{"class":355},[349,4514,1765],{"class":359},[349,4516,229],{"class":363},[349,4518,1770],{"class":590},[349,4520,468],{"class":363},[349,4522,318],{"class":590},[349,4524,4425],{"class":363},[349,4526,842],{"class":614},[349,4528,617],{"class":402},[349,4530,842],{"class":590},[349,4532,418],{"class":363},[349,4534,534],{"class":614},[349,4536,617],{"class":402},[349,4538,671],{"class":590},[349,4540,418],{"class":363},[349,4542,543],{"class":614},[349,4544,617],{"class":402},[349,4546,620],{"class":590},[349,4548,674],{"class":363},[349,4550,4551],{"class":351,"line":396},[349,4552,393],{"emptyLinePlaceholder":392},[349,4554,4555],{"class":351,"line":447},[349,4556,4557],{"class":1716},"# Wrong: instantiates immediately, bypasses config system\n",[349,4559,4560,4562,4564,4566,4568,4570,4572,4574,4576,4578,4580],{"class":351,"line":452},[349,4561,1723],{"class":460},[349,4563,1726],{"class":931},[349,4565,468],{"class":363},[349,4567,842],{"class":524},[349,4569,418],{"class":363},[349,4571,534],{"class":524},[349,4573,418],{"class":363},[349,4575,543],{"class":524},[349,4577,617],{"class":402},[349,4579,630],{"class":497},[349,4581,479],{"class":363},[349,4583,4584,4586,4588,4590,4592,4594,4596,4598,4600,4603],{"class":351,"line":457},[349,4585,1762],{"class":355},[349,4587,465],{"class":590},[349,4589,468],{"class":363},[349,4591,842],{"class":590},[349,4593,418],{"class":363},[349,4595,534],{"class":590},[349,4597,418],{"class":363},[349,4599,543],{"class":590},[349,4601,4602],{"class":363},")",[349,4604,4605],{"class":1716},"  # do not do this\n",[219,4607,4608,4609,4611],{},"The factory is called at config-build time (import time for the consuming config). Instantiation happens only when ",[226,4610,289],{}," is called on the root config.",[335,4613,2277,4615,4617],{"id":4614},"_2-lrepeat-for-homogeneous-stacks",[226,4616,1962],{}," for homogeneous stacks",[340,4619,4621],{"className":342,"code":4620,"language":344,"meta":345,"style":345},"# N identical blocks, all with the same hyperparameters\nstack = L.call(nn.Sequential, expand_args=True)(\n    L.repeat(num_layers, transformer_block(hidden_size=768, num_heads=12))\n)\n",[226,4622,4623,4628,4659,4694],{"__ignoreMap":345},[349,4624,4625],{"class":351,"line":352},[349,4626,4627],{"class":1716},"# N identical blocks, all with the same hyperparameters\n",[349,4629,4630,4633,4635,4637,4639,4641,4643,4645,4647,4649,4651,4653,4655,4657],{"class":351,"line":375},[349,4631,4632],{"class":359},"stack ",[349,4634,617],{"class":402},[349,4636,1765],{"class":359},[349,4638,229],{"class":363},[349,4640,1770],{"class":590},[349,4642,468],{"class":363},[349,4644,471],{"class":590},[349,4646,229],{"class":363},[349,4648,825],{"class":366},[349,4650,418],{"class":363},[349,4652,2071],{"class":614},[349,4654,617],{"class":402},[349,4656,776],{"class":640},[349,4658,1777],{"class":363},[349,4660,4661,4663,4665,4667,4669,4672,4674,4676,4678,4680,4682,4684,4686,4688,4690,4692],{"class":351,"line":389},[349,4662,2082],{"class":590},[349,4664,229],{"class":363},[349,4666,2087],{"class":590},[349,4668,468],{"class":363},[349,4670,4671],{"class":590},"num_layers",[349,4673,418],{"class":363},[349,4675,2838],{"class":590},[349,4677,468],{"class":363},[349,4679,2493],{"class":614},[349,4681,617],{"class":402},[349,4683,3155],{"class":497},[349,4685,418],{"class":363},[349,4687,2525],{"class":614},[349,4689,617],{"class":402},[349,4691,3164],{"class":497},[349,4693,1031],{"class":363},[349,4695,4696],{"class":351,"line":396},[349,4697,674],{"class":363},[219,4699,4700,4703,4704,4706,4707,4710,4711,4714],{},[226,4701,4702],{},"expand_args=True"," is required when passing a ",[226,4705,1962],{}," list to ",[226,4708,4709],{},"nn.Sequential",", which takes ",[226,4712,4713],{},"*modules"," not a list.",[335,4716,4718],{"id":4717},"_3-python-iteration-for-heterogeneous-stacks","3. Python iteration for heterogeneous stacks",[219,4720,4721,4722,182,4724,4727],{},"When layers differ (different strides, alternating window sizes), use Python ",[226,4723,4269],{},[226,4725,4726],{},"if"," at config-build time:",[340,4729,4731],{"className":342,"code":4730,"language":344,"meta":345,"style":345},"layers = []\nfor i in range(num_stages):\n    stride = 2 if i == 0 else 1\n    layers.append(basic_block(in_channels=ch, channels=ch, stride=stride))\nstack = L.call(nn.Sequential, expand_args=True)(*layers)\n",[226,4732,4733,4741,4758,4781,4820],{"__ignoreMap":345},[349,4734,4735,4737,4739],{"class":351,"line":352},[349,4736,4259],{"class":359},[349,4738,617],{"class":402},[349,4740,4264],{"class":363},[349,4742,4743,4745,4747,4749,4751,4753,4756],{"class":351,"line":375},[349,4744,4269],{"class":355},[349,4746,4272],{"class":359},[349,4748,4275],{"class":355},[349,4750,4278],{"class":512},[349,4752,468],{"class":363},[349,4754,4755],{"class":590},"num_stages",[349,4757,479],{"class":363},[349,4759,4760,4763,4765,4767,4769,4771,4774,4777,4779],{"class":351,"line":389},[349,4761,4762],{"class":359},"    stride ",[349,4764,617],{"class":402},[349,4766,4305],{"class":497},[349,4768,4297],{"class":355},[349,4770,4272],{"class":359},[349,4772,4773],{"class":402},"==",[349,4775,4776],{"class":497}," 0",[349,4778,4313],{"class":355},[349,4780,498],{"class":497},[349,4782,4783,4785,4787,4789,4791,4793,4795,4797,4799,4802,4804,4806,4808,4810,4812,4814,4816,4818],{"class":351,"line":396},[349,4784,4321],{"class":359},[349,4786,229],{"class":363},[349,4788,4326],{"class":590},[349,4790,468],{"class":363},[349,4792,326],{"class":590},[349,4794,468],{"class":363},[349,4796,842],{"class":614},[349,4798,617],{"class":402},[349,4800,4801],{"class":590},"ch",[349,4803,418],{"class":363},[349,4805,534],{"class":614},[349,4807,617],{"class":402},[349,4809,4801],{"class":590},[349,4811,418],{"class":363},[349,4813,543],{"class":614},[349,4815,617],{"class":402},[349,4817,620],{"class":590},[349,4819,1031],{"class":363},[349,4821,4822,4824,4826,4828,4830,4832,4834,4836,4838,4840,4842,4844,4846,4848,4850,4852,4854],{"class":351,"line":447},[349,4823,4632],{"class":359},[349,4825,617],{"class":402},[349,4827,1765],{"class":359},[349,4829,229],{"class":363},[349,4831,1770],{"class":590},[349,4833,468],{"class":363},[349,4835,471],{"class":590},[349,4837,229],{"class":363},[349,4839,825],{"class":366},[349,4841,418],{"class":363},[349,4843,2071],{"class":614},[349,4845,617],{"class":402},[349,4847,776],{"class":640},[349,4849,4425],{"class":363},[349,4851,1169],{"class":402},[349,4853,3289],{"class":590},[349,4855,674],{"class":363},[335,4857,4859],{"id":4858},"_4-export-both-class-and-factory","4. Export both class and factory",[340,4861,4863],{"className":342,"code":4862,"language":344,"meta":345,"style":345},"__all__ = [\"transformer_block\", \"TransformerBlock\"]\n",[226,4864,4865],{"__ignoreMap":345},[349,4866,4867,4869,4871,4873,4875,4877,4879,4881,4883,4885,4887],{"class":351,"line":352},[349,4868,278],{"class":399},[349,4870,403],{"class":402},[349,4872,406],{"class":363},[349,4874,410],{"class":409},[349,4876,2347],{"class":413},[349,4878,410],{"class":409},[349,4880,418],{"class":363},[349,4882,421],{"class":409},[349,4884,2356],{"class":413},[349,4886,410],{"class":409},[349,4888,444],{"class":363},[219,4890,4891,4892,4894],{},"Downstream code that does not use laco can import ",[226,4893,2356],{}," directly. Laco configs import the factory. Both are tested independently.",[4896,4897,4898],"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 .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 .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smCYv, html code.shiki .smCYv{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}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 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 .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}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 .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);}",{"title":345,"searchDepth":389,"depth":389,"links":4900},[4901,4902,4909,4916,4923],{"id":236,"depth":375,"text":237},{"id":295,"depth":375,"text":4903,"children":4904},"1. blocks\u002Fresidual.py: ResNet-style residual blocks",[4905,4906,4907,4908],{"id":337,"depth":389,"text":338},{"id":1908,"depth":389,"text":1909},{"id":1980,"depth":389,"text":1981},{"id":2242,"depth":389,"text":2243},{"id":2276,"depth":375,"text":4910,"children":4911},"2. blocks\u002Ftransformer.py: Pre-norm Transformer encoder block",[4912,4913,4914,4915],{"id":2301,"depth":389,"text":338},{"id":2961,"depth":389,"text":1909},{"id":3031,"depth":389,"text":1981},{"id":3195,"depth":389,"text":2243},{"id":3225,"depth":375,"text":4917,"children":4918},"3. blocks\u002Fdecoder.py: Autoregressive LLM decoder block",[4919,4920,4921,4922],{"id":3255,"depth":389,"text":338},{"id":3999,"depth":389,"text":1909},{"id":4047,"depth":389,"text":1981},{"id":4434,"depth":389,"text":2243},{"id":4469,"depth":375,"text":4470,"children":4924},[4925,4926,4928,4929],{"id":4473,"depth":389,"text":4474},{"id":4614,"depth":389,"text":4927},"2. L.repeat for homogeneous stacks",{"id":4717,"depth":389,"text":4718},{"id":4858,"depth":389,"text":4859},"md",{},{"title":144,"description":345},"ZQmxy_lNQ39auYApeqP24HIyJyF0Yx_Lewcnz4SpJDA",{},1785687303294]