Instructions to use ironbcc/Qwen3-Embedding-4B-NVFP4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ironbcc/Qwen3-Embedding-4B-NVFP4 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="ironbcc/Qwen3-Embedding-4B-NVFP4")# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("ironbcc/Qwen3-Embedding-4B-NVFP4") model = AutoModelForCausalLM.from_pretrained("ironbcc/Qwen3-Embedding-4B-NVFP4", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Qwen3-Embedding-4B-NVFP4
Qwen/Qwen3-Embedding-4B quantized to NVFP4 (4-bit weights and 4-bit activations) with llm-compressor, for serving on NVIDIA Blackwell (SM120) under vLLM. Built to back a scripture-retrieval application, so it is additionally patched to expose Matryoshka output dimensions and serve 768-dim vectors directly.
| Base model | Qwen/Qwen3-Embedding-4B (Apache-2.0) |
| Quantization | NVFP4, W4A4 |
| Size on disk | 2.7 GB (from 7.6 GB BF16, ~2.8x smaller) |
| Native embedding dim | 2560 (Matryoshka rungs down to 128) |
| Tooling | llm-compressor 0.12.0.1, compressed-tensors 0.17.1 |
| Checkpoint format | nvfp4-pack-quantized |
| Verified on | vLLM 0.26.0, torch 2.11.0+cu130, RTX PRO 6000 Blackwell |
Quantization details
QuantizationModifier(targets="Linear", scheme="NVFP4", ignore=["lm_head"])
- Weights — FP4,
group_size=16,strategy=tensor_group, symmetric, FP8 (e4m3) group scales. - Activations — FP4,
group_size=16,dynamic="local"per-group scales with a static global FP8 scale fitted from calibration data. This is why the calibration set matters: W4A4 has a data-dependent activation scale, unlike a weights-only scheme. - Excluded —
lm_headonly. The model is dense (no MoE), so no router/gate exclusions apply.lm_headis unused by the pooling runner and is tied to the input embeddings. - Architecture is
Qwen3ForCausalLM, so it loads withAutoModelForCausalLM; the embedding behaviour comes from last-token pooling, not a separate head.
Calibration
512 samples, max_seq_length=512, English only:
| Source | Samples | Shape |
|---|---|---|
| HuggingFaceH4/ultrachat_200k (MIT) | 256 | instruction / dialogue |
| google-research-datasets/natural_questions (CC BY-SA 3.0) | 128 | questions, carrying the query instruction prefix |
| natural_questions | 128 | passages, bare |
Query-shaped samples carry the model's real query prefix (below) and passages do not, so the calibrated activation scales match the asymmetric way the model is used at inference.
Matryoshka patch — read this if you fork the recipe
Upstream Qwen3-Embedding-4B supports MRL truncation but its config.json declares
neither is_matryoshka nor matryoshka_dimensions. vLLM refuses the dimensions
pooling parameter unless ModelConfig.is_matryoshka is true, so this checkpoint adds:
{ "is_matryoshka": true,
"matryoshka_dimensions": [128, 256, 512, 768, 1024, 1536, 2048, 2560] }
vLLM truncates after pooling and renormalizes, so a 768-dim response is unit-norm.
Serving with vLLM
vllm serve ironbcc/Qwen3-Embedding-4B-NVFP4 \
--served-model-name qwen3-embedding-4b \
--runner pooling --convert embed \
--pooler-config '{"dimensions": 768}' \
--max-model-len 8192
--pooler-config '{"dimensions": 768}' makes every response 768-dim, so OpenAI-compatible
clients need no dimensions parameter. Drop it to get the native 2560.
Measured on one Blackwell GPU at gpu_memory_utilization=0.09 (~8.8 GB resident): a 64-text
batch (1654 prompt tokens) returns in 57-59 ms, about 0.9 ms/text.
Asymmetric use matters
Embed documents bare, and prefix queries with the string from the base model's
config_sentence_transformers.json:
Instruct: Given a web search query, retrieve relevant passages that answer the query
Query: {your query}
This is not cosmetic. On a 31k-verse Bible corpus, "How can I be saved?" retrieves
Psalm 55:16 / Genesis 49:18 unprefixed versus Acts 15:11 / Romans 10:10 / Titus 3:5
prefixed; "I am so lonely" goes from Job 7:19 to Psalm 25:16 / 102:7 / 88:8.
Official MTEB subset evaluation
Official MTEB 2.18.13 evaluators, five complete English test tasks (ArguAna, ArXivHierarchicalClusteringP2P, Banking77Classification.v2, BIOSSES, CQADupstackGamingRetrieval) — a targeted subset, not the full MTEB English v2 suite. Evaluated against the BF16 original and the W4A16 sibling, at every Matryoshka width used in production, same protocol for all three.
TL;DR:
2.7GB weights (vs ~8GB BF16, ~3x smaller), weights and activations in FP4, at **97-98% of BF16 MTEB score** from 768 to 2048 dims. The W4A16 sibling trades the activation-speed gain for ~99% BF16 quality instead.
Average score across the 5 tasks:
| Dim | BF16 (baseline) | W4A16 | W4A4 (this model) |
|---|---|---|---|
| 768 | 0.7329 | 0.7241 (98.8%) | 0.7131 (97.3%) |
| 1024 | 0.7335 | 0.7258 (99.0%) | 0.7169 (97.7%) |
| 1536 | 0.7340 | 0.7266 (99.0%) | 0.7157 (97.5%) |
| 2048 | 0.7351 | 0.7274 (99.0%) | 0.7203 (98.0%) |
Per-task scores at each dimension
| Task | Dim | BF16 | W4A16 | W4A4 |
|---|---|---|---|---|
| ArguAna | 768 | 0.7333 | 0.7114 | 0.6904 |
| ArguAna | 1024 | 0.7390 | 0.7159 | 0.6974 |
| ArguAna | 1536 | 0.7377 | 0.7150 | 0.6960 |
| ArguAna | 2048 | 0.7355 | 0.7158 | 0.6962 |
| ArXivHierarchicalClusteringP2P | 768 | 0.5936 | 0.5904 | 0.5897 |
| ArXivHierarchicalClusteringP2P | 1024 | 0.5871 | 0.5846 | 0.5866 |
| ArXivHierarchicalClusteringP2P | 1536 | 0.5851 | 0.5895 | 0.5802 |
| ArXivHierarchicalClusteringP2P | 2048 | 0.5897 | 0.5871 | 0.5913 |
| Banking77Classification.v2 | 768 | 0.8435 | 0.8404 | 0.8323 |
| Banking77Classification.v2 | 1024 | 0.8442 | 0.8408 | 0.8314 |
| Banking77Classification.v2 | 1536 | 0.8457 | 0.8410 | 0.8337 |
| Banking77Classification.v2 | 2048 | 0.8473 | 0.8418 | 0.8348 |
| BIOSSES | 768 | 0.8258 | 0.8278 | 0.8169 |
| BIOSSES | 1024 | 0.8252 | 0.8289 | 0.8232 |
| BIOSSES | 1536 | 0.8248 | 0.8248 | 0.8194 |
| BIOSSES | 2048 | 0.8262 | 0.8300 | 0.8282 |
| CQADupstackGamingRetrieval | 768 | 0.6681 | 0.6503 | 0.6360 |
| CQADupstackGamingRetrieval | 1024 | 0.6722 | 0.6588 | 0.6458 |
| CQADupstackGamingRetrieval | 1536 | 0.6767 | 0.6626 | 0.6491 |
| CQADupstackGamingRetrieval | 2048 | 0.6767 | 0.6621 | 0.6509 |
Retrieval tasks (ArguAna, CQADupstackGamingRetrieval) take the biggest hit under W4A4 (~4-5% relative on CQADupstackGamingRetrieval); clustering and classification stay close to BF16. Raw embedding cosine similarity vs BF16 (separate 100-text check, not a task score): mean ~0.95-0.96 across dims.
Matched protocol
- Official MTEB task evaluators, complete
testsplits, dataset revisions pinned in the uploaded manifests. - 64,880 encoded texts per arm; 24 concurrent request workers, batch size 32.
- Retrieval instruction applied only to queries; documents remained bare.
- Inputs longer than 8,192 tokens were right-truncated identically across all three arms.
- MTEB cache disabled, isolated per-arm prediction artifacts, no result exceptions.
Raw scores:
benchmarks/mteb_dims_comparison/all_scores.json.
Downstream check on the target application: with W4A4 vectors, dense retrieval over a
31,086-verse corpus returns John.3.16 as top-1 for "For God so loved the world"
(cos 0.7865) and Psalm.23.1 for "the Lord is my shepherd" (0.7936).
Limitations
- Reported MTEB results cover five English tasks, not the full English v2 or multilingual suites; do not treat them as a leaderboard aggregate.
- BF16 baseline is now included (see above): W4A4 retains ~97-98% of BF16 average score across the tested widths, versus ~99% for W4A16.
- W4A4 is lossy in a way that shows up directly in embedding space — see above. Validate on your own retrieval set before trusting it in production.
- Blackwell/SM120-oriented. FP4 activation kernels need recent flashinfer; on vLLM 0.26.0 the
flashinfer-python==0.6.14pin has no matchingflashinfer-cubinrelease, which may requireFLASHINFER_DISABLE_VERSION_CHECK=1. - English calibration only. For multilingual retrieval, recalibrate on your languages.
- Inherits the base model's Apache-2.0 license and its biases.
Provenance
Quantized with llm-compressor 0.12.0.1 in an environment isolated from the serving stack
(transformers 5.10.1, torch 2.11.0+cu130). Conversion and calibration ran on a single
Blackwell GPU. recipe.yaml and the oneshot_*.log in this repo are the actual artifacts
emitted by the run.
- Downloads last month
- 35
Model tree for ironbcc/Qwen3-Embedding-4B-NVFP4
Evaluation results
- nDCG@10 on MTEB ArguAnatest set self-reported0.690
- V-measure on MTEB ArXiv Hierarchical Clustering P2Ptest set self-reported0.590
- Accuracy on MTEB Banking77 Classification v2test set self-reported0.832
- Cosine Spearman on MTEB BIOSSEStest set self-reported0.817
- nDCG@10 on MTEB CQADupstack Gaming Retrievaltest set self-reported0.636