{"record":{"id":"ba716e61c162e684","repo":"vllm-project/vllm","slug":"rejection-sample-method-synthetic-requires-exact","errorCode":null,"errorMessage":"rejection_sample_method='synthetic' requires exactly one of synthetic_acceptance_rates or synthetic_acceptance_length.","messagePattern":"rejection_sample_method='synthetic' requires exactly one of synthetic_acceptance_rates or synthetic_acceptance_length\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vllm/config/speculative.py","lineNumber":264,"sourceCode":"    def _acceptance_length_to_rates(length: float, n: int) -> list[float]:\n        \"\"\"Mean acceptance length to unconditional per-position rates, using\n        the minimum-variance schedule.\"\"\"\n        num_drafts = length - 1  # expected number of accepted draft tokens\n        num_full = int(num_drafts)\n        return (\n            [1.0] * num_full + [num_drafts - num_full] + [0.0] * (n - num_full - 1)\n        )[:n]\n\n    @staticmethod\n    def _resolve_synthetic_acceptance_rates(\n        n: int,\n        rates: list[float] | None,\n        length: float | None,\n    ) -> list[float]:\n        \"\"\"Return per-position unconditional acceptance rates from exactly one\n        of `rates` or `length` (validates range, length, and monotonicity).\"\"\"\n        if (rates is None) == (length is None):\n            raise ValueError(\n                \"rejection_sample_method='synthetic' requires exactly one of \"\n                \"synthetic_acceptance_rates or synthetic_acceptance_length.\"\n            )\n        if rates is not None:\n            if len(rates) != n:\n                raise ValueError(\n                    f\"synthetic_acceptance_rates must have length {n}, got {rates}.\"\n                )\n            if not all(0.0 <= r <= 1.0 for r in rates):\n                raise ValueError(\n                    f\"synthetic_acceptance_rates entries must be in [0, 1], \"\n                    f\"got {rates}.\"\n                )\n            if any(rates[i] > rates[i - 1] for i in range(1, n)):\n                raise ValueError(\n                    f\"synthetic_acceptance_rates must be non-increasing, got {rates}.\"\n                )\n            return list(rates)","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/config/speculative.py#L246-L282","documentation":"SpeculativeConfig._resolve_synthetic_acceptance_rates requires exactly one of synthetic_acceptance_rates (explicit per-position rates) or synthetic_acceptance_length (mean accepted length, converted to rates). The check (rates is None) == (length is None) fires when both are given or neither is — the synthetic rejection-sample profile is ambiguous.","triggerScenarios":"SpeculativeConfig(rejection_sample_method='synthetic') with neither rates nor length; supplying both synthetic_acceptance_rates=[...] and synthetic_acceptance_length=2.5; leftover defaults from config templates filling both fields.","commonSituations":"Config templating that sets 'sensible defaults' for every field; upgrading from an API that accepted either implicitly; merging YAML overlays that each contribute one of the two keys.","solutions":["Provide exactly one of synthetic_acceptance_rates or synthetic_acceptance_length","For a target mean accepted length use synthetic_acceptance_length (simpler); for precise per-position control use rates","Strip the unused key from YAML/JSON overlays that may inject it"],"exampleFix":"# before\nSpeculativeConfig(rejection_sample_method='synthetic', synthetic_acceptance_rates=[0.9, 0.8], synthetic_acceptance_length=2.0)\n\n# after\nSpeculativeConfig(rejection_sample_method='synthetic', synthetic_acceptance_length=2.0)","handlingStrategy":"validation","validationCode":"def exactly_one(rates, length) -> bool:\n    return (rates is None) != (length is None)","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Set exactly one of the two synthetic profile keys in YAML","Prefer synthetic_acceptance_length for simplicity","Lint speculative config templates for the both/neither case"],"tags":["speculative-decoding","config","validation"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}