Instructions to use BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision with MLX:
# Make sure mlx-vlm is installed # pip install --upgrade mlx-vlm from mlx_vlm import load, generate from mlx_vlm.prompt_utils import apply_chat_template from mlx_vlm.utils import load_config # Load the model model, processor = load("BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision") config = load_config("BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision") # Prepare input image = ["http://images.cocodataset.org/val2017/000000039769.jpg"] prompt = "Describe this image." # Apply chat template formatted_prompt = apply_chat_template( processor, config, prompt, num_images=1 ) # Generate output output = generate(model, processor, formatted_prompt, image) print(output) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Pi
How to use BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision with Pi:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision"
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "mlx-lm": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Hermes Agent
How to use BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision with Hermes Agent:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision"
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision with OpenClaw:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision"
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision" \ --custom-provider-id mlx-lm \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
borealis2-26b-a4b-preview-MLX-6bit-vision
6-bit MLX quantization of NbAiLab/borealis2-26b-a4b-preview with the vision tower
included, for Apple Silicon. Norwegian-centric preview model from the AI Lab at the National
Library of Norway (Nasjonalbiblioteket).
This is a format conversion, not a new model. Nothing was retrained, fine-tuned or merged.
Want text only? Use
BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bitinstead — same weights without the vision tower, ~1.1 GB smaller and less RAM. This repo is for people who actually want image input.
| Base model | NbAiLab/borealis2-26b-a4b-preview |
| Quantization | 6-bit affine, group size 64 (6.717 bits per weight) |
| On-disk size | 21.6 GB |
| RAM | 28 GB+ |
| Architecture | gemma4 mixture-of-experts — 26B total, ~4B active per token |
| Vision | included (358 vision tensors) |
| Measured speed | ~110 tok/s on an Apple M5 Max (128 GB) |
Building an agent that needs reasoning? LM Studio's MLX runtime cannot enable Gemma 4's reasoning channel — use the GGUF builds for that. Details in Reasoning below. MLX is still the faster and more accurate choice for everything else on Apple Silicon.
Running it
Images (mlx-vlm)
pip install -U mlx-vlm # needs Python >= 3.10
mlx_vlm.generate --model BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision \
--image side-1.png \
--prompt "Skriv av teksten i biletet ordrett." \
--max-tokens 500 --temperature 1.0 --top-p 0.95
Text only (plain mlx-lm also works)
mlx-lm loads this repo fine and simply ignores the vision weights, so you can use it as a drop-in
text model too:
mlx_lm.generate --model BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision \
--prompt "Kva er hovudstaden i Noreg?" --max-tokens 400 \
--temp 1.0 --top-k 64 --top-p 0.95
LM Studio
LM Studio's MLX runtime detects this as a vision model automatically.
OCR quality
Tested on rendered Nynorsk newspaper text, this build transcribed the page exactly, including
æ ø å, 500 000, and correct Nynorsk forms (opnar, gjere, tilgjengeleg, halde fram). It
also answered questions about the image in Nynorsk and switched to Bokmål on request.
For reference, the GGUF Q8_0 build of the same model slipped once on that page (gjøre for
gjere); this MLX build did not.
Important caveat: the vision tower is bit-identical to the google/gemma-4-26B-A4B-it base.
NbAiLab's continued pre-training and SFT were text-only, so image understanding is stock Gemma 4 —
what is different is that the language model describing the image is Norwegian-specialized. Treat
vision as inherited capability, not something tuned for here.
Sampling settings
temperature = 1.0 top_k = 64 top_p = 0.95
From the model's own generation_config.json. Plain temperature sampling without top_k/top_p
produced repetition loops on longer generations in testing.
Turn markers and the reasoning channel
Gemma 4 uses <|turn> … <turn|> turn markers and a <|channel>thought … <channel|> reasoning
channel, not Gemma 2/3's <start_of_turn>. chat_template.jinja here is the original, unmodified.
tokenizer_config.json declares eos_token as <turn|> rather than upstream's <eos>. That is
a deliberate change: tools that read eos_token instead of the eos_token_id array (LM Studio's MLX
runtime among them) otherwise leave a visible <turn|> at the end of every reply. All three stop ids
(1, 106, 50) remain active.
⚠️ Preview quality and safety — please read
- Preview experiment, not a production model. Outputs may be unstable and may hallucinate.
- Not fully safety-aligned. May produce harmful, biased or offensive content, and may follow harmful instructions.
- Not for safety-critical or high-stakes use. Add your own mitigations.
- Early SFT checkpoint, not a final release.
On open-ended long-form prompts the model is unreliable across seeds — sometimes stopping after only a title, sometimes degenerating. Verified identical on unquantized bf16, so it belongs to the preview checkpoint, not this quantization.
License — read before redistributing
Not Apache 2.0. Released under the NB-License 1.0, an adaptation of Apache 2.0 with additional use-based restrictions. You must not:
- intentionally use the model to recreate data it was trained on; or
- use the model or its output to power end-user services whose primary purpose is giving access to licensed press publications contained in the training data.
Redistribution is permitted but the license travels with the model. LICENSE and LICENSE_FAQ.pdf
are included here verbatim from the source.
Reasoning — read this before choosing a build
This model can reason, but it is off by default, and which runtime you use decides whether you can turn it on at all.
Upstream's chat_template.jinja sets enable_thinking | default(false), which pre-closes the
thought channel with <|channel>thought\n<channel|> so the model answers immediately. Setting
enable_thinking=true injects <|turn>system\n<|think|>\n<turn|> and the model reasons first.
What actually works — measured, same prompt and settings on one machine
| Runtime | Reasoning | Notes |
|---|---|---|
llama-server / llama-cli with --jinja --reasoning on |
✅ | reasoning in reasoning_content, answer in content, no leaked markers |
| LM Studio + GGUF | ✅ | works out of the box, no configuration — measured 426 reasoning tokens |
| LM Studio + MLX | ❌ | not possible — see below |
| mlx-lm, Python API | ✅ | tok.apply_chat_template(msgs, add_generation_prompt=True, enable_thinking=True) |
mlx_lm.generate / mlx_lm.server CLI flags |
⚠️ | --chat-template-config / --chat-template-args / per-request chat_template_kwargs had no effect in mlx-lm 0.31.3 — use the Python API |
LM Studio + MLX cannot reason
llama.cpp implements Gemma 4's reasoning channel at the architecture level — the same code that
registers <eos>, <turn|> and <|tool_response|> as end-of-generation for gemma4. LM Studio's
llama.cpp runtime inherits that and folds reasoning into a collapsible block automatically.
LM Studio's MLX runtime has no equivalent, so it never enables thinking and never parses the channel. Identical prompt and sampling, same machine:
| Build | reasoning_tokens |
|---|---|
| GGUF Q6_K | 426 |
| MLX 8-bit | 0 |
This affects every gemma4 MLX model in LM Studio, not just this one. It is a runtime gap, not
something a quantization or a model.yaml can fix — setting enable_thinking in the template only
makes the raw <channel|> markers leak into the reply, because nothing parses them.
If you want reasoning — for agents especially — use the GGUF builds. The MLX builds remain the better choice for everything else on Apple Silicon: faster (94–110 vs 75–109 tok/s) and more accurate on Norwegian OCR.
# recommended for agents
llama-server -m borealis2-26b-a4b-preview-Q6_K.gguf \
--jinja --reasoning on -ngl 99 -fa on -c 8192 \
--temp 1.0 --top-k 64 --top-p 0.95
Budget tokens generously — the reasoning block is often longer than the answer, and a truncated one
leaves content empty. The model tends to reason in English even when answering in Norwegian;
that is upstream behaviour.
llama-serverparses replies with a strictpeg-gemma4grammar and returns HTTP 500 if a generation is cut off mid-structure. If you see "output that does not match the expected peg-gemma4 format", raisemax_tokensrather than assuming the quant is broken.
All builds compared
Same model, same prompts, same machine (Apple M5 Max, 128 GB). Generation tok/s; quality is mean NLL on held-out Bokmål vs an unquantized bf16 MLX reference (lower is better).
| Build | Format | Size | tok/s | Bokmål NLL | Vision | Notes |
|---|---|---|---|---|---|---|
| MLX-8bit-vision | MLX | 28.0 GB | 95 | 1.635 | ✓ | Best overall on Apple Silicon |
| MLX-8bit | MLX | 26.8 GB | 94 | 1.635 | — | Same, ~1.1 GB less RAM |
| MLX-6bit-vision | MLX | 21.7 GB | 110 | 1.668 | ✓ | Fastest of the set |
| MLX-6bit | MLX | 20.5 GB | 108 | 1.668 | — | Fastest text-only |
| GGUF Q8_0 | GGUF | 26.9 GB | 75 | — | ✓* | Portable, effectively lossless |
| GGUF Q6_K | GGUF | 22.6 GB | 100 | — | ✓* | Norwegian imatrix |
| GGUF Q4_K_M | GGUF | 16.8 GB | 109 | — | ✓* | Smallest working build |
| (bf16 reference) | MLX | 47 GB | — | 1.630 | — | Not published; used for validation |
* GGUF vision needs the separate mmproj file from the GGUF repo.
On Apple Silicon MLX is meaningfully faster than GGUF at the same precision — 94 vs 75 tok/s at
8-bit, on identical hardware and prompts. MLX also won the Nynorsk OCR comparison: it transcribed
gjere correctly where GGUF Q8_0 produced bokmål gjøre.
GGUF is the right choice if you are not on Apple Silicon, or if you want the smallest build —
Q4_K_M at 16.8 GB has no MLX equivalent, because uniform 4-bit MLX quantization breaks this model
(NLL 2.47 → 9.50) while llama.cpp's K-quants protect the attention and dense-MLP tensors that are
the sensitive ones here.
Credit
Borealis 2 was built by the AI Lab at the National Library of Norway (Nasjonalbiblioteket), from
google/gemma-4-26B-A4B-it, continued pre-trained on Aurora and SFT'd on
NbAiLab/aurora-sft-2606.
All credit belongs to them — https://ai.nb.no · original repo · ailab@nb.no. I only ran the format conversion.
Conversion details
mlx_vlm convert --hf-path <local copy of NbAiLab/borealis2-26b-a4b-preview> \
-q --q-bits 6 --mlx-path borealis2-26b-a4b-preview-MLX-6bit-vision
mlx-vlm0.6.15,mlx0.32.1,transformers5.15.1- The upstream repo ships no
preprocessor_config.json;mlx-vlmsupplies its own gemma4 processor, so nothing about image preprocessing was guessed. (This vision tower standardizes internally —vision_config.standardize: truewithstd_bias/std_scalein the weights.)
Other builds: MLX text-only · GGUF for llama.cpp
- Downloads last month
- 102
6-bit
Model tree for BobTheShoplifter/borealis2-26b-a4b-preview-MLX-6bit-vision
Base model
google/gemma-4-26B-A4B