{"record":{"id":"bbdda2deddc346a8","repo":"invoke-ai/InvokeAI","slug":"qwen3-vl-encoder-did-not-return-hidden-states-can","errorCode":null,"errorMessage":"Qwen3-VL encoder did not return hidden_states; cannot build Krea-2 conditioning.","messagePattern":"Qwen3-VL encoder did not return hidden_states; cannot build Krea-2 conditioning\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"invokeai/app/invocations/krea2_text_encoder.py","lineNumber":147,"sourceCode":"            position_ids = (attention_mask.long().cumsum(dim=-1) - 1).clamp(min=0)\n            position_ids = position_ids.unsqueeze(0).expand(3, -1, -1)\n\n            outputs = text_encoder(\n                input_ids=input_ids,\n                attention_mask=attention_mask,\n                position_ids=position_ids,\n                output_hidden_states=True,\n                use_cache=False,\n                return_dict=True,\n            )\n\n            # Some VL models nest the language-model output; fall back to that if needed.\n            hidden_states_tuple = getattr(outputs, \"hidden_states\", None)\n            if hidden_states_tuple is None:\n                lm_output = getattr(outputs, \"language_model_outputs\", None)\n                hidden_states_tuple = getattr(lm_output, \"hidden_states\", None)\n            if hidden_states_tuple is None:\n                raise RuntimeError(\"Qwen3-VL encoder did not return hidden_states; cannot build Krea-2 conditioning.\")\n\n            # Stack the selected layers along a new layer axis: (B, seq, 12, hidden).\n            stacked = torch.stack([hidden_states_tuple[i] for i in KREA2_SELECT_LAYERS], dim=2)\n\n            # Drop the system-prompt prefix tokens.\n            prompt_embeds = stacked[:, KREA2_START_IDX:]\n            prompt_mask = attention_mask[:, KREA2_START_IDX:].bool()\n\n            # Match the device-safe compute dtype used by the denoise loop (falls back from bf16 to\n            # fp16/fp32 on devices without bf16 support) rather than forcing bfloat16.\n            prompt_embeds = prompt_embeds.to(dtype=TorchDevice.choose_bfloat16_safe_dtype(device))\n\n        return prompt_embeds, prompt_mask\n\n    def _lora_iterator(self, context: InvocationContext) -> Iterator[PatchSpec]:\n        \"\"\"Iterate over the LoRA models to apply to the Qwen3-VL text encoder.\"\"\"\n        for lora in self.qwen3_vl_encoder.loras:\n            lora_info = context.models.load(lora.lora)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/krea2_text_encoder.py#L129-L165","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nclass MyEncoderWrapper(nn.Module):\n    def forward(self, input_ids, attention_mask, position_ids, **kw):\n        return self.lm(input_ids=input_ids, attention_mask=attention_mask, position_ids=position_ids)\n// after\nclass MyEncoderWrapper(nn.Module):\n    def forward(self, input_ids, attention_mask, position_ids, **kw):\n        return self.lm(input_ids=input_ids, attention_mask=attention_mask,\n                       position_ids=position_ids, output_hidden_states=True, return_dict=True)","handlingStrategy":"try-catch","validationCode":"// Before invoking, sanity-check the loaded encoder model class/config\nenc_info = context.models.load(self.qwen3_vl_encoder.text_encoder)\nif \"qwen3\" not in enc_info.config.base.name.lower() or \"vl\" not in enc_info.config.base.name.lower():\n    raise ValueError(f\"Expected a Qwen3-VL text encoder, got {enc_info.config.base}\")","typeGuard":"def has_hidden_states(outputs: object) -> bool:\n    hs = getattr(outputs, \"hidden_states\", None)\n    if hs is not None:\n        return True\n    lm = getattr(outputs, \"language_model_outputs\", None)\n    return lm is not None and getattr(lm, \"hidden_states\", None) is not None","tryCatchPattern":"try:\n    prompt_embeds, prompt_mask = krea2_text_encoder.invoke(context)\nexcept RuntimeError as e:\n    if \"did not return hidden_states\" in str(e):\n        logger.error(\"Text encoder is not a compatible Qwen3-VL model; check the encoder model and library versions.\")\n        raise\n    raise","preventionTips":["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."],"tags":["runtime-error","text-encoder","transformers","model-compatibility"],"backgroundTag":"missing-model-output-field","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}