Interpretability
sentence_transformers.multi_vector_encoder.interpretability provides a per-query-token MaxSim
heatmap utility for ColPali-style image documents. Useful for spot-checking which patch
positions in an image contribute most to a given query.
Heatmaps
maxsim_heatmap is the one-shot entry point. get_n_patches supplies its n_patches argument,
and real_query_token_slice selects the query tokens worth visualizing.
- sentence_transformers.multi_vector_encoder.interpretability.maxsim_heatmap(image: PILImage | str, query_embedding: Tensor, image_embedding: Tensor, n_patches: tuple[int, int], image_mask: Tensor | None = None, aggregate: Literal['sum', 'amax', 'none'] = 'sum', alpha: float = 0.5) PILImage | list[PILImage][source]
One-shot MaxSim heatmap for a (query, image-document) pair.
- Parameters:
image – PIL image, URL, or local file path.
query_embedding –
(Qt, D)per-token query embeddings.image_embedding –
(Dt, D)per-token image-document embeddings.n_patches –
(n_cols, n_rows)image grid shape, as returned byget_n_patches().image_mask – optional mask filtering
image_embeddingto image patches only.aggregate –
"sum"adds every query token’s similarity at each patch, giving an aggregate similarity heatmap rather than an attribution of the MaxSim score, which counts only each query token’s single best patch."amax"shows the strongest single-token match per patch."none"returns one heatmap per query token as a list.alpha – constant overlay opacity in
[0, 1].
- Returns:
A single PIL image for
aggregate in {"sum", "amax"}, or a list for"none".
- sentence_transformers.multi_vector_encoder.interpretability.get_n_patches(model: MultiVectorEncoder, image_size: tuple[int, int]) tuple[int, int][source]
Infer the
(n_patches_x, n_patches_y)=(n_cols, n_rows)image-patch grid thatmodel’s processor produces for an image ofimage_size((width, height), i.e. PIL’simage.size). Plugs directly into then_patchesparameter ofmaxsim_similarity_map()andmaxsim_heatmap().Dynamic grids (Qwen-VL family) are read from the image processor’s own
image_grid_thwoutput for a blank image of that size, fixed square grids (PaliGemma / Gemma3) fromprocessor.image_seq_length. Idefics3 / SmolVLM split-image processors raiseNotImplementedError: their sub-patch token order is not a plain row-major grid.
- sentence_transformers.multi_vector_encoder.interpretability.real_query_token_slice(model: MultiVectorEncoder, query: str) slice[source]
Return the slice into
encode_query’s output that selects the real content tokens.Chat-template prefixes (e.g.
<bos>), ColBERT query markers (e.g. “[Q] “), suffixes (e.g.<|im_end|>), andMultiVectorEncoder’s query-expansion tokens (<mask>/<pad>) wrap the actual query and carry attention-sink signals that distort heatmap visualisations. Slicing them out keeps only the real tokens:s = real_query_token_slice(model, query) query_embedding = model.encode_query([query])[0][s]
Works for both right-padded (PaliGemma) and left-padded (ColQwen2 / ColModernVBert) backbones by comparing the encoded sequences of an empty and the actual query.
Building blocks
maxsim_heatmap composes these two. Use them directly to reach the raw similarity tensor, e.g. for a
custom colormap, a matplotlib figure, or an aggregation other than the built-in ones.
- sentence_transformers.multi_vector_encoder.interpretability.maxsim_similarity_map(query_embedding: Tensor, image_embedding: Tensor, n_patches: tuple[int, int], image_mask: Tensor | None = None, normalize: bool = False) Tensor[source]
Per-query-token similarity over a 2D image-patch grid.
- Parameters:
query_embedding –
(Qt, D)per-token query embeddings.image_embedding –
(Dt, D)per-token image-document embeddings. Passimage_maskifDtincludes non-image tokens, otherwiseDt == n_patches[0] * n_patches[1].n_patches –
(n_cols, n_rows)=(width, height), as returned byget_n_patches(). Patches are row-major.image_mask – boolean mask over the
Dtaxis (Truefor image-patch tokens).normalize – rescale each per-query-token map to
[0, 1].
- Returns:
Tensor of shape
(Qt, n_rows, n_cols), float32 regardless of the input dtype.
- sentence_transformers.multi_vector_encoder.interpretability.render_similarity_map_on_image(image: PILImage | str, similarity_map: Tensor, alpha: float = 0.5, normalization_range: tuple[float, float] | None = None) PILImage[source]
Overlay a 2D similarity map onto an image with the mako colormap.
- Parameters:
image – PIL image, URL, or local file path (loaded via
transformers.image_utils.load_image()).similarity_map –
(n_rows, n_cols)similarity tensor.alpha – constant overlay opacity in
[0, 1].normalization_range –
(min, max)for the colour scale. Defaults to the map’s own range. Pass a shared range across multiple per-token maps so they render proportionally.
- Returns:
A new RGBA PIL image.