vllm-project/vllm · error · ValueError

synthetic_acceptance_length must be in [1, {n + 1}], got {le

Error message

synthetic_acceptance_length must be in [1, {n + 1}], got {length}.

What it means

When synthetic_acceptance_length is used, it must lie in [1, n+1] where n is the speculative depth: the mean accepted length is at least 1 (the bonus/verified token) and at most the full draft chain plus one. Values outside mean the requested profile is impossible for this num_speculative_tokens.

Source

Thrown at vllm/config/speculative.py:285

            )
        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."""

    dspark_draft_topk: int | None = Field(default=None, ge=1)
    """For Qwen3 DSpark drafting, evaluate the Markov projection only for the
    top-k base-logit candidates. Requires draft tensor parallel size 1."""

    def compute_hash(self) -> str:
        """

View on GitHub (pinned to c794754062)

Solutions

  1. Scale the length to the current depth: 1 <= length <= num_speculative_tokens + 1
  2. Or increase num_speculative_tokens so the chain covers the desired length
  3. Use synthetic_acceptance_rates if you need control beyond what a single scalar can express

Example fix

# before
num_speculative_tokens=3, synthetic_acceptance_length=6.0

# after
num_speculative_tokens=5, synthetic_acceptance_length=6.0
Defensive patterns

Strategy: validation

Validate before calling

def length_ok(n: int, length: float) -> bool:
    return 1.0 <= length <= float(n + 1)

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: synthetic_acceptance_length=6 with num_speculative_tokens=3 (max is 4); length 0.5 (< 1); reusing a length tuned for a deeper draft config.

Common situations: Changing speculative depth without re-checking length bounds; interpreting length as accepted draft tokens (max n) instead of n+1; benchmark sweeps crossing depth boundaries.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/8b1a41be6c564a9e. Report an issue: GitHub.