The Decode Attention Hypothesis: A Pivotal Experiment in EAGLE-3 Speculative Decoding Optimization

Introduction

In the course of a deep optimization session for EAGLE-3 speculative decoding on an 8-GPU Kimi-K2.5 deployment, a single message represents a critical turning point. Message <msg id=4904> contains a bash command that launches an SGLang inference server with a single, carefully chosen parameter change: switching --speculative-attention-mode from its default value of prefill to decode. This seemingly minor flag alteration embodies the culmination of an intensive debugging session that had consumed the preceding messages, representing the operator's best hypothesis for why EAGLE-3 speculation was performing worse than the baseline non-speculative server — a deeply counterintuitive outcome that demanded explanation.

The Context: A Performance Mystery

To understand why this message matters, one must appreciate the puzzle that preceded it. The operator had spent hours chasing a phantom regression. Earlier in the day, EAGLE-3 speculation with 2 draft steps had achieved 94 tok/s — a respectable gain over the ~82 tok/s baseline. But subsequent runs showed only 59-61 tok/s, a staggering 27% degradation relative to the non-speculative server. This was the opposite of what speculative decoding should deliver.

The operator systematically eliminated potential causes. A git pull that had updated SGLang was suspected first — perhaps a code regression had slowed the verify path. But reverting to the old commit produced the same 82 tok/s baseline, ruling out a SGLang version issue. The NCCL tuning environment variables that had been carefully propagated were also exonerated. The performance discrepancy persisted regardless of commit, regardless of tuning.

What remained was a structural issue: the verify step — where the target model evaluates the draft tokens proposed by the EAGLE-3 drafter — was taking approximately 30 milliseconds to process three tokens. Meanwhile, the baseline decode path processed a single token in roughly 12 milliseconds. The verify step was thus 2.5× more expensive per-token than normal decode, despite doing essentially the same computation. This asymmetry was the root cause of the performance collapse.

The Insight: CUDA Graphs and Forward Mode

The operator's breakthrough came from tracing the code path. In SGLang's model runner, the forward pass can operate in different "modes" — primarily decode and extend. The decode mode is used when generating one token at a time, and critically, it can leverage CUDA graphs. A CUDA graph captures a sequence of GPU kernel launches and replays them with minimal overhead, eliminating the per-kernel launch latency that would otherwise accumulate across 61 transformer layers and their associated allreduce operations.

The baseline server used decode mode with CUDA graphs, achieving ~12ms per token. But the EAGLE-3 verify step, controlled by the speculative_attention_mode parameter, defaulted to prefill mode — which internally maps to the extend forward path. The extend path does not use CUDA graphs, because it is designed for variable-length prefills where the input size changes each time. Every kernel launch in the verify step incurred full overhead: 61 allreduce operations, each with its own NCCL kernel launch, plus all the attention and feed-forward kernels. The accumulated overhead pushed the verify time to ~30ms.

The operator discovered this by reading the SGLang source code, specifically the model_runner.py file where can_run_graph is determined. The critical code at line 2448 of model_runner.py shows:

can_run_graph = bool(
    mode_check()
    and self.graph_runner
    and self.graph_runner.can_run(forward_batch)
)

The mode_check() function verifies that the forward mode is CUDA-graph-compatible. For decode mode, this returns True; for extend mode, it returns False. Since EAGLE-3 verify used extend mode, CUDA graphs were disabled, and the full kernel launch tax was paid on every verify cycle.

The Hypothesis: Decode Mode for Verify

The operator then checked the server_args.py file and discovered that speculative_attention_mode accepts two values: prefill (the default) and decode. The decode option was designed precisely for this scenario — it would run the verify step using decode-mode attention, which would enable CUDA graph capture and potentially reduce the verify time from ~30ms to something closer to the ~12ms per-token cost of baseline decode.

This was not a guaranteed fix. There were reasons the default was prefill. The verify step processes multiple tokens simultaneously (in this case, 3 tokens: the 2 draft tokens plus the 1 verification token). Decode-mode attention is designed for single-token generation; using it for multiple tokens might produce incorrect results or encounter shape mismatches. The operator was venturing into untested territory.

The Message: Launching the Experiment

The message itself is a bash command that launches the SGLang server with the critical parameter change. Let us examine it in detail:

ssh root@10.1.230.174 'EAGLE3_PROFILE=1 SGLANG_ALLOW_OVERWRITE_LONGER_CONTEXT_LEN=1 \
  nohup /root/ml-env/bin/python3 -m sglang.launch_server \
  --model-path /shared/kimi-k2.5-int4 \
  --trust-remote-code \
  --tp-size 8 \
  --mem-fraction-static 0.88 \
  --host 0.0.0.0 --port 8000 \
  --num-continuous-decode-steps 4 \
  --disable-custom-all-reduce \
  --speculative-algorithm EAGLE3 \
  --speculative-draft-model-path /data/eagle3/output_100k_sglang/4 \
  --speculative-eagle-topk 1 \
  --speculative-num-draft-tokens 3 \
  --speculative-num-steps 2 \
  --speculative-attention-mode decode \
  > /data/eagle3/synth_100k/logs/sglang_eagle3_decode_attn_2step.log 2>&1 &'

Every parameter in this command reflects a decision made during the optimization journey:

Assumptions and Risks

The operator made several assumptions in this message:

  1. That decode mode attention would work correctly for multi-token verify. This was the biggest assumption. The decode attention backend in SGLang was designed for single-token generation, not for evaluating 3 tokens simultaneously. If the attention shapes or masking logic differed between the two modes, the verify step could produce incorrect logits or crash entirely.
  2. That the verify step's batch size would remain fixed. For CUDA graphs to work, the input shapes must be consistent across replays. With topk=1, the number of draft tokens is deterministic (always num_steps + 1), so the verify batch size is always 3. This makes CUDA graph capture feasible. If the operator had been using topk>1 (which produces variable-length draft sequences), decode-mode attention would not have been viable.
  3. That the performance improvement would be significant. Even with CUDA graphs, the verify step processes 3 tokens instead of 1. The attention computation scales linearly with the number of query tokens. So even with optimal CUDA graph acceleration, the verify step would likely be more expensive than a single decode step. The question was whether the overhead reduction would be enough to make EAGLE-3 competitive.
  4. That the NCCL tuning environment variables were still active. The operator had previously patched sitecustomize.py to persist NCCL tuning variables (NCCL_PROTO=LL, NCCL_ALGO=Ring, etc.) across Python processes. If these variables were not properly inherited by the server process, the allreduce performance could be suboptimal regardless of attention mode.

Input Knowledge Required

To fully understand this message, one needs:

Output Knowledge Created

This message creates a testable hypothesis. The log file it produces will answer several questions:

  1. Does decode-mode attention work at all for EAGLE-3 verify? If the server starts successfully and serves requests, the mode is at least functionally correct.
  2. What is the verify time per cycle? The profiling output will show whether verify time drops from ~30ms to something closer to ~12ms per token (i.e., ~36ms for 3 tokens with CUDA graphs, or potentially less if the graph captures the entire forward pass efficiently).
  3. What is the end-to-end throughput? Even if verify time improves, the overall throughput depends on the accept rate. If decode-mode attention somehow reduces the accept rate (e.g., by changing numerical precision or attention masking), the net gain could be zero or negative.
  4. Is the server stable? Running untested attention modes on a production-scale model could trigger crashes, numerical errors, or silent correctness issues.

The Thinking Process

The reasoning visible in the preceding messages reveals a methodical debugging approach. The operator:

  1. Established the baseline: Measured non-speculative throughput at 82 tok/s on both old and new SGLang commits, confirming there was no version regression.
  2. Identified the verify cost: Profiling showed verify taking ~30ms for 3 tokens, versus ~12ms for a single decode token.
  3. Traced the code path: Read model_runner.py to understand how can_run_graph is determined, discovering that extend mode (used by verify) disables CUDA graphs.
  4. Found the parameter: Checked server_args.py and discovered the speculative_attention_mode parameter with decode and prefill options.
  5. Formulated the hypothesis: If decode-mode attention enables CUDA graphs for verify, the per-token cost should drop from ~10ms (30ms/3) to something closer to the decode cost of ~12ms for all 3 tokens combined. This is textbook performance debugging: measure, identify the bottleneck, trace the code path, find the configuration lever, and test the hypothesis.

Conclusion

Message <msg id=4904> represents the moment of maximum leverage in the optimization process. After hours of chasing false leads — git regressions, NCCL tuning, thermal throttling — the operator has identified the true bottleneck (CUDA graph absence in the verify path) and found the configuration parameter that might fix it. The message is concise, containing only a single bash command, but it carries the weight of the entire preceding analysis. The outcome of this experiment will determine whether EAGLE-3 speculation on this hardware is viable, or whether the operator must pivot to alternative strategies like training more data to improve the accept rate. In the best tradition of systems optimization, this message is a clean, testable hypothesis expressed as a single flag change.