invoke-ai/InvokeAI · error · ValueError

Didn't get guidance strength for guidance distilled model.

Error message

Didn't get guidance strength for guidance distilled model.

What it means

This Flux ControlNet variant is built with params.guidance_embed=True, meaning the model was guidance-distilled (guidance scale baked into the model via an extra embedding) and therefore needs the per-step guidance vector at every forward call. When guidance_embed is enabled but the guidance argument is None, the model cannot compute vec and raises instead of silently producing wrong results.

Source

Thrown at invokeai/backend/flux/controlnet/instantx_controlnet_flux.py:130

        img_ids: torch.Tensor,
        txt: torch.Tensor,
        txt_ids: torch.Tensor,
        timesteps: torch.Tensor,
        y: torch.Tensor,
        guidance: torch.Tensor | None = None,
    ) -> InstantXControlNetFluxOutput:
        if img.ndim != 3 or txt.ndim != 3:
            raise ValueError("Input img and txt tensors must have 3 dimensions.")

        img = self.img_in(img)

        # Add controlnet_cond embedding.
        img = img + self.controlnet_x_embedder(controlnet_cond)

        vec = self.time_in(timestep_embedding(timesteps, 256))
        if self.params.guidance_embed:
            if guidance is None:
                raise ValueError("Didn't get guidance strength for guidance distilled model.")
            vec = vec + self.guidance_in(timestep_embedding(guidance, 256))
        vec = vec + self.vector_in(y)
        txt = self.txt_in(txt)

        # If this is a union ControlNet, then concat the control mode embedding to the T5 text embedding.
        if self.is_union:
            if controlnet_mode is None:
                # We allow users to enter 'None' as the controlnet_mode if they don't want to worry about this input.
                # We've chosen to use a zero-embedding in this case.
                zero_index = torch.zeros([1, 1], dtype=torch.long, device=txt.device)
                controlnet_mode_emb = torch.zeros_like(self.controlnet_mode_embedder(zero_index))
            else:
                controlnet_mode_emb = self.controlnet_mode_embedder(controlnet_mode)
            txt = torch.cat([controlnet_mode_emb, txt], dim=1)
            txt_ids = torch.cat([txt_ids[:, :1, :], txt_ids], dim=1)
        else:
            assert controlnet_mode is None

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Pass a guidance tensor, e.g. guidance=torch.full((batch,), 3.5, device=img.device) scaled per your CFG schedule, whenever params.guidance_embed is True.
  2. Load a checkpoint/config with guidance_embed=False if you want to run without guidance (e.g. schnell-style) and pass guidance=None.
  3. Check self.params.guidance_embed at the call site and branch your pipeline accordingly.
  4. Fix config loading so guidance_embed reflects the actual checkpoint metadata.

Example fix

// before
out = controlnet(img=img, txt=txt, controlnet_cond=cond, txt_ids=txt_ids, img_ids=img_ids, timesteps=t, y=y)  # guidance omitted
// after
guidance = torch.full((img.shape[0],), 3.5, device=img.device, dtype=img.dtype)
out = controlnet(img=img, txt=txt, controlnet_cond=cond, txt_ids=txt_ids, img_ids=img_ids, timesteps=t, y=y, guidance=guidance)
Defensive patterns

Strategy: validation

Validate before calling

if controlnet.params.guidance_embed:
    assert guidance is not None, "guidance tensor required for guidance-distilled (dev) Flux checkpoints"

Type guard

def needs_guidance(params) -> bool:
    return params.guidance_embed

Try / catch

try:
    out = controlnet(..., guidance=guidance)
except ValueError as e:
    if "guidance strength" in str(e):
        guidance = torch.full((batch,), 3.5, device=device)
        out = controlnet(..., guidance=guidance)
    else:
        raise

Prevention

When it happens

Trigger: Calling InstantXControlNetFlux.forward(...) with guidance=None (the default) while the loaded params have guidance_embed=True — i.e. using a Flux dev (guidance-distilled) checkpoint and omitting the guidance tensor.

Common situations: Reusing inference code written for guidance-distillation-free models (schnell) where guidance is not passed; pipeline refactor that dropped the guidance argument; loading a dev checkpoint but wiring a schnell-style scheduler that never produces guidance values.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/d092f8248a230171. Report an issue: GitHub.