Which Embedding Models Are Trained for Quantization
Under Oskar’s post about shrinking an EmbeddingGemma 2 index 16×, Tom Aarsen, who maintains sentence-transformers, asked: “Do you mean that these labs don’t finetune their models to be ‘embedding quantization’-aware?” Several do, mostly the companies that specialize in embeddings. Cohere, Voyage and Jina, whose main product is embeddings, say they train with quantization in the loop, and so do Snowflake and Perplexity; all but Snowflake return int8 or binary vectors directly. Alibaba says the same of Qwen3-VL-Embedding. Google and OpenAI document only dimension truncation for their current embedding models, although a 2025 Google paper did aim a training loss at quantization.
There are two ways to make a stored embedding smaller. Matryoshka truncation keeps the first k dimensions and drops the rest, which works when the model was trained to put the most information up front. Quantization keeps every dimension and stores each number in fewer bits: int8 is 4× smaller than float32, and binary, which keeps only the sign, is 32× smaller. A model can be trained for either. On October 11, 2026, I read the model cards, API docs, launch posts and linked papers for the models below, and counted a model as trained for quantization only where its maker says so.
Quantized vectors and training claims by model
| Model | Quantized vectors | What the maker says about training |
|---|---|---|
| Trained with quantization in the loss | ||
| Cohere Embed v3 (2023) | int8, binary | trained “for int8 and binary precision as well as in a product quantized space” |
| Voyage 4, incl. open-weights voyage-4-nano | int8, uint8, binary | “uses quantization-aware training to enable flexible output data types” |
| Jina v4, v5 | binary (v5 tuned for Elasticsearch’s Better Binary Quantization) | v4: published output-quantization fine-tuning; v5: a regularizer added for binary robustness |
| Snowflake arctic-embed v2 | float output; int4 at 256 dims recommended (128 B) | “quantization-aware embedding training” |
| Perplexity pplx-embed v1 | int8 by default, binary | int8 quantization in every contrastive training stage |
| Qwen3-VL-Embedding (2026) | int8, binary (per the paper) | quantization-aware training with a learned step size; loss on both full-precision and quantized vectors |
| Quantized vectors offered, training not described | ||
| Cohere Embed 5 (Sep 2026) | int8, uint8, binary | launch post makes no training claim |
| Mistral codestral-embed | int8, uint8, binary | none |
| NVIDIA nemotron-3-embed-1b (via NIM) | int8, uint8, binary | no method given |
| Amazon Titan Text Embeddings v2 | binary | none found |
| mixedbread mxbai-embed-large-v1 | int8, binary | binary is sign thresholding plus float rescoring, per their blog |
| Truncation only | ||
| EmbeddingGemma 2, Gemini Embedding 2 | none | Matryoshka dimensions only |
| OpenAI text-embedding-3 | none (float or base64 float) | dimensions parameter only |
| Qwen3-Embedding | none | Matryoshka dimensions only |
| Nomic embed v1.5 | none | Matryoshka only |
| IBM Granite Embedding R2, Amazon Nova embeddings | none | truncation only |
| Neither | ||
| BGE-M3, gte-Qwen2, Microsoft Harrier-OSS-v1, LFM2.5-Embedding | none | fixed-size float output |
The split does not follow the license. Voyage-4-nano, Jina, Snowflake, Perplexity and Qwen3-VL-Embedding all publish weights and still train for quantization. Cohere, Voyage and Jina sell embeddings as their product and quote storage cost to customers: Cohere’s BinaryVectorDB README prices a binary index for its example corpus at $1,359 a year against $43,488 for float32.
EmbeddingGemma’s spread-out loss
The EmbeddingGemma paper (September 2025) adds a “spread-out” loss, adapted from the global orthogonal regularizer, that pushes embeddings to fill the space evenly. The authors say it “intends to ensure that a) the model is robust to quantization (especially embedding quantization)”. The quantization experiments in that paper, and the quantization in Google’s EmbeddingGemma 2 docs, are about the model’s weights, which shrink the model in memory and leave the index the same size. EmbeddingGemma 2’s card offers truncation to 512, 256 or 128 dimensions, “up to 6x”. Google has published no technical report for version 2, so I can’t tell whether the loss carried over. On version 2, storing all 768 dimensions at 2 bits (16× smaller) changed nDCG@10 by −0.002 on SciFact and −0.007 on NFCorpus, both inside the 95% interval of zero; Google’s 128-dimension option (6× smaller) lost 0.056 and 0.065. The quantizer behind those numbers is untrained, so they measure how well EmbeddingGemma 2 tolerates quantization and cannot show whether its training aimed at it.
Training methods
The makers that describe a method do one of two things. Most put the quantizer inside the retrieval loss. Jina’s v4 experiment quantizes the output vectors, passes gradients straight through the rounding step, and fine-tunes on the retrieval objective. Perplexity quantizes to int8 throughout its contrastive training. Qwen3-VL-Embedding computes the loss on both full-precision and quantized vectors and learns the quantizer’s step size along with the model. Cohere says it trained in int8, binary and product-quantized spaces. Jina v5 and EmbeddingGemma instead add a regularizer that spreads vectors evenly over the space, which leaves fewer of them near the boundaries where rounding changes a ranking.
Both approaches keep the objective on search quality, which is where my July post, Don’t Train for Quantization, drew the line. Its title warns against minimizing quantization error directly. I had learned the rotation applied to each vector before rounding: the error went down, but nDCG@10 fell from 0.68 to 0.50, because the learned transform flattened the space. Fine-tuning on retrieval alone, with no compression term, shrank the gap between 1-bit and float32 search from 0.021 to 0.005. Computing that retrieval loss on quantized vectors, as the vendors do, is a step I did not test.
Jina’s ablation
Jina’s v4 post measures training and quantization separately. The vectors are 2048 dimensions with binary documents, on a beta checkpoint, scored as the average over twelve NanoBEIR datasets (small subsets of the BEIR retrieval benchmark) against a float32 baseline of 60.10:
| Training | Query | Change vs float32 |
|---|---|---|
| No fine-tuning | binary | −1.78 |
| No fine-tuning | float | −1.02 |
| Quantization-aware fine-tuning | binary | −0.89 |
| Quantization-aware fine-tuning | float | +0.70 |
Keeping the query in float is the asymmetric scoring from Don’t Binarize the Query. Each change alone recovers under a point; together they recover 2.5 points over plain binary. Jina reports no variance, and its 4- and 8-bit fine-tunes also beat the float baseline (+1.62, +1.56), so some of the gain may be the extra fine-tuning rather than the quantizer. For v5, the regularizer cut the binary loss on MTEB from 3.08 points to 1.90 (Table 6 of the technical report).
When a model ships only float vectors
Three steps, in order:
- Read the model card and the paper it links. I once wrote that H Company’s NeoMME document-retrieval model had no quantization story, when the linked paper’s abstract had one (correction in that post).
- Encode your corpus once in float32 and keep those vectors while you test. Encoding is the slow part; on a 4-core CPU, EmbeddingGemma 2 took 57 minutes for SciFact’s 5,183 documents.
- Quantize the cached vectors several ways (8, 4, 2 and 1 bit, at full and truncated width) and score each against the float32 ranking on your own queries. Each variant takes seconds.
I use remex for the third step. It starts by multiplying every vector by the same random orthogonal matrix. A rotation leaves every inner product unchanged, so rankings are unaffected, and it makes each coordinate behave like a draw from the same Gaussian. remex then rounds each coordinate to fixed Lloyd-Max levels (the levels with least squared error for a Gaussian), computed from the dimension and bit count alone, at 1, 2, 3, 4 or 8 bits, and stores each vector’s exact length in 4 bytes. The quantizer is fixed by dimension, bit count and seed, and no part of it is fit to the corpus, so a new document is encoded the moment it arrives and nothing has to be retrained when the corpus changes. Search keeps the query in float32 and scores it against the stored codes. How remex and remax compress an embedding has the details; remax is its 1-bit sibling, which scans sign bits with XOR and popcount.
For EmbeddingGemma 2 with remex (pip install remex), RemexIndex takes the sentence-transformers model and applies its query and document prompts:
from sentence_transformers import SentenceTransformer
from remex import RemexIndex
# text only: skip the vision and audio encoders
model = SentenceTransformer(
"google/embeddinggemma-2",
config_kwargs={"vision_config": None, "audio_config": None})
# 2 bits per dimension: 192 bytes of codes + 4 for the length, vs 3,072
index = RemexIndex(model, bits=2)
index.add(documents)
index.search("query text", top_k=10)
index.save("corpus-2bit.npz")
At 1 bit, EmbeddingGemma 2 lost measurable quality whichever tool did the encoding: remex with center=True lost 0.012 and 0.021 nDCG@10 on SciFact and NFCorpus, and sentence-transformers’ built-in binary format with a float query lost 0.022 on both. sentence-transformers also ships int8 (quantize_embeddings(…, precision="int8")), which changed nDCG@10 by 0.000 and +0.001 at 4×. remex adds the 2-, 3- and 4-bit widths between int8 and binary, and on this model 2 bits is the smallest width I could not tell apart from float32.
Earlier posts on embedding compression
Model-by-model results:
- A 16× Smaller Index for EmbeddingGemma 2 (Oct 10)
- A 16× Smaller Index for pplx-embed-v2-late (Oct 10), two-bit token vectors for a late-interaction model
- A One-Bit Token Index for NeoMME (Sep 7)
- The Compression Result Is on the Model Card, Below the Fold (Aug 4), bekko
- Quantize, Don’t Truncate (Jul 30), LFM2.5-Embedding
- A 4-Bit Model and a 1-Bit Index (Jul 16), Nemotron-3-Embed-1B
- One Bit Beats Two, Except on Jina (Jun 27)
- When Matryoshka Does Buy You Sign-Bit Compression (May 11), Jina v5 nano
- Matryoshka Doesn’t Buy You Sign-Bit Compression (May 3), Gemini
- Three Gigs to Search a Hundred Million Papers (May 3), SPECTER2
- One Bit Beats Two (May 2), SPECTER2
Scoring and training:
- Don’t Binarize the Query (Jul 30)
- Don’t Train for Quantization (Jul 30)
- Your Embedding Has a Free Coarse Index In It (May 2)
How remex and remax work:
- How remex and remax compress an embedding (Sep 18)
- A donut, a dead end, and codes that finally match (Sep 18)
- Five Differences Between RSLM and remex (Sep 8)
- Building an Empty Index Took Four and a Half Minutes (Aug 3)
- The 1-Bit Search Was Losing to a Float Matmul (Jun 26)
- From YouTube to PyPI in a Day (Apr 2), where it started, from TurboQuant
Search indexes built on them:
- 65 Repositories, 190 Milliseconds, One Bit Per Dimension (Aug 12)
- remax_kb: A Search Index With No Matrix In It (Jun 24)
- remax_kb: Hybrid Search in a File (Jun 20)
Dimension reduction for comparison:
- PCA Next to Quantization (Jul 28)
- Static-PCA Brittleness Has a Compression Rate (Apr 30)
- How Far Does a Basis Travel? (Apr 30)
Limits
This survey reports what makers say. A model can be trained for quantization without its maker saying so, and the claims above come with no shared benchmark: only Jina’s numbers separate what training adds from what quantizing costs. Cohere Embed 5 likely inherits v3’s training, but its launch post doesn’t say. Product pages change; everything here was read on October 11, 2026. The EmbeddingGemma 2 figures are text only, on two small English corpora, and SciFact may be in its training data.