ultralytics/ultralytics · error · ValueError

Prompt embeddings must be a float32 array with shape (1, cla

Error message

Prompt embeddings must be a float32 array with shape (1, classes, dimensions).

What it means

Raised by load_prompt_embeddings when the 'embeddings' array is not float32 with ndim 3 and a leading batch dim of exactly 1 — i.e. anything other than shape (1, classes, dimensions) in float32. The save path stores embeddings.detach().cpu().float() with that exact shape; float16/float64, 2-D matrices, or batch sizes > 1 are rejected.

Source

Thrown at ultralytics/models/yolo/model.py:415

            ValueError: If the file is invalid or belongs to a different YOLOE architecture.
        """
        assert isinstance(self.model, YOLOEModel)
        with np.load(file, allow_pickle=False) as data:
            if set(data.files) != {"embeddings", "names", "model"}:
                raise ValueError("Prompt embedding file must contain 'embeddings', 'names', and 'model'.")
            embeddings, names, model = data["embeddings"], data["names"], data["model"]

        if model.ndim != 0 or model.dtype.kind != "U":
            raise ValueError("Prompt embedding model identifier must be a scalar string.")
        model_name = str(model.item())
        if model_name != self._prompt_embedding_model():
            raise ValueError(
                f"Prompt embeddings for model '{model_name}' cannot be loaded into '{self._prompt_embedding_model()}'."
            )
        if names.ndim != 1 or names.dtype.kind != "U":
            raise ValueError("Prompt embedding class names must be a one-dimensional string array.")
        if embeddings.dtype != np.float32 or embeddings.ndim != 3 or embeddings.shape[0] != 1:
            raise ValueError("Prompt embeddings must be a float32 array with shape (1, classes, dimensions).")
        if embeddings.shape[1] != len(names) or embeddings.shape[2] != self.model.model[-1].embed:
            raise ValueError("Prompt embedding shape does not match the class names or model embedding dimension.")
        if not np.isfinite(embeddings).all():
            raise ValueError("Prompt embeddings must contain only finite values.")
        self.set_classes(names.tolist(), torch.from_numpy(embeddings.copy()).to(next(self.model.parameters()).device))

    def val(
        self,
        validator=None,
        load_vp: bool = False,
        refer_data: str | None = None,
        **kwargs,
    ):
        """Validate the model using text or visual prompts.

        Args:
            validator (callable, optional): A callable validator function. If None, a default validator is loaded.
            load_vp (bool): Whether to load visual prompts. If False, text prompts are used.

View on GitHub (pinned to 0449ea011c)

Solutions

  1. Cast and reshape before saving: emb.astype(np.float32).reshape(1, num_classes, dim)
  2. Keep exactly one batch entry — stack multiple classes along axis 1, not axis 0
  3. Regenerate the file via save_prompt_embeddings on the source model

Example fix

# before: np.savez('pe.npz', embeddings=emb.astype(np.float16))  # wrong dtype
# after
np.savez_compressed('pe.npz', embeddings=emb.astype(np.float32)[None])  # (1, C, D) float32
Defensive patterns

Strategy: validation

Validate before calling

with np.load(f, allow_pickle=False) as d:
    e = d['embeddings']
    assert e.dtype == np.float32 and e.ndim == 3 and e.shape[0] == 1, \
        f'embeddings must be float32 (1, C, D); got {e.dtype} {e.shape}'

Try / catch

try:
    model.load_prompt_embeddings(f)
except ValueError as e:
    if 'float32 array' in str(e):
        with np.load(f, allow_pickle=False) as d:
            e = np.ascontiguousarray(d['embeddings'], dtype=np.float32)
            if e.ndim == 2:
                e = e[None]
            np.savez_compressed(f, embeddings=e, names=d['names'], model=d['model'])
        model.load_prompt_embeddings(f)
    else:
        raise

Prevention

When it happens

Trigger: Loading an NPZ whose embeddings were saved as float16, float64, a 2-D (classes, dim) tensor, or a multi-object batch; converting tensors with .half() or squeezing away the batch dim before saving.

Common situations: Export pipelines that compress to fp16 before writing; hand-conversion from PyTorch .pt files where the (1, C, D) shape was collapsed to (C, D); concatenating multiple vocabularies along axis 0.

Related errors


AI-assisted analysis of ultralytics/ultralytics@0449ea011c (2026-08-15). Data as JSON: /api/errors/bfe7f3b670be8003. Report an issue: GitHub.