AI Vector Embedding Model Deep Comparison (2026): OpenAI, Cohere, BGE, E5 & Jina
Why embedding model selection matters more than you think
In 2026, RAG is the default LLM app pattern — yet many teams obsess over "which LLM" while neglecting "which embedding model." Embeddings are the foundation of semantic search. A bad embedding causes: context chunks completely off-target (GIGO), clustering confusion, and cross-lingual synonyms mapping to unrelated vector spaces.
This article is for production engineers and architects. Six models, benchmarks to cost to code.
Five evaluation dimensions
| Dimension | Key question |
|---|---|
| Semantic quality | Retrieval and STS scores on MTEB / C-MTEB |
| Dimension & storage | Vector dims? Matryoshka truncation support? |
| Multilingual | Target languages covered? Cross-lingual quality? |
| Cost | Per-million-token price? On-prem possible? |
| Latency & throughput | p95 latency? Batch throughput? |
Six models deep-dive
1. OpenAI text-embedding-3-small
Cost-efficient champion. 1536 dim, Matryoshka truncation to 512 with only ~2% quality drop.
- Dimensions: 1536 (trimmable to 256/512/768/1024)
- Max input: 8191 tokens
- Price: $0.02 / 1M tokens
- Languages: 100+, English strongest
- Matryoshka: ✅ native — pass
dimensionsparameter
from openai import OpenAI
client = OpenAI()
resp = client.embeddings.create(
model="text-embedding-3-small",
input=["The quick brown fox jumps over the lazy dog."],
dimensions=512 # 67% storage savings
)
print(len(resp.data[0].embedding)) # 512
Best for: English-first RAG, quick prototypes, budget-sensitive projects.
2. OpenAI text-embedding-3-large
3072 dim, MTEB avg 64.6, top-three commercial.
- Price: $0.13 / 1M tokens
- Quality: MTEB Retrieval ~59.3, STS ~82.7
Best for: legal/medical high-precision, budget allows.
3. Cohere Embed v3
De-facto standard for multilingual. embed-multilingual-v3.0 leads MIRACL consistently.
- Dimensions: 1024
- Asymmetric:
search_documentvssearch_queryinput types - Price: $0.10 / 1M tokens
- Multilingual: extremely strong, 100+ languages, best cross-lingual
import cohere
co = cohere.Client("your-api-key")
doc_emb = co.embed(texts=["Kubernetes networking guide."],
model="embed-multilingual-v3.0",
input_type="search_document").embeddings[0]
query_emb = co.embed(texts=["Kubernetes ネットワーク"],
model="embed-multilingual-v3.0",
input_type="search_query").embeddings[0]
⚠️ MUST use correct
input_typefor indexing vs querying — mixing degrades quality significantly.
Best for: multilingual RAG (zh/en/ja/fr/es mixed), asymmetric embedding optimization.
4. BGE-M3 (BAAI)
Open-source champion. The rare model supporting dense, sparse, AND multi-vector (ColBERT) retrieval simultaneously.
- Dimensions: 1024 (dense)
- License: MIT, commercial-friendly
- Deployment: HuggingFace + sentence-transformers, single A10
- Multilingual: exceptionally strong, especially zh/en
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-m3")
doc_emb = model.encode("This is about TiDB vector search.", normalize_embeddings=True)
query_emb = model.encode(
"Represent this sentence for searching relevant passages: how to choose TiDB vector index",
normalize_embeddings=True
)
BGE-M3's unique value: three modes from one model — dense (semantic), sparse (BM25-like keywords), multi-vector (ColBERT token-level). Combine for hybrid RAG with higher recall + precision.
Best for: data-sensitive (on-prem required), Chinese/multilingual-heavy, budget-limited but cutting-edge.
5. E5 series (Microsoft / intfloat)
Instruction-tuned embeddings.
| Variant | Dim | Notes |
|---|---|---|
intfloat/e5-large-v2 |
1024 | English-only, MTEB avg 62.88 |
intfloat/multilingual-e5-large |
1024 | 100+ languages |
intfloat/e5-mistral-7b-instruct |
4096 | Mistral-7B based, highest quality but heavy |
model = SentenceTransformer("intfloat/multilingual-e5-large")
passages = model.encode(["passage: The new M4 chip is 50% faster."])
queries = model.encode(["query: what's new in M4 chip?"])
Best for: high-quality fine-tunable open-source, academic research, LLM-style embedding experiments.
6. Jina Embeddings v3
Multi-vector + long-text specialist, 8192 tokens input.
- Dimensions: 1024 (task-adaptive)
- License: Apache-2.0
Best for: long-doc retrieval (legal contracts, full papers), token-level matching.
MTEB snapshot (2026 Q2)
| Model | Retrieval (avg) | STS (avg) | Languages |
|---|---|---|---|
| OpenAI text-embedding-3-large | 59.3 | 82.7 | Multilingual |
| Cohere embed-multilingual-v3.0 | 60.1 | 81.5 | Multilingual leader |
| BGE-M3 | 58.7 | 80.2 | zh/en exceptional |
| OpenAI text-embedding-3-small | 56.8 | 80.1 | English |
| E5-mistral-7b-instruct | 61.2 | 84.3 | English |
| multilingual-e5-large | 57.2 | 78.9 | Multilingual |
⚠️ Public benchmarks ≠ your domain. Always self-evaluate.
Cost analysis (per 1M document chunks)
1M chunks × 200 tokens = 200M tokens:
| Model | 200M tokens cost | Self-hostable |
|---|---|---|
| text-embedding-3-small (512) | $4 | ❌ |
| text-embedding-3-large (512) | $26 | ❌ |
| Cohere embed-v3 | $20 | ❌ |
| BGE-M3 | $0 (GPU ~$1.5/h) | ✅ |
| multilingual-e5-large | $0 (GPU) | ✅ |
Decision framework
| Situation | Recommended model | Why |
|---|---|---|
| English-first, fast launch | text-embedding-3-small | Cheap, reliable API |
| Multilingual RAG | Cohere embed-multilingual-v3.0 | Multilingual retrieval king |
| Chinese-heavy | BGE-M3 | Strong zh/en, OSS |
| Data must stay on-prem | BGE-M3 or multilingual-e5-large | Self-hosted, zero external deps |
| Legal/medical precision | text-embedding-3-large or E5-mistral | High dim + top quality |
| Long docs (5000+ tokens) | Jina v3 | 8192 token input + multi-vector |
| Very tight budget | BGE-M3 + single GPU | Zero API cost, decent quality |
Self-evaluation: the only truth
from sentence_transformers import SentenceTransformer, evaluation
model = SentenceTransformer("BAAI/bge-m3")
evaluator = evaluation.InformationRetrievalEvaluator(
queries=dataset["queries"],
corpus=dataset["corpus"],
relevant_docs=dataset["relevant_docs"],
)
results = evaluator(model)
print(f"NDCG@10: {results['ndcg@10']:.4f}")
print(f"Recall@10: {results['recall@10']:.4f}")
Compare on: semantic retrieval (NDCG@10, Recall@10), text classification (linear probe), clustering (Silhouette Score), cross-lingual retrieval (mAP@10).
FAQ
Q1: What exactly is Matryoshka Embedding?
Training technique that simultaneously optimizes multiple dimensions (256, 512, 1024, 1536). The resulting vector can be truncated to any of these dims without re-embedding. Example: text-embedding-3-large 3072-dim truncated to 256 dim — 92% storage savings with only 5–8% quality drop.
Q2: When should I fine-tune an embedding model?
When the general model clearly underperforms in your domain (medical, legal, finance). 2–5k domain query-doc pairs + a few contrastive learning epochs usually suffice. BGE provides fine-tuning scripts via FlagEmbedding.
Q3: What is asymmetric embedding?
Queries (5–15 words) and documents (hundreds of words) have very different information density. Asymmetric embedding uses different encoding paths (prompts, attention masks, pooling) for each, creating better-matched vector spaces. Cohere's search_query vs search_document is the canonical implementation.
Q4: Sparse vs dense retrieval?
- Sparse (BM25): exact keyword match — "RFC 9110" directly hit, dense might confuse.
- Dense (vectors): semantic match — "car" and "automobile" nearby.
- Hybrid: combine both for best quality.
Q5: Cost optimization tips
- Matryoshka truncation, caching (persist in Redis/TiDB), batch API calls (1 call with 20 texts = same cost as 20 single calls, much faster).
Conclusion
Three-step strategy: (1) Filter: pick 2–3 candidates from decision table. (2) Evaluate: BEIR on 500–1000 real query-doc pairs. (3) A/B test in production.