vllm-project/vllm · error · ValueError
synthetic_acceptance_rates must be non-increasing, got {rate
Error message
synthetic_acceptance_rates must be non-increasing, got {rates}. What it means
synthetic_acceptance_rates must be non-increasing: position i+1 can only be accepted after position i is, so the unconditional acceptance probability cannot rise with depth. Any list where some rates[i] > rates[i-1] is physically inconsistent for rejection sampling and is rejected.
Source
Thrown at vllm/config/speculative.py:279
"""Return per-position unconditional acceptance rates from exactly one
of `rates` or `length` (validates range, length, and monotonicity)."""
if (rates is None) == (length is None):
raise ValueError(
"rejection_sample_method='synthetic' requires exactly one of "
"synthetic_acceptance_rates or synthetic_acceptance_length."
)
if rates is not None:
if len(rates) != n:
raise ValueError(
f"synthetic_acceptance_rates must have length {n}, got {rates}."
)
if not all(0.0 <= r <= 1.0 for r in rates):
raise ValueError(
f"synthetic_acceptance_rates entries must be in [0, 1], "
f"got {rates}."
)
if any(rates[i] > rates[i - 1] for i in range(1, n)):
raise ValueError(
f"synthetic_acceptance_rates must be non-increasing, got {rates}."
)
return list(rates)
assert length is not None
if not 1.0 <= length <= float(n + 1):
raise ValueError(
f"synthetic_acceptance_length must be in [1, {n + 1}], got {length}."
)
return SpeculativeConfig._acceptance_length_to_rates(length, n)
draft_sample_method: DraftSampleMethod = "greedy"
"""How the draft model samples tokens. 'greedy' always picks the argmax
token, and the draft probabilities are treated as one-hot during rejection
sampling. 'probabilistic' samples stochastically from the draft
distribution and uses the full draft logits for the probability ratio test
during rejection sampling. This comes at the cost of additional GPU memory
usage."""
View on GitHub (pinned to c794754062)
Solutions
- Sort descending: rates = sorted(rates, reverse=True)
- Smooth noisy measurements (e.g. running minimum: rates = np.minimum.accumulate(rates))
- Or fall back to synthetic_acceptance_length, which always yields a monotone profile
Example fix
# before synthetic_acceptance_rates=[0.7, 0.75, 0.6] # after synthetic_acceptance_rates=[0.75, 0.7, 0.6]
Defensive patterns
Strategy: validation
Validate before calling
def rates_monotone(rates: list[float]) -> bool:
return all(rates[i] <= rates[i-1] for i in range(1, len(rates))) Type guard
null
Try / catch
null
Prevention
- Apply running-minimum smoothing to empirical profiles
- Sort descending before passing
- Fall back to synthetic_acceptance_length when monotonicity is uncertain
When it happens
Trigger: Profiles built from independent per-position measurements with noise (e.g. [0.7, 0.75, 0.6]); monotonicity broken by rounding/clipping steps; arrays sorted ascending by mistake.
Common situations: Empirical profiling without smoothing; accidental ascending sort of the rate list.
Related errors
- synthetic_acceptance_rates entries must be in [0, 1], got {r
- synthetic_acceptance_length must be in [1, {n + 1}], got {le
- rejection_sample_method='synthetic' requires exactly one of
- synthetic_acceptance_rates must have length {n}, got {rates}
- prompt_lookup_min={self.prompt_lookup_min} must be <= prompt
AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14).
Data as JSON: /api/errors/b7ee8fa264d12819.
Report an issue: GitHub.