Catálogo de herramientas de benchmark LLM: ficha práctica a fondo
Notación: importes en euros (N €), decimales con coma. No se usa el símbolo de dólar (en este sitio es delimitador de fórmula).
Qué cubre este artículo
Segundo artículo del track de benchmarking (B2). La introducción B1 fijó las métricas y la metodología; este artículo es el manual práctico: para cada herramienta, qué mide, cómo se invoca de verdad (con el comando), qué formato de salida da y cuándo elegirla. El objetivo es que, tras leerlo, sepas qué ejecutar para medir tu motor y puedas reproducir el número. Sin recomendaciones universales; solo la mecánica de cada herramienta y el criterio para escoger.
Cómo elegir: el mapa de herramientas
Recordando la división de B1, las herramientas se ordenan en dos ejes: micro-bench (mono-proceso, para tunear un motor) vs generador de carga (multi-proceso, para medir capacidad real), y propias del motor vs agnósticas del endpoint.
Datasets: la carga sintética importa tanto como la herramienta
Antes de las fichas, un punto que cambia los resultados sin que se note: qué carga le metes. Las herramientas aceptan distintos tipos de dataset, y cada uno mide algo distinto:
| Dataset | Qué simula | Sesgo que introduce |
|---|---|---|
| random (longitudes fijas) | carga uniforme controlada | irreal: el tráfico no es de longitud fija |
| sharegpt (conversaciones reales) | distribución realista de prompts | el estándar de facto para comparar |
| trazas propias | tu tráfico real | el más fiel, pero específico de tu caso |
La trampa: un benchmark con prompts cortos de longitud fija da un throughput altísimo que no se parece a producción, donde las longitudes varían y los prompts largos dominan el coste de prefill. Para una cifra defendible, usa sharegpt (comparabilidad) o, mejor, trazas de tu propio tráfico (fidelidad). Y declara siempre la distribución de longitudes (prompt/salida) junto al número, porque dos benchmarks con datasets distintos no son comparables aunque usen la misma herramienta.
vLLM bench serve
Qué mide: TTFT, TPOT, throughput y latencias del servidor vLLM bajo una carga sintética. Clase: micro-bench (mono-proceso). Es la herramienta para tunear vLLM y ver el efecto de sus optimizaciones (decode, prefill).
Invocación típica (vLLM · CLI de benchmark):
vllm bench serve \
--backend vllm \
--model meta-llama/Llama-3.1-8B-Instruct \
--endpoint /v1/completions \
--dataset-name sharegpt \
--dataset-path ShareGPT_V3_unfiltered_cleaned_split.json \
--num-prompts 1000
Parámetros clave: --num-prompts (carga), --dataset-name (sharegpt, random, etc.),
--request-rate (peticiones/s). La salida es un resumen por consola con TTFT, TPOT,
throughput y percentiles, y puede volcarse a JSON. Para barrer concurrencias existe vllm bench sweep serve, que automatiza el sweep (vLLM · sweep).
Límite: mono-proceso, se satura en el cliente a alta concurrencia; menos flexible que GuideLLM en datasets y patrones de carga. Úsalo para iterar rápido sobre la config de vLLM, no para medir la capacidad máxima a escala.
SGLang bench
Qué mide: el equivalente para el motor SGLang (TTFT, TPOT, throughput). Clase: micro-bench.
Uso: tunear SGLang y compararlo consigo mismo entre configuraciones. La mecánica es análoga a
vllm bench serve: una carga sintética, salida por consola/JSON con las mismas métricas. Si
evalúas SGLang vs vLLM, no los compares con sus micro-benchs respectivos (clases iguales
pero implementaciones distintas): usa un generador de carga agnóstico (GuideLLM/AIPerf) contra
ambos endpoints, para que la herramienta no sea la variable.
AIPerf (NVIDIA, ex genai-perf)
Qué mide: TTFT, ITL, throughput y latencia sobre cualquier endpoint compatible (vLLM, NIM,
TGI, SGLang). Clase: generador de carga multi-proceso. Es el sucesor de genai-perf
(jubilado el 15-abr-2026). Su rasgo distintivo: durante el sweep detecta la saturación de la
GPU y devuelve la iteración anterior como estimatedCapacity; por eso hay que extender el
sweep más allá del codo (AIPerf).
Salida: métricas estructuradas (JSON) con distribuciones de TTFT/ITL y el estimatedCapacity.
Úsalo cuando quieras la capacidad real de un endpoint, sea cual sea el motor, con la
detección automática del punto de saturación.
GuideLLM (proyecto vLLM)
Qué mide: distribuciones completas de TTFT, ITL y comportamiento de extremo a extremo, para
evaluación dirigida por SLO. Clase: generador de carga multi-proceso. Es la herramienta
recomendada para benchmarkear servidores vLLM en producción: más flexible que vllm bench serve en carga de datasets, formato de peticiones y patrones de tráfico, con progreso en
vivo y generación automática de informe (Red Hat).
Invocación típica:
guidellm benchmark \
--target "http://localhost:8000" \
--rate-type throughput \
--max-requests 1000 \
--data "samples=1000,prompt_tokens=1024,output_tokens=256"
Parámetros clave: --rate-type (synchronous, concurrent, throughput, o por tasa),
--data (especificación de la carga: nº de muestras y longitudes de prompt/salida), --target
(el endpoint). Genera sweeps reproducibles para hallar el rango de operación seguro bajo
SLO, con distribuciones completas (no solo medias). Salida: informe con percentiles y, a
menudo, exportable a JSON/HTML. Es la opción por defecto para responder “¿hasta dónde cargo
este motor sin romper el SLO?”.
LLMPerf (Anyscale/Ray)
Qué mide: throughput y latencia a nivel de inferencia. Clase: generador de carga. Uso: validación de endpoints, históricamente muy extendido en el ecosistema Ray/Anyscale. Es una opción sólida y conocida, aunque menos centrada en distribuciones y sweeps que GuideLLM/AIPerf. Encaja si ya operas en Ray o quieres una herramienta simple para validar un endpoint.
inference-benchmarker (Hugging Face)
Qué mide: latencia y throughput de endpoints de inferencia, con orientación a generar informes comparables. Clase: generador de carga. Uso: alternativa OSS dentro del ecosistema Hugging Face, útil si ya trabajas con TGI o el stack de HF. Como las demás de su clase, su valor está en medir capacidad real con carga distribuida; la elección entre ésta, GuideLLM y AIPerf suele venir por el ecosistema en el que ya operas más que por diferencias de fondo en lo que miden.
GuideLLM vs AIPerf: cuál de los dos generadores de carga
Son las dos opciones serias de carga multi-proceso, y se solapan mucho. Las diferencias prácticas que inclinan la elección:
| Criterio | GuideLLM | AIPerf |
|---|---|---|
| Origen | proyecto vLLM (Red Hat) | NVIDIA (sucesor de genai-perf) |
| Foco | evaluación dirigida por SLO, sweeps reproducibles | capacidad real, estimatedCapacity automático |
| Patrones de carga | síncrono, concurrente, por tasa | sweep con detección de saturación |
| Informe | progreso en vivo + informe automático | métricas estructuradas (JSON) |
| Ecosistema | vLLM / OpenShift AI | NVIDIA NIM / Triton / vLLM |
En la práctica: si tu pregunta es “¿hasta dónde cargo sin romper el SLO?”, GuideLLM la responde de forma más directa con sus sweeps dirigidos por SLO; si tu pregunta es “¿cuál es la capacidad máxima de este endpoint?”, AIPerf la da con su detección automática del codo. Muchos equipos usan los dos: GuideLLM para el SLO operativo, AIPerf para la capacidad de referencia. Lo que no debes hacer es comparar un resultado de GuideLLM con uno de AIPerf como si fueran la misma medida: aunque ambos sean multi-proceso, su metodología de sweep difiere; elige uno para una comparación dada y mantenlo.
MLPerf Inference (MLCommons)
Qué mide: rendimiento bajo escenarios normalizados (Offline, Server, Interactive) con reglas estrictas. A diferencia de las anteriores, MLPerf no se “ejecuta” para tu caso del día a día: es una suite de comparación entre fabricantes cuyos resultados se leen (publicados por NVIDIA, AMD, Intel, etc.). Úsalo para comparar hardware/motores entre sí con reglas idénticas, no para dimensionar tu carga concreta —para eso, GuideLLM/AIPerf sobre tu endpoint—.
Tabla comparativa práctica
| Herramienta | Clase | Comando base | Salida | Cuándo |
|---|---|---|---|---|
| vllm bench serve | micro | vllm bench serve | consola/JSON | tunear vLLM |
| vllm bench sweep | micro (sweep) | vllm bench sweep serve | consola/JSON | barrer concurrencia en vLLM |
| SGLang bench | micro | bench del repo SGLang | consola/JSON | tunear SGLang |
| AIPerf | carga | aiperf profile … | JSON + estimatedCapacity | capacidad real, multi-endpoint |
| GuideLLM | carga | guidellm benchmark … | informe + JSON/HTML | SLO, sweep reproducible |
| LLMPerf | carga | script Ray/LLMPerf | JSON | validar endpoint (Ray) |
| MLPerf | suite | (se leen resultados) | resultados oficiales | comparar fabricantes |
Resumen: qué ejecutas para cada pregunta
Para no perderse en el catálogo, el mapeo directo de pregunta a herramienta:
| Tu pregunta | Herramienta | Por qué |
|---|---|---|
| “¿Mejora mi cambio de config en vLLM?” | vllm bench serve (+ sweep) | rápido, propio del motor |
| “¿Hasta dónde cargo sin romper el SLO?” | GuideLLM | sweeps dirigidos por SLO |
| “¿Cuál es la capacidad máxima del endpoint?” | AIPerf | detección automática del codo |
| “¿vLLM o SGLang para mi carga?” | GuideLLM/AIPerf contra ambos | misma herramienta, motor variable |
| “¿Qué hardware/motor es mejor en abstracto?” | leer MLPerf | comparabilidad cross-vendor |
| “¿Hay regresión en este release?” | sweep corto en CI vs línea base | detección continua |
La regla que subyace a toda la tabla: micro-bench para iterar sobre un motor, generador de carga para medir capacidad y decidir, MLPerf para comparar fabricantes. Y, para cualquier comparación entre sistemas, la misma herramienta para todos los candidatos. Si tienes claras estas tres categorías, la elección concreta es secundaria.
Metodología paso a paso de un benchmark
Una corrida fiable no es “lanzar el comando”: es un procedimiento. Los pasos, con la herramienta de carga (GuideLLM/AIPerf) contra tu endpoint:
- Desplegar el motor con la config exacta a medir (modelo, precisión, flags), pineada.
- Calentar: lanzar unas peticiones y descartarlas, para que el prefix cache y el autotuning no inflen los primeros números.
- Sweep: barrer concurrencias crecientes (1, 8, 16, 24, 32…) más allá del codo, para ver dónde se dispara la latencia.
- Recoger la salida en JSON con percentiles (TTFT/ITL/throughput/goodput) y los metadatos.
- Comparar: leer el goodput bajo el SLO, no el throughput máximo.
Saltarse el paso 2 (warm-up) o no pasar el codo en el 3 son los dos errores que más sesgan el resultado.
Comparar dos motores: el protocolo justo
Si el objetivo es elegir entre vLLM y SGLang (o TRT-LLM), el protocolo que evita conclusiones falsas:
- Misma herramienta de carga (GuideLLM o AIPerf) contra ambos endpoints — nunca el micro-bench de cada motor.
- Mismo dataset y distribución de longitudes.
- Mismo hardware y precisión.
- Mismo SLO para calcular el goodput de ambos.
- Variar solo el motor; todo lo demás, fijo.
Solo así la diferencia que midas es del motor y no de la herramienta, el dataset o el hardware. Es el experimento controlado que sostiene la fila del cuadro de mando (artículo B8).
Formato de salida y comparabilidad
Lo que registres junto al número es lo que lo hace comparable. Una salida útil incluye, en JSON para versionarla:
{
"tool": "guidellm", "version": "x.y.z",
"model": "Llama-3.1-70B", "precision": "FP16",
"hardware": "8xH100 SXM NVLink",
"load": {"prompt_tokens": 1024, "output_tokens": 256, "concurrency": 16},
"results": {"ttft_p50_ms": 180, "ttft_p99_ms": 460,
"itl_p50_ms": 22, "throughput_tok_s": 3400, "goodput_tok_s": 3330}
}
Guardar esto por cada corrida convierte un benchmark en un dato auditable: cualquiera reproduce la cifra con la misma herramienta, versión, modelo, hardware y carga. Es el material del harness reproducible (artículo S4), y la diferencia entre un número defendible y una captura de consola.
Ejemplo trabajado: leer la salida de un sweep
Una salida ilustrativa de un sweep de GuideLLM sobre un 70B en 8×H100 (SLO: P99 de TTFT < 500 ms), tal como la leerías:
| Concurrencia | TTFT P99 (ms) | ITL P50 (ms) | Throughput (tok/s) | Goodput (tok/s) |
|---|---|---|---|---|
| 8 | 240 | 20 | 2.100 | 2.100 |
| 16 | 460 | 22 | 3.400 | 3.330 |
| 24 | 980 | 31 | 3.900 | 2.420 |
| 32 | 1.800 | 54 | 4.000 | 800 |
Cómo se lee: el codo está entre 16 y 24. A concurrencia 16, el P99 (460 ms) cumple el SLO y el goodput (3.330 tok/s) ≈ throughput. A 24, el throughput sube poco (3.400 → 3.900) pero el P99 ya viola el SLO y el goodput cae a 2.420. A 32, el throughput es máximo (4.000) pero el goodput se desploma a 800: el sistema “rinde mucho” sirviendo peticiones que incumplen. La capacidad defendible es la de concurrencia 16 (3.330 tok/s útiles), y ese es el número que entra en el capacity planning y en el coste por token. Quien reporte “4.000 tok/s” está describiendo el punto donde el sistema ya no cumple su SLO.
Automatizar el harness
Una corrida manual no escala a un programa de benchmarking. La automatización mínima:
- Script idempotente que despliega el motor, calienta, corre el sweep y guarda el JSON con todos los metadatos (modelo, versión, hardware, dataset, SLO).
- Nombrado por fecha y config, para versionar las corridas y comparar en el tiempo.
- Almacén de resultados (un repo git de JSONs, o un bucket) para que cualquiera reproduzca y compare.
El objetivo es que reproducir un número sea un comando, no una tarde. Es la base del harness del artículo S4, y lo que convierte el benchmarking de una actividad puntual en una capacidad continua de la plataforma.
Integración en CI: benchmarking continuo
El siguiente nivel es medir en cada cambio: un job de CI que, al actualizar el motor o la config, lanza un sweep corto contra un entorno de pruebas y compara con la línea base. Si el goodput cae más de un umbral, falla el pipeline. Así una regresión de rendimiento se detecta en el commit, no en producción. Cuidado con dos cosas: el benchmarking en CI consume GPU-horas (presupuéstalo) y necesita un entorno estable (mismo hardware) para que la comparación sea válida. No hace falta el sweep completo en cada commit: un sweep corto que cubra el codo basta para detectar regresiones; el sweep exhaustivo, para los releases.
El coste de medir (en euros)
Benchmarkear consume GPU-horas, y eso tiene un coste que conviene presupuestar. Un sweep serio sobre un nodo 8×H100 puede ocupar las tarjetas un par de horas; a coste amortizado de ~11 €/h, son ~22 € por sweep completo, más si barres varios modelos y precisiones. No es mucho por corrida, pero un programa de benchmarking continuo (cada release, cada cambio de config) suma. La regla práctica: automatiza el harness para que cada corrida sea barata y reproducible, y mide lo que vas a usar para decidir, no por exhaustividad. El coste de medir es parte del coste de la plataforma —pequeño frente al de servir, pero real—.
Observar durante el benchmark: una corrida, tres ejes
Un truco que ahorra trabajo y conecta la serie: mientras corre el sweep, captura también las métricas de GPU. Con DCGM exportando a Prometheus durante la corrida, registras a la vez:
| Eje | Fuente durante el sweep | Métrica |
|---|---|---|
| Rendimiento | la herramienta (GuideLLM/AIPerf) | TTFT, ITL, throughput, goodput |
| Energía | DCGM | potencia (W) → J/token |
| Coste | precio del nodo (OpenCost) | €/hora → CPM por punto |
Así, de una sola corrida sacas los tres números del mismo punto de operación: a concurrencia 16, el goodput (3.330 tok/s), la potencia media (de DCGM, que dividida por el throughput da los J/token) y el coste por token (con el precio del nodo). En vez de tres campañas separadas, mides los tres ejes a la vez, y quedan coherentes por construcción porque corresponden al mismo instante y la misma carga. Es lo que hace el harness del artículo S4, y la razón de exportar DCGM durante el benchmark aunque solo busques rendimiento: la energía y el coste salen casi gratis si los capturas en la misma ventana.
La advertencia metodológica: alinea las ventanas temporales. La potencia de DCGM y las métricas de la herramienta tienen que cubrir exactamente el mismo intervalo (sin warm-up ni apagado), o el J/token no corresponde al throughput medido. Misma ventana, mismos tres números.
El benchmark es también FinOps y energía
Una idea que conecta este artículo con el resto de la serie: medir rendimiento es, de hecho, medir coste y energía. Por la identidad del artículo de apertura, el goodput es el denominador del coste por token y de la energía por token. Cuando un sweep revela que la config A da 3.330 tok/s de goodput y la config B da 4.000, no estás midiendo solo velocidad: estás midiendo que B cuesta menos euros y menos vatios por token. Por eso el JSON de salida de un benchmark debería acompañarse del coste de hierro (de OpenCost) para calcular el CPM real de cada punto del sweep: throughput × precio del nodo = coste por token. El benchmarking no es un eje aislado; es la herramienta que, indirectamente, más mueve el coste y la energía de la plataforma, y la que llena la columna de rendimiento del cuadro de mando con números que se traducen directamente a euros.
La consecuencia operativa: no benchmarkees el rendimiento en el vacío. Cada corrida que guardes con su throughput y su goodput debería poder cruzarse con el coste del nodo (€/hora) y la energía (J/token) para dar las tres caras del mismo punto de operación. Esa es la forma de que el track de benchmarking alimente al de FinOps y al de energía, en vez de vivir aparte.
Estado del arte 2026 y límites
- Migración a multi-proceso: AIPerf (ex genai-perf) y GuideLLM consolidan la medición de capacidad real; los micro-benchs quedan para tunear motores.
- GuideLLM como estándar OSS de evaluación dirigida por SLO con informe automático.
- Cuidado con comparar entre clases: un micro-bench y un generador de carga no son comparables; fija la clase y la herramienta.
- Versión y dataset importan: el mismo comando con otro dataset o versión da otro número; pínealos.
- MLPerf no dimensiona tu caso: compara fabricantes, no sustituye un sweep sobre tu carga.
Con el catálogo práctico cubierto, el siguiente artículo del track (B3) entra en GuideLLM y la validación de SLO bajo carga a fondo. La herramienta es el medio; el dato reproducible, el fin.
Errores que invalidan un benchmark
Para terminar, la lista de lo que convierte una corrida en basura, por frecuencia:
| Error | Efecto | Arreglo |
|---|---|---|
| Comparar clases distintas | hasta 7× de diferencia espuria | misma herramienta para todos |
| No descartar el warm-up | TTFT artificialmente bajo | calentar y descartar |
| No pasar el codo | no conoces la capacidad segura | extender el sweep |
| Dataset irreal (longitud fija) | throughput que no aplica | sharegpt o trazas propias |
| Reportar media, no P99 | oculta la cola | percentiles siempre |
| Tokenizer ajeno al modelo | tok/s y coste/token sesgados | contar con el del modelo |
| No pinear versión/config | irreproducible | guardar todo en el JSON |
Cualquiera de estos basta para que el número no sea defendible. Un benchmark es tan bueno como su metodología: la herramienta importa menos que ejecutarla bien y registrarlo todo.
Cierre
El catálogo de herramientas de benchmark se reduce a una decisión simple —micro-bench para
tunear un motor, generador de carga para medir capacidad, MLPerf para comparar fabricantes— y a
una disciplina que pesa más que la elección: el método. La misma guidellm benchmark da un
dato de oro o uno inútil según el dataset, el warm-up, hasta dónde llegue el sweep y qué
registres en la salida. Para una propuesta de arquitectura soberana, el rendimiento solo cuenta
si viene con su comando, su versión, su carga y su goodput bajo SLO —y, cruzado con el coste en
euros y la energía por token, se convierte en la columna del cuadro de mando que decide qué
motor y qué configuración sostienen la plataforma. La herramienta la eliges en cinco minutos; la
metodología es lo que hace que el número aguante una auditoría.
Ver también
- GenAI-Perf a fondo — ficha ampliada del perfilador de NVIDIA: métricas (TTFT/TPOT/ISL/OSL), invocación contra endpoint OpenAI-compatible y comparación con GuideLLM/LLMPerf.
- Comparativa de motores de serving (vLLM/SGLang/TRT-LLM/Dynamo) — una vez medido el goodput con estas herramientas, aquí se ven qué motor gana en cada punto de la frontera de Pareto.
- Sesgo de medición y reproducibilidad — las fuentes de sesgo que invalidan resultados aunque la herramienta esté bien configurada: warmup, dataset real vs sintético, entorno compartido.
Fuentes
- vLLM · CLI de benchmark (
bench serve) — https://docs.vllm.ai/en/latest/cli/bench/serve/ - vLLM ·
bench sweep serve— https://docs.vllm.ai/en/latest/cli/bench/sweep/serve/ - Red Hat · desplegar y benchmarkear vLLM con GuideLLM en Kubernetes — https://developers.redhat.com/articles/2025/12/24/how-deploy-and-benchmark-vllm-guidellm-kubernetes
- GuideLLM · GitHub (proyecto vLLM) — https://github.com/vllm-project/guidellm
- NVIDIA AIPerf · guía de benchmarking — https://lucaberton.com/blog/nvidia-aiperf-llm-inference-benchmarking-guide/
- Medium · Benchmarking LLM Serving Performance (guía) — https://medium.com/@kimdoil1211/benchmarking-llm-serving-performance-a-comprehensive-guide-db94b1bfe8cf