InferBench

by rudrendupaul

Not rated
GitHub

About

Benchmarks local LLM inference speed (tokens/sec) on your own hardware via MCP tools.

Details

Author
rudrendupaul
Categories
Developer Tools, AI

Setup

Install InferBench in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/rudrendupaul/InferBench

Follow the installation instructions in the repository README, then restart your MCP client.

Every "best local LLM engine" article benchmarks someone else's machine. InferBench benchmarks yours.

Local-inference engines all publish their own benchmarks, on their own hardware, in their own README. None of them tell you which one is actually fastest on the machine sitting in front of you. InferBench runs a fixed, varied prompt set against whichever supported engines are installed on your own hardware and reports real, measured tokens/second -- not a number copied from someone else's blog post.

Install, first run, and a real omlx benchmark against a cached model:

npx inferbench-cli run --engines llama.cpp --model "bartowski/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M"

- Install
-
Features
-
Quickstart
-
CLI command reference
-
Library API reference
-
How the measurement works
-
Comparison
-
Why this exists
-
Documentation
-
FAQ
-
Contributing
-
Security
-
License

InferBench ships two independent, equally first-class packages -- pick whichever fits your toolchain, or install both. Neither is deprecated in favor of the other; both run the same measurement architecture against the same two supported engines.

# npm -- JavaScript/TypeScript CLI npm install -g inferbench-cli # or, no install: npx inferbench-cli run --engines llama.cpp --model "<repo>:<quant>" # PyPI -- Python CLI + library (genuine port, not a wrapper around the Node binary) pip install inferbench-cli

Both packages are published and installable today.npm install -g inferbench-cliandpip install inferbench-cliboth work -- seenpmjs.com/package/inferbench-cliandpypi.org/project/inferbench-cli, orpython/README.mdanddocs/getting-started.mdfor the Python-specific walkthrough, andCHANGELOG.mdfor each distribution's version history.

Requires Node.js >=18 for the npm package, Python >=3.9 for the PyPI package. At least one supported engine must already be installed either way (InferBench does not install engines for you):

- llama.cpp:brew install llama.cpp(macOS) or build fromggml-org/llama.cpp
- omlx:brew tap jundot/omlx https://github.com/jundot/omlx && brew install omlx(Apple Silicon only)

- Cross-engine, same measurement code.InferBench starts each engine's own OpenAI-compatible HTTP server (llama-server,omlx serve) and sends every engine the identical prompt set through the identical timing code, instead of comparing numbers each engine's own benchmark tool produced differently.
- Full-response-body timing, not headers.An earlier version of this code measured elapsed time right after the HTTP response object resolved, which only captures headers arriving, and once reported a physically impossible 64,646 tok/s before the bug was caught. Both distributions now time the complete response body, with a regression test guarding the fix in each language's harness.
- 8-prompt fixed sweep with warm-up.One throwaway completion absorbs first-request latency, then 8 varied prompts are timed individually and reported as avg/min/max tok/s (n=8in the results table).
- Two independently maintained distributions, matching output.npm'sinferbench-cli(TypeScript) and PyPI'sinferbench-cli(a genuine Python port, not a wrapper around the Node binary) expose the same CLI flags and the same JSON report field names.
- Machine-readable reports.--json/--out <file>writes a fullBenchmarkReportas camelCase JSON on both distributions, so CI or an agent can parse it without special-casing which language produced it.
- Local cloud-cost context (Python library).compare_to_cloud()looks up a static, dated cloud API price alongside your measured local throughput -- it discloses plainly that it's a snapshot, not a live quote, and returnsNonefor a model it doesn't recognize rather than guessing a number.
- Path-safe--out.A relative--outvalue that resolves outside the current working directory is rejected, so an agent-supplied output path can't escape the intended directory.

# llama.cpp -- pass a Hugging Face repo spec; llama.cpp downloads and # caches it automatically, no manual step required inferbench run --engines llama.cpp --model "bartowski/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M" # omlx -- pass the model-directory subdirectory name under ~/.omlx/models/; # omlx has no CLI download flow, so the model must already be present there # (download it once via omlx's own admin dashboard, or huggingface_hub's # snapshot_download into that directory) inferbench run --engines omlx --model "qwen2.5-1.5b-instruct-4bit" # Both installed engines, machine-readable output, saved to a file inferbench run --model "<spec>" --json --out report.json

Real output from a live run against an actualllama-serverprocess:

$ inferbench run --engines llama.cpp --model "bartowski/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M" Hardware: Apple M4 (darwin/arm64), 16GB llama.cpp: starting server... llama.cpp: warming up... llama.cpp: [1/8] benchmarking... ... llama.cpp: [8/8] benchmarking... Results: llama.cpp: avg 75.54 tok/s (range 69.54-79.78, n=8) Recommendation: llama.cpp -- highest measured throughput on this run (75.54 tok/s avg) -- specific to this hardware and model, not a universal ranking

[!WARNING]--modelmeans something different per engine (a downloadable HF spec for llama.cpp, a pre-downloaded local directory name for omlx), because the two engines have genuinely different model-acquisition capabilities -- omlx'sservecommand has no flag to pull an arbitrary model from Hugging Face directly. Running both engines against thesamemodel in one command therefore needs the model already available in both engines' own expected forms.

inferbench run [options] Options: --model <spec> Model spec (engine-specific, see Quickstart above) [required] --engines <list> Comma-separated engines to test (default: all installed -- omlx, llama.cpp) --max-tokens <n> Max completion tokens per prompt (default: 200) --json Output machine-readable JSON instead of a human table --out <file> Also write the full JSON report to this file --verbose Show raw engine server stdout/stderr

Exit code0on a successful run with at least one engine tested;1on a usage error or when no supported engine is installed. The Python CLI has one small, documented divergence: a missing required--modelflag exits2(the standardargparseconvention for a parse-time error) instead of1.

The Python package (pip install inferbench-cli) exposes a documented library surface, meant for use in scripts or notebooks instead of the CLI. The npm package'spackage.jsonmainfield points at the CLI script itself (dist/cli.js, which runs the argument parser as a side effect on import) and does not declare a separate library entry point, so today only the Python distribution is a supported library import.

from inferbench import ( benchmark_engine, detect_hardware, all_engines, resolve_engines, recommend, compare_to_cloud, report_to_dict, write_json_report, )
from inferbench import benchmark_engine, detect_hardware, all_engines, recommend, compare_to_cloud hardware = detect_hardware() results = [ benchmark_engine(adapter, model="qwen2.5-1.5b-instruct-4bit") for adapter in all_engines() ] best = recommend(results) print(f"{hardware.cpu_model}: {best.engine} -- {best.reason}") # What would the same output volume cost on a cloud API instead? cost = compare_to_cloud("claude-5-haiku") if cost: print(f"{cost.cloud_model}: ${cost.cloud_cost_per_1k_tokens_usd}/1K tokens (snapshot {cost.pricing_snapshot_date})")

InferBench ships aModel Context Protocolserver so an AI agent (Claude, Cursor, or any MCP-compatible client) can run a hardware benchmark directly, without a human invoking the CLI by hand.

pip install "inferbench-cli[mcp]"

Add it to your MCP client's config (for Claude Desktop,claude_desktop_config.json):

{ "mcpServers": { "inferbench": { "command": "uvx", "args": ["--from", "inferbench-cli", "inferbench-mcp"] } } }

The server exposes one tool,run, that shells out to the publishedinferbenchnpm binary with the given subcommand and arguments plus--json, and returns the parsed result:

run(["run", "--engines", "llama.cpp", "--model", "bartowski/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M"])

Transport is stdio, so there is nothing to host: the MCP client spawns the server as a local subprocess. Source:python/src/inferbench/mcp_server.py.

InferBench does not shell out to each engine's own benchmark tool and parse its output. That approach was in the original plan and turned out not to work at all:omlxhas no CLI benchmark command -- its "Performance Benchmark" feature is a GUI-only, one-click action in its admin dashboard, verified directly against its real README before writing a line of adapter code.

Instead, InferBench starts each engine's own already-standardized OpenAI-compatible HTTP server (omlx serve,llama-server) and sends the exact same prompts through the exact same measurement code to every engine, timing the full response (not just time-to-first-byte). This is the only approach that is genuinely apples-to-apples across engines with fundamentally different internals, and the only one that works at all foromlx.

What "recommended" means (and doesn't):the recommendation in every report names the engine with the highest measured average tokens/secondon this specific run, this specific hardware, this specific model-- not a general claim about which engine is best. A different model, a different machine, or a different day's thermal conditions can change the answer; two runs during this tool's own development produced opposite rankings betweenomlxandllama.cppon the same hardware and model, which is itself the reason this tool measures live rather than quoting a fixed number.

Three real, independently maintained tools sit in the same space, each with a different scope. Any cell not pulled from the linked project's own docs is marked accordingly.

Local inference on consumer hardware is now the default path for a growing share of developers, and every engine's own comparison against its competitors has an obvious incentive problem: no vendor is a disinterested judge of its own numbers. InferBench has no engine of its own to sell, which is the entire point.

The harder question this tool actually answers isn't "which engine is fastest in general" -- there is no such answer, because it depends on your exact hardware, your exact model, and your exact workload. It's "which engine is fastestright now, on this machine, for this model" -- a question only a tool that runs on your own hardware can answer honestly.

- docs/getting-started.md-- install, first run, and using the library instead of the CLI, for both distributions.
-
docs/concepts.md-- the measurement architecture, the hardware detector, the recommendation rule, and the exit-code contract.
-
docs/integrations/ci.md-- why InferBench is deliberately not a per-PR CI gate, and what patterns work instead.

Machine-readable output written to a file with--json --out, useful for CI or for an agent parsing the result:

Benchmarking multiple engines side by side, with a real measured recommendation between them:

What is InferBench, exactly?A benchmarking tool for local-LLM-inference engines already installed on your machine -- currentlyomlxandllama.cpp. It runs a fixed, varied prompt set against whichever of those are present, measures real tokens/second for each, and recommends whichever one was fastest on that specific run. It ships as two packages under the same name,inferbench-cli: one on npm (JavaScript/TypeScript) and one on PyPI (Python).

How is InferBench different from llama.cpp's ownllama-bench?llama-bench(bundled with llama.cpp) only benchmarks llama.cpp itself, with fine-grained tuning knobs (batch size, cache type, thread count, repetitions, and more) and outputs to Markdown, CSV, JSON, JSONL, or SQL. InferBench benchmarksacrossengines -- currentlyomlxandllama.cpp-- using the same prompt set and the same measurement code for both, so the resulting tokens/second numbers are directly comparable to each other on your hardware, not just tunable in isolation for one engine.

Does InferBench work on Linux and Windows, or only macOS?Thellama.cppengine works on any platform llama.cpp itself supports (Linux, macOS, Windows), since InferBench just startsllama-serverand measures its OpenAI-compatible endpoint. Theomlxengine is Apple Silicon-only, matching omlx's own scope -- on Linux or Windows,--engines omlxreports that engine as not installed and InferBench benchmarks whatever supported engine actually is present. Node.js >=18 is required for the npm package, Python >=3.9 for the PyPI package.

Does InferBench download models for me?For llama.cpp, yes -- pass a Hugging Face repo spec andllama-server's own-hfflag downloads and caches it. For omlx, no -- omlx'sservecommand only discovers models already present in a local directory, so you need to have the model downloaded there first.

Does any data leave my machine?No. Every benchmark request goes to a server InferBench itself started on127.0.0.1. Nothing is uploaded anywhere.

Why does--enginessometimes need a different--modelvalue per engine?Becauseomlxandllama.cpphave genuinely different model-acquisition mechanisms -- see the Known limitation note in Quickstart above.

Is the recommendation a guarantee this engine is fastest for me generally?No. It's the fastest engine measured on this exact run. Re-run it -- your own hardware, your own model, your own moment -- rather than trusting a number from a different machine or a different day.

Is--outsafe to point at a path that comes from an agent or other less-trusted input?Yes, with one documented restriction:--outrejects a relative path that resolves outside the current working directory (for example--out ../../etc/cron.d/x), specifically so a benchmark invoked with an agent-supplied path can't be tricked into writing outside the intended directory. An absolute path is still accepted, since that's a value the caller passed directly rather than one that escaped via..traversal.

What happens if no supported engine is installed, or a run fails partway through?If neitheromlxnorllama.cppis found, InferBench exits with code1and a message naming both install commands rather than returning a silent empty result. If an engine is installed but a specific run fails, that engine's line in the report readsFAILEDwith the underlying error instead of a number -- any other engine that did complete still gets a real result and remains eligible for the recommendation.

Can I use InferBench commercially, and is it free?Yes. InferBench is Apache License 2.0, which permits commercial use, modification, and redistribution with no licensing fee. It has no paid API dependency -- every benchmark request goes to a server it starts locally on your own machine.

SeeCONTRIBUTING.mdfor the full guide, covering both the TypeScript and Python codebases. Issues and PRs welcome. Known deferred scope includes additional engine adapters, a hosted fleet dashboard, and richer recommendation scoring -- open an issue if you'd like to pick one of these up.

SeeSECURITY.mdfor the vulnerability-reporting process.

This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases.

next-devtools-mcp is a MCP server that provides Next.js development tools and utilities for AI coding assistants like Claude and Cursor.

Word search, crossword, and sudoku generator MCP server with printable PDF worksheets, themed word banks, and verifiable LLM evals. Local-first, from the makers of puzzletide.com.

A demonstration server for ActionKit, providing access to Slack actions via Claude Desktop.

MCP server that lets Claude Code agents delegate tasks to agents in other project directories, with parallel dispatch, sessions, and async jobs.

Statistical regression testing for LLM agents: p-value, effect size, and CI on behavior change.

A Python MCP package that gives your LLM agents complete file system and shell capabilities — production-ready, sandboxed, and wired to any LLM in minutes.

Integrates with Google AI Studio/Gemini API for PDF to Markdown conversion and content generation.

Anchor Browser (https://anchorbrowser.io) is secure infrastructure for computer-use agents — stealth cloud browsers, authentication, captcha bypass, and a hosted MCP server for Cursor, Claude, and Windsurf.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.