Instructions to use ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx with MLX:
# Make sure mlx-lm is installed # pip install --upgrade mlx-lm # Generate text with mlx-lm from mlx_lm import load, generate model, tokenizer = load("ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx") prompt = "Write a story about Einstein" messages = [{"role": "user", "content": prompt}] prompt = tokenizer.apply_chat_template( messages, add_generation_prompt=True ) text = generate(model, tokenizer, prompt=prompt, verbose=True) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Pi
How to use ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx with Pi:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx"
Configure the model in Pi
# Install Pi: npm install -g @mariozechner/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "mlx-lm": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Hermes Agent new
How to use ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx 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 "ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx"
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 ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx
Run Hermes
hermes
- OpenClaw new
How to use ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx with OpenClaw:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx"
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 "ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx" \ --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"
- MLX LM
How to use ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx with MLX LM:
Generate or start a chat session
# Install MLX LM uv tool install mlx-lm # Interactive chat REPL mlx_lm.chat --model "ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx"
Run an OpenAI-compatible server
# Install MLX LM uv tool install mlx-lm # Start the server mlx_lm.server --model "ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx" # Calling the OpenAI-compatible server with curl curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx", "messages": [ {"role": "user", "content": "Hello"} ] }'
Hy3-295B-Instruct — MLX (w2q3 experts / Q8 rest / MTP)
An MLX port of tencent/Hy3
(Tencent Hunyuan 3, hy_v3) — a 295B-parameter Mixture-of-Experts model (21B active,
192 experts top-8, GQA + QK-norm, 256K context) with a Multi-Token-Prediction (MTP)
layer for self-speculative decoding.
Quantized in the asymmetric style of antirez/deepseek-v4-gguf: crush the routed experts (they are most of the weights), keep the decision-making parts high precision. The filename is the spec. Runs on a single 128 GB Apple Silicon machine.
⚠️ Needs a patched
mlx-lm. Upstreammlx-lmdoesn't shiphy_v3yet, and even PR #1211 (which adds the base model) strips the MTP layer. The branch below = PR #1211 (base model + tool parsers + tokenizer fix, by @kernelpool) plus the MTP self-speculative decoding added here.
Installation
One command. The branch = PR #1211 (hy_v3 base + tool parsers + tokenizer fix,
by @kernelpool) plus the MTP self-speculative decoding added here. The
transformers pin avoids a known crash on 5.13+ (AutoTokenizer.register).
pip install "transformers>=5.7,<5.13" \
"mlx-lm @ git+https://github.com/eauchs/mlx-lm.git@hy_v3-mtp"
Read this before running (memory). The weights must stay fully resident in RAM. This model is ~110 GB on a 128 GB Mac — tight. For usable speed:
- Keep the model on the internal SSD (external USB works but pages slowly).
- Close other big RAM users (Ollama, LM Studio, browsers).
Fully resident it does ~5–6 tok/s; paging from an external USB SSD it can drop to <1 tok/s. This is a hardware/memory limit, not the quant — see Performance and Troubleshooting.
Usage
mlx_lm.generate --model ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx \
--prompt "Explain mixture-of-experts routing in one paragraph." \
--max-tokens 300 --temp 0.0
mlx_lm.chat --model ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx
from mlx_lm import load, generate
model, tokenizer = load("ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx")
messages = [{"role": "user", "content": "Hello! Introduce yourself briefly."}]
prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True)
print(generate(model, tokenizer, prompt=prompt, max_tokens=300))
Reasoning modes
Hy3 supports no_think (default) and high reasoning effort via the chat template.
The #1211 tokenizer fix + hy_v3_opensource parser handle the release checkpoint's
:opensource special tokens (<think:opensource>, <tool_calls:opensource>, ...):
prompt = tokenizer.apply_chat_template(
messages, add_generation_prompt=True,
chat_template_kwargs={"reasoning_effort": "high"},
)
Files
| Repo | Size | Routed experts | Everything else |
|---|---|---|---|
| this repo | ~110 GB | 2-bit (gate, up) + 3-bit (down) | Q8 attn proj / shared expert / output head / router / dense-layer-0; bf16 embeddings; bf16/f32 norms & expert_bias; MTP layer included |
Quantization recipe
The filename is the spec (group_size = 64, MLX affine, verified against the tensors):
| Tensor class | Quant | Notes |
|---|---|---|
experts gate_proj, up_proj |
2-bit | routed-expert up/gate |
experts down_proj |
3-bit | routed-expert down (extra bit for quality) |
shared_mlp.* |
Q8 (8-bit) | shared expert |
self_attn.{q,k,v,o}_proj |
Q8 | all attention projections (GQA) |
lm_head |
Q8 | output head |
router.gate |
Q8 | learned router (antirez keeps this F16) |
| dense MLP (layer 0) | Q8 | first dense layer |
embed_tokens |
bf16 | input embedding |
all *_norm, expert_bias |
bf16 / f32 | |
| MTP layer | same scheme | self-speculative decoding |
Motivation for the asymmetry (per antirez): the routed experts are the majority of the parameter count, but each expert handles only a fraction of tokens, so aggressive quantization on them costs less average quality than the same treatment of the router, projections, or shared expert. Keeping the decision-makers at Q8 preserves behaviour; crushing the experts buys the size.
Differences from antirez's DS4 recipe
- Router: Q8 here vs F16 for antirez.
- Method: plain round-to-nearest (RTN), no calibration/imatrix. Expect a
visible quality drop at 2-bit on the expert
gate/upprojections vs the source model. A calibrated pass would need the source (FP8/BF16) weights.
Multi-Token Prediction (self-speculative decoding)
Because num_nextn_predict_layers > 0, the patched mlx_lm uses the built-in MTP head
for self-speculative decoding — no external draft model. Each step drafts one token with
the MTP head and verifies it with a single target pass, up to two tokens per pass.
Verification is distribution-preserving and honors your sampler (temperature, top-p,
top-k) — it is no longer greedy-only, so temp = 0.9 (Hy3's recommended sampling)
works correctly. Two rules, picked automatically:
- Residual (Leviathan) — at
temp > 0with a standard sampler: accept the draftx ~ qwith probabilitymin(1, p(x)/q(x))and resample from the normalizedrelu(p − q)on rejection. Accepts strictly more often (Σ min(p,q) ≥ Σ p·q) than plain matching, for the exact same output distribution. - Match — the sampler-agnostic fallback (custom samplers / XTC / active logits
processors), and what
temp = 0reduces to (greedy draft-equals-target).
Acceptance is checkpoint-bound: the MTP drafter here is quantized about as hard as the
target, so it reflects quant precision more than the method's ceiling. ≈ 35–40% at
greedy on this quant; at temp > 0 the residual rule accepts more often than matching on
the same draws (higher-precision drafters reach ~64–66% at greedy).
Performance
| Mode | Speed | Peak RAM |
|---|---|---|
| Standard decoding | ~4.8 tok/s | ~107 GB |
| MTP self-speculative | ~6.3 tok/s | ~114 GB |
These assume the model is fully resident. At ~114/128 GB it's borderline: any other
large RAM user, or serving the weights from a slow external disk, makes the mmap'd pages
page in from storage and throughput collapses (seen as low as ~0.7 tok/s). Prefer the
internal SSD and close other apps. (Note: forcing mx.set_wired_limit to pin ~110 GB
from an external USB SSD trips the Metal GPU watchdog, so wiring is left to the OS.)
Troubleshooting
AttributeError: 'str' object has no attribute '__module__'on import — atransformers5.13+ incompatibility inmlx-lm. Usetransformers<5.13(already pinned in the install command above).GPU Timeout Error (kIOGPUCommandBufferCallbackErrorTimeout)at load / first token —mlx-lmpins (wires) the whole model in RAM, and pinning ~110 GB from a slow external USB SSD trips Metal's watchdog. Fix: put the model on the internal SSD (fast enough to wire), or free enough RAM that it stays resident. This is a hardware/storage limit, not the quantization.
Limitations
- Requires ~128 GB unified memory; not usable on smaller Macs.
- RTN quantization (no calibration/imatrix) — reduced quality vs. the source model.
- MTP acceptance is capped by the drafter's precision (2–3-bit experts here), not the method.
- Depends on the
hy_v3-mtpmlx-lmbranch untilhy_v3(+ MTP) lands upstream.
Credits & license
- Base model: tencent/Hy3 — Apache 2.0.
hy_v3mlx-lm support + tool parsers + tokenizer fix: @kernelpool, mlx-lm PR #1211.- Asymmetric low-bit MoE recipe inspired by antirez/deepseek-v4-gguf.
- Quantization + MTP self-speculative decoding (distribution-preserving verification: residual/Leviathan + match): ox-ox (mlx-lm PR #1485).
- Released under Apache 2.0, following the base model's terms.
- Downloads last month
- 1,312
2-bit
Model tree for ox-ox/Hy3-295B-Instruct-w2q3exp-AProjQ8-SExpQ8-OutQ8-MTP-mlx
Base model
tencent/Hy3