{"record":{"id":"be3d70a8802ed565","repo":"sgl-project/sglang","slug":"could-not-access-latents-of-provided-encoder-outpu","errorCode":null,"errorMessage":"Could not access latents of provided encoder_output","messagePattern":"Could not access latents of provided encoder_output","errorType":"validation","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/stages/image_encoding.py","lineNumber":1073,"sourceCode":"    ):\n        if sample_mode == \"sample\":\n            if hasattr(encoder_output, \"latent_dist\"):\n                return encoder_output.latent_dist.sample(generator)\n            if hasattr(encoder_output, \"latent\"):\n                return encoder_output.latent\n            if hasattr(encoder_output, \"latents\"):\n                return encoder_output.latents\n            return encoder_output.sample(generator)\n        elif sample_mode == \"argmax\":\n            if hasattr(encoder_output, \"latent_dist\"):\n                return encoder_output.latent_dist.mode()\n            if hasattr(encoder_output, \"latent\"):\n                return encoder_output.latent\n            if hasattr(encoder_output, \"latents\"):\n                return encoder_output.latents\n            return encoder_output.mode()\n        else:\n            raise AttributeError(\"Could not access latents of provided encoder_output\")\n\n    def preprocess(\n        self,\n        image: torch.Tensor | PIL.Image.Image,\n    ) -> torch.Tensor:\n        if isinstance(image, PIL.Image.Image):\n            image = pil_to_numpy(image)  # to np\n            image = numpy_to_pt(image)  # to pt\n\n        do_normalize = True\n        if image.min() < 0:\n            do_normalize = False\n        if do_normalize:\n            image = normalize(image)\n\n        return image\n\n    def verify_input(self, batch: Req, server_args: ServerArgs) -> VerificationResult:","sourceCodeStart":1055,"sourceCodeEnd":1091,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/stages/image_encoding.py#L1055-L1091","documentation":"retrieve_latents() tries several known attribute conventions to pull raw latents out of a VAE/diffusers encoder output: .latent_dist, .latent, .latents, or a .mode() call. If the encoder_output object exposes none of these attributes, it raises AttributeError because the stage cannot extract latents from an unrecognized encoder output type.","triggerScenarios":"Passing a custom or newer-version AutoencoderKLOutput/encoder output class whose latents live under a different attribute name, or passing a plain tensor wrapper/tuple from a custom VAE wrapper that lacks the four known attributes.","commonSituations":"Upgrading diffusers so the output dataclass changed; swapping in a custom VAE or T2I-adapter encoder; passing a BaseOutput subclass with fields renamed (e.g. .sample only).","solutions":["Inspect dir(encoder_output) / type(encoder_output) and identify the actual latents attribute","If it is a diffusers AutoencoderKLOutput, ensure the earlier isinstance branch ran — update sglang/diffusers versions so the class identity matches","Wrap your custom encoder so its output exposes .latent_dist (or .latents), or convert to a torch.Tensor before passing"],"exampleFix":"// before\nlatent = stage.retrieve_latents(custom_encoder_output)  # AttributeError\n\n// after\nlatent = custom_encoder_output.my_latents  # or wrap:\ncustom_encoder_output.latent_dist = custom_encoder_output.my_latents\nlatent = stage.retrieve_latents(custom_encoder_output)","handlingStrategy":"type-guard","validationCode":"attrs = (\"latent_dist\", \"latent\", \"latents\")\nif not any(hasattr(encoder_output, a) for a in attrs) and not hasattr(encoder_output, \"mode\"):\n    raise TypeError(f\"Unsupported encoder output {type(encoder_output)}; expose .latents\")","typeGuard":"def has_accessible_latents(o) -> bool:\n    return any(hasattr(o, a) for a in (\"latent_dist\", \"latent\", \"latents\")) or hasattr(o, \"mode\")","tryCatchPattern":"try:\n    latents = stage.retrieve_latents(encoder_output)\nexcept AttributeError:\n    latents = encoder_output.sample  # or your wrapper's field\n    # log and adapt","preventionTips":["Pin diffusers versions compatible with your sglang release","Wrap custom VAEs to expose .latents or .latent_dist","Unit-test retrieve_latents against your encoder output class"],"tags":["vae","encoder-output","attribute-access","diffusers-compat"],"backgroundTag":"missing-attribute-on-library-output","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}