sgl-project/sglang · error · ValueError

Cannot duplicate reference image of batch size {latent_condi

Error message

Cannot duplicate reference image of batch size {latent_condition.shape[0]} to {batch_size} prompts.

What it means

In Longcat image-to-image / reference-image generation, postprocess_image_latent duplicates a reference latent across the prompt batch. Duplication is only possible when the prompt batch size is an integer multiple of the reference-image batch size; otherwise this ValueError is raised.

Source

Thrown at python/sglang/multimodal_gen/configs/pipeline_configs/longcat_image.py:512

        # VL image token count, which is unknown at latent preparation time.
        return None

    # --- ImageVAEEncodingStage hooks ---

    def preprocess_vae_encode(self, image, vae):
        # AutoencoderKL is a 2D image VAE; drop the frames dim added by
        # ImageVAEEncodingStage ([B, C, 1, H, W] -> [B, C, H, W]).
        if image.dim() == 5 and image.shape[2] == 1:
            image = image.squeeze(2)
        return image

    def postprocess_image_latent(self, latent_condition, batch):
        if latent_condition.dim() == 5 and latent_condition.shape[2] == 1:
            latent_condition = latent_condition.squeeze(2)
        batch_size = batch.batch_size
        if batch_size > latent_condition.shape[0]:
            if batch_size % latent_condition.shape[0] != 0:
                raise ValueError(
                    f"Cannot duplicate reference image of batch size "
                    f"{latent_condition.shape[0]} to {batch_size} prompts."
                )
            latent_condition = latent_condition.repeat(
                batch_size // latent_condition.shape[0], 1, 1, 1
            )
        _, num_channels_latents, height, width = latent_condition.shape
        return _pack_latents(
            latent_condition, batch_size, num_channels_latents, height, width
        )

    # --- Denoising hooks ---

    def shard_latents_for_sp(self, batch, latents):
        # (h/2)*(w/2) is odd at most ~1MP edit resolutions, so SP has to pad, and
        # the pads stay unmasked (USPAttention rejects a mask alongside the
        # replicated text prefix). Repeat the last token instead of the base
        # class's zeros, which would carry the RoPE of text token 0.

View on GitHub (pinned to 0132848349)

Solutions

  1. Make the number of prompts equal the number of reference images, or an exact multiple of it (drop the remainder prompts or pad references)
  2. Repeat reference images to match prompts yourself before the call so shapes already align
  3. Audit batch construction to ensure prompts and reference images are zipped 1:1

Example fix

# before
prompts = ["p1", "p2", "p3"]
ref_images = [img1, img2]  # 3 prompts, 2 refs -> raises

# after
prompts = ["p1", "p2"]
ref_images = [img1, img2]  # 1:1
Defensive patterns

Strategy: validation

Validate before calling

n_prompts = len(prompts); n_refs = latent_condition.shape[0]
assert n_prompts == n_refs or (n_prompts > n_refs and n_prompts % n_refs == 0), \
    f"prompts={n_prompts} not a multiple of refs={n_refs}"

Try / catch

except ValueError as e:
    if "Cannot duplicate reference image" in str(e):
        k = len(prompts) // n_refs * n_refs
        rerun(prompts[:k], refs)  # trim to a multiple

Prevention

When it happens

Trigger: Passing N prompts with M reference images where N > M and N % M != 0 — e.g. 3 prompts with 2 reference images, or 5 prompts with 3 references. latent_condition after squeezing has shape[0]=M and batch.batch_size=N.

Common situations: Mixing prompt counts and reference image counts when building image-edit batches; dynamically sized user prompt lists paired with a fixed album of reference images; off-by-one when filtering prompts/references so counts desynchronize.

Related errors


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