{"record":{"id":"b276581e7a1e14f6","repo":"vllm-project/vllm","slug":"dspark-draft-topk-is-only-supported-by-dspark","errorCode":null,"errorMessage":"dspark_draft_topk is only supported by DSpark","messagePattern":"dspark_draft_topk is only supported by DSpark","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vllm/config/speculative.py","lineNumber":1090,"sourceCode":"                        self.num_speculative_tokens = n_predict\n                    elif (\n                        self.num_speculative_tokens > n_predict\n                        and self.num_speculative_tokens % n_predict != 0\n                    ):\n                        # Ensure divisibility for MTP module reuse.\n                        raise ValueError(\n                            f\"num_speculative_tokens:{self.num_speculative_tokens}\"\n                            f\" must be divisible by {n_predict=}\"\n                        )\n\n                if self.num_speculative_tokens is None:\n                    raise ValueError(\n                        \"A speculative model was provided, but \"\n                        \"`num_speculative_tokens` was not provided\"\n                    )\n\n                if self.dspark_draft_topk is not None and self.method != \"dspark\":\n                    raise ValueError(\"dspark_draft_topk is only supported by DSpark\")\n\n                dspark_draft_topk = None\n                if self.method == \"dspark\":\n                    hf_config = self.draft_model_config.hf_config\n                    dspark_draft_topk = self.dspark_draft_topk\n                    if dspark_draft_topk is None:\n                        dspark_draft_topk = getattr(\n                            hf_config, \"dspark_draft_topk\", None\n                        )\n                    if dspark_draft_topk is not None:\n                        draft_vocab_size = (\n                            getattr(hf_config, \"draft_vocab_size\", None)\n                            or hf_config.vocab_size\n                        )\n                        if not 1 <= dspark_draft_topk <= draft_vocab_size:\n                            raise ValueError(\n                                \"dspark_draft_topk must be between 1 and the \"\n                                f\"draft vocabulary size ({draft_vocab_size})\"","sourceCodeStart":1072,"sourceCodeEnd":1108,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/config/speculative.py#L1072-L1108","documentation":"Raised when dspark_draft_topk is set to a non-None value but the speculative method is not 'dspark'. The top-k draft restriction is implemented only in the DSpark drafting worker, so applying the knob to ngram/eagle/mtp etc. is rejected at config validation time.","triggerScenarios":"speculative_config={'method': 'eagle', ..., 'dspark_draft_topk': 4} or a shared config template that sets dspark_draft_topk while switching method to something else.","commonSituations":"Reusing a DSpark-tuned config for a different speculative method; leaving the key behind after migrating methods in a YAML/JSON config that is copy-edited rather than regenerated.","solutions":["Remove dspark_draft_topk from the speculative_config when method != 'dspark'","Switch method to 'dspark' with a Qwen3DSparkModel draft if the top-k behavior is what you want"],"exampleFix":"# before\nspeculative_config={\"method\": \"ngram\", \"prompt_lookup_max\": 4, \"dspark_draft_topk\": 4}\n# after\nspeculative_config={\"method\": \"ngram\", \"prompt_lookup_max\": 4}","handlingStrategy":"validation","validationCode":"if spec_cfg.get(\"dspark_draft_topk\") is not None and spec_cfg.get(\"method\") != \"dspark\":\n    spec_cfg.pop(\"dspark_draft_topk\")  # or raise in strict mode","typeGuard":"def is_dspark_topk_usage_valid(method: str, topk: int | None) -> bool:\n    return topk is None or method == \"dspark\"","tryCatchPattern":null,"preventionTips":["Generate speculative configs from typed dataclasses per method so cross-method keys cannot mix","Treat method-specific knobs as exclusive: lint your config for keys not applicable to the chosen method"],"tags":["speculative-decoding","dspark","config","invalid-combination"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}