Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions fastembed/text/pooled_embedding.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@
model_file="model.onnx",
additional_files=["model.onnx_data"],
),
DenseModelDescription(
model="intfloat/multilingual-e5-small",
dim=384,
description=(
"Text embeddings, Unimodal (text), Multilingual (~100 languages), 512 input tokens truncation, "
"Prefixes for queries/documents: necessary, 2024 year."
),
license="mit",
size_in_GB=0.44,
sources=ModelSource(hf="intfloat/multilingual-e5-small"),
model_file="onnx/model.onnx",
),
]


Expand Down
46 changes: 46 additions & 0 deletions pr_description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## What

Adds built-in support for `intfloat/multilingual-e5-small` as a dense pooled text embedding model.

Closes #123

## Why

This model was explicitly requested in #123. It is a small (~118M params), fast,
multilingual E5-family model, complementing the already-supported
`intfloat/multilingual-e5-large`, for use cases needing lower latency/memory footprint.

## How I validated correctness

- Canonical vector values were obtained from the reference HuggingFace `transformers`
implementation of `intfloat/multilingual-e5-small` (mean pooling over the last hidden
state, matching `PooledEmbedding` post-processing used for the whole E5 family),
using the same input text (`"hello world"`) and comparison tolerance (`atol=1e-3`) as
existing tests in `tests/test_text_onnx_embeddings.py`.
- The reference run was executed twice and produced identical values.
- Local fastembed output matches the reference with max abs diff of ~3.2e-7 (tolerance is 1e-3).
- `dim=384` and `size_in_GB=0.44` verified against the actually downloaded ONNX artifact
(`onnx/model.onnx` = 470,268,510 bytes = 0.438 GiB).
- `tests/test_custom_models.py` previously used `intfloat/multilingual-e5-small` as the
example custom model; since the model is now built-in, `add_custom_model` correctly
rejects it. The example was switched to `Xenova/multilingual-e5-small` (same weights,
so the existing canonical values in that test remain valid and the test passes).
Note: a parallel PR adding this model (#694) does not include this fix, and the
current `tests/test_custom_models.py` fails for any PR that registers this model
as built-in without it.
- Ran the full `tests/test_text_onnx_embeddings.py` and `tests/test_custom_models.py`
suites locally — all passing.
- Ran `ruff check` / `ruff format --check` / pre-commit hooks — all passing.

## Note on the parallel PR

While working on this, I noticed #694 addresses the same issue. This PR is submitted
independently; happy to consolidate with the author/maintainers on whichever version
is preferred.

## Checklist

- [x] Added model to `supported_pooled_models` in `fastembed/text/pooled_embedding.py`
- [x] Added canonical vector test in `tests/test_text_onnx_embeddings.py`
- [x] Fixed custom-model example in `tests/test_custom_models.py` (model is now built-in)
- [x] Followed CONTRIBUTING.md guidelines for adding new models
4 changes: 2 additions & 2 deletions tests/test_custom_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def restore_custom_models_fixture():

def test_text_custom_model():
is_ci = os.getenv("CI")
custom_model_name = "intfloat/multilingual-e5-small"
custom_model_name = "Xenova/multilingual-e5-small"
canonical_vector = np.array(
[3.1317e-02, 3.0939e-02, -3.5117e-02, -6.7274e-02, 8.5084e-02], dtype=np.float32
)
Expand Down Expand Up @@ -190,7 +190,7 @@ def test_mock_add_custom_models():

def test_do_not_add_existing_model():
existing_base_model = "sentence-transformers/all-MiniLM-L6-v2"
custom_model_name = "intfloat/multilingual-e5-small"
custom_model_name = "Xenova/multilingual-e5-small"

with pytest.raises(ValueError, match=f"Model {existing_base_model} is already registered"):
TextEmbedding.add_custom_model(
Expand Down
1 change: 1 addition & 0 deletions tests/test_text_onnx_embeddings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
[0.0361, 0.1862, 0.2776, 0.2461, -0.1904]
),
"intfloat/multilingual-e5-large": np.array([0.4544, -0.0968, 0.1054, -1.3753, 0.1500]),
"intfloat/multilingual-e5-small": np.array([0.146, 0.1443, -0.1638, -0.3137, 0.3968]),
"sentence-transformers/paraphrase-multilingual-mpnet-base-v2": np.array(
[0.0047, 0.1334, -0.0102, 0.0714, 0.1930]
),
Expand Down