invoke-ai/InvokeAI · critical · RuntimeError
Qwen3-VL encoder did not return hidden_states; cannot build
Error message
Qwen3-VL encoder did not return hidden_states; cannot build Krea-2 conditioning.
What it means
This RuntimeError is thrown in _encode of the krea2_text_encoder invocation when the Qwen3-VL text encoder's forward output contains no hidden_states, neither at the top level nor nested under language_model_outputs. Krea-2 conditioning requires tapping 12 decoder hidden-state layers (KREA2_SELECT_LAYERS) to build the (B, seq, 12, hidden) tensor, so without hidden states conditioning cannot be constructed at all. It is guarded even though output_hidden_states=True is passed, because different VL model wrappers expose the output differently.
Source
Thrown at invokeai/app/invocations/krea2_text_encoder.py:147
position_ids = (attention_mask.long().cumsum(dim=-1) - 1).clamp(min=0)
position_ids = position_ids.unsqueeze(0).expand(3, -1, -1)
outputs = text_encoder(
input_ids=input_ids,
attention_mask=attention_mask,
position_ids=position_ids,
output_hidden_states=True,
use_cache=False,
return_dict=True,
)
# Some VL models nest the language-model output; fall back to that if needed.
hidden_states_tuple = getattr(outputs, "hidden_states", None)
if hidden_states_tuple is None:
lm_output = getattr(outputs, "language_model_outputs", None)
hidden_states_tuple = getattr(lm_output, "hidden_states", None)
if hidden_states_tuple is None:
raise RuntimeError("Qwen3-VL encoder did not return hidden_states; cannot build Krea-2 conditioning.")
# Stack the selected layers along a new layer axis: (B, seq, 12, hidden).
stacked = torch.stack([hidden_states_tuple[i] for i in KREA2_SELECT_LAYERS], dim=2)
# Drop the system-prompt prefix tokens.
prompt_embeds = stacked[:, KREA2_START_IDX:]
prompt_mask = attention_mask[:, KREA2_START_IDX:].bool()
# Match the device-safe compute dtype used by the denoise loop (falls back from bf16 to
# fp16/fp32 on devices without bf16 support) rather than forcing bfloat16.
prompt_embeds = prompt_embeds.to(dtype=TorchDevice.choose_bfloat16_safe_dtype(device))
return prompt_embeds, prompt_mask
def _lora_iterator(self, context: InvocationContext) -> Iterator[PatchSpec]:
"""Iterate over the LoRA models to apply to the Qwen3-VL text encoder."""
for lora in self.qwen3_vl_encoder.loras:
lora_info = context.models.load(lora.lora)View on GitHub (pinned to 0b6a024f2f)
Solutions
- Verify the model connected to qwen3_vl_encoder is the correct Qwen3-VL text encoder for Krea-2, not a different or renamed checkpoint.
- Upgrade diffusers/transformers to the version InvokeAI expects, so the Qwen3-VL output exposes hidden_states (directly or on language_model_outputs).
- Check that any custom wrapper around the encoder forwards output_hidden_states=True and returns a ModelOutput containing hidden_states.
- As a diagnostic, print type(outputs) and dir(outputs) after the forward call to see where hidden states actually live, and extend the fallback chain.
Example fix
// before
class MyEncoderWrapper(nn.Module):
def forward(self, input_ids, attention_mask, position_ids, **kw):
return self.lm(input_ids=input_ids, attention_mask=attention_mask, position_ids=position_ids)
// after
class MyEncoderWrapper(nn.Module):
def forward(self, input_ids, attention_mask, position_ids, **kw):
return self.lm(input_ids=input_ids, attention_mask=attention_mask,
position_ids=position_ids, output_hidden_states=True, return_dict=True) Defensive patterns
Strategy: try-catch
Validate before calling
// Before invoking, sanity-check the loaded encoder model class/config
enc_info = context.models.load(self.qwen3_vl_encoder.text_encoder)
if "qwen3" not in enc_info.config.base.name.lower() or "vl" not in enc_info.config.base.name.lower():
raise ValueError(f"Expected a Qwen3-VL text encoder, got {enc_info.config.base}") Type guard
def has_hidden_states(outputs: object) -> bool:
hs = getattr(outputs, "hidden_states", None)
if hs is not None:
return True
lm = getattr(outputs, "language_model_outputs", None)
return lm is not None and getattr(lm, "hidden_states", None) is not None Try / catch
try:
prompt_embeds, prompt_mask = krea2_text_encoder.invoke(context)
except RuntimeError as e:
if "did not return hidden_states" in str(e):
logger.error("Text encoder is not a compatible Qwen3-VL model; check the encoder model and library versions.")
raise
raise Prevention
- Always connect the officially supported Qwen3-VL text encoder model to the krea2_text_encoder node.
- Keep diffusers/transformers pinned to the versions InvokeAI requires.
- Avoid custom encoder wrappers unless they propagate output_hidden_states=True and return a ModelOutput.
- Test the encoder with a short prompt after model changes before long runs.
When it happens
Trigger: Calling the krea2_text_encoder invocation with a text encoder whose forward() returns an object lacking both .hidden_states and .language_model_outputs.hidden_states — e.g. a wrong or incompatible model loaded into the Qwen3-VL encoder slot, a custom/subclassed encoder that ignores output_hidden_states=True, or an older diffusers/transformers version whose Qwen3-VL output class does not expose hidden_states under either attribute name.
Common situations: Users point the Krea-2 text-encoder node at a plain Qwen3 (non-VL) or other LLM checkpoint whose ModelConfig does not match; library upgrades rename or nest the output attributes; custom wrapper code strips ModelOutput fields via use_cache/return_dict combinations or a custom forward that never sets output_hidden_states.
Related errors
- Mistral encoder did not return hidden_states. Ensure output_
- Text encoder did not return hidden_states.
- Expected at least 1 hidden state, got {len(outputs.hidden_st
- Text encoder did not return hidden_states. Ensure output_hid
- Text encoder did not return hidden_states. Ensure output_hid
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/bbdda2deddc346a8.
Report an issue: GitHub.