embeddinggemma-300m β€” MLX 8-bit (compact)

An 8-bit (affine, group size 64) MLX quantization of google/embeddinggemma-300m, produced with mlx-embeddings. Runs the full EmbeddingGemma pipeline (mean-pool β†’ 2Γ— Dense β†’ L2-normalize), 768-dim output, Matryoshka truncation to 512/256/128 supported.

Weights on disk 344 MB (all Linear + Embedding layers int8, scales/norms fp16)
Quantization affine, bits=8, group_size=64, every Linear + the token-embedding table
Backend Apple-Silicon GPU via MLX
Sibling embeddinggemma-300m-8bit-hi-mlx β€” larger (534 MB) but matches FP32 accuracy exactly

Which one do I want? This model is the smallest option and is fine for most use β€” it costs about βˆ’0.2 pp STS / βˆ’0.5 pp nDCG vs full precision (see below). If you want zero measurable accuracy loss, use the -hi-mlx sibling or the llama.cpp ggml-org GGUF instead.

Usage

pip install mlx-embeddings
import mlx.core as mx
from mlx_embeddings.utils import load

model, tokenizer = load("janihal/embeddinggemma-300m-8bit-mlx")

# EmbeddingGemma prompt prefixes matter:
QUERY = "task: search result | query: "
DOC   = "title: none | text: "

texts = [QUERY + "What is the capital of France?",
         DOC   + "Paris is the capital and most populous city of France."]

enc = tokenizer.batch_encode_plus(texts, return_tensors="mlx", padding=True)
out = model(enc["input_ids"], attention_mask=enc["attention_mask"])
emb = out.text_embeds                    # (2, 768), already mean-pooled + L2-normalized
sim = float((emb[0] * emb[1]).sum())     # cosine similarity

Prompt templates for other tasks (from config_sentence_transformers.json): Retrieval-query β†’ task: search result | query: Β· Retrieval-document β†’ title: none | text: Β· STS β†’ task: sentence similarity | query: Β· Classification β†’ task: classification | query: Β· Clustering β†’ task: clustering | query: .

How it was produced

python -m mlx_embeddings.convert \
  --hf-path google/embeddinggemma-300m \
  --mlx-path embeddinggemma-300m-q8 \
  -q --q-bits 8 --q-group-size 64 --q-mode affine

Evaluation

All numbers below are from a controlled comparison on one Apple M5 Max. Reference = the same model converted to MLX float32 (no quantization). Quantized candidates are scored against it on two public benchmarks and on raw embedding agreement.

  • STS: STS-Benchmark test, 1379 pairs β†’ Spearman(cosine, gold 0–5).
  • Retrieval: NFCorpus (BEIR) test, 323 queries Γ— 3633 docs β†’ nDCG@10.
  • mean cos vs FP32: mean cosine between this model's output vectors and the FP32 reference's, over all 6714 benchmark texts.
  • Ξ” confidence intervals are paired bootstrap, 2000 resamples.

Accuracy

Model Format Size STS Spearman Ξ”STS (95% CI) NFCorpus nDCG@10 Ξ”nDCG (95% CI) mean cos vs FP32
google/embeddinggemma-300m (MLX fp32) fp32 1.2 GB 88.18 β€” 39.06 β€” 1.0000
➀ this β€” MLX 8-bit, all-linears int8 g64 344 MB 87.98 βˆ’0.19 [βˆ’0.44, +0.05] 38.57 βˆ’0.49 [βˆ’1.05, +0.05] 0.9918
MLX 8-bit, blocks-only (hi-mlx) int8 g32 + fp16 embed 534 MB 88.24 +0.07 [βˆ’0.06, +0.19] 39.00 βˆ’0.07 [βˆ’0.36, +0.24] 0.9942
llama.cpp GGUF Q8_0 β€” ggml-org Q8_0 318 MB 88.17 βˆ’0.01 [βˆ’0.02, +0.01] 39.10 +0.04 [βˆ’0.27, +0.37] 0.9987
llama.cpp GGUF Q8_0 β€” unsloth (QAT) Q8_0 314 MB 88.63 +0.45 [+0.03, +0.91] 38.53 βˆ’0.52 [βˆ’1.44, +0.46] ~0 †

† The unsloth GGUF is built from Google's QAT checkpoint and omits the two Dense projection layers (converted without --sentence-transformers-dense-modules). Its output is the pooled backbone in a different vector space β€” hence ~0 cosine to the reference even though its STS score is fine. Not a like-for-like point.

Read: this compact model's accuracy loss is small but real and consistently negative (STS, nDCG, and embedding cosine all point the same way). The ggml-org GGUF and the -hi-mlx sibling are effectively lossless (Ξ” CIs cover 0).

Weight-space quantization error

Param-weighted relative RMSE of the de-quantized weights vs the FP32 base:

Source relRMSE vs FP32
MLX 8-bit, all-linears (this) 0.59 %
MLX 8-bit, blocks-only (hi-mlx) 0.49 %
GGUF Q8_0 (ggml-org) 0.60 %
GGUF Q8_0 (unsloth, QAT) 2.75 % (different checkpoint)

MLX affine-8bit and llama.cpp Q8_0 quantize the weights equally well. The end-to-end accuracy gap of this model comes almost entirely from 8-bit quantizing the token-embedding table (65 % of the parameters); keeping it in float precision β€” what the -hi-mlx sibling does β€” removes the gap.

Performance (Apple M5 Max, both stacks on the Metal GPU)

Stack Corpus throughput (3633 docs, 1.26 M tok) Query latency, batch 1 (p50) Model load Peak RAM
this β€” MLX 8-bit 253 docs/s Β· 87 k tok/s 3.2 ms 1.1 s 1.6 GB
MLX 8-bit blocks-only (hi-mlx) 249 docs/s Β· 86 k tok/s 3.2 ms 1.1 s 1.8 GB
llama.cpp GGUF Q8_0 (ggml-org) 137 docs/s Β· 47 k tok/s ~5 ms Β· 0.4 s 3.3 GB

Β· llama.cpp latency measured through llama-server and includes a localhost HTTP round-trip. Its model load is ~3Γ— faster than MLX (no Python import).

Read: on this machine MLX is ~1.8Γ— faster for bulk embedding and ~1.3–1.5Γ— faster per query than the GGUF, at roughly half the RAM. MLX throughput peaks around batch 16–32 (batch 64 drops to 220 docs/s from padding waste). Single-run numbers, Β±10 %.

Compared to other embedding models

Same benchmark (STS-B test, NFCorpus test) and same Apple M5 Max. MLX rows run on MLX/Metal, GGUF rows on llama.cpp/Metal. docs/s = wall time to embed the 3633-document NFCorpus corpus; query latency is single-text, warm.

Model Params STS ρ nDCG@10 docs/s Query p50 Peak RAM
EmbeddingGemma-300m β€” FP32 reference 0.3 B 88.2 39.1 β€” β€” β€”
➀ this β€” MLX 8-bit 0.3 B 88.0 38.6 253 3.2 ms 1.6 GB
EmbeddingGemma-300m β€” MLX 8-bit-hi (sibling) 0.3 B 88.2 39.0 249 3.2 ms 1.8 GB
EmbeddingGemma-300m β€” GGUF Q8_0 (llama.cpp) 0.3 B 88.2 39.1 137 ~5 ms 3.3 GB
Qwen3-Embedding-0.6B β€” GGUF Q8_0 0.6 B 91.3 36.7 50 4.0 ms 2.5 GB
Qwen3-Embedding-4B β€” GGUF Q8_0 4 B 93.6 40.8 10 12.6 ms 6.0 GB
Qwen3-VL-Embedding-2B β€” GGUF Q8_0 2 B 86.6 35.7 23 6.5 ms 3.7 GB

Read: only Qwen3-Embedding-4B clearly out-retrieves EmbeddingGemma-300m (nDCG 40.8 vs ~39) β€” at ~25Γ— the embedding time and 4Γ— the RAM. Qwen3-Embedding-0.6B is a stronger pure-similarity model (STS 91.3) but a weaker retriever (nDCG 36.7) and ~5Γ— slower. Qwen3-VL-Embedding-2B (multimodal) is weaker than EmbeddingGemma on text on both axes. For retrieval / RAG at this size, EmbeddingGemma-300m is the best accuracy per byte and per second.

(Nemotron-3-Embed-1B GGUF did not produce usable embeddings through this llama.cpp build and is omitted.)

Caveats

  • "FP32 reference" is the MLX implementation; the GGUFs run in llama.cpp, so a small cross-framework gap (~0.1–0.2 %) is folded into their numbers.
  • One benchmark pair (STS + one retrieval set). Not a full MTEB run.
  • Performance measured on M5 Max; ratios shift with hardware, batch size, and text length. llama.cpp likely has some tuning headroom (-fa, threads, ubatch).
  • Loadable only with mlx-embeddings, not vanilla sentence-transformers.

License & attribution

Derived from google/embeddinggemma-300m (Google DeepMind) by post-training weight quantization only β€” no fine-tuning.

Use is governed by the Gemma Terms of Use and the Gemma Prohibited Use Policy. This is a modified version of EmbeddingGemma; the same terms and use restrictions apply to this model and its outputs.

Quantization tooling: mlx-embeddings Β· MLX. GGUF baselines: ggml-org/embeddinggemma-300M-GGUF, unsloth/embeddinggemma-300M-GGUF.

Downloads last month
37
Safetensors
Model size
0.3B params
Tensor type
U32
Β·
F16
Β·
MLX
Hardware compatibility
Log In to add your hardware

Quantized

Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for janihal/embeddinggemma-300m-8bit-mlx

Quantized
(310)
this model