huggingface/candle · error

unexpected shape for txt {:?}

Error message

unexpected shape for txt {:?}

What it means

FluxModel forward requires txt (text token embeddings) to be a rank-3 tensor [batch, seq_len, hidden]. If the txt tensor's rank differs, forward bails early with the shape. This guards downstream ops (concatenation with img_ids, attention) that assume 3 dims.

Source

Thrown at candle-transformers/src/models/flux/quantized_model.rs:432

            final_layer,
        })
    }
}

impl super::WithForward for Flux {
    #[allow(clippy::too_many_arguments)]
    fn forward(
        &self,
        img: &Tensor,
        img_ids: &Tensor,
        txt: &Tensor,
        txt_ids: &Tensor,
        timesteps: &Tensor,
        y: &Tensor,
        guidance: Option<&Tensor>,
    ) -> Result<Tensor> {
        if txt.rank() != 3 {
            candle::bail!("unexpected shape for txt {:?}", txt.shape())
        }
        if img.rank() != 3 {
            candle::bail!("unexpected shape for img {:?}", img.shape())
        }
        let dtype = img.dtype();
        let pe = {
            let ids = Tensor::cat(&[txt_ids, img_ids], 1)?;
            ids.apply(&self.pe_embedder)?
        };
        let mut txt = txt.apply(&self.txt_in)?;
        let mut img = img.apply(&self.img_in)?;
        let vec_ = timestep_embedding(timesteps, 256, dtype)?.apply(&self.time_in)?;
        let vec_ = match (self.guidance_in.as_ref(), guidance) {
            (Some(g_in), Some(guidance)) => {
                (vec_ + timestep_embedding(guidance, 256, dtype)?.apply(g_in))?
            }
            _ => vec_,
        };

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Ensure txt is shape [batch, seq_len, hidden_size], unsqueeze(0) if missing batch dim
  2. Check rank before calling: txt.dims().len() == 3
  3. Use the model's own text-encoding helper rather than hand-built tensors

Example fix

// before
model.forward(&txt, &img, &txt_ids, &img_ids, &timesteps, &y, guidance)?;
// after
let txt = if txt.rank() == 2 { txt.unsqueeze(0)? } else { txt };
model.forward(&txt, &img, &txt_ids, &img_ids, &timesteps, &y, guidance)?;
Defensive patterns

Strategy: validation

Validate before calling

assert_eq!(txt.dims().len(), 3, "txt must be [batch, seq, hidden], got {:?}", txt.shape());

Type guard

fn is_rank3(t: &candle_core::Tensor) -> bool { t.rank() == 3 }

Try / catch

match model.forward(&txt, &img, /* ... */) {
    Err(e) if e.to_string().contains("unexpected shape for txt") =>
        Err(anyhow!("reshape txt to [batch, seq, hidden]: {e}")),
    r => r.map_err(Into::into),
}

Prevention

When it happens

Trigger: Calling FluxModel forward with a txt tensor built from tokenizer output of wrong rank — e.g. squeezed to 2D [seq, hidden], 1D flat embeddings, or 4D batched-with-channels tensor.

Common situations: Pre-processing text embeddings yourself instead of using the provided encode path; forgetting to unsqueeze a batch dimension; passing CLIP/T5 hidden states without reshaping to [b, seq, d].

Understand the failure class

Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.

Related errors


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