sgl-project/sglang · error · ValueError

Unconditional token logprobs are required for this method.

Error message

Unconditional token logprobs are required for this method.

What it means

Raised by the choices module (PMI/length-normalization helpers) when a method that computes contrastive scores is called with unconditional_token_logprobs=None. The algorithm needs the unconditional (reference) logprobs to normalize against, so refusing on None prevents silent nonsense results.

Source

Thrown at python/sglang/lang/choices.py:132

        return True

    def __call__(
        self,
        *,
        choices: List[str],
        normalized_prompt_logprobs: List[float],
        input_token_logprobs: List[List[Any]],
        output_token_logprobs: List[List[Any]],
        unconditional_token_logprobs: Optional[List[List[Any]]] = None,
    ) -> ChoicesDecision:
        """Select the option with the highest average token logprob once normalized by
        the unconditional token logprobs.

        The first unconditional token logprob is assumed to be None. If so, it is
        replaced with 0 for the purposes of normalization."""

        if unconditional_token_logprobs is None:
            raise ValueError(
                "Unconditional token logprobs are required for this method."
            )

        normalized_unconditional_prompt_logprobs = self._normalize_logprobs(
            input_token_logprobs, unconditional_token_logprobs
        )

        best_choice = choices[np.argmax(normalized_unconditional_prompt_logprobs)]
        meta_info = {
            "normalized_prompt_logprobs": normalized_prompt_logprobs,
            "input_token_logprobs": input_token_logprobs,
            "output_token_logprobs": output_token_logprobs,
            "unconditional_token_logprobs": unconditional_token_logprobs,
            "normalized_unconditional_prompt_logprobs": normalized_unconditional_prompt_logprobs,
        }
        return ChoicesDecision(decision=best_choice, meta_info=meta_info)

    def _normalize_logprobs(self, input_token_logprobs, unconditional_token_logprobs):

View on GitHub (pinned to 0132848349)

Solutions

  1. Compute unconditional logprobs for each choice (run the reference generation with logprobs enabled) and pass them as unconditional_token_logprobs
  2. Ensure the first element may be None (it's replaced with 0) but the array itself is not None
  3. Check upstream generation code actually returned logprobs (not None) before calling this method

Example fix

# before
result = choice_fn(input_token_logprobs=lp, unconditional_token_logprobs=None)
# after
uncond = gen_unconditional_logprobs(prompt, choices)  # reference pass with logprobs on
result = choice_fn(input_token_logprobs=lp, unconditional_token_logprobs=uncond)
Defensive patterns

Strategy: validation

Validate before calling

assert unconditional_token_logprobs is not None, "compute unconditional logprobs before scoring"

Type guard

def has_uncond_logprobs(lp) -> bool:
    return lp is not None and (len(lp) == 0 or lp[0] is None or isinstance(lp[0], float))

Try / catch

try:
    score = chooser(input_logprobs, uncond_logprobs)
except ValueError as e:
    if "Unconditional" in str(e):
        uncond = compute_reference_logprobs(...)
        score = chooser(input_logprobs, uncond)
    else:
        raise

Prevention

When it happens

Trigger: Calling the choice-scoring __call__ (e.g. contrastive/PMI-style selection over branches in an SGL program) without passing the unconditional_token_logprobs array, typically because the branch generation didn't request logprobs or the caller forgot to compute the reference scores.

Common situations: Using sgl.choice / branch selection helpers where only conditional generations were run; refactoring removed the unconditional scoring pass; sampling params without logprobs enabled so the array came back None.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/141c52e7ebb574a0. Report an issue: GitHub.