Isolating the Signal: The Standalone EAGLE-3 Drafter Test

In the middle of a protracted debugging session spanning dozens of messages, message [msg 4381] represents a critical methodological pivot. After hours of chasing configuration parameters, server logs, and silent overrides in SGLang's speculative decoding pipeline, the assistant makes a deliberate choice: step away from the complex inference server entirely and build a standalone test that isolates the EAGLE-3 draft model from its deployment environment. This message is the execution of that decision — a single bash command that runs a freshly written Python script on a remote server, capturing the first diagnostic output of a test designed to answer a fundamental question: is the draft model itself broken, or is SGLang using it incorrectly?

The Debugging Journey That Led Here

To understand why this message matters, one must appreciate the frustrating path that preceded it. The assistant had been working on deploying an EAGLE-3 speculative decoding system for the Kimi-K2.5 language model, using a draft model trained on 100,000 samples that achieved 74.7% validation accuracy. Yet when deployed inside SGLang's inference server, the speculative decoding was producing abysmal results: an accept length of only ~1.6 tokens out of 16 drafted, yielding throughput of ~56.8 tok/s — far below the 90 tok/s baseline of the target model alone.

The first breakthrough came when the assistant discovered that --speculative-num-steps 1 was silently overriding --speculative-num-draft-tokens 16 to just 2 draft tokens, due to an internal SGLang constraint when topk=1. Fixing this to --speculative-num-steps 15 should have produced a chain of 16 draft tokens. But the fix backfired: performance actually worsened to 46.7 tok/s, with accept length still only ~1.9 out of 16. The draft model was generating 16 tokens but only ~2 were being accepted, meaning 14 out of every 16 draft tokens were wasted computation. This strongly suggested the draft model was not predicting well in the actual deployment, despite its 74.7% training accuracy.

At this point, the user (the human in the conversation) made a crucial suggestion: "Try with a training sample and see if accept rate looks correct. Possible we didn't wire in the model correctly" ([msg 4374]). This insight reframed the problem: instead of assuming the model was at fault, consider that the interface between SGLang and the draft model might be wrong.

The Standalone Test Strategy

The assistant's response in [msg 4375] shows the reasoning process: "Good idea — let me test with an actual training sample to verify the drafter is working correctly. If accept rate is high on training data but low on new data, it's a generalization issue. If it's also low on training data, we have a wiring/loading bug." This is a textbook debugging strategy: control for variables by testing in isolation.

The assistant then wrote test_drafter_standalone.py ([msg 4379]), a Python script designed to:

  1. Load the draft model weights from their safetensors file
  2. Load a training sample's hidden states and input tokens
  3. Run the draft model's forward pass manually
  4. Compare predicted tokens against ground truth
  5. Report accuracy metrics The script was SCP'd to the remote server in [msg 4380], and then executed in the subject message [msg 4381].

What the Output Reveals

The output captured in this message shows the initial diagnostic phase of the standalone test. It reveals several important facts:

Vocab mapping: The target model uses a vocabulary of 163,840 tokens, while the draft model uses a compressed vocabulary of 32,000 tokens. This 5:1 compression ratio is a standard EAGLE technique — the draft model predicts in a smaller token space, and a mapping (d2t/t2d) converts between the two vocabularies.

Model architecture: The draft model has hidden_size=7168, matching the target model's hidden dimension. The intermediate_size=18432 and num_heads=64 describe the single transformer decoder layer that forms the core of the EAGLE-3 drafter. The fc.weight tensor has shape [7168, 21504] — note that 21504 = 3 × 7168, confirming that the fully-connected layer projects from 3 concatenated hidden states down to the model's hidden dimension.

Weight keys: The listed keys reveal the complete architecture: an embedding layer (embed_tokens.weight), the fc projection layer, a language model head (lm_head.weight), and a midlayer transformer block with attention (q_proj, k_proj, v_proj, o_proj), MLP (gate_proj, up_proj, down_proj), and normalization layers (input_layernorm, hidden_norm, post_attention_layernorm).

The output is truncated (ending with "..."), suggesting the script continued with more detailed diagnostics — likely the actual accuracy computation — that would appear in subsequent messages.

Assumptions and Hidden Pitfalls

The standalone test makes several implicit assumptions that are worth examining. First, it assumes that the hidden states stored in the training data are in the same format that SGLang passes to the draft model during inference. The training pipeline captured 4 hidden states per position: [embed_output, layer_3_output, layer_31_output, layer_59_output]. The fc layer was trained to take the first 3 of these (embed_output + layer_3 + layer_31) as input. But as later investigation would reveal, SGLang was passing [layer_3, layer_31, layer_59] — the 3 auxiliary hidden states from the target model, excluding the embedding output entirely. This mismatch meant the fc layer was receiving completely different inputs than what it was trained on.

Second, the test assumes the d2t mapping is correctly interpreted. The initial run of the test (visible in [msg 4388]) showed 0% accuracy, partly because the test script initially misinterpreted the d2t tensor as a direct mapping rather than an offset-based mapping. The assistant had to investigate the d2t format ([msg 4390]) to confirm that target_id = draft_id + d2t[draft_id], not target_id = d2t[draft_id].

The Thinking Process Visible in This Message

The decision to write and run a standalone test reveals several aspects of the assistant's reasoning. First, there is a recognition that the SGLang inference server is too complex a system to debug effectively — too many variables (server configuration, CUDA graphs, batch scheduling, hidden state capture) could be contributing to the poor performance. By extracting the draft model and running it in isolation with known inputs, the assistant creates a controlled experiment.

Second, the assistant is methodically narrowing down the hypothesis space. The initial hypothesis was that the draft model's training accuracy (74.7%) was misleading and the model simply didn't generalize. But the user's suggestion that the wiring might be wrong opened a new hypothesis: the model is fine, but SGLang is feeding it the wrong inputs. The standalone test is designed to distinguish between these two possibilities.

Third, the choice of using a training sample (rather than arbitrary text) is deliberate. Training samples have known ground truth — the correct next tokens are recorded. This allows the test to compute exact accuracy metrics that can be compared against the training metrics, providing a direct validation of whether the model weights were loaded and executed correctly.

Input and Output Knowledge

To fully understand this message, one needs knowledge of: the EAGLE-3 speculative decoding architecture (how draft models use compressed vocabularies and hidden state projections); the SGLang inference server's speculative decoding pipeline; the training pipeline that produced the draft model and its hidden state capture mechanism; and the vocabulary mapping scheme between draft and target token spaces.

The message creates new knowledge by beginning the process of validating the draft model in isolation. The output confirms the model architecture and weight dimensions, setting the stage for the accuracy computation that follows. This diagnostic output would eventually lead to the discovery of the hidden state input format mismatch — the critical bug that was causing the poor acceptance rate.

Significance in the Broader Context

This message represents a turning point in the debugging session. Before it, the assistant was operating inside SGLang's complex inference pipeline, trying to understand performance through server logs and configuration parameters. After it, the assistant would have a clean signal: the draft model, when given the correct inputs (matching the training format), achieves 76.9% accuracy — consistent with the training metrics. The problem was not the model but the interface. This discovery led directly to modifying deepseek_v2.py in SGLang to capture the embedding output and pass it as part of the hidden state input, fixing the wiring mismatch and bringing the deployment in line with the training pipeline.

The standalone test methodology — isolate, validate, compare — proved essential for cutting through the complexity of the speculative decoding system and identifying the root cause of the performance failure.