{"record":{"id":"c3fcf8e0553b1ae3","repo":"vllm-project/vllm","slug":"synthetic-acceptance-rates-entries-must-be-in-0","errorCode":null,"errorMessage":"synthetic_acceptance_rates entries must be in [0, 1], got {rates}.","messagePattern":"synthetic_acceptance_rates entries must be in \\[0, 1\\], got (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vllm/config/speculative.py","lineNumber":274,"sourceCode":"    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)\n        assert length is not None\n        if not 1.0 <= length <= float(n + 1):\n            raise ValueError(\n                f\"synthetic_acceptance_length must be in [1, {n + 1}], got {length}.\"\n            )\n        return SpeculativeConfig._acceptance_length_to_rates(length, n)\n\n    draft_sample_method: DraftSampleMethod = \"greedy\"\n    \"\"\"How the draft model samples tokens. 'greedy' always picks the argmax\n    token, and the draft probabilities are treated as one-hot during rejection","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/config/speculative.py#L256-L292","documentation":"Each entry of synthetic_acceptance_rates must be a probability in [0, 1]. Values outside that range (negative, > 1, NaN) are not valid acceptance probabilities and the profile is rejected before ever reaching the sampler.","triggerScenarios":"Rates computed as ratios with inverted denominators producing >1 values; NaN leaking in from logging measurements (0/0); percentage values (92) supplied instead of fractions (0.92).","commonSituations":"Hand-derived profiles from acceptance counts; pandas/numpy pipelines that emit NaN for empty buckets; unit confusion percent vs probability.","solutions":["Clip/normalize rates to [0,1] before passing them","Fix the measurement pipeline to emit probabilities (accepted/total)","Replace NaN with 0.0 or use synthetic_acceptance_length instead"],"exampleFix":"# before\nsynthetic_acceptance_rates=[92, 85, 70]  # percentages\n\n# after\nsynthetic_acceptance_rates=[0.92, 0.85, 0.70]","handlingStrategy":"validation","validationCode":"def rates_in_range(rates: list[float]) -> bool:\n    return all(0.0 <= r <= 1.0 for r in rates)","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Clip measured rates to [0,1] before config build","Guard against NaN from empty measurement buckets"],"tags":["speculative-decoding","config","validation","math"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}