@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 56e96b37e4
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 12, 19:45 UTC

[V0 Deprecation] Remove `best_of` (#29090)

Signed-off-by: DarkLight1337 <tlleungac@connect.ust.hk>

Cyrus Leung committed Nov 21, 2025 at 11:40 UTC 56e96b37e4951946c06379b4891d8170e743dcc2
6 files changed +4 -65
docs/usage/v1_guide.md
+2 -2
@@ -169,8 +169,8 @@ As part of the major architectural rework in vLLM V1, several legacy features ha
169 - **best_of**: This feature has been deprecated due to limited usage. See details at [RFC #13361](https://github.com/vllm-project/vllm/issues/13361).
170 - **Per-Request Logits Processors**: In V0, users could pass custom
171 processing functions to adjust logits on a per-request basis. In vLLM V1, this
172 - feature has been deprecated. Instead, the design is moving toward supporting **global logits
173 - processors**, a feature the team is actively working on for future releases. See details at [RFC #13360](https://github.com/vllm-project/vllm/pull/13360).
172 + feature has been deprecated. Instead, we now support **global logits processors**
173 + which are set at startup time, see [RFC #17799](https://github.com/vllm-project/vllm/issues/17799).
174
175 ##### KV Cache features
176
tests/v1/sample/test_sampling_params_e2e.py
-8
@@ -22,14 +22,6 @@ def test_n_gt_1(llm):
22 assert len(outputs[0].outputs) == 3
23
24
25 -def test_best_of(llm):
26 - """Raise a ValueError since best_of is deprecated."""
27 -
28 - params = SamplingParams(n=2, best_of=3)
29 - with pytest.raises(ValueError):
30 - _ = llm.generate(PROMPT, params)
31 -
32 -
25 def test_penalties(llm):
26 """Check that we do not get errors if applied."""
27
vllm/entrypoints/openai/protocol.py
-4
@@ -565,7 +565,6 @@ class ChatCompletionRequest(OpenAIBaseModel):
565 user: str | None = None
566
567 # --8<-- [start:chat-completion-sampling-params]
568 - best_of: int | None = None
568 use_beam_search: bool = False
569 top_k: int | None = None
570 min_p: float | None = None
@@ -889,7 +888,6 @@ class ChatCompletionRequest(OpenAIBaseModel):
888 extra_args["kv_transfer_params"] = self.kv_transfer_params
889 return SamplingParams.from_optional(
890 n=self.n,
892 - best_of=self.best_of,
891 presence_penalty=self.presence_penalty,
892 frequency_penalty=self.frequency_penalty,
893 repetition_penalty=repetition_penalty,
@@ -1088,7 +1086,6 @@ class CompletionRequest(OpenAIBaseModel):
1086 # https://platform.openai.com/docs/api-reference/completions/create
1087 model: str | None = None
1088 prompt: list[int] | list[list[int]] | str | list[str] | None = None
1091 - best_of: int | None = None
1089 echo: bool | None = False
1090 frequency_penalty: float | None = 0.0
1091 logit_bias: dict[str, float] | None = None
@@ -1375,7 +1372,6 @@ class CompletionRequest(OpenAIBaseModel):
1372 extra_args["kv_transfer_params"] = self.kv_transfer_params
1373 return SamplingParams.from_optional(
1374 n=self.n,
1378 - best_of=self.best_of,
1375 presence_penalty=self.presence_penalty,
1376 frequency_penalty=self.frequency_penalty,
1377 repetition_penalty=repetition_penalty,
vllm/entrypoints/openai/serving_completion.py
+2 -8
@@ -250,14 +250,8 @@ class OpenAIServingCompletion(OpenAIServing):
250 model_name = self.models.model_name(lora_request)
251 num_prompts = len(engine_prompts)
252
253 - # Similar to the OpenAI API, when n != best_of, we do not stream the
254 - # results. Noting that best_of is only supported in V0. In addition,
255 - # we do not stream the results when use beam search.
256 - stream = (
257 - request.stream
258 - and (request.best_of is None or request.n == request.best_of)
259 - and not request.use_beam_search
260 - )
253 + # We do not stream the results when using beam search.
254 + stream = request.stream and not request.use_beam_search
255
256 # Streaming response
257 if stream:
vllm/sampling_params.py
-40
@@ -144,12 +144,6 @@ class SamplingParams(
144 are generated and streamed cumulatively per request. To see all `n`
145 outputs upon completion, use `output_kind=RequestOutputKind.FINAL_ONLY`
146 in `SamplingParams`."""
147 - best_of: int | None = None
148 - """Number of output sequences that are generated from the prompt. From
149 - these `best_of` sequences, the top `n` sequences are returned. `best_of`
150 - must be greater than or equal to `n`. By default, `best_of` is set to `n`.
151 - Warning, this is only supported in V0."""
152 - _real_n: int | None = None
147 presence_penalty: float = 0.0
148 """Penalizes new tokens based on whether they appear in the generated text
149 so far. Values > 0 encourage the model to use new tokens, while values < 0
@@ -265,7 +259,6 @@ class SamplingParams(
259 @staticmethod
260 def from_optional(
261 n: int | None = 1,
268 - best_of: int | None = None,
262 presence_penalty: float | None = 0.0,
263 frequency_penalty: float | None = 0.0,
264 repetition_penalty: float | None = 1.0,
@@ -315,7 +308,6 @@ class SamplingParams(
308
309 return SamplingParams(
310 n=1 if n is None else n,
318 - best_of=best_of,
311 presence_penalty=0.0 if presence_penalty is None else presence_penalty,
312 frequency_penalty=0.0 if frequency_penalty is None else frequency_penalty,
313 repetition_penalty=1.0
@@ -348,22 +340,6 @@ class SamplingParams(
340 )
341
342 def __post_init__(self) -> None:
351 - # how we deal with `best_of`:
352 - # if `best_of` is not set, we default to `n`;
353 - # if `best_of` is set, we set `n` to `best_of`,
354 - # and set `_real_n` to the original `n`.
355 - # when we return the result, we will check
356 - # if we need to return `n` or `_real_n` results
357 - if self.best_of:
358 - if self.best_of < self.n:
359 - raise ValueError(
360 - f"best_of must be greater than or equal to n, "
361 - f"got n={self.n} and best_of={self.best_of}."
362 - )
363 - if not self._real_n:
364 - self._real_n = self.n
365 - self.n = self.best_of
366 -
343 if 0 < self.temperature < _MAX_TEMP:
344 logger.warning(
345 "temperature %s is less than %s, which may cause numerical "
@@ -433,18 +409,6 @@ class SamplingParams(
409 raise ValueError(f"n must be an int, but is of type {type(self.n)}")
410 if self.n < 1:
411 raise ValueError(f"n must be at least 1, got {self.n}.")
436 - if self.best_of is not None:
437 - if not isinstance(self.best_of, int):
438 - raise ValueError(
439 - f"best_of must be an integer, got {type(self.best_of)}"
440 - )
441 - if self.best_of < 1:
442 - raise ValueError(f"best_of must be at least 1, got {self.best_of}")
443 - if self.best_of < self.n:
444 - raise ValueError(
445 - f"best_of must be greater than or equal to n, "
446 - f"got n={self.n} and best_of={self.best_of}."
447 - )
412 if not -2.0 <= self.presence_penalty <= 2.0:
413 raise ValueError(
414 f"presence_penalty must be in [-2, 2], got {self.presence_penalty}."
@@ -519,10 +483,6 @@ class SamplingParams(
483 "stop strings are only supported when detokenize is True. "
484 "Set detokenize=True to use stop."
485 )
522 - if self.best_of != self._real_n and self.output_kind == (
523 - RequestOutputKind.DELTA
524 - ):
525 - raise ValueError("best_of must equal n to use output_kind=DELTA")
486
487 def _verify_greedy_sampling(self) -> None:
488 if self.n > 1:
vllm/v1/engine/processor.py
-3
@@ -142,9 +142,6 @@ class Processor:
142 self,
143 params: SamplingParams,
144 ) -> None:
145 - # Best of not yet supported.
146 - if params.best_of is not None and params.best_of > 1:
147 - raise ValueError("vLLM V1 does not yet support best_of.")
145 # Logits processors not supported.
146 if params.logits_processors:
147 raise ValueError(