{"record":{"id":"e9ec9a49d0984c91","repo":"tracel-ai/burn","slug":"affine-is-set-to-true-but-gamma-or-beta-is-none","errorCode":null,"errorMessage":"Affine is set to true, but gamma or beta is None","messagePattern":"Affine is set to true, but gamma or beta is None","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-nn/src/modules/norm/group.rs","lineNumber":155,"sourceCode":"///\n/// `Y = groupnorm(X) * γ + β`\n///\n/// Where:\n/// - `X` is the input tensor\n/// - `Y` is the output tensor\n/// - `γ` is the learnable weight\n/// - `β` is the learnable bias\n///\npub(crate) fn group_norm<const D: usize>(\n    input: Tensor<D>,\n    gamma: Option<Tensor<1>>,\n    beta: Option<Tensor<1>>,\n    num_groups: usize,\n    epsilon: f64,\n    affine: bool,\n) -> Tensor<D> {\n    if (beta.is_none() || gamma.is_none()) && affine {\n        panic!(\"Affine is set to true, but gamma or beta is None\");\n    }\n\n    let shape = input.shape();\n    if shape.num_elements() <= 2 {\n        panic!(\n            \"input rank for GroupNorm should be at least 3, but got {}\",\n            shape.num_elements()\n        );\n    }\n\n    let batch_size = shape[0];\n    let num_channels = shape[1];\n\n    let hidden_size = shape[2..].iter().product::<usize>() * num_channels / num_groups;\n    let input = input.reshape([batch_size, num_groups, hidden_size]);\n\n    // Widen before the reduction when the input dtype cannot hold a sum of\n    // squares (see [`accumulation_dtype`]); `square()` below is what overflows.","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-nn/src/modules/norm/group.rs#L137-L173","documentation":"The internal group_norm helper in burn-nn's GroupNorm module panics when the affine flag is true but the learnable affine parameters (gamma weight and/or beta bias) were passed as None. Affine GroupNorm requires both tensors to apply the learned per-channel scale and shift; an inconsistent combination of the flag and the Option parameters indicates a mis-constructed module. The same helper also panics if the input rank is below 3, so check both conditions when debugging.","triggerScenarios":"Calling GroupNorm::forward where the module was built with affine = true in GroupNormConfig but gamma or beta is None — e.g. the params were never initialized/loaded (checkpoint missing group_norm.gamma/beta keys), the tensors were set to None manually, or affine was flipped to true in the config after the params were created under affine = false.","commonSituations":"Loading a model state from a checkpoint trained with affine = false into a module built with affine = true (or vice versa), partially deserialized records where gamma/beta failed to load, copying a config between models with mismatched settings, or calling the low-level group_norm function directly without supplying the tensors.","solutions":["Align the config with the parameters: if the checkpoint/record has no gamma/beta, construct GroupNormConfig with affine = false; if affine is true, ensure the module was init()'d so gamma/beta exist and load the full record.","Re-initialize the module from its config (GroupNormConfig::init()) so affine parameters are created, then load the state.","Inspect the error path for the related panic: if input rank < 3, reshape/permute the input to [N, C, *] before forward.","Verify checkpoint keys include the GroupNorm weight/bias entries when affine was used at training time."],"exampleFix":"// before\nlet config = GroupNormConfig::new(32, 1e-5, true);\n// params loaded from an affine=false checkpoint: gamma/beta are None -> panics in forward\n// after\nlet config = GroupNormConfig::new(32, 1e-5, false); // matches the checkpoint\nlet norm = config.init();\nnorm = norm.load_record(checkpoint); // or re-init with affine=true and load full record","handlingStrategy":"validation","validationCode":"// before calling forward / group_norm\nif affine {\n    assert!(gamma.is_some() && beta.is_some(), \"affine GroupNorm requires gamma and beta\");\n}\nassert!(input.shape().num_elements() > 2, \"GroupNorm input rank must be at least 3\");","typeGuard":"fn affine_params_ready(affine: bool, gamma: &Option<Tensor<1>>, beta: &Option<Tensor<1>>) -> bool {\n    !affine || (gamma.is_some() && beta.is_some())\n}","tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| module.forward(input)));\nmatch result {\n    Ok(out) => out,\n    Err(_) => rebuild_module_from_config_and_reload_record(),\n}","preventionTips":["Keep affine consistent between training and inference configs; do not flip it after the record was created.","Always load the full record (including gamma/beta keys) when affine = true; verify checkpoint keys before load.","Re-init the module from its config if you suspect partially-deserialized parameters.","Reshape inputs to at least rank 3 ([N, C, *]) before GroupNorm forward."],"tags":["rust","burn-nn","panic","groupnorm","missing-parameters"],"backgroundTag":"missing-required-argument","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}