ACADEMY
All posts

Open-Source Embedding Models vs OpenAI: BGE-M3, Qwen3-Embedding, Nomic, and When Self-Hosting Actually Pays Off

OpenAI's text-embedding-3 models are the default pick for most RAG pipelines, but open-weight models like BGE-M3 and Qwen3-Embedding now beat them on MTEB and cost a fraction as much to run at real volume. Here's how to actually decide.

Most teams building a RAG pipeline spend weeks arguing about chunk size and reranking, then pick an embedding model in about four minutes by defaulting to whatever OpenAI's docs example uses. That default isn't wrong, exactly. But in 2026 it's no longer the obvious choice: several open-weight embedding models now outscore OpenAI's own models on the standard retrieval benchmark, run for a fraction of the API cost at real volume, and can be self-hosted with the same Ollama stack we've covered before. Here's what actually changed, and how to decide which one fits your pipeline.

What an embedding model is actually doing

An embedding model takes a chunk of text and converts it into a vector, a list of a few hundred to a few thousand numbers, positioned in space so that semantically similar text ends up close together and unrelated text ends up far apart. Retrieval then becomes a geometry problem: embed the user's query, find the nearest chunk vectors (by cosine similarity or dot product), and hand those chunks to the LLM as context.

The model choice matters for two separate reasons that get conflated. First, quality: a model trained on more diverse, higher-quality pairs will place semantically related text closer together more reliably, which directly changes how often your retrieval step surfaces the right chunk. Second, mechanics: dimension count (how long each vector is), max context length (how much text one chunk can represent), and whether the model does dense-only or hybrid retrieval all change what your vector database needs to store and how your pipeline is built. Getting this wrong doesn't throw an error, it just quietly returns worse chunks, which is why RAG pipeline evaluation has to happen before you trust any of this in production.

The real contenders in 2026

The standard way to compare embedding models is the Massive Text Embedding Benchmark (MTEB), a Hugging Face-hosted leaderboard covering retrieval, classification, and clustering tasks across dozens of datasets. Here's where the models people actually reach for stand:

ModelTypeDimensionsMax contextLicense
OpenAI text-embedding-3-largeAPI onlyup to 30728,191 tokensProprietary
OpenAI text-embedding-3-smallAPI onlyup to 15368,191 tokensProprietary
BGE-M3 (BAAI)Open-weight, self-hosted1024 (dense)8,192 tokensMIT
Qwen3-Embedding-8BOpen-weight, self-hostedup to 409632,768 tokensApache 2.0
nomic-embed-text-v1.5Open-weight, self-hosted or Ollamaup to 7688,192 tokensApache 2.0

At launch, OpenAI reported text-embedding-3-large scoring 64.6% average on MTEB, up from 61.0% for the older ada-002 model, and said the model can be shortened to 256 dimensions via a native dimension-truncation parameter while still beating full-size ada-002. That number hasn't moved since the January 2024 launch. In the same window, Qwen3-Embedding-8B took the No.1 spot on the MTEB multilingual leaderboard with a 70.58 score, and it's fully open-weight under Apache 2.0, meaning you can pull it from Hugging Face and run it yourself with no per-token bill at all.

What actually makes BGE-M3 different

BGE-M3's real distinction isn't just its MTEB score, it's that it does three retrieval methods from one model call: dense retrieval (the standard single-vector cosine similarity search), sparse retrieval (a learned, BM25-like keyword-weighting scheme baked into the same forward pass), and multi-vector, ColBERT-style late-interaction retrieval, which keeps a vector per token instead of collapsing the whole chunk into one. Most production RAG setups combine dense retrieval with a separate keyword search (hybrid search) to catch exact-term matches embeddings alone can miss, like model numbers or legal clause references. BGE-M3 produces both signals from a single pass instead of requiring two separate systems, which is a real architectural simplification if you're evaluating whether hybrid search from pgvector or a dedicated vector database is worth the added complexity.

nomic-embed-text-v1.5 takes the opposite bet: it's smaller (fits comfortably on a laptop GPU or even CPU) and ships with fully open training code and data, not just open weights, which matters if you need to audit or retrain it. It's also directly pullable through Ollama, so if you're already running the self-hosted Ollama stack for chat, adding local embeddings is a one-line `ollama pull` away rather than a separate deployment.

What this actually costs

OpenAI's current embedding pricing is $0.02 per million tokens for text-embedding-3-small and $0.13 per million tokens for text-embedding-3-large, both billed per input token with no separate output cost. For a lot of teams, especially anyone still building or validating a RAG pipeline, that's genuinely cheap: a few million tokens of documents costs cents, and there's no GPU to provision, patch, or babysit.

The economics shift once you're re-embedding large, frequently-updated corpora, think a document store that gets rewritten daily, or an app embedding every user message for memory or search. At that point the API's per-token cost is recurring and scales linearly with volume forever, while a self-hosted open-weight model's cost is mostly the fixed price of a GPU (rented hourly from a provider like RunPod or owned outright) that keeps running regardless of how many tokens you push through it. There's no universal break-even number that applies to every setup, since GPU rental rates and your actual token volume both move that line, but the direction is consistent: self-hosting only pays off once volume is high enough that the fixed GPU cost is smaller than the API bill it replaces, and below that line, the API is simply less work.

How to actually try one

You don't need to commit to a full self-hosted deployment to test whether an open-weight model beats what you're using now. Sentence-Transformers runs BGE-M3, Nomic, and most Hugging Face embedding models locally with a few lines of Python, which is enough to re-embed a sample of your real documents and compare retrieval quality directly. For production traffic, Hugging Face's Text Embeddings Inference (TEI) is the purpose-built serving layer, it batches requests and is what most of the self-hosted cost figures above assume. And if you're already running Ollama for chat, `ollama pull nomic-embed-text` gets you a local embeddings endpoint on the same box in under a minute.

Whichever you pick, the model choice is only half the pipeline. A better embedding model raises your retrieval ceiling, but chunking strategy, hybrid search, and reranking usually move recall more than swapping models does, which is exactly the kind of tradeoff evaluating a RAG pipeline with Recall@k and MRR is built to catch before you find out in production.

If you're building a real RAG system and want to work through embedding choice, chunking, hybrid retrieval, and evaluation as one connected pipeline instead of piecing it together from blog posts, that's the core of what the AI Product Development Bootcamp covers, with the retrieval and evaluation modules built around the same production-grade decisions this post only had room to introduce.

Go deeper

AI Product Development Bootcamp

Courses launching soon

Want this as a full course, not just a post?

Join the waitlist and get a 20% launch discount the moment we open checkout. No payment now.

Taught by Aditya Jha · 40+ AI products shipped for real clients. No spam, unsubscribe any time.

Or join our free community for AI tips while you wait

AI Weekly Radar

One email a week: the AI tools, tactics, and course drops actually worth your time. No spam, unsubscribe anytime.