The Moment of Truth: Executing the EAGLE-3 Training Pipeline for Kimi-K2.5
In the long arc of a complex machine learning engineering session—spanning environment setup, model deployment, profiling, and speculative decoding research—there comes a pivotal moment when all the debugging, patching, and iteration converges into a single command execution. Message [msg 2775] captures exactly such a moment: the assistant launches the EAGLE-3 training script for the Kimi-K2.5 model on a remote server with 8 Blackwell GPUs, after hours of resolving API incompatibilities, config mismatches, and architectural quirks. The output is deceptively brief—a few warnings and a truncated progress line—but the context leading up to it tells a story of systematic problem-solving.
The Command and Its Output
The message consists of a single bash tool call that SSHes into the remote machine (root@10.1.230.174) and executes the training script with these parameters:
CUDA_VISIBLE_DEVICES=0 /root/ml-env/bin/python3 /root/eagle3-train/04_train.py \
--verifier-path /shared/kimi-k2.5-int4 \
--data-dir /root/eagle3-train/data_test/hidden_states/rows_0-2000 \
--vocab-mapping-dir /root/eagle3-train/data_test/vocab_mapping \
--output-dir /root/eagle3-train/output_test \
--epochs 3 \
--lr 3e-5 \
--max-seq-len 2048 \
--ttt-steps 3 \
--val-ratio 0.2 \
--num-workers 0
The output shows two warnings and the beginning of the training banner:
/root/ml-env/lib/python3.12/site-packages/speculators/models/mlp.py:9: UserWarning: Field name "torch_dtype" in "MLPSpeculatorConfig" shadows an attribute in parent "SpeculatorModelConfig"
class MLPSpeculatorConfig(SpeculatorModelConfig):
/root/ml-env/lib/python3.12/site-packages/torch/nn/attention/flex_attention.py:1559: FutureWarning: return_lse is deprecated and will be removed in v2.10. Please use return_aux=AuxRequest(lse=True) instead.
_warn_once(
======================================...
The first warning is a known issue in the speculators library where a field name collides with a parent class attribute—benign but worth noting. The second is a PyTorch deprecation warning about the flex_attention API. The truncated line ======================================... is the beginning of the training script's banner output, which the next message ([msg 2776]) reveals completed successfully: "TRAINING WORKS! All 3 epochs completed successfully in ~1 minute on a single GPU with 10 samples."
Why This Message Was Written: The Long Road to a Working Pipeline
To understand why this particular command was issued, one must appreciate the journey that led to it. The assistant had been working on deploying speculative decoding for Kimi-K2.5—a 1-trillion-parameter Mixture-of-Experts reasoning model running on 8 NVIDIA RTX PRO 6000 Blackwell GPUs. After profiling revealed that AllReduce operations consumed 51.5% of decode time (<msg id=2755 context), the assistant pivoted to speculative decoding as a software-only optimization path.
The EAGLE-3 architecture was chosen as the speculative decoding framework. This required building a complete training pipeline from scratch, adapting the open-source speculators library to work with Kimi-K2.5's unusual architecture. The preceding messages in the conversation reveal a series of obstacles:
- Nested config structure (<msg id=2750-2751>): Kimi-K2.5 uses a
KimiK25Configwrapper with atext_configcontaining the actualDeepseekV3Config. The speculators library expectedhidden_sizeat the top level, but it was nested insidetext_config. - Weight key path mismatch (<msg id=2751-2752>): The model's embedding and LM head weights were stored under
language_model.model.embed_tokens.weightandlanguage_model.lm_head.weight, but the speculators code hardcodedmodel.embed_tokens.weightandlm_head.weight. - API exploration (<msg id=2759-2761>): The assistant discovered that
TransformTensorswas not a wrapper class but the base class itself, requiring a code fix. - Dtype mismatch (<msg id=2763-2765>): The hidden states were in bfloat16 but the model weights initialized in float32, requiring a
.to(torch.bfloat16)cast. - Attention implementation (<msg id=2767-2773>): The EAGLE-3 model uses
flex_attentionwithBlockMask, but theLlamaConfighad_attn_implementation = Noneby default. The assistant initially tried"sdpa"but then discovered through code inspection thatflex_attentionwas required. Each of these issues was identified, debugged, and fixed in a tight loop of code edits, file transfers viascp, and test executions. Message [msg 2775] represents the first run after all these fixes were applied—the moment of truth.## Decisions Made in This Message While the message itself is a single command execution, it embodies several implicit decisions: Decision to use a single GPU (CUDA_VISIBLE_DEVICES=0): The assistant chose to validate the training pipeline on one GPU before scaling up. This was a prudent decision—the model is only ~2.5B parameters in bfloat16 (the draft model, not the full verifier), so it fits comfortably in a single 96GB Blackwell GPU. Running on one GPU also avoids distributed training complexity during debugging. Decision to use 10 test samples: The--data-dirpoints torows_0-2000, but earlier in the conversation (see <msg id=2757-2758 context>), the assistant had extracted hidden states for rows 0-2000 from a larger dataset. Using a tiny slice (effectively 10 samples based on the file count) allows rapid iteration—3 epochs in ~1 minute. Decision to setflex_attention: After initially trying"sdpa"([msg 2770]), the assistant inspected the EAGLE-3 core code and discovered it usescreate_block_maskfrom PyTorch'sflex_attentioninfrastructure (<msg id=2771-2773>). This forced the attention implementation to"flex_attention"rather than the simpler"sdpa"default. This was a correct decision driven by reading the actual source code rather than guessing. Decision to keep--num-workers 0: The data loading uses zero worker processes, which is safe for small-scale testing but would need adjustment for production training.
Assumptions Made
The assistant made several assumptions in this message, some explicit and some implicit:
- The verifier model path is correct:
--verifier-path /shared/kimi-k2.5-int4assumes the INT4 quantized Kimi-K2.5 model is available at that path. This had been verified in earlier messages. - The hidden state extraction was successful: The data directory contains pre-extracted hidden states from the verifier model's forward pass. This was validated in segment 21 (<msg id=2736-2749 context>).
- The speculators library is correctly installed: The import path
/root/ml-env/bin/python3points to the virtual environment where speculators v0.3.0 was installed and patched. - Single GPU is sufficient for validation: The draft model's 2.5B parameters fit in GPU memory alongside the training infrastructure. This turned out to be correct—the training completed without OOM errors.
- The
flex_attentionwarning is non-blocking: The deprecation warning aboutreturn_lseis from PyTorch 2.9.1 and doesn't affect correctness. The assistant implicitly assumed this was safe to ignore. - The
MLPSpeculatorConfigfield shadowing warning is benign: This warning appears in every speculators import and doesn't affect functionality.
Mistakes and Incorrect Assumptions
The most significant incorrect assumption was the attention implementation choice. In [msg 2770], the assistant initially set attn_implementation="sdpa", reasoning that "safe default" would work. But the EAGLE-3 model's forward pass uses create_block_mask which produces a BlockMask object—a flex_attention-specific construct. Using "sdpa" would have caused a type error when the attention layer received a BlockMask instead of a standard attention mask. The assistant caught this by inspecting the source code of Eagle3DraftModel.forward (<msg id=2771-2772>), finding the create_block_mask call, and correcting to "flex_attention" in [msg 2773].
This is a classic pitfall in ML engineering: assuming a "safe default" will work when the library has specific architectural requirements. The assistant's systematic approach—reading the actual source rather than guessing—prevented a runtime failure.
Another subtle assumption was that the --val-ratio 0.2 split would work correctly with only 10 samples. With 8 training files and 2 validation files (as revealed in [msg 2776]), the split is deterministic based on file ordering. This is fine for testing but would need stratified sampling for real training.
Input Knowledge Required
To understand this message fully, one needs:
- EAGLE-3 architecture knowledge: Understanding that EAGLE-3 is a speculative decoding framework that trains a small "draft" model to predict the verifier's hidden states, using a tree-structured attention mechanism with
flex_attention. - Kimi-K2.5 model architecture: The model uses a nested config structure (
KimiK25ConfigwrappingDeepseekV3Config), with weights stored underlanguage_model.*prefixes. - speculators library API: The training pipeline uses
Eagle3SpeculatorConfig,Eagle3DraftModel, and the built-inTrainerclass from thespeculatorspackage. - Remote execution context: The command runs on a remote server with 8 Blackwell GPUs, accessed via SSH. The training uses a Python virtual environment at
/root/ml-env. - Previous debugging context: Understanding why the attention implementation needed to be
flex_attentionrequires knowing that the EAGLE-3 model usescreate_block_maskfor its tree-structured attention mask.
Output Knowledge Created
This message produced several important outputs:
- Validation that the training pipeline works end-to-end: The subsequent message ([msg 2776]) confirms all 3 epochs completed in ~1 minute, producing a 4.6GB checkpoint.
- Confirmation of correct model initialization: The
Eagle3DraftModelloaded successfully with the monkey-patched weight extraction, the bfloat16 casting worked, and theflex_attentionconfiguration was accepted. - Evidence of memory efficiency: The training ran on a single GPU and cleaned up properly ([msg 2778]), with all GPUs showing 0 MiB used afterward.
- Baseline training metrics: The output config ([msg 2776]) shows
total_params_M: 2543.35(2.5B parameters), 24 total steps across 3 epochs, and the learning rate schedule configuration. - A reusable training script: The
04_train.pyscript, after all fixes, became a general-purpose EAGLE-3 training pipeline for Kimi-K2.5 that could be scaled to larger datasets and multiple GPUs.
The Thinking Process Visible in the Reasoning
The assistant's reasoning, visible across the context messages, reveals a methodical debugging approach:
- Identify the error surface: When the speculators library failed to load weights, the assistant didn't just patch the symptom—it traced the error to
_setup_embeddings_and_lm_heads, understood why it failed (nested config + wrong weight key paths), and chose a clean monkey-patch approach. - Explore before fixing: Before rewriting the training script, the assistant explored the speculators library's
__main__.pyandTrainerclass to understand the intended API (<msg id=2756 context>). This prevented reinventing the wheel. - Iterative validation: Each fix was tested independently—first the model creation, then the noise transform, then the dtype, then the attention implementation. The assistant ran the script after each change, reading the error output to guide the next fix.
- Source code inspection: When unsure about API details, the assistant used
inspect.getsource()to read the actual Python source code rather than relying on documentation or assumptions. This was critical for discovering theflex_attentionrequirement. - Check GPU state before running: Before launching the training, the assistant checked
nvidia-smito confirm all GPUs were free ([msg 2757]), preventing resource conflicts.
Conclusion
Message [msg 2775] appears unremarkable at first glance—a simple command execution with truncated output. But it represents the culmination of a sophisticated debugging journey through nested configs, weight path mismatches, dtype incompatibilities, and attention implementation quirks. The successful training run validated hours of investigative work and unlocked the path toward speculative decoding for Kimi-K2.5. In the broader context of the session, this message marks the transition from "can we train?" to "how well can we train?"—a threshold that separates theoretical capability from practical deployment.