AI Development

Mellum2.1: Running JetBrains’ Open Coding-Agent Model Locally with vLLM

October 14, 2026
9 min read
Compact GPU workstation with an open side panel on a tidy desk in soft window light
Share:

In early October 2026, JetBrains published Mellum2.1, an open-weight 12B mixture-of-experts model with 2.5B active parameters, an Apache 2.0 license and a 131,072-token context window. It keeps the Mellum2 architecture from June and puts nearly all of its effort into reinforcement-learning post-training for agentic coding.

The headline is JetBrains’ own SWE-bench Verified score: 47.0, up from 2.0 for Mellum2. Here is what I could verify, the exact vLLM commands from the model card, a sketch for wiring it into an agent loop, and where it should not replace a bigger model. I read the sources; I did not benchmark the model myself.

1. What JetBrains shipped

Mellum started life as a code-completion model. Mellum2, released in June 2026 with a technical report on arXiv, was the move to a 12B mixture-of-experts design that activates about 2.5B parameters per token. Mellum2.1 is the next version of that Thinking model: same architecture, new post-training.

The weights are on Hugging Face under JetBrains/Mellum2.1-12B-A2.5B-Thinking. The launch post positions it for coding agents and fast sub-agents on your own hardware. There is no hosted JetBrains API or per-token price that I could find, so self-hosting is the path.

Model card at a glance

  • • Release: early October 2026 (JetBrains’ launch post sits under /2026/10/; third-party trackers date the Hugging Face release October 8) — successor to Mellum2 from June 2026
  • • Model: JetBrains/Mellum2.1-12B-A2.5B-Thinking — 12B total / 2.5B active parameters (MoE: 64 experts, 8 active per token)
  • • Context: 131,072 tokens; sliding-window attention (1,024) on 3 of every 4 layers; 28 layers; bfloat16
  • • License: Apache 2.0 (weights on Hugging Face)
  • • Price: no hosted API or per-token price found — you self-host; the BF16 checkpoint is ~24.3 GB
  • • Serving: vLLM (--reasoning-parser qwen3, hermes parser for tool calling); JetBrains GGUF repo for llama.cpp/Ollama; the MTP head for vLLM is still listed as coming soon

2. What changed vs Mellum2

Same skeleton, different training. JetBrains says the architecture is unchanged and that reinforcement learning became the main part of training rather than a short final stage. The data widened to math, competitive programming, science, tool use and software engineering, and JetBrains built in-house infrastructure that launched millions of sandboxes.

The practical shift is stated plainly in the launch post: Mellum2 could not work inside a repository at the level JetBrains wanted, while Mellum2.1 is meant to explore a codebase, edit files and check its own changes. That is the difference between a completion-style model and one you can put in a loop.

The three jumps (model card, self-reported)

🔧

Agentic coding

SWE-bench Verified 2.0 → 47.0, SWE-bench Pro 0.0 → 28.0, Terminal-Bench 2.1 0.6 → 17.4. Evaluated by JetBrains in an agent harness with shell and file tools.

🧮

Reasoning

LiveCodeBench v6 69.4 → 82.0, AIME 25/26 60.1 → 83.3, GPQA Diamond 51.0 → 64.6, IFEval 79.5 → 90.6.

🛠️

Tools and safety

BFCL v4 49.6 → 62.3, HarmBench (lower is better) 21.5 → 8.5. Not everything moved: WorkBench is flat (45.1 → 44.6) and XSTest slipped (91.2 → 88.8).

Golden rule

Same size, same serving cost, different behavior: the gain is post-training, not scale. If you tried Mellum2 for agent work and dropped it, that verdict is stale. If you never needed a small model, nothing here changes that.

3. The numbers, with provenance

Every score below comes from the Hugging Face model card and was produced by JetBrains. Non-agentic benchmarks used greedy decoding. Agentic ones used a harness called Pi (v0.73.1) with shell and file tools, a 114K-token context, up to 16K tokens per turn and temperature 1.0. The comparison set is Mellum2, Gemma 4 (E4B) and Qwen3.5 (9B).

Speed is a separate claim from the launch post: on one H200, under heavy load, JetBrains says Mellum2.1 serves almost twice as many tokens as Qwen3.5-9B, and that multi-token prediction would make a single request about 1.6 times faster. The exact values appear only in a chart, and the MTP head for vLLM is listed as coming soon.

What the card says (order: Mellum2.1 / Qwen3.5 9B / Gemma 4 E4B / Mellum2)

  • • SWE-bench Verified: 47.0 / 50.0 / 23.0 / 2.0 — Qwen3.5 (9B) is ahead
  • • SWE-bench Pro: 28.0 / 38.0 / 4.0 / 0.0 — Qwen3.5 (9B) is ahead
  • • Terminal-Bench 2.1: 17.4 / 21.7 / 3.4 / 0.6 — Qwen3.5 (9B) is ahead
  • • LiveCodeBench v6: 82.0 / 75.4 / 69.4 / 69.4 — Mellum2.1 leads
  • • BFCL v4 (tool calling): 62.3 / 58.5 / 52.5 / 49.6 — Mellum2.1 leads
  • • GPQA Diamond: 64.6 / 77.8 / 53.1 / 51.0 — Qwen3.5 (9B) is well ahead
  • • HarmBench (lower is better): 8.5 / 6.6 / 38.1 / 21.5

Read the fine print

All of it is vendor-run: JetBrains picked the harness, the context cap and the competitors, and as of October 14, 2026 I found no independent rerun. Do not mix numbers across cards either: the Mellum2.1 card lists LiveCodeBench v6 at 69.4 for Mellum2, while the original Mellum2 card listed 69.9, so they come from different evaluation setups.

4. Quickstart: serve it with vLLM

The card’s serving recipe is two commands: one without tool calling, one with. For an agent you want the second. Both pass --max-model-len 131072 and the qwen3 reasoning parser, which splits the thinking trace from the final answer. vLLM’s supported-models page lists the MellumForCausalLM architecture; the card states no minimum vLLM version, so use a recent release.

Memory is the real question, and the card gives no VRAM guidance. The numbers below are my arithmetic from the checkpoint size and config.json, not measurements. The 2.5B active parameters cut compute per token, not memory: all 12B must be resident.

Memory math (mine, not from the card)

  • • Weights: 12,149,923,072 parameters in bfloat16 is about 24.3 GB of safetensors. That is the floor for BF16 serving, before KV cache.
  • • KV cache (config: 28 layers, 4 KV heads, head_dim 128, bf16): about 14 KiB per token if only the 7 full-attention layers keep full history, about 56 KiB per token if all 28 did. At 131,072 tokens that is roughly 1.9 GB to 7.5 GB per sequence.
  • • Reading that: a 40–48 GB card holds BF16 plus a full-length context with room; 32 GB is tight at the full window; 24 GB cannot hold BF16 once KV cache and CUDA overhead are counted.
  • • Smaller cards: JetBrains’ GGUF repo lists Q4_K_M at 8.1 GB (marked recommended), Q6_K 10.9 GB, Q8_0 12.9 GB and MXFP4_MOE 7.0 GB. Its quality figures are KL divergence and top-token agreement on Wikitext-2, not coding-agent evals.

vLLM, without tool calling

Verified against the model card on 2026-10-14. Reasoning lands in a separate field.

vllm serve JetBrains/Mellum2.1-12B-A2.5B-Thinking \
  --max-model-len 131072 \
  --reasoning-parser qwen3

vLLM, with tool calling (what an agent needs)

Verified against the model card on 2026-10-14. Adds auto tool choice and the hermes tool-call parser.

vllm serve JetBrains/Mellum2.1-12B-A2.5B-Thinking \
  --max-model-len 131072 \
  --reasoning-parser qwen3 \
  --enable-auto-tool-choice \
  --tool-call-parser hermes

Client quickstart from the card

Verified against the model card on 2026-10-14. OpenAI() reads OPENAI_BASE_URL and OPENAI_API_KEY from the environment; point the first at your server’s /v1 (vLLM listens on port 8000 by default).

from openai import OpenAI
# Configured by environment variables
client = OpenAI()

messages = [
    {"role": "user", "content": "Find the bug in this function and explain the fix: def mean(xs): return sum(xs) / len(xs) - 1"},
]

chat_response = client.chat.completions.create(
    model="JetBrains/Mellum2.1-12B-A2.5B-Thinking",
    messages=messages,
    max_tokens=81920,
    temperature=0.6,
    top_p=0.95,
    extra_body={"top_k": 20},
)
print("Chat response:", chat_response)

Smaller GPU or laptop: JetBrains’ GGUF build

From the GGUF repo card, 2026-10-14. The launch post still lists GGUF as coming soon, but the repo was already in JetBrains’ collection; I did not verify tool calling on this path.

# JetBrains GGUF repo, Q4_K_M (the quant its card marks as recommended)
ollama run hf.co/JetBrains/Mellum2.1-12B-A2.5B-Thinking-GGUF:Q4_K_M

# or llama.cpp
llama-server -hf JetBrains/Mellum2.1-12B-A2.5B-Thinking-GGUF:Q4_K_M --ctx-size 131072 --temp 0.6 --top-p 0.95 --top-k 20

Lever for small GPUs

--max-model-len is how you trade context for memory. The card sets 131072; lowering it shrinks the KV cache you reserve. I have not tested which value fits which card, so start low and raise it until you hit your agent’s real context needs.

5. Wire it into a coding-agent loop

vLLM exposes an OpenAI-compatible server, so any harness that accepts a base URL and speaks chat-completions with tools can point at it. The sketch below is the smallest loop I would use to test the model: one tool, a step cap, no memory tricks, the card’s sampling settings and a per-turn token cap.

Two details from the vLLM docs matter. Reasoning comes back in its own field (currently reasoning, formerly reasoning_content, so read both). And tool calls are parsed only from the content, not from inside the reasoning: if the model emits a call inside its think block, your loop sees nothing.

Minimal agent loop against the local endpoint

My sketch, not from the model card, and I have not run it. It shows the shape: tools, tool_choice auto, reasoning logged, assistant turns replayed without the thinking text.

import json
import subprocess
from openai import OpenAI

# Sketch: not from the model card, not run by me.
client = OpenAI(base_url="http://localhost:8000/v1", api_key="local")
MODEL = "JetBrains/Mellum2.1-12B-A2.5B-Thinking"

TOOLS = [{
    "type": "function",
    "function": {
        "name": "run_shell",
        "description": "Run a shell command in the repo; returns stdout and stderr.",
        "parameters": {
            "type": "object",
            "properties": {"cmd": {"type": "string"}},
            "required": ["cmd"],
        },
    },
}]

def run_shell(cmd: str) -> str:
    # DANGER: model-written commands. Run inside a container, no secrets mounted.
    p = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=120)
    return (p.stdout + p.stderr)[-8000:]

messages = [
    {"role": "system", "content": "You are a coding agent. Explore with run_shell, edit files, run the tests, stop when they pass."},
    {"role": "user", "content": "tests/test_mean.py fails. Find the cause and fix it."},
]

for step in range(20):
    resp = client.chat.completions.create(
        model=MODEL,
        messages=messages,
        tools=TOOLS,
        tool_choice="auto",
        max_tokens=16384,          # per-turn cap; the card quickstart uses 81920
        temperature=0.6,
        top_p=0.95,
        extra_body={"top_k": 20},  # same sampling as the card quickstart
    )
    choice = resp.choices[0]
    msg = choice.message
    reasoning = getattr(msg, "reasoning", None) or getattr(msg, "reasoning_content", None)
    print(f"[step {step}] finish={choice.finish_reason} reasoning_chars={len(reasoning or '')} tool_calls={len(msg.tool_calls or [])}")

    assistant = {"role": "assistant", "content": msg.content or ""}
    if msg.tool_calls:
        assistant["tool_calls"] = [
            {
                "id": c.id,
                "type": "function",
                "function": {"name": c.function.name, "arguments": c.function.arguments},
            }
            for c in msg.tool_calls
        ]
    messages.append(assistant)

    if not msg.tool_calls:
        print(msg.content)
        break

    for c in msg.tool_calls:
        args = json.loads(c.function.arguments)
        messages.append({"role": "tool", "tool_call_id": c.id, "content": run_shell(args["cmd"])})

Before you trust the loop

  1. 1. Start the server with the tool-calling command and confirm /v1/models lists JetBrains/Mellum2.1-12B-A2.5B-Thinking.
  2. 2. Start with the card’s sampling (temperature 0.6, top_p 0.95, top_k 20), then A/B temperature 1.0, which is what JetBrains used for its agentic benchmarks.
  3. 3. Cap tokens per turn and total context. JetBrains’ benchmarks ran at 16K per turn and 114K context, far below the quickstart’s 81,920 max_tokens.
  4. 4. Log finish_reason, reasoning length and tool-call parse failures. A cap that truncates the think block gives you an empty answer.
  5. 5. Judge success with your test suite, never with the model’s own claim that it is done.

Run it in a sandbox

The loop executes shell commands written by a model. Use a disposable container or VM, mount no credentials, and keep network egress off unless the task needs it. A small MoE will sometimes be confidently wrong.

6. Where it fits, and the honest limits

JetBrains frames Mellum2.1 as a model for coding agents and fast sub-agents on your own hardware, not as a frontier replacement. Its comparison set is small models only. I have no same-harness numbers for larger or closed models, so I will not invent a gap; that is the question your own eval has to answer.

For Mellum2, the launch post suggested sub-agent jobs such as planning, validation, transformation and context preparation. Mellum2.1 keeps that role and adds repository-level edits, but the card’s own table shows a 9B rival ahead on the hardest agentic evals.

Where I would try it

  • • Many parallel sub-agents on a fixed GPU budget, where throughput per dollar matters more than the last few points of resolve rate.
  • • Code that cannot leave your network: Apache 2.0 weights, one GPU, no external API.
  • • A cheap first pass before escalation: let it try, run the tests, escalate to a bigger model on failure. That pattern is my suggestion, not JetBrains’.
  • • Competitive-programming and reasoning-heavy snippets, where its self-reported LiveCodeBench v6 score of 82.0 is its strongest result.

Honest limits

  • • Every benchmark is self-reported by JetBrains; I found no independent rerun as of October 14, 2026.
  • • 47.0 on SWE-bench Verified still means roughly half the tasks unresolved, in JetBrains’ harness at temperature 1.0 and 114K context. Your repo and harness will differ.
  • • Thinking mode is slow by design: the quickstart allows up to 81,920 output tokens, and JetBrains published no per-turn latency, only a throughput chart on one H200.
  • • The 1.6x single-request speed-up depends on an MTP head that is not in vLLM yet, so the commands above do not include it.
  • • Tool calling pairs it with vLLM’s hermes parser. Measure the tool-call parse rate on your own tools before you run unattended.
  • • The table has no long-context benchmark: 131,072 is the architectural limit, and I could not find quality numbers near the end of the window.
  • • Community quantizations (FP8, AWQ, MLX) already exist. I did not vet any of them; treat third-party weights as untrusted.

Verdict

Mellum2.1 is a credible small-footprint model for local agent work: Apache 2.0, one GPU, and a self-reported jump from 2.0 to 47.0 on SWE-bench Verified that comes from RL alone. It is not a frontier replacement, and the card itself shows Qwen3.5 (9B) ahead on SWE-bench Verified, SWE-bench Pro and Terminal-Bench 2.1.

What I would do: pull the weights, serve with the tool-calling command, run 20 to 50 of your own tickets with tests as the judge, and compare resolve rate, wall-clock and GPU cost against whatever you run now. Until someone outside JetBrains reruns SWE-bench, treat 47.0 as a promising number, not a settled one.

Sources for this post

Primary first, then secondary

  • • JetBrains AI blog: Mellum2.1 Gets to Work (October 2026)
  • • Hugging Face: Mellum2.1-12B-A2.5B-Thinking model card
  • • Hugging Face: Mellum2.1 GGUF repo, plus the Mellum2 card and launch post (previous generation)
  • • arXiv: Mellum2 Technical Report (May 29, 2026)
  • • vLLM docs: reasoning outputs and tool calling
  • • DataNorth AI: third-party write-up of the release (secondary)
Diego Rodriguez

Diego Rodriguez

Senior Full-Stack & AI Engineer

Diego has 10+ years of experience building production-grade AI-powered applications, from LLM orchestration and RAG pipelines to ML-driven risk detection and algorithmic trading systems.

Learn more about Diego →