vllm-project/vllm · error · ValueError

synthetic_acceptance_rates must have length {n}, got {rates}

Error message

synthetic_acceptance_rates must have length {n}, got {rates}.

What it means

When explicit synthetic_acceptance_rates are given, the list must contain exactly n entries — one per speculative position (n = number of speculative tokens/depth). The rate at index i is the unconditional acceptance probability at position i, so a shorter or longer list cannot be mapped onto the draft chain.

Source

Thrown at vllm/config/speculative.py:270

            [1.0] * num_full + [num_drafts - num_full] + [0.0] * (n - num_full - 1)
        )[:n]

    @staticmethod
    def _resolve_synthetic_acceptance_rates(
        n: int,
        rates: list[float] | None,
        length: float | None,
    ) -> list[float]:
        """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)

View on GitHub (pinned to c794754062)

Solutions

  1. Regenerate the rates list so len(rates) == num_speculative_tokens
  2. Or switch to synthetic_acceptance_length, which is depth-independent and auto-converted
  3. Derive rates programmatically: [min(1.0, L/(i+1)) for i in range(n)] from measured mean length L

Example fix

# before
num_speculative_tokens=3, synthetic_acceptance_rates=[0.9, 0.8]

# after
num_speculative_tokens=3, synthetic_acceptance_rates=[0.9, 0.8, 0.7]
Defensive patterns

Strategy: validation

Validate before calling

def rates_len_ok(n: int, rates: list[float]) -> bool:
    return len(rates) == n

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: synthetic_acceptance_rates=[0.9] with num_speculative_tokens=3; reusing a rates profile tuned for a different speculative depth without resizing; off-by-one lists built from measurements of accepted length rather than per-position rates.

Common situations: Changing --num-speculative-tokens without regenerating the rates profile; copying benchmark profiles between models with different draft depths.

Related errors


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