Views
No views yet
⚠️ This architecture needs a loader that knows about the loop
num_loops = 2: the same 22 decoder layers run twice over shared weights, for an effective depth of 44. Two consequences a generic loader gets wrong:
- The KV cache has 44 slots, not 22 (slot =
layer_idx + loop_idx * num_hidden_layers). A 22-slot cache does not crash — it emits fluent, confident, wrong tokens from the first one. This is verified with a negative control, not theory.- The final norm runs at the end of every loop, not once at the end (
skip_loop_final_norm = false). Loop 0's normed output is loop 1's input.mlx_lm0.31.x has nonanbeigemodel class, somlx_lm.generatealone will not load this bundle. Use a runtime that implements the loop (see Usage).
| Field | Value |
|---|---|
| Source | Nanbeige/Nanbeige4.2-3B @ fab06df (Apache-2.0) |
| Architecture | nanbeige — 22 layers × 2 loops (effective depth 44), 4.17B params, 256K ctx |
| On-disk size | 3.6 GB (1 shard) |
| Quantization | attention 8-bit · MLP 6-bit · embeddings/lm_head 6-bit, group size 32 |
| Norms, router bias | fp16 passthrough — plain Llama RMSNorm, no +1 shift |
| Attention | 48 heads / 8 KV heads (GQA), head_dim 128 — note n_heads × head_dim (6144) ≠ hidden_size (3072) |
| RoPE | θ = 7e7, NeoX half-rotation, full 128 dims, no scaling |
| Modality | text-only (verified from the tensor index) |
| Metric | Thinking on | Thinking off |
|---|---|---|
| Decode | 29.3 tok/s | 38.0 tok/s |
| Peak memory | 4.5 GB | 3.9 GB |
| Bundle | Size | Top-1 agreement vs bf16 | Mean KL | Max KL | Decode (thinking) |
|---|---|---|---|---|---|
Nanbeige4.2-3B-JANG_6M | 3.6 GB | 5/5 | 0.0010 | 0.0030 | 29.3 tok/s |
Nanbeige4.2-3B-JANG_4M | 2.9 GB | 5/5 | 0.0192 | 0.0398 | 44.7 tok/s |
Nanbeige4.2-3B-MXFP8 | 4.0 GB | 4/5 | 0.1446 | 0.6844 | 34.6 tok/s |
<think>\n; only enable_thinking=False prefills a closed <think>\n\n</think>\n\n.preserve_thinking controls whether previous turns' reasoning is kept. The template's default is to preserve; the vendor recommends False for general chat and True for multi-turn tool use and code-agent workflows.tool_call_format="xml" (the vendor's recommended format); json is supported for compatibility.<|im_start|> (id 166100 = bos_token) and the tokenizer's post-processor prepends another. Tokenize the rendered template with add_special_tokens=False.eos_token_id = 166101 (<|im_end|>).generation_config.json, matching the model card): temperature 0.6, top_p 0.95, top_k 20. The vendor suggests temperature 1.0 for agentic and tool-use tasks. The same values are stamped in jang_config.chat.sampling_defaults, and the two files are checked against each other at build time.{bits, group_size, mode} map in config.json[quantization] — any loader must honor those overrides. It needs the nanbeige looped model class, which registers into mlx_lm:1from jang_tools.nanbeige import mlx_register # registers the looped nanbeige class
2from mlx_lm import load, generate
3from mlx_lm.sample_utils import make_sampler
4
5model, tok = load("OsaurusAI/Nanbeige4.2-3B-JANG_6M")
6prompt = tok.apply_chat_template(
7 [{"role": "user", "content": "Which number is bigger, 9.11 or 9.8?"}],
8 add_generation_prompt=True, tokenize=False,
9)
10ids = tok.encode(prompt, add_special_tokens=False) # template already emits BOS
11print(generate(model, tok, prompt=ids, max_tokens=1024,
12 sampler=make_sampler(temp=0.6, top_p=0.95, top_k=20)))