Support on Ko-fi or X Money: @DJLougen
NVIDIA-Nemotron-3.5-Bolt-E4B-MLX
NVIDIA-Nemotron-3.5-Bolt-E4B quantized for MLX — 5 variants, 5.2–15.9 GB (5.19–16.00 bits per weight), measured peak RAM 4.9–14.9 GiB
MLX conversions of nvidia/NVIDIA-Nemotron-3.5-Bolt-E4B-BF16 (itself based on google/gemma-4-E4B-it). Built with mlx-vlm 0.7.10. Each variant ships in its own subfolder (bf16, 8bit, 6bit, dec6-emb4, 4bit).
Downloads
| Variant | Size | Top-1 vs bf16 | Link | Download |
|---|---|---|---|---|
bf16 |
15.9 GB | 100.0% | folder | hf download DJLougen/NVIDIA-Nemotron-3.5-Bolt-E4B-MLX --include "bf16/*" --local-dir bolt-e4b-mlx |
8bit |
8.9 GB | 96.8% | folder | hf download DJLougen/NVIDIA-Nemotron-3.5-Bolt-E4B-MLX --include "8bit/*" --local-dir bolt-e4b-mlx |
6bit |
7.0 GB | 92.5% | folder | hf download DJLougen/NVIDIA-Nemotron-3.5-Bolt-E4B-MLX --include "6bit/*" --local-dir bolt-e4b-mlx |
dec6-emb4 |
6.1 GB | 91.9% | folder | hf download DJLougen/NVIDIA-Nemotron-3.5-Bolt-E4B-MLX --include "dec6-emb4/*" --local-dir bolt-e4b-mlx |
4bit |
5.2 GB | 71.7% | folder | hf download DJLougen/NVIDIA-Nemotron-3.5-Bolt-E4B-MLX --include "4bit/*" --local-dir bolt-e4b-mlx |
Official model source: nvidia/NVIDIA-Nemotron-3.5-Bolt-E4B-BF16 — please credit NVIDIA for the original model.
At a glance
| Variant | Size (GB) | bpw | Peak short (GiB) | Peak 4k ctx (GiB) | KL vs bf16 | Top-1 agree | Judgement | Smoke 17×23 |
|---|---|---|---|---|---|---|---|---|
bf16 |
15.88 | 15.997 | 14.9 | 15.7 | 0.0000 | 100.0% | PERFECT | ✓ 391 |
8bit |
8.88 | 8.947 | 8.4 | 9.2 | 0.0071 | 96.8% | PERFECT | ✓ 391 |
6bit |
7.02 | 7.067 | 6.7 | 7.5 | 0.0399 | 92.5% | GREAT | ✓ 391 |
dec6-emb4 |
6.14 | 6.180 | 5.8 | 6.7 | 0.0534 | 91.9% | GREAT | ✓ 391 |
4bit |
5.15 | 5.187 | 4.9 | 5.8 | 0.7205 | 71.7% | GOOD | ✓ 391 |
Peak memory is the measured MLX peak on an M3 Max (short prompt, and a ~3.7k-token prompt), not a device-fit claim. Judgement labels are computed from the measured top-1 agreement: PERFECT ≥ 95%, GREAT ≥ 80%, GOOD ≥ 50%, MISS = below that or a failed smoke test.
Quick start
pip install mlx-vlm
Subfolder note: mlx-vlm 0.7.10 has no subfolder parameter — mlx_vlm.load() / get_model_path() accept either a local directory or a repo id (+ git revision), so point it at a local clone of one subfolder, or download the subfolder first. Verified end-to-end: hf download DJLougen/NVIDIA-Nemotron-3.5-Bolt-E4B-MLX --include "4bit/*" --local-dir e2e-check then python -m mlx_vlm generate --model e2e-check/4bit --prompt "What is 17*23? Answer with just the number." --max-tokens 8 printed 391.
The quick-start example uses dec6-emb4 — the smallest variant currently rated GREAT on the measured numbers. Swap the subfolder name for any variant in the table above.
hf download DJLougen/NVIDIA-Nemotron-3.5-Bolt-E4B-MLX --include "dec6-emb4/*" --local-dir bolt-e4b-mlx
python -m mlx_vlm generate --model bolt-e4b-mlx/dec6-emb4 \
--prompt "Explain what a QR code encodes." --max-tokens 256
Or from Python: from huggingface_hub import snapshot_download; snapshot_download("DJLougen/NVIDIA-Nemotron-3.5-Bolt-E4B-MLX", allow_patterns=["dec6-emb4/*"]) returns the snapshot dir; the variant then lives in <snapshot>/dec6-emb4.
Exact numbers
Click to expand the full measurement table (KL vs MLX bf16; 8,192 tokens, 16 seqs × 512 tokens, Apple Mac M3 Max 36GB (darwin 27.2.0, arm64), 2026-10-23)| Variant | bpw | KL mean | KL p99 | Top-1 agree (n) | Peak short (GiB) | Peak 4k ctx (GiB) | Gen tok/s | Smoke |
|---|---|---|---|---|---|---|---|---|
bf16 |
15.997 | 0.0000 | 0.0000 | 100.00% (8,192) | 14.85 | 15.72 | 11.4 | 391 |
8bit |
8.947 | 0.0071 | 0.0695 | 96.75% (7,926) | 8.40 | 9.23 | 36.6 | 391 |
6bit |
7.067 | 0.0399 | 0.4007 | 92.47% (7,575) | 6.66 | 7.50 | 46.8 | 391 |
dec6-emb4 |
6.180 | 0.0534 | 0.5143 | 91.87% (7,526) | 5.84 | 6.68 | 53.3 | 391 |
4bit |
5.187 | 0.7205 | 6.0926 | 71.69% (5,873) | 4.93 | 5.76 | 68.1 | 391 |
gen_tok_s is wall-clock generation speed including prefill and warm-up; the decode-only tokens/s reported by mlx-vlm is in the results file (gen_tps_reported). top1_n is the number of positions where the variant's greedy argmax token equals the bf16 argmax token (7,926 of 8,192 for 8bit = the 96.75% shown). Memory basis, verbatim from the results file: active_after_load_gib = mx.get_active_memory() after load; peak_mem_gib = mx.get_peak_memory() after mx.reset_peak_memory() before a 256-token greedy chat-template generation from the short prompt; peak_mem_gib_4k = same after reset, but with a 3683-token templated prompt (+256 generated). Prefill chunked at 2048 tokens.
How it was made
Converted from the upstream BF16 checkpoint with mlx-vlm 0.7.10. The plain variants (8bit, 6bit) are straight affine quantization at group size 64:
python -m mlx_vlm convert --hf-path nvidia/NVIDIA-Nemotron-3.5-Bolt-E4B-BF16 \
--mlx-path out/8bit -q --q-bits 8 --q-group-size 64
# 6bit: --q-bits 6
dec6-emb4 uses a custom quantization predicate (full recipe below; the predicate/eval script ships in results/ of this repo):
custom predicate over mlx_vlm convert(): 6-bit group-64 affine for every tensor under language_model.model.layers.* (attention q/k/v/o, MLP gate/up/down, AND the per-layer PLE gate/projection linears — they live under layers.N and match the predicate); 4-bit group-64 for the only 4 tensors outside layers: embed_tokens, embed_tokens_per_layer, per_layer_model_projection, embed_audio.embedding_projection; vision/audio towers unquantized; lm_head tied to embed_tokens. Quant map: 342x6-bit + 4x4-bit. Build script: results/build_dec6_emb4.py
Quality was measured against the MLX BF16 conversion (not the NVIDIA original) as the comparator: KL divergence and top-1 agreement over 8,192 tokens of text (deterministic 60/20/20 interleave of WikiText-2 test prose, CPython 3.14 stdlib argparse.py source, and GSM8K train questions+answers), plus a greedy 17*23 arithmetic smoke test per variant. The MLX bf16 conversion itself was measured against the upstream transformers BF16: KL 0.0027, top-1 agreement 98.1% on a 2048-token subset — so the quant-KL numbers are real quantization loss, not conversion error. The full comparator path, prompt, and packing details are in card_data.json in this repo.
Recipes we measured and didn't ship
Click to expand: measured variants excluded from this release| Recipe | KL vs bf16 | Top-1 agree | Reason |
|---|---|---|---|
4bit-ple8 |
0.3142 | 80.6% | dominated by dec6-emb4: worse KL (0.314 vs 0.053) at larger size (6.60 vs 6.14 GB) |
mixed_4_8 |
0.6480 | 72.8% | dominated by dec6-emb4: worse KL (0.648 vs 0.053) at larger size (7.18 vs 6.14 GB) |
mixed_4_6 |
0.6535 | 72.9% | dominated by dec6-emb4: worse KL (0.654 vs 0.053) at larger size (6.16 GB vs 6.14, same top-1 tier) |
mixed_3_8 |
4.2948 | 34.8% | 3-bit decoder weights: real quality loss (verified by dequant round-trip) |
mixed_3_6 |
4.3128 | 34.4% | 3-bit decoder weights: real quality loss (verified by dequant round-trip) |
mixed_3_5 |
4.4168 | 33.6% | 3-bit decoder weights: real quality loss (verified by dequant round-trip) |
Limitations
- No task accuracy suite was run — no MMLU, GSM8K, or any benchmark scores.
- Quality is proxied by KL divergence and top-1 agreement vs the MLX BF16 conversion only.
- One machine, one text set, one seed; vision and audio behaviour were not evaluated.
License & credits
Released under the openmdw-1.1 license (inherited from the upstream model). All credit for the original model goes to NVIDIA (nvidia/NVIDIA-Nemotron-3.5-Bolt-E4B-BF16, based on google/gemma-4-E4B-it).