Views
No views yet
BAAI/bge-m3
that emits all three BGE-M3 representations from one forward pass,
with dynamic batch and sequence axes:| Output | Shape | Notes |
|---|---|---|
dense | [batch, 1024] | CLS hidden state, raw (not L2-normalised) |
sparse | [batch, seq] | relu(sparse_linear(h)), per-token scalar, raw |
colbert | [batch, seq, 1024] | colbert_linear(h), raw (not normalised/masked) |
input_ids [batch, seq] (int64), attention_mask [batch, seq]
(int64). Opset 17.normalize flag and the exact lexical-weight contract stay
in application code, not frozen into the graph.text-embeddings-inference (TEI) cannot serve BGE-M3 learned-sparse: its
only sparse path is SPLADE pooling, which requires a ForMaskedLM model
and produces SPLADE — a different head with different semantics. BGE-M3's
sparse is its own trained sparse_linear head. This artifact lets a
single lightweight onnxruntime server (no torch) serve dense + sparse +
ColBERT, replacing a dense-only TEI lane without growing infra (the
XLM-RoBERTa encoder weights dominate either engine).model.onnx — graph (~210 KB)model.onnx.data — weights (~2.1 GB)tokenizer.json — the BGE-M3 XLM-RoBERTa fast tokenizer (vocab 250002)_process_token_weights:
drop {cls, eos, pad, unk} and non-positive weights, take the max
weight per unique token-id. Emit indices (raw 0-based token-ids, no
duplicates) and parallel values (post-ReLU, positive, not
L2-normalised); sparse_dim = tokenizer vocab cardinality (250002),
which should be read authoritatively, not hardcoded.1import numpy as np, onnxruntime as ort
2from tokenizers import Tokenizer
3
4tok = Tokenizer.from_file("tokenizer.json")
5sess = ort.InferenceSession("model.onnx", providers=["CPUExecutionProvider"])
6enc = tok.encode_batch(["quarterly management review minutes"])
7ids = np.array([e.ids for e in enc], dtype=np.int64)
8mask = np.array([e.attention_mask for e in enc], dtype=np.int64)
9
10# Request only the heads you need; the shared backbone makes a dense-only
11# call cheap (ColBERT projection is pruned).
12dense, sparse, colbert = sess.run(
13 ["dense", "sparse", "colbert"],
14 {"input_ids": ids, "attention_mask": mask},
15)BAAI/bge-m3.
Weights are unchanged BGE-M3 weights re-serialised to ONNX; please cite
BGE-M3 (Chen et al., 2024).