# `Sting.MultiVector`
[🔗](https://github.com/dkuku/sting/blob/v0.1.0/lib/sting/multi_vector.ex#L1)

ColBERT-style token embeddings and late-interaction scoring.

A multi-vector embedding is a rank-2 tensor, one row per token. Query and
document encodings deliberately remain separate because checkpoints can use
different prompts and scoring masks for each side. MaxSim processes batches
of at most 32 inputs and token chunks of at most 128 tokens; callers can
still provide longer representations.

# `embedding`

```elixir
@type embedding() ::
  Nx.Tensor.t() | %{optional(:mask) =&gt; Nx.Tensor.t(), embedding: Nx.Tensor.t()}
```

# `repository`

```elixir
@type repository() :: Bumblebee.repository()
```

# `encode_document`

```elixir
@spec encode_document(
  map(),
  Bumblebee.Tokenizer.t(),
  String.t() | [String.t()],
  keyword()
) ::
  Nx.Tensor.t() | [Nx.Tensor.t()]
```

Encodes document text into a rank-2 token matrix, or a list of matrices for
a list of inputs. The saved document, passage, or corpus prompt is used
unless `:prompt` or `:prompt_name` overrides it.

# `encode_query`

```elixir
@spec encode_query(
  map(),
  Bumblebee.Tokenizer.t(),
  String.t() | [String.t()],
  keyword()
) ::
  Nx.Tensor.t() | [Nx.Tensor.t()]
```

Encodes query text into a rank-2 token matrix, or a list of matrices for a
list of inputs. The saved query prompt is used unless `:prompt` or
`:prompt_name` overrides it.

# `hierarchical_token_pool`

```elixir
@spec hierarchical_token_pool(Nx.Tensor.t() | [Nx.Tensor.t()], number(), keyword()) ::
  Nx.Tensor.t() | [Nx.Tensor.t()]
```

Applies HierarchicalTokenPooling to a token matrix or list of token matrices.

This follows SentenceTransformers' saved-module behavior: leading
`:num_protected_tokens` stay untouched and the remaining L2-normalized rows
are clustered with Ward linkage on cosine distance before each cluster is
replaced by its mean.

# `load_model`

```elixir
@spec load_model(repository(), keyword()) :: {:ok, map()} | {:error, String.t()}
```

Loads a text multi-vector checkpoint.

The base transformer and its token-level `Dense`/`Normalize` modules are
built from the saved module manifest. `MultiVectorMask` configuration is
retained on the returned model info and applied by `encode_query/4` and
`encode_document/4`. Checkpoints may contain at most one mask module and
optional final `HierarchicalTokenPooling`; multiple masks or other pooling
orders are rejected.

# `maxsim`

```elixir
@spec maxsim(
  embedding() | [embedding()] | Nx.Tensor.t(),
  embedding() | [embedding()] | Nx.Tensor.t()
) ::
  Nx.Tensor.t()
```

Computes all-pairs MaxSim scores.

Each input may be a rank-2 token matrix, a rank-3 padded batch, or a list of
rank-2 matrices. Padded batches may be supplied as `%{embedding: tensor,
mask: mask}`; masked query tokens contribute zero and masked document tokens
are excluded from each maximum.

# `mean_maxsim`

```elixir
@spec mean_maxsim(
  embedding() | [embedding()] | Nx.Tensor.t(),
  embedding() | [embedding()] | Nx.Tensor.t()
) :: Nx.Tensor.t()
```

Computes all-pairs MaxSim scores divided by active query-token count.

# `similarity`

```elixir
@spec similarity(
  embedding() | [embedding()] | Nx.Tensor.t(),
  embedding() | [embedding()] | Nx.Tensor.t(),
  keyword()
) :: Nx.Tensor.t()
```

Computes MaxSim or MeanMaxSim selected by `:similarity_fn_name`.

# `token_embedding`

```elixir
@spec token_embedding(map(), Bumblebee.Tokenizer.t(), keyword()) :: Nx.Serving.t()
```

Builds a serving that returns rectangular token embeddings before the scoring
mask is applied. Each result map uses `%{embedding: rank_2_tensor}` and
includes `:tokenized` when requested. Prefer `encode_query/4` or
`encode_document/4` for variable-length public token matrices.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
