DataAIHub
DataAIHubNews · Research · Tools · Learning
Retrieval

Embedding Models Guide

Choosing and evaluating embedding models for production RAG - OpenAI, Cohere, BGE, E5, and open-source alternatives with benchmarks and deployment guidance.

11 min readIntermediateUpdated Jul 5, 2026
PrerequisitesEmbeddingsRAG

TL;DR

  • Embedding models convert text to dense vectors that capture semantic meaning - the foundation of all vector-based retrieval in RAG.

  • Model choice affects retrieval quality more than vector database choice - a better embedding model on a simple index outperforms a worse model on an optimized index.

  • OpenAI text-embedding-3-small and BGE-large are strong defaults for English RAG; evaluate on your domain before committing.

  • Changing embedding models requires full re-indexing - vectors from different models aren't comparable.

  • Match embedding dimensions, distance metric, and chunk size to your model's training characteristics.

Why This Matters

The embedding model is the lens through which your RAG system "sees" your documents. It determines whether a query about "rate limiting" finds your document about "API throttling" or returns irrelevant results about "network bandwidth."

Teams often spend weeks evaluating vector databases and LLMs while using whatever embedding model their framework defaults to. This is backwards. Embedding model quality is the single highest-leverage decision in the indexing pipeline - it affects every retrieval query until you re-index.

A domain-specific embedding model can improve recall@5 by 20–40% over a general-purpose model on specialized corpora (legal, medical, code). The cost difference between models is negligible compared to the downstream impact on answer quality.

The Problem Embedding Models Solve

Text is unstructured and unsearchable by meaning. Keyword search matches characters; embedding models match concepts.

The core challenge: compress variable-length text into a fixed-size vector that preserves semantic similarity. "Dog" and "puppy" should be close. "Dog" and "car" should be far apart. "Rate limit exceeded" and "API throttling error" should be close despite sharing no words.

Embedding models solve this by training neural networks on massive text corpora to produce vectors where semantic similarity corresponds to geometric proximity. This enables finding documents by meaning, cross-lingual retrieval, and powering the retrieval step in every RAG pipeline.

What Is an Embedding Model?

An embedding model is a neural network (typically a transformer encoder) trained to map text into a fixed-dimensional vector space. Similar texts produce vectors that are close together by cosine similarity or dot product.

from openai import OpenAI

client = OpenAI()
response = client.embeddings.create(
    model="text-embedding-3-small",
    input="How do I configure rate limiting for the API?",
)
vector = response.data[0].embedding  # list of 1536 floats

Key properties:

Property Description Example Values
Dimensions Vector size 384, 768, 1024, 1536, 3072
Max input tokens Maximum text length per embedding 512, 8192
Distance metric How similarity is computed Cosine, dot product
Language support Monolingual vs multilingual English-only, 100+ languages
Domain General vs specialized General, code, legal, medical

How Embedding Models Work

Architecture

Most modern text embedding models use a bi-encoder architecture: a transformer encoder followed by mean pooling and optionally a projection layer.

The retriever scores document chunks against the query embedding and returns the top-k passages that ground the generator.

Bi-encoder models embed queries and documents independently. This enables pre-computing document embeddings (fast indexing) and embedding only the query at search time (low latency). The trade-off: query and document embeddings are computed separately, so the model can't capture fine-grained query-document interactions.

Cross-encoder models (used in re-ranking, not initial retrieval) concatenate query and document and run them through the transformer together. More accurate but too slow for indexing entire corpora.

Training Methods

Method Description Examples
Contrastive learning Pull similar pairs together, push dissimilar apart SimCSE, BGE
Multi-task training Train on classification, NLI, retrieval simultaneously E5, GTE
Matryoshka training Train vectors that work at multiple dimensions OpenAI v3, Nomic
Instruction tuning Prefix queries with task instructions E5, BGE-M3

Matryoshka Embeddings

OpenAI's text-embedding-3 and Nomic's models support Matryoshka Representation Learning - vectors where the first N dimensions are useful on their own:

# Full 1536-dim embedding
full_vector = embed("query text", dimensions=1536)

# Truncated 256-dim still works (lower quality, less storage)
compact_vector = embed("query text", dimensions=256)

This lets you trade quality for storage and speed without re-indexing.

Architecture

Embedding models sit in both the indexing and query paths:

A production RAG stack separates offline indexing (load, chunk, embed, store) from online querying (embed query, retrieve, rerank, generate).

End-to-end RAG pipeline

Source: Survey on RAG

Critical rule: the same embedding model must be used for indexing and querying. Vectors from different models occupy different semantic spaces and cannot be compared.

Step-by-Step Flow

Step 1: Define requirements. Language(s), domain specificity, latency budget, data residency, and cost constraints.

Step 2: Select candidates. Start with 2–3 models from the comparison table below.

Step 3: Build an evaluation set. 50–200 query-document pairs from your actual corpus.

Step 4: Benchmark. Compute recall@k, MRR, and nDCG for each model.

Step 5: Consider operational factors. API vs self-hosted, cost at volume, latency, dimension constraints.

Step 6: Index and deploy. Embed the full corpus. Version the model name in metadata.

Step 7: Monitor. Track retrieval quality in production. Re-evaluate when new models release.

Real Production Example

Evaluating three embedding models on a legal document corpus:

import numpy as np
from dataclasses import dataclass

@dataclass
class EvalPair:
    query: str
    relevant_doc_id: str

def recall_at_k(embed_fn, corpus, eval_pairs, k=5):
    doc_ids = list(corpus.keys())
    doc_vectors = np.array([embed_fn(text) for text in corpus.values()])
    hits = 0
    for pair in eval_pairs:
        q_vec = np.array(embed_fn(pair.query))
        similarities = doc_vectors @ q_vec
        top_k_ids = [doc_ids[i] for i in np.argsort(similarities)[-k:][::-1]]
        if pair.relevant_doc_id in top_k_ids:
            hits += 1
    return hits / len(eval_pairs)

models = {
    "text-embedding-3-small": lambda t: openai_embed(t, "text-embedding-3-small"),
    "bge-large-en-v1.5": lambda t: hf_embed(t, "BAAI/bge-large-en-v1.5"),
    "e5-large-v2": lambda t: hf_embed(t, "intfloat/e5-large-v2"),
}

for name, embed_fn in models.items():
    score = recall_at_k(embed_fn, corpus, eval_pairs, k=5)
    print(f"{name}: recall@5 = {score:.3f}")
# Example output:
# text-embedding-3-small: recall@5 = 0.782
# bge-large-en-v1.5: recall@5 = 0.815
# e5-large-v2: recall@5 = 0.798

Run this on your domain before choosing. MTEB leaderboard scores are directional - your corpus is ground truth.

Model Comparison

Model Dims Max Tokens Cost Self-Host Best For
text-embedding-3-small 1536 8191 $0.02/1M tokens No General English RAG, fast to deploy
text-embedding-3-large 3072 8191 $0.13/1M tokens No Highest quality API option
Cohere embed-v3 1024 512 $0.10/1M tokens No Multilingual, compression
bge-large-en-v1.5 1024 512 Free Yes Best open-source English
e5-large-v2 1024 512 Free Yes Strong with instruction prefix
multilingual-e5-large 1024 512 Free Yes 100+ languages
Nomic embed-text-v1.5 768 8192 Free Yes Long documents, Matryoshka
jina-embeddings-v3 1024 8192 API/self-host Yes Long context, multilingual

Tip

For E5 models, prefix queries with "query: " and documents with "passage: ". This matches their training format and improves retrieval quality.

Design Decisions

Decision Option A Option B When to choose
Deployment API (OpenAI, Cohere) Self-hosted (BGE, E5) API for speed; self-hosted for data residency or high volume
Dimensions 384 (compact) 1536 (full) 384 for cost/storage; 1536 for quality. Cannot mix in one index.
Model size Small (384-dim) Large (1024-dim) Large for quality-critical; small for high-volume or latency-sensitive
Language English-only Multilingual Match to your corpus languages
Domain General Fine-tuned Fine-tune when general models score below 0.7 recall@5 on your eval set

⚠ Common Mistakes

  1. Using different models for indexing and querying. Vectors from different models are incomparable. Always use the same model on both paths.

  2. Choosing based on MTEB leaderboard alone. Benchmark scores don't predict performance on your specific domain. Always evaluate on your corpus.

  3. Ignoring input length limits. Embedding a 2000-token chunk in a 512-token model truncates silently. Match chunk size to model max tokens.

  4. Not versioning the model. When you eventually migrate models, you need to know which vectors were created with which model. Store model name/version in metadata.

  5. Skipping query preprocessing. E5 models need "query: " prefix. BGE recommends query instructions. Read the model card.

  6. Embedding raw HTML/PDF text. Garbage input produces garbage vectors. Clean and parse documents before embedding.

  7. Optimizing embedding model before fixing chunking. A perfect embedding model can't retrieve a complete answer from a badly chunked document.

Where It Breaks Down

Exact matching - Embeddings compress meaning and lose exact token information. Product codes, error IDs, and version numbers need hybrid search alongside embeddings.

Negation and logic - "Refundable" and "non-refundable" may embed similarly. Embeddings capture topic, not logical structure.

Numerical precision - "$4.2 million" and "$42 million" may be indistinguishable in vector space. Don't rely on embeddings for numeric comparison.

Domain shift - A model trained on web text may underperform on internal jargon, abbreviations, or domain-specific terminology. Fine-tune or evaluate carefully.

Multilingual mixing - Using an English-only model on a multilingual corpus silently degrades non-English retrieval. Use multilingual models or language-specific indexes.

Running in Production

Best Practice

Best Practices - Instrument every stage, version embedding models, enforce access control at retrieval time, and evaluate on a fixed golden set before shipping changes.

Dimension Consideration
Scaling API models scale automatically. Self-hosted: one GPU handles ~1000 embeddings/sec. Batch embed during indexing.
Latency API: 30–80ms per query embedding. Self-hosted GPU: 5–20ms. Batch document embedding offline - not on query path.
Cost OpenAI small: ~$0.02/1M tokens. Indexing 1M chunks (~500 tokens each) ≈ $10. Query embedding: negligible at most scales.
Monitoring Track embedding latency, error rate, and retrieval recall@k. Alert on model API outages - have a fallback or cache.
Evaluation Re-run eval set monthly. Compare against new model releases. A/B test model changes before full re-index.
Security API models send text to third parties. Self-hosted for sensitive data. Check data processing agreements.

Important

Store the embedding model name and version in your vector database metadata. You will need this for re-indexing and debugging.

Ecosystem

  • OpenAI: text-embedding-3-small, text-embedding-3-large - API-only, strong general performance.

  • Cohere: embed-v3 - multilingual, supports compression and image embeddings.

  • Hugging Face: Hosts BGE, E5, GTE, Nomic, and hundreds of open-source models.

  • Sentence Transformers: Python library for running open-source embedding models locally.

  • Voyage AI: Domain-specific embedding models for code, finance, and legal.

  • Jina AI: Long-context and multilingual embedding models.

  • Embeddings: The underlying concept - vector representations of meaning.

  • RAG: The primary use case for embedding models.

  • Vector Databases: Where embeddings are stored and searched.

  • Re-ranking: Cross-encoder models that complement bi-encoder embeddings.

  • Retrieval Evaluation: How to measure embedding model quality on your data.

  • Chunking Strategies: Chunk size must match model input limits.

Learning Path

Prerequisites: Embeddings · RAG

Next topics: Vector Databases · Re-ranking · Retrieval Evaluation

Estimated time: 45 min · Difficulty: Intermediate

FAQs

Which embedding model should I use?

For English RAG: OpenAI text-embedding-3-small (API) or bge-large-en-v1.5 (self-hosted). Evaluate both on your domain. Use multilingual-e5 for non-English corpora.

Can I mix embeddings from different models?

No. Vectors from different models occupy different semantic spaces. Mixing them in one index produces meaningless search results.

How do I switch embedding models?

Create a new collection/index with the new model's dimensions. Re-embed all documents. Run both indexes in parallel during migration. Cut over when eval confirms quality.

API or self-hosted?

API for speed to market and low ops. Self-hosted for data residency, high volume (cost savings above ~10M embeddings/month), or offline environments.

Do I need the largest model?

Not necessarily. text-embedding-3-small often matches text-embedding-3-large on domain-specific eval sets. Larger models cost more storage and compute. Measure, don't assume.

What input length should I use?

Match your chunk size to the model's max input tokens. Most models handle 512 tokens; some (Nomic, Jina) handle 8192. Truncation loses information silently.

How do I fine-tune an embedding model?

Use sentence-transformers with contrastive loss on query-document pairs from your domain. Requires 1K–10K labeled pairs. Worth it when general models score below 0.7 recall@5.

What distance metric should I use?

Cosine similarity for most text models. Dot product for OpenAI embeddings (they're normalized, so equivalent). Match your vector database configuration to the model.

How often do new models come out?

Major releases every 3–6 months. Re-evaluate quarterly. Don't chase every release - switch when eval shows meaningful improvement on your corpus.

Can one embedding model handle text and images?

Multimodal models (CLIP, Cohere embed-v3, Voyage multimodal) embed both. Useful for documents with diagrams and charts. Text-only models ignore visual content.

What is the E5 query/passage prefix?

E5 models are trained with "query: " before queries and "passage: " before documents. Using these prefixes at inference time significantly improves retrieval quality.

How do embedding costs compare to LLM costs?

Embeddings are 10–100x cheaper than generation. Indexing 1M chunks costs ~$10 with OpenAI small. The same text through GPT-4o costs ~$1250. Embed freely; generate carefully.

How do I batch embed efficiently?

Most APIs support batching 100–2000 texts per request. Batch during offline indexing - not on the query path. For self-hosted models, use sentence-transformers with encode(texts, batch_size=64, show_progress_bar=True). GPU batching is 10–50x faster than sequential encoding.

What is the MTEB benchmark?

Massive Text Embedding Benchmark (MTEB) evaluates embedding models across 56 datasets covering retrieval, classification, clustering, and semantic similarity. Leaderboard scores are useful for initial model selection but do not predict performance on your specific domain. Always validate with your own eval set.

Should I embed the document title separately?

For long documents, prepend the title and section heading to each chunk before embedding - this is more effective than storing the title as metadata alone. The embedding model encodes the title into the vector, improving retrieval when users search by topic name rather than exact content phrases.

References

Further Reading

Summary

  • Embedding model choice is the highest-leverage decision in the RAG indexing pipeline.
  • Always evaluate on your domain - leaderboard scores are directional, not definitive.
  • Use the same model for indexing and querying. Version it in metadata.
  • Match chunk size to model input limits. Prefix queries per model instructions.
  • API models for speed; self-hosted for data residency and cost at scale.
  • Plan for full re-indexing when changing models - vectors aren't transferable.

Next Topics

Learning Path

Continue Learning

Related Tools

ToolCategoryPurposeWebsiteBest For
Hugging Face Transformersml libraryLibrary for using pretrained transformers in Python and beyond.huggingface.coModel fine-tuning
PineconeVector DBManaged vector database for similarity search and RAG.pinecone.ioRAG systems