Instructions to use janihal/embeddinggemma-300m-8bit-mlx with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use janihal/embeddinggemma-300m-8bit-mlx with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir embeddinggemma-300m-8bit-mlx janihal/embeddinggemma-300m-8bit-mlx
- sentence-transformers
How to use janihal/embeddinggemma-300m-8bit-mlx with sentence-transformers:
from sentence_transformers import SentenceTransformer model = SentenceTransformer("janihal/embeddinggemma-300m-8bit-mlx") sentences = [ "The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium." ] embeddings = model.encode(sentences) similarities = model.similarity(embeddings, embeddings) print(similarities.shape) # [3, 3] - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
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-mlxsibling or the llama.cppggml-orgGGUF 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 vanillasentence-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
Quantized
Model tree for janihal/embeddinggemma-300m-8bit-mlx
Base model
google/embeddinggemma-300m