In February 2024 Nomic AI released nomic-embed-text-v1[1] and, weeks later, the v1.5[2] variant with Matryoshka representations. It’s not the first open-source embedding model, but it’s the first one arriving with three things at once. It has Apache 2.0 weights, fully auditable training data, and an MTEB score close enough to text-embedding-3-small. With that, the conversation stops being "open source or quality" and becomes "open source with enough quality."

Key takeaways

  • 137M parameters, 768-dimensional vectors, and up to 8192 tokens of context: triple most prior open models.

  • Apache 2.0 licence with published training data: no vendor lock-in.

  • The v1.5 variant adds Matryoshka Representation Learning: truncating to 256 dimensions loses only 2-3 MTEB points.

  • Task prefixes (search_query:, search_document:) are mandatory; omitting them is the most common migration mistake from OpenAI.

  • Compatible with Ollama, LangChain, LlamaIndex, and pgvector with no extra plugins.

Why open embeddings matter

An embedding is the quietly expensive part of a RAG system, not because of per-token cost, but because of coupling. If you index millions of documents with a proprietary model and it changes version or disappears, your index is orphaned. Reindexing isn’t trivial: reprocessing the corpus, regenerating vectors, rebuilding the HNSW index, and validating retrieval quality is a multi-day project.

Two additional dimensions matter:

  • Data residency: in the EU, sending the whole corpus to the OpenAI API still runs into legal review. A local model removes that friction.

  • Transparency: Nomic published the training dataset, allowing a compliance team to reason about what the model saw and its likely biases.

What nomic-embed-text-v1 actually is

137M parameters, 768-dimensional vectors, up to 8192 tokens of context. That last number is the surprising one: most open embeddings from the previous generation (E5, BGE, GTE) capped at 512 tokens. 8k lets you embed a full article or an entire conversation without artificial chunking.

The Nomic technical report[3] describes a two-stage contrastive scheme: weakly supervised pretraining on ~235M pairs (Common Crawl, Wikipedia, StackExchange), then supervised fine-tuning on MSMARCO, NQ, HotpotQA, and Nomic-curated sets.

On MTEB, v1 averages around 62.4 points. text-embedding-3-small sits at 62.3. Nomic isn’t the best open model, but it’s within noise of the default proprietary embedding, at 768 dimensions instead of 1536. Fewer dimensions mean smaller indices and faster searches.

Task prefixes and the v1.5 version

A critical operational quirk: the model uses task prefixes in the style of Cohere Embed v3. Prepend the right prefix depending on use:

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("nomic-ai/nomic-embed-text-v1.5", trust_remote_code=True)
doc = model.encode("search_document: RAG combines retrieval with generation.")
query = model.encode("search_query: what is RAG?")

Ignoring prefixes noticeably degrades retrieval quality. It’s the most frequent mistake when migrating from OpenAI, where prefixes don’t exist.

The v1.5 version adds Matryoshka Representation Learning: the model is trained so that the first N components of the vector are useful on their own. You can keep the full 768 dimensions or truncate to 512, 256, 128, or even 64 depending on storage constraints, with gradual and predictable quality degradation. Going from 768 to 256 dimensions cuts space by almost 70% at the cost of a couple of MTEB points.

Performance and integration

On a 16-core server CPU: ~100 embeddings/second; on an RTX 4090: ~3000; on Apple Silicon M2 Pro with MPS: ~500. With Ollama[4] (ollama pull nomic-embed-text) it exposes an OpenAI-compatible embeddings endpoint, letting you migrate existing code by changing only base_url. For pgvector: declare the column as vector(768) and index with HNSW over vector_cosine_ops. For the Spanish version of this article, see nomic-embed-text: embeddings abiertos competitivos.

There’s also a nomic-embed-text-v1-multilingual variant trained on roughly a hundred languages, including Spanish. It doesn’t match Cohere Embed v3 for serious multilingual work, but it covers the most common European cases reasonably well. For RAG systems where retrieval evaluation matters, see retrieval evaluation frameworks.

Realistic expectations

Nomic isn’t frontier: if your application depends on the last 3% of retrieval precision that separates a good model from an excellent one, text-embedding-3-large or mxbai-embed-large will still win. It’s also not the best choice if:

  • Your corpus is heavily multilingual (Cohere Embed v3 is still better).

  • You need more than 8192 tokens of context (an unusual case, but it exists).

  • Your team can’t take on running and maintaining a local model.

What it offers (and few models do) is an acceptable combination across four axes at the same time: quality close to the proprietary standard, long context, a genuinely permissive licence, and published training data.

Conclusion

That a model like nomic-embed-text exists, with the full supply chain open and competitive quality, probably matters more in the medium term than its exact position in this month’s benchmark. For a production RAG where the team prefers not to depend on an external API and English is the main language, Nomic becomes the reasonable default choice.

Sources:

  1. Hugging Face — nomic-ai/nomic-embed-text-v1 model card[1]
  2. Nomic AI — Unboxing Nomic Embed v1.5: Resizable Embeddings with Matryoshka Representation Learning[2]
  3. arXiv — Nomic Embed: Training a Reproducible Long Context Text Embedder[3]
  4. Ollama — nomic-embed-text library page[4]

Frequently asked questions

Why does retrieval quality drop when migrating from OpenAI to nomic-embed-text?

Almost always because the task prefixes were omitted; in Nomic they are mandatory, in the style of Cohere Embed v3: documents are encoded with search_document: and queries with search_query:. The OpenAI API has no prefixes, so they tend to be forgotten when porting code, and without them retrieval quality degrades noticeably. With Ollama (ollama pull nomic-embed-text) you get an OpenAI-compatible embeddings endpoint, so changing only the base_url is enough to migrate, but the prefixes are still required.

Can I reduce the vector dimensions to save index space?

Yes, with the v1.5 variant, which adds Matryoshka Representation Learning. The first N components of the vector are useful on their own, so you can truncate the 768 dimensions to 512, 256, 128 or 64 with gradual, predictable degradation. Going from 768 to 256 cuts space by almost 70% at a cost of only 2-3 MTEB points. In pgvector the column is declared as vector(768) with an HNSW index over vector_cosine_ops; if you truncate, adjust the column dimension accordingly.

How many embeddings per second does nomic-embed-text produce on different hardware?

On a 16-core server CPU, around 100 embeddings per second; on an RTX 4090, about 3000; on an Apple Silicon M2 Pro with the MPS backend, about 500. The model has 137M parameters and accepts up to 8192 tokens of context, versus the 512 cap of previous open embeddings such as E5, BGE or GTE. That context lets you embed a full article without chunking. On MTEB it averages around 62.4 points, essentially the same as text-embedding-3-small (62.3) at 768 dimensions instead of 1536.

Sources

  1. nomic-embed-text-v1
  2. v1.5
  3. Nomic technical report
  4. Ollama