vllm-project/vllm · error · ValueError
synthetic_acceptance_rates / synthetic_acceptance_length are
Error message
synthetic_acceptance_rates / synthetic_acceptance_length are only valid with rejection_sample_method='synthetic'.
What it means
vLLM's SpeculativeConfig rejects the synthetic acceptance tuning knobs (synthetic_acceptance_rates / synthetic_acceptance_length) unless rejection_sample_method is set to 'synthetic'. These parameters model a synthetic acceptance distribution instead of using a real draft model, so they are meaningless (and silently misleading) under other rejection-sampling methods. The check runs in the post-init validator of SpeculativeConfig, so it fires at config construction time before any engine startup.
Source
Thrown at vllm/config/speculative.py:1377
if self.num_speculative_tokens <= 0:
raise ValueError(
"Expected num_speculative_tokens to be greater "
f"than zero ({self.num_speculative_tokens})."
)
if self.rejection_sample_method == "synthetic":
# Consolidate to per-position rates
self.synthetic_acceptance_rates = self._resolve_synthetic_acceptance_rates(
self.num_speculative_tokens,
self.synthetic_acceptance_rates,
self.synthetic_acceptance_length,
)
self.synthetic_acceptance_length = None
elif (
self.synthetic_acceptance_rates is not None
or self.synthetic_acceptance_length is not None
):
raise ValueError(
"synthetic_acceptance_rates / synthetic_acceptance_length "
"are only valid with rejection_sample_method='synthetic'."
)
if self.draft_model_config:
self.draft_model_config.verify_with_parallel_config(
self.draft_parallel_config
)
if self.use_heterogeneous_vocab and not self.uses_draft_model():
raise ValueError(
"use_heterogeneous_vocab only works with method='draft_model'"
)
if self.use_heterogeneous_vocab and self.draft_sample_method != "greedy":
raise ValueError(
"use_heterogeneous_vocab currently only supports greedy draft "
"sampling. Set draft_sample_method='greedy' (the default) or "View on GitHub (pinned to c794754062)
Solutions
- Set rejection_sample_method='synthetic' in the speculative config (e.g. --speculative-config '{"method":"ngram",...}' style JSON or CLI flag) so the knobs are honored
- Remove synthetic_acceptance_rates and synthetic_acceptance_length from the config if you intend to use a real draft model or another rejection sampling method
- If you only want a target acceptance length, keep exactly one knob and the 'synthetic' method; the config resolves rates from the length automatically
Example fix
# before
speculative_config = {
"method": "ngram",
"num_speculative_tokens": 5,
"synthetic_acceptance_length": 3.0,
}
# after
speculative_config = {
"method": "ngram",
"rejection_sample_method": "synthetic",
"num_speculative_tokens": 5,
"synthetic_acceptance_length": 3.0,
} Defensive patterns
Strategy: validation
Validate before calling
from vllm.config.speculative import SpeculativeConfig
spec = {"method": "ngram", "num_speculative_tokens": 5,
"synthetic_acceptance_length": 3.0}
has_syn = any(spec.get(k) is not None for k in
("synthetic_acceptance_rates", "synthetic_acceptance_length"))
assert not has_syn or spec.get("rejection_sample_method") == "synthetic", \
"synthetic_acceptance_* requires rejection_sample_method='synthetic'" Type guard
def is_valid_synthetic_spec(spec: dict) -> bool:
uses_syn = any(spec.get(k) is not None
for k in ("synthetic_acceptance_rates",
"synthetic_acceptance_length"))
return not uses_syn or spec.get("rejection_sample_method") == "synthetic" Prevention
- Keep synthetic-acceptance knobs in the same config template as rejection_sample_method='synthetic' so they are never separated
- Validate speculative-config dicts with a helper before passing to LLM()/serve
- When switching speculative methods, strip method-specific fields instead of only changing 'method'
When it happens
Trigger: Creating EngineArgs/VllmConfig (e.g. LLM(model=...), vllm serve) with speculative_config containing num_speculative_tokens plus synthetic_acceptance_rates or synthetic_acceptance_length, while rejection_sample_method is left at its default or set to a non-'synthetic' value (e.g. 'rejection_sample').
Common situations: Copy-pasting a benchmark config that used synthetic drafting into a setup running a real draft model; upgrading vLLM where the synthetic acceptance API was introduced and forgetting the companion method flag; setting synthetic_acceptance_length for ngram/draft_model speculative decoding expecting it to act as a target rate.
Related errors
- rejection_sample_method='synthetic' requires exactly one of
- synthetic_acceptance_rates must have length {n}, got {rates}
- synthetic_acceptance_rates entries must be in [0, 1], got {r
- synthetic_acceptance_rates must be non-increasing, got {rate
- synthetic_acceptance_length must be in [1, {n + 1}], got {le
AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14).
Data as JSON: /api/errors/9465118000a40fce.
Report an issue: GitHub.