Views
No views yet
| Base model | Nanbeige4.2-3B (Looped Transformer, nanbeige arch, 22 unique layers × 2 loops, ~4B total / 3B non-embedding params) |
| Quantization | MX FP4 (micro-scaled 4-bit float) |
| Bits per weight | 4.250 |
| Disk size | 2.1 GB (from ~7.8 GB bf16) |
| Format | MLX (safetensors) |
model_type: "nanbeige"):
the same 22 decoder layers run twice (num_loops: 2), with a full RMSNorm applied
between and after each pass — a way to add effective depth without adding
parameters (3B non-embedding params, ~4B total). This architecture had no mlx-lm
support at all prior to this release. A minimal, from-scratch MLX port
(mlx_lm/models/nanbeige.py) was written for this conversion, implementing the
loop mechanism with per-loop KV cache isolation (each loop's attention only
attends to its own loop's keys/values) and covering the subset of the (very large)
upstream NanbeigeConfig that this checkpoint actually uses — the full reference
implementation also defines n-gram embeddings, hyper-connections, and
depth-attention, none of which are active here (num_loops=2 is the only
non-default architectural flag Nanbeige4.2-3B sets).mlx-lm release. A PR adding this support is
open against ml-explore/mlx-lm. Until it
merges, install mlx-lm from the PR branch to load this model:pip install git+https://github.com/SahilChachra/mlx-lm.git@add-nanbeige-support1from mlx_lm import load, generate
2
3model, tokenizer = load("sahilchachra/nanbeige4.2-3b-mxfp4-mlx")
4
5messages = [{"role": "user", "content": "Which number is bigger, 9.11 or 9.8?"}]
6prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
7out = generate(model, tokenizer, prompt=prompt, max_tokens=2048, verbose=False)
8print(out)enable_thinking (default on — set False for
non-thinking mode) and preserve_thinking (whether prior turns' reasoning is
kept in multi-turn contexts; the base model card recommends False for general
chat/QA and True for multi-turn tool-use/agentic workflows). Per the base
model's recommendations: temperature 1.0 for agentic/tool-use tasks, 0.6 for
reasoning/chat tasks; eos_token_id is 166101.1mlx_lm.generate --model sahilchachra/nanbeige4.2-3b-mxfp4-mlx \
2 --prompt "Which number is bigger, 9.11 or 9.8?" \
3 --max-tokens 2048mlx_lm.generate through the model's chat template, on an Apple M4 Pro:Prompt: "Explain the difference between TCP and UDP in two sentences."
Output (mxfp4): "...We need to provide an explanation that is concise, exactly two
sentences... TCP (Transmission Control Protocol) is a connection-oriented, reliable,
error-correcting protocol... UDP (User Datagram Protocol) is a connectionless,
unreliable, but lightweight protocol..."Prompt: "Write a haiku about the ocean at night."
Output (mxfp8): "...haiku structure: three lines with syllable counts: 5, 7, 5...
Elements to include: night setting, ocean imagery (waves, stars reflected,
moonlight, darkness)..."mlx_lm.generate on 5 GPQA-Diamond prompts (the same benchmark
the base model reports its 87.4 score on), Apple M4 Pro, max_tokens=400:| Variant | Bits/weight | Disk size | Decode speed | vs FP16 |
|---|---|---|---|---|
| fp16 | 16 | 7.8 GB | 16.6 tok/s | baseline |
| mxfp4 | 4.250 | 2.1 GB | 50.0 tok/s | 3.0x |
| int4 | 4.500 | 2.2 GB | 49.2 tok/s | 3.0x |
| mxfp8 | 8.250 | 4.0 GB | 30.2 tok/s | 1.8x |
| int8 | 8.500 | 4.2 GB | 29.7 tok/s | 1.8x |
mlx-lm (see "New architecture
support" below). That port was validated against the official
modeling_nanbeige.py reference implementation (run via transformers,
float32) on held-out prompts: computed logits from both implementations for
the same inputs and compared next-token predictions and full logit
distributions. After aligning RoPE frequency initialization between the two
implementations, results matched closely — logit cosine similarity ≥0.9999
and identical next-token predictions on every test prompt.mlx-optiq package,
which wasn't available in the conversion environment.