InferBench
Evalúa la velocidad de inferencia de LLM local (tokens/seg) en tu propio hardware mediante herramientas MCP.
Documentación
InferBench
Todo artículo sobre "el mejor motor LLM local" compara el hardware de otra persona. InferBench compara el tuyo.
Los motores de inferencia local publican sus propios benchmarks, en su propio hardware, en su propio README. Ninguno te dice cuál es realmente el más rápido en la máquina que tienes delante. InferBench ejecuta un conjunto fijo y variado de prompts contra los motores compatibles que estén instalados en tu propio hardware e informa tokens/segundo reales y medidos, no un número copiado del blog de otra persona.
Instalación, primera ejecución y un benchmark real de omlx contra un modelo en caché:

npx inferbench-cli run --engines llama.cpp --model "bartowski/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M"
Tabla de contenidos
- Instalación
- Características
- Inicio rápido
- Referencia de comandos CLI
- Referencia de la API de biblioteca
- Cómo funciona la medición
- Comparación
- Por qué existe esto
- Documentación
- Preguntas frecuentes
- Contribuciones
- Seguridad
- Licencia
Instalación
InferBench incluye dos paquetes independientes e igualmente de primera clase: elige el que se adapte a tu cadena de herramientas, o instala ambos. Ninguno está en desuso en favor del otro; ambos ejecutan la misma arquitectura de medición contra los mismos dos motores compatibles.
# 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 paquetes están publicados e instalables hoy.
npm install -g inferbench-cli y pip install inferbench-cli funcionan
ambos: consulta
npmjs.com/package/inferbench-cli
y pypi.org/project/inferbench-cli,
o python/README.md y
docs/getting-started.md para el tutorial
específico de Python, y CHANGELOG.md para el historial
de versiones de cada distribución.
Requiere Node.js >=18 para el paquete npm, Python >=3.10 para el paquete PyPI. Al menos un motor compatible debe estar ya instalado en cualquier caso (InferBench no instala motores por ti):
- llama.cpp:
brew install llama.cpp(macOS) o compilar desde ggml-org/llama.cpp - omlx:
brew tap jundot/omlx https://github.com/jundot/omlx && brew install omlx(solo Apple Silicon)
Características
- Multi-motor, mismo código de medición. InferBench inicia el servidor HTTP compatible con OpenAI de cada motor (
llama-server,omlx serve) y envía a cada motor el mismo conjunto de prompts a través del mismo código de temporización, en lugar de comparar números que la propia herramienta de benchmark de cada motor produjo de manera diferente. - Temporización del cuerpo completo de la respuesta, no de las cabeceras. Una versión anterior de este código medía el tiempo transcurrido justo después de que el objeto de respuesta HTTP se resolviera, lo que solo captura la llegada de las cabeceras, y una vez informó una velocidad físicamente imposible de 64,646 tok/s antes de que se detectara el error. Ambas distribuciones ahora temporizan el cuerpo completo de la respuesta, con una prueba de regresión que protege la corrección en el harness de cada lenguaje.
- Barrido fijo de 8 prompts con calentamiento. Una finalización desechable absorbe la latencia de la primera solicitud, luego se temporizan 8 prompts variados individualmente y se informan como promedio/mín/máx tok/s (
n=8en la tabla de resultados). - Dos distribuciones mantenidas de forma independiente, salida coincidente. El
inferbench-clide npm (TypeScript) y elinferbench-clide PyPI (un puerto genuino de Python, no un envoltorio alrededor del binario de Node) exponen las mismas banderas de CLI y los mismos nombres de campos en el informe JSON. - Informes legibles por máquina.
--json/--out <file>escribe unBenchmarkReportcompleto como JSON en camelCase en ambas distribuciones, para que CI o un agente puedan analizarlo sin tener que especializar qué lenguaje lo produjo. - Contexto local de coste en la nube (biblioteca de Python).
compare_to_cloud()busca un precio estático y fechado de API en la nube junto con tu rendimiento local medido: declara claramente que es una instantánea, no una cotización en vivo, y devuelveNonepara un modelo que no reconoce en lugar de adivinar un número. --outseguro para rutas. Un valor--outrelativo que se resuelve fuera del directorio de trabajo actual se rechaza, de modo que una ruta de salida proporcionada por un agente no pueda escapar del directorio previsto.
Inicio 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
Salida real de una ejecución en vivo contra un proceso 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
[!ADVERTENCIA]
--modelsignifica algo diferente según el motor (una especificación HF descargable para llama.cpp, un nombre de directorio local pre-descargado para omlx), porque los dos motores tienen capacidades genuinamente diferentes de adquisición de modelos: el comandoservede omlx no tiene una bandera para descargar un modelo arbitrario de Hugging Face directamente. Por lo tanto, ejecutar ambos motores contra el mismo modelo en un solo comando requiere que el modelo ya esté disponible en las formas esperadas de ambos motores.
Referencia de comandos 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 salida 0 en una ejecución exitosa con al menos un motor probado; 1 en un error de uso o cuando no hay ningún motor compatible instalado. La CLI de Python tiene una pequeña divergencia documentada: una bandera --model requerida que falta sale con 2 (la convención estándar de argparse para un error en tiempo de análisis) en lugar de 1.
Referencia de la API de biblioteca
El paquete de Python (pip install inferbench-cli) expone una superficie de biblioteca documentada, pensada para su uso en scripts o notebooks en lugar de la CLI. El campo package.json main del paquete npm apunta al propio script de CLI (dist/cli.js, que ejecuta el analizador de argumentos como efecto secundario al importar) y no declara un punto de entrada de biblioteca separado, por lo que hoy solo la distribución de Python es una importación de biblioteca compatible.
from inferbench import (
benchmark_engine, detect_hardware, all_engines, resolve_engines,
recommend, compare_to_cloud, report_to_dict, write_json_report,
)
| Símbolo | Firma | Qué devuelve |
|---|---|---|
detect_hardware() | () -> HardwareProfile | Plataforma, arquitectura, cadena del modelo de CPU, memoria total en GB y si la máquina es Apple Silicon. |
all_engines() | () -> List[EngineAdapter] | Una instancia de adaptador para cada motor compatible (omlx, llama.cpp). |
resolve_engines(names) | (names: List[str]) -> List[EngineAdapter] | Adaptadores para una lista de motores deduplicada y proporcionada por el usuario; lanza una excepción ante un nombre no reconocido. |
benchmark_engine(adapter, *, model, ...) | (adapter, *, model: str, max_tokens=None, prompts=None, verbose=False, on_progress=None) -> EngineBenchmarkResult | Ejecuta el barrido fijo de prompts contra un motor y devuelve un resultado estructurado. Nunca lanza una excepción por "motor no instalado" o un prompt fallido: ese estado vive en el objeto devuelto. |
recommend(results) | (results: List[EngineBenchmarkResult]) -> Optional[Recommendation] | El motor con el promedio más alto de tok/s medido entre los motores instalados y probados con éxito. |
compare_to_cloud(cloud_model) | (cloud_model: str) -> Optional[CostComparison] | Un precio estático y fechado por cada 1K tokens de salida para un modelo de nube conocido (actualmente claude-5-haiku, claude-5-sonnet) más una nota de divulgación, o None para un modelo que no reconoce. |
report_to_dict(report) / write_json_report(report, path) | (report: BenchmarkReport) -> dict / (report, path: str) -> None | Serializa un BenchmarkReport a la misma forma JSON en camelCase que producen el --json / --out de la CLI. |
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
InferBench incluye un servidor de Protocolo de Contexto de Modelo para que un agente de IA (Claude, Cursor o cualquier cliente compatible con MCP) pueda ejecutar un benchmark de hardware directamente, sin que un humano invoque la CLI manualmente.
Instala el extra:
pip install "inferbench-cli[mcp]"
Añádelo a la configuración de tu cliente MCP (para Claude Desktop, claude_desktop_config.json):
{
"mcpServers": {
"inferbench": {
"command": "uvx",
"args": ["--from", "inferbench-cli", "inferbench-mcp"]
}
}
}
El servidor expone una herramienta, run, que ejecuta el binario npm inferbench publicado con
el subcomando y los argumentos dados más --json, y devuelve el resultado analizado:
run(["run", "--engines", "llama.cpp", "--model", "bartowski/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M"])
El transporte es stdio, por lo que no hay nada que alojar: el cliente MCP inicia el servidor como un
subproceso local. Fuente: python/src/inferbench/mcp_server.py.
Cómo funciona la medición
InferBench no ejecuta la propia herramienta de benchmark de cada motor y analiza su salida. Ese enfoque estaba en el plan original y resultó no funcionar en absoluto: omlx no tiene un comando de benchmark CLI: su característica "Performance Benchmark" es una acción de un solo clic, solo GUI, en su panel de administración, verificada directamente contra su README real antes de escribir una línea de código de adaptador.
En su lugar, InferBench inicia el servidor HTTP compatible con OpenAI ya estandarizado de cada motor (omlx serve, llama-server) y envía los mismos prompts exactos a través del mismo código de medición a cada motor, temporizando la respuesta completa (no solo el tiempo hasta el primer byte). Este es el único enfoque que es genuinamente comparable entre motores con internals fundamentalmente diferentes, y el único que funciona en absoluto para omlx.
Qué significa "recomendado" (y qué no): la recomendación en cada informe nombra el motor con el promedio más alto de tokens/segundo medido en esta ejecución específica, este hardware específico, este modelo específico, no una afirmación general sobre cuál es el mejor motor. Un modelo diferente, una máquina diferente o las condiciones térmicas de otro día pueden cambiar la respuesta; dos ejecuciones durante el desarrollo de esta herramienta produjeron clasificaciones opuestas entre omlx y llama.cpp en el mismo hardware y modelo, lo que en sí mismo es la razón por la que esta herramienta mide en vivo en lugar de citar un número fijo.
Comparación
Tres herramientas reales mantenidas de forma independiente ocupan el mismo espacio, cada una con un alcance diferente. Cualquier celda que no provenga de la documentación del proyecto enlazado está marcada en consecuencia.
| InferBench | llama-bench (incluido con llama.cpp) | local-llm-bench | inference-benchmarker (Hugging Face) | |
|---|---|---|---|---|
| Motores cubiertos | omlx, llama.cpp | solo llama.cpp | Ollama, LM Studio, omlx, cualquier endpoint compatible con OpenAI | Cualquier API de chat compatible con OpenAI (TGI, vLLM, etc.) |
| Qué mide | Promedio/mín/máx tok/s de solicitud única en un barrido fijo de 8 prompts | Procesamiento de prompts y generación de tokens tok/s con tamaño de lote, tipo de caché y número de hilos ajustables | tok/s "efectivos" (tokens de salida / tiempo total de pared incluyendo prefill) en escenarios personalizados del mundo real | Barrido de concurrencia/rendimiento a tasas de solicitud crecientes (QPS), enfocado en servidores de producción |
| Multi-motor en una ejecución | Sí | No: solo un motor | Sí, motor elegido por invocación | Sí, cualquier servidor con la API, por invocación |
| Formatos de salida | Tabla humana, JSON | Markdown, CSV, JSON, JSONL, SQL | JSON a disco + un script compare.py separado | JSON |
| Distribución | npm + PyPI, pip install / npm install -g | Se incluye dentro de la compilación de llama.cpp, sin paquete separado | git clone + python3 bench.py (sin paquete PyPI/npm) | cargo install, binario precompilado o imagen Docker |
| Plataforma | Multiplataforma para llama.cpp; omlx es solo Apple Silicon | Multiplataforma (igual que llama.cpp) | Documentado y demostrado para Apple Silicon (motores MLX/GGUF) | Multiplataforma, construido para despliegues de servidores GPU |
Por qué existe esto
La inferencia local en hardware de consumo es ahora la ruta predeterminada para una parte creciente de desarrolladores, y la comparación de cada motor contra sus competidores tiene un problema de incentivos obvio: ningún proveedor es un juez desinteresado de sus propios números. InferBench no tiene un motor propio que vender, que es el punto central.
La pregunta más difícil que esta herramienta realmente responde no es "qué motor es el más rápido en general": no existe tal respuesta, porque depende de tu hardware exacto, tu modelo exacto y tu carga de trabajo exacta. Es "qué motor es el más rápido ahora mismo, en esta máquina, para este modelo", una pregunta que solo una herramienta que se ejecuta en tu propio hardware puede responder honestamente.
Documentación
- docs/getting-started.md -- instalación, primera ejecución y uso de la biblioteca en lugar de la CLI, para ambas distribuciones.
- docs/concepts.md -- la arquitectura de medición, el detector de hardware, la regla de recomendación y el contrato de código de salida.
- docs/integrations/ci.md -- por qué InferBench no es deliberadamente una puerta de CI por PR, y qué patrones funcionan en su lugar.
Demo
Salida legible por máquina escrita en un archivo con --json --out, útil para CI o para un agente que analice el resultado:

Evaluación comparativa de múltiples motores lado a lado, con una recomendación real medida entre ellos:

Preguntas frecuentes
¿Qué es exactamente InferBench?
Una herramienta de evaluación comparativa para motores de inferencia de LLM locales ya instalados en tu máquina -- actualmente omlx y llama.cpp. Ejecuta un conjunto de prompts fijo y variado contra cualquiera de los que estén presentes, mide tokens/segundo reales para cada uno y recomienda el que haya sido más rápido en esa ejecución específica. Se distribuye como dos paquetes con el mismo nombre, inferbench-cli: uno en npm (JavaScript/TypeScript) y otro en PyPI (Python).
¿En qué se diferencia InferBench del propio llama-bench de llama.cpp?
llama-bench (incluido con llama.cpp) solo evalúa llama.cpp en sí mismo, con ajustes finos (tamaño de lote, tipo de caché, número de hilos, repeticiones y más) y genera salida en Markdown, CSV, JSON, JSONL o SQL. InferBench evalúa entre motores -- actualmente omlx y llama.cpp -- usando el mismo conjunto de prompts y el mismo código de medición para ambos, de modo que los números de tokens/segundo resultantes son directamente comparables entre sí en tu hardware, no solo ajustables de forma aislada para un motor.
¿Funciona InferBench en Linux y Windows, o solo en macOS?
El motor llama.cpp funciona en cualquier plataforma que soporte el propio llama.cpp (Linux, macOS, Windows), ya que InferBench solo inicia llama-server y mide su endpoint compatible con OpenAI. El motor omlx es exclusivo de Apple Silicon, en línea con el alcance de omlx -- en Linux o Windows, --engines omlx informa que ese motor no está instalado e InferBench evalúa cualquier motor compatible que esté realmente presente. Se requiere Node.js >=18 para el paquete npm y Python >=3.10 para el paquete PyPI.
¿Descarga InferBench los modelos por mí?
Para llama.cpp, sí -- pasa una especificación de repositorio de Hugging Face y la bandera -hf del propio llama-server lo descarga y lo guarda en caché. Para omlx, no -- el comando serve de omlx solo descubre modelos ya presentes en un directorio local, por lo que debes tener el modelo descargado allí primero.
¿Sale algún dato de mi máquina?
No. Cada solicitud de evaluación va a un servidor que el propio InferBench inició en 127.0.0.1. No se sube nada a ningún lugar.
¿Por qué --engines a veces necesita un valor de --model diferente por motor?
Porque omlx y llama.cpp tienen mecanismos de adquisición de modelos genuinamente diferentes -- consulta la nota de limitación conocida en Inicio rápido arriba.
¿Es la recomendación una garantía de que este motor es el más rápido para mí en general? No. Es el motor más rápido medido en esta ejecución exacta. Vuelve a ejecutarlo -- tu propio hardware, tu propio modelo, tu propio momento -- en lugar de confiar en un número de otra máquina o de otro día.
¿Es seguro apuntar --out a una ruta que proviene de un agente u otra entrada menos confiable?
Sí, con una restricción documentada: --out rechaza una ruta relativa que se resuelva fuera del directorio de trabajo actual (por ejemplo, --out ../../etc/cron.d/x), específicamente para que una evaluación invocada con una ruta proporcionada por un agente no pueda ser engañada para escribir fuera del directorio previsto. Una ruta absoluta aún se acepta, ya que es un valor que el llamador pasó directamente en lugar de uno que escapó mediante un recorrido de ...
¿Qué sucede si no hay ningún motor compatible instalado, o si una ejecución falla a mitad de camino?
Si no se encuentra ni omlx ni llama.cpp, InferBench sale con el código 1 y un mensaje que nombra ambos comandos de instalación en lugar de devolver un resultado vacío silencioso. Si un motor está instalado pero una ejecución específica falla, la línea de ese motor en el informe dice FAILED con el error subyacente en lugar de un número -- cualquier otro motor que sí se completó aún obtiene un resultado real y sigue siendo elegible para la recomendación.
¿Puedo usar InferBench comercialmente y es gratuito? Sí. InferBench tiene licencia Apache 2.0, que permite uso comercial, modificación y redistribución sin tarifa de licencia. No tiene dependencia de API de pago -- cada solicitud de evaluación va a un servidor que inicia localmente en tu propia máquina.
Contribuciones
Consulta CONTRIBUTING.md para la guía completa, que cubre tanto los códigos base de TypeScript como de Python. Se aceptan problemas y solicitudes de extracción. El alcance diferido conocido incluye adaptadores de motores adicionales, un panel de control de flota alojado y una puntuación de recomendación más rica -- abre un problema si deseas tomar uno de estos.
Seguridad
Consulta SECURITY.md para el proceso de reporte de vulnerabilidades.
Licencia
Apache 2.0, consulta LICENSE.