Skip to page content
SAVRN
Search Plan a project

Open-weight model · Image and text to text

NeoHorse-1-9B-EXL3-16GB-12GB

by Jorge Ramírez Espejo JRamirez-UAB/NeoHorse-1-9B-EXL3-16GB-12GB

NeoHorse-1-9B-EXL3-16GB-12GB is an open-weight model for image and text to text from Jorge Ramírez Espejo, released under Apache License 2.0. It has 4.4B parameters and a 262,144-token context. At 16-bit it needs about 10.5 GB of GPU memory, which fits on 1x MI300X from $1.85 an hour, at the lowest prices in the SAVRN Index. It draws 117 downloads a month.

An EXL3 quantization of TokenRhythm/NeoHorse-1-9B (an agent-oriented finetune of Qwen3.5-9B) made with exllamav3, in two sizes: - main — 6.00 bpw, for 16 GB GPUs (e.g.

Parameters4.4B
Context262,144
Weights7.7 GB
Licenseapache-2.0
AccessOpen weights
Monthly Downloads117

Runs On

What it takes to serve NeoHorse-1-9B-EXL3-16GB-12GB (4.4B parameters): the memory its weights need at each precision, and the cheapest way to rent enough data-center GPUs to hold them.

PrecisionWeightsMemory neededCheapest setupPer hourAlso fits
16-bit 8.8 GB 10.5 GB 1x MI300X (192 GB)
Vultr
$1.85 1x H100 $1.99 · 1x MI325X $2.00
8-bit 4.4 GB 5.3 GB 1x MI300X (192 GB)
Vultr
$1.85 1x H100 $1.99 · 1x MI325X $2.00
4-bit 2.2 GB 2.6 GB 1x MI300X (192 GB)
Vultr
$1.85 1x H100 $1.99 · 1x MI325X $2.00

Memory is the weights at that precision plus 20% for the runtime and a short context; a long context needs more. Prices are the lowest on-demand hourly rates in the SAVRN Index, read Oct 16, 2026.

NeoHorse-1-9B-EXL3-16GB-12GB on every accelerator the SAVRN Index prices, at every precision

Model Card

By Jorge Ramírez Espejo, published under apache-2.0, revision baf2ef64793e.

An EXL3 quantization of TokenRhythm/NeoHorse-1-9B (an agent-oriented finetune of Qwen3.5-9B) made with exllamav3, in two sizes: - main — 6.00 bpw, for 16 GB GPUs (e.g. RTX 5060 Ti 16 GB / 4060 Ti 16 GB): the full 262,144-token context with vision, MTP speculative decoding and 2 concurrent sessions, KL divergence 0.0015 against BF16. - 4.50bpw — 4.50 bpw, for 12 GB GPUs (e.g. RTX 3060 12 GB): 176,000 tokens with vision, KLD 0.0058. Both are served with vLLM (continuous batching) through the OrcaSAQ2 plugin and a small plugin of ours (included), with INT8 token embeddings. Why this model: we evaluate small models as a Linux sysadmin agent driven by opencode, used in Spanish. Among the 9B…

Read Jorge Ramírez Espejo's full model card

NeoHorse-1-9B — EXL3 for 16 GB and 12 GB GPUs (vision + MTP, served with vLLM)

Install from this card, not from generic snippets. This is an EXL3 checkpoint: vLLM loads it only together with exllamav3 and our plugins. Follow Requirements & install and Quick start; a plain pip install vllm, Transformers or SGLang cannot load it.

An EXL3 quantization of TokenRhythm/NeoHorse-1-9B (an agent-oriented finetune of Qwen3.5-9B) made with exllamav3, in two sizes:

  • main — 6.00 bpw, for 16 GB GPUs (e.g. RTX 5060 Ti 16 GB / 4060 Ti 16 GB): the full 262,144-token context with vision, MTP speculative decoding and 2 concurrent sessions, KL divergence 0.0015 against BF16.
  • 4.50bpw — 4.50 bpw, for 12 GB GPUs (e.g. RTX 3060 12 GB): 176,000 tokens with vision, KLD 0.0058.

Both are served with vLLM (continuous batching) through the OrcaSAQ2 plugin and a small plugin of ours (included), with INT8 token embeddings.

Why this model: we evaluate small models as a Linux sysadmin agent driven by opencode, used in Spanish. Among the 9B models we measured with the same tests (Ornith-1.5-9B, AdQWENistrator-9B, Mellum2.1, Qwen3.5-9B), NeoHorse and Ornith-1.5-9B are the two good agents: over 60 real sysadmin tasks with opencode run (20 tasks × 3 runs), NeoHorse 50/60 as written and 53/60 with file names in backticks (Ornith: 45/60 and 55/60). NeoHorse is the stronger coder (browser games: 2-3 of 4 run, Ornith 0-1) and the more robust one without backticks; Ornith thinks ≈4× less. 30/30 tool calls with the real opencode request, even without reasoning.

Our focus. We quantize and evaluate models for one use case: a local Linux system-administration agent (opencode with tool calling) for a university IT department, used in Spanish. Our calibration traces include real sysadmin/agent conversations in Spanish, and our quality checks (tool calls with the real opencode request, agent tasks with real command execution, long-context retrieval, long answers in Spanish) reflect that use. KL divergence is also reported on turboderp's public trace, so it can be compared and reproduced. Numbers for other domains or languages may differ.

Vision and MTP are grafted. The original NeoHorse-1-9B release has no vision tower and no MTP head. We added both, unchanged, from Qwen/Qwen3.5-9B (same architecture). Images work in our tests (14/15 checks) and the MTP head is accepted 55-66 % of the time (≈2.7-3 tokens per step), but they were trained for Qwen3.5-9B, not for NeoHorse.

Sampling matters (please keep generation_config.json). The original repository has no generation_config.json. Without it, vLLM samples from the whole vocabulary (temperature 1.0, no top_k) whenever the client sends no sampling parameters (e.g. opencode without "temperature": true), and in long answers the model drifts into stray Chinese text: 6 of 10 long Spanish answers, 2 of 10 English ones. This repo ships generation_config.json with temperature 0.8 (0.6 until 2026-10-13), top_p 0.95, top_k 20 (applied automatically by vLLM): 0 of 10 in both languages at 0.6, and 0 of 10 in both at 0.8 (checked again on 2026-10-13). For non-English use, a system line such as "Responde siempre en castellano" does not change the CJK rate, but it made answers ≈35 % shorter.

Tested hardware: all numbers were measured on an RTX 3090 (24 GB, Ampere, 300 W) with the memory budget of the target card: the KV cache is fixed with --kv-cache-memory-bytes so that the peak memory used stays under what a 16 GB / 12 GB card offers (≈15,700 / ≈11,700 MiB usable after the driver's reservation). They have not been run on an actual 16 GB or 12 GB card yet — reports welcome (see Feedback).

What is in this repository

Which one to use

All NeoHorse-1-9B variants we publish, measured on 2026-10-14 under the same conditions (see Family comparison for every number):

Variant Weights Context on one RTX 3090 KLD vs BF16 Agent tasks Decode, 1 request Pick it for
EXL3 6.00 (16 GB) (this repo) 7.20 GiB 262,144 with vision 0.0015 23/30 139.1 tok/s a 16 GB GPU: 262,144 tokens with vision
EXL3 4.50 (12 GB) (this repo) 5.77 GiB 176,000 with vision 0.0058 22/30 146.6 tok/s a 12 GB GPU: 176,000 tokens with vision
Revision Target Linear layers lm_head Vision MTP head Embeddings Size
main 16 GB 6.00 bpw (uniform) 6 bits 6 bits 6 bits INT8 per row 7.20 GiB
4.50bpw 12 GB 4.50 bpw, per-tensor (SC) allocation 5 bits 4 bits 6 bits INT8 per row 5.77 GiB

Results

Family comparison (NeoHorse-1-9B, same conditions)

Measured on 2026-10-14 for every variant in the same way: weights downloaded from Hugging Face, one RTX 3090 24 GB (power limit 350 W, no other use), vLLM 0.31.0 (EXL3: + exllamav3 1.5.1 + plugins), each variant with its own Quick start configuration. KLD and perplexity come from exllamav3's qbench (see How to read it).

Variant Weights KLD mean / median (internal · public) Perplexity (BF16 3.1559 · pub. 2.0559) Needle (8 facts) near max. context Tools: real opencode request Agent tasks (10 × 3) Reasoning xhigh: correct · tokens Vision
EXL3 6.00 bpw (main, this repo) 7.20 GiB 0.0015 / 0.0007 · pub. 0.0014 / 0.0003 3.1583 · pub. 2.0572 8/8 at 241,437 56/60 23/30 44/48 · 100,363 14/15
EXL3 4.50 bpw (4.50bpw, this repo) 5.77 GiB 0.0058 / 0.0024 · pub. 0.0057 / 0.0010 3.1656 · pub. 2.0653 8/8 at 162,208 60/60 22/30 42/48 · 110,214 14/15
Variant Context on one RTX 3090 Sessions Prefill near max. context Decode, 1 / 2 / 8 requests (tok/s) MTP tokens per step VRAM used at peak (fits a 16 GB card up to ≈15,700 MiB, a 12 GB card up to ≈11,700)
EXL3 6.00 (16 GB) 262,144 with vision 2 1,712 tok/s 139.1 / 255.3 / 253.1 3.34 15,276 MiB
EXL3 4.50 (12 GB) 176,000 with vision 2 2,050 tok/s 146.6 / 259.6 / 268.0 3.38 11,400 MiB

How to read it: - KLD / perplexity: next-token KL divergence against the BF16 model with exllamav3's qbench (lower is better). Internal: our sysadmin/agent evaluation set (not published, separate from the calibration data); public: turboderp's qbench_prompts_gen.json, reproducible by anyone. GPTQ checkpoints were evaluated as a BF16 copy holding the dequantized weights. These two columns come from qbench, not from this campaign. - Needle: 8 facts spread through one prompt at about 92 % of the served context; all 8 must come back. Tools: the real request of the opencode agent (system prompt + 11 tools), 3 cases × 20 tries, at the model's default sampling (generation_config.json); a try counts when it calls a valid tool with valid arguments and the expected command. Agent: 10 sysadmin tasks run with opencode run and real command execution, 3 runs, at the recommended temperature; with sampling on, the same checkpoint varies by about ±2 of 30 between runs, so other measurements in this card may differ by that much. Reasoning: 6 checkable problems × 8 at xhigh; total reasoning tokens over the 48. Vision: our 4-image test. - Prefill / decode: prefill from the needle prompt; decode is aggregate throughput with 1 / 2 / 8 simultaneous requests (temperature 0; with more requests than Sessions, the extra ones wait). MTP tokens per step: vLLM's speculative-decoding metrics over the whole run. - VRAM really free: lowest memory.free while serving (nvidia-smi every 0.5 s, from the end of start-up to the end of the run); we require ≥100 MiB. - Older sections below keep their own date and setup; use this table to compare variants.

How many sessions fit with each Quick start configuration (KV size in tokens as reported by vLLM at start-up; a session uses the KV of its own context, and vLLM never runs more than max sessions at once):

Variant KV pool (tokens) Max sessions 32k each 64k each 128k each Full context each
EXL3 6.00 (16 GB) 267,185 2 2 2 2 1 × 262,144
EXL3 4.50 (12 GB) 177,955 2 2 2 1 1 × 176,000

Few users or many users. The Quick start configuration is tuned for 1–2 simultaneous users (fastest single request). For more users, the many users option below (measured the same day, same GPU) gives more total throughput; each request gets slower when many run at once. Same model, same quality: only the serving settings change.

Variant Configuration Decode by simultaneous requests (aggregate tok/s) N sessions at once, needle 8/8 Tools (5 × 3) VRAM used at peak
EXL3 6.00 (16 GB) Quick start (2 sessions, MTP 3) 1: 139 · 2: 255 · 8: 253 — 56/60 15,276 MiB
EXL3 6.00 (16 GB) many users (8 sessions of up to 262,144 tokens, MTP 3) 1: 136 · 2: 249 · 4: 451 · 8: 574 8/8 of 22k 15/15 15,386 MiB
EXL3 4.50 (12 GB) Quick start (2 sessions, MTP 3) 1: 147 · 2: 260 · 8: 268 — 60/60 11,400 MiB
EXL3 4.50 (12 GB) many users (8 sessions of up to 176,000 tokens, MTP 3) 1: 156 · 2: 268 · 4: 504 · 8: 655 8/8 of 22k 15/15 11,608 MiB

Earlier measurements

Earlier measurements (RTX 3090 within the target memory budget), before the controlled comparison of 2026-10-14: other dates, vLLM versions or settings, as stated in each table. Use Family comparison above to compare variants.

Test main 6.00 bpw · 16 GB · 262,144 + vision 4.50bpw · 12 GB · 176,000 + vision
KLD vs BF16, mean / median (our sysadmin trace; noise floor 0.0006) 0.0015 / 0.0007 0.0058 / 0.0024
KLD on turboderp's public trace (qbench_prompts_gen.json), mean / median (noise floor 0.0006) 0.0014 / 0.0003 0.0057 / 0.0010
Peak memory used (budget) 14,511 MiB (≈15,700) 11,517 MiB (≈11,700)
KV pool 267,185 tokens (5.25e9 B) 177,955 tokens (3.6e9 B)
8 facts in one long prompt 8/8 at 242,097 tokens (190 s) 8/8 at 158,732 tokens (101 s)
2 simultaneous sessions 2 × 117k, 8/8 in both 2 × 75k, 8/8 in both
Decode with MTP 3, 1 request / 2 concurrent 132 / 219-238 tok/s 138-141 tok/s / —
Images (4 sysadmin screenshots, 15 checks) 14/15 14/15
Real opencode request, tool calls (3 cases × 10): xhigh · T 0.3 · no reasoning 28/30 · 30/30 · 30/30 30/30 · 30/30 · 30/30
Agent: 10 sysadmin tasks with opencode run 7/10 9/10 †
Agent: 4 tasks × 2 (logs, sshd, script, summary) 8/8 7/8 †
Reasoning, 48 checkable problems (correct; total reasoning tokens) low 42 (112k) · medium 44 (79k) · xhigh 46 (77k) low 44 (86k) · medium 43 (88k) · xhigh 44 (68k) †
Coding: 4 browser games (static checks + headless run) 44/48, 3/4 run 44/48, 3/4 run †

† Measured with the same 4.50bpw weights at 198,000 tokens / KV 4.0e9 (peak 11,899 MiB, slightly over a 12 GB budget); the 176,000 configuration above was then validated for memory, needle, sessions, images and tools.

For reference, on the same tests AdQWENistrator-9B (same size, also quantized by us) scored 5/10 and 5/10 on the 10 agent tasks; Qwen3.5-9B base needed ≈146k reasoning tokens at xhigh for 38-39/48.

Sampling and repetition loops

Measured on 2026-10-14 with the same software and GPU as Family comparison, on our EXL3 6.00 (16 GB) build of NeoHorse-1-9B (loops come from the model and the sampling, not from the quantization format): 5 long Spanish sysadmin prompts × 6 runs per temperature, up to 16,000 tokens, top_p 0.95 and top_k 20; a loop = more than 30 % repeated 8-grams. Serving: the Quick start with a 32k context and 8 sessions.

Temperature 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
Loops / 30 6 3 3 1 0 0 0 0
Answers that finished before 16,000 tokens / 30 23 27 26 29 30 30 30 30

From temperature 0.6 up, loops are rare (at most 1 of 30). This repo's default (generation_config.json) is 0.8.

Other models, same test and setup (loops / 30):

Model (build) 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
Qwen3.8-27B · EXL3 3.85 12 12 7 8 1 1 1 0
Qwen3.8-27B-pi · EXL3 3.85 9 4 9 10 4 2 1 0
Qwopus3.8-27B-Flash-V2 · EXL3 3.85 3 1 2 1 2 0 0 0
Swift 1.5 (Qwen3.8-27B) · EXL3 3.85 7 5 3 4 3 1 1 0
Ornith-1.5-9B · EXL3 6.00 (16 GB) 6 2 3 1 1 0 0 0
Qwen3.6-35B-A3B · EXL3 4.00 0 0 1 1 0 0 0 0
Ornith-1.5-35B-A3B · EXL3 4.00 1 0 0 0 0 0 0 0
Qwopus3.6-35B-A3B-Coder · EXL3 4.00 9 13 12 6 11 6 5 4
Swift 1.5 Qwen3.8-Flash-Next (125B-A6B) · EXL3 2.25 · vLLM 24 24 21 21 17 8 0 0
Qwen3.8-Flash-Next (125B-A6B) · EXL3 2.25 · vLLM — — 13 7 5 2 0 0

Requirements & install (vLLM 0.31 + exllamav3 1.5.1 + plugins)

EXL3 is not a native vLLM format. Two plugins are needed, both loaded through vLLM's vllm.general_plugins entry point: - Continuum-AI-Corp/OrcaSAQ2-kernel (commit 7ddffb12c00c24b8bc6b1164723c04ac490a91bc): EXL3 linear layers through exllamav3's kernels, and INT8 / packed embed_tokens and lm_head for qwen3_5 models (no vLLM patch needed). - qwen38_exl3_vision 0.4.0 (ours; 0.4.0 adds multi-GPU: tensor parallelism for the dense models, -tp 2, e.g. Swift 27B on 2 GPUs with the same log-likelihood (+0.04 %) and +43 % speed for one request, and expert parallelism for the MoE ones, -tp 2 --enable-expert-parallel; 0.3.2 freed the host-RAM copy of the checkpoint, ~14 GB less for a 27B; in plugin/qwen38_exl3_vision/, the same version in all our EXL3 repos): the EXL3 vision tower (drops the separate attn.{q,k,v}_proj tensors and pads input dimensions to multiples of 128 where needed), EXL3 MoE experts with exllamav3's fused kernel, and the Qwen3.8-Flash-Next model.

Use exllamav3 1.5.1 (with 1.6.x the KLD is the same, but tool calls without reasoning got worse in our tests) and Python 3.12 (the exllamav3 wheels are cp312). flashinfer compiles some kernels on first start with the CUDA toolkit that comes with the vLLM wheel; if your system nvcc does not match, point CUDA_HOME at a CUDA 13.0 toolkit.

uv venv --python 3.12 venv
uv pip install --python venv/bin/python vllm==0.31.0 --torch-backend=auto        # torch 2.13.0
W=exllamav3-1.5.1+cu132.torch2.13.0-cp312-cp312-linux_x86_64.whl
curl -L -o /tmp/$W "https://github.com/turboderp-org/exllamav3/releases/download/v1.5.1/${W/+/%2B}"
git clone https://github.com/Continuum-AI-Corp/OrcaSAQ2-kernel && (cd OrcaSAQ2-kernel && git checkout 7ddffb12c00c24b8bc6b1164723c04ac490a91bc)
hf download JRamirez-UAB/NeoHorse-1-9B-EXL3-16GB-12GB --include "plugin/*" --local-dir .
uv pip install --python venv/bin/python /tmp/$W -e OrcaSAQ2-kernel -e plugin/qwen38_exl3_vision
venv/bin/python -c "import torch; from exllamav3.ext import exllamav3_ext; print(torch.__version__, torch.cuda.get_device_name(0))"

Quick start

16 GB GPU — main:

export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True VLLM_USE_FLASHINFER_SAMPLER=0
hf download JRamirez-UAB/NeoHorse-1-9B-EXL3-16GB-12GB --local-dir NeoHorse-1-9B-EXL3
vllm serve ./NeoHorse-1-9B-EXL3 \
  --served-model-name neohorse-1-9b \
  --limit-mm-per-prompt '{"image":1,"video":0}' \
  --mm-processor-kwargs '{"max_pixels":1003520}' \
  --max-model-len 262144 \
  --kv-cache-dtype fp8_e4m3 \
  --kv-cache-memory-bytes 5250000000 \
  --max-num-batched-tokens 8192 \
  --max-num-seqs 2 \
  --enable-prefix-caching \
  --speculative-config '{"method":"mtp","num_speculative_tokens":3}' \
  --reasoning-parser qwen3 \
  --enable-auto-tool-choice --tool-call-parser qwen3_coder

12 GB GPU — 4.50bpw: download with --revision 4.50bpw and use --max-model-len 176000 --kv-cache-memory-bytes 3600000000 --max-num-batched-tokens 4096 (peak 11,462 MiB used). 198,000 tokens with 4.0e9 B of KV also runs, but peaked at 11,899 MiB: only if your card leaves that much free.

Prompt processing (updated 2026-10-11): --max-num-batched-tokens 8192 (16 GB) / 4096 (12 GB) reads long prompts ≈22–27 % faster than the 1024 we used before (124k-token prompt: 2,236 vs 1,764 tok/s on the RTX 3090), and still fits: peak 15,260 / 11,462 MiB used, validated with the needle test (8/8 at 233k / 157k), 2 concurrent sessions, vision and tool calls. If you run something else on the same GPU, go back to 1024 (≈1 GB lower peak on 16 GB).

For many users (measured on 2026-10-14, same GPU): the same command with --max-num-seqs 8 — 8 sessions of up to 262,144 tokens, MTP 3. Aggregate decode 574 tok/s with 8 requests (Quick start: 253 with 8); a single request runs at 136 tok/s (139 with the Quick start); 8 of 8 simultaneous sessions returned all 8 needle facts; 15,386 MiB of VRAM used at peak. Rule for CUDA graphs: they must cover sessions × (1 + MTP) tokens per step.

Using it with opencode (how we tested)

Tool calling was measured with the real opencode request (captured and replayed against vLLM) and with opencode run agent tasks in a sandbox with deterministic checks.

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "local-vllm": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "local vLLM",
      "options": { "baseURL": "http://127.0.0.1:8000/v1" },
      "models": {
        "neohorse-1-9b": {
          "name": "NeoHorse 1 9B EXL3 (local)",
          "tool_call": true,
          "temperature": true,
          "attachment": true,
          "modalities": { "input": ["text", "image"], "output": ["text"] },
          "limit": { "context": 262144, "output": 32000 },
          "variants": {
            "none":   { "chat_template_kwargs": { "enable_thinking": false } },
            "low":    { "chat_template_kwargs": { "reasoning_effort": "low" } },
            "medium": { "chat_template_kwargs": { "reasoning_effort": "medium" } },
            "xhigh":  { "chat_template_kwargs": { "reasoning_effort": "xhigh" } }
          }
        }
      }
    }
  },
  "agent": {
    "build": { "model": "local-vllm/neohorse-1-9b", "variant": "xhigh", "temperature": 0.8 },
    "plan":  { "model": "local-vllm/neohorse-1-9b", "variant": "xhigh", "temperature": 0.8 }
  }
}
  • limit.context = --max-model-len (176000 with the 4.50bpw branch). Declare "temperature": true, otherwise opencode sends no temperature.
  • For Spanish (or another language), add the language line to your AGENTS.md or agent instructions.

Important notes

  • Keep generation_config.json (see the note at the top), or pass --override-generation-config '{"temperature":0.8,"top_p":0.95,"top_k":20}'.
  • Memory. The driver reserves ≈450 MiB that vLLM cannot use: read the real headroom with nvidia-smi --query-gpu=memory.used,memory.free --format=csv. Size the KV cache with --kv-cache-memory-bytes, never with --gpu-memory-utilization. With MTP, KV capacity grows in block-sized steps: check the GPU KV cache size line and keep --max-model-len below it.
  • Leave the GPU to the LLM. On a 12 GB card the margin is a couple of hundred MiB: a desktop session or a browser on the same GPU will not fit.
  • Hugging Face page warnings: the "Model size" shown by Hugging Face counts packed storage elements (EXL3 packs several weights per int16), not parameters: this is the 9B model. The Configuration Parsing Warning about quantization_config.bits is expected (for EXL3 it is an average).
  • Use --tool-call-parser qwen3_coder and --reasoning-parser qwen3. reasoning_effort accepts xhigh, medium and low, but in our measurements it does not change how much the model thinks (see Known weak spots).

Quantization recipe

Step What we did
Grafting Vision tower and MTP head copied unchanged from Qwen/Qwen3.5-9B (775 tensors; 48 kept in FP32 as in the original)
main exllamav3 1.5.1 convert.py -b 6.0 -hb 6 -vb 6 -mb 6 (uniform 6.00 bpw)
4.50bpw calibration trace Generated by NeoHorse itself with exllamav3's sc_trace (reasoning_effort: xhigh, MTP), 262,144-token budget
4.50bpw allocation sc_rfn_probe against a 2.00 bpw reference, sc_measure --shaped, sc_optimize -b 4.5 -hb 5 -al 2.0 → per-tensor recipe
Embeddings embed_tokens re-encoded to INT8 per row (absmax / 127, BF16 scales) in the OrcaSAQ2 plugin's format (≈1 GiB less VRAM); script included

Source: TokenRhythm/NeoHorse-1-9B revision ba5b6e40. Tokenizer and chat template unchanged (Qwen3.5 XML tool calls, qwen3_coder).

Integrity and validation

What was checked for this checkpoint, how, and where the numbers are (measured on 2026-10-14; the method and every figure are in Family comparison).

Artifact integrity - Every weight file is checked against our local copy with SHA-256 before publication (SHA256SUMS in this repo). - The measurements used the weights downloaded from this repo at commit 941a379aa41c; later commits change only metadata, documentation or the plugin, never the .safetensors files. - vLLM loads every tensor listed in model.safetensors.index.json on start-up (a missing tensor or a wrong shape would stop it): checked from a fresh download. - After the metadata update of 2026-10-14 (quantization_config.json, plugin 0.3.1, embed_int8.py): downloaded again from this repo and re-tested: loads; vision 14/15 needle 64k 8/8; tool calls 15/15; engine errors 0.

Quantization - Per-tensor bit allocation is recorded by exllamav3 in quantization_config.json; its tensor_storage entry for embed_tokens describes the INT8 qweight + BF16 scales actually stored (updated on 2026-10-14; the plugin only reads the .trellis entries). - The INT8 embedding conversion (scripts/embed_int8.py) is reproducible: re-running it on the source checkpoint gives the published qweight and scales bit for bit (checked on Ornith-1.5-9B 6.00 bpw); its reported error now uses the stored BF16 scales (0.00806 vs 0.00803 with FP32 scales). - Fidelity: KL divergence against the BF16 NeoHorse-1-9B with exllamav3's qbench on two traces (ours and turboderp's public one).

Chat template - The published template renders correctly in 40 edge cases (empty and very long system prompt, no tools, two tool calls in one message, nested JSON and multi-line arguments, images with tools, two images, earlier reasoning, multi-turn with several tool results) × the reasoning settings (enable_thinking: false, reasoning_effort low / xhigh): all pass (prueba_plantillas.py). With Transformers directly, pass tool-call arguments as dicts (vLLM converts JSON strings itself).

Runtime - Load, long-context needle, vision, tool calls with the real opencode request, 10 agent tasks × 3 runs, concurrency and VRAM: see Family comparison; engine errors during the run: 0.

Scope: results apply to the revision, software stack (vLLM 0.31.0 + exllamav3 1.5.1 + plugins), hardware and settings stated above; other setups are not tested.

Limitations

  • Review the commands before they run. As an agent, the model proposes shell commands and opencode can execute them: review them before running anything as root or with sudo, and give the agent a non-privileged account and a test machine where you can.
  • Measured on an RTX 3090 within the memory of the target cards, not yet on actual 16 GB / 12 GB GPUs (expect lower speeds on them).
  • The grafted vision tower and MTP head come from Qwen3.5-9B, not from NeoHorse's training.
  • Quality was evaluated with our own sysadmin-oriented tests (KL divergence, long-context retrieval, tool calls with the real opencode request, agent tasks, synthetic screenshots, small coding tasks), not with standard benchmarks. The original model card reports NeoHorse's benchmarks.

Known weak spots (measured 2026-10-11, same tests as Ornith-1.5-9B)

These come from the model, not from the quantization (KLD 0.0015 at 6.00 bpw); listed so you know what to watch: - File names in non-English prompts. It sometimes "translates" the file name it was asked for: errors.txt instead of errores.txt, processes.csv instead of procesos.csv (the content is right). Measured over 340 agent tasks in Spanish: 5 % of tasks; a line in AGENTS.md asking for exact names barely changes it (4 %). With the file names and paths written in backticks in the request (we did it automatically for every user message): 0 of 360 tasks, and +6 points of agent success. With the same tasks in English: 0 of 40 — it is a non-English problem. Same behaviour in Ornith-1.5-9B. The model is not translating: it renames output files whose Spanish name is a system concept (processes, users, errors) to the conventional English name; names unrelated to the system (e.g. tortuga.txt) are kept (34/34). Backticks fix it and did not hurt when the user describes a system file in words or misspells its path (70/70). - Invented command options and fields. With less common CLIs (Slurm sacctmgr/scontrol, nvidia-smi --query-*, systemd timer syntax) it may guess field names, subcommands or syntax that do not exist (scontrol show qos, --query-processes, OnCalendar=02:30 daily) and retry them; check its commands. This is a knowledge limit of a 9B model, the same in Spanish and English; a generic "read --help first" instruction did not fix it. Documenting the tools your agent uses (field names, correct syntax) in its instructions is the practical workaround. - Long reasoning. On our 6 reasoning problems × 3 it used ≈32,000–38,000 reasoning tokens per run (median ≈800–1,600 per answer), about 4× Ornith-1.5-9B, with 14–16/18 correct; reasoning_effort low/medium/xhigh made no difference. It also missed a systemd unit question that Ornith gets right. - Agent tasks: 7/10 (16 GB) and 9/10 (12 GB) on the RTX 3090, 21/30 over three more runs, 26/30 on ten additional control tasks.

Feedback welcome

Field reports are very welcome in the Community tab: GPU, driver, vLLM version, context and KV settings, whether it worked or not, and what failed.

Credits & license

Apache License 2.0, as the original NeoHorse-1-9B and Qwen3.5-9B. See NOTICE for what was changed and the attribution. Unofficial release by JRamirez-UAB; not affiliated with TokenRhythm, Alibaba Cloud or the Qwen team.

Configuration

Architecture
Qwen3_5ForConditionalGeneration
Context length (tokens)
262,144
Layers
32
Hidden size
4,096
Feed-forward size
12,288
Attention heads
16
Key/value heads
4
Head dimension
256
Vocabulary size
248,320
Model type
qwen3_5
Quantization
exl3

Identity and Version

Repository
JRamirez-UAB/NeoHorse-1-9B-EXL3-16GB-12GB
Publisher
Jorge Ramírez Espejo
Task
Image and text to text
Modality
Image and text
Library
exllamav3
Parameters
4.4B parameters
Languages
es, en
Revision
baf2ef64793e032c7448a61a3926852fec174b5e
First published
2026-10-11
Last updated
2026-10-16

Files and Weights

24 files, 7.8 GB in total. The weights are 2 files totalling 7.7 GB in safetensors.

Weights2 files · 7.7 GB
Configuration11 files · 470.7 KB
Tokenizer4 files · 22.9 MB
Documentation3 files · 41.2 KB
Other3 files · 8.6 KB
Repository1 file · 1.6 KB
Every file
FileTypeSizeSHA-256
model-00001-of-00002.safetensorsWeights7.6 GB aa0dcb436327
model-00002-of-00002.safetensorsWeights164.7 MB 567c433bf9c8
config.jsonConfiguration3.7 KB —
generation_config.jsonConfiguration223 B —
model.safetensors.index.jsonConfiguration184.0 KB —
plugin/qwen38_exl3_vision/qwen38_exl3_vision/__init__.pyConfiguration7.6 KB —
plugin/qwen38_exl3_vision/qwen38_exl3_vision/moe.pyConfiguration13.2 KB —
plugin/qwen38_exl3_vision/qwen38_exl3_vision/service_ple.pyConfiguration10.0 KB —
plugin/qwen38_exl3_vision/qwen38_exl3_vision/tp.pyConfiguration9.4 KB —
preprocessor_config.jsonConfiguration390 B —
quantization_config.jsonConfiguration238.2 KB —
scripts/embed_int8.pyConfiguration3.6 KB —
video_preprocessor_config.jsonConfiguration385 B —
LICENSEDocumentation11.3 KB —
NOTICEDocumentation1.9 KB —
README.mdDocumentation28.0 KB —
SHA256SUMSOther198 B —
chat_template.jinjaOther7.8 KB —
plugin/qwen38_exl3_vision/pyproject.tomlOther607 B —
.gitattributesRepository1.6 KB —
merges.txtTokenizer3.4 MB —
tokenizer.jsonTokenizer12.8 MB 5f9e4d4901a9
tokenizer_config.jsonTokenizer16.7 KB —
vocab.jsonTokenizer6.7 MB —

License and Download

License
apache-2.0
Access
Open weights, no gate
Download size
7.7 GB
Download from Jorge Ramírez Espejo

Released by Jorge Ramírez Espejo through its official repository on Hugging Face. Read the license.

Built From

  • Derived from TokenRhythm/NeoHorse-1-9B
  • Quantized from TokenRhythm/NeoHorse-1-9B

Memory Requirements

PrecisionWeights in memory
As published7.7 GB
16-bit8.8 GB
8-bit4.4 GB
4-bit2.2 GB

Weights only, from the published parameter count; the key-value cache and runtime add to this.

Questions About NeoHorse-1-9B-EXL3-16GB-12GB

How much GPU memory does NeoHorse-1-9B-EXL3-16GB-12GB need?

About 10.5 GB at 16-bit and 2.6 GB at 4-bit: the weights (4.4B parameters) plus a working margin. A long context needs more.

What is the cheapest GPU to run NeoHorse-1-9B-EXL3-16GB-12GB on?

At 16-bit, 1x MI300X from $1.85 an hour; at 4-bit, 1x MI300X from $1.85 an hour, at the lowest on-demand prices the SAVRN Index lists.

Can I use NeoHorse-1-9B-EXL3-16GB-12GB commercially?

Yes. NeoHorse-1-9B-EXL3-16GB-12GB is released under Apache License 2.0. The Apache License 2.0 is a permissive open-source license. It permits commercial use, modification and redistribution. It requires keeping the license and copyright notices and any NOTICE file, stating significant changes, and it includes an express patent grant from contributors.

What is NeoHorse-1-9B-EXL3-16GB-12GB's context length?

262,144 tokens, from the maximum position embeddings in its published configuration.

Similar Models

Model · Image and text to text

Ornith-1.5-9B-EXL3-16GB-12GB

Jorge Ramírez Espejo

An EXL3 quantization of ornith-ai/Ornith-1.5-9B made with exllamav3's per-tensor bit-allocation ("SC") pipeline with our own calibration, in two sizes: - main — 6.00 bpw, for 16 GB GPUs (e.g. RTX 5060 Ti 16 GB / 4060 Ti 16 GB): the full 262,144-token context with vision, MTP speculative decoding and 2 concurrent sessions, KL divergence 0.0019 against BF16. - 4.50bpw — 4.50 bpw, for 12 GB GPUs (e.g. RTX 3060 12 GB): 198,000 tokens with vision or 220,000 text-only, KLD 0.0095. Both are served with vLLM (continuous batching) through the OrcaSAQ2 plugin and a small plugin of ours (included), with INT8 token embeddings. Highlights (one RTX 3090 24 GB, measured on 2026-10-14; details in Family…

Open weights mit 4.4B parameters 262,144 tokens exllamav3

Model · Image and text to text

Qwen3-VL-4B-Instruct

Qwen

Meet Qwen3-VL — the most powerful vision-language model in the Qwen series to date. This generation delivers comprehensive upgrades across the board: superior text understanding & generation, deeper visual perception & reasoning, extended context length, enhanced spatial and video dynamics comprehension, and stronger agent interaction capabilities. Available in Dense and MoE architectures that scale from edge to cloud, with Instruct and reasoning‑enhanced Thinking editions for flexible, on‑demand deployment. Text Understanding on par with pure LLMs: Seamless text–vision fusion for lossless, unified comprehension. 1. Interleaved-MRoPE: Full‑frequency allocation over time, width, and height…

Open weights apache-2.0 4.4B parameters 262,144 tokens transformers

Model · Image and text to text

gemma-3-4b-it

Google

[Gemma 3 Technical Report][g3-tech-report] [Responsible Generative AI Toolkit][rai-toolkit] [Gemma on Kaggle][kaggle-gemma] [Gemma on Vertex Model Garden][vertex-mg-gemma3] Summary description and brief definition of inputs and outputs. Gemma is a family of lightweight, state-of-the-art open models from Google, built from the same research and technology used to create the Gemini models. Gemma 3 models are multimodal, handling text and image input and generating text output, with open weights for both pre-trained variants and instruction-tuned variants. Gemma 3 has a large, 128K context window, multilingual support in over 140 languages, and is available in more sizes than previous…

Access requested at publisher gemma 4.3B parameters transformers

Model · Image and text to text

medgemma-4b-it

Google

Model on Google Cloud Model Garden: MedGemma GitHub repository (supporting code, Colab notebooks, discussions, and Foundations terms of use](https://developers.google.com/health-ai-developer-foundations/terms). This section describes the MedGemma model and how to use it. MedGemma is a collection of Gemma 3 variants that are trained for performance on medical text and image comprehension. Developers can use MedGemma to accelerate building healthcare-based AI applications. MedGemma currently comes in three variants: a 4B multimodal version and 27B text-only and multimodal versions. Both MedGemma multimodal versions utilize a SigLIP image encoder that has been specifically pre-trained on a…

Access requested at publisher other 4.3B parameters transformers

Model · Image and text to text

Mephisto-1.5-4B

Model Merge JP

Mephisto-1.5-4B is a 4B-parameter agentic language model constructed via multi-stage model merging using mergekit. The model integrates reasoning, coding, and agentic capabilities into a single 4B checkpoint based on the Qwen3.5-4B architecture, targeting performance exceeding Mephisto-4B-v2 on Japanese and agentic benchmarks while maintaining deployment feasibility on consumer hardware (RTX 3060 12GB). The model is constructed through a three-stage merging pipeline: Normalized spherical linear interpolation (NuSLERP) on task vectors derived from a common base model (Qwen3.5-4B). This stage fuses a reasoning-distilled model (Opus-reasoning distillation) with a code-specialized model.…

Open weights 4.2B parameters 262,144 tokens transformers

Model · Image and text to text

h2o-lightning-4b

H2O.ai

H2O-Lightning-4B is a 4B-parameter decision model from H2O.ai, built on Qwen/Qwen3.5-4B. It answers typed decision questions about a record (a document, a ticket, a policy, a conversation) and about images that come with the record (photos, screenshots, scanned documents, charts). It returns a probability for every option: - yes/no (noul): gives the probability that a statement is true; It runs on unmodified vLLM 0.30.0 with a small standard-library shim in front (h2olightningshim.py). Each decision is one forward pass and one output token, so the cost is input tokens only. Try it in your browser: live demo on Hugging Face Spaces (text and images; built by the Hugging Face team and running…

Open weights apache-2.0 4.5B parameters 262,144 tokens transformers