sgl-project/sglang · error · AttributeError

Could not access latents of provided encoder_output

Error message

Could not access latents of provided encoder_output

What it means

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.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/image_encoding.py:1073

    ):
        if sample_mode == "sample":
            if hasattr(encoder_output, "latent_dist"):
                return encoder_output.latent_dist.sample(generator)
            if hasattr(encoder_output, "latent"):
                return encoder_output.latent
            if hasattr(encoder_output, "latents"):
                return encoder_output.latents
            return encoder_output.sample(generator)
        elif sample_mode == "argmax":
            if hasattr(encoder_output, "latent_dist"):
                return encoder_output.latent_dist.mode()
            if hasattr(encoder_output, "latent"):
                return encoder_output.latent
            if hasattr(encoder_output, "latents"):
                return encoder_output.latents
            return encoder_output.mode()
        else:
            raise AttributeError("Could not access latents of provided encoder_output")

    def preprocess(
        self,
        image: torch.Tensor | PIL.Image.Image,
    ) -> torch.Tensor:
        if isinstance(image, PIL.Image.Image):
            image = pil_to_numpy(image)  # to np
            image = numpy_to_pt(image)  # to pt

        do_normalize = True
        if image.min() < 0:
            do_normalize = False
        if do_normalize:
            image = normalize(image)

        return image

    def verify_input(self, batch: Req, server_args: ServerArgs) -> VerificationResult:

View on GitHub (pinned to 0132848349)

Solutions

  1. Inspect dir(encoder_output) / type(encoder_output) and identify the actual latents attribute
  2. If it is a diffusers AutoencoderKLOutput, ensure the earlier isinstance branch ran — update sglang/diffusers versions so the class identity matches
  3. Wrap your custom encoder so its output exposes .latent_dist (or .latents), or convert to a torch.Tensor before passing

Example fix

// before
latent = stage.retrieve_latents(custom_encoder_output)  # AttributeError

// after
latent = custom_encoder_output.my_latents  # or wrap:
custom_encoder_output.latent_dist = custom_encoder_output.my_latents
latent = stage.retrieve_latents(custom_encoder_output)
Defensive patterns

Strategy: type-guard

Validate before calling

attrs = ("latent_dist", "latent", "latents")
if not any(hasattr(encoder_output, a) for a in attrs) and not hasattr(encoder_output, "mode"):
    raise TypeError(f"Unsupported encoder output {type(encoder_output)}; expose .latents")

Type guard

def has_accessible_latents(o) -> bool:
    return any(hasattr(o, a) for a in ("latent_dist", "latent", "latents")) or hasattr(o, "mode")

Try / catch

try:
    latents = stage.retrieve_latents(encoder_output)
except AttributeError:
    latents = encoder_output.sample  # or your wrapper's field
    # log and adapt

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/be3d70a8802ed565. Report an issue: GitHub.