<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dvfs on lo0 — Tech Blog</title><link>https://blog.lo0.es/en/tags/dvfs/</link><description>Recent content in Dvfs on lo0 — Tech Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Tue, 16 Jun 2026 09:00:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/en/tags/dvfs/index.xml" rel="self" type="application/rss+xml"/><item><title>Levers for spending fewer watts per token: a quantified catalogue for LLM inference</title><link>https://blog.lo0.es/en/posts/levers-fewer-watts-per-token-llm-inference/</link><pubDate>Tue, 16 Jun 2026 09:00:00 +0200</pubDate><guid>https://blog.lo0.es/en/posts/levers-fewer-watts-per-token-llm-inference/</guid><description>&lt;blockquote>
&lt;p>Notation: amounts in &lt;strong>euros (N €)&lt;/strong>, decimals with a point. The dollar symbol 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>Seven independent levers act on the numerator or the denominator of the identity
\(\text{J/token} = \text{power (W)} / \text{throughput (tok/s)}\). Applied in order of
cost-benefit: &lt;strong>quantisation&lt;/strong> (FP16→FP8) cuts J/token by 30–50% without changing hardware;
&lt;strong>power capping&lt;/strong> to 70% of TDP reduces power by 30% with less than a 10% drop in
throughput on memory-bound loads; &lt;strong>DVFS&lt;/strong> in the decode phase saves a further 22–45%;
&lt;strong>continuous batching&lt;/strong> lowers J/token by 25–40% against unoptimised stacks; &lt;strong>speculative
decoding&lt;/strong> trims up to 29% off J/token at low batch; &lt;strong>prefix caching&lt;/strong> eliminates the
prefill recompute for repeated prompts; and &lt;strong>scheduling to clean hours&lt;/strong> shifts the
carbon footprint without changing physical consumption. Starting reference: a vLLM FP16 stack on an H100
SXM (700 W TDP) with Llama-3 70B produces ~0.39 J/token under realistic batch loads; an
unoptimised stack (PyTorch baseline) starts 2–6× higher. The levers stack; the combined effect
can reach a 73% reduction against the unoptimised baseline
(&lt;a href="https://arxiv.org/pdf/2504.17674">arXiv 2504.17674&lt;/a>).&lt;/p>
&lt;hr>
&lt;h2 id="the-reference-identity">The reference identity&lt;/h2>
$$\text{J/token} = \frac{\overline{P}\ [\text{W}]}{\text{throughput}\ [\text{tok/s}]}$$
&lt;p>where \(\overline{P}\) is the average power over the measurement window (see the methodology in
&lt;a href="https://blog.lo0.es/en/posts/energy-per-token-spain-methodology-electricity-market-speculation/">energy per token&lt;/a>). The levers act on one
of the two factors:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>They reduce \(\overline{P}\)&lt;/strong>: power capping, DVFS, scheduling to low-intensity hours.&lt;/li>
&lt;li>&lt;strong>They raise throughput&lt;/strong> (the denominator): quantisation, continuous batching, speculative decoding,
prefix caching, chunked prefill, model selection.&lt;/li>
&lt;li>&lt;strong>Both at once&lt;/strong>: quantisation (smaller weight footprint → a larger batch fits in VRAM → higher
throughput at similar or lower power).&lt;/li>
&lt;/ul>
&lt;p>The expanded formula including infrastructure overhead:&lt;/p>
$$\text{J/token}_{\text{effective}} = \frac{\overline{P}_{\text{GPU}} + \overline{P}_{\text{rest of node}}}{\text{throughput}_{\text{tok/s}}} \times \text{PUE}$$
&lt;p>For the lever calculations the work is done on \(\overline{P}_{\text{GPU}}\) for clarity; the
PUE factor (see &lt;a href="https://blog.lo0.es/en/posts/energy-per-token-spain-methodology-electricity-market-speculation/">energy per token&lt;/a>) amplifies or
attenuates the effect of each lever proportionally.&lt;/p>
&lt;hr>
&lt;h2 id="master-table-levers--impact--cost--tool">Master table: levers × impact × cost × tool&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Lever&lt;/th>
&lt;th>J/token reduction (%)&lt;/th>
&lt;th>Effect on latency&lt;/th>
&lt;th>Effect on quality&lt;/th>
&lt;th>Main OSS tool&lt;/th>
&lt;th>Source&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Quantisation FP16→FP8&lt;/td>
&lt;td>&lt;strong>30–50%&lt;/strong>&lt;/td>
&lt;td>−8–33% TPOT (improvement)&lt;/td>
&lt;td>&amp;lt;1% degradation on benchmarks&lt;/td>
&lt;td>vLLM, TRT-LLM, llm-compressor&lt;/td>
&lt;td>arXiv 2504.17674, baseten.co&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Quantisation FP16→INT4 (AWQ/GPTQ)&lt;/td>
&lt;td>&lt;strong>45–60%&lt;/strong>&lt;/td>
&lt;td>latency improves (lower BW)&lt;/td>
&lt;td>1–3% degradation depending on model&lt;/td>
&lt;td>AutoAWQ, llm-compressor, vLLM&lt;/td>
&lt;td>arXiv 2504.17674&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Continuous vs static batching&lt;/td>
&lt;td>&lt;strong>25–40%&lt;/strong> vs PyTorch&lt;/td>
&lt;td>+5× throughput (improvement)&lt;/td>
&lt;td>no impact&lt;/td>
&lt;td>vLLM, TGI, TRT-LLM&lt;/td>
&lt;td>arXiv 2504.17674, TokenPowerBench&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Power capping 70% TDP&lt;/td>
&lt;td>&lt;strong>20–30%&lt;/strong> power&lt;/td>
&lt;td>&amp;lt;10% throughput (decode)&lt;/td>
&lt;td>no impact&lt;/td>
&lt;td>nvidia-smi, DCGM, Zeus&lt;/td>
&lt;td>arXiv 2604.11391, NERSC docs&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>DVFS decode-phase&lt;/td>
&lt;td>&lt;strong>22–45%&lt;/strong> in decode&lt;/td>
&lt;td>1–6% total latency&lt;/td>
&lt;td>no impact&lt;/td>
&lt;td>nvidia-smi, GreenLLM, DVFS-GPT&lt;/td>
&lt;td>arXiv 2501.08219, HAL 05190051&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Speculative decoding&lt;/td>
&lt;td>&lt;strong>up to 29%&lt;/strong> (batch≤16)&lt;/td>
&lt;td>TTFT improves&lt;/td>
&lt;td>no demonstrable impact&lt;/td>
&lt;td>vLLM, TRT-LLM&lt;/td>
&lt;td>arXiv 2602.09113&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Prefix caching&lt;/td>
&lt;td>&lt;strong>50–90%&lt;/strong> on reusable prefill&lt;/td>
&lt;td>TTFT −50–80% (repeated prompts)&lt;/td>
&lt;td>no impact&lt;/td>
&lt;td>vLLM, SGLang&lt;/td>
&lt;td>vLLM docs&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Chunked prefill&lt;/td>
&lt;td>~10–15% on mixed loads&lt;/td>
&lt;td>more stable TTFT&lt;/td>
&lt;td>no impact&lt;/td>
&lt;td>vLLM (SARATHI)&lt;/td>
&lt;td>arXiv 2308.16369&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>SLM vs dense LLM selection&lt;/td>
&lt;td>&lt;strong>60–80%&lt;/strong> (7B vs 70B model)&lt;/td>
&lt;td>low latency&lt;/td>
&lt;td>degradation varies by task&lt;/td>
&lt;td>Ollama, vLLM, llama.cpp&lt;/td>
&lt;td>arXiv 2504.17674&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Scheduling to clean hours&lt;/td>
&lt;td>0% J/token, up to −70% CO₂&lt;/td>
&lt;td>no impact on the load&lt;/td>
&lt;td>no impact&lt;/td>
&lt;td>Kueue, Volcano, cron&lt;/td>
&lt;td>ACM SLIT, arXiv 2507.09942&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>Note: the percentages are against the effective J/token of the load, not against idle board
power. The effects are always measured under conditions of equal output quality (same model,
same serving stack, same prompt distribution).&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="lever-1-quantisation">Lever 1: quantisation&lt;/h2>
&lt;h3 id="mechanics">Mechanics&lt;/h3>
&lt;p>Quantisation reduces the numerical precision of the weights (and optionally the activations),
which shortens the time spent reading weights from HBM per generated token. Decode is
memory-bandwidth-bound: the bottleneck is reading the weights, not computing. Reducing bit width
frees bandwidth for higher throughput or allows a larger batch in VRAM.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Format&lt;/th>
&lt;th>Bits/weight&lt;/th>
&lt;th>BW reduction vs FP32&lt;/th>
&lt;th>J/token vs FP16&lt;/th>
&lt;th>Tool&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>FP32&lt;/td>
&lt;td>32&lt;/td>
&lt;td>1× (reference)&lt;/td>
&lt;td>+100% (worse)&lt;/td>
&lt;td>—&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>BF16/FP16&lt;/td>
&lt;td>16&lt;/td>
&lt;td>2×&lt;/td>
&lt;td>reference&lt;/td>
&lt;td>vLLM native&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>FP8 (W8A8)&lt;/td>
&lt;td>8&lt;/td>
&lt;td>~4×&lt;/td>
&lt;td>&lt;strong>−30–50%&lt;/strong>&lt;/td>
&lt;td>vLLM, TRT-LLM, llm-compressor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>INT4 AWQ (W4A16)&lt;/td>
&lt;td>4&lt;/td>
&lt;td>~8×&lt;/td>
&lt;td>&lt;strong>−45–60%&lt;/strong>&lt;/td>
&lt;td>AutoAWQ, llm-compressor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>INT4 GPTQ (W4A16)&lt;/td>
&lt;td>4&lt;/td>
&lt;td>~8×&lt;/td>
&lt;td>&lt;strong>−40–55%&lt;/strong>&lt;/td>
&lt;td>AutoGPTQ, vLLM&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Concrete reference figures:&lt;/p>
&lt;ul>
&lt;li>Llama-3 405B on H100, FP16→FP8: −30% J/token measured; TPOT improves by 33% (Baseten,
&lt;a href="https://www.baseten.co/blog/33-faster-llm-inference-with-fp8-quantization/">baseten.co/blog/33-faster-llm-inference-with-fp8-quantization&lt;/a>).&lt;/li>
&lt;li>The vLLM+CUDA graphs stack vs the PyTorch baseline: 2–6× more efficient in J/token
(&lt;a href="https://arxiv.org/pdf/2504.17674">arXiv 2504.17674&lt;/a>).&lt;/li>
&lt;li>Llama-65B on V100 FP16: 3–4 J/token. Llama-3 70B on H100 FP8: 0.39 J/token. Combined
hardware+quantisation reduction: ~90%
(&lt;a href="https://mlcommons.org/2025/09/mlperf-inference-v5-1-results/">MLCommons, arXiv 2504.17674&lt;/a>).&lt;/li>
&lt;/ul>
&lt;h3 id="quality-cost">Quality cost&lt;/h3>
&lt;p>FP8 quantisation with calibration produces &amp;lt;1% degradation on standard benchmarks (MMLU,
HumanEval). INT4 AWQ can produce 1–3% degradation depending on the model and the task;
INT4 GPTQ without fine calibration, up to 2–5%. Validate with &lt;a href="https://blog.lo0.es/en/posts/llm-energy-leaderboards-wh-per-token/">LLM energy leaderboards&lt;/a> and your own quality benchmarks.&lt;/p>
&lt;h3 id="oss-tooling">OSS tooling&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># vLLM with FP8 (load-time quantisation, H100/A100)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">vllm serve meta-llama/Llama-3-70B-Instruct &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --quantization fp8 &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --dtype auto
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># llm-compressor: offline quantisation to W4A16 (AWQ)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">python -m llmcompressor.transformers.compression.helpers &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --model meta-llama/Llama-3-70B-Instruct &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --recipe w4a16_awq.yaml &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --output-dir llama-70b-w4a16/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="lever-2-continuous-batching">Lever 2: continuous batching&lt;/h2>
&lt;h3 id="mechanics-1">Mechanics&lt;/h3>
&lt;p>Static batching keeps the batch fixed: if one request finishes early, the slot stays
empty until the end of the batch. &lt;strong>Continuous batching&lt;/strong> inserts new requests as
soon as a slot frees up, keeping the GPU always at the highest possible utilisation.&lt;/p>
&lt;p>The energy effect: GPU power is almost constant (the GPU is always active); the
throughput grows. The result is a larger denominator at similar power:&lt;/p>
$$\text{J/token}_{\text{continuous batch}} = \frac{\overline{P}}{\text{throughput}_{\uparrow}}$$
&lt;p>Measured figures (&lt;a href="https://arxiv.org/pdf/2504.17674">arXiv 2504.17674&lt;/a>,
&lt;a href="https://arxiv.org/pdf/2512.03024">TokenPowerBench arXiv 2512.03024&lt;/a>):&lt;/p>
&lt;ul>
&lt;li>vLLM with PagedAttention vs unoptimised Transformers: −25–40% J/token on high
batch loads.&lt;/li>
&lt;li>Online continuous batching vs static offline: a further −5% of J/token (small but
consistent).&lt;/li>
&lt;li>Batch 32→256 tokens: −25% J/token on Llama-3 70B (kernel economies of scale).&lt;/li>
&lt;li>Throughput: ×5 against static batching stacks at equivalent load.&lt;/li>
&lt;/ul>
&lt;p>The efficiency knee on the H100 sits at around 256–512 tokens of batch; beyond that,
J/token flattens or rises slightly.&lt;/p>
&lt;h3 id="oss-tooling-1">OSS tooling&lt;/h3>
&lt;p>vLLM, TGI (HuggingFace Text Generation Inference), TRT-LLM. The relevant flag in vLLM:
&lt;code>--max-num-seqs&lt;/code> (maximum concurrent sequences); tuning it to the available VRAM
maximises the effective batch.&lt;/p>
&lt;hr>
&lt;h2 id="lever-3-power-capping">Lever 3: power capping&lt;/h2>
&lt;h3 id="mechanics-2">Mechanics&lt;/h3>
&lt;p>The power cap sets a ceiling on instantaneous power (W). The GPU respects it by cutting the
clock (internal DVFS). The efficiency trick: LLM decode is &lt;strong>memory-bandwidth-bound&lt;/strong>; the
GPU is already not at usefully full clock, and lowering the TDP reduces power without degrading
throughput proportionally.&lt;/p>
&lt;h3 id="the-power-cap-vs-throughput-curve-h100-sxm">The power cap vs throughput curve (H100 SXM)&lt;/h3>
&lt;p>Figures from (&lt;a href="https://arxiv.org/html/2604.11391v1">arXiv 2604.11391&lt;/a>) and NERSC
(&lt;a href="https://docs.nersc.gov/jobs/power-capping/">docs.nersc.gov/jobs/power-capping&lt;/a>):&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Power cap (W)&lt;/th>
&lt;th>% of TDP (700 W)&lt;/th>
&lt;th>Relative throughput (memory-bound)&lt;/th>
&lt;th>Efficiency (tok/W)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>700 W&lt;/td>
&lt;td>100%&lt;/td>
&lt;td>100%&lt;/td>
&lt;td>1.00×&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>560 W&lt;/td>
&lt;td>80%&lt;/td>
&lt;td>~95%&lt;/td>
&lt;td>~1.19×&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>490 W&lt;/strong>&lt;/td>
&lt;td>&lt;strong>70%&lt;/strong>&lt;/td>
&lt;td>&lt;strong>~90–95%&lt;/strong>&lt;/td>
&lt;td>&lt;strong>~1.27×&lt;/strong> (sweet spot)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>420 W&lt;/td>
&lt;td>60%&lt;/td>
&lt;td>~80–85%&lt;/td>
&lt;td>~1.33× (latency rises)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>350 W&lt;/td>
&lt;td>50%&lt;/td>
&lt;td>~75% (the H100 reaches maximum BW at 350 W memory-bound)&lt;/td>
&lt;td>~1.50×&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>200 W&lt;/td>
&lt;td>29%&lt;/td>
&lt;td>~50%&lt;/td>
&lt;td>frequency saturation&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Key finding from &lt;a href="https://arxiv.org/html/2604.11391v1">arXiv 2604.11391&lt;/a>: &lt;strong>the H100 reaches
its maximum effective memory bandwidth with only ~350 W&lt;/strong> on memory-bound loads
(STriad benchmark), against a TDP of 700 W. Going from 700 W to 490 W (−30% power) produces
less than a 10% drop in decode throughput: J/token improves by ~20–27%.&lt;/p>
&lt;p>For compute-bound loads (heavy prefill), the sweet spot shifts to 400–500 W, where
performance scales almost linearly with the cap; from 500 W to 700 W, the gain is only
~10% extra throughput for each additional 100 W.&lt;/p>
&lt;h3 id="jtoken-formula-with-a-power-cap">J/token formula with a power cap&lt;/h3>
$$\text{J/token}(P_{\text{cap}}) = \frac{P_{\text{cap}} \times \eta(P_{\text{cap}})}{\text{throughput}_{\text{base}} \times f(P_{\text{cap}})}$$
&lt;p>where \(\eta(P_{\text{cap}})\) is the fraction of power actually consumed under the
cap (on memory-bound loads, the GPU no longer consumes the whole cap), and \(f(P_{\text{cap}})\) is
the resulting fraction of throughput. In the H100&amp;rsquo;s 490–560 W zone,
\(\eta \approx 0{.}9\) and \(f \approx 0{.}92\text{–}0{.}95\): the numerator falls more than the
denominator, so J/token improves.&lt;/p>
&lt;h3 id="commands">Commands&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Set the power cap to 490 W on GPU 0 (H100 SXM, 700 W TDP)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo nvidia-smi -i &lt;span class="m">0&lt;/span> -pl &lt;span class="m">490&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Check the applied limit and the power draw in real time&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nvidia-smi --query-gpu&lt;span class="o">=&lt;/span>power.limit,power.draw --format&lt;span class="o">=&lt;/span>csv -l &lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># With DCGM: read DCGM_FI_DEV_POWER_USAGE in Prometheus&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># and DCGM_FI_DEV_POWER_LIMIT to confirm the cap is active&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Apply the cap to every GPU on the node (systemd/cron script)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> i in &lt;span class="k">$(&lt;/span>seq &lt;span class="m">0&lt;/span> 3&lt;span class="k">)&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="k">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> sudo nvidia-smi -i &lt;span class="nv">$i&lt;/span> -pl &lt;span class="m">490&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">done&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>With DCGM in production, the cap can be set via
&lt;code>dcgmi policy --set powercap:490&lt;/code> or through the NVIDIA GPU Operator (the
&lt;code>powerLimit&lt;/code> field in the DevicePlugin). Zeus (&lt;a href="https://ml.energy/zeus/">ml.energy/zeus&lt;/a>)
can sweep caps automatically and measure the resulting J/token per configuration.&lt;/p>
&lt;hr>
&lt;h2 id="lever-4-dvfs-dynamic-voltage-and-frequency-scaling">Lever 4: DVFS (Dynamic Voltage and Frequency Scaling)&lt;/h2>
&lt;h3 id="mechanics-3">Mechanics&lt;/h3>
&lt;p>DVFS is finer-grained than a power cap: it allows the SM frequency to be set directly
(&lt;code>nvidia-smi -lgc&lt;/code> to lock the GPU clock) or left for the driver to adjust dynamically
according to available power and load. In LLM inference, the asymmetry between phases
is the key fact:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Prefill&lt;/strong>: compute-bound. Benefits from maximum clock. Sensitive to frequency reduction.&lt;/li>
&lt;li>&lt;strong>Decode&lt;/strong>: memory-bandwidth-bound. The SM clock barely matters; what rules is
HBM bandwidth.&lt;/li>
&lt;/ul>
&lt;p>This asymmetry is what LLM-specific DVFS systems exploit:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>System&lt;/th>
&lt;th>Energy saving&lt;/th>
&lt;th>Latency penalty&lt;/th>
&lt;th>Hardware&lt;/th>
&lt;th>Source&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>DVFS-GPT (HAL)&lt;/td>
&lt;td>up to &lt;strong>32%&lt;/strong> at iso-latency&lt;/td>
&lt;td>~1–2%&lt;/td>
&lt;td>A100, RTX 4090&lt;/td>
&lt;td>HAL 05190051&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>EcoInfer&lt;/td>
&lt;td>up to &lt;strong>25.4%&lt;/strong> (average 21.5%)&lt;/td>
&lt;td>&amp;lt;5%&lt;/td>
&lt;td>A100&lt;/td>
&lt;td>arXiv MDPI Electronics&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>DualScale (disaggregated prefill/decode)&lt;/td>
&lt;td>&lt;strong>22–45%&lt;/strong> with SLO&lt;/td>
&lt;td>1–6%&lt;/td>
&lt;td>H100&lt;/td>
&lt;td>arXiv 2602.18755&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GreenLLM (SLO-aware DVFS)&lt;/td>
&lt;td>&lt;strong>18–30%&lt;/strong>&lt;/td>
&lt;td>within the SLO&lt;/td>
&lt;td>—&lt;/td>
&lt;td>arXiv 2508.16449&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The paper &lt;a href="https://arxiv.org/abs/2501.08219">arXiv 2501.08219&lt;/a> measures that reducing the
GPU frequency from 2,842 MHz to 180 MHz achieves an average saving of 42% with only a 1–6%
latency increase in the decode phase, because decode is memory-bound and the SM
frequency is not the bottleneck.&lt;/p>
&lt;h3 id="commands-manual-dvfs">Commands (manual DVFS)&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Lock the SM clock at 1,200 MHz (H100 boost: 1,980 MHz) for decode&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo nvidia-smi -i &lt;span class="m">0&lt;/span> -lgc 1200,1200
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Restore the dynamic clock&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo nvidia-smi -i &lt;span class="m">0&lt;/span> -rgc
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Persistent mode (needed for the lock to survive between jobs)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo nvidia-smi -pm &lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For automatic DVFS tuned to the SLO (target TPOT), systems such as GreenLLM or
DVFS-GPT measure the time of each iteration and adjust the frequency in real time, without
overrunning the latency budget.&lt;/p>
&lt;hr>
&lt;h2 id="lever-5-model-selection-slm-moe-vs-dense">Lever 5: model selection (SLM, MoE vs dense)&lt;/h2>
&lt;h3 id="the-effect-of-scale">The effect of scale&lt;/h3>
&lt;p>J/token scales with model size, but sublinearly. For Llama-3
(&lt;a href="https://arxiv.org/pdf/2504.17674">arXiv 2504.17674&lt;/a>):&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Model&lt;/th>
&lt;th>Parameters&lt;/th>
&lt;th>Relative J/token&lt;/th>
&lt;th>Factor vs 1B&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Llama-3 1B&lt;/td>
&lt;td>1B&lt;/td>
&lt;td>1.0×&lt;/td>
&lt;td>reference&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Llama-3 8B&lt;/td>
&lt;td>8B&lt;/td>
&lt;td>~2.3×&lt;/td>
&lt;td>×2.3 (not ×8)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Llama-3 70B&lt;/td>
&lt;td>70B&lt;/td>
&lt;td>~7.3×&lt;/td>
&lt;td>×7.3 (not ×70)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Llama-3 405B&lt;/td>
&lt;td>405B&lt;/td>
&lt;td>~40×&lt;/td>
&lt;td>×40 (not ×405)&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>J/token grows ~7.3× from 1B to 70B, while parameters grow ×70: hardware
efficiency (caches, tensor parallelism, kernels) cushions the scaling.
Even so, moving from 70B to 8B cuts J/token by ~68% if the quality is sufficient for
the task.&lt;/p>
&lt;h3 id="moe-vs-dense">MoE vs dense&lt;/h3>
&lt;p>MoE models activate only a subset of experts per token (typically 2 of 8–64), which
reduces active compute. But there is an implementation trap:&lt;/p>
&lt;ul>
&lt;li>OLMoE-1B-7B (MoE, 1B active) vs OLMo-1B (dense): the MoE consumes &lt;strong>54.24% more&lt;/strong>
energy per token than the dense model of the same active size
(&lt;a href="https://arxiv.org/pdf/2504.17674">arXiv 2504.17674&lt;/a>), because the fused expert
kernels are ~19–63% slower than an equivalent dense GEMM.&lt;/li>
&lt;li>OLMoE-1B-7B vs OLMo-7B (dense): here the MoE is indeed more efficient (7B active → only 1B
active, a ~7× reduction in active FLOPs per token).&lt;/li>
&lt;/ul>
&lt;p>The rule: MoE is efficient when the comparison is &lt;strong>equal total parameters, fewer
active&lt;/strong> (for example Mixtral 8×7B vs dense Llama-3 70B). It is not efficient when the comparison
is &lt;strong>equal active parameters&lt;/strong> per token.&lt;/p>
&lt;h3 id="model-selection-table-by-use-case">Model selection table by use case&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Use case&lt;/th>
&lt;th>Recommended model&lt;/th>
&lt;th>Efficiency rationale&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Simple chat, entity extraction&lt;/td>
&lt;td>SLM 7–8B FP8&lt;/td>
&lt;td>−68% J/token vs 70B&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>RAG with long contexts&lt;/td>
&lt;td>70B FP8 or MoE 8×7B&lt;/td>
&lt;td>optimal quality/J at K&amp;gt;2K tokens&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Complex code, reasoning&lt;/td>
&lt;td>70B FP8 or 405B INT4&lt;/td>
&lt;td>quality is non-negotiable&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Classification, embeddings&lt;/td>
&lt;td>dedicated model (e.g. E5, BGE)&lt;/td>
&lt;td>orders of magnitude less J&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Deferrable offline batch&lt;/td>
&lt;td>large MoE (DeepSeek, Mixtral)&lt;/td>
&lt;td>high quality, batch throughput&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="lever-6-speculative-decoding">Lever 6: speculative decoding&lt;/h2>
&lt;h3 id="mechanics-4">Mechanics&lt;/h3>
&lt;p>Speculative decoding uses a small draft model to propose several
tokens, which the target model verifies in parallel in a single forward pass. If the tokens
are accepted, K tokens are generated per step instead of 1: potentially K× throughput.&lt;/p>
&lt;h3 id="the-energy-efficiency-condition">The energy efficiency condition&lt;/h3>
&lt;p>The J/token benefit &lt;strong>depends on batch size&lt;/strong> (&lt;a href="https://arxiv.org/pdf/2602.09113">arXiv 2602.09113&lt;/a>):&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Batch size&lt;/th>
&lt;th>Effect on J/token&lt;/th>
&lt;th>Reason&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1–16 (low batch)&lt;/td>
&lt;td>&lt;strong>−up to 29%&lt;/strong>&lt;/td>
&lt;td>the draft model fills the waiting time; verification is cheap&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>32–64 (medium batch)&lt;/td>
&lt;td>~0% (neutral)&lt;/td>
&lt;td>verification overhead cancels out the gain&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>128+ (high batch)&lt;/td>
&lt;td>&lt;strong>+25%&lt;/strong> (worse)&lt;/td>
&lt;td>GPU saturated; the draft model adds overhead without saving&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Conclusion: speculative decoding is a J/token lever only in a &lt;strong>low-latency regime
(batch≤16)&lt;/strong>; in high-throughput serving it is counterproductive in J/token terms
(although it reduces TPOT latency).&lt;/p>
&lt;h3 id="oss-tooling-2">OSS tooling&lt;/h3>
&lt;p>vLLM supports speculative decoding with &lt;code>--speculative-model&lt;/code> and &lt;code>--num-speculative-tokens&lt;/code>.
TRT-LLM does too. The draft model must come from the same family (for example Llama-3 8B as
draft for Llama-3 70B).&lt;/p>
&lt;hr>
&lt;h2 id="lever-7-prefix-caching-and-chunked-prefill">Lever 7: prefix caching and chunked prefill&lt;/h2>
&lt;h3 id="prefix-caching">Prefix caching&lt;/h3>
&lt;p>The prefill KV-cache of a shared prompt (system prompt, few-shot examples, document
context) is identical across requests. Storing and reusing it eliminates the prefill
recompute for that fraction of the prompt.&lt;/p>
&lt;p>Energy impact: prefill is compute-bound and draws power spikes. Removing the
repeated prefill removes those spikes. In scenarios with a fixed 1,000-token system prompt
and 200-token user prompts, the saving is ~1,000/(1,000+200) = &lt;strong>~83% of prefill
energy&lt;/strong>. In total J/token, the effect depends on the length of the shared prompt against
the generation length.&lt;/p>
&lt;p>Enabling it in vLLM:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">vllm serve meta-llama/Llama-3-70B-Instruct &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --enable-prefix-caching &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --max-num-seqs &lt;span class="m">256&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="chunked-prefill-sarathi">Chunked prefill (SARATHI)&lt;/h3>
&lt;p>Chunked prefill splits the prefill into fixed-size chunks and processes each chunk together with
decode tokens from other requests. The benefit: the prefill of a long prompt no longer
blocks the decode of other requests (reducing TPOT spikes), which allows higher
GPU utilisation over time.&lt;/p>
&lt;p>In terms of total J/token, chunked prefill reduces the node&amp;rsquo;s peak power
(fewer prefill spikes) and improves average utilisation, which translates into ~10–15% less
J/token on mixed loads with long prompts (&lt;a href="https://arxiv.org/pdf/2308.16369">arXiv 2308.16369&lt;/a>).&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Enable chunked prefill in vLLM (chunk size: 512 tokens)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">vllm serve meta-llama/Llama-3-70B-Instruct &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --enable-chunked-prefill &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --max-num-batched-tokens &lt;span class="m">512&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="lever-8-scheduling-to-clean-hours">Lever 8: scheduling to clean hours&lt;/h2>
&lt;p>This lever does not reduce physical J/token, but it does reduce the &lt;strong>gCO₂/token&lt;/strong> of deferrable load.
The mechanics: moving training, document ingestion, batch re-ranking and fine-tuning
to the hours of lowest grid carbon intensity.&lt;/p>
&lt;p>Impact figures for temporal shifting (&lt;a href="https://arxiv.org/pdf/2507.09942">ACM SLIT, arXiv 2507.09942&lt;/a>):&lt;/p>
&lt;ul>
&lt;li>CO₂ reduction from temporal shifting: &lt;strong>up to 34.7%&lt;/strong> for flexible loads.&lt;/li>
&lt;li>With carbon-aware reinforcement learning (Eco-Orchestrator): up to a &lt;strong>70% offset&lt;/strong> in
integrated deployments.&lt;/li>
&lt;li>In Spain, the hourly variation in intensity is ~80–250 gCO₂/kWh: a factor of ~3× within the
same day (see &lt;a href="https://blog.lo0.es/en/posts/watt-to-carbon-pue-grid-intensity-gco2-per-token/">from watt to carbon&lt;/a>).&lt;/li>
&lt;/ul>
&lt;p>The practical implementation uses Kueue or Volcano on Kubernetes, with a grid intensity
metric (the ElectricityMaps API or esios) as the scheduling signal. Loads are marked with a
&lt;code>carbon-deadline&lt;/code> annotation (the maximum tolerable wait) and the scheduler places them
in the minimum-intensity hours within that window.&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="c"># Kueue annotation for carbon-aware scheduling&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">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">kueue.x-k8s.io/carbon-aware&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;true&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">kueue.x-k8s.io/carbon-deadline&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;8h&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="the-power-cap-vs-throughput-curve-the-sweet-spot">The power cap vs throughput curve: the sweet spot&lt;/h2>
&lt;div class="diagram" style="max-width:720px;margin:1rem auto;">
&lt;svg viewBox="0 0 720 320" role="img" aria-label="Power cap vs throughput curve on H100 SXM: the efficiency sweet spot (minimum J/token) sits between 490 and 560 W, where the power reduction outpaces the throughput drop" xmlns="http://www.w3.org/2000/svg">
&lt;style>.ax{fill:none;stroke:currentColor;stroke-width:1}.ln{fill:none;stroke:currentColor;stroke-width:1.8}.ln2{fill:none;stroke:currentColor;stroke-width:1.8;stroke-dasharray:6 3}.tl{font:600 12px sans-serif;fill:currentColor}.ts{font:11px sans-serif;fill:currentColor}.dot{fill:currentColor}&lt;/style>
&lt;defs>&lt;marker id="arr" 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;line class="ax" x1="60" y1="30" x2="60" y2="240" marker-end="url(#arr)"/>
&lt;line class="ax" x1="60" y1="240" x2="660" y2="240" marker-end="url(#arr)"/>
&lt;text x="62" y="22" class="ts">%&lt;/text>
&lt;text x="330" y="268" class="ts">Power cap (W) →&lt;/text>
&lt;text x="10" y="80" class="ts" transform="rotate(-90 10 140)">%&lt;/text>
&lt;text x="62" y="245" class="ts">200&lt;/text>
&lt;text x="152" y="245" class="ts">280&lt;/text>
&lt;text x="242" y="245" class="ts">350&lt;/text>
&lt;text x="332" y="245" class="ts">420&lt;/text>
&lt;text x="412" y="245" class="ts">490&lt;/text>
&lt;text x="492" y="245" class="ts">560&lt;/text>
&lt;text x="572" y="245" class="ts">630&lt;/text>
&lt;text x="642" y="245" class="ts">700&lt;/text>
&lt;text x="64" y="235" class="ts">0&lt;/text>
&lt;text x="54" y="195" class="ts">50&lt;/text>
&lt;text x="54" y="155" class="ts">70&lt;/text>
&lt;text x="54" y="115" class="ts">80&lt;/text>
&lt;text x="54" y="75" class="ts">90&lt;/text>
&lt;text x="44" y="45" class="ts">100&lt;/text>
&lt;line class="ax" x1="58" y1="40" x2="62" y2="40"/>
&lt;line class="ax" x1="58" y1="75" x2="62" y2="75"/>
&lt;line class="ax" x1="58" y1="115" x2="62" y2="115"/>
&lt;line class="ax" x1="58" y1="155" x2="62" y2="155"/>
&lt;line class="ax" x1="58" y1="195" x2="62" y2="195"/>
&lt;path class="ln" d="M90,195 L180,160 L240,130 L330,115 L420,95 L500,75 L590,55 L650,40"/>
&lt;path class="ln2" d="M90,160 L180,140 L240,128 L330,118 L420,108 L500,98 L590,92 L650,90"/>
&lt;text x="580" y="48" class="ts">power (% TDP)&lt;/text>
&lt;text x="560" y="104" class="ts">throughput (%)&lt;/text>
&lt;circle class="dot" cx="420" cy="95" r="5"/>
&lt;circle class="dot" cx="500" cy="75" r="5"/>
&lt;line class="ax" x1="420" y1="95" x2="420" y2="240" stroke-dasharray="3 3"/>
&lt;line class="ax" x1="500" y1="75" x2="500" y2="240" stroke-dasharray="3 3"/>
&lt;text x="380" y="88" class="tl">sweet spot&lt;/text>
&lt;text x="362" y="280" class="ts">490–560 W: −30% power, &amp;lt;10% throughput. Minimum J/token.&lt;/text>
&lt;text x="62" y="305" class="ts">H100 SXM (700 W TDP). Memory-bound load (LLM decode). Source: arXiv 2604.11391, NERSC.&lt;/text>
&lt;/svg>
&lt;/div>
&lt;p>Reading the chart: the power curve (solid line) falls faster than the throughput
curve (dashed line) in the 490–560 W zone. Above 560 W, each additional 70 W
gives only ~5% extra throughput; below 420 W, throughput starts
falling faster than power. The &lt;strong>efficiency sweet spot&lt;/strong> (minimum J/token) sits
at 490–560 W for decode-bound loads.&lt;/p>
&lt;p>For compute-bound loads (pure prefill), the sweet spot shifts to 500–600 W: prefill
saturates SM compute and needs more power to sustain throughput.&lt;/p>
&lt;hr>
&lt;h2 id="how-to-measure-the-effect-and-validate-quality">How to measure the effect and validate quality&lt;/h2>
&lt;h3 id="measurement-stack">Measurement stack&lt;/h3>
&lt;p>The full stack for measuring the effect of each lever:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>What to measure&lt;/th>
&lt;th>Tool&lt;/th>
&lt;th>Metric&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Real-time GPU power&lt;/td>
&lt;td>DCGM (&lt;code>DCGM_FI_DEV_POWER_USAGE&lt;/code>)&lt;/td>
&lt;td>W per GPU, 100ms&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>J/token in production&lt;/td>
&lt;td>Kepler + vLLM tokens&lt;/td>
&lt;td>&lt;code>rate(kepler_joules) / rate(vllm_tokens)&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>J/token on the bench&lt;/td>
&lt;td>Zeus (&lt;code>ZeusMonitor&lt;/code>)&lt;/td>
&lt;td>J measured during the benchmark&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Throughput&lt;/td>
&lt;td>vLLM metrics (&lt;code>vllm:generation_tokens_total&lt;/code>)&lt;/td>
&lt;td>tok/s&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>TPOT latency&lt;/td>
&lt;td>vLLM (&lt;code>vllm:e2e_request_latency&lt;/code>)&lt;/td>
&lt;td>ms/tok&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Output quality&lt;/td>
&lt;td>lm-evaluation-harness&lt;/td>
&lt;td>MMLU, HumanEval, etc.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>See the full stack in &lt;a href="https://blog.lo0.es/en/posts/measuring-energy-in-production-kepler-dcgm-stack/">energy tooling&lt;/a>.&lt;/p>
&lt;h3 id="measurement-protocol-per-lever">Measurement protocol per lever&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-promql" data-lang="promql">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Real-time J/token (Kepler + vLLM in Prometheus)&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="k">sum&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="kr">rate&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">kepler_container_joules_total&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nl">container&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">&amp;#34;&lt;/span>&lt;span class="s">vllm&lt;/span>&lt;span class="p">&amp;#34;}[&lt;/span>&lt;span class="s">5m&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">))&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="o">/&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="k">sum&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="kr">rate&lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">vllm_generation_tokens_total&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s">5m&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">))&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="c1"># Average power per GPU (DCGM)&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="k">avg&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">by&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">gpu&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">DCGM_FI_DEV_POWER_USAGE&lt;/span>&lt;span class="o">)&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="c1"># Check that the power cap is active&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="k">avg&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">by&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">gpu&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">(&lt;/span>&lt;span class="nv">DCGM_FI_DEV_POWER_LIMIT&lt;/span>&lt;span class="o">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>With Zeus, the configuration sweep is automatic:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">zeus.monitor&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">ZeusMonitor&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">monitor&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ZeusMonitor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">gpu_indices&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">with&lt;/span> &lt;span class="n">monitor&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">begin_window&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;fp8_inference&amp;#34;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># run the benchmark with vLLM FP8&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">run_benchmark&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;llama-3-70b-fp8&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">num_tokens&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">10_000&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">monitor&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">end_window&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;fp8_inference&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;J/token: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">total_energy&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mi">10_000&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.4f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="quality-validation">Quality validation&lt;/h3>
&lt;p>Validating that the lever does not degrade quality is done with lm-evaluation-harness
(&lt;a href="https://github.com/EleutherAI/lm-evaluation-harness">github.com/EleutherAI/lm-evaluation-harness&lt;/a>):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Compare MMLU between FP16 and FP8&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">lm_eval --model vllm &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --model_args &lt;span class="nv">pretrained&lt;/span>&lt;span class="o">=&lt;/span>meta-llama/Llama-3-70B-Instruct,dtype&lt;span class="o">=&lt;/span>float16 &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --tasks mmlu --num_fewshot &lt;span class="m">5&lt;/span> --output_path ./results/fp16/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">lm_eval --model vllm &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --model_args &lt;span class="nv">pretrained&lt;/span>&lt;span class="o">=&lt;/span>meta-llama/Llama-3-70B-Instruct,quantization&lt;span class="o">=&lt;/span>fp8 &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> --tasks mmlu --num_fewshot &lt;span class="m">5&lt;/span> --output_path ./results/fp8/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The MMLU score difference between FP16 and FP8 with calibration is typically
&amp;lt;1%. Without calibration it can be 2–4%.&lt;/p>
&lt;hr>
&lt;h2 id="pareto-decision-table-energy--latency--quality">Pareto decision table (energy / latency / quality)&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Lever&lt;/th>
&lt;th>J/token&lt;/th>
&lt;th>TPOT (latency)&lt;/th>
&lt;th>Quality&lt;/th>
&lt;th>Implementation cost&lt;/th>
&lt;th>Reversibility&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>FP8 quantisation&lt;/td>
&lt;td>↓↓↓&lt;/td>
&lt;td>↓ (improves)&lt;/td>
&lt;td>~ (−&amp;lt;1%)&lt;/td>
&lt;td>Low (1 flag)&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>INT4 AWQ quantisation&lt;/td>
&lt;td>↓↓↓↓&lt;/td>
&lt;td>↓ (improves)&lt;/td>
&lt;td>↓ (−1–3%)&lt;/td>
&lt;td>Medium (recalibrate)&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Continuous batching&lt;/td>
&lt;td>↓↓↓&lt;/td>
&lt;td>~ (neutral on TPOT)&lt;/td>
&lt;td>~&lt;/td>
&lt;td>Low (new engine)&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Power cap 70% TDP&lt;/td>
&lt;td>↓↓&lt;/td>
&lt;td>↑ &amp;lt;10%&lt;/td>
&lt;td>~&lt;/td>
&lt;td>Very low (1 command)&lt;/td>
&lt;td>Immediate&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>DVFS decode&lt;/td>
&lt;td>↓↓↓&lt;/td>
&lt;td>↑ &amp;lt;6%&lt;/td>
&lt;td>~&lt;/td>
&lt;td>Medium (script + tuning)&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Speculative decoding&lt;/td>
&lt;td>↓ (low batch)&lt;/td>
&lt;td>↓ (improves TTFT)&lt;/td>
&lt;td>~&lt;/td>
&lt;td>Medium (draft model)&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Prefix caching&lt;/td>
&lt;td>↓↓ (prefill)&lt;/td>
&lt;td>↓↓ (TTFT improves)&lt;/td>
&lt;td>~&lt;/td>
&lt;td>Low (1 flag)&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Chunked prefill&lt;/td>
&lt;td>↓&lt;/td>
&lt;td>↑ stable TPOT&lt;/td>
&lt;td>~&lt;/td>
&lt;td>Low (1 flag)&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>SLM (7B vs 70B)&lt;/td>
&lt;td>↓↓↓↓&lt;/td>
&lt;td>↓↓ (improves a lot)&lt;/td>
&lt;td>↓↓ (−variable)&lt;/td>
&lt;td>High (quality re-eval)&lt;/td>
&lt;td>Medium&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>MoE (vs dense, same active size)&lt;/td>
&lt;td>↑ (+54%)&lt;/td>
&lt;td>↑&lt;/td>
&lt;td>~&lt;/td>
&lt;td>—&lt;/td>
&lt;td>—&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Scheduling to clean hours&lt;/td>
&lt;td>~ J/token, ↓↓ CO₂&lt;/td>
&lt;td>~ (for deferrable)&lt;/td>
&lt;td>~&lt;/td>
&lt;td>Medium (scheduler)&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Key: ↓↓↓↓ strong improvement · ↓↓↓ significant improvement · ↓↓ moderate improvement · ↓ slight improvement ·
~ neutral · ↑ worsens · ↑↑ worsens significantly.&lt;/p>
&lt;hr>
&lt;h2 id="stacking-levers-the-combined-effect">Stacking levers: the combined effect&lt;/h2>
&lt;p>The levers are mostly &lt;strong>orthogonal&lt;/strong> and they stack. The maximum combined impact
documented in (&lt;a href="https://arxiv.org/pdf/2504.17674">arXiv 2504.17674&lt;/a>):&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;Correct application of the relevant inference optimisations can reduce
total energy consumption by up to 73% against unoptimised baselines.&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>Recommended sequence by cost-benefit:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Optimised engine&lt;/strong> (vLLM, TRT-LLM) with continuous batching: −25–40% immediately.&lt;/li>
&lt;li>&lt;strong>FP8 quantisation&lt;/strong> (if the hardware supports it: H100, A100 with limited support): a further −30–50%
on the remaining J/token.&lt;/li>
&lt;li>&lt;strong>Power cap at 70% TDP&lt;/strong>: −20–30% power with &amp;lt;10% of throughput. Low cost.&lt;/li>
&lt;li>&lt;strong>Prefix caching&lt;/strong>: turn it on if there are system prompts or repeated contexts. No cost.&lt;/li>
&lt;li>&lt;strong>Chunked prefill&lt;/strong>: if the load has long variable prompts.&lt;/li>
&lt;li>&lt;strong>DVFS in decode&lt;/strong>: a further −22–45% if the SLO allows it.&lt;/li>
&lt;li>&lt;strong>Speculative decoding&lt;/strong>: only if the batch is low (&amp;lt;16) and TTFT latency matters.&lt;/li>
&lt;li>&lt;strong>Model selection&lt;/strong>: move to an SLM if the quality is sufficient (evaluate with
lm-evaluation-harness on your specific task).&lt;/li>
&lt;/ol>
&lt;p>Quantified example on 4×H100 SXM (2,800 W node TDP), Llama-3 70B, chat load:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Configuration&lt;/th>
&lt;th>Power (W)&lt;/th>
&lt;th>Throughput (tok/s)&lt;/th>
&lt;th>J/token&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>PyTorch FP16, static batching&lt;/td>
&lt;td>~2,100&lt;/td>
&lt;td>~400&lt;/td>
&lt;td>&lt;strong>5.25&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>vLLM FP16, continuous batching&lt;/td>
&lt;td>~2,200&lt;/td>
&lt;td>~1,800&lt;/td>
&lt;td>&lt;strong>1.22&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>vLLM FP8, continuous batching&lt;/td>
&lt;td>~2,100&lt;/td>
&lt;td>~2,400&lt;/td>
&lt;td>&lt;strong>0.875&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>+ power cap 490 W/GPU (1,960 W node)&lt;/td>
&lt;td>~1,960&lt;/td>
&lt;td>~2,160&lt;/td>
&lt;td>&lt;strong>0.907&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>+ prefix caching (40% hit rate)&lt;/td>
&lt;td>~1,960&lt;/td>
&lt;td>~2,600&lt;/td>
&lt;td>&lt;strong>0.754&lt;/strong>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>+ DVFS decode 1,200 MHz&lt;/td>
&lt;td>~1,500&lt;/td>
&lt;td>~2,400&lt;/td>
&lt;td>&lt;strong>0.625&lt;/strong>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>The values are illustrative estimates based on the cited papers applied to
a 4×H100 node. Real J/token depends on the prompt distribution, the effective batch
and the temperature of the models. Measuring it with Zeus or DCGM+Kepler is mandatory.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="reference-hardware-tdp-and-power-cap-ranges">Reference hardware: TDP and power cap ranges&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>GPU&lt;/th>
&lt;th>TDP (W)&lt;/th>
&lt;th>Supported cap range&lt;/th>
&lt;th>Decode sweet spot&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>H100 SXM 80GB&lt;/td>
&lt;td>700&lt;/td>
&lt;td>200–700 W&lt;/td>
&lt;td>~490–560 W&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>H100 PCIe 80GB&lt;/td>
&lt;td>350&lt;/td>
&lt;td>100–350 W&lt;/td>
&lt;td>~245–280 W&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>A100 SXM 80GB&lt;/td>
&lt;td>400&lt;/td>
&lt;td>100–400 W&lt;/td>
&lt;td>~280–320 W&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>A100 PCIe 80GB&lt;/td>
&lt;td>300&lt;/td>
&lt;td>100–300 W&lt;/td>
&lt;td>~210–240 W&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>L40S 48GB&lt;/td>
&lt;td>350&lt;/td>
&lt;td>100–350 W&lt;/td>
&lt;td>~245–280 W&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>RTX 5090 (reference, PCIe)&lt;/td>
&lt;td>575&lt;/td>
&lt;td>~100–575 W&lt;/td>
&lt;td>~400–460 W&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>For the exact ranges: &lt;code>nvidia-smi -q -d POWER | grep -E &amp;quot;Min|Max|Current&amp;quot;&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="executive-summary-by-role">Executive summary by role&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Role&lt;/th>
&lt;th>First action&lt;/th>
&lt;th>Second action&lt;/th>
&lt;th>Key tool&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Cluster operator&lt;/td>
&lt;td>&lt;code>nvidia-smi -pl [70% TDP]&lt;/code> on every node&lt;/td>
&lt;td>Enable persistent mode&lt;/td>
&lt;td>nvidia-smi, DCGM&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Serving engineer&lt;/td>
&lt;td>Migrate to vLLM FP8 with continuous batching&lt;/td>
&lt;td>Enable prefix caching&lt;/td>
&lt;td>vLLM, llm-compressor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Platform architect&lt;/td>
&lt;td>Select the smallest model that meets the quality SLO&lt;/td>
&lt;td>Design a carbon-based scheduling policy&lt;/td>
&lt;td>lm-evaluation-harness, Kueue&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>MLOps team&lt;/td>
&lt;td>Set up a power cap sweep with Zeus&lt;/td>
&lt;td>Instrument J/token in Prometheus&lt;/td>
&lt;td>Zeus, DCGM exporter&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>See the full measurement stack in &lt;a href="https://blog.lo0.es/en/posts/measuring-energy-in-production-kepler-dcgm-stack/">energy tooling&lt;/a>
and the J/token methodology in &lt;a href="https://blog.lo0.es/en/posts/energy-per-token-spain-methodology-electricity-market-speculation/">energy per token&lt;/a>.
For the context of reference energy leaderboards and benchmarks, see &lt;a href="https://blog.lo0.es/en/posts/llm-energy-leaderboards-wh-per-token/">LLM energy leaderboards&lt;/a>.
The connection with full TCO is in &lt;a href="https://blog.lo0.es/en/posts/gpu-idle-cost-not-on-any-invoice/">GPU utilisation as FinOps&lt;/a>.&lt;/p>
&lt;hr>
&lt;h2 id="sources">Sources&lt;/h2>
&lt;ul>
&lt;li>arXiv 2504.17674 · Energy Considerations of LLM Inference and Efficiency Optimizations (CMU/Hugging Face, 2025) — &lt;a href="https://arxiv.org/pdf/2504.17674">https://arxiv.org/pdf/2504.17674&lt;/a>&lt;/li>
&lt;li>arXiv 2604.11391 · Architectural Trade-offs: power-capping NVIDIA H100 and H200 (FAU Erlangen, 2026) — &lt;a href="https://arxiv.org/html/2604.11391v1">https://arxiv.org/html/2604.11391v1&lt;/a>&lt;/li>
&lt;li>arXiv 2512.03024 · TokenPowerBench: Benchmarking the Power Consumption of LLM Inference — &lt;a href="https://arxiv.org/pdf/2512.03024">https://arxiv.org/pdf/2512.03024&lt;/a>&lt;/li>
&lt;li>arXiv 2602.09113 · Benchmarking the Energy Savings with Speculative Decoding Strategies — &lt;a href="https://arxiv.org/pdf/2602.09113">https://arxiv.org/pdf/2602.09113&lt;/a>&lt;/li>
&lt;li>arXiv 2501.08219 · Characterizing LLM Inference Energy-Performance Tradeoffs across Workloads and GPU Scaling — &lt;a href="https://arxiv.org/abs/2501.08219">https://arxiv.org/abs/2501.08219&lt;/a>&lt;/li>
&lt;li>arXiv 2602.18755 · DualScale: Energy-Efficient Disaggregated LLM Serving via Phase-Aware Placement and DVFS — &lt;a href="https://arxiv.org/pdf/2602.18755">https://arxiv.org/pdf/2602.18755&lt;/a>&lt;/li>
&lt;li>arXiv 2508.16449 · GreenLLM: SLO-Aware Dynamic Frequency Scaling for Energy-Efficient LLM Serving — &lt;a href="https://arxiv.org/pdf/2508.16449">https://arxiv.org/pdf/2508.16449&lt;/a>&lt;/li>
&lt;li>HAL 05190051 · DVFS-GPT: Dynamic Voltage and Frequency Scaling for Energy-Efficient LLMs — &lt;a href="https://hal.science/hal-05190051">https://hal.science/hal-05190051&lt;/a>&lt;/li>
&lt;li>arXiv 2308.16369 · SARATHI: Efficient LLM Inference by Piggybacking Decodes with Chunked Prefills — &lt;a href="https://arxiv.org/pdf/2308.16369">https://arxiv.org/pdf/2308.16369&lt;/a>&lt;/li>
&lt;li>arXiv 2507.09942 · Green-LLM: Optimal Workload Allocation for Environmentally-Aware Distributed Inference — &lt;a href="https://arxiv.org/pdf/2507.09942">https://arxiv.org/pdf/2507.09942&lt;/a>&lt;/li>
&lt;li>arXiv 2505.06371 · The ML.ENERGY Benchmark: Toward Automated Inference Energy Measurement and Optimization — &lt;a href="https://arxiv.org/html/2505.06371v1">https://arxiv.org/html/2505.06371v1&lt;/a>&lt;/li>
&lt;li>Zeus Project (ml.energy) — &lt;a href="https://ml.energy/zeus/">https://ml.energy/zeus/&lt;/a>&lt;/li>
&lt;li>Zeus · PyTorch blog: Deep Learning Energy Measurement and Optimization — &lt;a href="https://pytorch.org/blog/zeus/">https://pytorch.org/blog/zeus/&lt;/a>&lt;/li>
&lt;li>Baseten · 33% faster LLM inference with FP8 quantization — &lt;a href="https://www.baseten.co/blog/33-faster-llm-inference-with-fp8-quantization/">https://www.baseten.co/blog/33-faster-llm-inference-with-fp8-quantization/&lt;/a>&lt;/li>
&lt;li>NVIDIA · Managing Power Capping (DGX H100/H200 User Guide) — &lt;a href="https://docs.nvidia.com/dgx/dgxh100-user-guide/power-capping.html">https://docs.nvidia.com/dgx/dgxh100-user-guide/power-capping.html&lt;/a>&lt;/li>
&lt;li>NERSC · GPU Power Capping documentation — &lt;a href="https://docs.nersc.gov/jobs/power-capping/">https://docs.nersc.gov/jobs/power-capping/&lt;/a>&lt;/li>
&lt;li>MLCommons · MLPerf Inference v5.1 results — &lt;a href="https://mlcommons.org/2025/09/mlperf-inference-v5-1-results/">https://mlcommons.org/2025/09/mlperf-inference-v5-1-results/&lt;/a>&lt;/li>
&lt;li>vLLM · Disaggregated Prefill documentation — &lt;a href="https://docs.vllm.ai/en/latest/features/disagg_prefill/">https://docs.vllm.ai/en/latest/features/disagg_prefill/&lt;/a>&lt;/li>
&lt;li>Microsoft Research · Characterizing Power Management Opportunities for LLMs in the Cloud (ASPLOS 2024) — &lt;a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2024/03/GPU_Power_ASPLOS_24.pdf">https://www.microsoft.com/en-us/research/wp-content/uploads/2024/03/GPU_Power_ASPLOS_24.pdf&lt;/a>&lt;/li>
&lt;li>EcoInfer (MDPI Electronics) · Optimizing Energy Efficiency with Latency Guarantees Through Iteration-Level GPU Frequency Control — &lt;a href="https://doi.org/10.3390/electronics15102139">https://doi.org/10.3390/electronics15102139&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>