InferBench
Avalia a velocidade de inferência local de LLMs (tokens/seg) no seu próprio hardware por meio de ferramentas MCP.
Documentação
InferBench
Todo artigo sobre "melhor mecanismo de LLM local" faz benchmark na máquina de outra pessoa. O InferBench faz benchmark na sua.
Os mecanismos de inferência local publicam seus próprios benchmarks, em seu próprio hardware, em seu próprio README. Nenhum deles diz qual é realmente o mais rápido na máquina que está na sua frente. O InferBench executa um conjunto fixo e variado de prompts contra os mecanismos suportados que estão instalados no seu próprio hardware e reporta tokens/segundo reais e medidos — não um número copiado do blog de outra pessoa.
Instalação, primeira execução e um benchmark real do omlx contra um modelo em cache:

npx inferbench-cli run --engines llama.cpp --model "bartowski/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M"
Sumário
- Instalação
- Recursos
- Início rápido
- Referência de comandos da CLI
- Referência da API de biblioteca
- Como a medição funciona
- Comparação
- Por que isto existe
- Documentação
- FAQ
- Contribuindo
- Segurança
- Licença
Instalação
O InferBench oferece dois pacotes independentes e igualmente de primeira classe — escolha o que melhor se adequa à sua ferramenta, ou instale ambos. Nenhum está obsoleto em favor do outro; ambos executam a mesma arquitetura de medição contra os mesmos dois mecanismos suportados.
# 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
Ambos os pacotes estão publicados e instaláveis hoje.
npm install -g inferbench-cli e pip install inferbench-cli ambos
funcionam — veja
npmjs.com/package/inferbench-cli
e pypi.org/project/inferbench-cli,
ou python/README.md e
docs/getting-started.md para o passo a passo
específico do Python, e CHANGELOG.md para o histórico
de versões de cada distribuição.
Requer Node.js >=18 para o pacote npm, Python >=3.10 para o pacote PyPI. Pelo menos um mecanismo suportado já deve estar instalado de qualquer forma (o InferBench não instala mecanismos para você):
- llama.cpp:
brew install llama.cpp(macOS) ou compile a partir de ggml-org/llama.cpp - omlx:
brew tap jundot/omlx https://github.com/jundot/omlx && brew install omlx(somente Apple Silicon)
Recursos
- Multi-mecanismo, mesmo código de medição. O InferBench inicia o servidor HTTP compatível com OpenAI de cada mecanismo (
llama-server,omlx serve) e envia a todos o mesmo conjunto de prompts através do mesmo código de temporização, em vez de comparar números que a ferramenta de benchmark de cada mecanismo produziu de forma diferente. - Temporização do corpo completo da resposta, não dos cabeçalhos. Uma versão anterior deste código media o tempo decorrido logo após o objeto de resposta HTTP ser resolvido, o que captura apenas a chegada dos cabeçalhos, e uma vez reportou um fisicamente impossível 64.646 tok/s antes de o bug ser detectado. Ambas as distribuições agora cronometram o corpo completo da resposta, com um teste de regressão protegendo a correção no harness de cada linguagem.
- Varredura fixa de 8 prompts com aquecimento. Uma conclusão descartável absorve a latência da primeira solicitação, então 8 prompts variados são cronometrados individualmente e reportados como média/mín/máx tok/s (
n=8na tabela de resultados). - Duas distribuições mantidas independentemente, saída correspondente. O
inferbench-clido npm (TypeScript) e oinferbench-clido PyPI (um port genuíno para Python, não um wrapper em torno do binário Node) expõem os mesmos flags da CLI e os mesmos nomes de campos no relatório JSON. - Relatórios legíveis por máquina.
--json/--out <file>grava umBenchmarkReportcompleto como JSON em camelCase em ambas as distribuições, para que CI ou um agente possa analisá-lo sem tratamento especial para saber qual linguagem o produziu. - Contexto local de custo de nuvem (biblioteca Python).
compare_to_cloud()consulta um preço estático e datado de API de nuvem junto com sua taxa de transferência local medida — ele declara claramente que é um instantâneo, não uma cotação ao vivo, e retornaNonepara um modelo que não reconhece, em vez de adivinhar um número. --outseguro para caminhos. Um valor relativo de--outque resolve para fora do diretório de trabalho atual é rejeitado, para que um caminho de saída fornecido por um agente não possa escapar do diretório pretendido.
Início rápido
# 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
Saída real de uma execução ao vivo contra um processo llama-server real:
$ 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
[!AVISO]
--modelsignifica algo diferente por mecanismo (uma spec HF baixável para llama.cpp, um nome de diretório local pré-baixado para omlx), porque os dois mecanismos têm capacidades genuinamente diferentes de aquisição de modelos — o comandoservedo omlx não tem flag para puxar um modelo arbitrário do Hugging Face diretamente. Executar ambos os mecanismos contra o mesmo modelo em um único comando, portanto, exige que o modelo já esteja disponível nas formas esperadas de ambos os mecanismos.
Referência de comandos da CLI
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
Código de saída 0 em uma execução bem-sucedida com pelo menos um mecanismo testado; 1 em um erro de uso ou quando nenhum mecanismo suportado está instalado. A CLI do Python tem uma pequena divergência documentada: um flag --model obrigatório ausente sai com 2 (a convenção padrão de argparse para erro em tempo de análise) em vez de 1.
Referência da API de biblioteca
O pacote Python (pip install inferbench-cli) expõe uma superfície de biblioteca documentada, destinada ao uso em scripts ou notebooks em vez da CLI. O campo main package.json do pacote npm aponta para o próprio script da CLI (dist/cli.js, que executa o analisador de argumentos como efeito colateral na importação) e não declara um ponto de entrada de biblioteca separado, então hoje apenas a distribuição Python é uma importação de biblioteca suportada.
from inferbench import (
benchmark_engine, detect_hardware, all_engines, resolve_engines,
recommend, compare_to_cloud, report_to_dict, write_json_report,
)
| Símbolo | Assinatura | O que retorna |
|---|---|---|
detect_hardware() | () -> HardwareProfile | Plataforma, arquitetura, string do modelo de CPU, memória total em GB e se a máquina é Apple Silicon. |
all_engines() | () -> List[EngineAdapter] | Uma instância de adaptador para cada mecanismo suportado (omlx, llama.cpp). |
resolve_engines(names) | (names: List[str]) -> List[EngineAdapter] | Adaptadores para uma lista de mecanismos fornecida pelo usuário e sem duplicatas; levanta erro em um nome não reconhecido. |
benchmark_engine(adapter, *, model, ...) | (adapter, *, model: str, max_tokens=None, prompts=None, verbose=False, on_progress=None) -> EngineBenchmarkResult | Executa a varredura fixa de prompts contra um mecanismo e retorna um resultado estruturado. Nunca levanta erro para "mecanismo não instalado" ou um prompt com falha — esse estado vive no objeto retornado. |
recommend(results) | (results: List[EngineBenchmarkResult]) -> Optional[Recommendation] | O mecanismo com a maior média medida de tok/s entre os mecanismos instalados e testados com sucesso. |
compare_to_cloud(cloud_model) | (cloud_model: str) -> Optional[CostComparison] | Um preço estático e datado por 1K tokens de saída para um modelo de nuvem conhecido (atualmente claude-5-haiku, claude-5-sonnet) mais uma nota de divulgação, ou None para um modelo que não reconhece. |
report_to_dict(report) / write_json_report(report, path) | (report: BenchmarkReport) -> dict / (report, path: str) -> None | Serializa um BenchmarkReport para a mesma forma JSON em camelCase que o --json / --out da CLI produzem. |
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})")
Servidor MCP
O InferBench inclui um servidor Model Context Protocol para que um agente de IA (Claude, Cursor ou qualquer cliente compatível com MCP) possa executar um benchmark de hardware diretamente, sem que um humano invoque a CLI manualmente.
Instale o extra:
pip install "inferbench-cli[mcp]"
Adicione-o à configuração do seu cliente MCP (para Claude Desktop, claude_desktop_config.json):
{
"mcpServers": {
"inferbench": {
"command": "uvx",
"args": ["--from", "inferbench-cli", "inferbench-mcp"]
}
}
}
O servidor expõe uma ferramenta, run, que chama o binário npm inferbench publicado com
o subcomando e argumentos fornecidos, mais --json, e retorna o resultado analisado:
run(["run", "--engines", "llama.cpp", "--model", "bartowski/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M"])
O transporte é stdio, então não há nada para hospedar: o cliente MCP inicia o servidor como um
subprocesso local. Fonte: python/src/inferbench/mcp_server.py.
Como a medição funciona
O InferBench não chama a ferramenta de benchmark de cada mecanismo e analisa sua saída. Essa abordagem estava no plano original e acabou não funcionando: omlx não tem comando de benchmark via CLI — seu recurso "Performance Benchmark" é uma ação somente GUI, de um clique, no painel administrativo, verificada diretamente contra seu README real antes de escrever uma linha de código de adaptador.
Em vez disso, o InferBench inicia o servidor HTTP compatível com OpenAI já padronizado de cada mecanismo (omlx serve, llama-server) e envia exatamente os mesmos prompts através do mesmo código de medição para cada mecanismo, cronometrando a resposta completa (não apenas o tempo até o primeiro byte). Esta é a única abordagem que é genuinamente comparável entre mecanismos com internals fundamentalmente diferentes, e a única que funciona para omlx.
O que "recomendado" significa (e não significa): a recomendação em cada relatório nomeia o mecanismo com a maior média medida de tokens/segundo nesta execução específica, neste hardware específico, neste modelo específico — não uma afirmação geral sobre qual mecanismo é melhor. Um modelo diferente, uma máquina diferente ou condições térmicas diferentes em outro dia podem mudar a resposta; duas execuções durante o desenvolvimento desta ferramenta produziram classificações opostas entre omlx e llama.cpp no mesmo hardware e modelo, o que é em si a razão pela qual esta ferramenta mede ao vivo em vez de citar um número fixo.
Comparação
Três ferramentas reais e mantidas independentemente ocupam o mesmo espaço, cada uma com um escopo diferente. Qualquer célula não extraída da documentação do projeto vinculado está marcada de acordo.
| InferBench | llama-bench (incluído com llama.cpp) | local-llm-bench | inference-benchmarker (Hugging Face) | |
|---|---|---|---|---|
| Mecanismos cobertos | omlx, llama.cpp | somente llama.cpp | Ollama, LM Studio, omlx, qualquer endpoint compatível com OpenAI | Qualquer API de chat compatível com OpenAI (TGI, vLLM, etc.) |
| O que mede | Média/mín/máx tok/s de solicitação única em uma varredura fixa de 8 prompts | Tok/s de processamento de prompt e geração de tokens com tamanho de lote, tipo de cache e contagem de threads ajustáveis | Tok/s "efetivos" (tokens de saída / tempo total de parede incluindo prefill) em cenários personalizados do mundo real | Varredura de concorrência/throughput em taxas de solicitação crescentes (QPS), focado em produção/serviço |
| Multi-mecanismo em uma execução | Sim | Não — apenas um mecanismo | Sim, mecanismo escolhido por invocação | Sim, qualquer servidor com a API, por invocação |
| Formatos de saída | Tabela humana, JSON | Markdown, CSV, JSON, JSONL, SQL | JSON em disco + um script compare.py separado | JSON |
| Distribuição | npm + PyPI, pip install / npm install -g | Incluído no build do llama.cpp, sem pacote separado | git clone + python3 bench.py (sem pacote PyPI/npm) | cargo install, binário pré-compilado ou imagem Docker |
| Plataforma | Multi-plataforma para llama.cpp; omlx é somente Apple Silicon | Multi-plataforma (igual ao llama.cpp) | Documentado e demonstrado para Apple Silicon (mecanismos MLX/GGUF) | Multi-plataforma, construído para implantações de servidores GPU |
Por que isto existe
A inferência local em hardware de consumo é agora o caminho padrão para uma parcela crescente de desenvolvedores, e a comparação de cada mecanismo contra seus concorrentes tem um problema óbvio de incentivo: nenhum fornecedor é um juiz desinteressado de seus próprios números. O InferBench não tem mecanismo próprio para vender, que é exatamente o ponto.
A questão mais difícil que esta ferramenta realmente responde não é "qual mecanismo é o mais rápido em geral" — não existe tal resposta, porque depende do seu hardware exato, do seu modelo exato e da sua carga de trabalho exata. É "qual mecanismo é o mais rápido agora, nesta máquina, para este modelo" — uma pergunta que apenas uma ferramenta que roda no seu próprio hardware pode responder honestamente.
Documentação
- docs/getting-started.md — instalação, primeira execução e uso da biblioteca em vez da CLI, para ambas as distribuições.
- docs/concepts.md — a arquitetura de medição, o detector de hardware, a regra de recomendação e o contrato de código de saída.
- docs/integrations/ci.md — por que o InferBench deliberadamente não é um portão de CI por PR, e quais padrões funcionam em vez disso.
Demonstração
Saída legível por máquina gravada em um arquivo com --json --out, útil para CI ou para um agente analisando o resultado:

Benchmarking de vários mecanismos lado a lado, com uma recomendação real medida entre eles:

Perguntas frequentes
O que é exatamente o InferBench?
Uma ferramenta de benchmarking para mecanismos de inferência de LLM local já instalados na sua máquina — atualmente omlx e llama.cpp. Ela executa um conjunto fixo e variado de prompts contra aqueles que estiverem presentes, mede tokens/segundo reais para cada um e recomenda o que foi mais rápido nessa execução específica. Ela é distribuída como dois pacotes com o mesmo nome, inferbench-cli: um no npm (JavaScript/TypeScript) e um no PyPI (Python).
Como o InferBench é diferente do próprio llama-bench do llama.cpp?
O llama-bench (incluído com o llama.cpp) só faz benchmark do próprio llama.cpp, com opções de ajuste fino (tamanho do lote, tipo de cache, número de threads, repetições e mais) e gera saída em Markdown, CSV, JSON, JSONL ou SQL. O InferBench faz benchmark entre mecanismos — atualmente omlx e llama.cpp — usando o mesmo conjunto de prompts e o mesmo código de medição para ambos, então os números de tokens/segundo resultantes são diretamente comparáveis entre si no seu hardware, não apenas ajustáveis isoladamente para um mecanismo.
O InferBench funciona no Linux e no Windows, ou apenas no macOS?
O mecanismo llama.cpp funciona em qualquer plataforma que o próprio llama.cpp suporte (Linux, macOS, Windows), já que o InferBench apenas inicia o llama-server e mede o endpoint compatível com OpenAI. O mecanismo omlx é exclusivo para Apple Silicon, alinhado ao escopo do omlx — no Linux ou no Windows, o --engines omlx informa que esse mecanismo não está instalado e o InferBench faz benchmark de qualquer mecanismo suportado que esteja realmente presente. Node.js >=18 é necessário para o pacote npm, Python >=3.10 para o pacote PyPI.
O InferBench baixa modelos para mim?
Para o llama.cpp, sim — passe uma especificação de repositório Hugging Face e a própria flag -hf do llama-server baixa e armazena em cache. Para o omlx, não — o comando serve do omlx apenas descobre modelos já presentes em um diretório local, então você precisa ter o modelo baixado lá primeiro.
Algum dado sai da minha máquina?
Não. Cada solicitação de benchmark vai para um servidor que o próprio InferBench iniciou em 127.0.0.1. Nada é enviado para lugar nenhum.
Por que o --engines às vezes precisa de um valor de --model diferente por mecanismo?
Porque o omlx e o llama.cpp têm mecanismos genuinamente diferentes de aquisição de modelos — veja a nota de limitação conhecida no Início rápido acima.
A recomendação é uma garantia de que este mecanismo é o mais rápido para mim em geral? Não. É o mecanismo mais rápido medido nesta execução exata. Execute novamente — seu próprio hardware, seu próprio modelo, seu próprio momento — em vez de confiar em um número de outra máquina ou de outro dia.
É seguro apontar o --out para um caminho que vem de um agente ou de outra entrada menos confiável?
Sim, com uma restrição documentada: o --out rejeita um caminho relativo que resolva para fora do diretório de trabalho atual (por exemplo, --out ../../etc/cron.d/x), especificamente para que um benchmark invocado com um caminho fornecido por agente não possa ser enganado para gravar fora do diretório pretendido. Um caminho absoluto ainda é aceito, pois é um valor que o chamador passou diretamente, em vez de um que escapou via travessia de ...
O que acontece se nenhum mecanismo suportado estiver instalado, ou se uma execução falhar no meio?
Se nem omlx nem llama.cpp for encontrado, o InferBench sai com o código 1 e uma mensagem nomeando ambos os comandos de instalação, em vez de retornar um resultado vazio silencioso. Se um mecanismo estiver instalado, mas uma execução específica falhar, a linha desse mecanismo no relatório mostra FAILED com o erro subjacente em vez de um número — qualquer outro mecanismo que tenha concluído ainda recebe um resultado real e permanece elegível para a recomendação.
Posso usar o InferBench comercialmente e é gratuito? Sim. O InferBench é licenciado sob Apache License 2.0, que permite uso comercial, modificação e redistribuição sem taxa de licenciamento. Ele não tem dependência de API paga — cada solicitação de benchmark vai para um servidor que ele inicia localmente na sua própria máquina.
Contribuindo
Consulte CONTRIBUTING.md para o guia completo, cobrindo tanto os codebases TypeScript quanto Python. Issues e PRs são bem-vindos. O escopo adiado conhecido inclui adaptadores adicionais de mecanismos, um painel de frota hospedado e pontuação de recomendação mais rica — abra uma issue se quiser assumir um desses itens.
Segurança
Consulte SECURITY.md para o processo de relato de vulnerabilidades.
Licença
Apache 2.0, consulte LICENSE.