{"record":{"id":"9a6d4dc5b978f8fb","repo":"huggingface/candle","slug":"unexpected-len-from-chunk-ys","errorCode":null,"errorMessage":"unexpected len from chunk {ys:?}","messagePattern":"unexpected len from chunk (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-transformers/src/models/flux/model.rs","lineNumber":250,"sourceCode":"#[derive(Debug, Clone)]\nstruct Modulation1 {\n    lin: Linear,\n}\n\nimpl Modulation1 {\n    fn new(dim: usize, vb: VarBuilder) -> Result<Self> {\n        let lin = candle_nn::linear(dim, 3 * dim, vb.pp(\"lin\"))?;\n        Ok(Self { lin })\n    }\n\n    fn forward(&self, vec_: &Tensor) -> Result<ModulationOut> {\n        let ys = vec_\n            .silu()?\n            .apply(&self.lin)?\n            .unsqueeze(1)?\n            .chunk(3, D::Minus1)?;\n        if ys.len() != 3 {\n            candle::bail!(\"unexpected len from chunk {ys:?}\")\n        }\n        Ok(ModulationOut {\n            shift: ys[0].clone(),\n            scale: ys[1].clone(),\n            gate: ys[2].clone(),\n        })\n    }\n}\n\n#[derive(Debug, Clone)]\nstruct Modulation2 {\n    lin: Linear,\n}\n\nimpl Modulation2 {\n    fn new(dim: usize, vb: VarBuilder) -> Result<Self> {\n        let lin = candle_nn::linear(dim, 6 * dim, vb.pp(\"lin\"))?;\n        Ok(Self { lin })","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-transformers/src/models/flux/model.rs#L232-L268","documentation":"Flux's Modulation1::forward projects the conditioning vector through a linear layer mapped to 3*dim and splits it into 3 chunks (shift/scale/gate). This bail fires when candle's Tensor::chunk(3, D::Minus1) returns a Vec whose length is not 3, meaning the last dimension of the projected tensor is not evenly divisible by 3 — practically always a symptom of a hidden_size/config mismatch between the loaded weights and the FluxConfig used, or a malformed conditioning vector.","triggerScenarios":"Calling Flux forward paths where the timesteps/class-label conditioning vector `vec_` has a last dimension that does not match the configured hidden_size, so `lin` output (3*dim) is not divisible by 3; loading Flux weights with a FluxConfig whose hidden_size disagrees with the checkpoint (e.g. using dev config for schnell-style partial weights or a custom checkpoint); feeding a `vec_` tensor of the wrong feature size into Modulation1 directly.","commonSituations":"Mixing Flux.1-dev and Flux.1-schnell checkpoints with the wrong config struct; hand-edited or quantized checkpoints whose modulation linear weights have unexpected dimensions; running modified pipeline code that reshapes the timestep embedding incorrectly.","solutions":["Verify the FluxConfig (hidden_size, num_heads) matches the checkpoint actually loaded in VarBuilder; use the config the model was published with (dev vs schnell).","Confirm `vec_` fed to the block has last dimension == cfg.hidden_size; check timestep_embedding output (256) passed through time_in and y through vector_in.","Print the chunked tensor shape from the error message {ys:?} and check the linear layer's weight shape (out_dim should be 3*hidden_size) with var_builder retrieval.","If using a custom/quantized checkpoint, re-export it with correct modulation layer shapes or regenerate safetensors from the reference implementation."],"exampleFix":"// before: config mismatch\nlet config = FluxConfig::dev(); // but loading schnell weights\nlet model = Flux::new(&config, vb)?;\n\n// after: matching config to checkpoint\nlet config = FluxConfig::schnell(); // matches loaded weights\nlet model = Flux::new(&config, vb)?;","handlingStrategy":"validation","validationCode":"// Rust: before constructing/running the model\nfn validate_dim(config_hidden: usize, vec_dim: usize) -> candle::Result<()> {\n    if vec_dim != config_hidden {\n        candle::bail!(\"vec_ dim {} != config hidden_size {}\", vec_dim, config_hidden);\n    }\n    if (3 * config_hidden) % 3 != 0 { /* always true; kept for symmetry */ }\n    Ok(())\n}\n// call: validate_dim(cfg.hidden_size, vec_.dim(D::Minus1)?)?;","typeGuard":"fn has_hidden_dim(t: &candle_core::Tensor, hidden: usize) -> bool {\n    t.rank() >= 1 && t.dim(candle_core::D::Minus1).map(|d| d == hidden).unwrap_or(false)\n}","tryCatchPattern":"match model_forward(...) {\n    Ok(out) => out,\n    Err(e) if e.to_string().contains(\"unexpected len from chunk\") => {\n        eprintln!(\"config/weights mismatch in modulation layer: {e}\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always derive FluxConfig from the checkpoint you load (dev vs schnell); never mix configs across checkpoints.","Assert vec_ last dim equals cfg.hidden_size before the forward pass.","When converting checkpoints, verify modulation lin weight shapes are 3*hidden_size x hidden_size (and 6* for double blocks).","Log tensor dims at pipeline boundaries (after time_in/vector_in) during development."],"tags":["candle","tensor-shape","chunk","flux","model-config"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}