{"record":{"id":"1550bf4d43453f1a","repo":"sgl-project/sglang","slug":"unsupported-text-encoder-output-expected-hidden","errorCode":null,"errorMessage":"Unsupported text encoder output: expected `hidden_states`.","messagePattern":"Unsupported text encoder output: expected `hidden_states`\\.","errorType":"validation","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/configs/pipeline_configs/ltx_2.py","lineNumber":167,"sourceCode":"def _gemma_postprocess_func(\n    outputs: BaseEncoderOutput,\n    text_inputs: dict,\n    pipeline_config: Optional[\"LTX2PipelineConfig\"] = None,\n) -> torch.Tensor:\n    # LTX-2 requires all hidden states concatenated for the connector\n    if hasattr(outputs, \"hidden_states\") and outputs.hidden_states is not None:\n        hidden_states = torch.stack(outputs.hidden_states, dim=-1)\n        attention_mask = text_inputs[\"attention_mask\"]\n        if (\n            pipeline_config is not None\n            and pipeline_config.dit_config.arch_config.caption_proj_before_connector\n        ):\n            return pack_text_embeds_v2(hidden_states, attention_mask)\n\n        sequence_lengths = attention_mask.sum(dim=-1)\n        return pack_text_embeds(hidden_states, sequence_lengths, padding_side=\"left\")\n    else:\n        raise AttributeError(\n            \"Unsupported text encoder output: expected `hidden_states`.\"\n        )\n\n\n@dataclasses.dataclass\nclass LTX2PipelineConfig(PipelineConfig):\n    \"\"\"Configuration for LTX-Video pipeline.\"\"\"\n\n    task_type: ModelTaskType = ModelTaskType.TI2V\n    skip_input_image_preprocess: bool = True\n    generator_device: str = \"cpu\"\n    dit_config: LTX2Config = field(default_factory=LTX2Config)\n\n    # Distilled checkpoints are trained against one fixed sigma schedule rather\n    # than a step count. When set, it replaces the derived schedule.\n    default_sigmas: tuple[float, ...] | None = None\n\n    # Model architecture","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/configs/pipeline_configs/ltx_2.py#L149-L185","documentation":"LTX-2's _gemma_postprocess_func expects the text-encoder output object to expose hidden_states (with the expected shape/layout); if the output structure lacks it, this AttributeError is raised because the pipeline cannot extract token embeddings.","triggerScenarios":"Swapping the text encoder (or a mock/fake encoder in tests) whose forward returns an object without a hidden_states attribute — e.g. returns a plain tensor, a tuple, or a dataclass with last_hidden_state instead of hidden_states.","commonSituations":"Running tests with stub encoders; upgrading/changing transformers versions where output dataclass field names differ; plugging a custom T5/Gemma-compatible encoder with a different output schema.","solutions":["Ensure the text encoder output exposes hidden_states (e.g. BaseModelOutputWithPast from HF transformers)","If using a custom encoder, wrap its output: return BaseModelOutputWithPast(hidden_states=...) or add a hidden_states property","In tests/mocks, return an object with a real hidden_states attribute matching [batch, seq, hidden]"],"exampleFix":"# before\nclass FakeEncoder(nn.Module):\n    def forward(self, ids):\n        return self.backbone(ids)  # tuple, no .hidden_states\n\n# after\nfrom transformers.modeling_outputs import BaseModelOutputWithPast\nclass FakeEncoder(nn.Module):\n    def forward(self, ids):\n        out = self.backbone(ids)\n        return BaseModelOutputWithPast(hidden_states=out[0])","handlingStrategy":"fallback","validationCode":"out = text_encoder(input_ids)\nif not hasattr(out, \"hidden_states\"):\n    out = wrap_as_model_output(out)  # expose .hidden_states","typeGuard":"def has_hidden_states(out) -> bool:\n    return hasattr(out, \"hidden_states\") and out.hidden_states is not None","tryCatchPattern":"except AttributeError as e:\n    if \"hidden_states\" in str(e):\n        hs = encoder_out[0] if isinstance(encoder_out, (tuple, list)) else encoder_out\n        out = BaseModelOutputWithPast(hidden_states=hs)","preventionTips":["Use HF modeling_outputs wrappers for custom encoders","In tests, mock encoder outputs with a hidden_states field"],"tags":["sglang","ltx-2","text-encoder","hidden-states","attribute-error","mocking"],"backgroundTag":"missing-expected-attribute","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}