Exam Room · Advanced GenAI

Choosing an Embedding Model for a Multilingual Corpus

July 29, 2026 · 28 min read

Generative AI Development · part of The Exam Room

The situation

A company runs a support knowledge base for a product sold across Europe and Asia. The articles are written in whatever language the author works in: roughly half in English, a quarter in French, the rest split across Japanese, German, and Spanish. Customers ask questions in their own language too, and the same question often has its best answer sitting in an article written in a different one. A French customer asking about a billing edge case might be best served by the definitive English article, or the other way round.

The team wants semantic search over the whole corpus, backed by a vector store, with retrieval feeding a Retrieval-Augmented Generation assistant on Amazon Bedrock. The first prototype embedded everything with an English-only model, and it looked fine in the demo because the demo was in English. In practice a French query returns French articles and misses the English one that actually answers it; a Japanese query barely retrieves anything useful at all. The vectors for “how do I cancel my subscription” in English and “comment annuler mon abonnement” in French land in completely different regions of the space, so Cosine similarityA measure of how closely two vectors point the same way, used as the default score for “how related is this text?”. between them is near zero even though they mean the same thing.

The decision in front of them is which embedding model to index and query with. That choice is upstream of everything: the vector store, the distance metric, the storage bill, and whether cross-language retrieval works at all are all downstream of it, and re-embedding a large corpus later is slow and expensive.

What actually matters

The first thing to settle is what “multilingual” has to mean here, because it hides two different capabilities. One is per-language coverage: the model handles French text and English text competently, each on its own. The other is cross-lingual alignment: text with the same meaning lands in the same region of the vector space regardless of the language it was written in, so a query in one language is close to a relevant document in another. A model can be good at the first and useless at the second. English-only models have neither for non-English content; a genuinely multilingual embedding model is trained so that translations sit near each other, and that shared space is the only thing that makes cross-language retrieval work. If the corpus and the queries can be in different languages and you want them to match, cross-lingual alignment is the property to buy, not just per-language competence.

Whether you even need cross-lingual matching is worth deciding deliberately rather than assuming. If every French customer should only ever see French articles and every English customer only English ones, then you don’t need one shared space; you could partition by language, detect the query language, and route to a per-language index, and an English-only model plus a French-only model would each do their own job. That partitioned design is simpler per model but multiplies indexes and falls apart the moment the best answer only exists in another language. The knowledge base here has exactly that shape, one canonical article per topic in whatever language it was written, so the shared-space multilingual model is the fit. Naming the requirement first stops you buying cross-lingual power you won’t use, or worse, partitioning a corpus that needed to be joined.

Embedding dimensionHow many numbers each embedding vector holds – fewer means a smaller, cheaper, faster index and slightly blurrier matching. is the next axis, and it trades quality against cost and speed. A higher-dimensional vector can capture more distinction, but every dimension is storage in the vector store and work for the Nearest-neighbour searchFinding the vectors closest to a query vector; at scale it’s approximated, trading a little accuracy for a lot of speed. on every query, so a larger dimension means a bigger index and slower retrieval. Some models let you choose the output dimension, so you can take a smaller vector and accept a little less quality in exchange for a cheaper, faster index. With a large corpus that difference compounds across millions of stored vectors, so the dimension is a real budget lever, not a detail.

Maximum input length per embedding call decides how you chunk. Every embedding model has a token limit on the text it will turn into a single vector, and anything past it is truncated, silently dropping the tail of a long article from what the vector represents. The limit sets the ceiling on ChunkingSplitting documents into retrievable pieces before embedding them – small enough to match precisely, big enough to still make sense. , and it varies a lot between models; a model with a generous input window lets you embed larger, more self-contained chunks, while a short window forces smaller chunks and more of them. Multilingual tokenisation matters here too, because non-English text, and especially scripts like Japanese, can consume more tokens per unit of meaning, so the effective amount of content that fits is smaller than an English estimate suggests.

Two operational constraints sit underneath all of it. The embedding model used to index the corpus and the model used to embed queries at search time must be the same model; vectors from two different models live in incompatible spaces, and comparing them gives nonsense similarity. And the distance metric configured in the vector store has to match what the model was trained for. Embedding models are typically trained so that cosine similarity, or equivalently inner product on Normalised vectorsScaling every vector to the same length, so comparisons depend only on direction and cosine and dot-product rank results identically. , expresses relatedness; configure the index for Euclidean distance when the model expects cosine, or skip normalisation when the model assumes it, and retrieval quality quietly degrades in a way that’s hard to spot because results still come back, just worse ones. Normalise consistently and use cosine or inner product, the same way, for both indexing and querying.

What we’ll filter on

  1. Language coverage, does the model handle every language in the corpus and the queries competently?
  2. Cross-lingual alignment, does same-meaning text from different languages land close together, and do we actually need that or just per-language search?
  3. Embedding dimension and cost, is the vector size fixed or selectable, and what does it cost in index size and query speed across the whole corpus?
  4. Maximum input length, how much text fits in one embedding call, and how does that set chunk size given heavier non-English tokenisation?
  5. Metric and consistency fit, does the vector store’s distance metric match the model’s training, and can we guarantee the same model for indexing and querying?

The embedding-model landscape

English-only or single-language models. Trained on one language, these produce strong vectors for that language and poor ones for anything else, and they have no shared cross-lingual space at all. On Bedrock this includes the original English-focused Titan text embeddings. Fine when the corpus and queries are genuinely single-language; wrong for anything multilingual, and the failure is quiet because English demos look healthy.

Amazon Titan Text Embeddings V2. A multilingual embedding model on Bedrock with broad language coverage, and its distinctive feature is selectable output dimensions, so you can emit a larger vector for quality or a smaller one to shrink the index and speed up search. That makes it a natural fit when the corpus is large enough that vector size drives the storage and latency bill and you want a single knob to trade quality for cost. It has a generous input token limit, which allows larger chunks.

Cohere Embed (multilingual). Cohere’s multilingual embedding models on Bedrock are built specifically for cross-lingual retrieval across a wide set of languages, with same-meaning text aligned across languages in one shared space. They also expose an input type distinction between embedding a document for indexing and embedding a search query, which can sharpen retrieval. The input length per call is shorter than Titan’s, so chunking has to be tighter. A strong default when cross-language matching over many languages is the central requirement.

Per-language partitioned models. Not a single model but a design: detect the language, route to a language-specific index built with a model chosen per language. Gives you the best single-language quality and keeps each index small, at the cost of running and maintaining several models and indexes, and no ability to match a query to a document in another language. Right only when languages must stay separate by policy or product design.

The distance-metric requirement is not a menu item here; it is a constraint every one of these imposes. Whichever model you pick, read what it was trained for and configure the vector store to match, normalising and using cosine or inner product consistently on both sides.

Side by side

Option Multilingual coverage Cross-lingual alignment Dimension Input length Best for
English-only model Fixed Model-dependent Genuinely single-language corpora
Titan Text Embeddings V2 Selectable Generous Large corpus where vector size drives cost
Cohere Embed multilingual ✓ (built for it) Fixed Shorter Cross-lingual retrieval across many languages
Per-language partitioned ✓ (each alone) Per model Per model Languages kept separate by design

Reading the table against this knowledge base: coverage and cross-lingual alignment are both required, which rules out the English-only model and the partitioned design straight away, and leaves the two genuinely multilingual Bedrock options. The choice between them comes down to dimension control against cross-lingual strength and input length.

Per-language spaces versus one shared multilingual space On the left, English and French text sit in separate vector spaces so a French query cannot reach an English document. On the right, a multilingual model places same-meaning text from both languages close together in one shared space, so the French query retrieves the English answer. Per-language spaces English-only model over everything: a French query cannot reach the English answer English space French space French query "comment annuler mon abonnement" crosses the divide and finds nothing relevant One shared multilingual space Same meaning lands together regardless of language; the French query retrieves the English answer cancel subscription billing edge case French query "comment annuler mon abonnement" lands next to the English answer and retrieves it

The picks in depth

For this knowledge base, a multilingual model with real cross-lingual alignment is the requirement, and both Titan Text Embeddings V2 and Cohere Embed multilingual meet it. The tie-breaker is the shape of the corpus and the cost profile.

If the corpus is large and growing, and the storage and query-latency cost of the vector index is a live concern, Titan Text Embeddings V2 earns its place through selectable output dimensions. You can start at a higher dimension, measure retrieval quality, and drop to a smaller vector if the quality holds, shrinking every stored vector and speeding every nearest-neighbour search across the whole index. Its generous input length also lets you embed larger, more self-contained chunks, which means fewer vectors overall and less chance of splitting an answer across chunk boundaries. That combination, a cost knob plus long inputs, makes it the pragmatic default when scale and budget dominate.

If cross-lingual retrieval quality across a wide spread of languages is the thing you cannot compromise on, Cohere Embed multilingual is built squarely for it, and its separate document and query input types can sharpen the match between a short question and a long article. The trade is a shorter input limit, so chunking has to be tighter and you’ll carry more vectors for the same corpus, and the dimension is fixed rather than a lever you can pull later. When retrieval fidelity across many languages is the whole point and the corpus is not so large that index size dominates, that’s a sound choice.

Whichever wins, three decisions are not optional. Use the same model for indexing and for embedding queries, without exception, because query vectors from a different model live in an incompatible space and retrieval collapses. Set the vector store’s distance metric to match the model, normalising vectors and using cosine or inner product consistently on both the index and the query side. And chunk to the model’s real input limit measured in tokens, remembering that French, German, and especially Japanese consume more tokens per unit of meaning than English, so a chunk size that fits an English article can truncate its Japanese equivalent and silently drop the end of it from the vector.

A worked example: fixing the French-misses-English gap

Take the concrete failure. An English article, “Cancelling your subscription”, is the canonical answer for a billing-cancellation question. A French customer asks “comment annuler mon abonnement”. Under the first prototype, everything was embedded with an English-only model, so the French query embedded into the English model’s space as near-random noise, its vector sat nowhere near the English article’s vector, cosine similarity came back close to zero, and the retriever surfaced three loosely related French articles instead.

Re-index the whole corpus with a multilingual model, say Titan Text Embeddings V2 at a chosen dimension, configure the vector store for cosine similarity with normalised vectors, and embed every article and every incoming query with that same model. Now “comment annuler mon abonnement” and “Cancelling your subscription” map to nearby points in the one shared space, because the model was trained so translations align. The French query’s nearest neighbour is the English article, cosine similarity is high, and the RAG assistant retrieves the right source and answers the French customer from the definitive English content.

If, later, the index has grown and query latency creeps up, the selectable dimension gives a direct remedy: re-embed at a smaller output dimension, measure that top-results retrieval quality holds, and accept a smaller, faster index. The one thing that stays fixed through all of it is the pairing, the same model for documents and queries, and the same metric on both sides; change the model on only one side and the French-misses-English gap reopens, just harder to diagnose the second time.

What’s worth remembering

  1. “Multilingual” hides two properties: per-language competence and cross-lingual alignment; only a model with the second lets a query in one language retrieve a document in another.
  2. English-only models over a multilingual corpus fail quietly, because English demos look healthy while non-English queries land in the wrong region of the space.
  3. Decide first whether you actually need cross-lingual matching or just per-language search; the shared-space model is right when the best answer may exist only in another language, and partitioned per-language indexes are right when languages must stay separate.
  4. On Bedrock the genuinely multilingual choices include Amazon Titan Text Embeddings V2 and Cohere Embed multilingual; the English-focused Titan model and single-language models are for single-language corpora.
  5. Embedding dimension trades quality against index size and query speed; a model with selectable output dimensions, like Titan V2, gives you a cost knob you can pull across the whole corpus.
  6. Maximum input length per call sets your chunk size, and non-English text, especially Japanese, spends more tokens per unit of meaning, so a chunk that fits in English can truncate its translation.
  7. Use the exact same embedding model for indexing and for querying; vectors from two models live in incompatible spaces and comparing them yields nonsense similarity.
  8. Match the vector store’s distance metric to what the model was trained for; normalise and use cosine or inner product consistently on both sides, or retrieval quality degrades invisibly.
  9. Re-embedding a large corpus is slow and expensive, so the model choice is upstream of the vector store, the metric, and the storage bill; get it right before you index at scale.
  10. When cross-language retrieval breaks, suspect the model or the metric before the prompt; the fix is usually a shared multilingual space and a consistent cosine setup, not more retrieval tuning.

These posts are LLM-aided. Backbone, original writing, and structure by Craig. Research and editing by Craig + LLM. Proof-reading by Craig.