# Multilingual embedder for Weaviate

**URL:** https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196
**Category:** Support
**Created:** [May 27, 2025, 3:51pm UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196 "2025-05-27T15:51:59Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![rjalex](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/rjalex/32/807_2.png) [@rjalex](https://forum.weaviate.io/u/rjalex)
#### Post date: [May 27, 2025, 3:52pm UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/1 "2025-05-27T15:52:00Z")

</div>

Dear friends,  
I need to embed millions of Italian language strings using the well tested intfloat/multilingual-e5-large model.

If anyone is interested I have uploaded a small repo that will show you how this is done and also test the setup and performance of your new multilingual Weaviate service.

> **[GitHub - rjalexa/weaaviate\_e5](https://github.com/rjalexa/weaaviate_e5)**
>
> Contribute to rjalexa/weaaviate\_e5 development by creating an account on GitHub.

I am left with one question though. As you can see from its Huggingface card, the strings to be vectorized should be all prefixed by the "passage: " string.

This string of course is only useful to generate the embedding and should not be saved to the DB.

How would you suggest handling this?

---

<div class="post-metadata">

### Author: ![DudaNogueira](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/dudanogueira/32/7846_2.png) [@DudaNogueira](https://forum.weaviate.io/u/DudaNogueira)
#### Post date: [May 27, 2025, 6:03pm UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/2 "2025-05-27T18:03:54Z")

</div>

Ciao amico mio!!!

Long time no see 🙂

Indeed, I don’t see anything that could prefix this in the inference container code.

Maybe it could be added as an ENV VAR, something like: VECTORIZER\_TEXT\_PREPEND, [somewhere around here](https://github.com/weaviate/t2v-transformers-models/blob/929a804e0eff3db35e1e761b172649eef8171ab5/vectorizer.py#L110C59-L110C63)

I will raise this internally with our team.

Thanks for exploring and sharing!

---

<div class="post-metadata">

### Author: ![antas-marcin](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/antas-marcin/32/20_2.png) [@antas-marcin](https://forum.weaviate.io/u/antas-marcin)
#### Post date: [May 27, 2025, 6:33pm UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/3 "2025-05-27T18:33:47Z")

</div>

@rjalex with our latest `v1.31` (which should be released this week) I have added one small change to transformers module.

Now when we do a query we are sending a `taskType: query` and when we send passage request we add `taskType: passage`. We can use this information in our [transformers inference container](https://github.com/weaviate/t2v-transformers-models) and prefix the text either with `passage: ` or `query: ` string if used model is `intfloat/multilingual-e5-large`

I can add support for this model and modify transformers inference container in a way that it will support your case.

---

<div class="post-metadata">

### Author: ![rjalex](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/rjalex/32/807_2.png) [@rjalex](https://forum.weaviate.io/u/rjalex)
#### Post date: [May 28, 2025, 7:39am UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/4 "2025-05-28T07:39:58Z")

</div>

Hi Duda yes I was absent for a while due to other job priorities. As always thanks a lot.

---

<div class="post-metadata">

### Author: ![rjalex](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/rjalex/32/807_2.png) [@rjalex](https://forum.weaviate.io/u/rjalex)
#### Post date: [May 28, 2025, 7:46am UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/5 "2025-05-28T07:46:00Z")

</div>

Hi Marcin, yes that would be cool. [intfloat/multilingual-e5-large · Hugging Face](https://huggingface.co/intfloat/multilingual-e5-large) and [BAAI/bge-m3 · Hugging Face](https://huggingface.co/BAAI/bge-m3) are as you probably know the best multilingual embedders out there, and as you can see from their HG pages both Milvus and Vespa do support them, so I guess that an optimal support also for my beloved Weaviate is strategic (and very useful for me 😉 ).

Here is the FAQ from e5-large HF page:

## FAQ

**1. Do I need to add the prefix "query: " and "passage: " to input texts?**

Yes, this is how the model is trained, otherwise you will see a performance degradation.

Here are some rules of thumb:

- Use "query: " and "passage: " correspondingly for asymmetric tasks such as passage retrieval in open QA, ad-hoc information retrieval.
- Use "query: " prefix for symmetric tasks such as semantic similarity, bitext mining, paraphrase retrieval.
- Use "query: " prefix if you want to use embeddings as features, such as linear probing classification, clustering.

Thanks for your attention and take care.

---

<div class="post-metadata">

### Author: ![antas-marcin](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/antas-marcin/32/20_2.png) [@antas-marcin](https://forum.weaviate.io/u/antas-marcin)
#### Post date: [May 28, 2025, 8:41am UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/6 "2025-05-28T08:41:17Z")

</div>

FYI: our transformers inference container already supports [bge-m3](https://hub.docker.com/r/semitechnologies/transformers-inference/tags?name=bge-m3) we expose ONNX images.

---

<div class="post-metadata">

### Author: ![rjalex](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/rjalex/32/807_2.png) [@rjalex](https://forum.weaviate.io/u/rjalex)
#### Post date: [May 28, 2025, 2:08pm UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/7 "2025-05-28T14:08:51Z")

</div>

Very cool to know but I already have 40 million vectors with e5-large 🙂 useful for another project though. Thanks

---

<div class="post-metadata">

### Author: ![antas-marcin](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/antas-marcin/32/20_2.png) [@antas-marcin](https://forum.weaviate.io/u/antas-marcin)
#### Post date: [July 6, 2025, 10:02am UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/8 "2025-07-06T10:02:43Z")

</div>

@rjalex sorry that it took me that long, here’s a [PR](https://github.com/weaviate/t2v-transformers-models/pull/111) that adds support for `intfloat/multilingual-e5-large` model and prepending of `query` `passage` prefixes to vectorized inputs

---

<div class="post-metadata">

### Author: ![antas-marcin](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/antas-marcin/32/20_2.png) [@antas-marcin](https://forum.weaviate.io/u/antas-marcin)
#### Post date: [July 8, 2025, 9:13am UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/9 "2025-07-08T09:13:51Z")

</div>

@rjalex I have released `v1.12.0` version of the `transformers-inference` container project and you can use a pre-built [intfloat-multilingual-e5-large](https://hub.docker.com/layers/semitechnologies/transformers-inference/intfloat-multilingual-e5-large/images/sha256-c762157432f6fc156a1197be2c91ddd1710c68f63dc08bd3b0d8ae4c0daa976f) docker image together with our `text2vec-tranformers` module to produce the embeddings using this model

---

<div class="post-metadata">

### Author: ![rjalex](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/rjalex/32/807_2.png) [@rjalex](https://forum.weaviate.io/u/rjalex)
#### Post date: [July 8, 2025, 2:46pm UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/10 "2025-07-08T14:46:54Z")

</div>

Thank you very much. This fixes one issue with this embedder 🙂 The other VERY RELEVANT aspect is that this model needs the vector output to be normalized before being stored or used for similarity. This is a short doc explaining why, hope it’s useful.

Normalizing the embeddings vector produced by the `intfloat/multilingual-e5-large` model (or any dense retrieval model in the E5 family) is important for **semantic similarity comparisons** and **retrieval tasks**. Below is a detailed explanation of the reasons and best practices for normalization.

* * *

## ❓ Why Normalize Embeddings

### 1. **Cosine Similarity vs. Dot Product**

Most retrieval and semantic similarity systems are based on **cosine similarity** , which compares the **angle** between two vectors, not their magnitude. However, many dense retrieval implementations (e.g., FAISS, Elasticsearch, Weaviate, etc.) are optimized to use the **dot product** for efficiency.

- **Cosine similarity** :

- **Dot product** after **L2 normalization** (i.e., unit norm):

By normalizing each embedding vector to **unit length (L2 norm = 1)**, the **dot product becomes equivalent to cosine similarity** , which is more meaningful in semantic spaces.

### 2. **Performance in Retrieval**

Normalized vectors are crucial in:

- **Similarity search** (e.g., top-k retrieval).
- **Clustering or classification** in embedding space.
- **Avoiding bias** from vector magnitude (especially in transformer outputs where magnitude can correlate with input length or token entropy).

### 3. **Model Training Convention**

The E5 paper (“Text Embeddings by Weakly-Supervised Contrastive Pre-training”) and model documentation explicitly state that normalization **should be applied at inference** to follow the behavior used during training.

* * *

## ✅ How to Normalize Embeddings

Assuming you’re using `sentence-transformers` or the HuggingFace `transformers` pipeline:

### Using `torch`:

```python
import torch
from transformers import AutoTokenizer, AutoModel

model_name = "intfloat/multilingual-e5-large"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)

# Encode text following E5's format
text = "passage: The Eiffel Tower is in Paris." # or "query: ..." if it's a query
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)

with torch.no_grad():
    output = model(**inputs)
    embeddings = output.last_hidden_state[:, 0] # CLS token

# Normalize the embedding to unit length
embeddings_normalized = torch.nn.functional.normalize(embeddings, p=2, dim=1)

```

### Using `sentence-transformers`:

If you’re using the `SentenceTransformer` interface (which wraps normalization internally if configured):

```python
from sentence_transformers import SentenceTransformer, util

model = SentenceTransformer("intfloat/multilingual-e5-large")

# model.encode applies mean pooling + normalization by default (check config)
embedding = model.encode("query: what is the capital of France?", normalize_embeddings=True)

```

* * *

## 📌 Summary

| Aspect | Reason/Implication |
| --- | --- |
| Normalize to unit length | Ensures cosine similarity ≈ dot product |
| Required for E5 models | Matches training conditions (contrastive learning setup) |
| Best practice for retrieval | Improves performance and semantic alignment |
| Method | `torch.nn.functional.normalize(..., p=2, dim=1)` or via `SentenceTransformer(..., normalize_embeddings=True)` |

---

<div class="post-metadata">

### Author: ![antas-marcin](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/antas-marcin/32/20_2.png) [@antas-marcin](https://forum.weaviate.io/u/antas-marcin)
#### Post date: [July 17, 2025, 10:40am UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/11 "2025-07-17T10:40:13Z")

</div>

I thought that this model already responds with normalized embeddings. I will fix that @rjalex in the next version. Thanks!

---

<div class="post-metadata">

### Author: ![antas-marcin](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/antas-marcin/32/20_2.png) [@antas-marcin](https://forum.weaviate.io/u/antas-marcin)
#### Post date: [July 28, 2025, 4:17pm UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/12 "2025-07-28T16:17:45Z")

</div>

@rjalex I just noticed that we already do set [normalize\_embeddings=True](https://github.com/weaviate/t2v-transformers-models/blob/main/vectorizer.py#L226) so just pull the latest version and all will be working as expected.

---

<div class="post-metadata">

### Author: ![rjalex](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.weaviate.io/rjalex/32/807_2.png) [@rjalex](https://forum.weaviate.io/u/rjalex)
#### Post date: [July 28, 2025, 6:40pm UTC](https://forum.weaviate.io/t/multilingual-embedder-for-weaviate/21196/13 "2025-07-28T18:40:44Z")

</div>

Yay! Super! Thanks a lot. Take care
