{"record":{"id":"6e6030dc2603758f","repo":"sgl-project/sglang","slug":"dspark-speculative-num-draft-tokens-must-be-2-6e6030","errorCode":null,"errorMessage":"DSpark speculative_num_draft_tokens must be >= 2 (= gamma + 1), got {num_draft_tokens}.","messagePattern":"DSpark speculative_num_draft_tokens must be >= 2 \\(= gamma \\+ 1\\), got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/speculative/dspark_components/dspark_config.py","lineNumber":53,"sourceCode":"    from sglang.srt.utils.hf_transformers_utils import get_config\n\n    draft_model_path = get_spec().speculative_draft_model_path\n    if not draft_model_path:\n        return False\n    draft_hf_config = get_config(\n        draft_model_path,\n        trust_remote_code=get_model().trust_remote_code,\n        revision=get_spec().speculative_draft_model_revision,\n        model_override_args=json.loads(get_model().json_model_override_args),\n        model_config_parser=get_model().model_config_parser,\n    )\n    return draft_hf_config is not None and is_deepseek_v4(draft_hf_config)\n\n\ndef dspark_gamma_from_num_draft_tokens(num_draft_tokens: int) -> int:\n    gamma = int(num_draft_tokens) - 1\n    if gamma < 1:\n        raise ValueError(\n            \"DSpark speculative_num_draft_tokens must be >= 2 (= gamma + 1), \"\n            f\"got {num_draft_tokens}.\"\n        )\n    return gamma\n\n\nclass DSparkDraftConfig(msgspec.Struct, frozen=True):\n    num_hidden_layers: Optional[int]\n    num_target_layers: Optional[int]\n    gamma: Optional[int]\n    target_layer_ids: Optional[List[int]]\n    mask_token: str\n    mask_token_id: Optional[int]\n    markov_rank: int\n    markov_head_type: Optional[str]\n\n    def resolve_gamma(self, *, default: Optional[int] = None) -> Optional[int]:\n        return self.gamma if self.gamma is not None else default","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/speculative/dspark_components/dspark_config.py#L35-L71","documentation":"DSpark computes gamma (number of draft tokens per step) as speculative_num_draft_tokens - 1, so num_draft_tokens must be at least 2. Passing 1 or 0 makes gamma < 1 which is nonsensical for speculative proposal, and dspark_gamma_from_num_draft_tokens raises immediately.","triggerScenarios":"Launching with --speculative-num-draft-tokens 1 (or 0) together with the DSpark speculative algorithm; resolve_runtime_config calls dspark_gamma_from_num_draft_tokens during worker init.","commonSituations":"Tuning speculative parameters and setting draft tokens to 1 thinking it disables drafting; misreading gamma vs num_draft_tokens semantics; config templates with a stale value.","solutions":["Set --speculative-num-draft-tokens to >= 2 (gamma + 1), e.g. 2-8 depending on workload","Leave speculative_num_draft_tokens unset so gamma is resolved from the draft checkpoint config","Check the draft checkpoint's block_size/gamma default before overriding"],"exampleFix":"# before\n--speculative-num-draft-tokens 1\n# after\n--speculative-num-draft-tokens 4","handlingStrategy":"validation","validationCode":"assert speculative_num_draft_tokens is None or speculative_num_draft_tokens >= 2, \"num_draft_tokens must be >= 2 (gamma+1)\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember gamma = num_draft_tokens - 1","Validate server args in launch scripts","Prefer checkpoint-resolved gamma when unsure"],"tags":["sglang","dspark","speculative-decoding","config-validation","gamma"],"backgroundTag":"speculative-decoding-config-out-of-range","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}