<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Idle on lo0 — Tech Blog</title><link>https://blog.lo0.es/en/tags/idle/</link><description>Recent content in Idle on lo0 — Tech Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Mon, 15 Jun 2026 05:00:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/en/tags/idle/index.xml" rel="self" type="application/rss+xml"/><item><title>GPU idle: the cost that shows up on no invoice but is paid by the whole TCO</title><link>https://blog.lo0.es/en/posts/gpu-idle-cost-not-on-any-invoice/</link><pubDate>Mon, 15 Jun 2026 05:00:00 +0200</pubDate><guid>https://blog.lo0.es/en/posts/gpu-idle-cost-not-on-any-invoice/</guid><description>&lt;blockquote>
&lt;p>Notation: amounts in &lt;strong>euros (N €)&lt;/strong>, decimals with a point. The dollar sign is not used
(on this site it is a formula delimiter).&lt;/p>
&lt;/blockquote>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>The cost per token of on-premise inference is \( \text{€/GPU-hour} \div \text{throughput} \). Throughput is a direct function of the GPU&amp;rsquo;s &lt;strong>useful occupancy&lt;/strong>. On a generic node of 4×H100 SXM with a reference cost of ~11 € per GPU-hour (depreciation plus energy plus infrastructure), the cost curve over occupancy looks like this:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Useful occupancy&lt;/th>
&lt;th>Effective throughput (tok/s)&lt;/th>
&lt;th>Cost per 1M tokens&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>20 %&lt;/td>
&lt;td>~700&lt;/td>
&lt;td>~43 €&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>40 %&lt;/td>
&lt;td>~1,400&lt;/td>
&lt;td>~21 €&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>70 %&lt;/td>
&lt;td>~2,500&lt;/td>
&lt;td>~12 €&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>85 % (practical ceiling)&lt;/td>
&lt;td>~3,000&lt;/td>
&lt;td>~10 €&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Doubling occupancy from 20 % to 40 % halves the cost per token, without buying more iron.&lt;/strong> At 70 % the cost competes with European cloud providers (~2.2 €/GPU-hour on-demand at Scaleway). At 20 % on-prem is four times dearer than renting. The lever is not the model, nor the precision: it is how many paid-for GPU-hours produce serving tokens.&lt;/p>
&lt;hr>
&lt;h2 id="1--the-fundamental-identity">1 · The fundamental identity&lt;/h2>
&lt;p>The cost per million tokens (CPM) in your own inference is not a list price. It is:&lt;/p>
$$
\text{CPM} = \frac{C_{\text{GPU}} \cdot N_{\text{GPU}}}{T_{\text{ef}} \times 3600 / 10^6}
$$
&lt;p>where \( C_{\text{GPU}} \) is the cost per GPU-hour (€/h), \( N_{\text{GPU}} \) the number of GPUs assigned to the service and \( T_{\text{ef}} \) the effective throughput (tok/s). Making the dependence on occupancy explicit:&lt;/p>
$$
T_{\text{ef}} = T_{\text{pico}} \times \rho
$$
&lt;p>where \( \rho \in [0,1] \) is the &lt;strong>useful occupancy rate&lt;/strong> (the fraction of time in which the GPU is processing real serving tokens). The resulting identity:&lt;/p>
$$
\text{CPM} = \frac{C_{\text{GPU}} \cdot N_{\text{GPU}}}{T_{\text{pico}} \times \rho \times 3600 / 10^6}
$$
&lt;p>The direct consequence: CPM is &lt;strong>inversely proportional to&lt;/strong> \( \rho \). Doubling \( \rho \) halves CPM. The numerator (cost of the iron) does not change.&lt;/p>
&lt;p>The posts &lt;a href="https://blog.lo0.es/en/posts/gpu-hour-to-cost-per-token-on-prem-vs-cloud/">coste-por-token-y-por-request&lt;/a> and &lt;a href="https://blog.lo0.es/en/posts/capacity-planning-on-premise-llm-inference/">capacity-planning-inferencia-llm-on-premise&lt;/a> cover how to calculate \( C_{\text{GPU}} \) and the reference peak throughput. This article deals with \( \rho \): how to measure it, what limits it and how to raise it.&lt;/p>
&lt;hr>
&lt;h2 id="2--why-the-standard-metric-lies-dcgm_fi_dev_gpu_util">2 · Why the standard metric lies: &lt;code>DCGM_FI_DEV_GPU_UTIL&lt;/code>&lt;/h2>
&lt;p>The field &lt;code>DCGM_FI_DEV_GPU_UTIL&lt;/code> (field ID 203) appears in &lt;code>nvidia-smi&lt;/code> as &amp;ldquo;GPU-Util&amp;rdquo;. Its official definition in the DCGM documentation:&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;GPU Utilization&amp;rdquo; — percentage of time during which one or more kernels were executing on the GPU.&lt;/p>
&lt;/blockquote>
&lt;p>The problem for LLM inference: &lt;strong>the decode phase is memory-bound&lt;/strong>. The GPU runs a kernel reading weights from HBM token by token; therefore &lt;code>GPU_UTIL&lt;/code> registers close to 100 % even though the tensor cores are at 15 % of their capacity. The field measures &lt;em>activity&lt;/em>, not &lt;em>useful work&lt;/em>.&lt;/p>
&lt;p>The distinction is critical for FinOps: an operator who sees &lt;code>GPU_UTIL 98 %&lt;/code> assumes &amp;ldquo;saturated GPU, no room for more load&amp;rdquo;. The reality may be &amp;ldquo;the tensor cores are at 20 % and the bottleneck is HBM&amp;rdquo;, which leaves room for continuous batching or additional bin-packing.&lt;/p>
&lt;p>The metrics that measure real occupancy are those of the &lt;code>_FI_PROF_*&lt;/code> subsystem, available in DCGM 3.x with the profiling module enabled:&lt;/p>
&lt;h3 id="table-of-relevant-dcgm-fields">Table of relevant DCGM fields&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>DCGM field&lt;/th>
&lt;th>Field ID&lt;/th>
&lt;th>What it measures&lt;/th>
&lt;th>Unit&lt;/th>
&lt;th>Operational note&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_DEV_GPU_UTIL&lt;/code>&lt;/td>
&lt;td>203&lt;/td>
&lt;td>% time with ≥1 active kernel&lt;/td>
&lt;td>%&lt;/td>
&lt;td>&lt;strong>Misleading&lt;/strong> in LLM decode&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_SM_ACTIVE&lt;/code>&lt;/td>
&lt;td>1002&lt;/td>
&lt;td>Ratio of cycles with ≥1 active warp per SM&lt;/td>
&lt;td>0–1&lt;/td>
&lt;td>Compute activity, not occupancy&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_SM_OCCUPANCY&lt;/code>&lt;/td>
&lt;td>1003&lt;/td>
&lt;td>Resident warps / theoretical maximum per SM&lt;/td>
&lt;td>0–1&lt;/td>
&lt;td>Real intra-SM parallelism&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_PIPE_TENSOR_ACTIVE&lt;/code>&lt;/td>
&lt;td>1004&lt;/td>
&lt;td>% cycles with tensor cores (HMMA) active&lt;/td>
&lt;td>0–1&lt;/td>
&lt;td>The real compute efficiency metric&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_DRAM_ACTIVE&lt;/code>&lt;/td>
&lt;td>1005&lt;/td>
&lt;td>% cycles with HBM transferring&lt;/td>
&lt;td>0–1&lt;/td>
&lt;td>Memory saturation&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_PCIE_TX_BYTES&lt;/code>&lt;/td>
&lt;td>—&lt;/td>
&lt;td>TX bytes over PCIe&lt;/td>
&lt;td>bytes/s&lt;/td>
&lt;td>Useful in PCIe inference&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_DEV_FB_USED&lt;/code>&lt;/td>
&lt;td>252&lt;/td>
&lt;td>HBM used&lt;/td>
&lt;td>MiB&lt;/td>
&lt;td>VRAM budget&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code>&lt;/td>
&lt;td>—&lt;/td>
&lt;td>Real consumption&lt;/td>
&lt;td>W&lt;/td>
&lt;td>For real energy cost&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_DEV_CLOCK_THROTTLE_REASONS&lt;/code>&lt;/td>
&lt;td>—&lt;/td>
&lt;td>Bitmap of throttle causes&lt;/td>
&lt;td>bitmap&lt;/td>
&lt;td>Detects silent degradation&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The &lt;code>_PROF_*&lt;/code> fields require the DCGM profiling module and the right driver permissions. They are documented exhaustively in the NVIDIA DCGM field ID reference and in the sibling post &lt;a href="https://blog.lo0.es/en/posts/gpu-observability-llm-inference-twelve-dcgm-vllm-metrics/">observabilidad-gpu-dcgm-llm&lt;/a>.&lt;/p>
&lt;h3 id="characteristic-reading-in-llm-decode-llama-70b-fp8-on-h100">Characteristic reading in LLM decode (Llama 70B FP8 on H100)&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Metric&lt;/th>
&lt;th>Typical decode value&lt;/th>
&lt;th>Interpretation&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_DEV_GPU_UTIL&lt;/code>&lt;/td>
&lt;td>95–99 %&lt;/td>
&lt;td>&lt;strong>A lie&lt;/strong>: there is an active kernel&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_SM_ACTIVE&lt;/code>&lt;/td>
&lt;td>0.45–0.65&lt;/td>
&lt;td>SMs with warps 45–65 % of the time&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_SM_OCCUPANCY&lt;/code>&lt;/td>
&lt;td>0.30–0.55&lt;/td>
&lt;td>Resident warps at 30–55 % of the maximum&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_PIPE_TENSOR_ACTIVE&lt;/code>&lt;/td>
&lt;td>0.10–0.25&lt;/td>
&lt;td>Tensor cores active only 10–25 %&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DCGM_FI_PROF_DRAM_ACTIVE&lt;/code>&lt;/td>
&lt;td>0.75–0.90&lt;/td>
&lt;td>HBM busy 75–90 % of the time&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Reading: decode is &lt;strong>memory-bound&lt;/strong>. The model weights are loaded from HBM for each token; HBM is saturated but the tensor cores wait. All of the &amp;ldquo;utilisation&amp;rdquo; in &lt;code>nvidia-smi&lt;/code> comes from memory reads, not from compute.&lt;/p>
&lt;hr>
&lt;h2 id="3--mfu-and-hfu-occupancy-expressed-in-flops">3 · MFU and HFU: occupancy expressed in FLOPs&lt;/h2>
&lt;p>The canonical compute efficiency metric is &lt;strong>MFU (Model FLOPs Utilization)&lt;/strong>, defined in the PaLM paper (Chowdhery et al., arXiv 2204.02311, section 4):&lt;/p>
$$
\text{MFU} = \frac{T_{\text{obs}} \times C_{\text{modelo}}}{P_{\text{pico}}}
$$
&lt;p>where \( T_{\text{obs}} \) is the observed throughput (tok/s) and \( P_{\text{pico}} \) is the theoretical peak performance of the hardware (FLOP/s).&lt;/p>
&lt;p>where \( C_{\text{modelo}} \) is the number of FLOPs per token in a complete forward pass. For a dense transformer with \( P \) parameters, the usual approximation (forward plus backward = 6P FLOPs per token; forward only = 2P):&lt;/p>
$$
C_{\text{modelo}} \approx 2P \quad \text{(inference)}
$$
$$
C_{\text{modelo}} \approx 6P \quad \text{(training, forward + backward)}
$$
&lt;p>&lt;strong>HFU (Hardware FLOPs Utilization)&lt;/strong> measures the FLOPs &lt;strong>actually executed&lt;/strong> in hardware, including activation recomputation (gradient checkpointing). In training with recompute:&lt;/p>
$$
C_{\text{hardware}} \approx 8P \quad \text{(forward × 2 + backward × 4)}
$$
&lt;p>therefore HFU &amp;gt; MFU when there is recompute; they are identical without it.&lt;/p>
&lt;h3 id="typical-mfu-values">Typical MFU values&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Regime&lt;/th>
&lt;th>Hardware&lt;/th>
&lt;th>Typical MFU&lt;/th>
&lt;th>Limiting regime&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Training (large batch, BF16)&lt;/td>
&lt;td>H100 SXM&lt;/td>
&lt;td>35–50 %&lt;/td>
&lt;td>compute-bound&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Training PaLM 540B&lt;/td>
&lt;td>TPU v4&lt;/td>
&lt;td>46.2 %&lt;/td>
&lt;td>compute-bound&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Prefill inference (large batch)&lt;/td>
&lt;td>H100 SXM&lt;/td>
&lt;td>25–45 %&lt;/td>
&lt;td>compute-bound&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Decode inference (bs=1)&lt;/td>
&lt;td>H100 SXM&lt;/td>
&lt;td>3–8 %&lt;/td>
&lt;td>memory-bound&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Decode inference (continuous batching, bs=32–64)&lt;/td>
&lt;td>H100 SXM&lt;/td>
&lt;td>15–30 %&lt;/td>
&lt;td>memory-bound, attenuated&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Decode with batch size 1 has a single-digit MFU because the hardware spends most of its time waiting for HBM to deliver weights. Raising the batch size (continuous batching) amortises the weight read across more simultaneous tokens and raises MFU.&lt;/p>
&lt;h3 id="the-roofline-model">The Roofline model&lt;/h3>
&lt;p>The roofline places each operation in the space (arithmetic intensity, throughput):&lt;/p>
&lt;div class="diagram" style="max-width:680px;margin:1rem auto;">
&lt;svg viewBox="0 0 680 320" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Roofline model for LLM inference: compute-bound prefill vs memory-bound decode">
&lt;style>.ax{stroke:currentColor;stroke-width:1.4;fill:none}.lbl{font:11px sans-serif;fill:currentColor}.ttl{font:700 13px sans-serif;fill:currentColor}.roof{stroke:currentColor;stroke-width:2;fill:none}.pt{fill:currentColor}&lt;/style>
&lt;text x="340" y="22" text-anchor="middle" class="ttl">Roofline: prefill vs decode on H100 SXM&lt;/text>
&lt;line x1="60" y1="270" x2="640" y2="270" class="ax"/>
&lt;line x1="60" y1="270" x2="60" y2="30" class="ax"/>
&lt;text x="350" y="298" text-anchor="middle" class="lbl">Arithmetic intensity (FLOP/byte)&lt;/text>
&lt;text x="14" y="155" text-anchor="middle" class="lbl" transform="rotate(-90 14 155)">Throughput (TFLOP/s)&lt;/text>
&lt;line x1="60" y1="270" x2="220" y2="60" class="roof"/>
&lt;line x1="220" y1="60" x2="640" y2="60" class="roof"/>
&lt;text x="230" y="52" class="lbl">~990 TFLOP/s (H100 BF16)&lt;/text>
&lt;text x="65" y="200" class="lbl" fill="currentColor">mem. bandwidth&lt;/text>
&lt;text x="65" y="213" class="lbl" fill="currentColor">~3.35 TB/s&lt;/text>
&lt;line x1="215" y1="50" x2="215" y2="270" stroke="currentColor" stroke-width="1" stroke-dasharray="4 3"/>
&lt;text x="200" y="284" class="lbl">~295&lt;/text>
&lt;text x="148" y="284" class="lbl">FLOP/byte ridge&lt;/text>
&lt;circle cx="130" cy="175" r="7" class="pt"/>
&lt;text x="138" y="171" class="lbl">decode bs=1&lt;/text>
&lt;text x="138" y="184" class="lbl">MFU ~5 %&lt;/text>
&lt;circle cx="185" cy="120" r="7" class="pt"/>
&lt;text x="193" y="116" class="lbl">decode bs=32&lt;/text>
&lt;text x="193" y="129" class="lbl">MFU ~20 %&lt;/text>
&lt;circle cx="300" cy="65" r="7" class="pt"/>
&lt;text x="308" y="61" class="lbl">prefill bs=128&lt;/text>
&lt;text x="308" y="74" class="lbl">MFU ~38 %&lt;/text>
&lt;/svg>
&lt;/div>
&lt;p>Decode with batch size 1 falls in the memory-bound zone to the left of the ridge point. Raising the batch (continuous batching) moves the point to the right and up, closer to the roofline.&lt;/p>
&lt;hr>
&lt;h2 id="4--tco-sensitivity-to-occupancy">4 · TCO sensitivity to occupancy&lt;/h2>
&lt;p>Assumptions for the example: a generic node with &lt;strong>4×H100 SXM 80 GB&lt;/strong>, total node cost ~44 €/hour (5-year depreciation of ~220,000 €, energy ~4×700 W at ~0.12 €/kWh, plus rack/colocation infrastructure; see &lt;a href="https://blog.lo0.es/en/posts/gpu-hour-to-cost-per-token-on-prem-vs-cloud/">coste-por-token-y-por-request&lt;/a> for the detail of the identity). Reference peak throughput with Llama 70B FP8 plus continuous batching: ~3,500 tok/s aggregate.&lt;/p>
$$
\text{CPM}(\rho) = \frac{44\ \text{€/h}}{3500 \times \rho \times 3600 / 10^6}
= \frac{44 \times 10^6}{3500 \times \rho \times 3600}
= \frac{3.49}{\rho}\ \text{€/1M tok}
$$
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Occupancy \( \rho \)&lt;/th>
&lt;th>Effective throughput (tok/s)&lt;/th>
&lt;th>On-prem CPM&lt;/th>
&lt;th>On-demand cloud CPM (~2.2 €/GPU-h)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>20 %&lt;/td>
&lt;td>700&lt;/td>
&lt;td>&lt;strong>~17.5 €&lt;/strong>&lt;/td>
&lt;td>~6.3 €&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>40 %&lt;/td>
&lt;td>1,400&lt;/td>
&lt;td>&lt;strong>~8.7 €&lt;/strong>&lt;/td>
&lt;td>~6.3 €&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>60 %&lt;/td>
&lt;td>2,100&lt;/td>
&lt;td>&lt;strong>~5.8 €&lt;/strong>&lt;/td>
&lt;td>~6.3 €&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>70 %&lt;/td>
&lt;td>2,450&lt;/td>
&lt;td>&lt;strong>~5.0 €&lt;/strong>&lt;/td>
&lt;td>~6.3 €&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>85 %&lt;/td>
&lt;td>2,975&lt;/td>
&lt;td>&lt;strong>~4.1 €&lt;/strong>&lt;/td>
&lt;td>~6.3 €&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>On-prem / cloud crossover point&lt;/strong>: with this example hardware, the on-prem cost advantage over a comparable European cloud starts at \( \rho \approx 55\text{-}60\,\% \). Below that, idle makes on-prem dearer than renting. The cloud column is flat because cloud bills per hour used, not per the throughput you extract from it.&lt;/p>
&lt;blockquote>
&lt;p>Example figures with generic hardware. The real numbers depend on the depreciation price, the local cost of energy, the model and the precision. The structure of the curve, CPM inversely proportional to \( \rho \), is universal.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="5--idle-metrics-where-occupancy-is-lost">5 · Idle metrics: where occupancy is lost&lt;/h2>
&lt;p>Before applying levers, you need to know which kind of idle dominates. Three categories:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Type of idle&lt;/th>
&lt;th>Symptom in metrics&lt;/th>
&lt;th>Usual cause&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Scheduling idle&lt;/strong>&lt;/td>
&lt;td>&lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code> low, &lt;code>SM_ACTIVE&lt;/code> &amp;lt; 0.05&lt;/td>
&lt;td>No requests in the queue; GPU waiting for work&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Batching idle&lt;/strong>&lt;/td>
&lt;td>&lt;code>SM_ACTIVE&lt;/code> high, &lt;code>PIPE_TENSOR_ACTIVE&lt;/code> low, &lt;code>DRAM_ACTIVE&lt;/code> low&lt;/td>
&lt;td>Batch too small; prefill stall between requests&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Memory-bound idle&lt;/strong>&lt;/td>
&lt;td>&lt;code>DRAM_ACTIVE&lt;/code> high, &lt;code>PIPE_TENSOR_ACTIVE&lt;/code> low&lt;/td>
&lt;td>Normal decode; HBM is the bottleneck; insufficient batch size&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Scheduling idle is the most expensive and the most directly attacked with bin-packing. Batching idle is attacked with continuous batching. Memory-bound idle in decode does not disappear entirely (it is the physics of the transformer), but it is attenuated with a larger batch size.&lt;/p>
&lt;p>The inference engine metrics that complement the diagnosis from the service side are documented in &lt;a href="https://blog.lo0.es/en/posts/gpu-observability-llm-inference-twelve-dcgm-vllm-metrics/">observabilidad-gpu-dcgm-llm&lt;/a> and &lt;a href="https://blog.lo0.es/en/posts/anatomy-dcgm-vllm-metrics-analogies-documented-anomalies/">anatomia-metricas-dcgm-vllm-anomalias&lt;/a>.&lt;/p>
&lt;hr>
&lt;h2 id="6--levers-for-raising-occupancy">6 · Levers for raising occupancy&lt;/h2>
&lt;h3 id="table-of-lever--effect--when-it-applies">Table of lever × effect × when it applies&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Lever&lt;/th>
&lt;th>Effect on \( \rho \)&lt;/th>
&lt;th>When it applies&lt;/th>
&lt;th>Operational complexity&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Continuous batching&lt;/strong>&lt;/td>
&lt;td>High: removes idle between requests; raises decode MFU from ~5 % to ~20 %&lt;/td>
&lt;td>Always in inference; enabled by default in vLLM&lt;/td>
&lt;td>Low (engine parameter)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Scheduler bin-packing&lt;/strong> (kube-scheduler / Kueue)&lt;/td>
&lt;td>High: concentrates loads on fewer nodes; frees whole nodes for shutdown or rebalancing&lt;/td>
&lt;td>Clusters with load that varies over the day&lt;/td>
&lt;td>Medium (scheduler policy)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>MIG&lt;/strong> (Multi-Instance GPU)&lt;/td>
&lt;td>Medium: fills GPUs with light loads that previously lived alone on a whole GPU&lt;/td>
&lt;td>Heterogeneous loads: embeddings + reranker + guardrail + large model&lt;/td>
&lt;td>High (hot repartitioning not available)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Time-slicing&lt;/strong>&lt;/td>
&lt;td>Low to medium: raises occupancy in dev/bursts; no isolation&lt;/td>
&lt;td>Consumer GPUs (RTX 5090/4090); low-risk multi-tenant dev&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>MPS&lt;/strong>&lt;/td>
&lt;td>Medium: concurrent execution of multiple small processes; reduces context-switch overhead&lt;/td>
&lt;td>Many small concurrent kernels on a datacenter GPU; trust between loads&lt;/td>
&lt;td>Medium&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Chunked prefill&lt;/strong>&lt;/td>
&lt;td>Medium: interleaves prefill and decode; reduces the TTFT spike and raises throughput&lt;/td>
&lt;td>Loads with a mix of short and long prompts&lt;/td>
&lt;td>Low (vLLM flag)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Quantisation&lt;/strong> (FP16→FP8→INT4)&lt;/td>
&lt;td>Indirect: raises peak throughput, which lowers CPM for the same \( \rho \)&lt;/td>
&lt;td>Models with quantised kernel support (native Hopper FP8)&lt;/td>
&lt;td>Medium&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Autoscaling&lt;/strong> (KEDA)&lt;/td>
&lt;td>Keeps \( \rho \) high by scaling replicas according to the queue&lt;/td>
&lt;td>Variable and predictable load; cluster with spare capacity&lt;/td>
&lt;td>Medium&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The post &lt;a href="https://blog.lo0.es/en/posts/sharing-one-gpu-time-slicing-mps-mig/">compartir-gpu-time-slicing-mps-mig&lt;/a> details the three sharing mechanisms (time-slicing, MPS, MIG) with VRAM budgets.&lt;/p>
&lt;h3 id="bin-packing-with-kueue">Bin-packing with Kueue&lt;/h3>
&lt;p>Kueue (sigs.k8s.io/kueue) is the Kubernetes-native queue manager for GPU jobs. Its model of &lt;strong>cohorts&lt;/strong> and &lt;strong>nominal quotas&lt;/strong> allows active bin-packing: jobs accumulate in a queue and are launched only when there is a node that can take them whole, instead of fragmenting the load across partially occupied nodes.&lt;/p>
&lt;p>&lt;code>BestFit&lt;/code> packing in the &lt;code>ClusterQueue&lt;/code> is configured with:&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">kueue.x-k8s.io/v1beta1&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">ClusterQueue&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">gpu-prod&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">preemption&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">reclaimWithinCohort&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Any&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">withinClusterQueue&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">LowerPriority&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">resourceGroups&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">coveredResources&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;nvidia.com/gpu&amp;#34;&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">flavors&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">h100-sxm&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">resources&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="s2">&amp;#34;nvidia.com/gpu&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 class="nt">nominalQuota&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">16&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The priority-based preemption policy ensures that production jobs displace experimentation ones when there is scarcity, keeping occupancy on the production nodes high.&lt;/p>
&lt;h3 id="mig-as-a-bin-packing-lever-inside-the-gpu">MIG as a bin-packing lever inside the GPU&lt;/h3>
&lt;p>MIG makes it possible to fill an H100 with light loads that would otherwise live alone on a whole GPU. A profile of &lt;code>3×2g.20gb + 1×1g.10gb&lt;/code> on an H100 can host simultaneously a 7B FP8 model (~14 GB of weights), two embedding services and an INT4 guardrail, all with hardware isolation. Without MIG, each of those loads would take a whole GPU with an individual \( \rho \) below 10 %.&lt;/p>
&lt;p>The profiles available on the H100 80 GB (SXM5) according to NVIDIA&amp;rsquo;s MIG User Guide:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>MIG profile&lt;/th>
&lt;th>Compute slices&lt;/th>
&lt;th>Memory&lt;/th>
&lt;th>Max. instances&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>1g.10gb&lt;/code>&lt;/td>
&lt;td>1/7 SMs&lt;/td>
&lt;td>10 GB&lt;/td>
&lt;td>7&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>1g.20gb&lt;/code>&lt;/td>
&lt;td>1/7 SMs&lt;/td>
&lt;td>20 GB&lt;/td>
&lt;td>4&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>2g.20gb&lt;/code>&lt;/td>
&lt;td>2/7 SMs&lt;/td>
&lt;td>20 GB&lt;/td>
&lt;td>3&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>3g.40gb&lt;/code>&lt;/td>
&lt;td>3/7 SMs&lt;/td>
&lt;td>40 GB&lt;/td>
&lt;td>2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>4g.40gb&lt;/code>&lt;/td>
&lt;td>4/7 SMs&lt;/td>
&lt;td>40 GB&lt;/td>
&lt;td>1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>7g.80gb&lt;/code>&lt;/td>
&lt;td>7/7 SMs&lt;/td>
&lt;td>80 GB&lt;/td>
&lt;td>1 (whole GPU)&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>MIG is not available on consumer GPUs (RTX 5090, RTX 4090). Time-slicing is the only sharing option on that hardware.&lt;/p>
&lt;hr>
&lt;h2 id="7--continuous-batching-the-effect-on-mfu">7 · Continuous batching: the effect on MFU&lt;/h2>
&lt;p>Continuous batching (also called iteration-level scheduling or in-flight batching) is the mechanism with the greatest impact on occupancy in inference. The idea: instead of waiting for a complete batch to finish before launching the next, the engine evaluates the pipeline after each token and replaces completed sequences with new requests from the waiting queue.&lt;/p>
&lt;p>Quantified effect in vLLM:&lt;/p>
&lt;ul>
&lt;li>Without batching (bs=1, static): decode MFU ~3–8 %; GPU idle between requests.&lt;/li>
&lt;li>With continuous batching (dynamic bs 16–64): decode MFU ~15–30 %; the GPU almost never waits.&lt;/li>
&lt;li>On pure prefill loads with a large batch (bs=128+): prefill MFU 25–45 %; it approaches the compute roofline.&lt;/li>
&lt;/ul>
&lt;p>The vLLM parameter &lt;code>--max-num-seqs&lt;/code> controls the maximum number of sequences in the concurrent batch. Raising it increases occupancy until HBM becomes the bottleneck (watch for &lt;code>DCGM_FI_PROF_DRAM_ACTIVE&lt;/code> &amp;gt; 90 % sustained).&lt;/p>
&lt;hr>
&lt;h2 id="8--hardware-and-scale-what-applies-to-what">8 · Hardware and scale: what applies to what&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Hardware&lt;/th>
&lt;th>MIG&lt;/th>
&lt;th>MPS&lt;/th>
&lt;th>Time-slicing&lt;/th>
&lt;th>Continuous batching&lt;/th>
&lt;th>Note&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>H100 SXM / H200&lt;/td>
&lt;td>Yes (7 inst.)&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>On-prem datacenter reference&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>A100 SXM/PCIe&lt;/td>
&lt;td>Yes (7 inst.)&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Previous generation; HBM2e&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>L40S / L40&lt;/td>
&lt;td>No&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Ada Lovelace; no MIG; good price/VRAM&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>RTX 5090&lt;/td>
&lt;td>No&lt;/td>
&lt;td>Yes (limited)&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Consumer; no MIG; does not scale in production&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>RTX 4090&lt;/td>
&lt;td>No&lt;/td>
&lt;td>Yes (limited)&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Consumer; 24 GB VRAM; no MIG&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The RTX 5090 and RTX 4090 illustrate the case of &lt;strong>hardware that does not scale&lt;/strong> for multi-tenant with isolation: they do not support MIG, VRAM is scarce for models above 7B with a wide KV-cache, and TDP (600 W / 450 W) is high relative to throughput. For production inference at scale, the 4×H100 SXM is the reference node of this series.&lt;/p>
&lt;hr>
&lt;h2 id="9--finops-diagnostic-flow-from-high-cpm-to-the-cause">9 · FinOps diagnostic flow: from high CPM to the cause&lt;/h2>
&lt;div class="diagram" style="max-width:720px;margin:1rem auto;">
&lt;svg viewBox="0 0 720 380" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="FinOps diagnostic flow from high CPM to the right lever">
&lt;style>.bx{fill:none;stroke:currentColor;stroke-width:1.3}.dec{fill:none;stroke:currentColor;stroke-width:1.3}.tl{font:600 11px sans-serif;fill:currentColor}.ts{font:10px sans-serif;fill:currentColor}.ar{fill:none;stroke:currentColor;stroke-width:1.2;marker-end:url(#fm)}&lt;/style>
&lt;defs>&lt;marker id="fm" 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="currentColor"/>&lt;/marker>&lt;/defs>
&lt;rect class="bx" x="270" y="10" width="180" height="42" rx="6"/>
&lt;text x="360" y="28" text-anchor="middle" class="tl">High CPM detected&lt;/text>
&lt;text x="360" y="44" text-anchor="middle" class="ts">OpenCost + LiteLLM&lt;/text>
&lt;path class="ar" d="M360,52 L360,80"/>
&lt;polygon class="dec" points="360,80 440,110 360,140 280,110"/>
&lt;text x="360" y="105" text-anchor="middle" class="tl">POWER_USAGE&lt;/text>
&lt;text x="360" y="120" text-anchor="middle" class="ts">low?&lt;/text>
&lt;path class="ar" d="M440,110 L530,110"/>
&lt;text x="537" y="114" class="ts">Yes → scheduling idle&lt;/text>
&lt;rect class="bx" x="530" y="128" width="170" height="34" rx="5"/>
&lt;text x="615" y="142" text-anchor="middle" class="ts">Bin-packing / Kueue&lt;/text>
&lt;text x="615" y="155" text-anchor="middle" class="ts">Autoscaling down&lt;/text>
&lt;path class="ar" d="M360,140 L360,168"/>
&lt;text x="270" y="114" class="ts">No&lt;/text>
&lt;polygon class="dec" points="360,168 450,198 360,228 270,198"/>
&lt;text x="360" y="193" text-anchor="middle" class="tl">PIPE_TENSOR_ACTIVE&lt;/text>
&lt;text x="360" y="208" text-anchor="middle" class="ts">low (&amp;lt;0.10)?&lt;/text>
&lt;path class="ar" d="M450,198 L530,198"/>
&lt;text x="537" y="202" class="ts">Yes → batching idle&lt;/text>
&lt;rect class="bx" x="530" y="216" width="170" height="34" rx="5"/>
&lt;text x="615" y="230" text-anchor="middle" class="ts">Continuous batching&lt;/text>
&lt;text x="615" y="243" text-anchor="middle" class="ts">Raise --max-num-seqs&lt;/text>
&lt;path class="ar" d="M360,228 L360,256"/>
&lt;text x="270" y="202" class="ts">No&lt;/text>
&lt;polygon class="dec" points="360,256 450,286 360,316 270,286"/>
&lt;text x="360" y="280" text-anchor="middle" class="tl">DRAM_ACTIVE high&lt;/text>
&lt;text x="360" y="296" text-anchor="middle" class="ts">and batch already large?&lt;/text>
&lt;path class="ar" d="M450,286 L530,286"/>
&lt;text x="537" y="290" class="ts">Yes → memory-bound&lt;/text>
&lt;rect class="bx" x="530" y="304" width="170" height="34" rx="5"/>
&lt;text x="615" y="318" text-anchor="middle" class="ts">FP8/INT4 quantisation&lt;/text>
&lt;text x="615" y="331" text-anchor="middle" class="ts">Smaller model / TP&lt;/text>
&lt;path class="ar" d="M360,316 L360,344"/>
&lt;text x="270" y="290" class="ts">No&lt;/text>
&lt;rect class="bx" x="270" y="344" width="180" height="30" rx="5"/>
&lt;text x="360" y="364" text-anchor="middle" class="ts">MIG / MPS / multi-model bin-pack&lt;/text>
&lt;/svg>
&lt;/div>
&lt;hr>
&lt;h2 id="10--worked-example-impact-of-continuous-batching-on-cpm">10 · Worked example: impact of continuous batching on CPM&lt;/h2>
&lt;p>Starting point: Llama 70B FP8 on 4×H100 SXM, a load of 8 requests/s with 512 output tokens on average, without continuous batching (static bs = 8):&lt;/p>
&lt;ul>
&lt;li>Observed throughput: ~900 tok/s (decode dominant).&lt;/li>
&lt;li>\( \rho_{\text{efectiva}} \approx 900 / 3500 \approx 0.26 \).&lt;/li>
&lt;li>CPM: \( 44 / (900 \times 3600 / 10^6) \approx 13.6\ \text{€} \).&lt;/li>
&lt;/ul>
&lt;p>Same load, enabling continuous batching with &lt;code>--max-num-seqs 64&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>Observed throughput: ~2,300 tok/s (the dynamic batch fills the gaps).&lt;/li>
&lt;li>\( \rho_{\text{efectiva}} \approx 2300 / 3500 \approx 0.66 \).&lt;/li>
&lt;li>CPM: \( 44 / (2300 \times 3600 / 10^6) \approx 5.3\ \text{€} \).&lt;/li>
&lt;/ul>
&lt;p>CPM reduction: from 13.6 € to 5.3 €, &lt;strong>–61 %&lt;/strong>, with no hardware change and without touching the model.&lt;/p>
&lt;p>The vLLM parameters relevant for raising effective throughput:&lt;/p>
&lt;pre tabindex="0">&lt;code>--max-num-seqs 64 # maximum concurrent batch
--max-num-batched-tokens 16384 # total tokens per iteration
--enable-chunked-prefill # interleaves prefill and decode
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="see-also">See also&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://blog.lo0.es/en/posts/gpu-hour-to-cost-per-token-on-prem-vs-cloud/">coste-por-token-y-por-request&lt;/a> — the identity CPM = €/GPU-hour ÷ throughput with data from LiteLLM and OpenCost.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/en/posts/gpu-observability-llm-inference-twelve-dcgm-vllm-metrics/">observabilidad-gpu-dcgm-llm&lt;/a> — the twelve DCGM metrics and five vLLM ones that make up the cockpit.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/en/posts/anatomy-dcgm-vllm-metrics-analogies-documented-anomalies/">anatomia-metricas-dcgm-vllm-anomalias&lt;/a> — a deep dive into the DCGM metrics with anomalies documented in production.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/en/posts/sharing-one-gpu-time-slicing-mps-mig/">compartir-gpu-time-slicing-mps-mig&lt;/a> — time-slicing, MPS and MIG with worked VRAM budgets.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/en/posts/capacity-planning-on-premise-llm-inference/">capacity-planning-inferencia-llm-on-premise&lt;/a> — sizing the cluster from peak throughput and target occupancy.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/en/posts/opencost-gpu-cost-allocation-kubernetes/">opencost-cost-allocation-kubernetes&lt;/a> — how OpenCost calculates the \( C_{\text{GPU}} \) that goes into the CPM identity.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/en/posts/cloud-gpu-on-demand-reserved-spot-neoclouds-2026-prices/">Cloud GPU: a comparison of prices, commitment and sovereign neoclouds&lt;/a> — the alternative €/GPU-hour when on-premise occupancy does not justify the CAPEX: spot and reserved prices from European neoclouds.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/en/posts/full-tco-on-premise-gpu-cluster-capex-gpu-hour-break-even/">TCO of an on-premise GPU cluster: depreciation, energy and infrastructure&lt;/a> — where the \( C_{\text{GPU}} \) of the identity comes from when the iron is your own: CAPEX, depreciation, energy and operations.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="sources">Sources&lt;/h2>
&lt;ul>
&lt;li>NVIDIA — &lt;em>DCGM Field Identifiers reference (v3.1)&lt;/em>, lista completa de &lt;code>DCGM_FI_*&lt;/code> con field IDs y definiciones. &lt;a href="https://docs.nvidia.com/datacenter/dcgm/3.1/dcgm-api/dcgm-api-field-ids.html">https://docs.nvidia.com/datacenter/dcgm/3.1/dcgm-api/dcgm-api-field-ids.html&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>GPU Profiling Metrics (Run:ai / DCGM)&lt;/em>, definiciones de &lt;code>DCGM_FI_PROF_SM_ACTIVE&lt;/code> (1002), &lt;code>SM_OCCUPANCY&lt;/code> (1003), &lt;code>PIPE_TENSOR_ACTIVE&lt;/code> (1004). &lt;a href="https://run-ai-docs.nvidia.com/self-hosted/platform-management/monitor-performance/gpu-profiling-metrics">https://run-ai-docs.nvidia.com/self-hosted/platform-management/monitor-performance/gpu-profiling-metrics&lt;/a>&lt;/li>
&lt;li>Chowdhery et al. — &lt;em>PaLM: Scaling Language Modeling with Pathways&lt;/em> (MFU definition, sección 4). arXiv 2204.02311. &lt;a href="https://arxiv.org/abs/2204.02311">https://arxiv.org/abs/2204.02311&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>Multi-Instance GPU (MIG) User Guide&lt;/em> (perfiles H100 SXM5, particionado, aislamiento). &lt;a href="https://docs.nvidia.com/datacenter/tesla/mig-user-guide/">https://docs.nvidia.com/datacenter/tesla/mig-user-guide/&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>Supported MIG Profiles&lt;/em> (catálogo completo H100 80 GB). &lt;a href="https://docs.nvidia.com/datacenter/tesla/mig-user-guide/supported-mig-profiles.html">https://docs.nvidia.com/datacenter/tesla/mig-user-guide/supported-mig-profiles.html&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>Time-Slicing GPUs in Kubernetes&lt;/em> (GPU Operator 24.9.0). &lt;a href="https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/24.9.0/gpu-sharing.html">https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/24.9.0/gpu-sharing.html&lt;/a>&lt;/li>
&lt;li>NVIDIA — &lt;em>Multi-Process Service (MPS) Overview&lt;/em> (kernel concurrency, SM allocation). &lt;a href="https://docs.nvidia.com/deploy/mps/latest/index.html">https://docs.nvidia.com/deploy/mps/latest/index.html&lt;/a>&lt;/li>
&lt;li>Kueue — &lt;em>Overview&lt;/em> (sigs.k8s.io/kueue, bin-packing, cohorts, quotas). &lt;a href="https://kueue.sigs.k8s.io/docs/overview/">https://kueue.sigs.k8s.io/docs/overview/&lt;/a>&lt;/li>
&lt;li>vLLM Blog — &lt;em>vLLM v0.6.0: 2.7x Throughput Improvement and 5x Latency Reduction&lt;/em> (continuous batching, chunked prefill). &lt;a href="https://blog.vllm.ai/2024/09/05/perf-update.html">https://blog.vllm.ai/2024/09/05/perf-update.html&lt;/a>&lt;/li>
&lt;li>GMI Cloud — &lt;em>NVIDIA H100 GPU Pricing: 2026 Rent vs. Buy Cost Analysis&lt;/em>. &lt;a href="https://www.gmicloud.ai/en/blog/nvidia-h100-gpu-pricing-2026-rent-vs-buy-cost-analysis">https://www.gmicloud.ai/en/blog/nvidia-h100-gpu-pricing-2026-rent-vs-buy-cost-analysis&lt;/a>&lt;/li>
&lt;li>Saxena et al. — &lt;em>LLM Inference Unveiled: Survey and Roofline Model Insights&lt;/em>. arXiv 2402.16363. &lt;a href="https://arxiv.org/abs/2402.16363">https://arxiv.org/abs/2402.16363&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>