The 250W Signal: How a User's Observation About GPU Power Draw Uncovered Hidden Underutilization in EAGLE-3 Training
"Also was seeing only 250/600W GPU power use, can we bump batch or sth to get better util?"
This single sentence, uttered by the user at message index 4251 in a sprawling AI-assisted coding session, is a masterclass in how domain expertise manifests as a seemingly casual observation that fundamentally redirects a technical trajectory. On its surface, it is a simple question about GPU utilization. In practice, it exposed a cascade of incorrect assumptions baked into the training configuration, triggered a complete re-evaluation of the EAGLE-3 drafter training pipeline, and ultimately led to a multi-fold improvement in training efficiency. To understand why this message matters, one must understand the context in which it landed, the assumptions it challenged, and the chain of reasoning it set in motion.
The Moment of Arrival
The message arrived at a pivotal moment. The assistant had just completed a complex sequence of operations: killing the initial EAGLE-3 training run (which used --ttt-steps 3), clearing the output directory, and relaunching with --ttt-steps 5 after the user agreed to the tradeoff of longer training for better deep-speculation capability ([msg 4250]). The training had been running for only a few minutes. The assistant had already performed several monitoring checks, reporting that the four GPUs were at "100% utilization" with approximately 250W power draw and 28.5 GB VRAM usage ([msg 4239]). The assistant's tone was satisfied: the training was converging, the loss was dropping, and the GPUs appeared fully occupied.
The user's message cut through this complacency. The key insight was not in the GPU utilization percentage (which showed 100%), but in the power draw. An RTX PRO 6000 Blackwell GPU has a 600W thermal design power (TDP). Drawing only 250W while showing 100% utilization is a telltale sign of a specific class of problem: the GPU is constantly active but never fully saturated. It is doing small amounts of work continuously rather than large amounts of work efficiently. The utilization metric reports that the GPU is never idle, but the power metric reveals that it is never truly busy.
The Assumptions Under Scrutiny
To appreciate what the user's observation challenged, one must reconstruct the assistant's mental model at that moment. The assistant had made several interconnected assumptions:
Assumption 1: 100% GPU-Util means full utilization. This is a common misconception. The nvidia-smi "GPU-Util" percentage measures what fraction of the time the GPU had at least one kernel running. It does not measure how many streaming multiprocessors (SMs) were active, nor how hard they were working. A GPU running a tiny kernel in a tight loop can show 100% utilization while drawing a fraction of its rated power. The assistant had reported "4 GPUs at 100% utilization, ~250W each" ([msg 4240]) without recognizing the contradiction in those two numbers.
Assumption 2: The batch size is adequate. The training script used batch_size=1 with sequence packing to max_seq_len=4096. The collate function packs multiple short sequences into one long sequence, with block-diagonal attention masking keeping them independent. The assistant had accepted this default without questioning whether it was sufficient to saturate the GPUs. The reasoning was that "packing handles effective batch size" (as noted in the script's comment at line 421: # Packing handles effective batch size).
Assumption 3: The 28.5 GB VRAM usage was reasonable. With 96 GB available per GPU and only 28.5 GB in use, the assistant had not flagged this as a problem. In fact, the assistant had interpreted the GPU compute bottleneck positively: "The bottleneck isn't disk or CPU — it's the GPU compute at 100% util. That's actually good — means the 4 GPUs are working at full capacity" ([msg 4244]). This was a critical misreading of the situation.
Assumption 4: The 35-hour training estimate was an immutable consequence of the data size. The assistant had calculated 35,446 batches per epoch, 5 epochs, at 1.4 steps/second, yielding ~35 hours total. This was presented as a fait accompli — the training would take this long because that's how many batches there were.
The Knowledge Gap the User Filled
The user brought knowledge that the assistant lacked: an intuitive understanding of what GPU power draw reveals about workload characteristics. The 250W/600W ratio is not a random number — it is a diagnostic signal. On NVIDIA GPUs, power draw correlates strongly with the number of active SMs and the intensity of the computations they perform. A model training step on a tiny batch (one packed sequence of 4096 tokens for a 1.2B parameter model) simply does not generate enough arithmetic intensity to keep the tensor cores saturated. The GPU spends most of its time on overhead: loading weights, synchronizing, moving data between memory hierarchies. The compute-to-move ratio is too low.
This is a well-known phenomenon in GPU computing. Small batch sizes lead to "compute-bound but underutilized" behavior where the GPU is technically never idle (hence 100% utilization) but is never fully engaged (hence 250W instead of 600W). The fix is almost always to increase the amount of work per step — larger batch size, longer sequences, or both.
What the Message Triggered
The assistant's response to this message ([msg 4252] onwards) shows a rapid course correction. The assistant immediately acknowledged the issue: "Good eye — 250W/600W means the GPUs are underutilized despite showing 100% GPU-Util. The 100% util just means the GPU always has some work, but the work per step is small (tiny batch)." This was followed by a systematic investigation:
- Killing the running training ([msg 4252]) — a decisive action that shows the assistant understood the severity of the problem. Continuing with underutilized GPUs would waste hours.
- Analyzing the data loader ([msg 4253]) — reading the speculators library's
data.pyto understand how packing and batch size interact. The collate function packs samples into a singlemax_lensequence, and the DataLoader usesbatch_size=1. - Reading the model's forward method (<msg id=4260-4261>) — discovering that the model expects batch dimension = 1 (shape
[1, total_seq_len, ...]), meaningbatch_sizecannot simply be increased without breaking the attention masking. The model usesflex_attentionwithBlockMaskbuilt for single-batch inputs. - Identifying the correct lever — since
batch_sizeis fixed at 1, the only way to increase work per step is to increasemax_seq_len, which allows more samples to be packed into each sequence. At 4096 tokens, each batch packs approximately 1 sample (since many training sequences are near 4096 tokens). At 8192, it might pack 1-2. At 32768, it could pack 4-8+. - Restarting with
--max-seq-len 8192([msg 4261]) — an immediate improvement that raised power draw from 250W to 412-476W and VRAM usage from 28.5 GB to 39.8 GB ([msg 4264]). - Further iteration — the user then pointed out that 8192 was still too small given the training data characteristics ([msg 4263]), leading to a further restart with
--max-seq-len 32768([msg 4265]).
The Deeper Significance
This message is remarkable not for its technical complexity — it is a simple observation — but for what it reveals about the human-AI collaboration dynamic. The assistant had all the data needed to identify the underutilization. It had run nvidia-smi and seen both the 100% utilization and the 250W power draw in the same command output ([msg 4239]). It had the VRAM usage (28.5 GB out of 96 GB). It had the step rate (1.4 steps/second). It had the total step count (177,230). All the pieces were there, but the assistant failed to connect them into the correct diagnosis.
The user, by contrast, immediately spotted the anomaly. The 250W/600W ratio was a red flag that the assistant's monitoring logic did not know to look for. The assistant's mental model of "good GPU utilization" was binary — the GPU is either busy or idle. The user's mental model was continuous — the GPU can be busy at different intensities, and power draw reveals the intensity.
This is a pattern that recurs throughout the session: the assistant provides comprehensive monitoring data, and the user spots the one number that contradicts the narrative. The assistant reports 100% utilization; the user sees 250W and knows that's not right. The assistant reports 28.5 GB VRAM; the user knows that with 96 GB available, something is wasting capacity.
Output Knowledge Created
This message created several new pieces of knowledge that persisted through the rest of the session:
- The diagnostic heuristic: GPU power draw relative to TDP is a better indicator of true utilization than the GPU-Util percentage. This became a standard check in subsequent monitoring.
- The batch size constraint: The EAGLE-3 model's forward method requires batch dimension = 1, meaning the only way to increase throughput is via sequence packing length. This is now documented implicitly in the training configuration.
- The sequence length lever:
max_seq_lenin the trainer controls both packing efficiency and VRAM usage. At 4096: 28.5 GB, 250W. At 8192: 39.8 GB, 412-476W. The relationship is not linear but the improvement is dramatic. - The training time reduction: By packing more samples per step, the effective number of steps per epoch dropped from 35,446 to something much smaller, dramatically reducing the 35-hour estimate.
Conclusion
The user's message at index 4251 is a perfect example of why human oversight remains essential in AI-assisted development. The assistant can execute complex multi-step workflows, monitor dozens of metrics, and reason about tradeoffs — but it can miss the forest for the trees. A single number (250W) that contradicted the assistant's narrative (100% utilization) was invisible to the automated reasoning but immediately obvious to the human expert. The message is short, almost offhand, but it redirected the entire training pipeline toward efficiency. In doing so, it saved not just the hours of wasted GPU time that would have accumulated under the original configuration, but also established a diagnostic pattern that would inform every subsequent training run in the session.