<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dcgm on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/dcgm/</link><description>Recent content in Dcgm on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Tue, 02 Jun 2026 04:00:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/tags/dcgm/index.xml" rel="self" type="application/rss+xml"/><item><title>Anatomía de las doce métricas DCGM y cinco vLLM: analogías, anomalías documentadas y casos reales 2024-2026</title><link>https://blog.lo0.es/posts/anatomia-metricas-dcgm-vllm-anomalias/</link><pubDate>Tue, 02 Jun 2026 04:00:00 +0200</pubDate><guid>https://blog.lo0.es/posts/anatomia-metricas-dcgm-vllm-anomalias/</guid><description>&lt;blockquote>
&lt;p>Este post profundiza la lista de métricas presentada en &lt;a href="https://blog.lo0.es/posts/observabilidad-gpu-dcgm-llm/">Observabilidad GPU para inferencia LLM&lt;/a>. Allí cada métrica recibió su umbral V/Á/R y query PromQL; aquí cada una recibe su analogía explicativa y la anomalía documentada en producción con caso público referenciado. Es el post que conviene tener abierto cuando una alerta dispara y todavía no se sabe qué hacer con ella; el &lt;a href="https://blog.lo0.es/posts/runbooks-incident-response-llm-keep-kafka/">siguiente post sobre runbooks&lt;/a> traduce cada anomalía a acción concreta.&lt;/p>
&lt;/blockquote>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>Las doce métricas DCGM (compute, memoria, térmico-energético, salud) y las cinco del motor vLLM (concurrencia, KV pool, latencias del SLO) cubiertas en el post anterior pintan la cabina del cluster, pero la lista sin contexto no enseña a diagnosticar. Cada métrica tiene un &lt;strong>patrón anómalo recurrente&lt;/strong> documentado en literatura pública —papers académicos, issues GitHub, KBs de OEMs, blogs de operadores— que el operador veterano reconoce al instante y el junior no. Este post desarrolla cada métrica con una &lt;strong>analogía propia&lt;/strong> que fija qué pregunta responde y con la &lt;strong>anomalía estadísticamente relevante&lt;/strong> con cifras de incidentes documentados. Tres ejemplos del calibre: &lt;strong>Meta&lt;/strong> publicó que durante el entrenamiento de Llama 3 405B sobre 16.384 H100 hubo &lt;strong>419 fallos no planificados en 54 días&lt;/strong> —uno cada 3 horas—, con GPU + HBM3 acumulando el 47 % del total; el paper &lt;em>Story of Two GPUs&lt;/em> (arXiv 2503.11901) cuantifica que &lt;strong>H100 tiene 3.2× peor MTBE por ECC uncorrectable que A100&lt;/strong> atribuible a la densidad superior de HBM3; el issue &lt;strong>vllm#16300&lt;/strong> documenta que en un cluster de 8×A100 80 GB &lt;strong>TP=8 entrega peor throughput que TP=4&lt;/strong> porque la saturación de NVLink mata el speedup de partition. Las KBs &lt;strong>Dell 000220508&lt;/strong> y &lt;strong>Lenovo HT514380&lt;/strong> formalizan el caso recurrente de &lt;em>HW Power Brake&lt;/em> en racks H100 sobrecomprometidos a nivel de PDU. El issue &lt;strong>vllm#25677&lt;/strong> mostró &lt;em>chunked prefill&lt;/em> 10× más lento que sin él en Qwen3-30B-A3B (mala calibración de &lt;code>max_num_batched_tokens&lt;/code>). El issue &lt;strong>vllm#11912&lt;/strong> documenta regresión de TPOT de 15.7 ms a 25.7 ms cruzando versión 0.6.4. Cada caso incluye URL verificable. La regla operativa: cuando llega una alerta, mira primero el patrón anómalo asociado a la métrica que disparó, &lt;strong>antes&lt;/strong> de abrir la traza de la request; el 80 % de las degradaciones casan con uno de los patrones documentados.&lt;/p>
&lt;h2 id="estás-aquí-observe--la-capa-de-diagnóstico">Estás aquí: OBSERVE — la capa de diagnóstico&lt;/h2>
&lt;div class="diagram" style="max-width:780px;margin:1rem auto;">
&lt;svg viewBox="0 0 780 90" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="estás aquí: Observe, capa de diagnóstico">
&lt;style>.box{stroke:#444;stroke-width:1.4;rx:6}.active{fill:#c9a8e9;stroke-width:3}.idle{fill:#f4f4f4}.lbl{font:600 12px sans-serif;fill:#222}.arr{stroke:#666;stroke-width:1.4;fill:none;marker-end:url(#anm)}.cyc{stroke:#888;stroke-width:1.2;fill:none;stroke-dasharray:4 2;marker-end:url(#anm)}&lt;/style>
&lt;defs>&lt;marker id="anm" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">&lt;path d="M0,0 L10,5 L0,10 z" fill="#666"/>&lt;/marker>&lt;/defs>
&lt;text x="390" y="20" text-anchor="middle" class="lbl">Estás aquí: OBSERVE · cada métrica es una pregunta con una anomalía típica asociada&lt;/text>
&lt;rect x="30" y="35" width="110" height="35" class="box idle"/>&lt;text x="85" y="58" text-anchor="middle" class="lbl">1 · Data&lt;/text>
&lt;rect x="155" y="35" width="110" height="35" class="box idle"/>&lt;text x="210" y="58" text-anchor="middle" class="lbl">2 · Tune&lt;/text>
&lt;rect x="280" y="35" width="110" height="35" class="box idle"/>&lt;text x="335" y="58" text-anchor="middle" class="lbl">3 · Eval&lt;/text>
&lt;rect x="405" y="35" width="110" height="35" class="box idle"/>&lt;text x="460" y="58" text-anchor="middle" class="lbl">4 · Deploy&lt;/text>
&lt;rect x="530" y="35" width="110" height="35" class="box active"/>&lt;text x="585" y="58" text-anchor="middle" class="lbl">5 · Observe&lt;/text>
&lt;rect x="655" y="35" width="110" height="35" class="box idle"/>&lt;text x="710" y="58" text-anchor="middle" class="lbl">6 · Retrain&lt;/text>
&lt;path class="arr" d="M140,52 L155,52"/>&lt;path class="arr" d="M265,52 L280,52"/>&lt;path class="arr" d="M390,52 L405,52"/>&lt;path class="arr" d="M515,52 L530,52"/>&lt;path class="arr" d="M640,52 L655,52"/>
&lt;path class="cyc" d="M710,72 L710,82 L85,82 L85,72"/>
&lt;/svg>
&lt;/div>
&lt;h2 id="familia-1--compute">Familia 1 — Compute&lt;/h2>
&lt;h3 id="dcgm_fi_prof_sm_occupancy--hay-trabajo-paralelo-en-los-motores">&lt;code>DCGM_FI_PROF_SM_OCCUPANCY&lt;/code> — ¿hay trabajo paralelo en los motores?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> Una cocina industrial con 32 fogones y un único chef. La métrica responde &lt;em>&amp;quot;¿cuántos fogones tienen una sartén encima ahora mismo?&amp;quot;&lt;/em>. Si la mitad están vacíos, la cocina está infrautilizada — los pedidos van uno detrás de otro porque el chef no abre paralelo. Si todos están ocupados pero el chef está sin moverse mirando un cronómetro, los fogones están encendidos pero no se cocina (un kernel patológico saturando SMs sin hacer trabajo útil).&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> La trampa más conocida: &lt;strong>SM occupancy alto no implica throughput real&lt;/strong>. El artículo &lt;em>&amp;ldquo;GPU Utilization Is a Counter, Not a Cause&amp;rdquo;&lt;/em> (Ingero, mayo 2026) lo formuló con una frase exacta: &lt;em>&amp;ldquo;un kernel que corre al 5 % del pico de FLOPS durante 100 ms todavía marca 100 % en SM_ACTIVE&amp;rdquo;&lt;/em>. En workloads MoE, el efecto se vuelve patológico: los expertos sobrecargados producen el &lt;strong>Straggler Effect&lt;/strong> (paper arXiv 2503.05066) — los SMs aparecen ocupados esperando al experto saturado, y el dashboard de utilización pinta verde mientras la latencia se va al techo.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> No fiar el sizing ni el autoscaling solo a SM occupancy. Combinar siempre con &lt;code>PIPE_TENSOR_ACTIVE&lt;/code> (¿hay compute útil?) y &lt;code>DRAM_ACTIVE&lt;/code> (¿la memoria es el cuello?). El régimen normal LLM en decode es 30–55 %, no 99 %; ver 99 % sostenido con TPOT alto es síntoma de bug del kernel o de straggler MoE.&lt;/p>
&lt;h3 id="dcgm_fi_prof_pipe_tensor_active--los-tensor-cores-producen">&lt;code>DCGM_FI_PROF_PIPE_TENSOR_ACTIVE&lt;/code> — ¿los tensor cores producen?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> Una fábrica con dos líneas: la artesanal (CUDA cores) y la automatizada (tensor cores). La métrica responde &lt;em>&amp;quot;¿qué porcentaje del tiempo está activa la línea automatizada?&amp;quot;&lt;/em>. Si compras una H100 por sus tensor cores y la línea automatizada está al 5 %, has pagado un Ferrari para llevar mensajería en bicicleta.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El issue &lt;strong>vllm#20783&lt;/strong> (julio 2025) tituló literalmente &lt;em>&amp;ldquo;Performance Anomaly: compressed-tensors no muestra speedup sobre BF16 en H100&amp;rdquo;&lt;/em>. El operador esperaba 1.5–2× con cuantización FP8 y obtuvo paridad con BF16; la métrica &lt;code>PIPE_TENSOR_ACTIVE&lt;/code> reveló que el path FP8 no estaba ejecutándose en los HMMA (la unidad tensor de FP16/BF16/FP8) y caía a CUDA cores. El issue &lt;strong>vllm#31475&lt;/strong> documentó el caso paralelo en MI300X: FP8 más lento que BF16 por regresión en el path ROCm. DCGM expone counters separados por unidad (&lt;code>HMMA&lt;/code> para FP16/BF16/FP8, &lt;code>IMMA&lt;/code> para INT8, &lt;code>DMMA&lt;/code> para TF32/FP32); si &lt;code>HMMA&lt;/code> está bajo aunque el modelo es BF16, el engine no usa tensor cores.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Verificar &lt;code>PIPE_TENSOR_ACTIVE&lt;/code> después de cada cambio de quantization o versión del motor; un cambio supuestamente neutro puede haber desactivado el path optimizado. Para prefill esperar 50–80 %; para decode 15–30 % es normal (decode es memory-bound, no compute-bound). Cifra &amp;lt; 5 % en prefill = el motor no está usando tensor cores.&lt;/p>
&lt;h3 id="dcgm_fi_prof_dram_active--está-la-hbm-saturada">&lt;code>DCGM_FI_PROF_DRAM_ACTIVE&lt;/code> — ¿está la HBM saturada?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> Una autopista con N carriles. La métrica responde &lt;em>&amp;quot;¿qué porcentaje del tiempo están todos los carriles ocupados moviendo coches?&amp;quot;&lt;/em>. Cuando los tensor cores piden datos más rápido de lo que la HBM los entrega, la autopista está al 95 % y los motores esperan. En decode, este es el régimen normal — paseas los pesos del modelo y el KV cache por cada token.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El paper &lt;em>&amp;ldquo;Mind the Memory Gap: Unveiling GPU Bottlenecks in Large-Batch LLM Inference&amp;rdquo;&lt;/em> (arXiv 2503.08311) cuantifica que a contextos ≥ 128k, la lectura del KV cache &lt;strong>domina el tiempo total de decode&lt;/strong> y satura la HBM3 (3.35 TB/s en H100). Patrón distintivo: &lt;code>DRAM_ACTIVE&lt;/code> &amp;gt; 80 % con &lt;code>PIPE_TENSOR_ACTIVE&lt;/code> ~10–20 %. Subir el batch ya no ayuda — el cuello no son FLOPS, es bandwidth. La palanca útil es comprimir KV: ver &lt;a href="https://blog.lo0.es/posts/quantization-fundamentos-inferencia/">Quantization&lt;/a> para &lt;code>--kv-cache-dtype=fp8&lt;/code> que recorta el footprint de KV ~50 %.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Si &lt;code>DRAM_ACTIVE &amp;gt; 95 %&lt;/code> sostenido y &lt;code>gpu_cache_usage_perc &amp;lt; 70 %&lt;/code>, &lt;strong>algo está pidiendo HBM que no es tu motor&lt;/strong> (leak en una librería, otro proceso compartiendo GPU sin MIG). Investigar inmediatamente con &lt;code>nvidia-smi&lt;/code> y &lt;code>fuser /dev/nvidia*&lt;/code>.&lt;/p>
&lt;h2 id="familia-2--memoria">Familia 2 — Memoria&lt;/h2>
&lt;h3 id="dcgm_fi_dev_fb_used--cuánta-vram-lleva-consumida">&lt;code>DCGM_FI_DEV_FB_USED&lt;/code> — ¿cuánta VRAM lleva consumida?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> El nivel de combustible del depósito de un avión en vuelo: el piloto necesita saber cuánto queda &lt;strong>y a qué ritmo se consume&lt;/strong>, no solo la cifra puntual. Una H100 al 88 % de FB used &lt;strong>estable&lt;/strong> puede operar tranquila; la misma cifra &lt;strong>subiendo 2 %/min&lt;/strong> anuncia OOM en 7 minutos.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El issue &lt;strong>dcgm-exporter#512&lt;/strong> documenta una sorpresa relevante para clusters MIG: &lt;strong>&lt;code>DCGM_FI_DEV_FB_USED&lt;/code> y &lt;code>DCGM_FI_DEV_FB_FREE&lt;/code> están ausentes en GPU instances H100 con MIG activado&lt;/strong> — sí presentes en A100 y B200, pero un bug del exporter los esconde en H100-MIG. Operadores que asumen el dashboard cubre todo descubren la ceguera el día del primer OOM. Issue &lt;strong>dcgm-exporter#271&lt;/strong> documenta otro detalle: &lt;code>FB_USED + FB_FREE&lt;/code> &lt;strong>no siempre suma constante&lt;/strong> porque hay overhead reservado por el driver que aparece en el delta. El paper original de &lt;strong>PagedAttention/vLLM&lt;/strong> estimaba que serving frameworks pre-PagedAttention desperdiciaban &lt;strong>60–80 %&lt;/strong> del KV cache por fragmentación; PagedAttention lo bajó a &amp;lt; 4 %.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> En clusters MIG H100, verificar que &lt;code>DCGM_FI_DEV_FB_USED&lt;/code> aparece por instance antes de confiar en alertas; si está ausente, monitorizar vía &lt;code>nvidia-smi --query-gpu=memory.used&lt;/code> directamente. Regla operativa: alertar sobre &lt;strong>delta&lt;/strong> (subida sostenida), no solo umbral absoluto.&lt;/p>
&lt;h3 id="dcgm_fi_dev_fb_free--el-complemento-absoluto">&lt;code>DCGM_FI_DEV_FB_FREE&lt;/code> — el complemento absoluto&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> El indicador &amp;ldquo;kilómetros restantes&amp;rdquo; del coche moderno: complementa al porcentaje con una cifra absoluta directamente accionable.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> Cuando un PagedAttention pool agresivo deja &lt;code>FB_FREE&lt;/code> en valores absolutos pequeños (&amp;lt; 2 GiB), cualquier asignación normal de buffers transitorios (activaciones de un prefill grande) puede empujar al OOM. El patrón clásico: porcentaje &amp;ldquo;verde&amp;rdquo; (87 %) pero absoluto &amp;ldquo;rojo&amp;rdquo; (&amp;lt; 4 GiB libres en una H100 de 80 GB).&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Alerta complementaria con umbral absoluto: &lt;code>DCGM_FI_DEV_FB_FREE &amp;lt; 4096&lt;/code> (MiB). Es la red de seguridad para los casos donde el porcentaje engaña porque el motor está configurado con &lt;code>gpu_memory_utilization&lt;/code> muy alto.&lt;/p>
&lt;h3 id="dcgm_fi_dev_nvlink_bandwidth_total--el-bus-interno-aguanta">&lt;code>DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL&lt;/code> — ¿el bus interno aguanta?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> Una autopista interestatal entre cuatro ciudades. Cada coche que cruza para hacer un all-reduce de tensor parallel paga peaje y consume ancho. Cuando hay más coches que la autopista soporta, la latencia para llegar a destino se dispara — aunque cada coche individual sea rápido.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El issue &lt;strong>vllm#16300&lt;/strong> (abril 2025) tituló &lt;em>&amp;ldquo;Performance degradation with tp=8 compared to tp=4 on 8×A100(80G)&amp;rdquo;&lt;/em> y documentó &lt;strong>TP=8 entregando peor throughput que TP=4&lt;/strong> en el mismo cluster, mismo modelo, misma quantization. Causa raíz: el tensor parallelism requiere all-reduce tras cada bloque de atención y MLP; a TP=8, el coste de comunicación entre 8 GPUs (incluso vía NVSwitch) crece más rápido que el speedup del partition compute. La regla práctica que emerge: &lt;strong>TP=4 + 2 réplicas&lt;/strong> suele entregar mejor latencia/throughput que &lt;strong>TP=8 + 1 réplica&lt;/strong> salvo para contextos extremadamente largos (≥128k) donde necesitas la VRAM agregada. Capacidad teórica NVLink 4.0 en H100 SXM: ~450 GB/s por GPU; régimen TP=4 sostenido típico: 50–150 GB/s.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Si &lt;code>NVLINK_BANDWIDTH_TOTAL &amp;gt; 90 %&lt;/code> capacidad sostenido, no es problema &lt;em>resoluble subiendo paralelismo&lt;/em> — al revés, &lt;strong>bajar TP&lt;/strong>. La métrica es ortogonal al sizing del &lt;a href="https://blog.lo0.es/posts/capacity-planning-inferencia-llm-on-premise/">capacity planning&lt;/a>: el techo no es solo VRAM/tiempo, también el bus.&lt;/p>
&lt;h2 id="familia-3--térmico-y-energético">Familia 3 — Térmico y energético&lt;/h2>
&lt;h3 id="dcgm_fi_dev_gpu_temp--la-gpu-respira">&lt;code>DCGM_FI_DEV_GPU_TEMP&lt;/code> — ¿la GPU respira?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> La temperatura corporal de un atleta de élite en pleno esfuerzo. 36–37 °C es normal; 38 °C es estrés sostenible; por encima de 39 °C el cuerpo activa mecanismos de protección (sudoración, ralentización) que &lt;strong>degradan el rendimiento&lt;/strong>. La GPU hace lo mismo: por encima de un umbral térmico, reduce su clock automáticamente. Si no lo hiciera, se rompería.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El H100 SXM5 con TDP 700 W tiene thresholds térmicos no enteramente públicos (NVIDIA no los publica exhaustivamente en datasheet), pero el comportamiento es bien conocido: por encima de ~85 °C edge o ~95 °C HBM aparece el bit &lt;code>0x40 HW_THERMAL&lt;/code> en clock throttle reasons. Operadores en el foro NVIDIA developer reportan que con &lt;strong>temperatura de entrada al rack &amp;gt; 27 °C&lt;/strong>, el throttle es habitual. El paper de NVIDIA HGX Platform indica que el flujo de aire mínimo recomendado es &lt;strong>&amp;gt; 1000 CFM/kW&lt;/strong>; densidades &amp;gt; 30 kW/rack a 700 W TDP exigen liquid cooling obligatorio porque el aire forzado no llega.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Si &lt;code>GPU_TEMP &amp;gt; 83 °C&lt;/code> sostenido, mirar primero &lt;code>CLOCK_THROTTLE_REASONS&lt;/code> (bit 0x40) y temperatura de entrada al rack — no es problema del motor, es del flujo de aire. Para racks legacy aire-cooled, plantear redistribuir carga térmica o instalar rear-door HX.&lt;/p>
&lt;h3 id="dcgm_fi_dev_power_usage--cuánto-pide-al-enchufe">&lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code> — ¿cuánto pide al enchufe?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> El consumo instantáneo de un electrodoméstico industrial conectado a una toma trifásica con un breaker dimensionado. Si la lavadora arranca a 9 kW y el breaker es de 10 kW, vives al filo; si la lavadora se &amp;ldquo;lleva bien&amp;rdquo; con el breaker es porque alguien dimensionó conscientemente.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> Medición real publicada: una H100 SXM5 con vLLM corriendo Llama 3.1 405B batch=4 consume &lt;strong>~697 W at-wall&lt;/strong> sostenido (NVIDIA TDP 700 W). Ahora la palanca operativa interesante: &lt;strong>bajar &lt;code>nvidia-smi -pl&lt;/code> de 700 W a 500 W&lt;/strong> entrega ~30 % de ahorro energético con solo ~20 % de pérdida de throughput. Cluster de 4 nodos × 8 H100 a 700 W = ~22 kW solo de GPU; a 500 W = ~16 kW. La diferencia paga la factura eléctrica entera de un trimestre en clusters operados ininterrumpidamente. Una rama PDU 415 VAC trifásica 60–80 A soporta ~32 kW, ~4 DGX H100. Legacy 208 V no soporta densidad H100 — referencia: NVIDIA DGX SuperPOD Electrical Specifications.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Métrica útil para tres cosas: (1) detectar workloads anómalamente bajos (idle inesperado), (2) calcular showback de coste energético real por tenant (no estimaciones), (3) alertar si el draw se acerca al límite de PDU rama. Tener mapeado &lt;strong>GPU → PDU rama → breaker&lt;/strong> en CMDB.&lt;/p>
&lt;h3 id="dcgm_fi_dev_clock_throttle_reasons--quién-pisa-el-freno">&lt;code>DCGM_FI_DEV_CLOCK_THROTTLE_REASONS&lt;/code> — ¿quién pisa el freno?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> El testigo de &amp;ldquo;modo limitado&amp;rdquo; en el salpicadero de un coche moderno. Cuando se enciende, el coche reduce su rendimiento automáticamente, pero &lt;strong>no te dice por qué&lt;/strong> salvo que sepas leer la combinación de letras. Los bits del bitmap son esas letras.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> Caso público formalmente reconocido por dos OEMs distintos: &lt;strong>Dell KB 000220508&lt;/strong> y &lt;strong>Lenovo HT514380&lt;/strong> abordan el mismo fenómeno: &lt;em>HW Power Brake Slowdown active&lt;/em> (bit &lt;code>0x80&lt;/code>) en H100 SXM. La causa no es la GPU — es la PDU del chasis enviando una señal eléctrica de power-brake porque la rama del rack está cerca del límite del breaker. El operador ve throughput caído 30–50 % sin XID ni ECC, y el motor de inferencia &amp;ldquo;está sano&amp;rdquo;; el problema está en electricidad. Foro NVIDIA developer en &lt;em>&amp;ldquo;HW Power Brake Slowdown&amp;rdquo;&lt;/em> corrobora el patrón. El bit &lt;code>0x40 HW_THERMAL&lt;/code> aparece en racks mal ventilados; el bit &lt;code>0x04 SW_POWER_CAP&lt;/code> aparece si alguien dejó &lt;code>nvidia-smi -pl 500&lt;/code> y nadie revertirá.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Cualquier bit ≠ 0 ni &lt;code>Idle&lt;/code> (bit 0x01) sostenido &lt;strong>es alerta inmediata&lt;/strong>. La descodificación recomendada: registrar el valor bitmap completo en el log + atributo &lt;code>throttle.reasons.decoded=[&amp;quot;HW_THERMAL&amp;quot;, &amp;quot;HW_POWER_BRAKE&amp;quot;]&lt;/code> en el span OTel. Sin esto, el incident response no sabe qué hacer.&lt;/p>
&lt;h2 id="familia-4--salud-los-reportes-catastróficos">Familia 4 — Salud (los reportes catastróficos)&lt;/h2>
&lt;h3 id="dcgm_fi_dev_xid_errors--los-códigos-rojos-del-driver">&lt;code>DCGM_FI_DEV_XID_ERRORS&lt;/code> — los códigos rojos del driver&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> Las luces de alarma críticas en una sala de control nuclear. No suben gradualmente; aparecen o no aparecen. Cada XID es un código predefinido (XID 13 = excepción del motor de gráficos; XID 31 = fault de MMU; XID 43 = stopped channel; XID 79 = GPU fallen off the bus; XID 95 = uncontained ECC), y cada uno tiene su procedimiento documentado.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El caso público más estudiado: &lt;strong>Meta&lt;/strong> publicó que durante el entrenamiento de Llama 3 405B sobre &lt;strong>16.384 H100 en 54 días&lt;/strong> hubo &lt;strong>419 fallos no planificados&lt;/strong>, uno cada 3 horas a escala de cluster. GPU acumuló 148 (35 %) + HBM3 72 (17 %) = casi la mitad de todos los fallos. El paper &lt;em>&amp;ldquo;Story of Two GPUs: Characterizing the Resilience of Hopper H100 and Ampere A100&amp;rdquo;&lt;/em> (arXiv 2503.11901) cuantifica con un dataset distinto (2.1M GPU-horas) que H100 tiene &lt;strong>3.2× peor MTBE para ECC uncorrectable que A100&lt;/strong>. El paper de ByteDance MegaScale reporta que XID 79 (&amp;ldquo;GPU fallen off the bus&amp;rdquo;) coocurre con errores PCIe en el &lt;strong>43 % de los casos&lt;/strong>. El foro NVIDIA developer documenta casos persistentes de XID 31 (MMU fault) que &lt;strong>siguen a la GPU al cambiar de slot PCIe&lt;/strong> — bug hardware del módulo, no del backplane.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> &lt;strong>Cualquier incremento del contador es alerta inmediata&lt;/strong>: muchos XID exigen reset del nodo o RMA de la GPU. La distinción XID-por-XID importa: XID 13/43 suele ser bug de software si coincide con cambio reciente; XID 31/48/79/94/95 suele ser hardware. Mantener tabla canónica &lt;code>xid → procedimiento&lt;/code>. Ver &lt;a href="https://blog.lo0.es/posts/runbooks-incident-response-llm-keep-kafka/">los runbooks&lt;/a> para la traducción a acción concreta.&lt;/p>
&lt;h3 id="dcgm_fi_dev_ecc_dbe_vol_total--los-errores-que-corrompen-datos">&lt;code>DCGM_FI_DEV_ECC_DBE_VOL_TOTAL&lt;/code> — los errores que corrompen datos&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> Un libro de contabilidad donde a veces alguien borra una entrada y la rescribe (ECC single-bit corregido — anota un cambio en el margen y sigue) y a veces alguien quema dos páginas a la vez (double-bit — la información se perdió, hay que parar la auditoría).&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El paper &lt;em>&amp;ldquo;Characterizing GPU Resilience&amp;rdquo;&lt;/em> cuantifica para H100: cuando XID 48 (DBE) aparece, &lt;strong>el job en curso muere con 100 % de probabilidad&lt;/strong> (5/5 en el dataset estudiado). La recuperación documentada: drenar el nodo + reset + completar row remap = &lt;strong>~19 horas de downtime de nodo&lt;/strong>. La densidad HBM3 explica el peor MTBE vs HBM2e: hay más celdas por unidad de área, mayor probabilidad estadística de degradación. En Llama 3, HBM3 causó 72 de 419 interrupciones (17 %).&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Cualquier valor &amp;gt; 0 = alerta crítica. La GPU debe ser &lt;strong>drenada inmediatamente&lt;/strong>, retirada del scheduler, reset completo, validación de row remap con &lt;code>nvidia-smi -q -d ROW_REMAPPER&lt;/code> (&lt;code>Pending: No&lt;/code>), y antes de volver al pool, smoke test extenso. Si el row remap usa &amp;gt; 4–8 páginas de spare en una GPU, planificar reemplazo en próxima ventana — la degradación es progresiva.&lt;/p>
&lt;h3 id="dcgm_fi_dev_retired_dbe--las-páginas-marcadas-para-retirar">&lt;code>DCGM_FI_DEV_RETIRED_DBE&lt;/code> — las páginas marcadas para retirar&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> Las baldosas que el restaurador del museo marca con cinta amarilla porque están dañadas. No suponen peligro inmediato (la sala sigue abierta), pero la acumulación dice que el suelo se está degradando estructuralmente y el reemplazo entero hay que planificarlo.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> NVIDIA documenta hasta &lt;strong>512 páginas de spare por banco HBM&lt;/strong> en H100; el contador &lt;code>RETIRED_DBE&lt;/code> indica cuántas se han usado. Operadores en foros NVIDIA reportan que por encima de &lt;strong>4–8 páginas retiradas en una GPU concreta&lt;/strong>, la frecuencia de XID 48 sube. Patrón: GPU con 6 páginas retiradas hoy → 12 en un mes → primer XID 48 dos meses después → drain forzoso.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Métrica de tendencia, no de alerta inmediata. Documentar valor por GPU y revisar mensualmente; las GPUs con valores crecientes entran al plan de reemplazo proactivo antes del fallo catastrófico.&lt;/p>
&lt;h2 id="las-cinco-métricas-del-motor-vllm">Las cinco métricas del motor vLLM&lt;/h2>
&lt;h3 id="vllmnum_requests_running--cuántas-requests-caben-en-el-batch">&lt;code>vllm:num_requests_running&lt;/code> — ¿cuántas requests caben en el batch?&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> El número de coches que un peaje deja pasar simultáneamente. Si la barrera abre N a la vez, las N+1 esperan en cola. La saturación se nota porque la fila no se acorta.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> Llegar al &lt;code>--max-num-seqs&lt;/code> configurado y mantenerse ahí es síntoma típico de &lt;strong>cluster por debajo del sizing&lt;/strong>; el motor admite hasta el techo y no más. La query &lt;code>vllm:num_requests_running == max_num_seqs&lt;/code> durante &amp;gt; 5 minutos indica saturación firme.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Combinar con &lt;code>num_requests_waiting&lt;/code>: si running está al techo Y waiting &amp;gt; 0, hay que escalar. Si running está al techo y waiting es 0, estás en el régimen óptimo (cluster usado al máximo sin cola).&lt;/p>
&lt;h3 id="vllmnum_requests_waiting--el-indicador-primario-de-saturación">&lt;code>vllm:num_requests_waiting&lt;/code> — el indicador primario de saturación&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> La cola visible delante del peaje. Mientras esté vacía, el sistema fluye; en cuanto se forma cola sostenida, los conductores empiezan a llegar tarde a destino — el TTFT se va al techo.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> Caso público en &lt;em>&amp;ldquo;11-Second Time to First Token on a Healthy vLLM Server&amp;rdquo;&lt;/em> (Medium, Ingero, 2026): servidor sin XIDs, sin preemption, métricas DCGM en verde, pero &lt;code>num_requests_waiting&lt;/code> sostenido &amp;gt; 0 y TTFT de &lt;strong>11 segundos&lt;/strong>. El issue &lt;strong>vllm#16985&lt;/strong> documenta degradación progresiva en sesiones largas: la queue crece lentamente durante horas sin que ningún otro indicador se mueva. La causa raíz no es de hardware — es de &lt;strong>admission control&lt;/strong>: la tasa de entrada supera la de finalización y el sistema no encola más, deja en &lt;code>WAITING&lt;/code>. Red Hat la designa como &lt;strong>la métrica primaria de saturación&lt;/strong> en su tutorial &lt;em>&amp;ldquo;5 steps to triage vLLM performance&amp;rdquo;&lt;/em>.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Métrica primaria del HPA en KEDA —ver &lt;a href="https://blog.lo0.es/posts/autoscaling-llm-kubernetes-keda/">Autoscaling LLM en Kubernetes&lt;/a>—. Umbral típico: alertar si &lt;code>avg_over_time(vllm:num_requests_waiting[5m]) &amp;gt; 5&lt;/code>. Para canary: si la cola se forma solo en el pool v2, es regresión del nuevo modelo, no carga del cluster.&lt;/p>
&lt;h3 id="vllmgpu_cache_usage_perc--el-pool-de-kv-cache">&lt;code>vllm:gpu_cache_usage_perc&lt;/code> — el pool de KV cache&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> La capacidad de una sala de eventos donde cada invitado ocupa un espacio variable. El maître admite hasta el aforo; cuando llega un invitado nuevo y no hay sitio, &lt;strong>echa al invitado que lleva más tiempo&lt;/strong> para hacerle hueco al recién llegado. Eso es el preempt-on-OOM de vLLM.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El issue &lt;strong>vllm#5051&lt;/strong> &lt;em>&amp;ldquo;Add num_requests_preempted metric&amp;rdquo;&lt;/em> nació exactamente de operadores observando degradación pero sin métrica directa que les dijese cuántas requests se estaban echando. Documentación oficial vLLM confirma: &lt;em>&amp;ldquo;sustained &lt;code>gpu_cache_usage_perc&lt;/code> above 90 % indicates the server is approaching its KV cache limit and will begin preempting sequences&amp;rdquo;&lt;/em> (oldest-first). El patrón visual distintivo: &lt;strong>sierra (sawtooth) cerca del 100 %&lt;/strong> con picos de preemption. En modo &lt;code>swap&lt;/code>, la latencia de la request preempted explota porque hay copia PCIe host↔device; en modo &lt;code>recompute&lt;/code> (default en V1), la request preempted rehace su prefill desde cero, lo que dispara su TTFT al doble o triple.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Si &lt;code>gpu_cache_usage_perc &amp;gt; 92 %&lt;/code> sostenido, &lt;strong>dos palancas&lt;/strong>: bajar &lt;code>max_num_seqs&lt;/code> (admite menos concurrencia pero ninguna se preempta) o subir &lt;code>gpu_memory_utilization&lt;/code> (más pool, menos VRAM para activations transitorias — riesgo distinto). La elección depende del workload. La métrica que falta directamente —contador de preempted— se exporta a partir de vLLM v1.0 en &lt;code>vllm:num_preemptions_total&lt;/code> (ver issue #5051).&lt;/p>
&lt;h3 id="vllmtime_to_first_token_seconds--la-latencia-visible-al-cliente">&lt;code>vllm:time_to_first_token_seconds&lt;/code> — la latencia visible al cliente&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> El tiempo desde que un cliente entra a un restaurante hasta que recibe el primer trozo de pan en la mesa. Demasiado largo y el cliente piensa que se han olvidado de él, aunque la comida principal vaya a llegar perfecta.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> Tres patrones documentados de spike de TTFT recurrentes:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Chunked prefill mal calibrado.&lt;/strong> Issue &lt;strong>vllm#25677&lt;/strong> (Qwen3-30B-A3B) reportó &lt;strong>prefill 10–11× más lento con chunked prefill activado&lt;/strong> que sin él. Causa: &lt;code>max_num_batched_tokens&lt;/code> muy bajo fuerza chunks pequeños que no llenan los kernels. Issue &lt;strong>vllm#7604&lt;/strong> documenta regresión equivalente en Llama-3-70B v0.5.4. La palanca: subir &lt;code>max_num_batched_tokens&lt;/code> a 4096–8192 para prompts típicos &amp;gt; 2k.&lt;/li>
&lt;li>&lt;strong>Regresión entre versiones del motor.&lt;/strong> Issue &lt;strong>vllm#8819&lt;/strong> documenta regresión de &lt;code>vllm:time_to_first_token_seconds_sum&lt;/code> entre versiones minor. Issue &lt;strong>vllm#11912&lt;/strong> reporta que con prompt ~8000 tokens, TPOT subió de &lt;strong>15.7 ms → 25.7 ms&lt;/strong> desde v0.6.4.post1 sin cambio de config — regresión confirmada y trackable solo con la métrica.&lt;/li>
&lt;li>&lt;strong>Long-context prefill bloqueando decodes.&lt;/strong> El caso &lt;em>&amp;ldquo;11s TTFT on healthy server&amp;rdquo;&lt;/em> citado arriba: un prefill de 30k tokens monopoliza la GPU durante varios segundos y los decodes activos congelan. Solución: chunked prefill bien calibrado, o disaggregated serving (ver &lt;a href="https://blog.lo0.es/posts/disaggregated-serving-prefill-decode/">Disaggregated serving&lt;/a>).&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> No alertar solo sobre P95 absoluto; alertar también sobre &lt;strong>ratio v2/v1&lt;/strong> cuando hay canary (&lt;code>histogram_quantile(0.95, ..., version=&amp;quot;v2&amp;quot;) / histogram_quantile(0.95, ..., version=&amp;quot;v1&amp;quot;) &amp;gt; 1.10&lt;/code>). Si TTFT crece y la queue está estable, el bottleneck es prefill — no resoluble subiendo réplicas, sí palanca de quantization o chunked prefill.&lt;/p>
&lt;h3 id="vllmtime_per_output_token_seconds--la-fluidez-del-streaming">&lt;code>vllm:time_per_output_token_seconds&lt;/code> — la fluidez del streaming&lt;/h3>
&lt;p>&lt;strong>La analogía.&lt;/strong> La velocidad a la que el camarero trae los platos uno detrás de otro después del primero. Si tarda en venir el siguiente, el comensal nota que algo no va bien aunque el primer plato haya llegado a tiempo.&lt;/p>
&lt;p>&lt;strong>La anomalía documentada.&lt;/strong> El patrón distintivo es el &lt;strong>escalón abrupto cuando &lt;code>gpu_cache_usage_perc&lt;/code> cruza ~85 %&lt;/strong>: el TPOT pasa de 35 ms a 80 ms en pocos segundos porque el motor empieza a competir por la HBM con sus propias evicciones. Issue &lt;strong>vllm#35387&lt;/strong> documenta otro caso anómalo: &lt;strong>MTP (speculative decoding) causando 76 % de regresión de latencia&lt;/strong> en Qwen3-Next-80B-A3B-Instruct-FP8 — la métrica TPOT lo capturó antes de que se reportasen quejas de clientes.&lt;/p>
&lt;p>&lt;strong>Implicación operacional.&lt;/strong> Diferencia con TTFT: si TTFT crece y Queue Time estable → prefill bound; si TPOT crece a tasa estable → presión sobre HBM (KV cache pool o swap activado). Alerta secundaria sobre el SLO de TPOT, pero también vigilar la &lt;strong>derivada&lt;/strong>: TPOT subiendo 1 ms cada 10 minutos es regresión latente que aún no rompe SLO pero lo hará.&lt;/p>
&lt;h2 id="la-regla-operativa-leer-las-métricas-por-familia-no-aisladas">La regla operativa: leer las métricas por familia, no aisladas&lt;/h2>
&lt;div class="diagram" style="max-width:820px;margin:1.5rem auto;">
&lt;svg viewBox="0 0 820 280" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="lectura combinada de métricas por familia">
&lt;style>.b{stroke:#333;stroke-width:1.4;rx:6}.c{fill:#dfe9f5;stroke:#356}.m{fill:#eef0d0;stroke:#7a3}.t{fill:#f4e3cf;stroke:#a63}.s{fill:#f6e2e2;stroke:#a33}.title{font:600 13px sans-serif;fill:#222}.h{font:700 12px sans-serif;fill:#222}.l{font:11px sans-serif;fill:#222}.n{font:italic 10px sans-serif;fill:#444}&lt;/style>
&lt;text x="410" y="20" text-anchor="middle" class="title">Combinaciones que diagnostican (cada familia por sí sola engaña)&lt;/text>
&lt;rect x="20" y="40" width="380" height="100" class="b c"/>
&lt;text x="30" y="62" class="h">COMPUTE saturada PERO memoria libre&lt;/text>
&lt;text x="30" y="80" class="l">SM_OCCUPANCY 95% + TENSOR_ACTIVE 75% + DRAM_ACTIVE 50%&lt;/text>
&lt;text x="30" y="98" class="l">+ FB_USED 60%&lt;/text>
&lt;text x="30" y="120" class="n">→ Prefill bound. Palanca: speculative decoding,&lt;/text>
&lt;text x="30" y="134" class="n"> chunked prefill, disaggregated serving.&lt;/text>
&lt;rect x="420" y="40" width="380" height="100" class="b m"/>
&lt;text x="430" y="62" class="h">MEMORIA saturada PERO compute holgado&lt;/text>
&lt;text x="430" y="80" class="l">SM_OCCUPANCY 35% + TENSOR_ACTIVE 18% + DRAM_ACTIVE 92%&lt;/text>
&lt;text x="430" y="98" class="l">+ gpu_cache_usage_perc 88%&lt;/text>
&lt;text x="430" y="120" class="n">→ Decode bound + KV cache presionado.&lt;/text>
&lt;text x="430" y="134" class="n"> Palanca: KV cache FP8, contexto más corto.&lt;/text>
&lt;rect x="20" y="150" width="380" height="120" class="b t"/>
&lt;text x="30" y="172" class="h">TPOT alto SIN saturar compute ni memoria&lt;/text>
&lt;text x="30" y="190" class="l">DRAM_ACTIVE 65% + FB_USED 70% + temp 78°C&lt;/text>
&lt;text x="30" y="208" class="l">+ THROTTLE_REASONS = 0x40 (HW_THERMAL)&lt;/text>
&lt;text x="30" y="230" class="n">→ Throttle térmico silencioso.&lt;/text>
&lt;text x="30" y="244" class="n"> Palanca: revisar ventilación rack, no motor.&lt;/text>
&lt;text x="30" y="258" class="n"> Caso clásico Dell/Lenovo KB.&lt;/text>
&lt;rect x="420" y="150" width="380" height="120" class="b s"/>
&lt;text x="430" y="172" class="h">TTFT P95 alto SIN throttle ni cola&lt;/text>
&lt;text x="430" y="190" class="l">num_requests_waiting 0 + throttle 0 + DRAM_ACTIVE 70%&lt;/text>
&lt;text x="430" y="208" class="l">+ ratio v2/v1 = 1.4 (canary activo)&lt;/text>
&lt;text x="430" y="230" class="n">→ Regresión del modelo v2 en prefill.&lt;/text>
&lt;text x="430" y="244" class="n"> Palanca: rollback del canary,&lt;/text>
&lt;text x="430" y="258" class="n"> revisar config del motor v2.&lt;/text>
&lt;/svg>
&lt;/div>
&lt;h2 id="tres-anti-patterns-del-operador-novato">Tres anti-patterns del operador novato&lt;/h2>
&lt;p>&lt;strong>Anti-pattern 1 — alertar solo sobre umbrales absolutos.&lt;/strong> Una H100 al 87 % de FB no es necesariamente alarma; la H100 con 87 % subiendo 2 %/min sí lo es. Las alertas que disparan por umbral fijo sin mirar derivada producen el doble de ruido y la mitad de la utilidad. Regla: para métricas con dinámica conocida (KV cache, FB, queue), alertar sobre &lt;strong>delta sostenido&lt;/strong>, no solo nivel.&lt;/p>
&lt;p>&lt;strong>Anti-pattern 2 — confundir SBE con DBE.&lt;/strong> El contador &lt;code>DCGM_FI_DEV_ECC_SBE_VOL_TOTAL&lt;/code> (single-bit, corregibles) crece &lt;strong>continuamente&lt;/strong> en cualquier HBM bajo carga; no es alarma, es física. El que importa es &lt;code>DCGM_FI_DEV_ECC_DBE_VOL_TOTAL&lt;/code> (double-bit, no corregibles). Confundirlos = falsos negativos (no alertar sobre DBE real) o falsos positivos (alertar sobre SBE inofensivo).&lt;/p>
&lt;p>&lt;strong>Anti-pattern 3 — tratar SM_OCCUPANCY 99 % como &amp;ldquo;saturada&amp;rdquo;.&lt;/strong> El régimen LLM en decode es memory-bound, no compute-bound; SM occupancy alto con TENSOR_ACTIVE bajo y DRAM_ACTIVE alto &lt;strong>es lo normal&lt;/strong>. Dimensionar para &amp;ldquo;GPU al 60 %&amp;rdquo; pidiendo más hardware cuando el cluster está saturado en HBM (no en SM) es comprar el doble de GPU sin ganar throughput. Regla: leer SM_OCCUPANCY siempre con TENSOR_ACTIVE y DRAM_ACTIVE; aislada no significa nada.&lt;/p>
&lt;h2 id="aplicado-a-hardware-on-premise-típico">Aplicado a hardware on-premise típico&lt;/h2>
&lt;p>Para un cluster genérico de &lt;strong>4 nodos × 4×H100 SXM 80 GB con NVLink intra-nodo&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>DCGM Exporter&lt;/strong> por nodo (DaemonSet del GPU Operator) emitiendo cada 15 s; cardinalidad por GPU = ~80 series. Cluster 16 GPUs ≈ 1.3k series base, ~85k samples/min con scrape de 15 s.&lt;/li>
&lt;li>&lt;strong>vLLM /metrics&lt;/strong> por pod inferencia; cada réplica emite ~50 series base. Para 16 réplicas, ~800 series adicionales, ~3k samples/min.&lt;/li>
&lt;li>&lt;strong>Prometheus retention&lt;/strong>: 30 días alta resolución + 1 año downsampled vía Thanos sidecar o Mimir. Volumen estimado: 25–35 GB/día.&lt;/li>
&lt;li>&lt;strong>Alertmanager&lt;/strong>: las 6 alertas críticas del &lt;a href="https://blog.lo0.es/posts/observabilidad-gpu-dcgm-llm/">post anterior&lt;/a> + alertas derivadas (delta, ratio v2/v1, throttle bitmap decodificado).&lt;/li>
&lt;/ul>
&lt;p>Cada métrica conviene exponer también como &lt;strong>atributo OTel&lt;/strong> en los spans del &lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">tracing GenAI&lt;/a>: &lt;code>gpu.fb_used_pct&lt;/code>, &lt;code>gpu.dram_active&lt;/code>, &lt;code>gpu.throttle_reasons.decoded&lt;/code>. Eso permite correlacionar una request lenta con el estado de la GPU en ese instante, sin saltar entre dashboards.&lt;/p>
&lt;h2 id="lo-que-no-hemos-cubierto-próximos-posts">Lo que no hemos cubierto (próximos posts)&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Runbooks por alerta&lt;/strong> — la traducción de cada métrica anómala a acción concreta (drain, reset, RMA, escalado, rollback) en el siguiente post: &lt;a href="https://blog.lo0.es/posts/runbooks-incident-response-llm-keep-kafka/">Runbooks de incident response&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Tail-sampling para correlación métrica ↔ traza&lt;/strong> — qué se preserva cuando una alerta dispara para investigación post-mortem.&lt;/li>
&lt;li>&lt;strong>Showback por tenant&lt;/strong> combinando &lt;code>vllm:request_success_total&lt;/code> × &lt;code>gen_ai.usage.*&lt;/code> × &lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code> para facturar coste energético real.&lt;/li>
&lt;li>&lt;strong>Métricas de fairness multi-tenant&lt;/strong> — cuándo un tenant acapara el KV cache pool y cómo detectarlo.&lt;/li>
&lt;/ul>
&lt;h2 id="ver-también">Ver también&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://blog.lo0.es/posts/observabilidad-gpu-dcgm-llm/">Observabilidad GPU para inferencia LLM&lt;/a> — la lista compacta que este post profundiza.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/runbooks-incident-response-llm-keep-kafka/">Runbooks de incident response para LLM con Keep + Kafka&lt;/a> — la traducción de cada anomalía a acción.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">Tracing LLM con OpenTelemetry GenAI&lt;/a> — la otra mitad de la observabilidad.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/autoscaling-llm-kubernetes-keda/">Autoscaling LLM en Kubernetes&lt;/a> — &lt;code>num_requests_waiting&lt;/code> y &lt;code>gpu_cache_usage_perc&lt;/code> como métricas primarias de HPA.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/capacity-planning-inferencia-llm-on-premise/">Capacity planning para inferencia LLM on-premise&lt;/a> — cómo se relacionan los umbrales con el sizing.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/canary-blue-green-shadow-modelos-llm/">Canary, blue-green y shadow&lt;/a> — el ratio TTFT v2/v1 como gate.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/continuous-batching-fundamentos/">Continuous batching&lt;/a> — explica el preempt-on-OOM y la sierra del KV pool.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/kv-cache-fundamentos/">KV cache&lt;/a> — fundamenta el cálculo de &lt;code>gpu_cache_usage_perc&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;ul>
&lt;li>Meta — &lt;em>Faulty Nvidia H100 GPUs and HBM3 memory caused half of failures during Llama 3 training&lt;/em> (Tom&amp;rsquo;s Hardware, 2024). &lt;a href="https://www.tomshardware.com/tech-industry/artificial-intelligence/faulty-nvidia-h100-gpus-and-hbm3-memory-caused-half-of-the-failures-during-llama-3-training-one-failure-every-three-hours-for-metas-16384-gpu-training-cluster">tomshardware.com&lt;/a>&lt;/li>
&lt;li>&lt;em>Story of Two GPUs: Characterizing the Resilience of Hopper H100 and Ampere A100&lt;/em>. arXiv 2503.11901. &lt;a href="https://arxiv.org/html/2503.11901v3">https://arxiv.org/html/2503.11901v3&lt;/a>&lt;/li>
&lt;li>ByteDance — &lt;em>Robust LLM Training Infrastructure at ByteDance&lt;/em>. arXiv 2509.16293. &lt;a href="https://arxiv.org/pdf/2509.16293">https://arxiv.org/pdf/2509.16293&lt;/a>&lt;/li>
&lt;li>&lt;em>Mind the Memory Gap: Unveiling GPU Bottlenecks in Large-Batch LLM Inference&lt;/em>. arXiv 2503.08311.&lt;/li>
&lt;li>&lt;em>Capacity-Aware Inference: Mitigating the Straggler Effect in Mixture of Experts&lt;/em>. arXiv 2503.05066.&lt;/li>
&lt;li>NVIDIA — &lt;em>Analyzing Xid Errors with the Xid Catalog&lt;/em> y &lt;em>Memory Error Management&lt;/em> (docs.nvidia.com/deploy).&lt;/li>
&lt;li>Dell — &lt;em>PowerEdge XE8640 with H100 - GPU Performance Issue HW Power Brake Slowdown - Active&lt;/em> (KB 000220508).&lt;/li>
&lt;li>Lenovo — &lt;em>Power brake reporting on H100 GPU&lt;/em> (HT514380).&lt;/li>
&lt;li>vLLM project — issues #5051 (preempted metric), #7604 y #25677 (chunked prefill regression), #11912 (long-prompt regression), #16300 (TP=8 worse than TP=4), #16985 (long-running degradation), #20783 (compressed-tensors no speedup), #35387 (MTP regression).&lt;/li>
&lt;li>Red Hat — &lt;em>5 steps to triage vLLM performance&lt;/em>. &lt;a href="https://developers.redhat.com/articles/2026/03/09/5-steps-triage-vllm-performance">https://developers.redhat.com/articles/2026/03/09/5-steps-triage-vllm-performance&lt;/a>&lt;/li>
&lt;li>AI21 — &lt;em>Go big or go OOM: the art of scaling vLLM&lt;/em>. &lt;a href="https://www.ai21.com/blog/scaling-vllm-without-oom/">https://www.ai21.com/blog/scaling-vllm-without-oom/&lt;/a>&lt;/li>
&lt;li>&lt;em>11-Second Time to First Token on a Healthy vLLM Server&lt;/em> (Medium, Ingero, 2026).&lt;/li>
&lt;li>NVIDIA — &lt;em>DGX SuperPOD Electrical Specifications&lt;/em> (docs.nvidia.com/dgx-superpod).&lt;/li>
&lt;/ul>
&lt;p>Sources: las URLs completas están enlazadas en línea sobre cada referencia.&lt;/p></description></item><item><title>Observabilidad GPU para inferencia LLM: las doce métricas DCGM y vLLM que dictan la salud de tu producción</title><link>https://blog.lo0.es/posts/observabilidad-gpu-dcgm-llm/</link><pubDate>Mon, 01 Jun 2026 15:30:00 +0200</pubDate><guid>https://blog.lo0.es/posts/observabilidad-gpu-dcgm-llm/</guid><description>&lt;blockquote>
&lt;p>Este post complementa los de &lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">Tracing LLM con OpenTelemetry GenAI&lt;/a> (la capa de tracing por encima de las métricas), &lt;a href="https://blog.lo0.es/posts/capacity-planning-inferencia-llm-on-premise/">Capacity planning&lt;/a> (qué se dimensionó y qué se debe vigilar) y &lt;a href="https://blog.lo0.es/posts/continuous-batching-fundamentos/">Continuous batching&lt;/a> (el mecanismo que explica varias de las métricas del motor).&lt;/p>
&lt;/blockquote>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>La observabilidad de un cluster de inferencia LLM se construye sobre &lt;strong>dos fuentes complementarias&lt;/strong>: las métricas del hardware GPU expuestas por &lt;strong>DCGM (Data Center GPU Manager) Exporter&lt;/strong> —parte del NVIDIA GPU Operator— y las métricas del &lt;strong>motor de inferencia&lt;/strong> (vLLM, SGLang, TensorRT-LLM) expuestas en &lt;code>/metrics&lt;/code> Prometheus-compatibles. Ninguna de las dos basta sola. La métrica clásica de &lt;code>nvidia-smi&lt;/code> llamada &lt;em>GPU utilization&lt;/em> es engañosa para LLMs: marca alto cuando hay &lt;strong>cualquier kernel&lt;/strong> ejecutándose, sin distinguir tensor cores ardiendo de SMs esperando por HBM. La cabina de pilotaje completa tiene &lt;strong>doce métricas DCGM en cuatro familias&lt;/strong> (compute: &lt;code>DCGM_FI_PROF_SM_OCCUPANCY&lt;/code>, &lt;code>DCGM_FI_PROF_PIPE_TENSOR_ACTIVE&lt;/code>, &lt;code>DCGM_FI_PROF_DRAM_ACTIVE&lt;/code>; memoria: &lt;code>DCGM_FI_DEV_FB_USED&lt;/code>, &lt;code>DCGM_FI_DEV_FB_FREE&lt;/code>, &lt;code>DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL&lt;/code>; térmico-energético: &lt;code>DCGM_FI_DEV_GPU_TEMP&lt;/code>, &lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code>, &lt;code>DCGM_FI_DEV_CLOCK_THROTTLE_REASONS&lt;/code>; salud: &lt;code>DCGM_FI_DEV_XID_ERRORS&lt;/code>, &lt;code>DCGM_FI_DEV_ECC_DBE_VOL_TOTAL&lt;/code>, &lt;code>DCGM_FI_DEV_RETIRED_DBE&lt;/code>) y &lt;strong>cinco métricas del motor vLLM&lt;/strong> (&lt;code>vllm:num_requests_running&lt;/code>, &lt;code>vllm:num_requests_waiting&lt;/code>, &lt;code>vllm:gpu_cache_usage_perc&lt;/code>, &lt;code>vllm:time_to_first_token_seconds&lt;/code>, &lt;code>vllm:time_per_output_token_seconds&lt;/code>). Cada una tiene un umbral verde/ámbar/rojo defendible, una PromQL para alerta, y al menos una falsa lectura habitual que confunde al operador junior. Las &lt;strong>seis alertas críticas&lt;/strong> que cualquier cluster productivo debe disparar son: HBM &amp;gt; 92 %, throttle por térmico o por power, XID error, ECC double-bit, KV cache pool &amp;gt; 95 %, y TTFT P95 fuera de SLO durante 5 minutos. El objetivo de tener este panel: que el operador de turno diagnostique el origen de una degradación en &lt;strong>menos de cinco minutos&lt;/strong>, sin abrir consola SSH a las GPUs. Cuando esto se cumple, el cluster ha pasado a operación profesional; mientras no, se opera por intuición.&lt;/p>
&lt;h2 id="estás-aquí-observe-la-otra-mitad-del-tracing">Estás aquí: OBSERVE (la otra mitad del tracing)&lt;/h2>
&lt;div class="diagram" style="max-width:780px;margin:1rem auto;">
&lt;svg viewBox="0 0 780 90" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="estás aquí: Observe">
&lt;style>.box{stroke:#444;stroke-width:1.4;rx:6}.active{fill:#c9a8e9;stroke-width:3}.idle{fill:#f4f4f4}.lbl{font:600 12px sans-serif;fill:#222}.arr{stroke:#666;stroke-width:1.4;fill:none;marker-end:url(#obm)}.cyc{stroke:#888;stroke-width:1.2;fill:none;stroke-dasharray:4 2;marker-end:url(#obm)}&lt;/style>
&lt;defs>&lt;marker id="obm" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">&lt;path d="M0,0 L10,5 L0,10 z" fill="#666"/>&lt;/marker>&lt;/defs>
&lt;text x="390" y="20" text-anchor="middle" class="lbl">Estás aquí: OBSERVE · métricas (DCGM + motor) complementan al tracing&lt;/text>
&lt;rect x="30" y="35" width="110" height="35" class="box idle"/>&lt;text x="85" y="58" text-anchor="middle" class="lbl">1 · Data&lt;/text>
&lt;rect x="155" y="35" width="110" height="35" class="box idle"/>&lt;text x="210" y="58" text-anchor="middle" class="lbl">2 · Tune&lt;/text>
&lt;rect x="280" y="35" width="110" height="35" class="box idle"/>&lt;text x="335" y="58" text-anchor="middle" class="lbl">3 · Eval&lt;/text>
&lt;rect x="405" y="35" width="110" height="35" class="box idle"/>&lt;text x="460" y="58" text-anchor="middle" class="lbl">4 · Deploy&lt;/text>
&lt;rect x="530" y="35" width="110" height="35" class="box active"/>&lt;text x="585" y="58" text-anchor="middle" class="lbl">5 · Observe&lt;/text>
&lt;rect x="655" y="35" width="110" height="35" class="box idle"/>&lt;text x="710" y="58" text-anchor="middle" class="lbl">6 · Retrain&lt;/text>
&lt;path class="arr" d="M140,52 L155,52"/>&lt;path class="arr" d="M265,52 L280,52"/>&lt;path class="arr" d="M390,52 L405,52"/>&lt;path class="arr" d="M515,52 L530,52"/>&lt;path class="arr" d="M640,52 L655,52"/>
&lt;path class="cyc" d="M710,72 L710,82 L85,82 L85,72"/>
&lt;/svg>
&lt;/div>
&lt;p>El tracing —ya cubierto en &lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">Tracing LLM con OpenTelemetry GenAI&lt;/a>— responde &lt;em>qué pasó en esta request concreta&lt;/em>. Las métricas responden &lt;em>qué está pasando en el cluster en agregado&lt;/em>. Son complementarias: una alerta del lado de métricas te dice &amp;ldquo;el clúster está degradando&amp;rdquo;, el tracing te dice &amp;ldquo;y esta es la traza concreta que te lo demuestra&amp;rdquo;. Un cluster sin tracing pero con métricas opera; un cluster sin métricas pero con tracing &lt;strong>no opera, debuggea&lt;/strong>.&lt;/p>
&lt;h2 id="la-analogía-la-cabina-de-un-avión-moderno">La analogía: la cabina de un avión moderno&lt;/h2>
&lt;p>En un avión comercial moderno, el panel de instrumentos del piloto tiene más de 70 indicadores activos. Si solo hubiese uno —el altímetro, por ejemplo— el avión volaría hacia el suelo en el primer momento de baja visibilidad. Hace falta el altímetro &lt;strong>y&lt;/strong> el indicador de actitud, &lt;strong>y&lt;/strong> el de velocidad, &lt;strong>y&lt;/strong> el de viraje, &lt;strong>y&lt;/strong> el de combustible, &lt;strong>y&lt;/strong> los de presión de aceite de cada motor, &lt;strong>y&lt;/strong> las temperaturas de salida de turbina. Cada uno responde una pregunta distinta. Y todos juntos cubren la pregunta operacional: &lt;em>¿está el avión sano, está donde debe, y va donde queremos?&lt;/em>&lt;/p>
&lt;p>La observabilidad de un cluster de inferencia LLM funciona igual. Una sola métrica —&amp;ldquo;GPU utilization 99 %&amp;quot;— no responde nada útil. Es como mirar solo el cuentakilómetros del coche para diagnosticar por qué hace ruido el motor. La cabina completa es &lt;strong>doce instrumentos del lado de hardware más cinco del lado del motor de inferencia&lt;/strong>, organizados en familias que responden preguntas distintas:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Compute y eficiencia&lt;/strong>: &lt;em>¿están los tensor cores haciendo el trabajo que esperamos o están esperando?&lt;/em>&lt;/li>
&lt;li>&lt;strong>Memoria&lt;/strong>: &lt;em>¿queda VRAM para nuevas requests o estamos al borde del OOM?&lt;/em>&lt;/li>
&lt;li>&lt;strong>Térmico y energético&lt;/strong>: &lt;em>¿el hardware está sano o está limitando el throughput silenciosamente?&lt;/em>&lt;/li>
&lt;li>&lt;strong>Salud y errores&lt;/strong>: &lt;em>¿hay degradación del hardware en curso (ECC, XID, NVLink)?&lt;/em>&lt;/li>
&lt;li>&lt;strong>Motor de inferencia&lt;/strong>: &lt;em>¿la cola crece, el KV pool está saturado, el SLO se está cumpliendo?&lt;/em>&lt;/li>
&lt;/ul>
&lt;p>Las cuatro primeras responden a &amp;ldquo;¿la GPU está bien?&amp;rdquo;. La quinta responde a &amp;ldquo;¿está dando el servicio que prometimos?&amp;rdquo;. Las dos preguntas son distintas y ambas deben tener respuesta a un golpe de vista.&lt;/p>
&lt;h2 id="por-qué-nvidia-smi-gpu-util-engaña-en-llms">Por qué &lt;code>nvidia-smi&lt;/code> &lt;code>GPU-Util&lt;/code> engaña en LLMs&lt;/h2>
&lt;p>La métrica clásica que aparece en &lt;code>nvidia-smi&lt;/code> como &lt;code>GPU-Util&lt;/code> corresponde a &lt;code>DCGM_FI_DEV_GPU_UTIL&lt;/code>. Su definición oficial: &amp;ldquo;porcentaje del tiempo durante el cual uno o más kernels estuvieron ejecutándose en la GPU&amp;rdquo;. El problema en LLMs: la fase de decode es &lt;strong>memory-bound&lt;/strong>, no compute-bound. Cuando el motor de inferencia hace decode token a token, la GPU pasa el 90 % del tiempo esperando que la HBM termine de entregar los pesos del modelo y el KV cache. Hay un kernel corriendo (lectura de HBM); por tanto &lt;code>GPU-Util&lt;/code> reporta valores cercanos al 100 %. Pero los tensor cores están parados — el cuello de botella es la memoria, no el compute.&lt;/p>
&lt;p>Resultado práctico: el operador ve &amp;ldquo;GPU-Util 99 %&amp;rdquo; en Grafana y asume &amp;ldquo;GPU saturada, no se puede meter más carga&amp;rdquo;. Pero la realidad puede ser &amp;ldquo;compute al 25 %, HBM saturada al 95 %&amp;rdquo;, lo que cambia las decisiones operativas (quantization, batch size, paralelismo). La métrica clásica miente por simplificación.&lt;/p>
&lt;p>Lo correcto es mirar las &lt;strong>tres métricas de profiling DCGM&lt;/strong> del subsistema &lt;code>_FI_PROF_*&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>&lt;code>DCGM_FI_PROF_SM_OCCUPANCY&lt;/code> — ratio de warps activos sobre máximos por SM. &lt;em>¿Hay trabajo paralelo?&lt;/em>&lt;/li>
&lt;li>&lt;code>DCGM_FI_PROF_PIPE_TENSOR_ACTIVE&lt;/code> — % de ciclos con tensor cores efectivamente activos. &lt;em>¿Está el compute trabajando?&lt;/em>&lt;/li>
&lt;li>&lt;code>DCGM_FI_PROF_DRAM_ACTIVE&lt;/code> — % de ciclos con la HBM transfiriendo. &lt;em>¿Está la memoria saturada?&lt;/em>&lt;/li>
&lt;/ul>
&lt;p>Una decode-bound GPU típica de Llama 70B en H100 muestra: SM occupancy 35–55 %, tensor active 15–30 %, DRAM active 80–95 %. Esa es la &amp;ldquo;GPU saturada&amp;rdquo; real para LLMs. Las tres juntas distinguen los regímenes; cada una sola no dice nada accionable.&lt;/p>
&lt;h2 id="cómo-se-montan-en-producción">Cómo se montan en producción&lt;/h2>
&lt;p>La parte de plataforma se cubre en &lt;a href="https://blog.lo0.es/posts/cinco-niveles-madurez-plataforma-llm-on-premise/">Cinco niveles de madurez&lt;/a> (nivel 4 — GPU plane) y &lt;a href="https://blog.lo0.es/posts/siete-fases-despliegue-plataforma-llm-on-premise/">Siete fases de despliegue&lt;/a> (fase F5). Para el observador, las piezas clave son:&lt;/p>
&lt;p>&lt;strong>NVIDIA GPU Operator.&lt;/strong> Manifiestos Helm que despliegan en cada nodo GPU: drivers, container toolkit, MIG manager y &lt;strong>DCGM Exporter&lt;/strong>. Este último expone &lt;code>/metrics&lt;/code> en formato Prometheus con todos los &lt;code>DCGM_FI_*&lt;/code> listados arriba. Se scrapea desde el Prometheus interno del cluster.&lt;/p>
&lt;p>&lt;strong>Motor de inferencia.&lt;/strong> vLLM expone &lt;code>/metrics&lt;/code> en el puerto 8000 (default) con métricas &lt;code>vllm:*&lt;/code>. SGLang lo expone también con prefijo &lt;code>sglang:&lt;/code>. TensorRT-LLM lo expone vía Triton Inference Server con prefijo &lt;code>nv_inference:&lt;/code>. La convención básica de nombres es similar entre los tres motores; los umbrales y queries de este post asumen vLLM, pero se traducen.&lt;/p>
&lt;p>&lt;strong>ServiceMonitor / PodMonitor.&lt;/strong> Recurso del operador de Prometheus que indica qué scrapear. Ejemplo mínimo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">monitoring.coreos.com/v1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">PodMonitor&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">vllm-inference&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">selector&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matchLabels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">app&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">vllm }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">podMetricsEndpoints&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">port&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">metrics&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">interval&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">15s&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Dashboards.&lt;/strong> El operador de NVIDIA publica dashboards Grafana de referencia para DCGM en &lt;code>nvidia/dcgm-exporter&lt;/code> (repo oficial). vLLM publica uno en &lt;code>vllm-project/vllm&lt;/code> (carpeta &lt;code>examples/&lt;/code>). Ambos sirven como base; cada equipo añade los paneles propios de su SLO.&lt;/p>
&lt;h2 id="las-doce-métricas-dcgm-organizadas-por-familia">Las doce métricas DCGM organizadas por familia&lt;/h2>
&lt;div class="diagram" style="max-width:820px;margin:1.5rem auto;">
&lt;svg viewBox="0 0 820 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="doce métricas DCGM en cuatro familias">
&lt;style>.b{stroke:#333;stroke-width:1.4;rx:6}.fc{fill:#dfe9f5;stroke:#356}.fm{fill:#eef0d0;stroke:#7a3}.ft{fill:#f4e3cf;stroke:#a63}.fs{fill:#f6e2e2;stroke:#a33}.title{font:600 13px sans-serif;fill:#222}.fam{font:700 11px sans-serif;fill:#222}.met{font:10px monospace;fill:#222}.note{font:italic 10px sans-serif;fill:#555}&lt;/style>
&lt;text x="410" y="20" text-anchor="middle" class="title">Cabina DCGM: 12 métricas en 4 familias&lt;/text>
&lt;rect x="20" y="40" width="195" height="290" class="b fc"/>
&lt;text x="117" y="60" text-anchor="middle" class="fam">COMPUTE&lt;/text>
&lt;text x="30" y="90" class="met">DCGM_FI_PROF_&lt;/text>&lt;text x="30" y="105" class="met">SM_OCCUPANCY&lt;/text>
&lt;text x="30" y="135" class="met">DCGM_FI_PROF_&lt;/text>&lt;text x="30" y="150" class="met">PIPE_TENSOR_ACTIVE&lt;/text>
&lt;text x="30" y="180" class="met">DCGM_FI_PROF_&lt;/text>&lt;text x="30" y="195" class="met">DRAM_ACTIVE&lt;/text>
&lt;text x="30" y="240" text-anchor="start" class="note">¿Compute trabaja o&lt;/text>
&lt;text x="30" y="254" text-anchor="start" class="note">espera por HBM?&lt;/text>
&lt;rect x="220" y="40" width="195" height="290" class="b fm"/>
&lt;text x="317" y="60" text-anchor="middle" class="fam">MEMORIA&lt;/text>
&lt;text x="230" y="90" class="met">DCGM_FI_DEV_&lt;/text>&lt;text x="230" y="105" class="met">FB_USED&lt;/text>
&lt;text x="230" y="135" class="met">DCGM_FI_DEV_&lt;/text>&lt;text x="230" y="150" class="met">FB_FREE&lt;/text>
&lt;text x="230" y="180" class="met">DCGM_FI_DEV_NVLINK_&lt;/text>&lt;text x="230" y="195" class="met">BANDWIDTH_TOTAL&lt;/text>
&lt;text x="230" y="240" class="note">¿Queda VRAM para&lt;/text>
&lt;text x="230" y="254" class="note">nuevas requests?&lt;/text>
&lt;rect x="420" y="40" width="195" height="290" class="b ft"/>
&lt;text x="517" y="60" text-anchor="middle" class="fam">TÉRMICO · ENERGÉTICO&lt;/text>
&lt;text x="430" y="90" class="met">DCGM_FI_DEV_&lt;/text>&lt;text x="430" y="105" class="met">GPU_TEMP&lt;/text>
&lt;text x="430" y="135" class="met">DCGM_FI_DEV_&lt;/text>&lt;text x="430" y="150" class="met">POWER_USAGE&lt;/text>
&lt;text x="430" y="180" class="met">DCGM_FI_DEV_CLOCK_&lt;/text>&lt;text x="430" y="195" class="met">THROTTLE_REASONS&lt;/text>
&lt;text x="430" y="240" class="note">¿Hardware sano o&lt;/text>
&lt;text x="430" y="254" class="note">limitando silenciosamente?&lt;/text>
&lt;rect x="620" y="40" width="180" height="290" class="b fs"/>
&lt;text x="710" y="60" text-anchor="middle" class="fam">SALUD&lt;/text>
&lt;text x="630" y="90" class="met">DCGM_FI_DEV_&lt;/text>&lt;text x="630" y="105" class="met">XID_ERRORS&lt;/text>
&lt;text x="630" y="135" class="met">DCGM_FI_DEV_&lt;/text>&lt;text x="630" y="150" class="met">ECC_DBE_VOL_TOTAL&lt;/text>
&lt;text x="630" y="180" class="met">DCGM_FI_DEV_&lt;/text>&lt;text x="630" y="195" class="met">RETIRED_DBE&lt;/text>
&lt;text x="630" y="240" class="note">¿Hay degradación&lt;/text>
&lt;text x="630" y="254" class="note">del silicio en curso?&lt;/text>
&lt;text x="410" y="350" text-anchor="middle" class="note">Cada familia responde una pregunta distinta · ninguna basta sola&lt;/text>
&lt;/svg>
&lt;/div>
&lt;h3 id="familia-1--compute">Familia 1 — Compute&lt;/h3>
&lt;p>&lt;strong>&lt;code>DCGM_FI_PROF_SM_OCCUPANCY&lt;/code>&lt;/strong> — Ratio de warps activos por SM sobre el máximo posible. Valor entre 0 y 1.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Verde&lt;/strong>: 0.30–0.70 (régimen típico LLM en decode).&lt;/li>
&lt;li>&lt;strong>Ámbar&lt;/strong>: &amp;lt; 0.20 sostenido (batch demasiado pequeño, GPU infrautilizada en paralelismo).&lt;/li>
&lt;li>&lt;strong>Rojo&lt;/strong>: 0.95 sostenido con DRAM_ACTIVE bajo (kernel patológico saturando SMs).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>&lt;code>DCGM_FI_PROF_PIPE_TENSOR_ACTIVE&lt;/code>&lt;/strong> — % de ciclos con tensor cores ejecutando. La métrica clave de &amp;ldquo;¿el compute está produciendo?&amp;rdquo;.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Verde en prefill&lt;/strong>: 50–80 %.&lt;/li>
&lt;li>&lt;strong>Verde en decode&lt;/strong>: 15–30 % (decode es memory-bound, no es síntoma de problema).&lt;/li>
&lt;li>&lt;strong>Rojo&lt;/strong>: &amp;lt; 5 % sostenido en prefill o el motor no usa los tensor cores (mala config, formato incompatible).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>&lt;code>DCGM_FI_PROF_DRAM_ACTIVE&lt;/code>&lt;/strong> — % de ciclos con HBM transfiriendo datos. Métrica clave para detectar saturación de memoria.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Verde en decode&lt;/strong>: 60–85 %.&lt;/li>
&lt;li>&lt;strong>Ámbar&lt;/strong>: &amp;gt; 90 % sostenido (HBM cuello de botella firme — explica la TPOT alta).&lt;/li>
&lt;li>&lt;strong>Rojo&lt;/strong>: &amp;gt; 95 % sostenido con KV cache pool &amp;lt; 70 % (algo está pidiendo HBM que no es el motor; investigar leaks).&lt;/li>
&lt;/ul>
&lt;h3 id="familia-2--memoria">Familia 2 — Memoria&lt;/h3>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_FB_USED&lt;/code>&lt;/strong> — Frame Buffer (HBM) usado en MiB.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Verde&lt;/strong>: 70–85 % del total.&lt;/li>
&lt;li>&lt;strong>Ámbar&lt;/strong>: 86–92 %.&lt;/li>
&lt;li>&lt;strong>Rojo&lt;/strong>: &amp;gt; 92 % (riesgo de OOM en el siguiente paged-attention allocation).&lt;/li>
&lt;/ul>
&lt;p>PromQL para porcentaje sobre cluster: &lt;code>100 * sum(DCGM_FI_DEV_FB_USED) / sum(DCGM_FI_DEV_FB_TOTAL)&lt;/code>.&lt;/p>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_FB_FREE&lt;/code>&lt;/strong> — Frame Buffer libre. Complementaria de la anterior; útil para alertas absolutas (&lt;code>&amp;lt; 4096 MiB libres&lt;/code>).&lt;/p>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL&lt;/code>&lt;/strong> — Bandwidth NVLink agregado en MB/s. Para topologías TP (tensor parallel) que cruzan GPUs vía NVLink, esta métrica revela si el reparto de paralelismo está saturando el bus.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Verde&lt;/strong>: variable según topología. En 4×H100 SXM con NVLink 4.0, capacidad teórica 450 GB/s por GPU. Régimen TP=4 típico: 50–150 GB/s sostenido.&lt;/li>
&lt;li>&lt;strong>Rojo&lt;/strong>: &amp;gt; 90 % capacidad sostenido (revisar si el modelo cabría con TP menor o pipeline parallel).&lt;/li>
&lt;/ul>
&lt;h3 id="familia-3--térmico-y-energético">Familia 3 — Térmico y energético&lt;/h3>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_GPU_TEMP&lt;/code>&lt;/strong> — Temperatura del die en °C.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Verde&lt;/strong>: &amp;lt; 75 °C.&lt;/li>
&lt;li>&lt;strong>Ámbar&lt;/strong>: 75–82 °C.&lt;/li>
&lt;li>&lt;strong>Rojo&lt;/strong>: &amp;gt; 83 °C (cerca del thermal throttle automático de H100; revisar ventilación, caudal de aire, temperatura de entrada al rack).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code>&lt;/strong> — Consumo en watts. Para H100 SXM, TDP nominal 700 W. Útil para tres cosas: detectar workload inusualmente bajo (sospechar idle o stall), facturar coste energético real, y disparar alertas si el draw se acerca al límite de la PDU.&lt;/p>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_CLOCK_THROTTLE_REASONS&lt;/code>&lt;/strong> — Bitmap codificado con las razones de throttle activas. Es la métrica que &lt;strong>silenciosamente explica&lt;/strong> las degradaciones de TPOT.&lt;/p>
&lt;p>Bits relevantes:&lt;/p>
&lt;ul>
&lt;li>&lt;code>0x0000000000000001&lt;/code> — Idle (no es problema).&lt;/li>
&lt;li>&lt;code>0x0000000000000002&lt;/code> — App clocks setting.&lt;/li>
&lt;li>&lt;code>0x0000000000000004&lt;/code> — SW Power Cap (límite de software, p. ej. por &lt;code>nvidia-smi -pl&lt;/code>).&lt;/li>
&lt;li>&lt;code>0x0000000000000008&lt;/code> — HW Slowdown.&lt;/li>
&lt;li>&lt;code>0x0000000000000010&lt;/code> — Sync Boost (NVIDIA Sync).&lt;/li>
&lt;li>&lt;code>0x0000000000000020&lt;/code> — SW Thermal Slowdown (límite térmico de software).&lt;/li>
&lt;li>&lt;code>0x0000000000000040&lt;/code> — HW Thermal Slowdown (límite térmico de hardware — emergencia).&lt;/li>
&lt;li>&lt;code>0x0000000000000080&lt;/code> — HW Power Brake Slowdown (caída de tensión PSU).&lt;/li>
&lt;li>&lt;code>0x0000000000000100&lt;/code> — Display Clock Setting.&lt;/li>
&lt;/ul>
&lt;p>Cualquier throttle salvo &lt;code>Idle&lt;/code> con valor &amp;gt; 0 sostenido &lt;strong>es alerta&lt;/strong>. La degradación de TPOT con &lt;code>DRAM_ACTIVE&lt;/code> ya alto y throttle térmico activo es el clásico &amp;ldquo;el rack está mal ventilado, no es problema del motor&amp;rdquo;.&lt;/p>
&lt;h3 id="familia-4--salud">Familia 4 — Salud&lt;/h3>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_XID_ERRORS&lt;/code>&lt;/strong> — Contador acumulado de XID errors del driver. Los XID son códigos de evento crítico que NVIDIA documenta exhaustivamente (XID 13: graphics engine exception; XID 31: GPU memory page fault; XID 43: reset channel verif error; XID 79: GPU has fallen off the bus; XID 95: uncontained ECC error; etc.). &lt;strong>Cualquier incremento es alerta inmediata&lt;/strong>: muchos XID requieren reset del nodo o RMA de la GPU.&lt;/p>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_ECC_DBE_VOL_TOTAL&lt;/code>&lt;/strong> — Errores ECC double-bit volátiles (no corregibles). A diferencia de los single-bit (que ECC corrige silenciosamente y se contabilizan en &lt;code>DCGM_FI_DEV_ECC_SBE_*&lt;/code>), los double-bit &lt;strong>corrompen datos&lt;/strong>. Cualquier valor &amp;gt; 0 es alerta crítica: la GPU debe ser drenada y revisada.&lt;/p>
&lt;p>&lt;strong>&lt;code>DCGM_FI_DEV_RETIRED_DBE&lt;/code>&lt;/strong> — Páginas físicas de HBM retiradas por double-bit errors acumulados. NVIDIA retira páginas defectuosas automáticamente para prevenir corrupción futura. Más de 4–8 páginas retiradas en una GPU sugiere degradación del silicio: documentar y planificar reemplazo en próxima ventana de mantenimiento.&lt;/p>
&lt;h2 id="las-cinco-métricas-del-motor-de-inferencia-vllm">Las cinco métricas del motor de inferencia (vLLM)&lt;/h2>
&lt;p>Las métricas DCGM responden &amp;ldquo;¿está sana la GPU?&amp;rdquo;. Las del motor responden &amp;ldquo;¿está el servicio cumpliendo el SLO?&amp;rdquo;. Sin ellas, sabes que el hardware funciona pero no sabes si los clientes están contentos.&lt;/p>
&lt;p>&lt;strong>&lt;code>vllm:num_requests_running&lt;/code>&lt;/strong> — Requests actualmente en el batch. Si llega al &lt;code>--max-num-seqs&lt;/code> configurado y no baja, el motor está saturado en concurrencia (revisar VRAM y rebalancear vía autoscaler — ver &lt;a href="https://blog.lo0.es/posts/autoscaling-llm-kubernetes-keda/">Autoscaling LLM en Kubernetes&lt;/a>).&lt;/p>
&lt;p>&lt;strong>&lt;code>vllm:num_requests_waiting&lt;/code>&lt;/strong> — Requests en cola, sin entrar al batch. Cualquier valor &amp;gt; 0 sostenido durante minutos indica que el cluster no escala con la carga. &lt;strong>Esta es la métrica primaria para HPA&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>&lt;code>vllm:gpu_cache_usage_perc&lt;/code>&lt;/strong> — % del KV cache pool usado.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Verde&lt;/strong>: 50–80 %.&lt;/li>
&lt;li>&lt;strong>Ámbar&lt;/strong>: 80–92 %.&lt;/li>
&lt;li>&lt;strong>Rojo&lt;/strong>: &amp;gt; 92 % (riesgo de &lt;strong>preempt-on-OOM&lt;/strong>: vLLM tirará requests para liberar memoria, lo que aumenta TTFT visiblemente).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>&lt;code>vllm:time_to_first_token_seconds&lt;/code>&lt;/strong> — Histograma de TTFT por request. Se consume como &lt;code>histogram_quantile(0.95, sum by(le)(rate(vllm:time_to_first_token_seconds_bucket[5m])))&lt;/code>. Comparado contra el SLO de TTFT P95 dispara la alerta primaria de servicio.&lt;/p>
&lt;p>&lt;strong>&lt;code>vllm:time_per_output_token_seconds&lt;/code>&lt;/strong> — Histograma de TPOT. Equivalente al anterior pero para fluidez de streaming. Comparado contra el SLO de TPOT P95 dispara la alerta secundaria.&lt;/p>
&lt;h2 id="las-seis-alertas-que-deben-pagear-en-producción">Las seis alertas que deben pagear en producción&lt;/h2>
&lt;p>Cualquier cluster productivo serio dispara estas seis alertas a un canal con rotación de guardia. Sin estas, el SLO se cumple por suerte, no por proceso.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">groups&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">gpu-llm-critical&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rules&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">alert&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">GpuHbmNearOom&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">expr&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">100&lt;/span>&lt;span class="w"> &lt;/span>*&lt;span class="w"> &lt;/span>&lt;span class="l">(DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL) &amp;gt; 92&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">for&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">2m&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">severity&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">critical }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">annotations&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">summary&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;HBM de {{ $labels.gpu }} en {{ $value }}% — riesgo OOM&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">alert&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">GpuThermalOrPowerThrottle&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">expr&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">(DCGM_FI_DEV_CLOCK_THROTTLE_REASONS != 0) and ignoring(reason) (DCGM_FI_DEV_CLOCK_THROTTLE_REASONS != 1)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">for&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">1m&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">severity&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">warning }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">annotations&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">summary&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;GPU {{ $labels.gpu }} en throttle (reasons={{ $value }})&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">alert&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">GpuXidErrorDetected&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">expr&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">increase(DCGM_FI_DEV_XID_ERRORS[5m]) &amp;gt; 0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">severity&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">critical }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">annotations&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">summary&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;XID error en GPU {{ $labels.gpu }} — investigar inmediatamente&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">alert&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">GpuEccDoubleBit&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">expr&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">DCGM_FI_DEV_ECC_DBE_VOL_TOTAL &amp;gt; 0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">severity&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">critical }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">annotations&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">summary&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;ECC double-bit en GPU {{ $labels.gpu }} — drenar nodo&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">alert&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">VllmKvCachePoolNearFull&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">expr&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">vllm:gpu_cache_usage_perc &amp;gt; 0.95&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">for&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">3m&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">severity&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">warning }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">annotations&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">summary&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;KV cache pool &amp;gt; 95% en {{ $labels.instance }}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">alert&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">VllmTtftP95OutOfSlo&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">expr&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">histogram_quantile(0.95, sum by(le, instance)(rate(vllm:time_to_first_token_seconds_bucket[5m]))) &amp;gt; 1.5&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">for&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">5m&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">severity&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">warning }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">annotations&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">summary&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;TTFT P95 sobre SLO ({{ $value }}s &amp;gt; 1.5s)&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Estas seis cubren el 80 % de los incidentes que afectan a SLO. El 20 % restante exige investigación con tracing (ver &lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">Tracing LLM con OpenTelemetry GenAI&lt;/a>).&lt;/p>
&lt;h2 id="tabla-maestra-umbrales-y-queries">Tabla maestra: umbrales y queries&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Métrica&lt;/th>
&lt;th>Verde&lt;/th>
&lt;th>Ámbar&lt;/th>
&lt;th>Rojo&lt;/th>
&lt;th>Query base (PromQL)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>SM occupancy&lt;/td>
&lt;td>0.30–0.70&lt;/td>
&lt;td>0.15–0.30&lt;/td>
&lt;td>&amp;lt; 0.10 sostenido&lt;/td>
&lt;td>&lt;code>DCGM_FI_PROF_SM_OCCUPANCY&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Tensor active (decode)&lt;/td>
&lt;td>15–30 %&lt;/td>
&lt;td>&amp;lt; 10 %&lt;/td>
&lt;td>&amp;lt; 3 %&lt;/td>
&lt;td>&lt;code>DCGM_FI_PROF_PIPE_TENSOR_ACTIVE&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>DRAM active&lt;/td>
&lt;td>60–85 %&lt;/td>
&lt;td>85–95 %&lt;/td>
&lt;td>&amp;gt; 95 % con KV bajo&lt;/td>
&lt;td>&lt;code>DCGM_FI_PROF_DRAM_ACTIVE&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>FB used&lt;/td>
&lt;td>70–85 %&lt;/td>
&lt;td>86–92 %&lt;/td>
&lt;td>&amp;gt; 92 %&lt;/td>
&lt;td>&lt;code>100 * DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>NVLink BW&lt;/td>
&lt;td>&amp;lt; 70 % cap&lt;/td>
&lt;td>70–90 % cap&lt;/td>
&lt;td>&amp;gt; 90 % cap&lt;/td>
&lt;td>&lt;code>DCGM_FI_DEV_NVLINK_BANDWIDTH_TOTAL&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GPU temp&lt;/td>
&lt;td>&amp;lt; 75 °C&lt;/td>
&lt;td>75–82 °C&lt;/td>
&lt;td>&amp;gt; 83 °C&lt;/td>
&lt;td>&lt;code>DCGM_FI_DEV_GPU_TEMP&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Power usage&lt;/td>
&lt;td>&amp;lt; 90% TDP&lt;/td>
&lt;td>90–98 % TDP&lt;/td>
&lt;td>&amp;gt; 98 % TDP&lt;/td>
&lt;td>&lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Throttle reasons&lt;/td>
&lt;td>0 o Idle&lt;/td>
&lt;td>App/SW&lt;/td>
&lt;td>HW Therm/Power&lt;/td>
&lt;td>&lt;code>DCGM_FI_DEV_CLOCK_THROTTLE_REASONS&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>XID errors&lt;/td>
&lt;td>sin cambio&lt;/td>
&lt;td>—&lt;/td>
&lt;td>cualquier delta&lt;/td>
&lt;td>&lt;code>increase(DCGM_FI_DEV_XID_ERRORS[5m])&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ECC DBE&lt;/td>
&lt;td>0&lt;/td>
&lt;td>—&lt;/td>
&lt;td>&amp;gt; 0&lt;/td>
&lt;td>&lt;code>DCGM_FI_DEV_ECC_DBE_VOL_TOTAL&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Retired pages&lt;/td>
&lt;td>&amp;lt; 4&lt;/td>
&lt;td>4–8&lt;/td>
&lt;td>&amp;gt; 8&lt;/td>
&lt;td>&lt;code>DCGM_FI_DEV_RETIRED_DBE&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>KV cache used&lt;/td>
&lt;td>50–80 %&lt;/td>
&lt;td>80–92 %&lt;/td>
&lt;td>&amp;gt; 92 %&lt;/td>
&lt;td>&lt;code>vllm:gpu_cache_usage_perc&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Requests waiting&lt;/td>
&lt;td>0&lt;/td>
&lt;td>1–5 sostenido&lt;/td>
&lt;td>&amp;gt; 10 sostenido&lt;/td>
&lt;td>&lt;code>vllm:num_requests_waiting&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>TTFT P95&lt;/td>
&lt;td>&amp;lt; SLO&lt;/td>
&lt;td>80–100 % SLO&lt;/td>
&lt;td>&amp;gt; SLO&lt;/td>
&lt;td>ver query alerta arriba&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>TPOT P95&lt;/td>
&lt;td>&amp;lt; SLO&lt;/td>
&lt;td>80–100 % SLO&lt;/td>
&lt;td>&amp;gt; SLO&lt;/td>
&lt;td>&lt;code>histogram_quantile(0.95, sum by(le)(rate(vllm:time_per_output_token_seconds_bucket[5m])))&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="tres-pitfalls-que-confunden-al-operador-junior">Tres pitfalls que confunden al operador junior&lt;/h2>
&lt;p>&lt;strong>Pitfall 1 — &amp;ldquo;GPU-Util al 99 % = saturada&amp;rdquo;.&lt;/strong> Como se explicó al inicio: &lt;code>DCGM_FI_DEV_GPU_UTIL&lt;/code> se enciende con cualquier kernel. Lo correcto es mirar las tres &lt;code>_PROF_*&lt;/code> (SM occupancy, tensor active, DRAM active) juntas. &lt;em>GPU util 99 % + tensor active 8 % + DRAM active 92 %&lt;/em> = &amp;ldquo;saturada por memoria, no compute&amp;rdquo;; &lt;em>GPU util 99 % + tensor active 75 % + DRAM active 50 %&lt;/em> = &amp;ldquo;saturada por compute, prefill heavy&amp;rdquo;. Las dos situaciones piden palancas distintas.&lt;/p>
&lt;p>&lt;strong>Pitfall 2 — confundir ECC single-bit (SBE) con double-bit (DBE).&lt;/strong> Los single-bit se corrigen silenciosamente y son &lt;strong>inevitables&lt;/strong> en cualquier HBM bajo carga (radiación cósmica, fluctuaciones de tensión). Un contador SBE creciendo lentamente no es alerta — es física. El DBE sí: corrompe datos. Distinguir las dos métricas evita falsas alarmas y falsos negativos a partes iguales.&lt;/p>
&lt;p>&lt;strong>Pitfall 3 — alertar sobre &lt;code>num_requests_waiting &amp;gt; 0&lt;/code> sin contexto.&lt;/strong> Un valor instantáneo de 1 o 2 durante un pico es normal. Lo que importa es la cola &lt;strong>sostenida&lt;/strong>: usar &lt;code>for: 5m&lt;/code> con umbral 3–5. Sin esa ventana, el sistema satura el canal de alertas con ruido.&lt;/p>
&lt;h2 id="aplicado-a-hardware-on-premise-típico">Aplicado a hardware on-premise típico&lt;/h2>
&lt;p>Para un cluster genérico de &lt;strong>4×H100 SXM 80 GB con NVLink intra-nodo&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>DCGM Exporter desplegado vía NVIDIA GPU Operator, un DaemonSet por nodo GPU.&lt;/li>
&lt;li>Prometheus interno con retención 30 días para métricas de alta frecuencia, 1 año para downsampled (Thanos/Mimir si el volumen lo justifica).&lt;/li>
&lt;li>Grafana con tres dashboards estándar: hardware GPU (DCGM), motor (vLLM), SLO (TTFT/TPOT/RPS contra objetivos escritos).&lt;/li>
&lt;li>Alertmanager con rotación de guardia y rate-limiting por silencio agrupado por nodo.&lt;/li>
&lt;li>Cardinalidad controlada: &lt;code>gpu&lt;/code> (id local), &lt;code>node&lt;/code>, &lt;code>pod&lt;/code>, &lt;code>model&lt;/code> — no añadir &lt;code>request_id&lt;/code> ni labels de alta cardinalidad a métricas (eso es trabajo del tracing).&lt;/li>
&lt;/ul>
&lt;p>Volumen estimado para un cluster de 16 GPUs con scraping cada 15 s: ~2 millones de samples/min, ~25 GB/día de Prometheus crudo. Manejable con un Prometheus por cluster + retention; si el equipo escala a &amp;gt; 64 GPUs, considerar Thanos sidecar o VictoriaMetrics. Ver &lt;a href="https://blog.lo0.es/posts/catalogo-herramientas-oss-llmops/">Catálogo de herramientas OSS LLMOps&lt;/a> para alternativas equivalentes.&lt;/p>
&lt;h2 id="lo-que-no-hemos-cubierto-próximos-artículos">Lo que no hemos cubierto (próximos artículos)&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Tracing de cargas LLM&lt;/strong>: ya cubierto en &lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">Tracing LLM con OpenTelemetry GenAI&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Autoscaling&lt;/strong> basado en estas métricas: ver &lt;a href="https://blog.lo0.es/posts/autoscaling-llm-kubernetes-keda/">Autoscaling LLM en Kubernetes&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Runbooks de incident response&lt;/strong>: cómo cada una de estas alertas se traduce a acción concreta (drain, restart, RMA, escalado, rollback).&lt;/li>
&lt;li>&lt;strong>Cost accounting&lt;/strong>: usar &lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code> y &lt;code>vllm:request_success_total&lt;/code> para showback de coste por tenant.&lt;/li>
&lt;li>&lt;strong>Monitorización de fairness multi-tenant&lt;/strong>: cuando varios tenants comparten cluster, qué métricas detectan que uno está acaparando el KV cache.&lt;/li>
&lt;/ul>
&lt;h2 id="ver-también">Ver también&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://blog.lo0.es/posts/tracing-llm-otel-genai/">Tracing LLM con OpenTelemetry GenAI&lt;/a> — la otra mitad de la observabilidad.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/capacity-planning-inferencia-llm-on-premise/">Capacity planning para inferencia LLM on-premise&lt;/a> — qué se dimensionó y, por tanto, qué umbrales son defendibles aquí.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/continuous-batching-fundamentos/">Continuous batching&lt;/a> — explica por qué &lt;code>num_requests_running&lt;/code>, &lt;code>num_requests_waiting&lt;/code> y &lt;code>gpu_cache_usage_perc&lt;/code> son las métricas operativas del motor.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/cinco-niveles-madurez-plataforma-llm-on-premise/">Cinco niveles de madurez&lt;/a> — la observabilidad LLM-aware vive en el nivel 4.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/siete-capas-stack-inferencia-llm-on-premise/">Siete capas del stack de inferencia LLM on-premise&lt;/a> — DCGM Exporter es pieza de la capa de plataforma.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/autoscaling-llm-kubernetes-keda/">Autoscaling LLM en Kubernetes&lt;/a> — usa estas métricas como input.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/anatomia-metricas-dcgm-vllm-anomalias/">Anatomía de las doce métricas DCGM y cinco vLLM&lt;/a> — profundización con analogía y anomalía documentada en producción para cada métrica, con cifras de incidentes públicos (Meta Llama 3, &lt;em>Story of Two GPUs&lt;/em>, issues vLLM, KBs Dell/Lenovo).&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/runbooks-incident-response-llm-keep-kafka/">Runbooks de incident response para LLM con Keep + Kafka&lt;/a> — la traducción de cada alerta crítica a acción concreta (drain, reset, RMA, rollback) con workflow YAML, schema Kafka WORM y encaje en ISO 27035, ENS, NIS2, EU AI Act art. 73.&lt;/li>
&lt;/ul>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;ul>
&lt;li>NVIDIA — &lt;em>DCGM Exporter&lt;/em> (repo &lt;code>nvidia/dcgm-exporter&lt;/code>, métricas y unidades documentadas).&lt;/li>
&lt;li>NVIDIA — &lt;em>DCGM Field Identifiers reference&lt;/em> (lista completa de &lt;code>DCGM_FI_*&lt;/code>).&lt;/li>
&lt;li>NVIDIA — &lt;em>XID Errors documentation&lt;/em> (catálogo de códigos XID y procedimientos de remediación).&lt;/li>
&lt;li>NVIDIA — &lt;em>NVIDIA GPU Operator&lt;/em> (Helm chart oficial).&lt;/li>
&lt;li>vLLM project — &lt;code>examples/production_monitoring/&lt;/code> (PromQL y dashboards Grafana de referencia).&lt;/li>
&lt;li>Prometheus — &lt;em>Histogram and summary best practices&lt;/em> (para construir queries de percentiles defendibles).&lt;/li>
&lt;li>NVIDIA — &lt;em>H100 Tensor Core GPU datasheet&lt;/em> (TDP, HBM bandwidth, NVLink capacities).&lt;/li>
&lt;/ul></description></item></channel></rss>