huggingface/candle · error

{dim} is odd

Error message

{dim} is odd

What it means

timestep_embedding() in flux/model.rs builds sinusoidal timestep embeddings by concatenating sin and cos halves of size dim/2, which only works for even dim. An odd dim triggers bail!("{dim} is odd").

Source

Thrown at candle-transformers/src/models/flux/model.rs:123

    let x0 = x.narrow(D::Minus1, 0, 1)?;
    let x1 = x.narrow(D::Minus1, 1, 1)?;
    let fr0 = freq_cis.get_on_dim(D::Minus1, 0)?;
    let fr1 = freq_cis.get_on_dim(D::Minus1, 1)?;
    (fr0.broadcast_mul(&x0)? + fr1.broadcast_mul(&x1)?)?.reshape(dims.to_vec())
}

pub(crate) fn attention(q: &Tensor, k: &Tensor, v: &Tensor, pe: &Tensor) -> Result<Tensor> {
    let q = apply_rope(q, pe)?.contiguous()?;
    let k = apply_rope(k, pe)?.contiguous()?;
    let x = scaled_dot_product_attention(&q, &k, v)?;
    x.transpose(1, 2)?.flatten_from(2)
}

pub(crate) fn timestep_embedding(t: &Tensor, dim: usize, dtype: DType) -> Result<Tensor> {
    const TIME_FACTOR: f64 = 1000.;
    const MAX_PERIOD: f64 = 10000.;
    if dim % 2 == 1 {
        candle::bail!("{dim} is odd")
    }
    let dev = t.device();
    let half = dim / 2;
    let t = (t * TIME_FACTOR)?;
    let arange = Tensor::arange(0, half as u32, dev)?.to_dtype(candle::DType::F32)?;
    let freqs = (arange * (-MAX_PERIOD.ln() / half as f64))?.exp()?;
    let args = t
        .unsqueeze(1)?
        .to_dtype(candle::DType::F32)?
        .broadcast_mul(&freqs.unsqueeze(0)?)?;
    let emb = Tensor::cat(&[args.cos()?, args.sin()?], D::Minus1)?.to_dtype(dtype)?;
    Ok(emb)
}

#[derive(Debug, Clone)]
pub struct EmbedNd {
    #[allow(unused)]
    dim: usize,

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Pass an even dim (use the model's standard embedding size, e.g. 256).
  2. If a custom width is needed, round it up to the next even number before calling.
  3. Check your Flux Config for odd dimensions and align them with upstream Flux defaults.

Example fix

// before
let emb = timestep_embedding(&t, 255, dtype)?; // bails: odd
// after
let emb = timestep_embedding(&t, 256, dtype)?; // even, ok
Defensive patterns

Strategy: validation

Validate before calling

let dim = config.time_step_embedding_dim;
if dim % 2 != 0 {
    return Err(anyhow::anyhow!("embedding dim {dim} must be even for sinusoidal timestep embedding"));
}

Type guard

fn even_dim(dim: usize) -> Option<usize> { if dim % 2 == 0 { Some(dim) } else { None } }

Try / catch

let dim = if dim % 2 == 0 { dim } else { dim + 1 };
let emb = timestep_embedding(&t, dim, dtype)
    .map_err(|e| anyhow!("timestep embedding failed (check dim is even): {e}"))?;

Prevention

When it happens

Trigger: Calling timestep_embedding(t, dim, dtype) (directly or via Flux forward) with an odd dim — e.g. a custom Flux config whose embedding/hidden dimension is odd.

Common situations: Modifying Flux's time_step_embedding_dim / hidden_size to a nonstandard odd value, or invoking the pub(crate) helper with a hand-picked odd width in custom code.

Related errors


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