huggingface/candle · error

The number of encoder hidden states {} is not equal to the n

Error message

The number of encoder hidden states {} is not equal to the number of linear layers {}

What it means

SegFormer's decode head applies one MLP linear layer per encoder stage. This error means the slice of encoder hidden states passed to `SegmentDecoderHead::forward` has a different length than the `linear_c` layer list built from `config.num_encoder_blocks` (4 stages by default). The library bails early rather than silently mis-zipping states to MLPs.

Source

Thrown at candle-transformers/src/models/segformer.rs:558

        )?;
        let classifier = conv2d_no_bias(
            config.decoder_hidden_size,
            num_labels,
            1,
            Conv2dConfig::default(),
            vb.pp("classifier"),
        )?;
        Ok(Self {
            linear_c,
            linear_fuse,
            batch_norm,
            classifier,
        })
    }

    fn forward(&self, encoder_hidden_states: &[Tensor]) -> Result<Tensor> {
        if encoder_hidden_states.len() != self.linear_c.len() {
            candle::bail!(
                "The number of encoder hidden states {} is not equal to the number of linear layers {}",
                encoder_hidden_states.len(),
                self.linear_c.len()
            )
        }
        // most fine layer
        let (_, _, upsample_height, upsample_width) = encoder_hidden_states[0].shape().dims4()?;
        let mut hidden_states = Vec::with_capacity(self.linear_c.len());
        for (hidden_state, mlp) in encoder_hidden_states.iter().zip(&self.linear_c) {
            let (batch, _, height, width) = hidden_state.shape().dims4()?;
            let hidden_state = mlp.forward(&hidden_state.flatten_from(2)?.permute((0, 2, 1))?)?;
            let hidden_state = hidden_state.permute((0, 2, 1))?.reshape((
                batch,
                hidden_state.dim(2)?,
                height,
                width,
            ))?;
            let hidden_state = hidden_state.upsample_nearest2d(upsample_height, upsample_width)?;

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Pass ALL per-stage hidden states from the encoder in order (fine-to-coarse), one per `num_encoder_blocks`.
  2. Check the model config's `num_encoder_blocks` (default 4) and ensure the encoder actually returns that many feature maps.
  3. If you only have one/few feature maps, build the head with a config whose `num_encoder_blocks` matches, or wrap states so the count matches.
  4. Verify with candle_core::Error::backtrace / log the two counts in the message to see which side is wrong.

Example fix

// before: only last stage
let features = vec![encoder.last_hidden_state];
let seg = head.forward(&features)?;
// after: all stages
let features = encoder.all_hidden_states; // Vec<Tensor> of len num_encoder_blocks
let seg = head.forward(&features)?;
Defensive patterns

Strategy: validation

Validate before calling

if states.len() != head.num_linear_layers() {
    return Err(format!("expected {} hidden states, got {}", head.num_linear_layers(), states.len()));
}

Type guard

fn states_match_head(states: &[Tensor], head: &SegmentDecoderHead) -> bool {
    states.len() == head.linear_c.len()
}

Try / catch

let seg = match head.forward(&states) {
    Ok(t) => t,
    Err(e) if e.to_string().contains("not equal to the number of linear layers") => {
        candle::bail!("pass all {} encoder hidden states", states_hint); 
    }
    Err(e) => return Err(e.into()),
};

Prevention

When it happens

Trigger: Calling `forward` (or higher-level segmentation forward) with a Vec of hidden states whose count differs from the number of encoder blocks — e.g. passing only the last stage's output, passing 3 states from a modified encoder, or hand-constructing a config with a `num_encoder_blocks` value that doesn't match the checkpoint's actual stage count.

Common situations: Users feed the decoder only the final encoder output instead of all 4 multi-scale feature maps; or they truncate/extend hidden states for memory savings; or a fine-tuned/modified SegFormer variant changes the number of stages while reusing this head.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/e32d69a9b57fd56e. Report an issue: GitHub.