Instructions to use decent-jawfish/bonsai-2-27b-mtp with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use decent-jawfish/bonsai-2-27b-mtp with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0 # Run inference directly in the terminal: llama cli -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0 # Run inference directly in the terminal: llama cli -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0
Build from source code
git clone https://github.com/ggml-org/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-app # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama serve -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0 # Run inference directly in the terminal: ./build/bin/llama cli -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0
Use Docker
docker model run hf.co/decent-jawfish/bonsai-2-27b-mtp:Q2_0
- Llama new
- LM Studio
- Jan
- vLLM
How to use decent-jawfish/bonsai-2-27b-mtp with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "decent-jawfish/bonsai-2-27b-mtp" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "decent-jawfish/bonsai-2-27b-mtp", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/decent-jawfish/bonsai-2-27b-mtp:Q2_0
- Ollama
How to use decent-jawfish/bonsai-2-27b-mtp with Ollama:
ollama run hf.co/decent-jawfish/bonsai-2-27b-mtp:Q2_0
- Unsloth Desktop
- Pi
How to use decent-jawfish/bonsai-2-27b-mtp with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "decent-jawfish/bonsai-2-27b-mtp:Q2_0" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use decent-jawfish/bonsai-2-27b-mtp with Docker Model Runner:
docker model run hf.co/decent-jawfish/bonsai-2-27b-mtp:Q2_0
- Lemonade
How to use decent-jawfish/bonsai-2-27b-mtp with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull decent-jawfish/bonsai-2-27b-mtp:Q2_0
Run and chat with the model
lemonade run user.bonsai-2-27b-mtp-Q2_0
List all available models
lemonade list
- Hermes Agent
How to use decent-jawfish/bonsai-2-27b-mtp with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0
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 decent-jawfish/bonsai-2-27b-mtp:Q2_0
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use decent-jawfish/bonsai-2-27b-mtp with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf decent-jawfish/bonsai-2-27b-mtp:Q2_0
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 "decent-jawfish/bonsai-2-27b-mtp:Q2_0" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
Bonsai 2 27B + MTP (GGUF)
prism-ml/Ternary-Bonsai-2-27B-gguf (PQ2_0) with the multi-token-prediction
head from Qwen3.8-27B grafted in, so it can drive --spec-type draft-mtp
speculative decoding.
~44% faster decode at the same quality โ the ternary weights are untouched, and speculative decoding verifies every draft against the target model, so the output distribution is unchanged.
| tok/s | acceptance | |
|---|---|---|
| Bonsai 2 27B PQ2_0, no MTP | 41.9 | โ |
this model, --spec-draft-n-max 2 |
60.5 | 0.60 |
this model, --spec-draft-n-max 3 |
58.9 | 0.49 |
this model, --spec-draft-n-max 4 |
55.4 | 0.42 |
Measured on one NVIDIA RTX PRO 6000 Blackwell MIG 1g.24gb slice (a quarter
GPU, 24 GB), driver 580.126.20, --parallel 1, 400 generated tokens, 5 prompts,
median. On a full GPU the absolute numbers will be higher; the ratio is the
durable part.
โ ๏ธ Requires a patched llama.cpp
With stock binaries this model loads and runs normally, but --spec-type draft-mtp fails at startup:
llama_verify_hadamard_graph: latent lookup 'mtp_tok_embd-64' consumed by op=RMS_NORM
llama_init_from_model: failed to initialize the context:
Hadamard-latent table 'token_embd.weight' is read without the inverse transform
This is not a defect in the graft. PrismML's ternary models store
token_embd.weight in a rotated ("Hadamard-latent") domain, and every read must
apply the inverse transform first. The main model path in
PrismML-Eng/llama.cpp does this; the
MTP draft graph, which is upstream llama.cpp code predating the folding, has its
own embedding lookup and skips it.
0001-qwen35-mtp-hadamard-inverse.patch in this repo fixes it in ~8 lines against
tag prism-b10685-7dffb15. Build:
curl -fsSL -o src.tgz https://github.com/PrismML-Eng/llama.cpp/archive/refs/tags/prism-b10685-7dffb15.tar.gz
mkdir src && tar -xzf src.tgz -C src --strip-components=1
cd src && patch -p1 < ../0001-qwen35-mtp-hadamard-inverse.patch
cmake -B build -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=<your arch> -DLLAMA_CURL=OFF
cmake --build build --target llama-server -j
Single CUDA arch, server target only: ~150 s on 16 cores.
Run
llama-server -m Bonsai-2-27B-PQ2_0-MTP.gguf \
-ngl 99 -fa on -c 32768 --jinja \
--spec-type draft-mtp --spec-draft-n-max 2
Sampling, per the base model card โ thinking mode: temperature=1.0, top_p=0.95, top_k=20, min_p=0.0; instruct: temperature=0.7, top_p=0.80, top_k=20, presence_penalty=1.5.
--spec-draft-n-max 2 was best on a 24 GB slice. Sweep it for your card; larger
values draft deeper but acceptance falls.
Concurrency
Unusually for speculative decoding, the gain here does not vanish under load โ the MTP head is one small block, so drafting is cheap against a bandwidth-bound ternary trunk:
| concurrent | vanilla agg tok/s | this model agg tok/s | |
|---|---|---|---|
| 1 | 37.6 | 57.8 | +54% |
| 2 | 60.4 | 56.1 | -7% |
| 3 | โ | 99.2 | |
| 4 | 88.4 | 115.5 | +31% |
| 8 | 85.1 | 111.9 | +32% |
(both -c 65536 -np 4.)
There is a reproducible dip at exactly 2 concurrent streams, where per-request throughput falls to 29 tok/s โ below the 37 tok/s seen at 3 concurrent โ and MTP ends up ~7% behind vanilla. Confirmed over four runs. Everywhere else MTP leads by 31-54%. If your workload sits at exactly 2 concurrent requests, benchmark before adopting.
The MTP draft context also costs VRAM, so on a 24 GB card you can allocate fewer
slots than vanilla: vanilla reaches -np 32 and peaks at ~186 agg tok/s, while
this model OOMs past -np 16 and peaks at ~175. Vanilla wins the absolute
aggregate ceiling by ~7%; MTP wins everywhere below it.
How it was made
15 blk.64.* tensors โ a full transformer block plus the nextn projections โ
were copied verbatim and unrotated from
unsloth/Qwen3.8-27B-GGUF UD-Q2_K_XL into the Bonsai GGUF, with
qwen35.block_count set to 65 and qwen35.nextn_predict_layers to 1.
No rotation was applied to them, and they are deliberately not listed in
prism.hadamard.weight_names. The justification: Bonsai's RMSNorm weights match
stock Qwen3.8 elementwise (cosine > 0.99996 on blk.0.attn_norm,
blk.0.post_attention_norm, output_norm). An elementwise scale cannot commute
with a rotation, so the residual stream is in the original basis and
prism.hadamard.* is an online per-matmul quantisation aid, not a change of
basis. A stock MTP block therefore receives exactly the activations it expects.
Only the embedding table is genuinely latent, which is why the one patch is needed.
Base tensors are bit-identical to the source GGUF; only metadata changed and 15
tensors were appended. Merge tool: graft_mtp.py in this repo.
Acceptance
0.60 here versus 0.70 for the same head on stock Qwen3.8 โ the expected cost of a head trained on FP16 hidden states drafting for a ternary trunk. Well above break-even, hence the speedup.
Provenance and attribution
Not affiliated with, or endorsed by, PrismML or the Qwen team. All components are Apache-2.0, as is this derivative.
- Language model:
prism-ml/Ternary-Bonsai-2-27B-gguf(Apache-2.0) - MTP head:
unsloth/Qwen3.8-27B-GGUFUD-Q2_K_XL(Apache-2.0), quantised fromQwen/Qwen3.8-27B(Apache-2.0) - Runtime: PrismML-Eng/llama.cpp
prism-b10685-7dffb15(MIT) - MTP recipe and the observation that the head ships inside the GGUF: sudoingX/qwen38-mtp
Limitations
- Needs the patch for MTP. Without it, works as a normal Bonsai 2 27B.
- Quality was not re-benchmarked. The claim that quality is unchanged rests on speculative decoding being verified-lossless and the base weights being bit-identical โ not on a benchmark run.
- The MTP block is Q6_K/Q8_0, not ternary, adding ~0.35 GB over the base model.
- Tested only on CUDA sm_120. Metal and CPU paths are untested.
- The vision
mmprojis not included; text-only.
- Downloads last month
- 2,052
2-bit