<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Metodologia on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/metodologia/</link><description>Recent content in Metodologia on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Tue, 16 Jun 2026 07:00:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/tags/metodologia/index.xml" rel="self" type="application/rss+xml"/><item><title>Sesgo de medición y reproducibilidad: por qué dos benchmarks del mismo modelo dan cifras que difieren hasta 7×</title><link>https://blog.lo0.es/posts/sesgo-medicion-reproducibilidad-bench/</link><pubDate>Tue, 16 Jun 2026 07:00:00 +0200</pubDate><guid>https://blog.lo0.es/posts/sesgo-medicion-reproducibilidad-bench/</guid><description>&lt;blockquote>
&lt;p>Notación: importes en &lt;strong>euros (N €)&lt;/strong>, decimales con coma. El símbolo matemático se
reserva para fórmulas: los importes se expresan en € o USD. Millar con espacio fino
((1,000)).&lt;/p>
&lt;/blockquote>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>Correr el mismo modelo Llama-3-70B-Instruct en el mismo nodo de 4×H100 SXM 80 GB con dos
herramientas distintas puede producir resultados de throughput que difieren &lt;strong>7,2×&lt;/strong> sin que
el motor cambie una línea de código. La causa no es el motor: es el &lt;strong>método de medida&lt;/strong>. A
1.000 QPS, un cliente asyncio mono-proceso (vLLM bench, SGLang bench, genai-perf
pre-AIPerf) procesó &lt;strong>75.574 tokens&lt;/strong> frente a los &lt;strong>545.733 tokens&lt;/strong> de un cliente
multi-proceso —ambos midiendo el mismo endpoint—
(&lt;a href="https://arxiv.org/abs/2605.24217">arXiv 2605.24217&lt;/a>). El sesgo no es aleatorio: es
sistemático, direccional y reproducible. Este artículo cataloga las fuentes de sesgo, cuantifica
su magnitud y describe el harness mínimo que convierte un número en un dato auditable.&lt;/p>
&lt;hr>
&lt;h2 id="las-fuentes-de-sesgo-catálogo-con-magnitudes">Las fuentes de sesgo: catálogo con magnitudes&lt;/h2>
&lt;p>Cada fuente de sesgo mueve el número publicado en una dirección determinada y con una
magnitud característica. La tabla siguiente ordena las fuentes de mayor a menor impacto
observado en la literatura:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Fuente de sesgo&lt;/th>
&lt;th>Dirección del sesgo&lt;/th>
&lt;th>Magnitud documentada&lt;/th>
&lt;th>Referencia&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Saturación del cliente mono-proceso&lt;/strong> (GIL Python, asyncio)&lt;/td>
&lt;td>infravalora throughput; sobrevalora latencia&lt;/td>
&lt;td>hasta &lt;strong>7,2×&lt;/strong> menos tokens procesados a 1.000 QPS&lt;/td>
&lt;td>arXiv 2605.24217&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Tokenizer distinto al del modelo&lt;/strong> (LLMPerf usa LlamaTokenizer universal)&lt;/td>
&lt;td>tok/s incomparables entre vocabularios distintos&lt;/td>
&lt;td>variable; hasta &lt;strong>33 %&lt;/strong> de overhead de overhead de cliente en denominador del TPS&lt;/td>
&lt;td>NVIDIA blog (TPS = overhead de cliente ÷ duración total)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>ignore_eos ausente u OSL inconsistente&lt;/strong>&lt;/td>
&lt;td>subestima throughput; acorta artificialmente OSL real&lt;/td>
&lt;td>hasta terminación prematura; benchmark de longitud fija irreal&lt;/td>
&lt;td>docs vLLM bench; NVIDIA fundamental concepts&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Distribución ISL/OSL irreal&lt;/strong> (longitud fija en vez de distribución realista)&lt;/td>
&lt;td>codo optimista que no se parece a producción&lt;/td>
&lt;td>desplazamiento del codo; prefill infravalorado con prompts cortos&lt;/td>
&lt;td>docs AIPerf sequence-length-distributions&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Warmup ausente / prefix-cache caliente&lt;/strong>&lt;/td>
&lt;td>sobrevalora TTFT (artificialmente bajo en las primeras peticiones)&lt;/td>
&lt;td>TTFT infra-estimado por KV-cache ya poblado&lt;/td>
&lt;td>vLLM prefix caching docs; arXiv 2605.24217&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>&lt;code>concurrency&lt;/code> vs &lt;code>request-rate&lt;/code>&lt;/strong> como modo de carga&lt;/td>
&lt;td>concurrency satura simétricamente; request-rate puede acumular cola&lt;/td>
&lt;td>ITL sobreestimado si la cola crece sin techo con request-rate&lt;/td>
&lt;td>NVIDIA fundamentals; AIPerf docs&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Ventana de medición demasiado corta&lt;/strong>&lt;/td>
&lt;td>no capta el régimen estacionario; incluye ramp-up&lt;/td>
&lt;td>throughput sobre-estimado; latencia subestimada&lt;/td>
&lt;td>meta-métricas arXiv 2508.10251&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Estado térmico y frecuencias de GPU&lt;/strong>&lt;/td>
&lt;td>throttling térmico reduce throughput si no hay estabilización previa&lt;/td>
&lt;td>temperatura &amp;gt; 75 °C dispara throttling; diferencia de ~3 W de potencia estable&lt;/td>
&lt;td>arXiv 2604.09048&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Prefix-cache caliente entre corridas&lt;/strong>&lt;/td>
&lt;td>sobrevalora TTFT; TTFT irreal si el cache está pre-poblado de la corrida anterior&lt;/td>
&lt;td>efecto severo en evaluaciones multi-prompt con prefijos compartidos&lt;/td>
&lt;td>arXiv 2605.24217&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Media en vez de percentiles&lt;/strong>&lt;/td>
&lt;td>oculta la cola de latencia&lt;/td>
&lt;td>P99 puede ser 4–6× la mediana a alta concurrencia&lt;/td>
&lt;td>NVIDIA fundamentals; Anyscale docs&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="el-sesgo-dominante-saturación-del-cliente-mono-proceso">El sesgo dominante: saturación del cliente mono-proceso&lt;/h2>
&lt;p>El sesgo de mayor magnitud no está en el motor sino en el &lt;strong>cliente que genera la carga&lt;/strong>. Las
herramientas mono-proceso (vLLM bench, SGLang bench, genai-perf antes de su reemplazo por
AIPerf el 15 de abril de 2026) usan un único proceso Python con asyncio para gestionar las
peticiones concurrentes. El Python Global Interpreter Lock (GIL) impide que un solo proceso
utilice más de un núcleo CPU simultáneamente, lo que introduce un cuello de botella en el
lado cliente que se vuelve crítico a alta concurrencia.&lt;/p>
&lt;p>El efecto matemático: a medida que el request rate sube, el cliente no consigue despachar
peticiones al ritmo configurado, acumula tiempo de espera en cola en el lado cliente, y ese
tiempo se registra como latencia del motor. El resultado es que el TTFT y el TPOT
&lt;strong>aparecen inflados&lt;/strong> y el throughput &lt;strong>aparece deprimido&lt;/strong>, sin que el motor haya cambiado
nada (&lt;a href="https://arxiv.org/abs/2605.24217">arXiv 2605.24217&lt;/a>).&lt;/p>
&lt;p>La discrepancia documentada a 1.000 QPS:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Arquitectura de cliente&lt;/th>
&lt;th>Tokens procesados a 1.000 QPS&lt;/th>
&lt;th>Ratio&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Mono-proceso (asyncio, Python GIL)&lt;/td>
&lt;td>75.574&lt;/td>
&lt;td>1× (base)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Multi-proceso (carga distribuida)&lt;/td>
&lt;td>545.733&lt;/td>
&lt;td>&lt;strong>7,2×&lt;/strong>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Nota: ambos clientes apuntan al &lt;strong>mismo endpoint&lt;/strong>; la diferencia es íntegramente atribuible
al cliente de benchmark, no al motor.&lt;/p>
&lt;div class="diagram" style="max-width:780px;margin:1rem auto;">
&lt;svg viewBox="0 0 780 220" role="img" aria-label="Diagrama de saturacion del cliente: cliente mono-proceso acumula cola en el lado cliente y reporta latencia inflada; cliente multi-proceso elimina el cuello y mide el motor real" xmlns="http://www.w3.org/2000/svg">
&lt;style>.bx{fill:none;stroke:currentColor;stroke-width:1.3}.dsh{fill:none;stroke:currentColor;stroke-width:1.3;stroke-dasharray:5 3}.tl{font:600 12px sans-serif;fill:currentColor}.ts{font:11px sans-serif;fill:currentColor}.ar{fill:none;stroke:currentColor;stroke-width:1.3;marker-end:url(#bm2)}&lt;/style>
&lt;defs>&lt;marker id="bm2" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">&lt;path d="M0,0 L10,5 L0,10 z" fill="currentColor"/>&lt;/marker>&lt;/defs>
&lt;text x="20" y="22" class="tl">MONO-PROCESO (vLLM bench, SGLang bench, genai-perf pre-AIPerf)&lt;/text>
&lt;rect class="bx" x="20" y="32" width="140" height="44" rx="5"/>
&lt;text x="30" y="52" class="ts">1 proc. Python&lt;/text>
&lt;text x="30" y="67" class="ts">asyncio + GIL&lt;/text>
&lt;rect class="dsh" x="200" y="32" width="130" height="44" rx="5"/>
&lt;text x="210" y="52" class="ts">cola cliente&lt;/text>
&lt;text x="210" y="67" class="ts">(≠ cola motor)&lt;/text>
&lt;path class="ar" d="M160,54 L198,54"/>
&lt;path class="ar" d="M330,54 L375,54"/>
&lt;rect class="bx" x="375" y="32" width="110" height="44" rx="5"/>
&lt;text x="385" y="58" class="ts">Motor (vLLM…)&lt;/text>
&lt;text x="498" y="48" class="ts">TTFT/TPOT&lt;/text>
&lt;text x="498" y="63" class="ts">sobreestimados&lt;/text>
&lt;text x="498" y="78" class="ts">TPS subestimado&lt;/text>
&lt;text x="20" y="112" class="tl">MULTI-PROCESO (AIPerf, GuideLLM)&lt;/text>
&lt;rect class="bx" x="20" y="122" width="140" height="44" rx="5"/>
&lt;text x="30" y="142" class="ts">N procesos&lt;/text>
&lt;text x="30" y="157" class="ts">sin GIL compartido&lt;/text>
&lt;path class="ar" d="M160,144 L375,144"/>
&lt;rect class="bx" x="375" y="122" width="110" height="44" rx="5"/>
&lt;text x="385" y="148" class="ts">Motor (vLLM…)&lt;/text>
&lt;text x="498" y="138" class="ts">mide el motor;&lt;/text>
&lt;text x="498" y="153" class="ts">7,2× más throughput&lt;/text>
&lt;text x="498" y="168" class="ts">capturado&lt;/text>
&lt;text x="20" y="210" class="ts">La arquitectura del cliente determina qué se mide: el cuello del cliente o el del motor.&lt;/text>
&lt;/svg>
&lt;/div>
&lt;hr>
&lt;h2 id="el-sesgo-del-tokenizer-toks-no-son-comparables-entre-vocabularios">El sesgo del tokenizer: tok/s no son comparables entre vocabularios&lt;/h2>
&lt;p>Los tokens no son universales. Cada modelo tiene su propio tokenizer con su propio
vocabulario. Llama-3 usa un vocabulario de 128.256 tokens; Gemma usa 256.128; modelos
anteriores usaban 32.000–50.000. El mismo texto en inglés produce un número de tokens
distinto según el tokenizer del modelo.&lt;/p>
&lt;p>La consecuencia directa para el benchmarking: si la herramienta mide tok/s con un
tokenizer distinto al del modelo servido, el número de tokens —y por tanto el throughput en
tok/s y el coste por token— están sesgados. LLMPerf (archivado en diciembre de 2025) usaba
&lt;strong>LlamaTokenizer&lt;/strong> de forma universal para todos los modelos, lo que garantizaba consistencia
interna en el leaderboard pero hacía los tok/s &lt;strong>incomparables&lt;/strong> con mediciones de otros
modelos con vocabularios distintos.&lt;/p>
&lt;p>La fórmula del TPS en LLMPerf incluía además el denominador completo del benchmark —tiempo
de generación de prompts, preparación de peticiones y almacenamiento de respuestas—, que
NVIDIA estimó en hasta un &lt;strong>33 % de la duración total&lt;/strong> a concurrencia 1. Esto hace que el
TPS de LLMPerf sea sistemáticamente inferior al de GenAI-Perf/AIPerf para el mismo sistema,
sin que el motor sea peor:&lt;/p>
&lt;p>$$\text{TPS}&lt;em>{\text{LLMPerf}} = \frac{\text{tokens salida}}{T&lt;/em>{\text{end}} - T_{\text{start}}}$$&lt;/p>
&lt;p>$$\text{TPS}_{\text{GenAI-Perf}} = \frac{\text{tokens salida}}{T_y - T_x}$$&lt;/p>
&lt;p>Donde (T_{\text{start}}) y (T_{\text{end}}) incluyen los overheads de cliente, mientras
que (T_x) y (T_y) son el instante del primer request y el del último token recibido,
respectivamente (&lt;a href="https://developer.nvidia.com/blog/llm-benchmarking-fundamental-concepts/">NVIDIA · Fundamental Concepts&lt;/a>).&lt;/p>
&lt;p>La regla operativa: &lt;strong>siempre contar tokens con el tokenizer del modelo servido&lt;/strong>, no con un
tokenizer proxy.&lt;/p>
&lt;hr>
&lt;h2 id="el-sesgo-de-ignore_eos-y-osl-inconsistente">El sesgo de ignore_eos y OSL inconsistente&lt;/h2>
&lt;p>La mayoría de los modelos LLM generan un token especial de fin de secuencia (EOS) cuando
consideran completa la respuesta. Si el benchmark no configura &lt;code>ignore_eos=True&lt;/code>, la longitud
real de salida (OSL) varía de petición en petición según la distribución de longitudes
naturales del modelo, lo que produce:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>OSL inconsistente&lt;/strong>: dos corridas con la misma semilla pueden producir distribuciones
de OSL distintas si el modelo varía su output natural.&lt;/li>
&lt;li>&lt;strong>Comparación espuria&lt;/strong>: un modelo &amp;ldquo;más rápido&amp;rdquo; puede serlo simplemente porque genera
respuestas más cortas (termina antes en EOS), no porque tenga más throughput real.&lt;/li>
&lt;li>&lt;strong>Throughput subestimado&lt;/strong>: si el benchmark espera OSL=256 pero el modelo termina en
OSL=80 de media, el throughput en tok/s parece mayor pero mide menos trabajo.&lt;/li>
&lt;/ol>
&lt;p>El parámetro &lt;code>ignore_eos&lt;/code> (o &lt;code>--ignore-eos&lt;/code> en vLLM bench) instruye al motor a ignorar el
token EOS y continuar hasta alcanzar &lt;code>max_tokens&lt;/code>. Es &lt;strong>obligatorio&lt;/strong> para que el OSL sea el
configurado, no el natural del modelo, y para que dos corridas sean comparables
(&lt;a href="https://docs.vllm.ai/en/latest/benchmarking/cli/">vLLM benchmark CLI docs&lt;/a>).&lt;/p>
&lt;hr>
&lt;h2 id="el-sesgo-de-la-distribución-islosl">El sesgo de la distribución ISL/OSL&lt;/h2>
&lt;p>La distribución de longitudes de entrada (ISL) y salida (OSL) determina qué proporción del
tiempo de cómputo se destina al prefill (costoso en TTFT) y cuánto al decode (costoso en
ITL). Un benchmark con longitud fija —por ejemplo ISL=128, OSL=128— produce resultados que
no se parecen a ningún tráfico real.&lt;/p>
&lt;p>Los casos de uso reales tienen distribuciones muy distintas:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Caso de uso&lt;/th>
&lt;th>ISL típico (tokens)&lt;/th>
&lt;th>OSL típico (tokens)&lt;/th>
&lt;th>Domina&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Traducción&lt;/td>
&lt;td>500–2.000&lt;/td>
&lt;td>500–2.000&lt;/td>
&lt;td>equilibrado&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Generación (código, email)&lt;/td>
&lt;td>~100&lt;/td>
&lt;td>~1.000&lt;/td>
&lt;td>decode (OSL largo)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Resumen / RAG&lt;/td>
&lt;td>~1.000&lt;/td>
&lt;td>~100&lt;/td>
&lt;td>prefill (ISL largo)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Razonamiento (CoT)&lt;/td>
&lt;td>~100&lt;/td>
&lt;td>1.000–10.000&lt;/td>
&lt;td>decode muy largo&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Un benchmark de ISL corto con un modelo optimizado para prefill dará un TTFT artificialmente
bajo y un throughput artificialmente alto. El codo del sweep se desplaza: con ISL=64 el
sistema admite más concurrencia sin romper el SLO de TTFT; con ISL=1.024 el prefill satura
antes y el codo aparece antes. Usar la distribución equivocada es dimensionar para un tráfico
que no existe.&lt;/p>
&lt;p>AIPerf introduce &lt;strong>distribuciones de secuencia&lt;/strong> con varianza configurable por componente
para reproducir mezclas de tráfico realistas
(&lt;a href="https://docs.nvidia.com/aiperf/tutorials/datasets-inputs/sequence-length-distributions-for-advanced-benchmarking">AIPerf · Sequence Length Distributions&lt;/a>):&lt;/p>
&lt;pre tabindex="0">&lt;code>--sequence-distribution &amp;#34;64|10,32|8:70;256|40,128|20:20;1024|100,512|50:10&amp;#34;
&lt;/code>&lt;/pre>&lt;p>Esto crea el 70 % de peticiones con (\text{ISL} \sim \mathcal{N}(64, 10)) y
(\text{OSL} \sim \mathcal{N}(32, 8)), el 20 % con ISL/OSL medios, y el 10 % con
ISL/OSL largos —mucho más fiel a un tráfico de chatbot real que una longitud fija—.&lt;/p>
&lt;hr>
&lt;h2 id="el-sesgo-del-warmup-y-el-prefix-cache">El sesgo del warmup y el prefix-cache&lt;/h2>
&lt;p>Dos fuentes de sesgo relacionadas pero distintas:&lt;/p>
&lt;p>&lt;strong>Warmup ausente.&lt;/strong> Las primeras peticiones de un benchmark llegan a un motor &amp;ldquo;frío&amp;rdquo;: la
GPU está en estado de baja frecuencia, el KV cache está vacío, y el sistema operativo puede
estar paginando memoria. El TTFT de las primeras peticiones es estructuralmente más alto que
el del régimen estacionario. Si el benchmark no descarta un periodo de warmup, la media de
TTFT incluye estos outliers y sobreestima la latencia real de producción. Algunos frameworks
(GenAI-Perf/AIPerf) usan una &lt;strong>ventana deslizante&lt;/strong> que excluye las peticiones de ramp-up y
ramp-down; otros no.&lt;/p>
&lt;p>&lt;strong>Prefix-cache caliente entre corridas.&lt;/strong> La caché de KV de prefijos (prefix cache o prompt
cache) almacena los resultados computados de los prefijos de prompt que se repiten. Si el
benchmark corre múltiples corridas consecutivas con los mismos prompts, la segunda y
siguientes corridas encuentran el KV cache ya poblado y reportan un TTFT artificialmente
bajo —el del decode, no el del prefill—. Para un benchmark de baseline, el prefix cache debe
estar frío; para uno que simula producción con prompts repetidos, caliente. La distinción
debe explicitarse
(&lt;a href="https://arxiv.org/abs/2605.24217">arXiv 2605.24217&lt;/a>; &lt;a href="https://docs.vllm.ai/en/stable/design/prefix_caching/">vLLM · Automatic Prefix Caching&lt;/a>).&lt;/p>
&lt;hr>
&lt;h2 id="el-sesgo-de-concurrency-vs-request-rate">El sesgo de &lt;code>concurrency&lt;/code> vs &lt;code>request-rate&lt;/code>&lt;/h2>
&lt;p>Los dos modos de control de carga producen distribuciones de latencia distintas para el
mismo sistema:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Modo&lt;/th>
&lt;th>Semántica&lt;/th>
&lt;th>Cuándo usar&lt;/th>
&lt;th>Riesgo&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>concurrency N&lt;/strong>&lt;/td>
&lt;td>mantiene exactamente N peticiones en vuelo; en cuanto termina una, lanza otra&lt;/td>
&lt;td>medir el sistema bajo una carga de concurrencia fija&lt;/td>
&lt;td>sobrerepresenta la carga sostenida; no simula llegadas reales&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>request-rate r&lt;/strong> (constante o Poisson)&lt;/td>
&lt;td>lanza una petición cada (1/r) segundos (constante) o con interarrival (\sim \text{Exp}(1/r)) (Poisson)&lt;/td>
&lt;td>simular tráfico real (llegadas aleatorias)&lt;/td>
&lt;td>si el motor no puede absorber r req/s, la cola crece sin techo&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>NVIDIA recomienda el modo &lt;strong>concurrency&lt;/strong> para la mayoría de los benchmarks de capacidad
(&lt;a href="https://developer.nvidia.com/blog/llm-benchmarking-fundamental-concepts/">NVIDIA · LLM Benchmarking Fundamental Concepts&lt;/a>). El modo request-rate es más fiel para tráfico online
(distribución Poisson de llegadas), pero si el rate supera la capacidad del motor la cola
crece indefinidamente y las métricas de latencia incluyen tiempo de espera en cola que puede
dominar el TTFT, mezclando comportamiento de cola con comportamiento del motor.&lt;/p>
&lt;p>Un sistema medido con concurrency=16 y otro con request-rate=16 req/s &lt;strong>no están bajo la
misma carga&lt;/strong>: la concurrencia fija garantiza 16 peticiones simultáneas; el rate configura
el ritmo de llegada pero no la concurrencia instantánea. Comparar sus resultados sin ajuste
es incorrecto.&lt;/p>
&lt;hr>
&lt;h2 id="el-sesgo-de-la-ventana-de-medición-y-el-estado-térmico">El sesgo de la ventana de medición y el estado térmico&lt;/h2>
&lt;p>&lt;strong>Ventana demasiado corta.&lt;/strong> Un benchmark de 30 segundos puede medir el ramp-up del
sistema, no el régimen estacionario. La recomendación de arXiv 2508.10251 es que la ventana
de medición cubra al menos 3-5× el tiempo de rampa del sistema bajo carga, y que las
métricas se calculen solo sobre la ventana estacionaria —excluyendo warmup y cooldown—.&lt;/p>
&lt;p>&lt;strong>Estado térmico de la GPU.&lt;/strong> Las GPUs de datacenter (H100 SXM, A100) operan con throttling
térmico por encima de ~75 °C. Si la GPU no ha alcanzado la temperatura de régimen antes del
benchmark, las primeras mediciones corresponden a un estado de mayor frecuencia que el
sostenible. Experimentos controlados documentan que la potencia debe estabilizarse en un
rango de &lt;strong>3 W&lt;/strong> durante al menos 30 segundos antes de que las medidas sean representativas
(&lt;a href="https://arxiv.org/html/2604.09048v1">arXiv 2604.09048 · Watt Counts&lt;/a>). El efecto es
especialmente severo en benchmarks de prefill (TTFT), donde las frecuencias altas del estado
frío producen TTFT artificialmente bajo.&lt;/p>
&lt;p>Para un benchmark reproducible en 4×H100 SXM 80 GB: antes de medir, correr carga sostenida
durante al menos 2–3 minutos hasta que &lt;code>nvidia-smi&lt;/code> reporte temperatura estable y potencia
estable (variación &amp;lt; 3 W en 30 s). Solo entonces iniciar la ventana de medición.&lt;/p>
&lt;hr>
&lt;h2 id="cómo-las-herramientas-calculan-diferente-la-itl">Cómo las herramientas calculan diferente la ITL&lt;/h2>
&lt;p>La ITL (Inter-Token Latency) aparece en todas las herramientas pero su fórmula varía, y las
diferencias no son pequeñas:&lt;/p>
&lt;p>&lt;strong>GenAI-Perf / AIPerf:&lt;/strong>&lt;/p>
&lt;p>$$\text{ITL} = \frac{\text{e2e latency} - \text{TTFT}}{\text{tokens salida} - 1}$$&lt;/p>
&lt;p>El TTFT se excluye del numerador y el denominador descuenta el primer token. ITL es una
métrica pura del &lt;strong>decode&lt;/strong>, sin contaminación del prefill.&lt;/p>
&lt;p>&lt;strong>LLMPerf&lt;/strong> (archivado dic. 2025):&lt;/p>
&lt;p>$$\text{ITL}_{\text{LLMPerf}} = \frac{\text{e2e latency}}{\text{tokens salida}}$$&lt;/p>
&lt;p>El TTFT se &lt;strong>incluye&lt;/strong> en el numerador. Para secuencias cortas (OSL &amp;lt; 50 tokens), el TTFT
puede representar el 50–80 % de la e2e_latency, con lo que la ITL de LLMPerf mide
principalmente el prefill, no el decode. Dos sistemas con el mismo decode pero distinto
prefill aparecerán con ITL distintas en LLMPerf aunque sean idénticos en velocidad de decode.&lt;/p>
&lt;p>&lt;strong>vLLM bench (benchmark_serving.py):&lt;/strong>&lt;/p>
&lt;p>Calcula ITL como media de los intervalos entre tokens consecutivos del stream de salida,
incluyendo varianza intra-petición. Puede revelar jitter de decode que los otros promedian.&lt;/p>
&lt;p>La consecuencia práctica: &lt;strong>nunca cruzar una ITL de GenAI-Perf con una de LLMPerf&lt;/strong> como si
fueran la misma métrica. Son fórmulas distintas sobre la misma señal.&lt;/p>
&lt;hr>
&lt;h2 id="comparabilidad-entre-herramientas-por-qué-sus-números-no-se-cruzan">Comparabilidad entre herramientas: por qué sus números no se cruzan&lt;/h2>
&lt;p>La tabla siguiente resume las diferencias metodológicas que hacen que los números de una
herramienta sean &lt;strong>estructuralmente incompatibles&lt;/strong> con los de otra sin ajuste explícito:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Dimensión&lt;/th>
&lt;th>vLLM bench&lt;/th>
&lt;th>LLMPerf (archivado)&lt;/th>
&lt;th>GenAI-Perf / AIPerf&lt;/th>
&lt;th>GuideLLM&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Arquitectura cliente&lt;/strong>&lt;/td>
&lt;td>mono-proceso asyncio&lt;/td>
&lt;td>mono-proceso&lt;/td>
&lt;td>&lt;strong>multi-proceso&lt;/strong>&lt;/td>
&lt;td>&lt;strong>multi-proceso&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>ITL incluye TTFT&lt;/strong>&lt;/td>
&lt;td>no&lt;/td>
&lt;td>&lt;strong>sí&lt;/strong>&lt;/td>
&lt;td>no&lt;/td>
&lt;td>no&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>TPS denominador&lt;/strong>&lt;/td>
&lt;td>(T_y - T_x)&lt;/td>
&lt;td>(T_{\text{end}} - T_{\text{start}}) (overhead incluido)&lt;/td>
&lt;td>(T_y - T_x)&lt;/td>
&lt;td>por ronda&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Tokenizer&lt;/strong>&lt;/td>
&lt;td>el del modelo servido&lt;/td>
&lt;td>LlamaTokenizer universal&lt;/td>
&lt;td>el del modelo servido&lt;/td>
&lt;td>el del modelo servido&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Warmup / sliding window&lt;/strong>&lt;/td>
&lt;td>no automático&lt;/td>
&lt;td>no&lt;/td>
&lt;td>&lt;strong>sí (sliding window)&lt;/strong>&lt;/td>
&lt;td>por ronda&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>ignore_eos por defecto&lt;/strong>&lt;/td>
&lt;td>no&lt;/td>
&lt;td>no&lt;/td>
&lt;td>recomendado explícitamente&lt;/td>
&lt;td>configurable&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Distribución ISL/OSL&lt;/strong>&lt;/td>
&lt;td>parámetro manual&lt;/td>
&lt;td>parámetro manual&lt;/td>
&lt;td>distribuciones con varianza&lt;/td>
&lt;td>&lt;code>--data&lt;/code> configurable&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Modo de carga primario&lt;/strong>&lt;/td>
&lt;td>concurrency&lt;/td>
&lt;td>concurrency (batches drenados)&lt;/td>
&lt;td>concurrency (recomendado)&lt;/td>
&lt;td>sweep + poisson&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Salida estructurada&lt;/strong>&lt;/td>
&lt;td>JSON básico&lt;/td>
&lt;td>JSON&lt;/td>
&lt;td>JSON + CSV&lt;/td>
&lt;td>JSON + HTML + CSV&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Un resultado de LLMPerf y uno de GenAI-Perf para el mismo endpoint pueden diferir en TTFT,
ITL y TPS &lt;strong>simultáneamente&lt;/strong> y en todas ellas por razones metodológicas, no por diferencias
del motor. La única forma de cruzarlos es ejecutar ambas herramientas sobre el mismo sistema
en las mismas condiciones y calcular el factor de conversión empírico —lo que en la práctica
equivale a re-medir con una sola herramienta.&lt;/p>
&lt;hr>
&lt;h2 id="el-harness-honesto-checklist-de-reproducibilidad">El harness honesto: checklist de reproducibilidad&lt;/h2>
&lt;p>Un benchmark cuyo número puede defenderse en una auditoría tiene que venir acompañado de
todos los metadatos que permiten reproducirlo. El mínimo exigible, organizado por categoría:&lt;/p>
&lt;h3 id="hardware">Hardware&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Metadato&lt;/th>
&lt;th>Ejemplo 4×H100&lt;/th>
&lt;th>Efecto si no se fija&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>GPU (modelo, variante, cantidad)&lt;/td>
&lt;td>4× NVIDIA H100 SXM 80 GB&lt;/td>
&lt;td>H100 PCIe vs SXM difieren en BW de memoria y NVLink&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Interconexión GPU-GPU&lt;/td>
&lt;td>NVLink 4.0&lt;/td>
&lt;td>tensor parallelism depende de la BW de interconexión&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>CPU, RAM, ancho de banda CPU-GPU&lt;/td>
&lt;td>2× Intel Xeon 8480+, 512 GB DDR5, PCIe 5.0&lt;/td>
&lt;td>el cuello de tokenización puede estar en la CPU&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Estado térmico al inicio&lt;/td>
&lt;td>temperatura GPU &amp;lt; 65 °C, potencia estable ± 3 W&lt;/td>
&lt;td>throttling altera TPS y TTFT en hasta ~15 %&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Frecuencias de GPU (clocks)&lt;/td>
&lt;td>sin &lt;code>nvidia-smi -pm 1&lt;/code> pueden variar&lt;/td>
&lt;td>diferencia de hasta ~10 % en throughput&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="software-y-modelo">Software y modelo&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Metadato&lt;/th>
&lt;th>Ejemplo&lt;/th>
&lt;th>Efecto si no se fija&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Motor + versión + flags&lt;/td>
&lt;td>vLLM 0.8.4, &lt;code>--tensor-parallel-size 4 --gpu-memory-utilization 0.90&lt;/code>&lt;/td>
&lt;td>cada versión cambia el scheduler y el KV cache management&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Modelo + precisión&lt;/td>
&lt;td>Llama-3-70B-Instruct, FP8&lt;/td>
&lt;td>FP16 vs FP8 difieren ~1,4–1,8× en throughput&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Tokenizer usado para contar&lt;/td>
&lt;td>tokenizer del modelo servido (HF tokenizer)&lt;/td>
&lt;td>LlamaTokenizer universal sesga tok/s entre vocabularios&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Semilla de generación&lt;/td>
&lt;td>&lt;code>--seed 42&lt;/code>&lt;/td>
&lt;td>sin semilla fija, la OSL varía run-to-run&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>ignore_eos&lt;/code>&lt;/td>
&lt;td>&lt;code>True&lt;/code>&lt;/td>
&lt;td>sin él, OSL varía con el contenido del prompt&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Sampling parameters&lt;/td>
&lt;td>&lt;code>temperature=1.0, top_p=0.95&lt;/code>&lt;/td>
&lt;td>greedy vs sampling afectan velocidad de logit&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="carga">Carga&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Metadato&lt;/th>
&lt;th>Ejemplo&lt;/th>
&lt;th>Efecto si no se fija&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Herramienta de bench + versión&lt;/td>
&lt;td>AIPerf 0.2.1&lt;/td>
&lt;td>cada versión cambia fórmulas y warmup&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Distribución ISL/OSL&lt;/td>
&lt;td>(\mathcal{N}(512, 64)) ISL, (\mathcal{N}(128, 20)) OSL&lt;/td>
&lt;td>cambiar distribución mueve el codo&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Modo de carga&lt;/td>
&lt;td>concurrency, sweep 1–64&lt;/td>
&lt;td>concurrency vs request-rate: distribuciones distintas&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Niveles de concurrencia&lt;/td>
&lt;td>1, 2, 4, 8, 16, 32, 64 (sweep completo, más allá del codo)&lt;/td>
&lt;td>sin pasar el codo, la capacidad segura es desconocida&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Duración por punto&lt;/td>
&lt;td>120 s mínimo por nivel&lt;/td>
&lt;td>ventanas cortas capturan ramp-up, no régimen estacionario&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Warmup&lt;/td>
&lt;td>30 s excluidos del cómputo de métricas&lt;/td>
&lt;td>sin warmup, las métricas incluyen estado frío&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Tratamiento prefix cache&lt;/td>
&lt;td>frío (flush entre corridas) o caliente (declarar explícitamente)&lt;/td>
&lt;td>cache caliente: TTFT irreal para baseline&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="slo-y-métricas-reportadas">SLO y métricas reportadas&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Metadato&lt;/th>
&lt;th>Ejemplo&lt;/th>
&lt;th>Efecto si no se declara&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>SLO declarado&lt;/td>
&lt;td>TTFT P99 &amp;lt; 500 ms, ITL P95 &amp;lt; 50 ms&lt;/td>
&lt;td>el goodput depende del SLO; sin SLO no hay goodput&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Percentiles reportados&lt;/td>
&lt;td>P50, P95, P99 (no solo media)&lt;/td>
&lt;td>la media oculta la cola; irrelevante para SLO&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Throughput vs goodput&lt;/td>
&lt;td>goodput bajo SLO, no throughput bruto&lt;/td>
&lt;td>el throughput de catálogo puede ser 5–10× el goodput&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Número de peticiones totales&lt;/td>
&lt;td>≥ 1.000 por nivel de concurrencia&lt;/td>
&lt;td>muestras pequeñas: alta varianza en percentiles&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="defensa-metodológica-del-dato-ante-una-auditoría">Defensa metodológica del dato ante una auditoría&lt;/h2>
&lt;p>Un número de throughput que se presenta sin la ficha anterior no es un dato: es una anécdota.
El patrón de validación para una auditoría técnica:&lt;/p>
&lt;p>&lt;strong>1. Trazabilidad de la herramienta.&lt;/strong> La herramienta y su versión deben ser pinables a un
commit de Git o a un hash de imagen de contenedor. AIPerf y GuideLLM exportan JSON con
metadatos de versión; vLLM bench los omite por defecto y hay que capturarlos manualmente.&lt;/p>
&lt;p>&lt;strong>2. Reproducibilidad del entorno.&lt;/strong> El script de despliegue del motor (o el manifiesto de
Kubernetes) y el comando exacto de benchmark deben ser suficientes para que un tercero
reproduzca el número en el mismo hardware. GuideLLM exporta el archivo de benchmark como
registro autoritativo de la sesión: configuración, metadatos, estadísticas por benchmark y
entradas de petición con tiempos individuales
(&lt;a href="https://github.com/vllm-project/guidellm">GitHub vllm-project/guidellm&lt;/a>).&lt;/p>
&lt;p>&lt;strong>3. Verificación del régimen estacionario.&lt;/strong> Las métricas deben proceder de la ventana
estacionaria del benchmark (excluido warmup). La curva throughput vs concurrencia debe
mostrar el codo —el punto donde el throughput satura y la latencia se dispara— y extenderse
más allá de él. Sin codo visible, la capacidad reportada puede ser el límite del cliente, no
del motor.&lt;/p>
&lt;p>&lt;strong>4. Goodput, no throughput bruto.&lt;/strong> El throughput auditable es el goodput bajo el SLO
declarado, no el throughput máximo. Un sistema que reporta 4.000 tok/s pero cuyo goodput
bajo TTFT P99 &amp;lt; 500 ms es 1.800 tok/s tiene una capacidad real de 1.800 tok/s para los
casos de uso interactivos.&lt;/p>
&lt;p>&lt;strong>5. Comparabilidad interna.&lt;/strong> Si se comparan dos motores o dos configuraciones, la
herramienta, la distribución de carga, el SLO, el hardware y el tratamiento del warmup
deben ser &lt;strong>idénticos&lt;/strong>. Cualquier diferencia en estas dimensiones contamina la comparación.&lt;/p>
&lt;p>La fórmula del goodput como métrica auditable:&lt;/p>
&lt;p>$$\text{goodput} = \text{throughput} \times \Pr[\text{TTFT} \leq \text{SLO}&lt;em>{\text{TTFT}}] \times \Pr[\text{ITL} \leq \text{SLO}&lt;/em>{\text{ITL}}]$$&lt;/p>
&lt;p>Donde las probabilidades se estiman sobre la distribución empírica de la corrida. Un motor
con throughput de 4.000 tok/s y (\Pr[\text{TTFT} \leq 500,\text{ms}] = 0{,}45) tiene
un goodput de (4{,}000 \times 0{,}45 = 1{,}800) tok/s.&lt;/p>
&lt;hr>
&lt;h2 id="ejemplo-numérico-el-mismo-nodo-cuatro-medidas-distintas">Ejemplo numérico: el mismo nodo, cuatro medidas distintas&lt;/h2>
&lt;p>Hardware de referencia: 4×H100 SXM 80 GB, modelo Llama-3-70B-Instruct FP8, tensor
parallel 4, SLO TTFT P99 &amp;lt; 500 ms.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Configuración de benchmark&lt;/th>
&lt;th>Throughput reportado&lt;/th>
&lt;th>Goodput real&lt;/th>
&lt;th>Factor vs goodput&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>vLLM bench, concurrency=32, sin ignore_eos, sin warmup, OSL=64 fijo&lt;/td>
&lt;td>5.800 tok/s&lt;/td>
&lt;td>~1.200 tok/s (OSL corto infla TPS)&lt;/td>
&lt;td>&lt;strong>4,8×&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>LLMPerf, concurrency=32, LlamaTokenizer, overhead incluido en denominador&lt;/td>
&lt;td>3.100 tok/s&lt;/td>
&lt;td>~1.600 tok/s (ITL incluye TTFT)&lt;/td>
&lt;td>&lt;strong>1,9×&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>AIPerf, concurrency=32, ignore_eos, sliding window, tokenizer del modelo&lt;/td>
&lt;td>3.400 tok/s&lt;/td>
&lt;td>3.350 tok/s&lt;/td>
&lt;td>&lt;strong>1,01×&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GuideLLM, sweep 1–64, poisson, distribución ISL/OSL realista, SLO declarado&lt;/td>
&lt;td>3.330 tok/s goodput (codo en ronda 6)&lt;/td>
&lt;td>3.330 tok/s&lt;/td>
&lt;td>&lt;strong>1,0× (base honesta)&lt;/strong>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>El rango: de 1.200 tok/s a 5.800 tok/s para el mismo motor, el mismo hardware y el mismo
modelo. El factor máximo es &lt;strong>4,8×&lt;/strong>. La causa no es el motor; son las decisiones de
instrumentación.&lt;/p>
&lt;hr>
&lt;h2 id="la-descomposición-del-sesgo-total">La descomposición del sesgo total&lt;/h2>
&lt;p>El sesgo total observable entre dos herramientas es la composición multiplicativa de los
sesgos individuales. Para una comparación de vLLM bench mono-proceso vs GuideLLM
multi-proceso sobre el mismo sistema:&lt;/p>
&lt;p>$$\text{factor total} \approx \underbrace{f_{\text{cliente}}}&lt;em>{\leq 7{,}2\times} \times \underbrace{f&lt;/em>{\text{tokenizer}}}&lt;em>{1{,}0{-}1{,}3\times} \times \underbrace{f&lt;/em>{\text{ignore-eos}}}&lt;em>{1{,}0{-}2{,}0\times} \times \underbrace{f&lt;/em>{\text{ISL/OSL}}}&lt;em>{1{,}0{-}1{,}5\times} \times \underbrace{f&lt;/em>{\text{warmup}}}_{1{,}0{-}1{,}2\times}$$&lt;/p>
&lt;p>El factor de saturación del cliente ((\leq 7{,}2\times)) domina, pero los demás factores
se multiplican. En condiciones adversas (cliente mono-proceso + tokenizer distinto + sin
ignore_eos + OSL irreal + sin warmup), el sesgo compuesto puede superar &lt;strong>15–20×&lt;/strong> para
el mismo sistema.&lt;/p>
&lt;hr>
&lt;h2 id="estado-del-arte-2026-qué-ha-cambiado">Estado del arte 2026: qué ha cambiado&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Migración genai-perf → AIPerf&lt;/strong> (15-abr-2026): NVIDIA retiró genai-perf y lo sustituyó
por AIPerf, que es multi-proceso con detección automática de saturación, distribuciones
ISL/OSL configurables y ventana deslizante integrada. La migración elimina el sesgo de
cliente mono-proceso del tooling oficial de NVIDIA.&lt;/li>
&lt;li>&lt;strong>Archivo de LLMPerf&lt;/strong> (dic. 2025): el repositorio &lt;code>ray-project/llmperf&lt;/code> está archivado y
en modo solo-lectura. Los resultados históricos del LLMPerf leaderboard son comparables
solo entre sí; no se deben cruzar con mediciones modernas sin ajuste.&lt;/li>
&lt;li>&lt;strong>GuideLLM 0.5.x&lt;/strong> (2025–2026): refactor arquitectural completo, soporte multimodal, y
exportación JSON autoritativa con todos los metadatos de sesión. Es el estándar OSS de
evaluación dirigida por SLO.&lt;/li>
&lt;li>&lt;strong>arXiv 2605.24217&lt;/strong> (may. 2026): primera caracterización formal del sesgo sistemático de
medición en benchmarks de producción LLM, con demostración matemática del efecto GIL y
propuesta de harness multi-proceso.&lt;/li>
&lt;li>&lt;strong>arXiv 2508.10251&lt;/strong>: meta-métricas y buenas prácticas para benchmarking de rendimiento a
nivel de sistema; establece las dimensiones mínimas del espacio de parámetros que deben
declararse para que un resultado sea reproducible.&lt;/li>
&lt;li>&lt;strong>MLPerf Inference v5.1&lt;/strong> (sep. 2025): 27 participantes, récord de participación. Las
reglas de MLPerf exigen declarar el código exacto, el dataset y el hardware, y admiten
revisión pública —es el único benchmark de la industria con proceso de revisión formal de
reproducibilidad.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="cross-links-del-track-de-benchmarking">Cross-links del track de benchmarking&lt;/h2>
&lt;p>Los sesgos descritos aquí aplican a todas las herramientas del catálogo. Para la ficha
completa de cada herramienta:&lt;/p>
&lt;ul>
&lt;li>Catálogo completo: &lt;a href="https://blog.lo0.es/posts/herramientas-benchmark-llm-ficha-a-ficha/">Herramientas de benchmarking LLM, ficha a ficha&lt;/a>&lt;/li>
&lt;li>GuideLLM y la validación de SLO: &lt;a href="https://blog.lo0.es/posts/guidellm-validacion-slo-bajo-carga/">GuideLLM a fondo: validar el SLO bajo carga&lt;/a>&lt;/li>
&lt;li>AIPerf (ex genai-perf) y la detección de saturación: &lt;a href="https://blog.lo0.es/posts/nvidia-genai-perf-a-fondo/">NVIDIA GenAI-Perf a fondo&lt;/a>&lt;/li>
&lt;li>Estado del arte de frameworks: &lt;a href="https://blog.lo0.es/posts/benchmarking-llm-frameworks-estado-del-arte/">Benchmarking LLM: frameworks y estado del arte&lt;/a>&lt;/li>
&lt;li>Decisión de motor en el eje Pareto: &lt;a href="https://blog.lo0.es/posts/comparativa-motores-serving-pareto/">Comparativa de motores de serving: frontera Pareto&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="fuentes">Fuentes&lt;/h2>
&lt;ul>
&lt;li>arXiv 2605.24217 · Identifying and Mitigating Systemic Measurement Bias in Production LLM Inference Benchmarks — &lt;a href="https://arxiv.org/abs/2605.24217">https://arxiv.org/abs/2605.24217&lt;/a>&lt;/li>
&lt;li>arXiv 2508.10251 · Meta-Metrics and Best Practices for System-Level Inference Performance Benchmarking — &lt;a href="https://arxiv.org/pdf/2508.10251">https://arxiv.org/pdf/2508.10251&lt;/a>&lt;/li>
&lt;li>arXiv 2604.09048 · Watt Counts: Energy-Aware Benchmark for Sustainable LLM Inference on Heterogeneous GPU Architectures — &lt;a href="https://arxiv.org/html/2604.09048v1">https://arxiv.org/html/2604.09048v1&lt;/a>&lt;/li>
&lt;li>NVIDIA Technical Blog · LLM Inference Benchmarking: Fundamental Concepts (ITL, TPS, ISL/OSL, ignore_eos, concurrency vs request-rate) — &lt;a href="https://developer.nvidia.com/blog/llm-benchmarking-fundamental-concepts/">https://developer.nvidia.com/blog/llm-benchmarking-fundamental-concepts/&lt;/a>&lt;/li>
&lt;li>NVIDIA AIPerf Docs · Sequence Length Distributions for Advanced Benchmarking — &lt;a href="https://docs.nvidia.com/aiperf/tutorials/datasets-inputs/sequence-length-distributions-for-advanced-benchmarking">https://docs.nvidia.com/aiperf/tutorials/datasets-inputs/sequence-length-distributions-for-advanced-benchmarking&lt;/a>&lt;/li>
&lt;li>NVIDIA AIPerf · Request Rate with Max Concurrency — &lt;a href="https://docs.nvidia.com/aiperf/tutorials/load-patterns-scheduling/request-rate-with-max-concurrency">https://docs.nvidia.com/aiperf/tutorials/load-patterns-scheduling/request-rate-with-max-concurrency&lt;/a>&lt;/li>
&lt;li>NVIDIA AIPerf · Comprehensive LLM Benchmarking Guide — &lt;a href="https://lucaberton.com/blog/nvidia-aiperf-llm-inference-benchmarking-guide/">https://lucaberton.com/blog/nvidia-aiperf-llm-inference-benchmarking-guide/&lt;/a>&lt;/li>
&lt;li>vLLM Documentation · Benchmark CLI (ignore_eos, métricas disponibles) — &lt;a href="https://docs.vllm.ai/en/latest/benchmarking/cli/">https://docs.vllm.ai/en/latest/benchmarking/cli/&lt;/a>&lt;/li>
&lt;li>vLLM Documentation · Automatic Prefix Caching — &lt;a href="https://docs.vllm.ai/en/stable/design/prefix_caching/">https://docs.vllm.ai/en/stable/design/prefix_caching/&lt;/a>&lt;/li>
&lt;li>GitHub · ray-project/llmperf (archivado dic. 2025) — &lt;a href="https://github.com/ray-project/llmperf">https://github.com/ray-project/llmperf&lt;/a>&lt;/li>
&lt;li>GitHub · vllm-project/guidellm (exportación JSON autoritativa, metadatos de sesión) — &lt;a href="https://github.com/vllm-project/guidellm">https://github.com/vllm-project/guidellm&lt;/a>&lt;/li>
&lt;li>Red Hat Developer · GuideLLM: evaluar despliegues LLM para inferencia real — &lt;a href="https://developers.redhat.com/articles/2025/06/20/guidellm-evaluate-llm-deployments-real-world-inference">https://developers.redhat.com/articles/2025/06/20/guidellm-evaluate-llm-deployments-real-world-inference&lt;/a>&lt;/li>
&lt;li>MLCommons · MLPerf Inference v5.1 results (récord 27 participantes, reproducibilidad formal) — &lt;a href="https://mlcommons.org/2025/09/mlperf-inference-v5-1-results/">https://mlcommons.org/2025/09/mlperf-inference-v5-1-results/&lt;/a>&lt;/li>
&lt;li>arXiv 2502.16721 · Speed and Conversational LLMs: Not All Is About Tokens per Second (tokenizer incompatibilidad y tok/s entre vocabularios) — &lt;a href="https://arxiv.org/pdf/2502.16721">https://arxiv.org/pdf/2502.16721&lt;/a>&lt;/li>
&lt;li>Medium · LLM Inference Benchmarking (genAI-perf y vLLM, discrepancia 7,2×) — &lt;a href="https://kchandan.medium.com/llm-inference-benchmarking-genai-perf-and-vllm-5dd06b57428e">https://kchandan.medium.com/llm-inference-benchmarking-genai-perf-and-vllm-5dd06b57428e&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>