Deconstructing SGLang's MTP/NEXTN Speculation: A Systematic Codebase Exploration for Hybrid Models

In the ever-evolving landscape of large language model serving, speculative decoding has emerged as a critical technique for reducing latency without sacrificing quality. For hybrid architectures like Qwen3.5-122B-A10B—which interleave full attention layers with linear attention (GatedDeltaNet) layers—the path to enabling Multi-Token Prediction (MTP) speculation is far from straightforward. This article chronicles a deep, systematic exploration of the SGLang codebase to understand exactly how MTP/NEXTN speculation works for these hybrid models, what flags are needed, and where the hidden gotchas lie.

The Research Mission

The session began with a focused research task: understand how MTP/NEXTN speculation operates in SGLang specifically for hybrid Mamba/attention models like Qwen3.5-122B-A10B. The user posed five concrete questions covering command-line flags, scheduler strategies, compatibility constraints, model configuration fields, and code-level gotchas. What followed was a 37-message odyssey through SGLang's source code—a masterclass in systematic codebase reconnaissance.

Architecture Mapping: The Chain of Transformations

One of the first discoveries was that SGLang's MTP support involves a multi-step architecture transformation chain. When a user passes --speculative-algorithm NEXTN, the code in server_args.py (line 2679-2680) immediately converts it to EAGLE internally. NEXTN is essentially an alias, not a separate algorithm. This is a crucial detail: anyone looking for NEXTN-specific code paths will find none—the algorithm is EAGLE all the way down.

The architecture renaming continues in model_config.py (lines 328-332). When the system detects a draft model with the architecture Qwen3_5MoeForConditionalGeneration or Qwen3_5ForConditionalGeneration, it renames the architecture to Qwen3_5ForCausalLMMTP and hardcodes num_nextn_predict_layers = 1. This mapping is what triggers the loading of the specialized MTP model class defined in qwen3_5_mtp.py.

The MTP model itself is a stripped-down, single-layer version of the full model. Critically, the code sets full_attention_interval = 1 (line 73-74 of qwen3_5_mtp.py), meaning the single draft layer uses full attention rather than linear attention. This makes sense: the draft head needs to predict multiple future tokens, and full attention provides the richest representation for that task. The is_nextn=True flag is threaded through the model components to prevent issues with MoE expert routing in the draft context.

Command-Line Flags and Environment Variables

The research uncovered a precise set of flags needed to enable MTP speculation for Qwen3.5. Beyond the algorithm selection, the --speculative-num-steps flag controls how many draft tokens are generated per step. If not set, auto_choose_speculative_params defaults to (3, 1, 4)—three steps, top-k of 1, and four draft tokens—for architectures not explicitly listed. Qwen3.5 is notably absent from that explicit list, so it receives these defaults.

The environment variable SGLANG_ENABLE_SPEC_V2 (defined in environ.py, line 421) emerged as a critical toggle. When set to True, it enables the v2 overlap schedule for EAGLE/NEXTN speculation, forcing disable_overlap_schedule to False. Without this variable, overlap scheduling is disabled, which significantly impacts throughput.

A significant gotcha concerns the draft model path. Unlike DeepSeek and GLM architectures, Qwen3.5 is not in the list of architectures that auto-set speculative_draft_model_path = model_path (lines 2731-2740 of server_args.py). Users must explicitly pass --speculative-draft-model-path pointing to the same model path, or the system will error out. This is an easy trap to fall into.

The Scheduler Strategy Puzzle

The scheduler strategy proved to be one of the most nuanced aspects of the configuration. The default mamba_scheduler_strategy = "auto" resolves to "no_buffer" (lines 925-928 of server_args.py). However, combining no_buffer with radix cache (enabled by default) and speculative decoding triggers a hard error:

"Speculative decoding for {model_arch} is not compatible with radix cache when using --mamba-scheduler-strategy no_buffer."
"To use radix cache with speculative decoding, please use --mamba-scheduler-strategy extra_buffer and set SGLANG_ENABLE_SPEC_V2=1."

The solution is --mamba-scheduler-strategy extra_buffer, which is explicitly supported for Qwen3.5 architectures (line 1867-1872 of server_args.py). This strategy allocates an extra buffer for Mamba cache states, enabling the radix cache to function correctly alongside speculative decoding.

However, extra_buffer comes with its own constraints. The mamba_track_interval must be divisible by page_size, and FLA_CHUNK_SIZE and page_size must be mutually divisible. These constraints are enforced at lines 2008-2016 of server_args.py.

Compatibility Deep Dive

The research systematically probed four compatibility dimensions:

Hybrid GDN Models

Qwen3.5-122B-A10B is a hybrid GDN model with 48 layers, where layer_types alternates between "linear_attention" (GatedDeltaNet) and "full_attention" (every 4th layer). The hybrid_gdn_config property in model_runner.py (lines 1589-1601) explicitly recognizes Qwen3_5Config and Qwen3_5MoeConfig instances. Both eagle_worker.py (v1) and eagle_worker_v2.py (v2) have dedicated code paths that call _mamba_verify_update after verification when hybrid_gdn_config is not None. This means the speculative decoding pipeline has explicit, tested support for updating Mamba states in hybrid models after the verification step.

Triton Attention Backend

For Blackwell GPUs (SM120/SM100), the attention registry (attention_registry.py, lines 210-216) requires the triton, trtllm_mha, or fa4 backend for hybrid GDN models. The triton backend has special handling for hybrid_gdn_config to correctly retrieve v_head_dim (lines 98-102 of triton_backend.py). Rather than being a compatibility concern, triton is the required backend for this configuration.

--disable-custom-all-reduce

A search through the entire speculative decoding directory found zero references to disable_custom_all_reduce. The flag is purely a communication optimization that affects all-reduce kernel selection, with no interaction with speculative decoding logic. It is safe to use alongside MTP speculation.

TP=4

The MTP model code reads tp_size but imposes no TP-specific restrictions. The base model's attention heads (32) and key-value heads (2) divide evenly by TP=4, with GQA replication logic handling the KV head distribution. No TP-based assertions or restrictions were found in any speculative decoding code path.

The Model Configuration: What the config.json Reveals

The HF config for Qwen3.5-122B-A10B contains mtp_num_hidden_layers = 1 and mtp_use_dedicated_embeddings = false. However, a striking finding emerged: SGLang's code never directly reads mtp_num_hidden_layers from the config. Instead, it hardcodes num_nextn_predict_layers = 1 for Qwen3.5 architectures in model_config.py. The config value is purely informational from SGLang's perspective—a consistency check at best.

This has implications for future model variants. If a future Qwen3.5 model ships with mtp_num_hidden_layers = 2 or higher, SGLang would still use a single-layer draft model unless the code is updated. The hardcoded value is a potential maintenance risk.

The Complete Launch Command

The research culminated in a recommended launch command that synthesizes all findings:

SGLANG_ENABLE_SPEC_V2=1 python -m sglang.launch_server \
  --model-path /shared/models/Qwen3.5-122B-A10B \
  --speculative-algorithm NEXTN \
  --speculative-draft-model-path /shared/models/Qwen3.5-122B-A10B \
  --mamba-scheduler-strategy extra_buffer \
  --tp 4 \
  --attention-backend triton \
  --trust-remote-code

Each flag addresses a specific requirement uncovered during the exploration: SGLANG_ENABLE_SPEC_V2=1 enables the overlap schedule, --speculative-algorithm NEXTN triggers the EAGLE code path, --speculative-draft-model-path explicitly sets the draft model (since Qwen3.5 is not auto-detected), --mamba-scheduler-strategy extra_buffer avoids the radix cache conflict, and --attention-backend triton satisfies the Blackwell requirement.

Key Takeaways

This exploration revealed that SGLang's MTP/NEXTN support for hybrid models is both sophisticated and fragile. The architecture renaming chain, the scheduler strategy interactions, and the hidden gotchas around draft model path auto-detection all represent potential failure points for the unwary user. However, for those who navigate these complexities, the payoff is substantial: MTP speculation can deliver 12-45% per-request throughput improvement at low concurrency, as confirmed in subsequent testing.

The session also highlighted the value of systematic codebase exploration. By tracing each configuration parameter through the code—from server_args.py through model_config.py into the speculative workers—the research built a complete picture of how the pieces fit together. This approach uncovered not just the answers to the original five questions, but a deeper understanding of SGLang's architectural philosophy: that speculative decoding is not a simple flag toggle but a coordinated system of architecture mappings, scheduler strategies, and backend selections that must all align for success.## Inside the Speculative Engine: How Verification Works for Hybrid Models

One of the most technically intricate aspects uncovered during the exploration is how SGLang handles state verification for hybrid GDN models. Unlike pure transformer models where verification simply compares draft tokens against target model outputs, hybrid models require careful management of Mamba/linear attention states.

The eagle_worker_v2.py file (lines 814-820) contains a critical code path that checks hybrid_gdn_config is not None after verification. When this condition is true, it calls _mamba_verify_update, which updates the linear attention states (the GatedDeltaNet recurrent states) to reflect the accepted tokens. This is necessary because the draft model's speculative trajectory may produce states that diverge from what the target model would generate, and the verification step must reconcile them.

The same pattern appears in eagle_worker.py (lines 771-778) for the v1 speculative path and in multi_layer_eagle_worker.py (line 537). This redundancy across three worker implementations underscores how fundamental this state reconciliation is for hybrid model speculation. Without it, the linear attention states would accumulate errors across successive speculation rounds, degrading quality.

The Attention Registry: Gatekeeper for Blackwell Compatibility

The attention registry in attention_registry.py plays a crucial gatekeeping role. When a hybrid GDN model is detected on a Blackwell GPU, the code enforces a strict backend requirement:

if is_blackwell():
    assert (
        runner.server_args.attention_backend == "triton"
        or runner.server_args.attention_backend == "trtllm_mha"
        or runner.server_args.attention_backend == "fa4"
    ), "triton or trtllm_mha or fa4 backend are the only supported backends on Blackwell GPUs for hybrid GDN models"

This assertion prevents silent failures or performance degradation from incompatible backend choices. The triton backend, in turn, has special handling in triton_backend.py (lines 98-102) where it checks hybrid_gdn_config to determine how to retrieve the value head dimension (v_head_dim). In standard models, v_head_dim can be derived from the first attention layer's value buffer, but in hybrid models, layer 0 may be a linear attention layer with no KV cache buffer at all.

The MTP Model Architecture: A Peek Inside

The qwen3_5_mtp.py file defines Qwen3_5ForCausalLMMTP, the draft model class. Its constructor reveals several design decisions:

  1. Single-layer design: The model sets config.num_hidden_layers = 1, creating a single transformer block for draft prediction.
  2. Full attention override: It sets config.full_attention_interval = 1, ensuring the single layer uses full attention rather than linear attention. This is a deliberate choice—the draft head benefits from the full expressive power of self-attention.
  3. Quantization bypass: When the base model uses modelopt_fp4 quantization, the MTP model explicitly sets quant_config = None (lines 53-54). The draft head remains unquantized to preserve prediction quality.
  4. MoE awareness: The is_nextn flag is passed through to prevent the MoE routing logic from behaving differently in the draft context. This architecture reflects a pragmatic trade-off: the draft model is lightweight enough to generate tokens quickly (single layer, full attention) while being structurally compatible with the target model's embedding and output layers.

The auto_choose_speculative_params Gap

A notable finding was that auto_choose_speculative_params in server_args.py (lines 6223-6280) has no specific entry for Qwen3.5 architectures. The function checks for Llama, DeepSeek, GLM, and other architectures, assigning tuned default values for each. Qwen3.5 falls through to the generic default of (3, 1, 4)—three speculative steps, top-k of 1, and four draft tokens.

This is not necessarily wrong, but it means users cannot rely on architecture-specific tuning. The generic defaults may not be optimal for Qwen3.5's hybrid architecture, where the interaction between full attention and linear attention layers could benefit from different speculation parameters. Users are advised to experiment with --speculative-num-steps values using the benchmarking script at scripts/playground/bench_speculative.py to find the optimal configuration for their specific workload.

Conclusion: A Blueprint for Hybrid Model Speculation

The 37-message exploration of SGLang's MTP/NEXTN codebase produced a comprehensive blueprint for deploying speculative decoding on hybrid attention models. The key findings—the architecture renaming chain, the scheduler strategy requirements, the explicit hybrid GDN support in verification workers, and the Blackwell backend constraints—form a complete picture of what it takes to make MTP speculation work on modern hardware.

For practitioners looking to deploy Qwen3.5-122B-A10B with MTP speculation, the path is clear but requires attention to detail. Every component must be correctly configured: the algorithm flag, the draft model path, the scheduler strategy, the attention backend, and the environment variable. Miss any one, and the system either fails to start or runs without speculation benefits.

The session also demonstrated the power of systematic codebase exploration as a research methodology. By tracing each parameter through the code, reading the relevant source files, and cross-referencing findings across multiple files, the research built a reliable, actionable understanding that goes far beyond what documentation alone could provide. For anyone working with cutting-edge model serving infrastructure, this approach—starting with concrete questions, following the code paths, and documenting every finding—is invaluable.