[Frontend] Support min_p in the Responses API (#48084)

Signed-off-by: sungbin1015 <sbin@solbox.com>
Co-authored-by: Flora Feng <4florafeng@gmail.com>
This commit is contained in:
sungbin1015
2026-10-08 20:38:17 +00:00
committed by GitHub
co-authored by Flora Feng
parent c5c1161382
commit 2ddde19e8e
5 changed files with 27 additions and 8 deletions
@@ -204,6 +204,12 @@ To get prompt token IDs before generation, use
a self-contained Responses request without inference and returns the prompt
token IDs, so a separate `/tokenize` call is not needed.
#### Sampling parameters
In addition to the OpenAI request fields, the Responses API forwards vLLM
[sampling parameters](../../api/README.md#inference-parameters) such as `top_k`,
`min_p`, `repetition_penalty`, `seed`, `stop`, and `ignore_eos` to the engine.
#### Extra parameters
The following extra parameters in the request object are supported:
@@ -183,6 +183,7 @@ def test_request_payload_is_accepted_by_the_server_schema():
"temperature": 0.7,
"top_p": 0.9,
"top_k": 20,
"min_p": 0.05,
"frequency_penalty": 0.2,
"presence_penalty": 0.1,
"repetition_penalty": 1.05,
@@ -217,9 +218,6 @@ def test_request_payload_is_accepted_by_the_server_schema():
assert set(seen["payload"]) <= set(ResponsesRequest.model_fields)
ResponsesRequest.model_validate(seen["payload"])
# `vllm bench serve` rejects --min-p for this backend for the same reason.
assert "min_p" not in ResponsesRequest.model_fields
def test_latency_accounting_matches_the_other_endpoints():
"""`latency - ttft` must equal `sum(itl)`.
@@ -29,6 +29,7 @@ class TestResponsesRequestSamplingParams:
temperature=0.8,
top_p=0.95,
top_k=50,
min_p=0.1,
max_output_tokens=100,
)
@@ -37,8 +38,20 @@ class TestResponsesRequestSamplingParams:
assert sampling_params.temperature == 0.8
assert sampling_params.top_p == 0.95
assert sampling_params.top_k == 50
assert sampling_params.min_p == 0.1
assert sampling_params.max_tokens == 100
def test_min_p_default(self):
"""Test that min_p defaults to 0.0 when unset (parity with top_k)."""
request = ResponsesRequest(
model="test-model",
input="test input",
)
sampling_params = request.to_sampling_params(default_max_tokens=1000)
assert sampling_params.min_p == 0.0
def test_extra_sampling_params(self):
"""Test extra sampling parameters are correctly mapped."""
request = ResponsesRequest(
-5
View File
@@ -2196,11 +2196,6 @@ async def main_async(args: argparse.Namespace) -> dict[str, Any]:
"Sampling parameters are only supported by openai-compatible backends."
)
# The Responses API accepts every sampling parameter above except
# min_p, which it would silently drop as an unknown field.
if args.backend == "openai-responses" and "min_p" in sampling_params:
raise ValueError("--min-p is not supported by the Responses API.")
if "temperature" not in sampling_params:
print(
"WARNING: vllm bench serve no longer sets temperature==0 (greedy) "
@@ -259,6 +259,7 @@ class ResponsesRequest(OpenAIBaseModel):
top_logprobs: TopLogprobsParam = 0
top_p: float | None = None
top_k: int | None = None
min_p: float | None = None
truncation: Literal["auto", "disabled"] | None = "disabled"
user: str | None = None
skip_special_tokens: bool = True
@@ -444,6 +445,7 @@ class ResponsesRequest(OpenAIBaseModel):
"temperature": 1.0,
"top_p": 1.0,
"top_k": 0,
"min_p": 0.0,
}
def extract_structured_outputs(self) -> StructuredOutputsParams | None:
@@ -494,6 +496,10 @@ class ResponsesRequest(OpenAIBaseModel):
top_k = default_sampling_params.get(
"top_k", self._DEFAULT_SAMPLING_PARAMS["top_k"]
)
if (min_p := self.min_p) is None:
min_p = default_sampling_params.get(
"min_p", self._DEFAULT_SAMPLING_PARAMS["min_p"]
)
if (repetition_penalty := self.repetition_penalty) is None:
repetition_penalty = default_sampling_params.get("repetition_penalty", 1.0)
@@ -519,6 +525,7 @@ class ResponsesRequest(OpenAIBaseModel):
watermarking=self.watermarking,
top_p=top_p,
top_k=top_k,
min_p=min_p,
max_tokens=max_tokens,
logprobs=self.top_logprobs if self.is_include_output_logprobs() else None,
stop=stop,